Return of the Lex
Development July 7th, 2006
I don’t touch the flex/yacc since the final exam of the class, until today I have to cope with the FORTRAN 90 input data. The input file is like:
80000.00 0.00
120000.00 0.00
with various data formats, flexible lengths of white space, scattered white lines. I first tired the standard string search/match, and soon lost the patience for tedious if..else. Therefore, I decided to try Lex, the very first flex in action.
First, the flex rule. We just need the float pointer number, and ignore all the spaces, new-lines and end-of-file. We expect the token is returned one by one, so we return the flag as soon as the pattern matches.
space [ \t]+
number [-+]?[0-9]*\.?[0-9]*
%%
{number} { return 1; }
{space} |
\n ;
%%
In main.c, we would like to override default input file handle stdin for yyin if additional argument is fed ( for some reason, this cause the wordpress 503 error, so take a look at the tarball, sorry for the inconveniece). Then we fetch the token one by one, convert the matched yytext to float-point number until the end of file.
extern char* yytext;
extern int yylex(void);
int main(int argc, char* argv[] )
{
double x;
assert( yyin );
if( argc == 1 )
yyin = stdin;
while( yylex() )
{
fprintf(stderr, "text = %s ", yytext );
x = atof( yytext );
fprintf(stderr, "x = %f\n", x );
}
return 0;
}
At then end, Makefile glues all the parts together.
LEXFLAGS = -t
CFLAGS = -g
OBJS = obstac.o main.o
TARGET = scan
all : ${TARGET}
${TARGET} : ${OBJS}
${CC} ${CFLAGS} -o ${TARGET} ${OBJS}
%.c : %.l
${LEX} ${LEXFLAGS} $< > $@
%.o : %.c
${CC} ${CFLAGS} -o $@ -c $<
.PHONY: clean
clean :
${RM} ${TARGET} ${OBJS}
Here is the tarball for the source code and example input file.







Leave a Comment