C 编译器的移位/减少冲突示例



这是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。

相关内容

  • 没有找到相关文章

最新更新