3

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

谢谢

4

3 回答 3

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_-prefixed 符号用于第二个扫描仪,而不是yy-prefixed

于 2010-03-20T06:18:04.683 回答
1

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

可以通过包含带有前缀选项的解析器或在运行时从 DSO 加载的解析器来设置函数指针,a-la 插件设置。

这样做的好处是,处理 AST 的代码可能不知道使用哪个解析器/词法分析器组合来生成它,这对您可能有用也可能没有用。

于 2010-03-19T22:24:04.860 回答
1

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

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

问候

于 2010-03-19T22:24:54.947 回答