編集:コード全体。ここで問題となるのは、目標の作成で「:」を使用する必要があることです。これは、おもちゃのc言語の3番地コードを生成するためのコードです。問題の生成IDは、目標から始まります。
私の古いレクサーコードを編集します:
%%
"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
コロンなし:すなわち:-
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
あとはコロンを消したい。