Flex, Bison, C++ - 编译错误
Flex, Bison, C++ - compile error
我想做一个程序,为函数创建解析树。例如:"f(g(x,h(y),v,k(l(c))))"可能是有效的函数调用。
h1.l
%{
#include <iostream>
#include <list>
using namespace std;
#include "h1.tab.hpp"
%}
%option noyywrap
%option c++
%%
[a-z][a-zA-z0-9]* { yylval.s = yytext; return (TERM_ID); }
"(" { return (OP); }
")" { return (CP); }
";" { return (COMMA); }
%%
h1.ypp
%{
#include <list>
#include <string>
#include <iostream>
using namespace std;
extern "C" int yylex();
extern "C" int yyerror(char *p) { cerr << "Error!" << endl; }
struct ts {
string *name;
list<struct ts*> *plist; /* NULL if the sturcture represents a variable, parameter list if the structure represents a function */
};
%}
%union {
struct ts *t;
list<struct ts *> *tl;
char *s;
}
%token <s> TERM_ID
%token OP CP COMMA
%type <tl> termlist
%type <t> term
%%
term : TERM_ID OP termlist CP { $$ = new struct ts(); $$->name = new string($1); $$->plist = $3; }
| TERM_ID { $$ = new struct ts(); $$->name = new string($1); $$->plist = NULL; }
;
termlist : termlist COMMA term { $$ = $1; $$->push_back($3); }
| term { $$ = new list<struct ts*>(); $$->push_back($1); }
;
%%
int main()
{
yyparse();
return 0;
}
编译:
$ bison -d h1.ypp
$ flex h1.l
$ g++ h1.tab.cpp lex.yy.cc
h1.tab.cpp: In function ‘int yyparse()’:
h1.tab.cpp:1382: warning: deprecated conversion from string constant to ‘char*’
h1.tab.cpp:1528: warning: deprecated conversion from string constant to ‘char*’
Undefined symbols for architecture x86_64:
"_yylex", referenced from:
yyparse() in ccmRHVKn.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
我对这些工具了解不多,而且我以前从未使用过 cpp。
我应该更改什么才能使这些东西正常工作?
问题是你正在生成一个C++词法分析器类(使用 .l 文件中的%option c++
),而 bison 期待一个 C yylex
函数。 删除%option c++
,改为将extern "C" int yyex();
添加到.l
文件的顶部(或从.y
文件中删除extern "C"
),一切都应该没问题。
您正在生成一个C++ yylex
,然后在解析器中将其声明为extern "C"
。C++函数和 C 函数没有相同的名称(即使它们看起来相同),因此链接器找不到yylex
(或_yylex
,因为它实际上被称为。
从两个声明中删除外部"C",它可能会链接。
你应该将%union
中的char* s
更改为std::string* s
;否则,你会遇到初学者最常见的野牛/flex问题之一:yytext
指向的C字符串仅在下次调用yylex
之前有效,因此当野牛开始使用指针时,它指向不同的字符串。
因此,您需要在词法分析器中复制yytext
,而不是在解析器中。因此,在词法分析器中,您将执行以下操作:
yylval.s = new std::string(yytext);
在你的语法中,你会这样做(例如):
term : TERM_ID OP termlist CP {
$$ = new struct ts();
$$->name = $1; // <-- Here is the change
$$->plist = $3;
}
相关文章:
- std::is_base_of表示ctor编译错误
- Qt5:使用QCommandLineParser类时出现奇怪的编译错误
- 如何修复sfml c++代码编译错误
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- vscode下的Arduino代码出现意外编译错误
- 第三方 API 中的编译错误 - Visual Studio
- std::cout输出int时出现编译错误
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 提升图广度优先搜索前置编译错误
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 我在C++中遇到了这个奇怪的编译错误
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- 现代OpenGL和GLEW Libraray的编译错误
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- C ++程序编译错误,找不到/访问文件
- 使用直接大括号初始化时,C++ 编译错误"声明末尾的预期";"
- 为什么传递非静态成员函数会导致编译错误?