Build an LALR viable prefix recognition machine given a start
production. This method operates by first building a start state
from the start production (based on a single item with the dot at
the beginning and EOF as expected lookahead). Then for each state
it attempts to extend the machine by creating transitions out of
the state to new or existing states. When considering extension
from a state we make a transition on each symbol that appears before
the dot in some item. For example, if we have the items:
[A ::= a b * X c, {d,e}]
[B ::= a b * X d, {a,b}]
in some state, then we would be making a transition under X to a new
state. This new state would be formed by a "kernel" of items
corresponding to moving the dot past the X. In this case:
[A ::= a b X * c, {d,e}]
[B ::= a b X * Y, {a,b}]
The full state would then be formed by "closing" this kernel set of
items so that it included items that represented productions of things
the parser was now looking for. In this case we would items
corresponding to productions of Y, since various forms of Y are expected
next when in this state (see lalr_item_set.compute_closure() for details
on closure).
The process of building the viable prefix recognizer terminates when no
new states can be added. However, in order to build a smaller number of
states (i.e., corresponding to LALR rather than canonical LR) the state
building process does not maintain full loookaheads in all items.
Consequently, after the machine is built, we go back and propagate
lookaheads through the constructed machine using a call to
propagate_all_lookaheads(). This makes use of propagation links
constructed during the closure and transition process.