如何修复YACC转变/减少递增运算符的冲突?
-
23-08-2019 - |
题
我正在写在YACC(实际上野牛)语法,并且我有一个移位/降低的问题。这是由于包括后缀增量和减量运算。下面是语法的下调版本:
%token NUMBER ID INC DEC
%left '+' '-'
%left '*' '/'
%right PREINC
%left POSTINC
%%
expr: NUMBER
| ID
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| INC expr %prec PREINC
| DEC expr %prec PREINC
| expr INC %prec POSTINC
| expr DEC %prec POSTINC
| '(' expr ')'
;
%%
野牛告诉我有12换档/减少冲突,但如果我注释掉线,为后缀增量和减量,它工作正常。有谁知道如何解决这个矛盾呢?在这一点上,我考虑搬到一个LL(k)的解析器生成,这使得它更容易,但LALR语法总是显得更自然书写。我也在考虑GLR,但我不知道有什么好的的C / C ++ GLR分析器生成。
解决方案
如果在选项章节指定%glr-parser
野牛/ yacc可以生成一个GLR解析器。
其他提示
尝试这种情况:
%token NUMBER ID INC DEC
%left '+' '-'
%left '*' '/'
%nonassoc '++' '--'
%left '('
%%
expr: NUMBER
| ID
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| '++' expr
| '--' expr
| expr '++'
| expr '--'
| '(' expr ')'
;
%%
的关键是要声明后缀运算符作为的非缔合即可。否则,你将能够
++var++--
在括号还需要给予一优先级以最小化移位/减少警告
我喜欢定义多个项。你不应该需要向左%,%右,%PREC的东西。
simple_expr: NUMBER
| INC simple_expr
| DEC simple_expr
| '(' expr ')'
;
term: simple_expr
| term '*' simple_expr
| term '/' simple_expr
;
expr: term
| expr '+' term
| expr '-' term
;
玩弄此方法
这基本的问题是,你不必为INC
和DEC
令牌的优先级,所以它不知道如何解决涉及INC
或DEC
的前瞻歧义。如果添加
%right INC DEC
在优先级列表的末尾(您想unaries是更高的优先级和后缀比前缀更高),这将修复它,你甚至可以摆脱所有PREINC
/ POSTINC
的东西,因为它是不相关的。
增量和后增量运营商有nonassoc如此限定,在优先级部分并在规则使这些运营商通过使用%prec
高的优先级
不隶属于 StackOverflow