修改 我的旧勒克斯代码:
%%
"if" return IF;
"else" return ELSE;
"for" return FOR;
[0-9]+ {strcpy(yylval.dval,yytext);return NUM;}
{CHAR}+({DIGIT}*{CHAR}*)* {strcpy(yylval.dval,yytext);return ID;}
[ \t]+ ;
[\n] return -1;
. {return yytext[0];}
%%
Yacc代码:
%{
#include <stdio.h>
#include <math.h>
int yylex(void);
char p[10]="t",n1[10];
int n =0;
%}
%union
{
char dval[10];
}
%token IF ELSE FOR
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
%token <dval> ID NUM
%type <dval> S E
%type <dval> RO
%%
goal : IF '(' RO ')' {if_label1();} S ';'{if_label2();} ELSE ':' S ';' {if_label3();}
| S
| FOR '(' S ';' {for_label1();} RO ';' {for_label2();} S ')' {for_label3();} S {for_label4();}
;
S : ID '=' E {printf(" %s = %s\n",$$, $3);}
| E
;
E : ID {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s\n",$$,$1);}
| NUM {} {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s\n",$$,$1);}
| E '+' E {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s + %s\n",$$,$1,$3);}
| E '-' E {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s – %s\n",$$,$1,$3);}
| E '*' E {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s * %s\n",$$,$1,$3);}
| E '/' E {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s / %s\n",$$,$1,$3);}
| '(' E ')' {strcpy($$,p);strcat($$,n1);}
RO : E '>' E {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s > %s\n",$$,$1,$3);}
| E '<' E {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s < %s\n",$$,$1,$3);}
| E '==' E {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s == %s\n",$$,$1,$3);}
| E '!=' E {n++;sprintf(n1,"%d",n);strcpy($$,p);strcat($$,n1);printf(" %s = %s != %s\n",$$,$1,$3);}
| E
;
%%
main()
{
yyparse();
}
int yyerror (char *s)
{
}
if_label1()
{
printf("t%d = not t%d\n", n+1, n);
printf("if t%d GOTO L1\n",n+1);
}
if_label2()
{
printf("GOTO L2\n");
printf("L1 :\n");
}
if_label3()
{
printf("L2\n");
}
for_label1()
{
printf("L0:\n");
}
for_label2()
{
printf("t%d = not t%d\n", n+1, n);
printf("if t%d GOTO L1\n",n+1);
printf("GOTO L2:\n");
printf("L3:\n");
}
for_label3()
{
printf("GOTO L0\n");
printf("L2:\n");
}
for_label4()
{
printf("GOTO L3\n");
printf("L1:\n");
}
以上代码的输出:
./a.out
if(a>c)a=b;else:a=c;
t1 = a
t2 = c
t3 = t1 > t2
t4 = not t3
if t4 GOTO L1
t4 = b
a = t4
GOTO L2
L1 :
t5 = c
a = t5
L2
没有冒号:ie: -
goal : IF '(' RO ')' {if_label1();} S ';'{if_label2();} ELSE S ';' {if_label3();}
输出
./a.out
if(a>c)a=d;else d=s;
t1 = a
t2 = c
t3 = t1 > t2
t4 = not t3
if t4 GOTO L1
t4 = d
a = t4
GOTO L2
L1 :
wrong syntax //which is not expected
我想在其他地方消灭结肠。
答案 0 :(得分:2)
我猜你的评论是你的词法分析器将空格作为标记返回到你的解析器,这意味着由于你的语法没有任何空格(' '
)标记,所以带空格的输入不匹配任何东西。
更常见的安排是让词法分析器不返回空格 - 只需忽略它们。所以你有一个lex / flex规则,如:
[ \t\n] ; /* ignore spaces, tabs, and newlines */
当然这只是一个猜测,因为你没有提供有关你的词法分析器或它使用的标记的信息。
修改强>
你还没有发布你的词法分析器代码,但结合下面的flex lexer,你的解析器对我来说很好:
"if" return IF;
"else" return ELSE;
"for" return FOR;
[a-z]+ { strcpy(yylval.dval, yytext); return ID; }
[0-9]+ { strcpy(yylval.dval, yytext); return NUM; }
[ \t\n] ;
. return *yytext;
$ ./a.out
if(a>c)a=d;else d=s;
t1 = a
t2 = c
t3 = t1 > t2
t4 = not t3
if t4 GOTO L1
t4 = d
a = t4
GOTO L2
L1 :
t5 = s
d = t5
L2