Lex 和 yacC语言 无法编译 y.tab.c 文件



我正在尝试使用lex和yacc实现编程语言。我已经构建了令牌,语法(加上语义操作(和3个地址代码表示。我正在尝试使用以下方法编译我的文件:

yacc --defines=yaccWithSemanticAnd3AD.tab.h parser.y
flex lexer.l
gcc -O2 y.tab.c lex.yy.c -ll

但是,结果我收到此错误。我不确定它的原因是什么:

e:/flex windows/gcc/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: cannot find -ll
collect2.exe: error: ld returned 1 exit status

我正在尝试在Windows上编译它。以下是我的lex(lexer.l(和yacc(parser.y(文件:

词法分析器.l

/*Lex File*/
%{
#include <stdio.h>
#include <string.h>
#include<conio.h>
#include<string.h>
#include "yaccWithSemanticAnd3AD.tab.h"
char c;
void removeComment();
void removeWhiteSpace();
%}
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);}
"True"   {return (TRUE);}
"False"  {return (FALSE);}
"Number" {return (TYPES);}
"String" {return (TYPES);}
"Boolean" {return (TYPES);}
"Print"   {return (PRINT);}
"Return"  {return (TYPES);}
"<!"      { removeComment();}
">" {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 = 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);
}
%%
void removeComment()
{
register int c;
while(1)
{
while((c=input())!='!' && c!=EOF);
{
if(c==EOF)
{
exit(1);
}
}
if(c==EOF)
{
exit(1);
}
if((c=input())=='<')
break;
else
unput(c);
}
removeWhiteSpace();
}
void removeWhiteSpace()
{
c=input();
while(c==' '||c=='t'||c=='n')
{
c=input();
}
unput(c);
}

解析器.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 heren");
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 constructn");

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 WHILEn");
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 whilen");
puts(ret);
$$ = ret;
}

|
IF '(' bool ')' block
{
printf("Inside IFn");
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 ELSEn");
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
{
s1 = $3;
}
;
block:  '{' list '}'
{
printf("Inside class blockn");
$$ = $2;
}
|
'{' construct '}'
{
$$ = $2;
}
|
'[' list ']'
{
printf("Inside specific blockn");
$$ = $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
{
s1 = $2;
}
;

stat:    '.'
{
to_return_expr = (struct exprType*) malloc(sizeof(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 optn");
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 ORn");
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 ANDn");
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 NOTn");
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;
}
|
TRUE 
{  
printf("Inside TRUEn");
ret = (char *)malloc(20);
ret[0] = 0;
strcat(ret,"ngoto TRUE");
$$ = ret;

}
| 
FALSE 
{  
printf("Inside Falsen");
ret = (char *)malloc(20);
ret[0] = 0;
strcat(ret,"ngoto FAIL");
$$ = ret;

}
;
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));
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));
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));
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 : %sn",$1);
var = (char *)malloc(20);
snprintf(var, 10,"%s",$1);
$$ = var;
}
|
STRING
{
printf("Inside String : ");
printf("Inside STRING : %sn",$1);
var = (char *)malloc(20);
snprintf(var, 10,"%s",$1);
$$ = var;
}
|
NUMBER
{
printf("Inside Number : n");
printf("Inside Number : %fn", $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;
}
;
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);
}

如何摆脱此错误并成功编译代码?这些文件是否有问题?任何帮助将不胜感激。谢谢。

您使用的用于构建的命令对于运行MacOS和Linux的系统通常是正确的,但不要在Windows或MinGW的Windows平台上使用相同的库名称。为此,库由-lfl表示:

yacc --defines=yaccWithSemanticAnd3AD.tab.h parser.y
flex lexer.l
gcc -O2 y.tab.c lex.yy.c -lfl

但是,正如注释中已经指出的,当您提供自己的main程序时,您通常不需要 flex 库,只需完全删除-ll即可。

最新更新