我遇到无法解决的问题。我有两个文件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"));
^~~~~~~
当我尝试执行“示例”目标文件时,出现错误:
{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.
]
}
答案 0 :(得分:0)
问题很简单,您在使用yyerror()
函数之前没有声明它。因此,隐式声明返回int
,而您的函数定义为返回void
,这会导致冲突类型错误。
解决方案是,在文件顶部(即此处)声明yyerror()
函数:
%{
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
char *s1, *s2;
char *b1, *b2;
void yyerror(const char *s);
那应该可以解决此错误。
要调试解析错误,可以使用yacc
选项调用-t
并声明变量
int yydebug = 1;
位于文件顶部。然后,解析器将为每个读取的令牌输出状态信息。在这种情况下,问题在于您的词法分析器规则不正确,尤其是正则表达式:
BOOLEAN ["True" "False"]
ARITHMETIC_OPERATORS [+*/-]
OTHER_CHARACTERS [=.(){}\[\]]
TYPES ["Number" "String" "Boolean" "Return"]
应该是
BOOLEAN (True|False)
ARITHMETIC_OPERATORS [+*/-]
OTHER_CHARACTERS [=.()\{\}\[\]]
TYPES (Number|String|Boolean|Return)
flex定义文件有几个可用的示例,它们可能使您了解正则表达式的外观。