使用g ++,bison和flex进行编译时,在yyparse()中未定义对yylex的引用 [英] Undefined reference to `yylex' in yyparse() while compiling using g++, bison and flex

查看:337
本文介绍了使用g ++,bison和flex进行编译时,在yyparse()中未定义对yylex的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编译代码(undefined reference to 'yylex')时遇到问题.让我们从片段开始,我将在下面描述细节:

I have a problem while compiling my code (undefined reference to 'yylex'). Let's start off with the snippet and I'll describe the details below:

Flex:

%{
#include <stdlib.h>
extern int yylex();
%}
%%
"=" {return EQ;}
"!="    {return NE;}
"<" {return LT;}
">" {return GT;}
":="    {return ASSIGN;}
";" {return SEMICOLON;}
"IF"    {return IF;}
"THEN"{return THEN;}

"END" {return END;}
[_a-z]+ {yylval.text = strdup(yytext); return IDENTIFIER;}
[ \t]+
[0-9]+          {
                yylval.var = atoi (yytext);
                return NUMBER;
                }
[-+/^*'%'()]    {
                return *yytext;
                }
\n              return RESULT;
%%

野牛:

%{
  extern "C"
  {
    int yyparse();
    int yylex(void);
    void yyerror(char *s){}
    int yywrap(void){return 1;}
  }

  #include <iostream>
  #include <vector>
  #include <string>
  #include <stdlib.h>
  #include <map>

  using namespace std;

  vector <string> instructions;
  map <> vars;
%}

%union{
  char* text;
  int var;
}


%token EQ
%token NE
%token ASSIGN
%token SEMICOLON
%token IF
%token THEN
%token <text> IDENTIFIER
%token <var> NUMBER
%token <var> RESULT

%left '+' '-'
%left '*' '/' '%'
%right '^'

%%

exp: NUMBER
| IDENTIFIER
| IDENTIFIER "+" IDENTIFIER
| IDENTIFIER "-" IDENTIFIER
;
%%

int main(void){
  yyparse();
} 

这是我用来编译&的bash脚本.运行程序:

And here's the bash script I use to compile & run the program:

#!/bin/bash
clear
rm launcher lex.yy.cpp *.tab.cpp *.tab.hpp
bison  -d -o list.tab.cpp *.y
flex -o lex.yy.cpp *.l
g++ -o launcher *.cpp -lfl

仅出于清晰可见性,我仅在此处发布代码的最重要部分,因为其余部分在这里并不是必需的.无论如何,如果有人想看完整的代码,请在此处发布: http://pastebin.com/1rS2FBJj.这是更大的代码块,但是占用的空间更大.

Just for clear visibility, I'm posting here only the most important part of the code, because the rest is not really necessary here. Anyway, if someone would like to see the whole code, it's posted here: http://pastebin.com/1rS2FBJj. It's a bigger chunk of code and takes more place though.

当我尝试将所有文​​件编译为* .c文件,然后使用gcc时,一切都很好.但是,当我尝试将编译器切换为g ++并因此将文件切换为cpp时,我一直收到此错误:

When I try to compile all files to *.c files and then use gcc, it is all fine. But when I attempt to switch the compiler to g++ and therefore the files to cpp ones, I keep getting this error:


list.tab.cpp: In function ‘int yyparse()’:
list.tab.cpp:1397: warning: deprecated conversion from string constant to ‘char*’
list.tab.cpp:1540: warning: deprecated conversion from string constant to ‘char*’
/tmp/ccdqpQVx.o: In function `yyparse':
list.tab.cpp:(.text+0x252): undefined reference to `yylex'
collect2: ld returned 1 exit status

任何人都可以给我一个提示,最好的方法是什么?

Could anyone give me a hint please, how would be the best to approach it?

推荐答案

在您的Flex文件中,您需要声明以下内容:

In your Flex file, you declare this:

extern int yylex();

当编译为C ++时,它声明具有 C ++链接的函数.在您的Bison文件中,您声明以下内容:

When compiled as C++, that declares a function with C++ linkage. In your Bison file, you declare this:

extern "C" {
  int yylex();
}

这使它具有 C链接.它们是两个不同的功能.您定义 C ++版本(或者,Flex为您定义了它),但是您声明 C版本,而C版本是编译器认为您尝试的版本.调用(在Bison生成的代码中).链接器看到使用了C版本,但是找不到该定义.

That gives it C linkage. They're two different functions. You define the C++ version (or, rather, Flex defines it for you), but you declare the C version, and the C version is the one the compiler thinks you try to call (in the Bison-generated code). The linker sees that the C version is used, but it cannot find the definition.

选择一个链接并持续使用它. (我会选择C ++,因为它允许完全省略代码中的外部"内容.)

Pick one linkage and use it consistently. (I'd choose C++, since it allows omission of the "extern" stuff from the code entirely.)

这篇关于使用g ++,bison和flex进行编译时,在yyparse()中未定义对yylex的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆