Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

So, let's do some rewriting using the pattern matching filter=true mode. Again, the VecMath.g parser will build trees but we'll avoid building an entire tree grammar. We'll focus on some patterns we want to rewrite.

Here's the grammar to build trees.

grammar VecMath;
options {output=AST;} // we want to create ASTs
tokens {
    MULT='*';
    SHIFT;    // needed during simplification
    VEC;      // define imaginary VEC for vector literal
}

prog:   stat+ ;                         // build list of stat trees
stat:   ID '=' expr  -> ^('=' ID expr)  // '=' is operator subtree root
    |   'print' expr -> ^('print' expr) // 'print' is subtree root
    ;

expr:   multExpr ('+'^ multExpr)* ;     // '+' is root node

multExpr
    :   primary (('*'^|'.'^) primary)*  // '*', '.' are roots
    ;

primary
    :   INT
    |   ID
    |   '[' expr (',' expr)* ']' -> ^(VEC expr+)
    |   '(' expr ')'             -> expr
    ;

ID  :   'a'..'z'+ ;
INT :   '0'..'9'+ ;
WS  :   (' '|'\r'|'\n')+ {skip();} ;

And now, let's distribute scalar-vector multiplies. 4*1,2 = 4*1,4*2.

tree grammar Simplify;
options {
    tokenVocab=VecMath;      // use tokens from VecMath.g
    ASTLabelType=CommonTree; // we're using CommonTree nodes
    output=AST;              // build ASTs from input AST
    filter=true;             // tree pattern matching, rewrited mode
}

topdown
    :   ^('*' INT ^(VEC (e+=.)+)) -> ^(VEC ^('*' INT $e)+)
    ;

bottomup
    :  ^('*' a=. b=INT {$b.int==0}?) -> $b // x*0 -> 0
    ;
  • No labels