当我在我的c2p.y yacc文件上执行命令yacc -dv c2p.y时,错误$ 1的“...”在Bison / Yacc中没有声明类型多次出现。
我所知道的是我必须添加%类型的东西,并删除$ 1.string但它仍然不起作用。
你能帮忙解决一下这个错误吗?
这是我的初始代码:
%{ #include #include int func; char* ch; int mainf=-1; %} %start prog %token MAIN_ %token PRINTF_ %token STRING_ %token TYPE_ %token ID_ %token IF_ %token COND_ %token ELSE_ %token FOR_ %token WHILE_ %token DO_ %token UNTIL_ %token ATRIB_ %token PLUSPLUS_ %union { char* string; }; %% prog: funcs ; funcs: | func funcs ; func: head block ; head: TYPE_ MAIN_ '(' args ')' {mainf++;} | TYPE_ {if(!strcmp($1.string, "void")) {func = 0; printf("\n\nprocedure "); } else { func = 1; printf("\n\nfunction ");} } ID_ '(' {printf("%s(", $3.string);} args ')' {printf(")"); if(func == 1) transRetType($1.string); else printf(";");} ; args: | TYPE_ ID_ {translateType($1.string, $2.string);} args | TYPE_ ID_ ',' {translateType($1.string, $2.string);printf("; ");} args ; block: | '{' {if(mainf==0) { printf("\n\nBEGIN");mainf--;} else printf("\nbegin"); } called_funcs '}' { if(t_main == 0) printf("\nEND."); else printf("\nend;");} | '{' decvars {printf("\nbegin");} called_funcs '}' {printf("\nend"); if(t_main == 0) printf("."); else printf(";");} ; decvars: {printf("\nvar ");} listdecl ; listdecl: decl | listdecl decl ; decl: TYPE_ listvars ';' { transRetType($1.string);} ; listvars: ID_ {printf("%s", $1.string);} | ID_ ',' listvars {printf(", %s", $1.string);} ; called_funcs: | block | called_func called_funcs ; called_func: printf | if | func_apel | for | while | do | atrib | inc ; inc: ID_ PLUSPLUS_ ';' {printf("%s = %s + 1 ;",$1,$1);} ; expr: ID_ {printf("%s",$1);} | expr '+'{printf("+");} expr | expr '-'{printf("-");} expr | expr '*'{printf("*");} expr | expr '/'{printf(" div ");} expr | expr '%'{printf(" mod ");} expr | '-'{printf("- ");} expr | '('{printf("(");} expr ')'{printf(")");} ; for: FOR_ {printf("\nfor ");} '(' ID_ {printf("%s :=", yylval.string);} ATRIB_ ID_ {printf("%s to ", yylval.string);} ';' ID_ COND_ ID_ {printf("%s do",yylval.string);} ';' ID_ '+' ')' called_funcs ; while: WHILE_ {printf("\nwhile ");} '(' ID_ {printf("%s", $3);} COND_ { if(!strcmp(yylval.string, "==")) printf("="); else if(!strcmp(yylval.string, "!=")) printf(""); else printf("%s", yylval.string);} ID_ {printf(" %s do", yylval.string);} ')' called_funcs ; do: DO_ {printf("\nrepeat");} called_funcs UNTIL_ {printf("\nuntil ");} '(' ID_ {printf("%s", yylval.string);} COND_ { if(!strcmp(yylval.string, "==")) printf("="); else if(!strcmp(yylval.string, "!=")) printf(""); else printf("%s", yylval.string);} ID_ {printf(" %s ;", yylval.string);} ')' ';' ; atrib: ID_ {printf("\n%s := ",$1);} ATRIB_ expr ';' {printf(";");} | ID_ "++" {printf("\n %s = %s + 1",$1,$1);} | ID_ '--' {printf("\n %s = %s - 1",$1,$1);} ; if: IF_ '(' ID_ {printf("\nif %s", yylval.string);} COND_ {if(!strcmp(yylval.string, "==")) printf("="); else printf("%s", yylval.string);} ID_ {printf(" %s then", yylval.string);} ')' called_funcs else ; else: | ELSE_ {printf("\nelse");} called_funcs ; func_apel: ID_ '(' {printf("\n%s(", $1.string);} call_args ')' ';' {printf(");");} ; call_args: call_args ',' {printf(", ");} call_arg | call_arg ; call_arg: | ID_ {printf("%s", yylval.string);} ; printf: PRINTF_ '(' STRING_ {output(yylval.string);} ')' ';' ; %% void transRetType(char* str) { if(!strcmp(str, "int")) printf(":integer;"); if(!strcmp(str, "long")) printf(":longint;"); if(!strcmp(str, "char")) printf(":byte;"); if(!strcmp(str, "float")) printf(":real;"); } void translateType(char* str1, char* str2) { if(!strcmp(str1, "int")) printf("%s:integer", str2); if(!strcmp(str1, "long")) printf("%s:longint", str2); if(!strcmp(str1, "char")) printf("%s:byte", str2); if(!strcmp(str1, "float")) printf("%s:real", str2); } void output(char* str) { int i; printf("\nwriteln(\""); for(i = 1; i
谢谢你,Horatiu
答案 0 :(得分:3)
您需要为具有语义值的标记声明添加类型,如下所示:
%token <string> TYPE_