我想在我的Flex解析C风格的多行注释(.L)文件:为什么flex/bison中的多行注释如此回避?
%s ML_COMMENT
%%
...
"/*" BEGIN(ML_COMMENT);
"*/" BEGIN(INITIAL);
[.\n]+ { }
我不返回任何令牌和我的语法(.Y)没有解决意见以任何方式。
当我运行我的可执行文件,我得到一个解析错误:
$ ./a.out
/*
abc
def
Parse error: parse error
$ echo "/* foo */" | ./a.out
Parse error: parse error
(我的yyerror函数做一个printf(“解析错误:%s \ n”),这是其中的第一个半多余的错误信息来自)。
我可以看到为什么第二个示例失败,因为整个输入是注释,并且由于语法忽略了注释,所以没有语句。因此输入不是一个有效的程序。但是,第一部分在我完成评论之前抛出了一个解析错误。
另外混乱:
$ ./a.out
/* foo */
a = b;
Parse error: parse error
在这种情况下,注释之前实际有效的输入(其没有评论,解析就好)关闭。在解析“a”之后实际发生失败,而不是在尝试解析赋值“a = b;”之后发生。如果我自己输入“a”,它仍然会报错。
鉴于错误消息是一个解析器错误,而不是扫描仪错误,是否有什么关键我在我的.y文件中缺少?或者我在扫描器规则中做错了什么,传播到解析器端?
编辑:每@鲁迪的建议下,我打开调试,发现:
$ ./a.out
Starting parse
Entering state 0
Reading a token: /*
foo
Next token is 44 (IDENTIFER)
Shifting token 44 (IDENTIFER), Entering state 4
Reducing via rule 5 (line 130), IDENTIFER -> identifier
state stack now 0
Entering state 5
我关掉调试,发现确实/* foo */ = bar;解析一样foo = bar;。我使用的是flex 2.5.4;它并没有给我任何关于我试图使用的有状态规则的警告。
2010-11-10
adelarge
+1
我重新标记弯曲以GNU-FLEX。您的扫描仪规则看起来没问题。解析错误指示解析器的无效令牌输入。你可能想发布一些相应的Bison规则。此外,它可能是一个好主意,把printf()的报表您的野牛规则里面,这样你可以看到什么样的规则令牌的扫描过程中解析器尝试。 –
2010-11-10 14:40:24
+2
为您的扫描仪创建单独的测试工具也是一个好主意。这样您就可以将扫描仪缺陷与解析器缺陷隔离开来。任何扫描分析器系统是复杂的,以至于当你添加了'--debug'标志的野牛,你不需要通过执行集成测试,当你真正想要的是要进行单元测试...... –
2010-11-10 15:11:51
+1
注入额外的复杂性调用并设置'YYDEBUG = 1'的'yyparse()'呼叫之前,则解析器发出调试信息为每一个令牌从词法分析器看到。 –
2010-11-10 15:14:41