Next: Conflicts due to Midrule Actions, Previous: Typed Midrule Actions, Up: Actions in Midrule [Contents][Index]
Midrule actions are actually transformed into regular rules and actions. The various reports generated by Bison (textual, graphical, etc., see Understanding Your Parser) reveal this translation, best explained by means of an example. The following rule:
exp: { a(); } "b" { c(); } { d(); } "e" { f(); };
is translated into:
$@1: %empty { a(); }; $@2: %empty { c(); }; $@3: %empty { d(); }; exp: $@1 "b" $@2 $@3 "e" { f(); };
with new nonterminal symbols $@n
, where n is a number.
A midrule action is expected to generate a value if it uses $$
, or
the (final) action uses $n
where n denote the midrule
action. In that case its nonterminal is rather named @n
:
exp: { a(); } "b" { $$ = c(); } { d(); } "e" { f = $1; };
is translated into
@1: %empty { a(); }; @2: %empty { $$ = c(); }; $@3: %empty { d(); }; exp: @1 "b" @2 $@3 "e" { f = $1; }
There are probably two errors in the above example: the first midrule action
does not generate a value (it does not use $$
although the final
action uses it), and the value of the second one is not used (the final
action does not use $3
). Bison reports these errors when the
midrule-value
warnings are enabled (see Invoking Bison):
$ bison -Wmidrule-value mid.y
mid.y:2.6-13: warning: unset value: $$ 2 | exp: { a(); } "b" { $$ = c(); } { d(); } "e" { f = $1; }; | ^~~~~~~~
mid.y:2.19-31: warning: unused value: $3 2 | exp: { a(); } "b" { $$ = c(); } { d(); } "e" { f = $1; }; | ^~~~~~~~~~~~~
It is sometimes useful to turn midrule actions into regular actions, e.g., to factor them, or to escape from their limitations. For instance, as an alternative to typed midrule action, you may bury the midrule action inside a nonterminal symbol and to declare a printer and a destructor for that symbol:
%nterm <context> let %destructor { pop_context ($$); } let %printer { print_context (yyo, $$); } let
%%
stmt: let stmt { $$ = $2; pop_context ($let); };
let: "let" '(' var ')' { $let = push_context (); declare_variable ($var); };
Next: Conflicts due to Midrule Actions, Previous: Typed Midrule Actions, Up: Actions in Midrule [Contents][Index]