bison -v ex1.yppThis will produce the file
ex1.output which,
among other things, includes a text description of the CFSM
computed by bison. Open up the file with the text-editor of
your choice (i.e. xemacs) and take a look. Print it out.
Using this, show
the stack contents for each step of parsing:
3 * ( 5 - 7 ) ; $endTurn in the printout of
ex1.output as well as the
stack contents, step-by-step.
Recall from last class that if your "goal" is the LR item exp → exp + • term, then any LR item with term on the left-hand side and • at the beginning of the right-hand side is a good "sub-goal". Moreover, all these subgoals ended up in the same state as the initial goal in the deterministic CFSM, because in the non-deterministic machine there were lambda transitions from the goal state to the sub-goal state. We define the "closure of a set I of LR items" to be the set I plus all the sub-goals for each element of I. See book for details.
With the closure, we can construct the CFSM directly from the grammar. Suppose S' → S is our dummy initial rule. closure({S'→•S}) is the initial state of the CFSM. For each state I of the CFSM and grammar symbol (terminal or non-terminal) X do the following
In general, let act = { }. If there's a transition for X, add "shift" to act. For each item Ij of the form A → α •, where X ∈ FOLLOW(A), add "reduce by A → α" to act. Now, in state s with lookahead X we should:
Of course this, like our top-down table-diven parser construction requires that we can compute these "FOLLOW(A)" sets.
It's convenient to define FIRST(β) for an arbitrary string of terminals and non-terminals. See book.