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.