lex
(ou flex
em sistemas Linux) é um programa que usa uma especificação de scanner / lexer e o transforma em um programa em C. Sua especificação de scanner é similar em natureza a um programa awk
, mas onde awk
é orientado a registro lex
é "orientado a caracteres".
Usando lex
com a seguinte fonte em lexer.l
:
%x OUTPUT
%%
int quoted = 0;
^[0-9]*[ \t]*"/test1/" { BEGIN OUTPUT; ECHO; }
<OUTPUT>\n { if (!quoted) { BEGIN 0; } ECHO; }
<OUTPUT>[^\]["] { quoted = !quoted; ECHO; }
<OUTPUT>. { ECHO; }
.|\n ;
Este scanner usa um estado OUTPUT
para acompanhar se queremos que os caracteres atuais sejam exibidos ou não. Entramos nesse estado com BEGIN OUTPUT
quando encontramos uma linha parecida com
<number> /test1/
(isso é tratado pela primeira regra). Saímos desse estado quando uma linha termina e não estamos verificando uma string entre aspas (isso é tratado pela segunda regra).
Uma string entre aspas é iniciada e finalizada com um caractere "
não escapado (a terceira regra). Todos os outros caracteres são transmitidos como estão sem ação (a quarta regra).
Embora não esteja no estado OUTPUT
, ignoramos tudo (a última regra).
Note que este é um scanner improvisado escrito para seus dados específicos. Ele não manipula strings entre aspas que terminam com uma barra invertida com escape ( "some data \"
), mas funciona nos dados que você mostrou.
Construindo:
$ make lexer
lex -o lex.lexer.c lexer.l
cc -O2 -pipe -o lexer lex.lexer.c -ll
rm -f lex.lexer.c
(no Linux, ao usar flex
, você pode ter que usar make lexer LDLIBS=-ll
)
Usando:
$ ./lexer <file
20 /test1/catergory="Food"
20 /test1/target="Adults, \"Goblins\", Elderly,
Babies, \"Witch\",
Faries"
20 /test1/type="Western"
20 /test1/end=category
20 /test1/Purpose=
20 /test1/my_purpose="To create
a fun-filled moment"
20 /test1/end=Purpose