Error handling 故意违反yacc规则

Error handling 故意违反yacc规则,error-handling,grammar,yacc,Error Handling,Grammar,Yacc,在yacc/bison语法中,是否有一种方法可以从中间规则操作中丢弃规则 总之,但是没有错误(以及对yyerror的调用),因此其他选项仍然可以 是否有效(类似于flex中的“拒绝” 假设'num'有一个整数值,那么下面的规则将定义不同的 奇偶乘积的语法 rule : num { if (($1 & 1) == 1) reject; } a b c | num { if (($1 & 1) == 0) reject; } d e ; thx您可以使用mid规

在yacc/bison语法中,是否有一种方法可以从中间规则操作中丢弃规则 总之,但是没有错误(以及对yyerror的调用),因此其他选项仍然可以 是否有效(类似于flex中的“拒绝”

假设'num'有一个整数值,那么下面的规则将定义不同的 奇偶乘积的语法

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

thx

您可以使用mid规则操作将令牌推送到解析堆栈,然后由另一个规则对其进行评估,这将使您能够对解析结果进行编程选择

中间规则操作本身算作 规则。这会在以后的操作中产生影响 同样的规则(通常结尾还有另一条):你必须 计算出数字时,将动作和符号一起计算 n要在$n中使用

中间规则操作也可以具有语义值。动作可以设定 将其值赋值为$$,然后可以执行规则中稍后的操作 请使用$n引用该值。因为没有符号来命名 操作时,无法为中的值声明数据类型 高级,因此必须使用“$n”构造来指定数据类型 每次引用此值时,请键入


因此,这样做是可能的,但与flex中的方式不同。这样做可能有点不妥,因为您实际上是在破坏语法的上下文无关性。

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

如果要使用(支持回溯),可以通过在试探性操作中调用
YYERROR
来执行所需操作。这将导致它回溯并尝试不同的替代方案,并且只有在没有替代方案的情况下才会实际给出语法错误