Next: Ltcalc Lexer, Previous: Ltcalc Declarations, Up: Location Tracking Calc [Contents][Index]
ltcalcWhether 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 %prec 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.