Undefined reference to `yylex'

情到浓时终转凉″ 提交于 2019-12-11 00:58:10

问题


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


回答1:


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.




回答2:


  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.



来源:https://stackoverflow.com/questions/34782625/undefined-reference-to-yylex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!