I'm trying to implement a programming language using lex and yacc. I have build the tokens, grammar(plus semantic actions) and 3 address code representation. I am trying to compile my files using:
yacc --defines=yaccWithSemanticAnd3AD.tab.h parser.y
flex lexer.l
gcc -O2 y.tab.c lex.yy.c -ll
However, I'm getting this error in result. I am not sure what is the cause of it:
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
I am trying to compile it on Windows. Following are my lex (lexer.l) and yacc (parser.y) files:
lexer.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);
}
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
{
s1 = $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
{
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 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;
}
|
TRUE
{
printf("Inside TRUE\n");
ret = (char *)malloc(20);
ret[0] = 0;
strcat(ret,"\ngoto TRUE");
$$ = ret;
}
|
FALSE
{
printf("Inside False\n");
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 : %s\n",$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;
}
|
NUMBER
{
printf("Inside Number : \n");
printf("Inside Number : %f\n", $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);
}
How to get rid of this error and successfully compile the code? Is there something wrong in any of these files? Any help will be appreciated. Thanks.
-ll
library (it's looking forlibl.a
orlibl.dll
, given that you're on Cygwin; it might be looking forlibl.so
). That library either hasn't been installed or isn't needed. Step 1: try linking without the-ll
option. Step 2: if step 1 fails, then you'll need to find how to install it. It normally comes withlex
, but you're building withflex
which doesn't need that, IIRC. Actually, if you provideyywrap()
, I don't think you need-ll
with Lex, again IIRC. – Jonathan Leffler-ll
, as you are provide your ownmain()
. Just remove it, – user207421