Is possible recover the value of a token?
I have a rule that is similar to:
unaryOperation:
NOT { $$ = new UnaryOP(NOT); }
| PLUS { $$ = new UnaryOP(PLUS); }
| MINUS { $$ = new UnaryOP(MINUS); }
;
NOT, PLUS and MINUS are tokens and I am using the generated definition in my program too. Is possible recover this data and not repeat myself in the same line?
I'm not interested in the semantic value, so it is not correct for my write this:
unaryOperation:
NOT { $$ = new UnaryOP($1); }
| PLUS { $$ = new UnaryOP($1); }
| MINUS { $$ = new UnaryOP($1); }
;
Thank you
bison
doesn't need to know which token was recognized, since that information is effectively part of the stack state. However, if debugging is enabled, the bison tables include an encoded version of the right-hand side of each reduction, which allows the built-in trace feature to produce human-readable traces.
In theory you could use this information, too, but it won't be what you want because bison translates flex token numbers into a contiguous sequence (to allow for more compact parse tables) and doesn't provide any way to translate them back. So it would be tedious.
A better solution is to use the semantic value, which you are currently ignoring (assuming that it has an integer variant). The cost of assigning the semantic value is trivial, since bison really requires every token's semantic value to be initialized to something anyway.
So a plausible flex/bison solution might be:
%union {
int intval;
/* ... other semantic values */
}
%%
/* All the other rules come first */
/* Default rule which just passes any character through to bison
* (see note)
*/
. { return (yylval.intval = yytext[0]); }
/* This declaration is only necessary because these tokens
* have a semantic value
*/
%token <intval> '-' '+' '!'
%%
unaryOperation
: '!' { $$ = new UnaryOP($1); }
| '+' { $$ = new UnaryOP($1); }
| '-' { $$ = new UnaryOP($1); }
;
Note: I removed the token names NOT
, PLUS
and MINUS
because I prefer the style of using single-character tokens to represent themselves. The difference here is that the flex rule also sets the semantic value (to the same number). If the operators were multicharacter, you could do that too:
'!=' { return (yylval.intval = NOTEQUAL); }