我有一个复杂的 Yacc 文件,其中包含一堆规则,其中一些规则很复杂,例如:
start: program
program: extern_list class
class: T_CLASS T_ID T_LCB field_dec_list method_dec_list T_RCB
确切的规则和我对它们采取的操作并不重要,因为我想做的事情看起来相当简单:只需打印源文件中出现的程序,使用我为其他目的定义的规则。但令我惊讶的是这样做有多困难。
首先,我尝试将 printf("%s%s", $1, $2)
添加到上面的第二条规则中。这产生了“��@P�@”。据我了解,解析后的文本也可以作为变量使用,yytext
。我将 printf("%s", yytext)
添加到文件中的每个规则,并将 extern char* yytext;
添加到文件顶部。这从有效文件生成了 (null){void)1133331122222210101010--552222202020202222;;;;||||&&&;;;;;;;;;}}}}}}}}
根据语言的语法。最后,我将 extern char* yytext;
更改为 extern char yytext[]
,认为这不会有什么区别。屏幕截图 可以最好地显示其输出的差异。
我在 Xubuntu 14.04 上使用 Bison 3.0.2。
最佳答案
如果您只想在解析源代码时将其回显到某些输出,最简单的方法是在词法分析器中执行此操作。您没有说明您使用的词法分析器是什么,但您提到了 lex/flex 使用的 yytext,所以我会假设这一点。
当你使用flex来识别token时,变量yytext
指的是flex用于识别token的内部缓冲区。在 token 的操作中,它可用于获取 token 的文本,但只是暂时的 - 一旦操作完成并且读取下一个 token ,它将不再有效。
所以如果你有一个像这样的弹性规则:
[a-zA-Z_][a-zA-Z_0-9]* { yylval.str = yytext, return T_ID; }
这可能根本不起作用,因为你的程序中会有悬空指针运行;可能是您看到的随机输出的来源。相反,您需要复印一份。如果您还想不改变地输出输入,您也可以在这里执行此操作:
[a-zA-Z_][a-zA-Z_0-9]* { yylval.str = strdup(yytext); ECHO; return T_ID; }
这使用了flex宏ECHO
,它大致相当于fputs(yytext, yyout)
——将输入复制到FILE *
称为 yyout
(默认为 stdout
)
关于c++ - 如何打印在 Yacc/Bison 中看到的任何内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35835192/