Rules with multiple actions
A rule can have more than one action. For example, you
might have:
a : A1 {action1} A2 {action2} A3 {action3};
The
nonterminal symbol a consists of symbols A1, A2,
and A3. When A1 is recognized, action1 is
invoked; when A2 is recognized, action2 is invoked;
and when A3 is recognized (and therefore the entire symbol A), action3 is
invoked. In this case:
$1 — is the value of A1
$2 — is the value of $$ in action1
$3 — is the value of A2
$4 — is the value of $$ in action2
$5 — is the value of A3
If types are involved, multiple actions become more complicated.
If action1 mentions $$, there is no way for yacc to
guess what type $$ has, since it is not really associated
with a token or nonterminal symbol. You must therefore state it explicitly
by specifying the appropriate type name in angle brackets between
the two dollar signs. If you had:
%union {
int intval;
float realval;
}
you might code:
$<realval>$
in place of $$ in
the action, to show that the result had type float. In the
same way, if action2 refers to $2 (the result of
action1), you might code:
$<realval>2
To deal with multiple actions, yacc changes the form of
the given grammar rule and creates grammar rules for dummy symbols. The
dummy symbols have names made up of a $ followed by the
rule number. For example:
a : A1 {action1} A2 {action2} A3 {action3};
might
be changed to the rules:
$21 : /* null */ {action1} ;
$22 : /* null */ {action2} ;
a : A1 $21 A2 $22 A3 {action3};
These rules are shown
in the rules summary of the parser description report.This technique can introduce conflicts. For example, if you have:
a : A1 {action1} A2 X;
b : A1 A2 Y;
These are changed to:
$50 : /* null */ {action1};
a : A1 $50 A2 X;
b : A1 A2 Y;
The definitions of a and b give
a shift-reduce conflict because the parser cannot tell whether A1 followed by A2 has
the null string for $50 in the middle. It has to decide whether
to reduce $50 or to shift to a state diagrammed by:
b : A1 A2.Y
As a general rule, you can resolve this conflict by moving intermediate actions to just before a disambiguating token.