HANDBOOK / GENTLE PRIMER / At a Glance /

# A Calculator

In this section, we turn the parser into a simple calculator. It will read its input (which must be an expression as defined by the above grammar) and print the value of the expression.

Our starting point is the parser given above. Each nonterminal gets an output parameter that specifies its value.

    'root' expression(-> X) print(X)

    'nonterm' expression(-> INT)

       'rule' expression(-> X): expr2(-> X)
       'rule' expression(-> X+Y): expression(-> X) "+" expr2(-> Y)
       'rule' expression(-> X-Y): expression(-> X) "-" expr2(-> Y)

    'nonterm' expr2(-> INT)

       'rule' expr2(-> X): expr3(-> X)
       'rule' expr2(-> X*Y): expr2(-> X) "*" expr3(-> Y)
       'rule' expr2(-> X/Y): expr2(-> X) "/" expr3(-> Y)

    'nonterm' expr3(-> INT)

       'rule' expr3(-> X): Number(-> X)
       'rule' expr3(-> - X): "-" expr3(-> X)
       'rule' expr3(-> + X): "+" expr3(-> X)
       'rule' expr3(-> X): "(" expression(-> X) ")"

    'token' Number(-> INT)

Nonterminals and tokens can have output parameters.

    'nonterm' expression(-> INT)

introduces the nonterminal `expression` with one output parameter of type `INT`.

The rule

    'rule' expression(-> X+Y): expression(-> X) "+" expr2(-> Y)

specifies how the value of an `expression` is computed from the values of its constituents.

`expression(-> X)` and `expr2(-> Y)` on the right hand side define the variables `X` and `Y` as the values of the `expression` and the `expr2` constituents of the parsed phrase. For example, if the phrase is `10+20*30`, then `X` is defined as 10 and `Y` is defined as 600.

`expression(-> X + Y)` on the left hand side defines the value of the phrase parsed according to this rule as the sum of `X` and `Y`, i.e. as 610 in the example given.

    'root' expression(-> X) print(X)

defines the following elaboration: Parse the input as an `expression`. This yields a value `X`. Print `X`.