The tt(exp) grouping has several rules, one for each kind of expression. The
first rule handles the simplest expressions: those that are just numbers. The
second handles an addition-expression, which looks like two expressions
followed by a plus-sign. The third handles subtraction, and so on.
        verb(
    exp:      
            NUM             
    | 
            exp exp '+'     
            { 
                $$ = $1 + $2;    
            }
    | 
            exp exp '-'     
            { 
                $$ = $1 - $2;    
            }
    ...
        )
    It is customary to use `tt(|)' to join all the rules for exp, but the
rules could equally well have been written separately:
        verb(
    exp:      
            NUM             
    ;

    exp:
            exp exp '+'     
            { 
                $$ = $1 + $2;    
            }
    ;

    exp:
            exp exp '-'     
            { 
                $$ = $1 - $2;    
            }
    ;

    ...
        )
    Most of the rules have actions that compute the value of the expression in
terms of the values of its parts. For example, in the rule for addition,
tt($1) refers to the first component tt(exp) and tt($2) refers to the second
one. The third component, 'tt(+)', has no meaningful associated semantic
value, but if it had one you could refer to it as tt($3). When the parser's
parsing function tt(parse()) recognizes a sum expression using this rule, the
sum of the two subexpressions' values is produced as the value of the entire
expression. See section ref(ACTIONS).

You don't have to give an action for every rule. When a rule has no action,
Bison by default copies the value of tt($1) into tt($$). This is what happens
in the first rule (the one that uses tt(NUM)).

The formatting shown here is the recommended convention, but Bison does not
require it. You can add or change whitespace as much as you wish.
