2011-04-19 5 views
1

マイlexのファイルがあります。エクストラ右ブレース

word [^{}"=,\t\[email protected]\\ ]+ 

\{ { 
    return(LBRACE); 
} 

\} { 
    return(RBRACE); 
} 

{word} { 
    yylval = yytext; printf("WORD=%s",yytext); return(WORD); 
} 

私のyaccファイルがあります。

phrase: LBRACE WORD RBRACE {printf("LBRACE %s RBRACE\n",$2);}; 

入力するには:

{FooBar} 

私が手:

WORD=FooBar 
LBRACE FooBar} RBRACE 

私はWORD生産にそれは(yylval経由)yytextの値を格納するのはあなた次第ですされなければならない理想的な

答えて

3

行うことができると思います。この語彙素を処理している間

{word} { 
    yylval = yytext; printf("WORD=%s",yytext); return(WORD); 
} 

yytextの値にのみ有効です。次の字句に移動すると、バッファの内容が上書きされることがあります。したがって、yytextポインタを保存することは、あなたに何の役にも立たないでしょう。トークンをバッファからコピーする必要があります。

{word} { yylval = (char*)calloc(yylen+1, sizeof(char)); 
      strncpy(yylval, yytext, yylen); // Remember you need to free this. 
      return WORD; 
     } 
+0

答えをありがとう!私はあなたがグローバル変数yylengを意味すると思いますよね?また、 'strncpy'は' yyleng + 1'文字を越えて終端ヌルを得るべきではありませんか? 'strndup'が使用されている場合は、それ自身で終了するnullを追加します。 –

+0

@crypto:はい、私はlexによって提供されたグローバルなyylenを意味します。私がcalloc()を使用するので、strncpyはyylen + 1をコピーする必要はありません。したがって、strncpyが余分な '\ 0'を追加するかどうかは関係なく、 '\ 0'となります。 –

2

、のみ$ 2印刷てるにもかかわらず、私は余分な右中括弧を取得していますなぜ私はわかりませんよ。これは単なるlexの作業空間へのポインタです。 RBRACEを解析した後、作業スペースが変更されています。 LBRACE WORD COMMA WORD LBRACEのようなyaccのルールを考えてみましょう。

あなたが別の生産を持ってしたくない場合は

は、私はあなたがここに LBRACE WORD { code to strdup yylval } RBRACE { ... }

+0

なぜ '$ 2'と渡された' yylval'文字列の値に違いがありますか? –

+0

'yylval'はそれ自体が文字列ではなく、lexのプライベートデータを指すポインタ*です。あなたは 'yylval'を所有していますが、あなたはそれが指しているものを所有していません。これは 'yylex()'が返ってきた時刻と、あなたがそれを再び呼び出す時刻との間の特定の端末シンボルに対してのみ有効です。私が意味するものを見るために 'yylval = strdup(yytext)'を試してみてください。 –

+0

strdupは安全ではありません。 lexバッファが '\ 0'終了しているという保証はありません。必要なバッファの一部を抽出するには、yylenを使用する必要があります。 –

関連する問題