这是C编译器的一部分:
Exp :
INTNUMBER { $$ = $1; }
| lvalue { $$ = $1; }
| REALNUMBER { $$ = $1; }
| CHARVALUE { $$ = $1; }
| TRUE { $$ = $1; }
| FALSE { $$ = $1; }
| Exp '+' Exp { $$ = $1 + $3; }
| Exp '*' Exp { $$ = $1 * $3; }
| Exp '/' Exp { $$ = $1 / $3; }
| Exp '-' Exp { $$ = $1 - $3; }
| Exp '%' Exp { $$ = $1 % $3; }
| Exp AND Exp { $$ = $1 && $3; }
| Exp OR Exp { $$ = $1 || $3; }
| Exp LEQ Exp { $$ = $1 <= $3; }
| Exp GEQ Exp { $$ = $1 >= $3; }
| Exp EQ Exp { $$ = $1 == $3; }
| Exp NEQ Exp { $$ = $1 != $3; }
| Exp GE Exp { $$ = $1 > $3; }
| Exp LE Exp { $$ = $1 < $3; }
| '-' Exp %prec UMINUS { $$ = -1 * $2; }
| STRING { $$ = $1; }
| '('Exp')' { $$ = $2; }
| lvalue '=' Exp { $1 = $3; }
| ID'('ExpList')' {printf("Exp");}
;
IDD :
ID { printf("IDD"); }
| IDD '[' Exp ']' {printf("IDD");}
;
ExpList
: { printf("ExpList"); }
ExpPlus {printf("ExpList");}
|
;
ExpPlus :
Exp { printf("Expn"); }
| Exp ',' ExpPlus {printf("ExpPlus");}
;
其中,ID 是一个终端(即在 C 中,ID 可以以 _ 或 [a-zA-Z] 开头。 在使用 -v 标志与 bison 解析此代码时,我遇到了如下移位/减少冲突:
52 IDD: ID .
78 Exp: ID . '(' ExpList ')'
'(' shift, and go to state 56
'(' [reduce using rule 52 (IDD)]
$default reduce using rule 52 (IDD)
到目前为止,我已经解决了我面临的所有转变/减少冲突。但我不明白这个问题应该如何解决。
谢谢
发生冲突本身是因为,在前瞻令牌中看到带有括号(
的ID
后,解析器可以执行移位并开始处理ID ( ExpList )
函数调用语法,或者将ID
减少到IDD
并将(
保留在令牌流中。
这与典型的 LALR 语法中常见的问题相同:
if (exp1)
if (exp2)
stmt;
/**/else /* which "if" does this "else" match?! */
此时(在展望中else
(,解析器可以切换到一个新的状态,将else
绑定到第二个(更深嵌套的(if
,或者将if (exp2) stmt;
减少为与第一个if
一起使用的语句,并将else
留给第一个if
的 else 部分。
类似Yacc的解析器,当遇到移位/减少冲突时,总是支持移位。 在这种情况下,这是我们想要的if
,这也是您想要的语法片段。 所以你不需要处理它。 (但是,我无法判断您的其余语法是否正常,我只评论这一特定部分。 一般来说,转移/减少冲突"按照你期望的方式工作",它减少/减少有问题的冲突。
另请参阅克里斯·多德(Chris Dodd(对改革语法以消除移位的回答,以减少if-then-else中的冲突。
没有足够的信息来解决您的问题 您没有足够的代码来弄清楚您到底要做什么。特别是,我们没有显示IDD和EXP非终端之间的关系
但是,你有
国际长途电话 : 身份证
和
Exp : ID'('ExpList'('
这导致了是否
SomeID
在输入流中是 IDD 或 EXP。