Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
public Object downup(Object t, boolean showTransformations) {
    this.showTransformations = showTransformations;
    TreeVisitor v = new TreeVisitor(new CommonTreeAdaptor());
    TreeVisitorAction actions = new TreeVisitorAction() {
        public Object pre(Object t)  { return applyOnce(t, topdown_fptr); }
        public Object post(Object t) { return applyRepeatedly(t, bottomup_ftpr); }
    };  
    t = v.visit(t, actions);
    return t;
}   

If you don't like the strategy that I've implemented by default, you can trivially make your own by cutting and pasting from downup().

Tree patterns

First, remember that we are not specify entire tree grammar. We are primarily looking for subtrees of interest. Tree grammars specify not only the patterns but how to visit the tree. With patterns, we use the dot (wildcard) a lot. The following pattern matches an add subtree anywhere in the tree:

...

Code Block
exitMethod
    :   METHOD_DECL
        {
        System.out.println("args: "+currentScope);
        currentScope = currentScope.getEnclosingScope();    // pop arg scope
        }
    ;

Tree rewriting

The rule speciļ¬es a Think of the tree rewriting patterns as tree pattern to tree pattern mapping.mappings. For example, here is how we would do some Boolean simplifications:

Code Block
e : ^('!' 'true') -> 'false' // !true -> false 
  | ^('!' 'false') -> 'true' // !false -> true 
  | ^('&&' 'true' x=.) -> $x // true && x -> x 
  | ^('&&' x=. 'true') -> $x // x && true -> x 
;

With predicates, we can check for multiply by zeroes:

Code Block
zeroX : ^('*' a=INT b=INT {$a.int==0}?) -> $a ; // 0*x -> 0 
xZero : ^('*' a=INT b=INT {$b.int==0}?) -> $b ; // x*0 -> 0

...