【问题标题】:Flex throws "input in flex scanner failed" after parsing whole file?解析整个文件后,Flex 抛出“flex 扫描仪中的输入失败”?
【发布时间】:2018-03-15 13:33:32
【问题描述】:

我正在尝试使用 Flex 和 Bison 在 C++ 中制作解析器。我只在提供错误文件进行解析的帖子中在线看到“flex 扫描仪中的输入失败”。但是在我的整个文件被正确解析后,我收到了这个错误。是否存在一些 flex 无法正确检测 EOF 的错误?以下是相关定义:

野牛 -

%union {
    char node;
    char gate;
    int index;
}

%token END;
%token <node> NODE;
%token <gate> GATE;
%token <index> INDEX;

%%

atpg:
    body END { cout << "Reading last line." << endl; };
body:
    assignments;
assignments:
    assignments assignment { cout << "Token: assignments - rec." << endl; }
    | assignment         { cout << "Token: assignments - first." << endl; };
assignment:
    outnode gatedec '(' nodelist ')'  {
        cout << "Token: assignment" << endl;
        g_gatelist[last_gate].setOutput(&g_nodelist[out_node]);
        for(int i : t_nodelist)
            g_gatelist[last_gate].addInput(&g_nodelist[i]);
        t_nodelist.clear();
        };
outnode:
    nodedec '='  {
        cout << "Token: outnode" << endl;
        out_node = last_node;
        };
nodedec:
    NODE INDEX  {
        num_nodes ++;
        if ($1 == 'i') input_nodes ++;
        if ($1 == 'o') output_nodes ++;

        new(&g_nodelist[$2]) Node($1, $2);
        last_node = $2;

        cout << g_nodelist[$2] << endl;
        };
gatedec:
    GATE INDEX  {
        num_gates ++;

        createGateFromName(&g_gatelist[$2], $1, $2);
        last_gate = $2;

        cout << "Gate: " << $1 << "-" << $2 << endl; 
        };
nodelist:
    nodedec nodelist { 
        cout << "Token: nodelist - rec" << endl;
        t_nodelist.push_back(last_node);
        }
    | nodedec {
        cout << "Token: nodelist - first" << endl;
        t_nodelist.push_back(last_node);
        };

弹性 -

%{
#include "gatelist.tab.h"
#define YY_DECL extern "C" int yylex()
%}

INDEX    [0-9]+
GATE     and|or|not
NODE     n|i|o

%%

{GATE}      { yylval.gate = yytext[0]; return GATE; }

{NODE}      { yylval.node = yytext[0]; return NODE; }

{INDEX}     { yylval.index = atoi(yytext); return INDEX; }

[\(\)=]     { return yytext[0]; }

end         { return END; }

.|\n ;/* ignore */
%%
;

输入 -

n3 = and1 ( i0 i1 i2 )
n4 = or2 ( i1 i2 )
n5 = not3 ( n4 )
n6 = and4 ( n5 n4 )
end

输出 -

Node(n-3 = 0)
Token: outnode
Gate: a-1
Node(i-0 = 0)
Node(i-1 = 0)
Node(i-2 = 0)
Token: nodelist - first
Token: nodelist - rec
Token: nodelist - rec
Token: assignment
Token: assignments - first.
Node(n-4 = 0)
Token: outnode
Gate: o-2
Node(i-1 = 0)
Node(i-2 = 0)
Token: nodelist - first
Token: nodelist - rec
Token: assignment
Token: assignments - rec.
Node(n-5 = 0)
Token: outnode
Gate: n-3
Node(n-4 = 0)
Token: nodelist - first
Token: assignment
Token: assignments - rec.
Node(n-6 = 0)
Token: outnode
Gate: a-4
Node(n-5 = 0)
Node(n-4 = 0)
Token: nodelist - first
Token: nodelist - rec
Token: assignment
Token: assignments - rec.
Reading last line.
input in flex scanner failed

【问题讨论】:

  • 我已尽我所能,但请阅读有关如何准备minimal reproducible example 的信息。无法测试您的代码,因为 (1) 操作取决于外部函数,并且 (2) 不包括驱动程序和 Makefile 或构建过程。不要只添加所需函数的定义,因为这会使非最小示例变得更长。相反,准备一个没有(不必要的)操作的版本(在您的情况下,所有操作都是不必要的)并包括所有其他使用的定义(例如,yywrap 和 yyerror,尽管我总是更喜欢在 flex 文件中使用%option noyywrap 以避免需要。 )

标签: bison flex-lexer


【解决方案1】:

Bison 始终通过添加与您提供的开始规则相匹配的目标规则和后跟文件结束指示符(令牌编号 0)来增强提供的语法,以便强制输入匹配完整的文件。如果您想使用自己的结束标记并在识别到解析时终止解析,则应在关联操作中使用 YYACCEPT 操作以使解析成功终止而无需读取更多标记。

当 flex 扫描器在尝试读取数据时收到读取错误时,就会发生您遇到的错误。文件结尾不是错误,I/O 错误相当少见。通常,此错误表示在报告文件结尾并且yyin 关闭(或设置为无效值)后尝试继续读取输入。一般来说,您应该避免在报告文件结束后读取令牌;虽然它通常可以工作,但它并没有得到完全支持,并且使用某些扫描仪选项会产生意想不到的结果。


作为一个附带问题,您通常会发现使用 bison 的内置 trace facility 比在整个代码中分散 printf 更容易。您最终会添加和删除 printf,这是一件令人讨厌的事情,而且它们永远不会像野牛踪迹那样为您提供完整的图片。

【讨论】:

  • 我添加了 YYACCEPT 并解决了问题。我无法让跟踪工作,添加了 YYDEBUG--debug 标志
  • @udiboy1209:您只需要--debug#define YYDEBUG,但您还需要yydebug = 1;。一个常见的习惯用法是将 #if YYDEBUG yydebug = 1; #endif 放入 main (如果解析器包含在 main 中可见)。
  • 可能这一段应该更靠近文档页面的顶部。 “一旦你用跟踪工具编译了程序,请求跟踪的方法就是在变量 yydebug 中存储一个非零值。”人们似乎经常错过它。程序员实际上会阅读整页文档的假设似乎已成为过去,如果曾经是这样的话。
猜你喜欢
  • 2020-03-02
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多