Sometimes reduce/reduce conflicts occur that are puzzling at first sight. Here
is an example:
        verb(
    %token ID
    
    %%
    def:    
        param_spec return_spec ','
    ;

    param_spec:
        type
    |    
        name_list ':' type
    ;

    return_spec:
        type
    |
        name ':' type
    ;

    type:
        ID
    ;

    name:
        ID
    ;

    name_list:
        name
    |
        name ',' name_list
    ;
        ) 
    It would seem that this grammar can be parsed with only a single
look-ahead token: when a param_spec is being read, an tt(ID) is a tt(name) if
a comma or colon follows, or a tt(type) if another tt(ID) follows. In other
words, this grammar is LR(1).

However, b(), like most parser generators, cannot actually handle all LR(1)
grammars. In this grammar two contexts, one after an tt(ID) at the beginning
of a tt(param_spec) and another one at the beginning of a tt(return_spec), are
similar enough for b() to assume that they are identical. They appear similar
because the same set of rules would be active--the rule for reducing to a name
and that for reducing to a type. B() is unable to determine at that stage of
processing that the rules would require different look-ahead tokens in the two
contexts, so it makes a single parser state for them both. Combining the two
contexts causes a conflict later. In parser terminology, this occurrence means
that the grammar is not LALR(1).

In general, it is better to fix deficiencies than to document them. But this
particular deficiency is intrinsically hard to fix; parser generators that can
handle LR(1) grammars are hard to write and tend to produce parsers that are
very large. In practice, b() is more useful the way it's currently operating.

When the problem arises, you can often fix it by identifying the two parser
states that are being confused, and adding something to make them look
distinct. In the above example, adding one rule to tt(return_spec) as follows
makes the problem go away:
        verb(
    %token BOGUS
    ...
    %%
    ...
    return_spec:
        type
    |    
        name ':' type
    |    
        ID BOGUS        // This rule is never used. 
    ;
        ) 
    This corrects the problem because it introduces the possibility of an
additional active rule in the context after the tt(ID) at the beginning of
tt(return_spec). This rule is not active in the corresponding context in a
tt(param_spec), so the two contexts receive distinct parser states. As long as
the token tt(BOGUS) is never generated by the parser's member function
tt(lex()), the added rule cannot alter the way actual input is parsed.

In this particular example, there is another way to solve the problem: rewrite
the rule for tt(return_spec) to use tt(ID) directly instead of via name. This
also causes the two confusing contexts to have different sets of active rules,
because the one for tt(return_spec) activates the altered rule for
tt(return_spec) rather than the one for name.
        verb(
    param_spec:
        type
    |    
        name_list ':' type
    ;

    return_spec:
        type
    |    
        ID ':' type
    ;
        )



