这不是this question的重复,因为解决方案不是使用解析器!
我有一个可以通过./parser < file_to_parse
运行的Bison解析器。我想从我的C ++程序中调用Bison解析器。我不想做的是system(./parser < file_to_parse)
,因为这会假设解析器是预编译的,然后我的整个程序将不是平台独立的。
如果我有一个功能:
void foo(file_name) {
// call parser on file_name
}
那怎么办呢?有任何想法吗?我认为这是调用yyparse或者其他东西的情况,但我没有随处可见!
谢谢你:)。
答案 0 :(得分:2)
您使用的是适合C ++的版本吗?
我使用的是Alain Coetmeur的那个。
目前,我只使用代码方便使用flex ++,但它应该告诉你这是怎么回事。
当你运行flex ++时,它会输出一个头文件和一个新类的实现文件来进行解析。将这些添加到您的项目中,然后写:
// Construct new instance of parser
::lex * plex = new lex();
// tell parser what file to parse
plex->yyin = _wfopen(L"C:/Documents and Settings/All Users/Application Data/QuietWake/eCrew/new_rules_to_be_parsed.txt",L"r");
// run the parser
int lex_return = plex->yylex();
答案 1 :(得分:1)
这正是你所做的 - 你称之为yyparse()。你编写yylex()使你的主程序可以指定它的输入。据推测,你当前的yylex()调用getchar()或其他东西来读取一个字符;相反,你可能需要编写它来从主程序指定的某个地方获取输入。
答案 2 :(得分:1)
这是C Code,但我想这也是C ++的一个指示性案例
当我们必须在大学里编写一个编译器时,我们必须在.l
文件中定义YY_DECL,如下所示:
#define YY_DECL int alpha_yylex(yylval_) void *yylval_;
int alpha_yylex(yylval_)
是函数,void *yylval
是参数类型。
显然,你需要这个,以便解析器知道从何处开始,即哪个函数是应该从中进行解析的。
您还需要在extern int alpha_yylex(void *yylval_);
文件中外设此函数原型(.y
)
之后,Flex / Bison实用程序将为您自动生成相关的.c
文件。
通常,.l
用于词汇规则,.y
用于语法规则。因此,如果您需要从某个地方获取值,您必须在.y
中定义 union ,如下所示(示例):
%union {
union {
int Integer;
double Double;
char Character;
char* String;
} value;
}
然后,根据您的语法和规则,您可以在yylval.value.String = strdup(yytext)
.l file
中执行$$.Double = $1.Double + $3.Double
,并根据您的语法规则,在.y
文件中{{1}}。< BR />
我记不清了很多,因为我已经做了一段时间,但我想你可以尝试,你可以参考文档或在这里问:)。
P.S :(我在某个地方有一个很好的常见问题,但不记得它在哪里 - &gt;如果我很幸运能找到它xD:D xD将会发布