class ExpressionParser extends Parser; options { buildAST=true; } imaginaryTokenDefinitions : SIGN_MINUS SIGN_PLUS ; expr : {System.out.println("trying expr");} LPAREN^ sumExpr RPAREN! {System.out.println("matched expr");}; sumExpr : {System.out.println("trying sumExpr");} prodExpr ((PLUS^|MINUS^) prodExpr)* {System.out.println("matched sumExpr");}; prodExpr : {System.out.println("trying prodExpr");} powExpr ((MUL^|DIV^|MOD^) powExpr)* {System.out.println("matched prodExpr");}; powExpr : {System.out.println("trying powExpr");} signExpr (POW^ signExpr)? {System.out.println("matched powExpr");} ; signExpr : {System.out.println("trying signExpr");} ( m:MINUS^ {#m.setType(SIGN_MINUS); System.out.println("matched signExpr");} | p:PLUS^ {#p.setType(SIGN_PLUS); System.out.println("matched signExpr");} )? atom ; atom : {System.out.println("trying atom");} INT | expr {System.out.println("matched atom");}; class ExpressionLexer extends Lexer; PLUS : '+' ; MINUS : '-' ; MUL : '*' ; DIV : '/' ; MOD : '%' ; POW : '^' ; LPAREN: '(' ; RPAREN: ')' ; SEMI : ';' ; protected DIGIT : '0'..'9' ; INT : (DIGIT)+ ; WS : (' ' | '\t' | '\r' | '\n') {$setType(Token.SKIP);} ; {import java.lang.Math;} class ExpressionTreeWalker extends TreeParser; expr returns [double r] { double a,b; r=0; } : #(PLUS a=expr b=expr) { r=a+b; } | #(MINUS a=expr b=expr) { r=a-b; } | #(MUL a=expr b=expr) { r=a*b; } | #(DIV a=expr b=expr) { r=a/b; } | #(MOD a=expr b=expr) { r=a%b; } | #(POW a=expr b=expr) { r=Math.pow(a,b); } | #(LPAREN a=expr) { r=a; } | #(SIGN_MINUS a=expr) { r=-1*a; } | #(SIGN_PLUS a=expr) { if(a<0)r=0-a; else r=a; } | i:INT { r=(double)Integer.parseInt(i.getText()); } ;