0

DOLLARID($foo) と DOTID(.foo) を返したいので、2 つのルールを書きます (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行目は字句解析器によって印刷されています、それは正しいです

2 行目は bison によって出力され、2 文字を超えています( " =")

Flex にはトークン以上のものが必要ですか?</p>

理由がわかりません。修正を手伝ってください。

4

1 に答える 1

2

問題はyytext、単一のトークンに対してのみ有効であり、次に読み取られるトークンによって上書きまたは変更されることです。そのため、ポインターをそこに返すことは通常は機能しません。トークン テキストはしばらくの間保持されますが、後で変更されます。yytextパーサーでその値を実際に利用したい場合は、文字列のコピーを作成する必要があります。

lexer コードを使用するように変更するyylval.string = strdup(yytext);と、動作が改善されます (ただし、メモリ リークを避けるために文字列を解放することについて心配する必要があります)。

于 2013-04-15T06:23:03.883 に答える