如何让yacc/bison和/或lex/flex在令牌替换之类的事情之后重新启动扫描?

如何让yacc/bison和/或lex/flex在令牌替换之类的事情之后重新启动扫描?,c,parsing,bison,yacc,flex-lexer,C,Parsing,Bison,Yacc,Flex Lexer,在我用其他令牌替换某些令牌后,有没有办法强制bison和/或flex重新启动扫描 我的具体示例是替换特定的单词/字符串。如果我想用echo hello替换hello一个单词,我如何让flex或bison替换hello,然后重新开始解析(拾取两个单词而不是一个单词)。因此,这就像: 获取标记字(字符串类型) 如果hello,则将令牌值替换为echo hello 重新分析整个输入(现在是echo hello) 获取令牌字(echo) 获取令牌字(hello) 我见过非常诱人的函数,如yyrest

在我用其他令牌替换某些令牌后,有没有办法强制bison和/或flex重新启动扫描

我的具体示例是替换特定的单词/字符串。如果我想用
echo hello
替换
hello
一个单词,我如何让flex或bison替换
hello
,然后重新开始解析(拾取两个单词而不是一个单词)。因此,这就像:

  • 获取标记字(字符串类型)
  • 如果
    hello
    ,则将令牌值替换为
    echo hello
  • 重新分析整个输入(现在是
    echo hello
  • 获取令牌字(
    echo
  • 获取令牌字(
    hello
我见过非常诱人的函数,如
yyrestart()
,但我并不真正理解该函数真正实现了什么。非常感谢您的帮助,谢谢

2010年4月23日更新

我最后使用的一种黑客和斜杠解决方案是,对于每个通过的
单词,我检查一个“别名”数组。如果
单词
有别名,我将替换该单词的值(例如使用
strcopy($1,aliasval)
),并标记
aliasfound
标志

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

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


如果有人知道我如何通过别名值有效地扩展我的单词,将其插入stdin(或其他方法),并在我进行时基本上扩展所有别名(甚至嵌套),那就太棒了。我一直在玩
yypush\u buffer\u state()
yypop\u buffer\u state()
,还有
yy\u switch\u to\u buffer()
,但我无法通过继续解析工作实现“内联”替换…

在我看来,解决这个问题的地方是lexer。我建议使用flex,它支持状态机(在flex文档中称为“”。您可以使用
BEGIN
更改状态,需要在“定义”部分中定义这些状态

例如,你可以有一个规则,比如

<INITIAL>hello    BEGIN(in_echo); yyless(0); return (WORD_ECHO);
<in_echo>hello    BEGIN(0); return (WORD_HELLO);
hello BEGIN(在回声中);yyless(0);返回(WORD_ECHO);
你好,开始(0);返回(WORD_HELLO);
yyless()
yytext
截断为给定值,因此这会将整个输入放回流中

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

根据我最后所做的添加一个“答案”。希望将此问题标记为已回答

2010年4月23日更新

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

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

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


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

谢谢,我很快就会尝试!