将Yacc / Bison Parser与C ++程序连接起来

时间:2011-07-09 13:36:54

标签: c++ yacc bison

这不是this question的重复,因为解决方案不是使用解析器!

我有一个可以通过./parser < file_to_parse运行的Bison解析器。我想从我的C ++程序中调用Bison解析器。我不想做的是system(./parser < file_to_parse),因为这会假设解析器是预编译的,然后我的整个程序将不是平台独立的。

如果我有一个功能:

void foo(file_name) {
   // call parser on file_name
}
那怎么办呢?有任何想法吗?我认为这是调用yyparse或者其他东西的情况,但我没有随处可见!

谢谢你:)。

3 个答案:

答案 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将会发布