This is in the first rule of Perl:
grammar : GRAMPROG
{
PL_parser->expect = XSTATE;
}
remember stmtseq
{
newPROG(block_end($3,$4));
$$ = 0;
}
How can $4
work when there're only 3
e开发者_运维百科lements on the right side?
An embedded action (the code { PL_parser->expect = XSTATE; }
which occurs in the middle of the rule) counts as an element. So there are 4 elements. $1 is the terminal GRAMPROG, $2 is the embedded action, $3 is the nonterminal remember, and $4 is the nonterminal stmtseq. (The value of $2 is whatever value is assigned to $$ inside the embedded action. Currently it would be garbage.)
Under the covers, yacc only really supports actions at the end of a production. So when you interleave an action { PL_parser->expect = XSTATE; }
in the middle of a production, yacc (or whatever descendent you're using) pulls out the action and sticks it at the end of an empty rule as such:
grammar: GRAMPROG $$1 remember stmtmseq
{
newPROG(block_end($3, $4));
$$ = 0;
}
$$1:
{
PL_parser->expect = XSTATE;
}
(If your yacc variant support dumping the verbose grammar and you do that, you'll see a lot of $$1, $$2, etc. rules for actions.)
In this case the interleaved action doesn't actually assign anything to $$
, but if it had, the grammar
rule could have accessed the value as $2
.
精彩评论