我正在尝试在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;
}
答案 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