2011-05-22 55 views
2

当我在我的c2p.y yacc文件上执行命令yacc -dv c2p.y时,$ ...的错误$ 1没有声明类型野牛/ 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

谢谢霍拉丘

回答

3

你需要一个类型添加到语义值令牌的声明,就像这样:

%token <string> TYPE_ 
+0

这是正确的,我将添加到%标记,而不是%类型,并修复了它。谢谢。 – 2011-05-22 13:09:07