我有一个包含一堆规则的复杂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识别令牌时,变量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
)