为什么返回值超过令牌?

时间:2013-04-15 04:07:16

标签: bison yacc lex flex-lexer

我想返回DOLLARID($ foo)和DOTID(.foo),所以我想要拖拽规则(我的lex文件的代码片段):

ID  ([_a-zA-Z]+[a-zA-Z0-9_\-]*)
DOLLAR ("$"|("$!"))
DOT "."
%x DIRECTIVE REFERENCE
%%

[^#$]*?/"$" {BEGIN REFERENCE;yylval.string = yytext;printf("==========begin reference flex content===content:%s=====\n",yytext);return CONTENT;}
[^$#]*?/"#" {BEGIN DIRECTIVE;yylval.string = yytext; return CONTENT;}
<REFERENCE,DIRECTIVE>{DOLLAR}{ID} {yylval.string = yytext;printf("==========flex    content===ID:%s=====\n",yytext);return DOLLARID;}
<REFERENCE,DIRECTIVE>{DOT}{ID} {yylval.string = yytext;printf("==========flex content===DOTID:%s=====\n",yytext);return DOTID;}

我的yacc文件的代码片段:

set:SET PARENTHESIS reference EQUAL expression CLOSE_PARENTHESIS { $$ = set_directive($3,$5); }
;
reference: DOLLARID {printf("reference ---Id,key:%s\n",$1);$$ = reference($1);}
|DOLLARID DOTID {printf("reference ---dotId\n");$$ = reference($2);}
;

我写了一个测试文件test.vm

#set($arr = [1..5])
#set($hell = "sinory")
$hell
$arr

当我运行它时,结果的一部分是:

第1行由lexer打印,它是正确的

第2行由bison打印,它超过两个字符(" ="

因为flex需要的不仅仅是令牌吗?

我不知道为什么?请帮我解决。

1 个答案:

答案 0 :(得分:2)

问题是yytext仅对单个令牌有效,并且会被下一个令牌读取覆盖或以其他方式修改。所以将指针返回到它通常是行不通的 - 它会有一段时间的令牌文本,但稍后会从你下面改变。如果要在解析器中实际使用其值,则需要在yytext中复制该字符串。

更改你的词法分析器代码以使用yylval.string = strdup(yytext);并且事情会更好(尽管你需要担心释放字符串以避免泄漏内存)。

相关问题