Related articles |
---|
How to process unary minus for constants by other way than expressions marek@tynska.cuni.cz (Marek Peca) (2007-03-14) |
Re: How to process unary minus for constants by other way than express schmitz@i3s.unice.fr (Sylvain Schmitz) (2007-03-14) |
From: | Marek Peca <marek@tynska.cuni.cz> |
Newsgroups: | comp.compilers |
Date: | 14 Mar 2007 14:31:48 -0400 |
Organization: | Charles University Prague |
Keywords: | parse, question |
Posted-Date: | 14 Mar 2007 14:31:48 EDT |
Dear compiler compilers,
I'm trying to write simple expression evaluator in flex/bison. The
aim is to evaluate math expr using infix operators + - / * ^, libm
functions such as pow, sin ot atan2, named variables and 1.234e-56
like constants. The expression will be parsed once over a time and a
produced tree will be then executed many times, so the tree should be
nearly optimal.
The general task is a holy simplicity itself, even given as an
example in bison's docs. However, I'd like to tune one detail: unary
minus for numbers. In lexer, I specify numbers without preceding
optional sign, the reason is to not to confuse binary and unary
minus. I want to distinguish two different cases in bison parser:
* unary minus before general expression -- it will produce n+1 order
subtree, calling unary minus function to the expression value;
* unary minus before number constant -- it should be applied at
"parse time" to the number to simplify the tree.
Is this solvable using bison, ie. is its set of parseable grammars
sufficient for this task? I know, I can optimize the tree after
parsing, its simple, but this would be very stupid, if it can be
easily specified in a bison input grammar description.
I tried something like this:
-----
%token NUMBER
%token IDENTIFIER
%left '-' '+'
%left UNEXP
%left UNNUM
%right '^'
%%
input: /* nic */
| input line
;
line: '\n'
| expr '\n'
expr: NUMBER { $$ = $1; }
| '(' expr ')' { $$ = $2; }
| expr '+' expr { $$ = sub($1,$3); }
| expr '-' expr { $$ = add($1,$3); }
| expr '^' expr { $$ = pow($1,$3); }
| '-' NUMBER %prec UNNUM { $$ = -$2; }
| '-' expr %prec UNEXP { $$ = neg($2); }
;
%%
-----
then, I changed to
-----
expr: NUMBER
| expr_nonnum
;
expr_nonnum: '(' expr ')'
| '(' expr ')'
| expr '+' expr
| expr '-' expr
| expr '^' expr
| '-' NUMBER %prec UNNUM
| '-' expr_nonnum %prec UNEXP
;
-----
but without success.
Thank you for your help.
Best regards,
Marek P.
Return to the
comp.compilers page.
Search the
comp.compilers archives again.