flex程序默认总是从标准输入读取, 实际上,词法分析程序都从文件读取输入
flex总是通过名为yyin的文件句柄读取输入, 下面的例子,我们修改单词计数程序,使得它能从文件读取输入
/* even more like Unix wc */ %option noyywrap %{ int chars = 0; int words = 0; int lines = 0; %} %% [a-zA-Z]+ { words++; chars += strlen(yytext); } \n { chars++; lines++; } . { chars++; } %% main(argc, argv) int argc; char **argv; { if(argc > 1) { if(!(yyin = fopen(argv[1], "r"))) { perror(argv[1]); return (1); } } yylex(); printf("%8d%8d%8d\n", lines, words, chars); }
程序中,如果在命令行中提供的文件参数, 那么程序会打开它,修改yyin
yywrap
-lfl库,提供了默认的main主程序和早期lex遗留至今的鸡肋-yywrap
yywarp作用
单lex读取到文件末尾时,会调用yywrap(), 目的是,当有另外一个输入文件时,yywrap可以调整yyin的值并且返回0来重新开始词法分析。如果是真正的文件末尾,那么就返回1来完成分析。
flex默认main程序
int main()
{
while (yylex() != 0) ;
return 0;
}
现在大多flex程序使用“%option noyywrap” 来禁用yywrap,然后写出自己的主程序,所以它们不需要-lfl库
读取多个文件,yyrestart(fp); 如果yylex, yyparse()出现错误, 调用yyrestart()重置调整yyin,重新开始yylex(), 所以开始lex之前,都要调用yyrestart()
main(argc, argv) int argc; char **argv; { int i; if(argc < 2) { /* just read stdin */ yylex(); printf("%8d%8d%8d\n", lines, words, chars); return 0; }
for(i = 1; i < argc; i++) { FILE *f = fopen(argv[i], "r"); if(!f) { perror(argv[i]); return (1); }
yyrestart(f); yylex(); fclose(f); printf("%8d%8d%8d %s\n", lines, words, chars, argv[i]); totchars += chars; chars = 0; totwords += words; words = 0; totlines += lines; lines = 0; }
if(argc > 1) /* print total if more than one file */ printf("%8d%8d%8d total\n", totlines, totwords, totchars); return 0; }