使用yyparse进行编译g ++,bison,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;
%%
野牛:
%{
  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脚本:
#!/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
我只在这里发布了代码中最重要的部分,因为在这里没有必要其余部分。无论如何,如果有人想看完整的代码,我将其粘贴在这里: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文件中,您声明:
extern \"C\" {
  int yylex();
}
这给了它C链接。它们是两个不同的功能。您定义了C ++版本(或者说,Flex为您定义了它),但是您声明了C版本,而C版本是编译器认为您尝试调用的版本(在Bison生成的代码中)。链接器看到使用了C版本,但是找不到该定义。 选择一个链接并持续使用它。 (我会选择C ++,因为它允许完全省略代码中的“外部”内容。)