您的位置:首页 > 其它

第二章 flex输入输出

2015-07-11 09:47 274 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: