Return of the Lex
cpp fortran lex yaccI 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 50.00
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.
%option noyywrap
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. Then we fetch the token one by one,
convert the matched yytext
to float-point number until the end of file.
extern FILE* yyin;
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.
LEX = flex
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 $
Here is the tarball for the source code and example input file.