lex和yacc程序将中缀转换为前缀

时间:2016-04-03 08:56:37

标签: compiler-construction yacc lex

我是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);}

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

1 个答案:

答案 0 :(得分:2)

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

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

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

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