如何在yacc中进行条件编译。类似于在C中使用ifdef完成的操作。
我想创建一个基于条件的规则。在yacc中是否可以。举例说明。基于条件,规则A定义如下:
ruleA : A | B, /* For condition 1 */
ruleA : C /* If condition 1 is not satisfied */ 发布于 2012-11-02 05:26:43
与C预处理器类似,btyacc具有基于定义的标志的条件编译。你可以说:
%ifdef VERSION_A
ruleA: A | B ;
%endif
%ifdef VERSION_B
ruleA: C ;
%endif然后使用-DVERSION_A或-DVERSION_B命令行参数获取一个或另一个版本。它非常原始(每个%ifdef只能测试一个标志,不能嵌套%ifdef,也没有%else),但对于简单的事情它已经足够了。
发布于 2012-11-01 13:21:28
如果您不能使用适当的预处理器对Yacc语法进行预处理,那么您可以使用基于操作的解决方案:
ruleA : A { if (condition1) { process OK; } else YYERROR; }
| B { if (condition1) { process OK; } else YYERROR; }
| C { if (!condition1) { process OK; } else YYERROR; }
;YYERROR操作触发Yacc的正常错误处理机制。这意味着,就Yacc而言,您的语法必须与操作中的两组规则一起“工作”。如果这会因为shift/reduce (甚至是reduce/reduce)冲突而导致复杂性,那么预处理是可行的。结果语法将变得更小,更有针对性。
发布于 2012-11-02 04:09:09
我的建议是,将条件标志公开为终端符号,我们可以将其称为模式终端。(因此,从技术上讲,它是运行时条件,而不是编译时条件。)
你需要在每一点返回模式terminal,因为它会在解析过程中产生影响。当您的语法接收到额外的值时,可以忽略它。它只能在“条件1”的情况下返回模式终端,也只能在“非条件1”的情况下返回,或者您可以在这两种情况下返回一个不同的模式。假设您有两个标记C1和C2,每个模式一个。
如果你正在解析现有的语法,这可能不会很好地工作,但是如果你同时设计语法和解析器,所有的问题都是可以解决的。
然后你会得到这样的结果:
ruleA : C1 A | C1 B | C2 C ;https://stackoverflow.com/questions/13170812
复制相似问题