Abstract Syntax Tree Discrete Mathematics and Its Applications Baojian Hua
Grammar Consider this simple grammar: exp -> exp + exp | exp-exp | num Sample program: The set of nums in this exp is {4, 3, 5}
Abstract Syntax Tree (AST) Consider this simple grammar: exp -> exp + exp | exp-exp | num Sample program: Our goal: represent such kind of trees in a computer!
Abstract Syntax Tree In C
Union Recall the definition of a union: union uuu { int i; double f; }; union uuu u; u.i = 99; u.f? // Dangerous! i f
Tagged Union struct tu { enum {INT, DOUBLE} kind; union uuu { int i; double f; } u; }; struct tu x; x.u.i = 99; // atomic operations x.kind = INT; if (x.kind==INT) … // Perfect! :-P i f kind
AST Recall the grammar for expression: exp -> exp+exp | exp-exp | num Oh, it ’ s just a kind of (tagged) union! :-)
The Interface #ifndef MINIC_H #define MINIC_H typedef struct exp *exp; struct exp { enum {ADD, SUB, NUM} kind; // +, -, integer union { struct{ exp e1; exp e2; } binop; // left binop right int num; // num } u; }; // functions on next slide
The Interface // miniC interface continued // constructors for building the tree exp newExpAdd (exp e1, exp e2); exp newExpSub (exp e1, exp e2); exp newExpNum (int i); // return the set of numbers in expression e set numsSet (exp e); #endif
Implementation #include “miniC.h” exp newExpAdd (exp e1, exp e2) { exp e = malloc (sizeof (*e)); e->kind = ADD; (e->u).binop.e1 = e1; (e->u).binop.e2 = e2; return e; } // others are similar, leave to you
Implementation #include “miniC.h” // The definiton of numsSet. For simplicity, we // write “f” for this function. { f(e1) f(e2), if e is e1+e2; f(e)= { f(e1) f(e2), if e is e1-e2; { {num}, otherwise. (e1 is num)
Implementation #include “miniC.h” // From definition to code. This function // familiarize you with recursion functions. set numsSet (exp e){ switch (e->kind){ case ADD: { return setUnion (numsSet ((e->u).binop.e1), numsSet ((e->u).binop.e2)); } case SUB: … // similar case NUM: return setInsert (newSet(), (e->u).i); }
Client Code int main () { // exp e1 = newExpNum (4); exp e2 = newExpNum (3); exp e3 = newExpNum (5); exp e4 = newExpNum (4); exp e5 = newExpAdd (e1, e2); exp e6 = newExpSub (e5, e3); exp e7 = newExpAdd (e6, e4); // the final tree numsSet (e7); // number set return 0; }
Client Code int main () { // exp e1 = newExpNum (4); exp e2 = newExpNum (3); exp e3 = newExpNum (5); exp e4 = newExpNum (4); exp e5 = newExpAdd (e1, e2); exp e6 = newExpSub (e5, e3); exp e7 = newExpAdd (e6, e4); // the final tree numsSet (e7); // number set return 0; }
Client Code int main () { // exp e1 = newExpNum (4); exp e2 = newExpNum (3); exp e3 = newExpNum (5); exp e4 = newExpNum (4); exp e5 = newExpAdd (e1, e2); exp e6 = newExpSub (e5, e3); exp e7 = newExpAdd (e6, e4); // the final tree numsSet (e7); // number set return 0; }
Client Code int main () { // exp e1 = newExpNum (4); exp e2 = newExpNum (3); exp e3 = newExpNum (5); exp e4 = newExpNum (4); exp e5 = newExpAdd (e1, e2); exp e6 = newExpSub (e5, e3); exp e7 = newExpAdd (e6, e4); // the final tree numsSet (e7); // number set return 0; }
Client Code int main () { // exp e1 = newExpNum (4); exp e2 = newExpNum (3); exp e3 = newExpNum (5); exp e4 = newExpNum (4); exp e5 = newExpAdd (e1, e2); exp e6 = newExpSub (e5, e3); exp e7 = newExpAdd (e6, e4); // the final tree numsSet (e7); // number set return 0; }
Client Code int main () { // exp e1 = newExpNum (4); exp e2 = newExpNum (3); exp e3 = newExpNum (5); exp e4 = newExpNum (4); exp e5 = newExpAdd (e1, e2); exp e6 = newExpSub (e5, e3); exp e7 = newExpAdd (e6, e4); // the final tree numsSet (e7); // number set return 0; }
Client Code int main () { // exp e1 = newExpNum (4); exp e2 = newExpNum (3); exp e3 = newExpNum (5); exp e4 = newExpNum (4); exp e5 = newExpAdd (e1, e2); exp e6 = newExpSub (e5, e3); exp e7 = newExpAdd (e6, e4); // the final tree numsSet (e7); // number set return 0; }
Client Code int main () { // exp e1 = newExpNum (4); exp e2 = newExpNum (3); exp e3 = newExpNum (5); exp e4 = newExpNum (4); exp e5 = newExpAdd (e1, e2); exp e6 = newExpSub (e5, e3); exp e7 = newExpAdd (e6, e4); // the final tree numsSet (e7); // number set return 0; }
Abstract Syntax Tree In Java
Union in Java? Java does not support explicit unions directly :-( However, the class hierarchy of Java implicitly support this :-) Consider again: union { int i; double f; } x;
Union in Java? // A mimic of unions in Java using two classes: class MyInt{ int i; … } class MyDouble{ double f; … } // Why?
Local Class Hierarchy // However, this hierarchy is too loose, so we // want to build a local class hierarchy: abstract class Exp{} class ExpAdd extends Exp { Exp e1; Exp e2; … // constructors and methods } class ExpSub extends Exp { // similar } class ExpNum extends Exp { int i; … // constructors and methods }
In Picture ExpNumExpSubExpAdd Exp
Local Class Hierarchy // Operations: (ugly version) Set numsSet (Exp e){ if (e instanceof ExpAdd){ … } else if (e instanceof ExpSub) { … } else if (e instanceof ExpNum) { … } else throw new Error (…); } // Or, use the visitor pattern.
Client Code // In main method: Exp e1 = new ExpNum (4); Exp e2 = new ExpNum (3); Exp e3 = new ExpNum (5); Exp e4 = new ExpNum (4); Exp e5 = new ExpAdd (e1, e2); Exp e6 = new ExpSub (e5, e3); Exp e7 = new ExpAdd (e6, e4); Set set = e7.numsSet ();