首页 > 解决方案 > 如何使 flex 使用包含文本的文件 (.txt/.c/etc.) 作为其输入

问题描述

我对 flex 完全陌生,而且我的编程经验很少。我需要使用 flex 创建一个扫描仪,最终将输出一个令牌流。目前,我只需要启动和运行绝对基础知识。我希望编译后的输出文件“a.exe”能够从单个文件中的文本运行,而不是用户输入。输出也应该是一个文件。作业要求程序能够在 cmd/PS 窗口中像这样运行: .\a.exe inputfile.txt outputfile.txt 其中输入和输出文件是按该顺序添加的任何文件名。就目前而言,我的程序创建了我指定的输出文件,但没有写入任何内容。在尝试阅读 Flex 手册时,我很困惑,因为我对计算机科学还是很陌生。就目前而言,我只想获得一个可执行文件,该文件将遵守规则部分并正确输出。这就是说我通常只是计算输入文件中的字符并尝试将它们显示到输出文件中。我也试图帮助班上的其他人有一个开始的地方(因为我们都没有在这件事上受过正式教育)所以我花时间尝试一般地创建这个文件(带有安装和使用说明),以便我可以给他们一个地方来开始制作扫描仪的实际任务。

我从http://gnuwin32.sourceforge.net/packages.html安装了 Flex 2.5.4a 。我在安装后编辑了我的路径以包含 bin 文件。

我使用命令“flex tokenout.l”构建文件,然后使用“gcc lex.yy.c”,它会生成一个 a.exe 文件。在创建输出文件之后,该文件似乎根本不起作用。

代码:

int num_lines = 0;
int num_chars = 0;
FILE *yyin;
FILE *yyout;

%%
\n  ++num_lines; ++num_chars;
.   ++num_chars;
%%

int yywrap(void) {
    return 0;
}
int main(int argc, char *argv[])
{
    yyin = fopen(argv[1],"r");
    yyout = fopen(argv[2],"w");
    yyparse();
    yylex();
    fprintf(yyout,"# of lines = %d, # of chars = %d\n", num_lines, num_chars);
    fclose(yyin);
    fclose(yyout);
    return 0;
}

结果应该是指定为第二个参数的文件中的行“# of lines = 实际# of lines, # of chars = the actual # of characters”。

当前由第二个参数指定的文件已创建但仍为空白。

标签: ccompiler-constructionflex-lexerc99

解决方案


yyin = fopen(argv[1],"r");
yyout = fopen(argv[2],"w");
yyparse();
yylex();

就目前而言,我的程序创建了我指定的输出文件,但没有写入任何内容。

你很困惑,因为你不知道你的程序在做什么,你也不知道它在做什么,因为它没有告诉你。你需要的是反馈。特别是,您需要检查错误。

例如,如果第一个fopen (3) 失败了怎么办?如果yyparse失败或不返回怎么办?(它不会。)检查错误,让程序告诉你发生了什么。

#include <err.h>
if( argc < 3 ) {
    errx(EXIT_FAILURE, "syntax: foo in out");
}
if( (yyin = fopen(argv[1],"r")) == NULL ) {
    err(EXIT_FAILURE, "could not read '%s'", argv[1]);
}
if (yyout = fopen(argv[2],"w")) == NULL ) {
    err(EXIT_FAILURE, "could not write '%s'", argv[2]);
}

printf("starting yyparse\n");
if( 0 != yyparse() ) {
    errx(EXIT_FAILURE, "parse error");
}
printf("starting yylex\n");
if( 0 != yylex() )  {
    errx(EXIT_FAILURE, "lex error");
}

以上确保程序以足够的参数启动,确保两个文件都成功打开,并检查解析和词法分析的错误。不过,这只是一个例子。正如 John Bollinger建议的那样,您不需要 yyparse,因为您没有使用野牛,并且 yyout 仅控制 flex ECHO 语句使用的文件。您可以在 flex 操作中使用自己的全局 FILE *句柄和fprintf (3)。

我想你会发现你永远不会在屏幕上看到“正在启动 yylex”,因为 yyparse 永远不会返回,因为——如果它是在某处生成的——它不会返回,因为它正在调用yylex,它永远不会返回任何东西.

我会删除这些行,并设置 flex 调试

  yy_flex_debug = 1;

在打电话给 yylex 之前。我想你会发现它更有意义。


推荐阅读