如何从lex / yacc生成不同的yyparse函数以在同一程序中使用?

时间:2010-03-19 22:11:30

标签: c bison yacc lex flex-lexer

我想从lex / yacc生成两个单独的解析函数。通常yacc会为你提供一个函数yyparse(),当你需要进行一些解析时你可以调用它,但是我需要有几个不同的yyparses,每个yypars都与不同的词法和语法相关联。手册页似乎建议使用-p(前缀)标志,但这对我不起作用。我从gcc那里得到错误,表明yylval没有被正确地重新标记(即它声称没有定义几个不同的令牌)。有谁知道生成这些单独函数的一般规则?

感谢

3 个答案:

答案 0 :(得分:2)

前段时间我遇到了同样的问题,最后我写了下面的头文件:

#ifndef RENAME_FLEX_H
#define RENAME_FLEX_H

#define yy_create_buffer scan__create_buffer
#define yy_delete_buffer scan__delete_buffer
#define yy_init_buffer scan_init_buffer
#define yy_load_buffer_state scan_load_buffer_state
#define yy_switch_to_buffer scan_switch_to_buffer
#define yyin scan_in
#define yyleng scan_leng
#define yylex scan_lex
#define yyout scan_out
#define yyrestart scan_restart
#define yytext scan_text
#define yy_flex_debug scab_flex_debug
#define yywrap scan_wrap
#define yyrealloc scan_realloc
#define yyfree scan_free
#define yy_flush_buffer scan_flush_buffer
#define yypush_buffer_state scan_push_buffer_state
#define yypop_buffer_state scan_pop_buffer_state
#define yy_scan_buffer scan_scan_buffer
#define yy_scan_string scan_scan_string
#define yy_scan_bytes scan_scan_bytes
#define yyget_in scan_get_in
#define yyget_out scan_get_out
#define yyget_leng scan_get_leng
#define yyset_text scan_set_text
#define yyset_in scan_set_in
#define yyset_out scan_set_out
#define yyget_debug scan_get_debug
#define yyset_debug scan_set_debug
#define yylex_destroy scan_lex_destroy
#define yyalloc scan_alloc
#define yyget_text scan_get_text

#endif

并将其包含在.l中,因此,从我的.c文件中我可以使用scan_ - 第二个scaner的前缀符号,而不是yy - 前缀

答案 1 :(得分:1)

周围代码中交换解析器的函数指针怎么样,假设您不想在同一缓冲区的yylex()中间更改解析上下文。

可以设置函数指针,包括带有前缀选项的解析器,或者在运行时从DSO加载的解析器,a-la a plugin setup。

这样做的优势在于,您处理AST的代码可能无法使用哪个解析器/词法分析器组合来生成它。这可能对您有用,也可能没有用。

答案 2 :(得分:1)

如果您使用flex / bison,则可以使用“reentrant”选项,该选项允许具有相同(或不同)扫描仪的多个实例。此选项出现在最近的flex版本中。恕我直言,这是在同一个程序中拥有多个扫描仪/解析器的更干净的方法。 This article深入解释了这个问题。

另一种方法是使用flex的能力来生成C ++类而不是静态扫描器,但是这迫使C程序员编写一些包装函数。

问候