【问题标题】:yacc program to convert arithmetic expression into postfixyacc程序将算术表达式转换为后缀
【发布时间】:2015-04-16 11:33:50
【问题描述】:

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

这是我的 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+) 请帮助我找出代码中的错误。 谢谢。

【问题讨论】:

  • 您的语法只接受一个表达式。如果在表达式之后关闭输入,它将正确打印。
  • 另请注意,您不需要 T 非终结符,因为您使用运算符优先级指定相同。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    \n { 返回(0); }

    只需将此行添加到 lex 文件中代码的规则部分即可:)

    【讨论】:

    • 为什么?稍微解释一下会很有帮助。
    【解决方案3】:

    中缀和后缀符号是以不同顺序遍历 AST 的结果。因此,您必须从构建 AST 开始,以便在 AST 完成后按照所选顺序运行。

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

    %start start
    
    %%
    
    start: E { walk_post_order($1); }
    

    【讨论】:

    • 这真的不是真的。 OP 发布的操作足以遍历解析树。构建 AST 并不总是必要的:生产编译器没有构建。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多