/ GENTLE PRIMER
/ At a Glance
In this section we show how to process abstract syntax. For this purpose we discuss a calculator which is based on abstract syntax.
The root clause of this specification has the form
'root' expression(-> X) eval(X -> N) print(N)
where expression is defined as in the preceding example. It yields a term X of type Expr, as defined above.
eval is a procedure with one input parameter of type Expr and one output parameter of type INT. It maps its input value (the abstract syntax of a particular expression) onto the numeric value of this expression.
This mapping is defined by the following rules.
'action' eval (Expr -> INT) 'rule' eval(plus(X1, X2) -> N1+N2): eval(X1 -> N1) eval(X2 -> N2) 'rule' eval(minus(X1, X2) -> N1-N2): eval(X1 -> N1) eval(X2 -> N2) 'rule' eval(mult(X1, X2) -> N1*N2): eval(X1 -> N1) eval(X2 -> N2) 'rule' eval(div(X1, X2) -> N1 / N2): eval(X1 -> N1) eval(X2 -> N2) 'rule' eval(neg(X) -> -N): eval(X -> N) 'rule' eval(num(N) -> N)
Whereas in concrete syntax rules are selected according to the structure of the concrete input, here rules are selected according to the structure of the terms of the abstract syntax. In this example, there is a rule for each alternative of the type Expr that specifies how to compute the numerical value from the numerical value of the constituents of the term.
Consider the rule
'rule' eval(plus(X1, X2) -> N1+N2): eval(X1 -> N1) eval(X2 -> N2)which is selected if the input term of eval has the structure plus(S1,S2) with subterms S1 and S2. The variables X1 and X2 are defined as these subterms. The invocations eval(X1 -> N1) and eval(X2 -> N2) define N1 and N2 as the numeric values of the corresponding subterms. These values are then used to compute the output parameter N1 + N2.
For example, if the input term is plus(num(10), mult(num(20), num(30)), then X1 is defined as num(10) and X2 is defined as mult(num(20), num(30)). The recursive invocations of eval then define N1 as 10 (the numeric value of X1) and N2 as 600 (the numeric value of X2). With these values the output parameter of the left-hand side is computed, N1+N2 yields 610.