【问题标题】:lex and yacc program to convert infix to prefixlex 和 yacc 程序将中缀转换为前缀
【发布时间】:2016-04-03 08:56:36
【问题描述】:

我是 lex 和 yacc 程序的新手。我一直在尝试编写一个 yacc 程序,该程序将算术表达式作为输入并给出前缀符号作为输出。 这是我的 lex 代码。

%{
#include<string.h>
#include"pre.tab.h"
%}
%%
"*"|"/"|"+"|"-"|"("|")" {return yytext[0];}
[0-9]+ {yylval.name=(char*)malloc(yyleng+1);
   strcpy(yylval.name,yytext);
   return NUM;}
\n {return(0);}
[a-zA-Z][a-zA-Z]* {yylval.name=(char*)malloc(yyleng+1);
      strcpy(yylval.name,yytext);
      return ID;}
. {}
%%
int yywrap()
{
return 1;
}

这是我的 YACC 代码

%{
#include<stdio.h>
#include<string.h>
char buf[10];
%}

%union
{
  char *name;
}
%token<name>NUM ID
%type<name>E 
%left'+''-'
%left'*''/'
%nonassoc UMINUS
%%
S:E  {printf("\n%s",$1);}
;
E:E'*'E {buf[0]='\0';strcpy($$,strcat(strcpy(buf,"*"),strcat($1,$3)));}
|E'/'E {buf[0]='\0';strcpy($$,strcat(strcpy(buf,"/"),strcat($1,$3)));}
|E'+'E {buf[0]='\0';strcpy($$,strcat(strcpy(buf,"+"),strcat($1,$3)));}
|E'-'E {buf[0]='\0';strcpy($$,strcat(strcpy(buf,"-"),strcat($1,$3)));}
|ID
|NUM
|'('E')'{strcpy($$,$2);}
;
%%
main()
{
yyparse();
}
int yyerror(char *s) {fprintf(stderr,"%s\n",s);}

当我在括号中输入算术表达式时,我没有得到任何输出。例如:输入:1+(2*3) 输出:+*23*23。我曾多次尝试纠正代码但徒劳无功。

【问题讨论】:

  • 空格键坏了?你有什么收获吗?语法错误?
  • @EJP 我没有得到任何输出。当我输入 1 + 2 时,命令提示符中没有显示任何内容。我输入1+2时也是这样
  • 查看半标准函数 strdupasprintf,可用于 Linux、Windows、OSX、*BSD 和大多数类 unix 系统...

标签: compiler-construction yacc lex


【解决方案1】:

在 C 中,字符串不会像在其他语言中那样神奇地扩展。 (或者,更好的说法是,真的没有字符串对象。)你不能调用strcat(a, b),除非你已经确保char数组a在NUL终止符后面有足够的空间来附加b

你不能strcat到一个字符串文字,因为不仅没有足够的空间,而且字符串文字可能在只读内存中。

而且您不能 strcpy 到未分配的变量并期望自动分配足够的内存。 (虽然$$ 实际上不是一个未初始化的变量,因为它被初始化为$1 的值。)

所以你的代码充满了缓冲区溢出,这是未定义的行为。

【讨论】:

  • 我更正了上面已更新的代码,但现在出现了一个新错误。输入:1+(2*3) 输出:+*23*23
  • @user46663:当你写strcpy($$, ...)时,$$指向的是什么缓冲区?你分配了吗?你知道里面有多少可用空间吗?您确实需要了解如何在 C 中进行字符串操作才能完成您想做的事情。 (并且请不要在回答后编辑您的问题;这会使答案不正确甚至无关紧要。)
  • 我知道 $$ 指向哪个缓冲区。也许您需要在发表评论之前复习一下您的 Yacc 技能。如果你不知道答案,你不应该含糊其辞。
  • @user46663:所以在生产中'(' E ')' {strcpy($$,$2);},例如$$在规则运行之前已经被$$ = $1初始化,但是$1指的是终端( .这甚至有与之相关的语义值吗?它是否被初始化为任何东西? ... SO 不是“请为我编写代码”服务,我的回答旨在为您指明一个有用的方向。当然,您完全可以忽略它。
  • @user46663: 哦,顺便说一句,在你为某些操作减少 E op E 的情况下,$1 是减少 E:IDE:NUM 的结果,strcat($1, $3) 的缓冲区将由词法分析器使用malloc(yyleng+1) 创建,因此它显然没有任何空间可用于追加。我希望这对你来说足够具体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 2020-04-04
  • 1970-01-01
  • 2013-04-02
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
相关资源
最近更新 更多