我的lex文件中有以下定义:
L [a-zA-Z_]
A [a-zA-Z_0-9]
%%
{L}{A}* { yylval.id = yytext; return IDENTIFIER; }
我在YACC文件中执行以下操作:
primary_expression
: IDENTIFIER { puts("IDENTIFIER: "); printf("%s", $1); }
我的源代码(我正在分析的那个)有以下任务:
ab= 10;
出于某种原因,printf("%s", $1);
部分正在打印ab=
,而不仅仅是ab
。
我很确定这是打印ab=
的部分,因为当我删除printf("%s", $1);
时,根本不会打印标识符。
我真的没想完了。我究竟做错了什么?
如果我能更清楚,请告诉我。
答案 0 :(得分:3)
我做错了什么?
您假设yytext
指向的字符串是常量。事实并非如此。
yytext
指向的字符串的生命周期是相关规则的词法操作。如果该规则最终返回,yytext
将一直存在,直到下次调用yylex
为止。就是这样。
bison
- 生成的解析器具有单符号前瞻。因此,当解析器执行语义操作时,再次调用yylex
(对于前瞻);因此,即使是规则中的最后一个(或唯一)令牌,也不能使用yytext
的保存值。
解决方案:复制字符串。 (我使用strdup
,但无论出于何种原因,有些人喜欢malloc和strcpy。如果你这样做,不要忘记NUL终止符。)并且在完成后记得free()
副本用它。