来自字符串向量的 Bison 输入
Bison input from string vector
我有一个字符串向量,我想在 bison 中解析它。我应该远程接收这个,我不想写入文件并读回。我的字符串向量可以很大。
这是我到目前为止尝试过的方法
将所有字符串加到一个字符串中并使用yy_scan_string
我还尝试将所有字符串添加到缓冲区和 yy_scan_string。
我尝试按如下方式构建可执行文件:
bison -d logic.y
flex logic.l
g++ logic.tab.c lex.yy.c -lfl -o logic
但我收到错误消息:
undefined reference to `yy_scan_string'.
这是我的解析器:
%{
#include <cstdio>
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
#include <Server.h>
using namespace std;
//stuff from flex that bison needs to know about:
extern "C" int yylex();
typedef struct yy_buffer_state * YY_BUFFER_STATE;
extern "C" int yyparse();
extern "C" YY_BUFFER_STATE yy_scan_string(const char * str);
//extern "C" void yy_delete_buffer(YY_BUFFER_STATE buffer);
extern int line_num;
vector<string> statements;
void yyerror(const char *s);
%}
//C union holding each of the types of tokens that Flex could return
%union {
char const *sval;
}
//symbol defination
//end of declaration section
%%
//Start of grammar section
//grammar
//end of grammar section
%%
int main(int argc, char *argv[]) {
try
{
logicMessage = server.getLogic();
statements = logicMessage->get_LogicStatements ();
string single = "";
for (vector<string>::iterator it=statements.begin(); it!=statements.end(); ++it)
single += *it;
char* buffer = new char[single.length()+1];
strcpy(buffer,single.c_str());
yy_scan_string(single.c_str());
yyparse();
//yy_delete_buffer(buffer);
return 0;
}
catch(IPC_RETURN_CODE IPC_CODE)
{
std::cerr<< "IPC Error Code:" <<IPC_CODE;
}
}
void yyerror(const char *s) {
cout << "Parse error on line " << line_num << "! Message: " << s << endl;
// might as well halt now:
exit(-1);
}
我读到您需要在词法分析器文件中放置“%option reentrant”。查看 here 了解更多信息。似乎您还需要创建一个 yyscan_t 类型的对象来传入。
您真的不需要那些 extern "C"
声明,它们会使您的构建过程复杂化。
(现代)bison
和 flex
都生成可以编译为 C 或 C++ 的代码,但如果以相同的方式编译它们,您会发现它更简单。在这种情况下,您将不需要使用 extern
声明,因为所有外部函数都将针对您使用的语言正确编译。
请注意,当您使用 g++
进行编译时,扩展名为 .c
的文件将被编译为 C++ 程序。因此,lex.yy.c
被编译为 C++ 程序,外部函数,包括 yylex
和 yy_scan_string
,具有正常的 C++ linkage(和名称修改),并声明它们因为 external "C"
在不同的翻译单元中会产生 link 个错误。
除此之外,我通常使用 flex
和 bison
的 -o
选项来创建具有适当扩展名的文件名。使用 flex
的 --header-file
选项生成包含导出函数声明的头文件也很有用,例如 yy_scan_string
.
我有一个字符串向量,我想在 bison 中解析它。我应该远程接收这个,我不想写入文件并读回。我的字符串向量可以很大。
这是我到目前为止尝试过的方法
将所有字符串加到一个字符串中并使用yy_scan_string
我还尝试将所有字符串添加到缓冲区和 yy_scan_string。
我尝试按如下方式构建可执行文件:
bison -d logic.y
flex logic.l
g++ logic.tab.c lex.yy.c -lfl -o logic
但我收到错误消息:
undefined reference to `yy_scan_string'.
这是我的解析器:
%{
#include <cstdio>
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
#include <Server.h>
using namespace std;
//stuff from flex that bison needs to know about:
extern "C" int yylex();
typedef struct yy_buffer_state * YY_BUFFER_STATE;
extern "C" int yyparse();
extern "C" YY_BUFFER_STATE yy_scan_string(const char * str);
//extern "C" void yy_delete_buffer(YY_BUFFER_STATE buffer);
extern int line_num;
vector<string> statements;
void yyerror(const char *s);
%}
//C union holding each of the types of tokens that Flex could return
%union {
char const *sval;
}
//symbol defination
//end of declaration section
%%
//Start of grammar section
//grammar
//end of grammar section
%%
int main(int argc, char *argv[]) {
try
{
logicMessage = server.getLogic();
statements = logicMessage->get_LogicStatements ();
string single = "";
for (vector<string>::iterator it=statements.begin(); it!=statements.end(); ++it)
single += *it;
char* buffer = new char[single.length()+1];
strcpy(buffer,single.c_str());
yy_scan_string(single.c_str());
yyparse();
//yy_delete_buffer(buffer);
return 0;
}
catch(IPC_RETURN_CODE IPC_CODE)
{
std::cerr<< "IPC Error Code:" <<IPC_CODE;
}
}
void yyerror(const char *s) {
cout << "Parse error on line " << line_num << "! Message: " << s << endl;
// might as well halt now:
exit(-1);
}
我读到您需要在词法分析器文件中放置“%option reentrant”。查看 here 了解更多信息。似乎您还需要创建一个 yyscan_t 类型的对象来传入。
您真的不需要那些 extern "C"
声明,它们会使您的构建过程复杂化。
(现代)bison
和 flex
都生成可以编译为 C 或 C++ 的代码,但如果以相同的方式编译它们,您会发现它更简单。在这种情况下,您将不需要使用 extern
声明,因为所有外部函数都将针对您使用的语言正确编译。
请注意,当您使用 g++
进行编译时,扩展名为 .c
的文件将被编译为 C++ 程序。因此,lex.yy.c
被编译为 C++ 程序,外部函数,包括 yylex
和 yy_scan_string
,具有正常的 C++ linkage(和名称修改),并声明它们因为 external "C"
在不同的翻译单元中会产生 link 个错误。
除此之外,我通常使用 flex
和 bison
的 -o
选项来创建具有适当扩展名的文件名。使用 flex
的 --header-file
选项生成包含导出函数声明的头文件也很有用,例如 yy_scan_string
.