1 /////////////////////////////////////////////////////////////////////////////
2 // This program demonstrates the use of attribute evaluation in Prop's
4 /////////////////////////////////////////////////////////////////////////////
8 /////////////////////////////////////////////////////////////////////////////
9 // The datatype EXP represents a simple expression (with pretty printing.)
10 /////////////////////////////////////////////////////////////////////////////
11 datatype EXP :: rewrite
13 | add (EXP, EXP) => "(" _ " + " _ ")"
14 | sub (EXP, EXP) => "(" _ " - " _ ")"
15 | mul (EXP, EXP) => "(" _ " * " _ ")"
16 | div (EXP, EXP) => "(" _ " / " _ ")"
19 /////////////////////////////////////////////////////////////////////////////
20 // The rewrite class Eval involves the transformation of datatype
22 /////////////////////////////////////////////////////////////////////////////
23 rewrite class Eval (EXP : int) :: treeparser {};
25 /////////////////////////////////////////////////////////////////////////////
26 // Now, here are the rules. Pattern variables of the form '$x' refer
27 // to synthesized attributes. (Normal pattern variables of the
28 // form 'x' still refer to the components of a term.)
30 // Notice that nested attributes and guards on attribute values
31 // are both allowed. (The nested attribute rule is contrived.)
32 /////////////////////////////////////////////////////////////////////////////
34 num (x as _): { ## = x; }
35 | add (x as _, y as _): { ## = #x + #y; }
36 | sub (x as _, y as _): { ## = #x - #y; }
37 // | mul (x, add(y,z)): { ## = $x * (#y + #z); } // nested attributes
38 | mul (x as _, y as _): { ## = #x * #y; }
39 | div (x as _, y as _) where (#y != 0): { ## = #x / #y; }
40 | div (x as _, y as _): { cerr << "Division by zero\n"; ## = 0; }
43 /////////////////////////////////////////////////////////////////////////////
44 // Generate the implementation of the datatype.
45 /////////////////////////////////////////////////////////////////////////////
46 instantiate datatype EXP;
48 /////////////////////////////////////////////////////////////////////////////
49 // Test the rewriting rules.
50 /////////////////////////////////////////////////////////////////////////////
52 { // Instantiate a rewriting class.
55 // e = (1 + 2) * (5 - 3)
56 EXP e = mul(add(num(1), num(2)), sub(num(5),num(3)));
58 cout << e << " = " << eval(e) << '\n';