我有一个无法解决的问题。我有两个文件lexer.l和parser.y(用于令牌和语法+三个地址代码)。我正在使用以下命令在Linux上编译文件:
yacc -d parser.y lex lexer.l
这给了我lex.yy.c和y.tab.c和y.tab.h文件。
但是,当我尝试将它们一起编译为示例文件时,我试图为其构建(input.txt)的语言,例如:
gcc y.tab.c lex.yy.c -lfl -o example
我收到以下警告:
parser.y:963:6: warning: conflicting types for ‘yyerror’ void yyerror(const char *s) { ^~~~~~~ y.tab.c:2333:7: note: previous implicit declaration of ‘yyerror’ was here yyerror (YY_("syntax error")); ^~~~~~~
[当我尝试执行'example'对象文件时,出现错误:
{EEK, parse error! Message: syntax error
它显示程序陷入在parser.y中创建的yyerror函数中(在底部)。我不确定为什么它在y.tab.c文件中弄乱了。我想要的是成功执行示例(input.txt)的“示例”对象文件。但是我猜该程序似乎陷入了yyerror中。我也是使用lex和yacc的新手。有办法摆脱这个错误吗?任何帮助将不胜感激。谢谢。
lexer.l
/*Lex File*/ %{ #include <stdio.h> #include <string.h> #include "y.tab.h" char c; %} DIGIT [0-9]+ NUMBER [+-]?[0-9]+|[+-]?[0-9]*"."[0-9]+ STRING \"(\\.|[^\"])*\" BOOLEAN ["True" "False"] ID [a-zA-Z_][0-9a-zA-Z_]* FLOAT [0-9]+[.][0-9]* ARITHMETIC_OPERATORS ['+' '-' '*' '/'] OTHER_CHARACTERS ['=' '.' '(' ')' '{' '}' '[' ']'] TYPES ["Number" "String" "Boolean" "Return"] %% [ \t] ; [\n] ; "If" { return (IF); } "Else" { return (ELSE); } "While" { return (WHILE); } "Main()" {return (MAIN); } "Read()" {return (READ);} "Class" {return (CLASS);} "Number" {return (TYPES);} "String" {return (TYPES);} "Boolean" {return (TYPES);} "Print" {return (PRINT);} "Return" {return (TYPES);} "<!--".*"--!>" ; ">" {yylval.sval = strdup(yytext); return (REL_OPT);} "<" {yylval.sval = strdup(yytext); return (REL_OPT);} ">=" {yylval.sval = strdup(yytext); return (REL_OPT);} "<=" {yylval.sval = strdup(yytext); return (REL_OPT);} "!=" {yylval.sval = strdup(yytext); return (REL_OPT);} "==" {yylval.sval = strdup(yytext); return (REL_OPT);} "|" {yylval.sval = strdup(yytext); return (OR);} "&" {yylval.sval = strdup(yytext); return (AND);} "!" {yylval.sval = strdup(yytext); return (NOT);} {NUMBER} { yylval.nval = atof(yytext); return NUMBER; } {BOOLEAN} { yylval.sval = yytext; return BOOLEAN; } {STRING} { yylval.sval = yytext; return STRING; } {ID} { yylval.sval = strdup(yytext); return ID; } {ARITHMETIC_OPERATORS} { c = yytext[0]; return(c); } {OTHER_CHARACTERS} { c = yytext[0]; return(c); } %%
parser.y
/*Yacc File with semantics*/ %{ #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> char *s1, *s2; char *b1, *b2; struct exprType{ char *addr; char *code; }; int n=1; int nl = 1; char *var; char num_to_concatinate[10]; char num_to_concatinate_l[10]; char *ret; char *temp; char *label; char *label2; char *check; char *begin; struct exprType *to_return_expr; char * newTemp(){ char *newTemp = (char *)malloc(20); strcpy(newTemp,"t"); snprintf(num_to_concatinate, 10,"%d",n); strcat(newTemp,num_to_concatinate); n++; return newTemp; } char * newLabel(){ char *newLabel = (char *)malloc(20); strcpy(newLabel,"L"); snprintf(num_to_concatinate_l, 10,"%d",nl); strcat(newLabel,num_to_concatinate_l); nl++; return newLabel; } %} %start startSym %union { float nval; char *sval; struct exprType *EXPRTYPE; } %token <nval> NUMBER %token <sval> BOOLEAN %token <sval> STRING %token <sval> READ %token <sval> PRINT %token <sval> ID IF ELSE WHILE TYPES REL_OPT OR AND NOT MAIN CLASS TRUE FALSE %token <sval> '+' '-' '*' '/' '\n' '=' '.' %type <sval> list text construct block dec bool program startSym %type <EXPRTYPE> expr stat %left OR %left AND %left NOT %left REL_OPT %right '=' %left '+' '-' %left '*' '/' '%' %% startSym: program { s1 = $1; label = newLabel(); check = strstr(s1, "NEXT"); while(check != NULL) { strncpy(check, label, strlen(label)); strncpy(check + strlen(label)," ", (4 - strlen(label))); check = strstr(s1, "NEXT"); } ret = (char*) malloc(strlen(s1) + 10); ret[0] = 0; strcat(ret, s1); strcat(ret, "\n"); strcat(ret, label); strcat(ret, "3AD ends here\n"); printf("\nIntermediate code:\n"); puts(ret); $$ = ret; } ; program : program construct { s1 = $1; s2 = $2; label = newLabel(); check = strstr(s1, "NEXT"); while(check != NULL) { strncpy(check, label, strlen(label)); strncpy(check + strlen(label), " ", (4 - strlen(label))); check = strstr(s1, "NEXT"); } ret = (char*) malloc(strlen($1) + strlen($2) + 4); ret[0] = 0; strcat(ret, $1); strcat(ret, "\n"); strcat(ret, label); strcat(ret, " : "); strcat(ret, $2); printf("Program construct\n"); puts(ret); $$ = ret; } | construct { printf("Final construct \n"); puts($1); $$ = $1; } | list { printf("Final list \n"); puts($1); $$ = $1; } ; construct : block { $$ = $1; } | WHILE '(' bool ')' block { printf("Inside WHILE\n"); puts($5); b1 = $3; s1 = $5; begin = newLabel(); label = newLabel(); check = strstr(b1, "TRUE"); while(check!=NULL){ strncpy (check,label,strlen(label)); strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"TRUE"); } check = strstr (b1,"FAIL"); while(check!=NULL){ strncpy (check,"NEXT",4); //strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"FAIL"); } check = strstr (s1,"NEXT"); while(check!=NULL){ strncpy (check,begin,strlen(begin)); strncpy (check+strlen(begin)," ",(4-strlen(begin))); check = strstr (s1,"NEXT"); } ret = (char *)malloc(strlen(b1)+strlen(s1)+20); ret[0] = 0; strcat(ret,begin); strcat(ret," : "); strcat(ret,b1); strcat(ret,"\n"); strcat(ret,label); strcat(ret," : "); strcat(ret,s1); strcat(ret,"\n"); strcat(ret,"goto "); strcat(ret,begin); printf("Final return from WHILE\n"); puts(ret); $$ = ret; } | IF '(' bool ')' block { printf("Inside IF\n"); label = newLabel(); b1 = $3; check = strstr (b1,"TRUE"); while(check!=NULL){ strncpy (check,label,strlen(label)); strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"TRUE"); } check = strstr (b1,"FAIL"); while(check!=NULL){ strncpy (check,"NEXT",4); //strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"FAIL"); } ret = (char *)malloc(strlen(b1)+strlen($5)+4); ret[0] = 0; strcat(ret,b1); strcat(ret,"\n"); strcat(ret,label); strcat(ret," : "); strcat(ret,$5); puts(ret); $$ = ret; } | IF '(' bool ')' block ELSE block { printf("Inside IF then ELSE\n"); b1 = $3; label = newLabel(); check = strstr (b1,"TRUE"); while(check!=NULL){ strncpy (check,label,strlen(label)); strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"TRUE"); } label2 = newLabel(); check = strstr (b1,"FAIL"); while(check!=NULL){ strncpy (check,label2,strlen(label2)); strncpy (check+strlen(label2)," ",(4-strlen(label2))); check = strstr (b1,"FAIL"); } ret = (char *)malloc(strlen(b1)+strlen($5)+strlen($7)+20); ret[0] = 0; strcat(ret,b1); strcat(ret,"\n"); strcat(ret,label); strcat(ret," : "); strcat(ret,$5); strcat(ret,"\n"); strcat(ret,"goto NEXT"); strcat(ret,"\n"); strcat(ret,label2); strcat(ret," : "); strcat(ret,$7); puts(ret); $$ = ret; } | CLASS ID block { $$ = $3; } ; block: '{' list '}' { printf("Inside class block\n"); $$ = $2; } | '{' construct '}' { $$ = $2; } | '[' list ']' { printf("Inside specific block\n"); $$ = $2; } | '[' construct ']' { $$ = $2; } ; list: stat { $$ = $1->code; } | list stat { ret = (char*) malloc(strlen($1) + strlen($2->code) + 4); ret[0] = 0; strcat(ret, $1); strcat(ret, "\n"); strcat(ret, $2->code); printf("Inside list stat \n"); puts(ret); $$ = ret; } | list error '\n' { yyerrok; } | MAIN block { $$ = $2; } ; stat: '.' { to_return_expr = (struct exprType*) malloc(sizeof(struct exprType)); to_return_expr->addr = (char *) malloc(20); to_return_expr->addr = $1; to_return_expr->code = (char*) malloc(2); to_return_expr->code[0] = 0; $$ = to_return_expr; } | expr '.' { $$ = $1; } | dec '.' { to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = $1; to_return_expr->code = (char *)malloc(2); to_return_expr->code[0] = 0; $$ = to_return_expr; } | text '=' expr '.' { printf("Assignment statement \n"); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = newTemp(); ret = (char*)malloc(20); ret[0] = 0; strcat(ret, $1); strcat(ret, "="); strcat(ret, $3->addr); printf("RET = \n"); puts(ret); temp = (char*) malloc(strlen($3->code) + strlen(ret) + 6); temp[0] = 0; if($3->code[0] != 0) { strcat(temp, $3->code); strcat(temp, "\n"); } strcat(temp, ret); printf("TEMP = \n"); puts(temp); to_return_expr->code = temp; $$ = to_return_expr; } | dec '=' expr '.' { printf("Dec and Assignment statement \n"); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = newTemp(); ret = (char *)malloc(20); ret[0] = 0; strcat(ret,$1); strcat(ret,"="); strcat(ret,$3->addr); printf("RET = \n"); puts(ret); temp = (char *)malloc(strlen($1)+strlen($3->code)+strlen(ret)+6); temp[0] = 0; if ($3->code[0]!=0){ strcat(temp,$3->code); strcat(temp,"\n"); } strcat(temp,ret); printf("TEMP = \n"); puts(temp); to_return_expr->code = temp; $$ = to_return_expr; } ; dec : TYPES text { $$ = $2; } ; bool : expr REL_OPT expr { printf("Inside rel opt\n"); temp = (char *)malloc(strlen($1->code)+strlen($3->code)+50); temp[0] = 0; if($1->code[0]!=0){ strcat(temp,$1->code); strcat(temp,"\n"); } if($3->code[0]!=0){ strcat(temp,$3->code); strcat(temp,"\n"); } ret = (char *)malloc(50); ret[0] = 0; strcat(ret,"if("); strcat(ret,$1->addr); strcat(ret,$2); strcat(ret,$3->addr); strcat(ret,") goto TRUE \n goto FAIL"); strcat(temp,ret); $$ = temp; } | bool OR bool { printf("Inside OR\n"); b1 = $1; b2 = $3; label = newLabel(); check = strstr (b1,"FAIL"); while(check!=NULL){ strncpy (check,label,strlen(label)); strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"FAIL"); } temp = (char *)malloc(strlen(b1)+strlen(b2)+10); temp[0] = 0; strcat(temp,b1); strcat(temp,"\n"); strcat(temp,label); strcat(temp," : "); strcat(temp,b2); $$ = temp; } | bool AND bool { printf("Inside AND\n"); b1 = $1; b2 = $3; label = newLabel(); check = strstr (b1,"TRUE"); while(check!=NULL){ strncpy (check,label,strlen(label)); strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"TRUE"); } temp = (char *)malloc(strlen(b1)+strlen(b2)+10); temp[0] = 0; strcat(temp,b1); strcat(temp,"\n"); strcat(temp,label); strcat(temp," : "); strcat(temp,b2); $$ = temp; } | NOT '(' bool ')' { printf("Inside NOT\n"); b1 = $3; label = "TEFS"; check = strstr (b1,"TRUE"); while(check!=NULL){ strncpy (check,label,strlen(label)); //strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"TRUE"); } label = "TRUE"; check = strstr (b1,"FAIL"); while(check!=NULL){ strncpy (check,label,strlen(label)); //strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"FAIL"); } label = "FAIL"; check = strstr (b1,"TEFS"); while(check!=NULL){ strncpy (check,label,strlen(label)); //strncpy (check+strlen(label)," ",(4-strlen(label))); check = strstr (b1,"TEFS"); } $$ = b1; } | '(' bool ')' { $$ = $2; } ; expr: '(' expr ')' { $$ = $2; } | expr '*' expr { printf("Multiplication : "); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = newTemp(); ret = (char *)malloc(20); ret[0] = 0; strcat(ret,to_return_expr->addr); strcat(ret,"="); strcat(ret,$1->addr); strcat(ret,"*"); strcat(ret,$3->addr); printf("RET = \n"); puts(ret); temp = (char *)malloc(strlen($1->code)+strlen($3->code)+strlen(ret)+6); temp[0] = 0; if ($1->code[0]!=0){ strcat(temp,$1->code); strcat(temp,"\n"); } if ($3->code[0]!=0){ strcat(temp,$3->code); strcat(temp,"\n"); } strcat(temp,ret); printf("TEMP = \n"); puts(temp); to_return_expr->code = temp; $$ = to_return_expr; } | expr '/' expr { printf("Division: "); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = newTemp(); ret = (char *)malloc(20); ret[0] = 0; strcat(ret,to_return_expr->addr); strcat(ret,"="); strcat(ret,$1->addr); strcat(ret,"/"); strcat(ret,$3->addr); printf("RET = \n"); puts(ret); temp = (char *)malloc(strlen($1->code)+strlen($3->code)+strlen(ret)+6); temp[0] = 0; if ($1->code[0]!=0){ strcat(temp,$1->code); strcat(temp,"\n"); } if ($3->code[0]!=0){ strcat(temp,$3->code); strcat(temp,"\n"); } strcat(temp,ret); printf("TEMP = \n"); puts(temp); to_return_expr->code = temp; $$ = to_return_expr; } | expr '+' expr { printf("Addition : "); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); printf("Addition : "); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = newTemp(); ret = (char *)malloc(20); ret[0] = 0; strcat(ret,to_return_expr->addr); strcat(ret,"="); strcat(ret,$1->addr); strcat(ret,"+"); strcat(ret,$3->addr); printf("RET = \n"); puts(ret); temp = (char *)malloc(strlen($1->code)+strlen($3->code)+strlen(ret)+6); temp[0] = 0; if ($1->code[0]!=0){ strcat(temp,$1->code); strcat(temp,"\n"); } if ($3->code[0]!=0){ strcat(temp,$3->code); strcat(temp,"\n"); } strcat(temp,ret); printf("TEMP = \n"); puts(temp); to_return_expr->code = temp; $$ = to_return_expr; } | expr '-' expr { printf("Subtraction : "); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); printf("Subtraction : "); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = newTemp(); ret = (char *)malloc(20); ret[0] = 0; strcat(ret,to_return_expr->addr); strcat(ret,"="); strcat(ret,$1->addr); strcat(ret,"-"); strcat(ret,$3->addr); printf("RET = \n"); puts(ret); temp = (char *)malloc(strlen($1->code)+strlen($3->code)+strlen(ret)+6); temp[0] = 0; if ($1->code[0]!=0){ strcat(temp,$1->code); strcat(temp,"\n"); } if ($3->code[0]!=0){ strcat(temp,$3->code); strcat(temp,"\n"); } strcat(temp,ret); printf("TEMP = \n"); puts(temp); to_return_expr->code = temp; $$ = to_return_expr; } | text { printf("Text : "); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); printf("Text : "); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = $1; to_return_expr->code = (char *)malloc(2); to_return_expr->code[0] = 0; $$ = to_return_expr; } | BOOLEAN { // printf("Inside BOOLEAN : %s\n",$1); printf("Inside BOOLEAN : %s\n",$1); //$$ = $1; var = (char *)malloc(20); snprintf(var, 10,"%s",$1); $$ = var; } | STRING { /*printf("Inside String : "); printf("Inside STRING : %s\n",$1); var = (char *)malloc(20); snprintf(var, 10,"%s",$1); $$ = var;*/ printf("Inside STRING : %s\n",$1); var = (char *)malloc(20); snprintf(var, 10,"%s",$1); $$ = var; //$$ = $1; } | NUMBER { printf("Inside NUMBER : %f\n",$1); //$$ = $1; var = (char *)malloc(20); snprintf(var, 10,"%f",$1); $$ = var; } | READ { /*printf("Inside Read: \n"); to_return_expr = (struct exprType *)malloc(sizeof(struct exprType)); to_return_expr->addr = (char *)malloc(20); to_return_expr->addr = $1; to_return_expr->code = (char *)malloc(2); to_return_expr->code[0] = 0; $$ = to_return_expr;*/ printf("Inside Read: \n"); var = (char *)malloc(20); snprintf(var, 10,"%s",$1); $$ = var; } ; text: ID { printf("Inside Identifier : "); $$ = $1; } ; %% extern int yylex(); extern int yyparse(); extern FILE *yyin; main() { // open a file handle to a particular file: FILE *myfile = fopen("input.txt", "r"); // make sure it is valid: if (!myfile) { printf("I can't open a.snazzle.file!"); return -1; } // set lex to read from it instead of defaulting to STDIN: yyin = myfile; // parse through the input until there is no more: do { yyparse(); } while (!feof(yyin)); } void yyerror(const char *s) { printf("EEK, parse error! Message: "); puts(s); //printf("\n"); // might as well halt now: exit(-1); }
input.txt
Class ABC {
Main() [
Number a = 8.
Return 0.
]
}
我有一个无法解决的问题。我有两个文件lexer.l和parser.y(用于令牌和语法+三个地址代码)。我正在使用以下命令在linux上编译文件:yacc -d parser.y ...
问题很简单,您在使用yyerror()
函数之前没有声明它。因此,隐式声明返回int
,而您的函数定义为返回void
,这将导致conflicting types