A b() grammar rule has the following general form:
        verb( 
    result: 
        components
        ...
    ;
        )
    where em(result) is the nonterminal symbol that this rule describes and
em(components) are various terminal and nonterminal symbols that are put
together by this rule (see section ref(SYMBOLS)). With respect to the way
rules are defined, note the following:
    itemization(
    it() The construction:
        verb(
    exp:    
        exp '+' exp
    ;
        )
    means that two groupings of type tt(exp), with a `+' token in between, can
be combined into a larger grouping of type tt(exp).

    it() Whitespace in rules is significant only to separate symbols. You can
add extra whitespace as you wish.

    it() Scattered among the components can be em(actions) that determine the
semantics of the rule. An action looks like this:
        verb(
    {
        C++ statements
    }
        )
    Usually there is only one action and it follows the components. See
section ref(ACTIONS).

    it() Multiple rules for the same result can be written separately or can
be joined with the vertical-bar character `|' as follows:
        verb(
    result: 
        rule1-components
        ...
    | 
        rule2-components...
        ...
    ;
        )
    They are still considered distinct rules even when joined in this way.

    it() Alternatively, multiple rules of the same nonterminal can be
defined. E.g., the previous definition of tt(result:) could also have been
defined as:
        verb(
    result: 
        rule1-components
        ...
    ;

    result:
        rule2-components...
        ...
    ;
        )
    However, this is a potentially dangerous practice, since one of the two
tt(result) rules could also have used a misspelled rule-name (e.g., the second
tt(result)) should have been tt(results). Therefore, b() generates a
warning if the same nonterminal is used repeatedly when defining production
rules. 

    it() If em(components) in a rule is em(empty), it means that em(result)
can match the empty string. Such a alternative is called an em(empty
production rule). For example, here is how to define a
comma-separated sequence of zero or more tt(exp) groupings:
        verb(
    expseq:   
        expseq1
    | 
        // empty 
    ;

    expseq1:  
        expseq1 ',' exp
    | 
        exp
    ;
        )
    Convention calls for a comment `tt(// empty)' in each empty production
rule.
    )
