tree grammar CMinusTree; options { tokenVocab=CMinus; output=template; ASTLabelType=CommonTree; } program scope { StringTemplate foo } @init { $program::foo = templateLib.getInstanceOf("program" ); } : (declaration[$program::foo])+ -> {$program::foo} ; declaration[StringTemplate code]: ^(GLOBALS variable) {($program::foo).setAttribute("globals", $variable.st);} -> {$variable.st} | ^(FUNCTIONS function) {$program::foo.setAttribute("functions", $function.st);} -> {$function.st} ; variable: ^(VAR type declarator) -> variable(type={$type.st}, name={$declarator.text}) ; function: ^(FUNCTION type ID ^(PARAMS (arg+=formalParameter)+) ^(BLOCK block)) -> function(type={$type.st}, name={$ID.text}, args={$arg}, locals={$block.vv}, stats={$block.ss}) ; formalParameter: ^(PARAM type declarator) -> parameter(type={$type.st}, name={$declarator.text}) ; block returns[List vv, List ss] : ^(LOCALS (v+=variable)*) ^(STATEMENTS (s+=stat)*) {$vv = $v; $ss = $s; } ; stat: forStat -> {$forStat.st} | expr -> statement(expr = {$expr.st}) | block -> statementList(locals={$block.vv}, stats={$block.ss}) | assignStat -> {$assignStat.st} ; forStat: ^(FOR ^(INIT e1=assignStat) ^(COND condExpr) ^(STMT e3=assignStat) ^(BLOCK block)) -> forLoop(e1={$e1.st}, e2={$condExpr.st}, e3={$e3.st}, locals={$block.vv}, stats={$block.ss}) ; assignStat: ^(ASSIGN ID expr) -> assign(lhs={$ID.text}, rhs={$expr.st}) ; expr: condExpr -> {$condExpr.st} ; condExpr: ^(EQUALS a1=aexpr a2=aexpr) -> equals(left={$a1.st}, right={$a2.st}) | ^(LT a1=aexpr a2=aexpr) -> lessThan(left={$a1.st}, right={$a2.st}) | aexpr -> {$aexpr.st} /* aexpr ( (EQUALS | LT)^ aexpr )?*/ ; aexpr: ^(PLUS a1=atom a2=atom) -> add(left={$a1.text}, right={$a2.text}) | atom -> iconst(value={$atom.text}) // atom ( // PLUS^ atom // )* ; atom: ID | INT | LPAREN expr RPAREN ; type: 'int' -> type_int() | 'char' -> type_char() | ID ; declarator: ID ;