www.delorie.com/gnu/docs/bison/bison_28.html | search |
Buy the book! | |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
calc
We now modify rpcalc to handle infix operators instead of postfix. Infix notation involves the concept of operator precedence and the need for parentheses nested to arbitrary depth. Here is the Bison code for `calc.y', an infix desk-top calculator.
/* Infix notation calculator. */ %{ #define YYSTYPE double #include <math.h> #include <stdio.h> int yylex (void); void yyerror (char const *); %} /* Bison declarations. */ %token NUM %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ %% /* The grammar follows. */ input: /* empty */ | input line ; line: '\n' | exp '\n' { printf ("\t%.10g\n", $1); } ; exp: NUM { $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = pow ($1, $3); } | '(' exp ')' { $$ = $2; } ; %% |
The functions yylex
, yyerror
and main
can be the
same as before.
There are two important new features shown in this code.
In the second section (Bison declarations), %left
declares token
types and says they are left-associative operators. The declarations
%left
and %right
(right associativity) take the place of
%token
which is used to declare a token type name without
associativity. (These tokens are single-character literals, which
ordinarily don't need to be declared. We declare them here to specify
the associativity.)
Operator precedence is determined by the line ordering of the
declarations; the higher the line number of the declaration (lower on
the page or screen), the higher the precedence. Hence, exponentiation
has the highest precedence, unary minus (NEG
) is next, followed
by `*' and `/', and so on. See section Operator Precedence.
The other important new feature is the %prec
in the grammar
section for the unary minus operator. The %prec
simply instructs
Bison that the rule `| '-' exp' has the same precedence as
NEG
---in this case the next-to-highest. See section Context-Dependent Precedence.
Here is a sample run of `calc.y':
$ calc 4 + 4.5 - (34/(8*3+-3)) 6.880952381 -56 + 2 -54 3 ^ 2 9 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
webmaster | delorie software privacy |
Copyright © 2003 by The Free Software Foundation | Updated Jun 2003 |