Archive: expreval-2005-01-23.zip inflating: expreval/src/grammar/expression.g header { package net.christopherschultz.evaluator.parser; import java.util.ArrayList; import java.util.List; import net.christopherschultz.evaluator.*; } class ExpressionParserImpl extends Parser; options { buildAST = false; k=2; // 2-token lookahead: can differentiate between // ( MINUS INT ) and ( MINUS FLOAT ) } /* We have expr and mexpr separate, with the addition and subtraction separate from multiplication in order to enforce order-of-operations. */ expr returns [Expression exp = null] { Expression right; } : exp=relexpr ( ( AND^ right=relexpr) { exp = new MathExpression(exp, "&&", right); } | (OR^ right=relexpr) { exp = new MathExpression(exp, "||", right); } )* // This (EOF)? seem totally sketchy, but it works! (EOF)? ; // Relational Expression relexpr returns [Expression exp = null] { Expression right; } : exp=addexpr ( (EQUALS^ right=addexpr) { exp = new MathExpression(exp, "=", right); } | (NOT_EQUALS^ right=addexpr) { exp = new MathExpression(exp, "!=", right); } | (GREATERTHAN^ right=addexpr) { exp = new MathExpression(exp, ">", right); } | (LESSTHAN^ right=addexpr) { exp = new MathExpression(exp, "<", right); } | (GREATERTHANEQUALTO^ right=addexpr) { exp = new MathExpression(exp, ">=", right); } | (LESSTHANEQUALTO^ right=addexpr) { exp = new MathExpression(exp, "<=", right); } )* ; // Arithmetic Expression addexpr returns [Expression exp = null] { Expression right; } : exp=multexpr (( PLUS^ right=multexpr { exp = new MathExpression(exp, "+", right); } | MINUS^ right=multexpr { exp = new MathExpression(exp, "-", right); } ))* ; // Multiplicative (or divisive) expression multexpr returns [Expression exp = null] { Expression right; } : exp=negexpr ( ( STAR^ right=negexpr { exp = new MathExpression(exp, "*", right); } ) | ( SLASH right=negexpr { exp = new MathExpression(exp, "/", right); } ) | ( PERCENT right=negexpr { exp = new MathExpression(exp, "%", right); } ) )* ; // (Logically) negated expression negexpr returns [ Expression exp = null ] : ((BANG^ exp=atom { exp = new NegatedExpression(exp); }) | exp=atom) ; // Function call expression functioncall returns [ Expression exp = null ] { List args = null; } : func:IDENTIFIER^ LPAREN! (args=argumentlist)? RPAREN! { exp = new FunctionCallExpression(func.getText(), args); } ; // Argument List argumentlist returns [List list = new ArrayList()] { Expression arg; } : arg=argument { list.add(arg); } (COMMA! arg=argument { list.add(arg); })* ; // Argument (i.e. anything) argument returns [Expression exp = null] : exp=expr ; // Indentifiers (i.e. symbols) identifier returns [ Expression exp = null ] : id:IDENTIFIER { exp = new IdentifierExpression(id.getText()); } ; // Atoms atom returns [Expression exp = null] : exp=functioncall | exp=identifier | i:INT { exp = new ConstantExpression(new Integer(i.getText())); } | (MINUS j:INT ) { exp = new ConstantExpression(new Integer("-" + j.getText())); } | (PLUS k:INT ) { exp = new ConstantExpression(new Integer(k.getText())); } | f:FLOAT { exp = new ConstantExpression(new Double(f.getText())); } | (MINUS g:FLOAT) { exp = new ConstantExpression(new Double("-" + g.getText())); } | (PLUS h:FLOAT) { exp = new ConstantExpression(new Double(h.getText())); } | s:STRING { exp = new ConstantExpression(s.getText()); } | LPAREN! exp=expr RPAREN! | ( PLUS LPAREN! exp=expr RPAREN! ) | ( MINUS LPAREN! exp=expr RPAREN! ) { exp = new UnaryMinusExpression(exp); } ; class ExpressionLexerImpl extends Lexer; options { k=2; // (2)needed for newline junk, (5) needed for booleans charVocabulary = '\3'..'\377'; } IDENTIFIER: WORDCHAR (WORDCHAR | DIGIT)*; STRING : DOUBLEQUOTE! (CHAR_ESC | ~('\"' | '\\') )* DOUBLEQUOTE! ; protected CHAR_ESC : '\\' ( 'n' { $setText("\n"); } | 'r' { $setText("\r"); } | 't' { $setText("\t"); } | 'b' { $setText("\b"); } | 'f' { $setText("\f"); } | '\"' { $setText("\""); } | '\'' { $setText("\'"); } | '\\' { $setText("\\"); } ) ; INT_OR_FLOAT: (DOT INT) => FLOAT { $setType(FLOAT); } | (INT DOT) => FLOAT { $setType(FLOAT); } | (INT) { $setType(INT); } ; protected INT: (DIGIT)+ ; protected FLOAT: ((DIGIT)+)? DOT (DIGIT)+ ; protected WORDCHAR: 'a'..'z' | 'A'..'Z' | '_' ; protected DIGIT: '0'..'9'; BANG: '!' ; protected DOT: '.' ; COMMA: ',' ; LPAREN: '(' ; RPAREN: ')' ; PLUS: '+' ; MINUS: '-' ; STAR: '*' ; PERCENT: '%' ; SLASH: '/' ; AND: '&''&' ; OR: '|''|' ; EQUALS: '=' ; NOT_EQUALS : BANG EQUALS ; GREATERTHAN: '>' ; LESSTHAN: '<' ; GREATERTHANEQUALTO: '>' '=' ; LESSTHANEQUALTO: '<' '=' ; SINGLEQUOTE: '\'' ; DOUBLEQUOTE: '\"' ; /* protected TRUE: 't''r''u''e' ; protected FALSE: 'f''a''l''s''e' ; */ WS: ( ' ' | '\t' | '\r' '\n' { newline(); } | '\n' { newline(); } ) {$setType(Token.SKIP);} //ignore this token ;