Undefined reference to `yylex'

14,026

Solution 1

I had a similar problem, it turns out that flex 2.6.x changed the way yylex behaves. I solved this problem by using an older version of Flex. In Ubuntu, there's this package called flex-old that is that older version. Replacing flex by flex-old solved this problem for me.

Solution 2

You have some errors in the code which stop it from compiling. You need to add into the file yacc.y:

%token <sval> TOK_EMPTY_LINE 

and at the end:

#include "lex.yy.c"

and build this way:

flex bas.l 
bison -d yacc.y 
g++ yacc.tab.c -lfl -o scanner.exe 

You will find it now compiles.

You may want to note I removed a couple of typos in your lexer source in the question. Not all the the rules started in the first column. I removed a couple of leading spaces on the basis that they were typos.

Solution 3

  1. In parser.y, more precisely C part of the code where you include stuff, you need to write: extern int yylex(void);. Extern keyword is not needed, because global functions by default have dynamic connectivity, but it is good practice to write keyword to point that function is not from that file you're working. Your code has no mistake here however.

  2. Compile lex.yy.c to the object file, compile y.tab.c to object file and then link them together in final program. It is very important to first do yacc command, because Lex is using yacc.tab.h generated with Yacc. You're getting error because you flex it, but you don't know what yacc.tab.h is.

    yacc -d yacc.y Make y.tab.c

    g++ -c y.tab.c -o y.tab.o Compile y.tab.c to object file y.tab.o

    flex lex.l Make lex.yy.c

    g++ -c lex.yy.c -o lex.yy.o Compile lex.yy.c to object file lex.yy.o

    g++ lex.yy.o y.tab.o -o program Link them together.

Note: Make sure that in your lex file you include "y.tab.h" after other includes, because it is possible that other includes use some function declared in y.tab.h, so have that in mind. Situations like this can occur when you're writing more complex parsers.

Share:
14,026
shailavi shah
Author by

shailavi shah

Updated on June 23, 2022

Comments

  • shailavi shah
    shailavi shah almost 2 years

    I am trying to parse one input file using flex and bison but I am facing one difficulty while compiling my program. I am attaching my flex and bison code and error which I am getting.

    Please help me out to solve these errors

    lex.l

    %{
     #include <iostream>  
     #include <stdio.h>
    #include "yacc.tab.h"
     #define YY_DECL extern "C" int yylex()
    
    using namespace std;  
    
    
    %}
    
    DOT             "."  
    COLON           ":"  
    SEMICOLON       ";"  
    COMMA           ","  
    ANGLE_LEFT      "<"  
    ANGLE_RIGHT     ">"  
    AT              "@"  
    EQUAL           "="  
    SQUARE_OPEN     "["  
    SQUARE_CLOSE    [^\\]"]"  
    OPENBRACE       "\("  
    CLOSEBRACE      "\)"  
    QUOTE           "\""  
    QUOTE_OPEN      "\""  
    QUOTE_CLOSE     [^\\]"\""  
    SPACE           " "  
    TAB             "\t"  
    CRLF            "\r\n"  
    QUOTED_PAIR     "\\"[^\r\n]  
    DIGIT           [0-9]  
    ALPHA           [a-zA-Z]  
    QTEXT           [0-9a-zA-Z!#$%&'()*+,\-.\/:;<=>?@\[\]^_`{|}~]  
    
    %%
    
    [a-zA-Z0-9]+            { yylval.sval = strdup(yytext); return TOK_STRING; }
    
    {SPACE}*                    {return TOK_SPACE; }
    
    {SPACE}*Name.*              {return TOK_NAME; }  
    {SPACE}*SIZE.*              {return TOK_SIZE; }  
    {SPACE}*ITERATE.*           {return TOK_ITERATE; }  
    {SPACE}*DIRECTION.*     {return TOK_DIRECTION; }  
    
    ^{CRLF}                         { return TOK_EMPTY_LINE; }  
    {CRLF}                          {}  
    .                               {}/* ignore unknown chars */  
    

    yacc.y

     %{
     #include <cstdio> 
     #include <cstring>
     #include <iostream>
     #include <stdio.h>
    
    using namespace std;
    
    extern "C" int yylex();  
    extern "C" FILE *yyin;
    
    void yyerror(const char* s);  
    
    
    %}
    
    %union  
    {  
        char* sval;  
    };  
    
    %token <sval> TOK_NAME  
    %token <sval> TOK_SIZE  
    %token <sval> TOK_STRING  
    %token <sval> TOK_ITERATE  
    %token <sval> TOK_DIRECTION  
    
    
    %token TOK_SPACE  
    
    
    %%
    
    str:  
        TOK_SPACE TOK_NAME TOK_SPACE TOK_STRING   
        {  
            cout << "Value:" << $2 << "->" << $4;  
        }  
        ;  
    %%  
    
    int main(void) {  
        FILE * pt = fopen("new file ", "r" );  
        if(!pt)  
        {  
        cout << "Bad Input.Noexistant file" << endl;  
        return -1;  
        }  
        yyin = pt;  
        do  
        {  
            yyparse();  
         }while (!feof(yyin));        
    }  
    void yyerror(const char *s)  
    {  
       cout << "Error. " << s << endl;   
       exit(-1);     
    }  
    

    I build these using:

    flex bas.l 
    bison -d yacc.y 
    g++ lex.yy.c yacc.tab.c -lfl -o scanner.exe 
    

    While compiling program I found following errors:

    /tmp/cceIyDkD.o: In function `main':
    yacc.tab.c:(.text+0x708): multiple definition of `main'
    /tmp/ccatq95p.o:lex.yy.c:(.text+0x1228): first defined here
    /usr/bin/ld: Warning: size of symbol `main' changed from 86 in /tmp/ccatq95p.o to 120 in /tmp/cceIyDkD.o
    /tmp/cceIyDkD.o: In function `yyparse()':
    yacc.tab.c:(.text+0x2d6): undefined reference to `yylex'
    collect2: ld returned 1 exit status

    Please help me out