故意违反yacc规则

时间:2012-05-15 13:21:13

标签: error-handling grammar yacc

在yacc / bison语法中,是否有一种方法可以从中规则行动中放弃规则 完全,但没有错误(以及对yyerror的调用),以便其他选项仍然存在 是有效的(类似于flex中的'reject')?

假设'num'具有整数值,则以下规则将定义不同的值 偶数和奇数制作的语法

rule :   num { if (($1 & 1) == 1) reject; } a b c 
       | num { if (($1 & 1) == 0) reject; } d e ;

THX

2 个答案:

答案 0 :(得分:2)

与flex不同,Yacc不进行任何类型的回溯,因此在运行时没有其他选项 - 规则运行正确,或者出现错误。您可以使用YYREJECT宏完全退出解析器(从yyparse返回1),但这可能不是您想要的。

如果您使用btyacc(支持回溯),您可以通过暂定操作调用YYERROR来执行您想要的操作。这将导致它回溯并尝试不同的替代方案,并且如果没有替代方案,实际上只会给出语法错误。

答案 1 :(得分:1)

您可以使用中间规则操作将令牌推送到解析堆栈,然后可以通过其他规则对其进行评估,这样您就可以对解析的结果进行编程选择。

http://www.gnu.org/software/bison/manual/html_node/Mid_002dRule-Actions.html

  

中期规则行动本身就是其中一个组成部分   规则。当稍后有另一个动作时,这会有所不同   同样的规则(通常最后还有另一条规则):你必须这样做   在计算出哪个数字时,计算动作和符号   n用于$ n。

     

中规则操作也可以具有语义值。动作可以设定   它的值赋值为$$,后面的规则中的操作可以   使用$ n引用值。由于没有符号可以命名   动作,没有办法为该值声明数据类型   提前,所以你必须使用'$< ...> n'结构来指定数据   每次引用此值时键入。

因此,有可能这样做,但不能与flex完全相同。这样做可能有些苛刻,因为你本质上正在做的是破坏语法的无上下文性质。