linux - `...' 的 $1 在 Bison/Yacc 中没有声明类型

标签 linux compiler-construction yacc bison

当我在 c2p.y yacc 文件上执行命令 yacc -dv c2p.y 时,多次出现 $1 of `...' has noclarified type in Bison/Yacc 错误。

我知道我必须添加一个 %type 的东西,并删除 $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 

谢谢你,霍拉蒂乌

最佳答案

您需要将类型添加到具有语义值的标记声明中,如下所示:

%token <string> TYPE_

关于linux - `...' 的 $1 在 Bison/Yacc 中没有声明类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6087925/

相关文章:

c - 尽可能少地制作二进制文件

c++ - 使用不同的编译器输入 char* 时出现奇怪的输出

使用 Bison 的 C 到 Forth 解析器

c++ - (F)莱克斯 : get text not matched by rules/get default output

linux - 在文件夹中的所有文件中插入行号

regex - 如何在 Linux 中指定进程名称中只获取进程 ID?

linux - 有没有办法克服 linux 系统上的端口限制?

linux - 测试ip能ping通,但是只有一个loop就结束了。

c# - 扩展 Mono C# 编译器 : is there any documentation or precedent?

python - 识别 lex 中的关键字对