The information in this file is closely related to what's happening in
state/define.cc. Refer to define.cc for the implementation of the process
described below. All functions mentioned below are defined by the class State.


Defining states proceeds as follows:

 0. The initial state is constructed. It contains the augmented grammar's
    production rule. This part is realized by the static member

         initialState();

    Following this, states are constructed via State::construct, initially
    called for the initial state (state 0)

    State construction (i.e., State::construct) consists of two steps:

        1. All items are defined in State::setItems as either reducible items
           (no transitions) or non-reducible items (when the dot is not beyond
            the last item's symbol). Whenever there are non-reducible items 

        2.

 1. From the state's kernel item(s) all implied rules are added as
    additional state items. This results in a vector of (kernel/non-kernel)
    items,
 
    >>!! as well as per item the numbers of the items that are affected
    by this item. This information is used later on to propagate the
    LA's. This part is realized by the member
         
         setItems()

    This fills the StateItem::Vector vector. A StateItem contains

        1. an item (containing a production rule, dot position, and LA set)
        2. a size_t vector of indices of `dependent' items, indicating which
           items have LA sets that depend on the current item
           (StateItem::d_child).
        3. The size_t field `d_nextIdx' holds the index in d_nextVector,
           allowing quick access of the d_nextVector element defining the
           state having the current item as its kernel. A next value 'npos'
           indicates that the item does not belong to a next-kernel.

    E.g., 

    StateItem:
    -------------------------------------
    item        LA-set  dependent   next 
                        stateitems  state
    -------------------------------------
    S* -> . S,  EOF,    (1, 2)      0    
    ...
    -------------------------------------

    Also, State::d_nextVector vector is filled.

    A Next element contains

         0. The symbol on which the transition takes place
         1. The number of the next state
         2. The indices of the StateItem::Vector defining the next
                state's kernel 
     
     E.g., 

     Next:
     -------------------------------
     On          next    next kernel
     Symbol      state   from items
     -------------------------------
     S           ?       (0, 1)
     ...
     -------------------------------

    Empty production rules don't require special handling as they won't appear
    in the Next table, since there's no transition on them.

    Next, from these facilities all states are constructed. LA propagation is
    performed after the state construction State construction takes place (in
    the while loop in State::define.cc following the initial state
    construction).

 2. After the state construction the LA sets of the items are computed. State
    0's single kernel item is S_$: . S, and represents the augmented grammar's
    start rule, just before observing the grammar's start symbol. The LA sets
    are computed by State::determineLAsets. The file state/determinelasets.cc
    contains a description of the implemented algorithm, as does chapter 7
    (The Bisonc++ Parser Algorithm) of Bisonc++'s User Guide. The reader is
    referred to these documentation sources for further information about the
    LA set computation algorithm.

 3. Once all states have been constructed, conflicts are located and
    solved. If a state contains conflict, they are resolved and
    information about these conflicts is stored in an SRConflict::Vector
    and/or RRConflict::Vector. Conflicts are identified and resolved by the
    member: 

         State::checkConflicts();

 4. S/R conflicts are handled by the d_srConflict object. This object received
    at construction time a context consisting of the state's d_itemVector and
    d_nextVector as well as d_reducible containing all indices of reducible
    items. Each of these indices is the index of a reducible item which is,
    together with a context consisting of the state's d_itemVector and
    d_nextVector, passed to Next::checkShiftReduceConflict(), which solves the
    observed shift-reduce conflicts. 

    Here is how this is done:

    Assume a state's itemVector holds the following StateItems:

        0:    [P11 3] expression -> expression '-' expression  .   
                        { EOLN '+' '-' '*' '/' ')' }  0, 1, () -1 
        1:    [P10 1] expression -> expression  . '+' expression   
                        { EOLN '+' '-' '*' '/' ')' }  0, 0, () 0 
        2:    [P11 1] expression -> expression  . '-' expression   
                        { EOLN '+' '-' '*' '/' ')' }  0, 0, () 1 
        3:    [P12 1] expression -> expression  . '*' expression   
                        { EOLN '+' '-' '*' '/' ')' }  0, 0, () 2 
        4:    [P13 1] expression -> expression  . '/' expression   
                        { EOLN '+' '-' '*' '/' ')' }  0, 0, () 3 
    
    and the associated nextVector is:
    
        0:    On '+' to state 15 with (1 )
        1:    On '-' to state 16 with (2 )
        2:    On '*' to state 17 with (3 )
        3:    On '/' to state 18 with (4 )
    
    
    Conflicts are inspected for all reducible items. Here the reducible item
    is the item having index 0. 

    Inspection involves (but see below for an extension of this process when
    the LHS of a reducible item differs from the LHS of a non-reducible item):
    
        1. The nextVector's symbols are searched for in the LA set of the
           reduction item (so, subsequently '+', '-', '*' and '/' are searched
           for in the LA set of itemVector[0]).
        2. In this case, all are found and depending on the token's priority
           and the rule's priority either a shift or a reduce is selected. 


     
     Production rules received their priority setting either explicitly (using
     %prec) or from their first terminal token. See also
     rules/updateprecedences.cc
    

    What happens if neither occurs? In a rule like 'expr: term' there is no
    first terminal token and there is no %prec being used. 
    In these cases the rule is removed, by default using a shift instead of a
    reduce (until 4.00.00 this was handled incorrectly by giving the reduction
    rule the highest precedence, using a reduce rather than a shift) 
    The problem with rules without precedence was originally brought to my
    attention by Ramanand Mandayam.

    Different LHS elements of items:

    As pointed out by Ramanand Mandayam, S/R conflicts may be observed when
    reducible rules merely consist of non-terminals. Here is an example:
    
    %left  '*'                                
    %token ID
    %%
    expr: 
        term 
    ;
    term:
        term '*' primary
    | 
        ID
    ;
    primary:
        '-' expr
    | 
        ID
    ;
    
    This grammar contains the following state
    
    State 2:
    0: [P1 1] expr -> term  .   { <EOF> }  1, () -1
    1: [P2 1] term -> term  . '*' primary   { '*' <EOF> }  0, () 0
      0: On '*' to state 4 with (1 )
      Reduce item(s): 0 
    
    Here, item 0 reduces to N 'expr' and item 1 requires a shift in a
    production rule of the N 'term'.
    
    In these cases the rule 'expr -> term .' has no precedence that can be
    derived from either %prec or an initial terminal. Such reductions
    automatically receive the highest possible precedence and 'reduce' is
    used, rather than 'shift'. Since there is no explicit basis for this
    choice the choice between shift and reduce is flagged as a conflict.


Here is another illustration. Consider the familiar unary minus operator, but
with a somewhat different grammar than usual:

    %left '-'
    %right UNARY
    
    expr:
        NR
    |
        expr '-' expr
    |
        expr '-'
    ;

When this grammar is analyzed one of its states looks like this (the items are
reordered so that items transiting to identical next states are clustered:

    0: [P2 2] expr -> expr '-'  . expr   { '-' <EOF> }  0
    3: [P2 0] expr ->  . expr '-' expr   { '-' <EOF> }  0
    4: [P3 0] expr ->  . expr '-'   { '-' <EOF> }  0
    
      0:   On expr to state 4 with (0 3 4 )
    
    2: [P1 0] expr ->  . NR   { '-' <EOF> }  1
      1:   On NR to state 2 with (2 )
    
    1: [P3 2] expr -> expr '-'  .   { '-' <EOF> }  -1
      Reduce item(s): 1 

Even though the rule    
        expr: expr '-'   
has a higher priority than the binary minus operator it is not automatically
selected. To see why look at the nextVector's symbols: for items 0, 3, and 4
this is 'expr'; for item 2 this is NR. But the look-ahead set does not contain
these symbols, and so there is no conflict. So, when encountering the
following input:

        expr '-' expr '-'

the parser will, after processing the leftmost minus, parse the second expr,
followed by a transition to another state, where expr '-' expr is reduced to
expr. Only then the second minus is processed.

After changing the grammar so that we get the familiar unary minus
specification (expr: '-' expr %prec UMINUS) the comparable state looks like
this: 

    0: [P3 2] expr -> '-' expr  .   { '-' <EOF> }  -1
    1: [P2 1] expr -> expr  . '-' expr   { '-' <EOF> }  0
      0 (removed by precedence):   On '-' to state 4 with (1 )
      Reduce item(s): 0 

In this case there *is* a conflict: item 1 would transit to state 4 when the
minus is the next symbol to process. But the minus is also in item 0's
lookahead set, hence the conflict. Now the priorities of the two rules
determines which one is selected. As the priority of the production rule
referred to by item 0 is higher than the priority of the production rule
referred to by item 1, item 1 is removed from the set of items, and the unary
minus is processed (a reduce action), while the shift implied by item 1 never
occurs as item 1 is reoved from the set of items.

As a further illustration consider what happens if the unary minus's priority
is set to a lower priority than the binary minus operator. In that case we
encounter this state:

    0: [P3 2] expr -> '-' expr  .   { <EOF> }  -1
    1: [P2 1] expr -> expr  . '-' expr   { '-' <EOF> }  0
      0:   On '-' to state 4 with (1 )
      Reduce item(s): 0 

Here the minus has disappeared from the LA set of the reducible item; there is
no conflict anymore, and a minus token results in a shift to state 4. In other
cases item 0 is selected, reducing expr '-' to an expr.

