0
votes

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.

1
The loader can't find the -ll library (it's looking for libl.a or libl.dll, given that you're on Cygwin; it might be looking for libl.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 with lex, but you're building with flex which doesn't need that, IIRC. Actually, if you provide yywrap(), I don't think you need -ll with Lex, again IIRC.Jonathan Leffler
You don't need -ll, as you are provide your own main(). Just remove it,user207421

1 Answers

1
votes

The commands for building that you have used are generally correct for systems running MacOS and Linux, but do not use the same library name on a Windows platform with windows or MinGW. For that the library is indicated by -lfl:

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

However, as already indicated in the comments, when you provide your own main program you generally don't need the flex library and can just remove the -ll altogether.