我正在写在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
;

玩弄此方法

这基本的问题是,你不必为INCDEC令牌的优先级,所以它不知道如何解决涉及INCDEC的前瞻歧义。如果添加

%right INC DEC

在优先级列表的末尾(您想unaries是更高的优先级和后缀比前缀更高),这将修复它,你甚至可以摆脱所有PREINC / POSTINC的东西,因为它是不相关的。

增量和后增量运营商有nonassoc如此限定,在优先级部分并在规则使这些运营商通过使用%prec高的优先级

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top