对"yylex"的未定义引用

Undefined reference to `yylex'

本文关键字:引用 未定义 yylex      更新时间:2023-10-16

我正在尝试使用 flex 和 bison 解析一个输入文件,但在编译程序时遇到了一个困难。我正在附加我的 flex 和野牛代码以及我得到的错误。

请帮助我解决这些错误

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            "rn"  
QUOTED_PAIR     "\"[^rn]  
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 */  

亚克·

 %{
 #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);     
}  

我使用以下方法构建这些:

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

编译程序时,我发现以下错误:

/

tmp/cceIyDkD.o:在函数"main"中:
yacc.tab.c:(.text+0x708):"主要"
的多重定义 /tmp/ccatq95p.o:lex.yy.c:(.text+0x1228):首先在此处
定义 /usr/bin/ld:警告:符号"main"的大小从/tmp/ccatq95p.o 中的 86 更改为/tmp/cceIyDkD.o
中的 120 /tmp/cceIyDkD.o: 在函数 'yyparse()' 中:
yacc.tab.c:(.text+0x2d6):对"yylex"
的未定义引用 收集2:LD 返回 1 个退出状态

请帮帮我

我有一个类似的问题,事实证明 flex 2.6.x 改变了 yylex 的行为方式。我通过使用旧版本的 Flex 解决了这个问题。在 Ubuntu 中,有一个名为 flex-old 的软件包,它是旧版本。用flex-old替换flex为我解决了这个问题。

  1. 在parser.y中,更准确地说是包含内容的代码的C部分,您需要编写:extern int yylex(void);。不需要 Extern 关键字,因为默认情况下全局函数具有动态连接,但最好编写关键字以指出该函数不是来自您正在处理的文件。但是,您的代码在这里没有错误。

  2. 将lex.yy.c编译为目标文件,将y.tab.c编译为目标文件,然后在最终程序中将它们链接在一起。首先执行yacc命令非常重要,因为 Lex 使用的是使用 Yacc 生成的 yacc.tab.h。你得到错误,因为你弯曲它,但你不知道yacc.tab.h是什么。

    yacc -d yacc.y 制作 y.tab.c

    g++ -c y.tab.c -o y.tab.o 将 y.tab.c 编译为目标文件 y.tab.o

    flex lex.l 制作 lex.yy.c

    g++ -c lex.yy.c -o lex.yy.o 编译 lex.yy.c 到目标文件 lex.yy.o

    g++ lex.yy.o y.tab.o -o program 将它们链接在一起。

注意:确保在 lex 文件中在其他包含之后包含"y.tab.h",因为其他包含可能会使用 y.tab.h 中声明的某些函数,因此请记住这一点。当您编写更复杂的解析器时,可能会发生此类情况。

代码中有一些错误,导致它无法编译。您需要添加到文件 yacc.y 中:

%token <sval> TOK_EMPTY_LINE 

最后:

#include "lex.yy.c"

并以这种方式构建:

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

你会发现它现在编译了。

您可能要注意,我在问题中删除了词法分析器源中的几个拼写错误。并非所有规则都从第一列开始。我删除了几个前导空格,因为它们是错别字。