/ / Pourquoi la valeur de retour pour plus qu'un jeton? - bison, yacc, lex, flex-lexer

Pourquoi la valeur de retour pour plus qu'un jeton? - bison, yacc, lex, flex-lexer

Je veux renvoyer DOLLARID ($ foo) et DOTID (.foo), donc je règle la règle de remorquage (un extrait de code de mon fichier 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 extrait de code de mon fichier 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);}
;

J'écris un fichier test test.vm

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

quand je le lance, une partie du résultat est:

la ligne 1 est imprimée par lexer, c’est à droite

la ligne 2 est imprimée par le bison, il contient plus de deux caractères (" =")

En raison de la flexion nécessite plus qu'un jeton

Je ne sais pas pourquoi? S'il vous plaît, aidez-moi à le réparer.

Réponses:

2 pour la réponse № 1

Le problème est que yytext est uniquement valable pour un seul jeton et seraécrasé ou autrement modifié par le prochain jeton lu. Donc, retourner un pointeur dedans ne fonctionnera généralement pas - il aura le texte du jeton pendant un petit bout de temps mais changera plus tard sous vous. Vous devez faire une copie de la chaîne yytext si vous voulez réellement utiliser sa valeur dans l'analyseur.

Changer votre code lexer à utiliser yylval.string = strdup(yytext); et les choses fonctionneront mieux (bien que vous deviez alors vous soucier de libérer les chaînes pour éviter de perdre de la mémoire).