使用yyparse()编译期间的困难(g ++,bison,flex); [英] Difficulties during the compilation (g++, bison, flex) with yyparse();

查看:1189
本文介绍了使用yyparse()编译期间的困难(g ++,bison,flex);的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码编译出现问题:

Flex:

 %{
#includelista4.tab.hpp
#include
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);
返回NUMBER;
}
[ - + / ^ *'%'()] {
return * yytext;
}
\\\
返回RESULT;
%%



Bison:

< pre $ %{
externC
{
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>

使用namespace std;

vector< string>说明;
map<>瓦尔;
%}

%union {
char * text;
int var;
}


%令牌EQ
%令牌NE
令牌ASSIGN $ b $令牌SEMICOLON
令牌IF
%令牌THEN
%令牌< text> IDENTIFIER
%token< var> NUMBER
%token< var>结果
$ b $留下'+'' - '
留下'*''/''%'
%right'^'

% %

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

int main(void){
yyparse();
}



和bash脚本:

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

我在这里发布的只是代码中最重要的部分,因为其余部分在这里不是必需的。无论如何,如果有人想看到整个代码,我把它粘贴在这里: http://pastebin.com/1rS2FBJj。但它有点大,需要更多的地方。

当我试图编译所有的* .c文件,然后通过gcc时,它都很好。但是,当我将编译器切换到g ++并将文件转换为cpp时,我得到以下错误:


$ lista4.tab.cpp:在函数'int yyparse )':
lista4.tab.cpp:1397:警告:不推荐将字符串常量转换为'char *'
lista4.tab.cpp:1540:警告:不推荐将字符串常量转换为'char * '
/tmp/ccdqpQVx.o:在函数`yyparse'中:
lista4.tab.cpp :(。text + 0x252):未定义的对`yylex'的引用
collect2:ld返回1退出状态

任何人都可以给我提示如何解决它?

解决方案

在你的Flex文件中,你声明了这个:

  extern int yylex(); 

当以C ++编译时,它声明一个带有 C ++链接的函数。在你的Bison文件中,你声明了这个:

  externC{
int yylex();
}

给它连接。他们是两种不同的功能。您可以定义 C ++版本(或者Flex为您定义它)​​,但是您声明了C版本,而C版本是编译器认为您尝试的版本打电话给(在野牛生成的代码中)。链接器看到使用了C版本,但它找不到定义。



选择一个链接并一致地使用它。 (我会选择C ++,因为它完全允许从代码中省略extern)。


I have a problem with compilation of my code:

Flex:

%{
#include "lista4.tab.hpp"
#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;
%%

Bison:

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

And bash script:

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

I posted here only the most important part of code, because rest of them is not necessary here. Anyway, if someone would like to see whole code, I pasted it here: http://pastebin.com/1rS2FBJj. But it's a little bigger and takes more place.

When I tried to compile all to *.c files and then by gcc it was all fine. But when I switched compiler to g++ and files to cpp I get this error:

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

Could anyone give me a tip how to fix it?

解决方案

In your Flex file, you declare this:

extern int yylex();

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

extern "C" {
  int yylex();
}

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.

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

这篇关于使用yyparse()编译期间的困难(g ++,bison,flex);的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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