/ / Perché il valore restituito per più di un token? - bison, yacc, lex, flex-lexer

Perché il valore restituito per più di un token? - bison, yacc, lex, flex-lexer

Voglio restituire DOLLARID ($ foo) e DOTID (.foo), quindi ho impostato la regola di rimorchio (un frammento di codice del mio file 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;}

Un frammento di codice del mio file yacc:

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

Scrivo un file di prova test.vm

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

quando lo eseguo, una parte del risultato è:

la riga 1 è stampata da lexer, è giusto

la linea 2 è stampata dal bisonte, è più di due caratteri (" =")

Perché flex ha bisogno di più di un token?

Non so perché? Per favore aiutami a sistemarlo.

risposte:

2 per risposta № 1

Il problema è che yytext è valido solo per un singolo token e otterràsovrascritto o altrimenti modificato dal prossimo token letto. In questo caso, il ritorno di un puntatore in genere non funzionerà: avrà il testo del token per un po ', ma in seguito cambierà da sotto di te. Devi fare una copia della stringa in yytext se vuoi veramente usare il suo valore nel parser.

Cambia il tuo codice lexer da usare yylval.string = strdup(yytext); e le cose funzioneranno meglio (anche se poi dovrai preoccuparti di liberare le stringhe per evitare perdite di memoria).