Node:Ltcalc Rules, Next:Ltcalc Lexer, Previous:Ltcalc Decls, Up:Location Tracking Calc
ltcalc
Whether handling locations or not has no effect on the syntax of your language. Therefore, grammar rules for this example will be very close to those of the previous example: we will only modify them to benefit from the new information.
Here, we will use locations to report divisions by zero, and locate the
wrong expressions or subexpressions.
input : /* empty */ | input line ; line : '\n' | exp '\n' { printf ("%d\n", $1); } ; exp : NUM { $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { if ($3) $$ = $1 / $3; else { $$ = 1; fprintf (stderr, "%d.%d-%d.%d: division by zero", @3.first_line, @3.first_column, @3.last_line, @3.last_column); } } | '-' exp %preg NEG { $$ = -$2; } | exp '^' exp { $$ = pow ($1, $3); } | '(' exp ')' { $$ = $2; }
This code shows how to reach locations inside of semantic actions, by
using the pseudo-variables @n
for rule components, and the
pseudo-variable @$
for groupings.
We don't need to assign a value to @$
: the output parser does it
automatically. By default, before executing the C code of each action,
@$
is set to range from the beginning of @1
to the end
of @n
, for a rule with n components. This behavior
can be redefined (see Default Action for Locations), and for very specific rules, @$
can be computed by
hand.