2
votes

When I execute the command yacc -dv c2p.y on my c2p.y yacc file the error $1 of `...' has no declared type in Bison/Yacc occurs several times.

What I know is that I have to add a %type something, and delete $1.string but it still doesn't work.

Can you please help solve this error ?

Here is my initial code:

%{
#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 

Thank you, Horatiu

1

1 Answers

3
votes

You need to add a type to the declarations of tokens with semantic values, like this:

%token <string> TYPE_