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

发布于 2024-08-25 10:52:13 字数 231 浏览 6 评论 0原文

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

谢谢

I want to generate two separate parsing functions from lex/yacc. Normally yacc gives you a function yyparse() that you can call when you need to do some parsing, but I need to have several different yyparses each associated with different lexers and grammars. The man page seems to suggest the -p (prefix) flag, but this didn't work for me. I got errors from gcc that indicated that yylval was not properly being relabeled (i.e. it claims that several different tokens are not defined). Does anyone know the general rpocedure for generating these separate functions?

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

舂唻埖巳落 2024-09-01 10:52:14

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

#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_ - 第二个扫描仪的前缀符号,而不是 yy - 前缀

I had a same problem sometime ago and I ended up writing following header file:

#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

and include it into .l, so from my .c file I can use scan_-prefixed symbols for second scaner, rather then yy-prefixed

方觉久 2024-09-01 10:52:14

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

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

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

How about a function pointer in surrounding code that swaps out parsers, presuming you don't want to change the parsing context in the middle of yylex() on the same buffer.

The function pointer can be set from including parsers with the prefix option, or ones loaded in from DSOs at runtime, a-la a plugin setup.

This has the advantage, which may or may not be useful to you, that your code which handles the AST can be blind to which parser/lexer combo was used to produce it.

何以心动 2024-09-01 10:52:14

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

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

问候

If you are using flex/bison, you can use the "reentrant" options, that permits to have multiple instances of the same (or also different) scanner. This option is present on recent flex version. IMHO it's the more clean way to have multiple scanners/parsers inside the same program. This article explains in depth the issue.

An alternate way is to use the flex's ability to generate a C++ class instead of a static scanner, but this force the C programmer to write some wrapper functions.

Regards

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文