2

在我用其他东西替换一些令牌后,有没有办法强制 bison 和/或 flex 重新开始扫描?

我的特定示例是替换特定的单词/字符串。如果我想hello用 替换一个词,echo hello我怎样才能让 flex 或 bison 替换hello然后重新开始解析(选择 2 个词而不是一个词)。所以它会像:

  • 获取token WORD(字符串类型)
  • 如果hello,将令牌值替换为echo hello
  • 重新开始解析整个输入(现在是echo hello
  • 获取令牌 WORD ( echo)
  • 获取令牌 WORD ( hello)

我见过非常诱人的函数yyrestart(),比如 非常感谢任何帮助,谢谢!

2010 年 4 月 23 日更新

我最终使用的一种 hack-and-slash 解决方案是针对每个word通过的,我检查一个“别名”数组。如果word有别名,我会替换单词的值(例如,使用strcopy($1,aliasval)),并标记一个aliasfound标志。

一旦整行输入被解析一次,如果aliasfound标志为真,我会使用yy_scan_string()扩展别名将缓冲区状态切换到输入,然后调用YYACCEPT.

然后它跳到主函数,我yyparse()再次调用,缓冲区仍然指向我的字符串。这一直持续到找不到别名为止。一旦我所有的语法动作都完成了,我就会打电话yyrestart(stdin)回到“正常”模式。

如果有人知道我如何使用它们的别名值有效地扩展我的单词,注入stdin(或其他方法),并在我进行时基本上扩展所有别名(甚至嵌套),那就太棒了。我正在玩yypush_buffer_state()and yypop_buffer_state(),以及yy_switch_to_buffer(),但是我无法通过继续解析工作来获得“内联”替换......

4

2 回答 2

1

在我看来,解决这个问题的地方是词法分析器。我建议使用支持状态机的 flex(在 flex 文档中称为“开始条件”)。您使用 更改状态BEGIN,并且需要在定义部分中定义状态。

因此,例如,您可以有一个规则,例如

<INITIAL>hello    BEGIN(in_echo); yyless(0); return (WORD_ECHO);
<in_echo>hello    BEGIN(0); return (WORD_HELLO);

yyless()将 截断为yytext给定值,因此这会将整个输入放回流中。

我自己没有尝试过,但我认为这是您想要的解决方案的结构。

于 2010-04-25T13:04:33.513 回答
0

根据我最终所做的添加“答案”。想要将此问题标记为已回答。

2010 年 4 月 23 日更新

我最终使用的一种 hack-and-slash 解决方案是对于通过的每个单词,我检查一个“别名”数组。如果这个词有一个别名,我会替换这个词的值(例如,使用 strcopy($1,aliasval)),并标记一个 aliasfound 标志。

一旦整行输入被解析一次,如果 aliasfound 标志为真,我使用 yy_scan_string() 将缓冲区状态切换到具有扩展别名的输入,并调用 YYACCEPT。

然后它跳到主函数,我再次调用 yyparse() ,缓冲区仍然指向我的字符串。这一直持续到找不到别名为止。完成所有语法操作后,我调用 yyrestart(stdin) 以返回“正常”模式。

如果有人知道我如何有效地使用它们的别名值扩展我的单词,注入标准输入(或其他方法),并在我进行时基本上扩展所有别名(甚至嵌套),那将是很棒的。我正在玩 yypush_buffer_state() 和 yypop_buffer_state() 以及 yy_switch_to_buffer(),但我无法通过继续解析工作来获得“内联”替换......

于 2012-01-07T16:00:41.100 回答