解决冲突:1 yacc程序中的Shift Reduce

时间:2014-03-19 05:25:04

标签: compiler-warnings yacc

我正在尝试在ubuntu终端执行一个yacc程序,用于表达式2 + 6 * 9.正确的输出应该是56,但我得到2作为输出。请帮助

<i>
%{
#include<stdio.h>
%}
%token DIGIT
%%
S:E'\n' {printf("%d\n",$1);
            return 1;
            }
  ;
E:E'+'T {$$ - $1 + $3;}
  |T
  ;
T:T'*'T {$$ = $1 * $3;}
  |F
  ;
F:'('E')' {$$ = $2;}
  |DIGIT
;
%%
yylex()
{
 int c;
c = getchar();
if(isdigit(c))
{
 yylval = c- '0';
 return DIGIT;
}
return c;
}
main()
{
 printf("enter the expression");
yyparse();
return 0;
}

1 个答案:

答案 0 :(得分:1)

错误输出是由于操作:

E:E'+'T {$$ - $1 + $3;}

这永远不会设置$$的值,因此您从堆栈中获取默认值($1)。将-更改为=以实际分配给$$

留下了转移/减少冲突。您可以使用-v标志来yacc获取y.output中状态机的列表,为您提供有关冲突究竟是什么的更多详细信息。在这种情况下,它来自规则:

T:T'*'T

这是不明确的 - 乘法可以左递归或右递归组合(因此像2*3*4这样的输入可以解析为(2×3)×4或2×(3×4)) 。 defauult移位解析解析左递归(这是正确的),但实际上它与乘法无关是相关的。您可以通过将规则更改为left-recursive来解决冲突:

T:T'*'F