yacc程序将算术表达式转换为后缀

时间:2015-04-16 11:33:50

标签: compiler-construction yacc lex bnf postfix-notation

我是lex和yacc程序的新手。我一直在尝试编写一个yacc程序,它将算术表达式作为输入,并将后缀表示法作为输出。 我使用的语法是: exp:exp + term     |期限     |术语 术语:术语*因子      |期限/因素      |因子 factor:num

这是我的lex代码:

 %{
extern int yylval;
#include "y.tab.h"
%}

%%

[0-9]+  {yylval = atoi(yytext);return INTEGER;}
[ \t\n]     /* skip whitespace */
.   {return *yytext;}
%%

int yywrap(void) {
return 1;
}

这是我的yacc计划:

%{
#include<stdio.h>
%}
%token INTEGER
%left '+' '-'
%left '*' '/'
%%

E:  E '+' T  {printf("+");}
    | E '-' T {printf("-");}
    | T     
    ;

T:  T '*' F   {printf("*");}
    | T '/' F {printf("/");}
    | F
    ;     

F:  '(' E ')'
    | INTEGER {printf("%d",yylval);}
    ;   

%%

int main(){
    yyparse();
}

int yyerror (char *msg) {
    return printf ("error YACC: %s\n", msg);
}

但是这段代码正确编译。但是如果在表达式中使用'+'或' - ',则输出不正确 例如输入:2 + 3             输出:23(而不是23+) 请帮我找出代码中的错误。 谢谢。

3 个答案:

答案 0 :(得分:2)

如果您输入 2 + 3 ,仅此而已,解析器并不知道您打算将其作为完整表达式。它可能是表达 2 + 3 * 4 的开始。所以解析器就坐在那里等待更多的输入。

尝试在你的语法中添加一个结束表达式标记,例如分号。

答案 1 :(得分:0)

\ n {return(0); }

只需在你的lex文件的代码规则部分添加这一行:)

答案 2 :(得分:-1)

中缀和后缀符号是以不同顺序行走AST的结果。因此,您必须首先构建AST,以便在完成AST之后以所选顺序行走。

在语义操作中,您必须创建指向它们所包含的节点的节点。然后在完成后走树:

%start start

%%

start: E { walk_post_order($1); }