我有一个包含一堆规则的复杂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[],以为这不会有所作为。产生的输出差异最好显示为屏幕截图c++ - 如何打印在Yacc/野牛中看到的所有内容?-LMLPHP

我在Xubuntu 14.04上使用Bison 3.0.2。

最佳答案

如果您只想在解析时将源回显到某些输出,则在词法分析器中执行此操作最简单。您没有说您要为词法分析器使用的内容,而是提到了lex / flex使用的yytext,因此我假设是。

当您使用flex识别令牌时,变量yytext引用flex用于识别令牌的内部缓冲区。在令牌动作中,可以使用它来获取令牌的文本,但是只能用于临时操作-一旦动作完成并且读取了下一个令牌,它将不再有效。

因此,如果您有一个弹性规则,例如:

[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

08-17 04:39