Dans un programme plus large, j’ai donné ce qui suit (flex / bison)
En flex:
pn [\+|\-] dig [0-9]+ exp [e|E]{dig}+
.
.
.
"+" {printf("+ detected\n"); return PLUS_SIGN;} {pn}?{dig}+ { printf("digit detected - %s\n",yytext); sscanf(yytext, "%d", (int*)&yylval); return TYPE_INT;}
À Bison:
expr: expr PLUS_SIGN expr { $$ = $1 + $3; printf(" $$=%f\n",$$); } | TYPE_INT { $$ = (int)$1; printf(" $$=%f\n",$$); } ;
Le problème est:
Quand je donne 2 + 2 il reconnaît 2 et +2 au lieu de 2, +, 2
Comment puis-je le faire faire l’addition?
{pn}?{dig}+
Ne faites pas du signe plus ou moins ( {pn?}
) Une partie du jeton de nombre. Traitez-les comme deux jetons séparés, +
et 2
. Alors flex n’aura aucune ambiguïté à résoudre.
{dig}+
Demandez aux bison de gérer les opérateurs unaires plus et moins unaires. Faites-en le travail du parseur, pas celui du lexer.
| PLUS_SIGN expr { $$ = +$2; printf(" $$=%f\n",$$); } | MINUS_SIGN expr { $$ = -$2; printf(" $$=%f\n",$$); }
La grammaire montre la partie gauche et la partie droite de PLUS_SIGN a la même priorité lors de la réduction du symbole. La combinaison PLUS_SIGN est laissée; la nouvelle grammaire est donc la suivante:
expr: expr PLUS_SIGN expr2 { $$ = $1 + $3; printf("$$=%f\n", $$); } | expr2 { $$ = $1; } ; expr2: TYPE_INT { $$ = (int)$1; printf(" $$=%f\n",$$); } ;