14 Mar 2007 14:31:48 -0400

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.

Post a followup to this message

Return to the
comp.compilers page.

Search the
comp.compilers archives again.