/* Generated By:JavaCC: Do not edit this line. ExpressionParser.java */ package prefuse.data.expression.parser; import java.io.StringReader; import java.util.logging.Logger; import prefuse.data.expression.AndPredicate; import prefuse.data.expression.ArithmeticExpression; import prefuse.data.expression.BooleanLiteral; import prefuse.data.expression.ColumnExpression; import prefuse.data.expression.ComparisonPredicate; import prefuse.data.expression.Expression; import prefuse.data.expression.Function; import prefuse.data.expression.FunctionTable; import prefuse.data.expression.IfExpression; import prefuse.data.expression.NotPredicate; import prefuse.data.expression.NumericLiteral; import prefuse.data.expression.ObjectLiteral; import prefuse.data.expression.OrPredicate; import prefuse.data.expression.Predicate; import prefuse.data.expression.XorPredicate; import prefuse.util.StringLib; /** * Parser for statements written in the prefuse expression language. Text * expression are parsed into {@link prefuse.data.expression.Expression} * instances, and can be used as predicates or to create derived * table columns. This parser is implemented using the * JavaCC package. To parse * a text String to an {@link prefuse.data.expression.Expression}, use * the {@link #parse(String)} method. If a parse error occurs, the method * will fail silently and return null. Any generated exception can be * later retrieved using the {@link #getError()} method. One can also * use the {@link #parse(String, boolean)} with a true * boolean argument to request that Exceptions be thrown when * errors occur. * *

Prefuse Expression Language Reference

*

* The prefuse expression language provides a convenient way of creating manipulable statements * over data in a prefuse data structure. For example, the expression language can be used to * write {@link prefuse.data.expression.Predicate} instances for querying and filtering a table * or graph, or to create arbitrary expressions over a data set to generate new, derived data * fields that can in turn be subject to additional processing or visualization. For example, * the {@link prefuse.data.tuple.TupleSet#tuples(prefuse.data.expression.Predicate)} method * uses a Predicate to filter the requested set of tuples, and the * {@link prefuse.data.Table#addColumn(java.lang.String,prefuse.data.expression.Expression)} * method creates a new table column whose values are generated by the provided Expression. * The expression machinery is used * throughout the toolkit -- it underlies the filtering and query optimization features, * is a key component of {@link prefuse.data.query dynamic query bindings}, and is used to * create the rule chains evaluated by the * {@link prefuse.render.DefaultRendererFactory}, * {@link prefuse.action.assignment.ColorAction}, * {@link prefuse.action.assignment.ShapeAction}, * {@link prefuse.action.assignment.FontAction}, and * {@link prefuse.action.assignment.SizeAction} classes. *

*

* The {@link prefuse.data.expression.Expression} interface is quite simple: given a single * Tuple, compute and return a value. The returned value could be an Object, a boolean, an int, * or other primitive type. Individual methods for each type are available, and which ones are * legal to call for any given Expression depends on the type of Expression. *

*

* Expressions can be created directly in Java, by instantiating and chaining together the * desired Expression instances. This process, however, can be somewhat tedious, so prefuse * also provides a built-in parser/compiler for generating these chains of Expression * instances from a textual language. The language is based on a subset of SQL, the * standard language for database queries. If you have ever written a "WHERE" clause in * a SQL "SELECT" query, you probably know most of the language already. To parse an * expression, simply pass a text string containing an expression statement to the * {@link prefuse.data.expression.parser.ExpressionParser#parse(java.lang.String)} * method. If the string parses successfully, the parsed Expression instance will be * returned. *

*

* Below is the reference for the language, including literal types, data field references, * basic operators, and included functions. If need be, you can also introduce a new * function by creating a new instance of the {@link prefuse.data.expression.Function} interface * and registering it with the {@link prefuse.data.expression.FunctionTable} class. *

*

* All keywords and functions in the prefuse expression language can be written in * either uppercase or lowercase. Writing in mixed-case, however, will likely result in parse * errors. *

* *

Literal Values and Data Field References

*

The fundamental building blocks of the expression language, representing data values * or referencing the contents of a Tuple data field.

* * *

Operators and Control Flow

*

Basic operators and control flow structures for the expression language.

* * *

General Functions

*

General purpose functions.

* * *

Mathematical Functions

*

Functions for performing mathematical calculations.

* * *

String Functions

*

Functions for processing text strings.

* * *

Color Functions

*

Functions for generating, translating, and interpolating color values.

* * *

Visualization Functions

*

These functions can only be used when the Tuple being evaluated is * a VisualItem, and provide access to data group information of the VisualItem's * Visualization. Individual visual data fields can be accessed directly using * a data field reference. For example, _x, _y, * _hover, _highlight, _fillColor would * evaluate to references for the x-coordinate, y-coordinate, mouse hover status, * highlight status, and fill color, respectively.

* * * @author jeffrey heer */ public class ExpressionParser implements ExpressionParserConstants { private static final Logger s_logger = Logger.getLogger(ExpressionParser.class.getName()); private static boolean s_init = false; private static Throwable s_error; /** * Parse an expression. * @param expr the expression text to parse * @param throwsException true if this method should throw an * exception if an error occurs or should fail quietly * @return the parsed Expression, or null if the parse failed * and throwsException is false */ public synchronized static Expression parse(String expr, boolean throwsException) { // initialize the parser if ( !s_init ) { new ExpressionParser(new StringReader(expr)); s_init = true; } else { ExpressionParser.ReInit(new StringReader(expr)); } // attempt to parse the expression try { Expression e = Parse(); s_error = null; s_logger.info("Parsed Expression: "+e); return e; } catch ( ParseException t ) { s_error = t; if ( throwsException ) { throw t; } else { s_logger.warning("Expression Parse Error: " + t.getMessage() + "\n" + StringLib.getStackTrace(t)); return null; } } } /** * Parse an expression. This method does not throw an exception if * a parse error occurs. Use {@link #getError()} to access any * generated exceptions. * @param expr the expression text to parse * @return the parsed Expression, or null if the parse failed */ public synchronized static Expression parse(String expr) { return parse(expr, false); } /** * Get the last error, if any, generated by a parse operation. * @return the last error generated during parsing */ public synchronized static Throwable getError() { return s_error; } /** * Replace escape sequences with represented characters. This * includes newlines, tabs, and quotes. * @param s the input String, possibly with escape sequences * @return a String with recognized escape sequences properly replaced */ private static String unescape(String s) { int len = s.length(), base = 0, idx; String escapes = "tnrbf\\\"'"; String chars = "\t\n\r\b\f\\\"'"; StringBuffer sbuf = null; while ( (idx=s.indexOf('\\',base)) != -1) { if ( sbuf != null ) sbuf.append(s.substring(base, idx)); if (idx+1 == len) break; // find escape character char c = s.charAt(idx+1); // find the index of the escape character int cidx = escapes.indexOf(c); if (cidx == -1) { // no match, so continue sbuf.append('\\'); sbuf.append(c); } else { // replace escape sequence with true char if ( sbuf == null ) sbuf = new StringBuffer(s.substring(base, idx)); sbuf.append(chars.charAt(cidx)); } // skip over escape sequence base = idx + 2; } if ( sbuf != null && base < len ) sbuf.append(s.substring(base)); return ( sbuf == null ? s : sbuf.toString() ); } // ---------------------------------------------------------------------------- // Grammar definitions static final public String Name() throws ParseException { Token t; t = jj_consume_token(IDENTIFIER); {if (true) return t.image;} throw new Error("Missing return statement in function"); } static final public String Quoted() throws ParseException { Token t; t = jj_consume_token(QUOTED); {if (true) return t.image.substring(1,t.image.length()-1);} throw new Error("Missing return statement in function"); } static final public Expression Parse() throws ParseException { Expression e; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case TRUE: case FALSE: case NULL: case IF: case NOT: case INT: case LONG: case DOUBLE: case FLOAT: case STRING: case QUOTED: case IDENTIFIER: case LPAREN: case ADD: case SUB: e = Expression(); jj_consume_token(0); {if (true) return e;} break; case 0: jj_consume_token(0); {if (true) throw new ParseException("No expression provided");} break; default: jj_la1[0] = jj_gen; jj_consume_token(-1); throw new ParseException(); } throw new Error("Missing return statement in function"); } static final public Expression Expression() throws ParseException { Expression e; e = OrExpression(); {if (true) return e;} throw new Error("Missing return statement in function"); } static final public Expression OrExpression() throws ParseException { Expression l, r; l = XorExpression(); label_1: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case OR: ; break; default: jj_la1[1] = jj_gen; break label_1; } jj_consume_token(OR); r = XorExpression(); if ( l instanceof OrPredicate ) { ((OrPredicate)l).add((Predicate)r); } else { l = new OrPredicate((Predicate)l,(Predicate)r); } } {if (true) return l;} throw new Error("Missing return statement in function"); } static final public Expression XorExpression() throws ParseException { Expression l, r; l = AndExpression(); label_2: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case XOR: ; break; default: jj_la1[2] = jj_gen; break label_2; } jj_consume_token(XOR); r = AndExpression(); if ( l instanceof XorPredicate ) { ((XorPredicate)l).add((Predicate)r); } else { l = new XorPredicate((Predicate)l,(Predicate)r); } } {if (true) return l;} throw new Error("Missing return statement in function"); } static final public Expression AndExpression() throws ParseException { Expression l, r; l = EqualityExpression(); label_3: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case AND: ; break; default: jj_la1[3] = jj_gen; break label_3; } jj_consume_token(AND); r = EqualityExpression(); if ( l instanceof AndPredicate ) { ((AndPredicate)l).add((Predicate)r); } else { l = new AndPredicate((Predicate)l,(Predicate)r); } } {if (true) return l;} throw new Error("Missing return statement in function"); } static final public Expression EqualityExpression() throws ParseException { Expression l, r; Token t; int op; l = RelationalExpression(); label_4: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case EQ: case NE: ; break; default: jj_la1[4] = jj_gen; break label_4; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case EQ: t = jj_consume_token(EQ); break; case NE: t = jj_consume_token(NE); break; default: jj_la1[5] = jj_gen; jj_consume_token(-1); throw new ParseException(); } r = RelationalExpression(); op = (t.kind==EQ ? ComparisonPredicate.EQ : ComparisonPredicate.NEQ); l = new ComparisonPredicate(op, l, r); } {if (true) return l;} throw new Error("Missing return statement in function"); } static final public Expression RelationalExpression() throws ParseException { Expression l, r; Token t; int op=-1; l = AdditiveExpression(); label_5: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case GT: case LT: case LE: case GE: ; break; default: jj_la1[6] = jj_gen; break label_5; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LT: t = jj_consume_token(LT); break; case GT: t = jj_consume_token(GT); break; case LE: t = jj_consume_token(LE); break; case GE: t = jj_consume_token(GE); break; default: jj_la1[7] = jj_gen; jj_consume_token(-1); throw new ParseException(); } r = AdditiveExpression(); switch ( t.kind ) { case LT: op = ComparisonPredicate.LT; break; case GT: op = ComparisonPredicate.GT; break; case LE: op = ComparisonPredicate.LTEQ; break; case GE: op = ComparisonPredicate.GTEQ; break; } l = new ComparisonPredicate(op, l, r); } {if (true) return l;} throw new Error("Missing return statement in function"); } static final public Expression AdditiveExpression() throws ParseException { Expression l, r; Token t; int op=-1; l = MultiplicativeExpression(); label_6: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ADD: case SUB: case MOD: ; break; default: jj_la1[8] = jj_gen; break label_6; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ADD: t = jj_consume_token(ADD); break; case SUB: t = jj_consume_token(SUB); break; case MOD: t = jj_consume_token(MOD); break; default: jj_la1[9] = jj_gen; jj_consume_token(-1); throw new ParseException(); } r = MultiplicativeExpression(); switch ( t.kind ) { case ADD: op = ArithmeticExpression.ADD; break; case SUB: op = ArithmeticExpression.SUB; break; case MOD: op = ArithmeticExpression.MOD; break; } l = new ArithmeticExpression(op, l, r); } {if (true) return l;} throw new Error("Missing return statement in function"); } static final public Expression MultiplicativeExpression() throws ParseException { Expression l, r; Token t; int op=-1; l = UnaryExpression(); label_7: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case MUL: case DIV: case POW: ; break; default: jj_la1[10] = jj_gen; break label_7; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case MUL: t = jj_consume_token(MUL); break; case DIV: t = jj_consume_token(DIV); break; case POW: t = jj_consume_token(POW); break; default: jj_la1[11] = jj_gen; jj_consume_token(-1); throw new ParseException(); } r = UnaryExpression(); switch ( t.kind ) { case MUL: op = ArithmeticExpression.MUL; break; case DIV: op = ArithmeticExpression.DIV; break; case POW: op = ArithmeticExpression.POW; break; } l = new ArithmeticExpression(op, l, r); } {if (true) return l;} throw new Error("Missing return statement in function"); } static final public Expression UnaryExpression() throws ParseException { Expression e; Token t; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ADD: case SUB: switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ADD: t = jj_consume_token(ADD); break; case SUB: t = jj_consume_token(SUB); break; default: jj_la1[12] = jj_gen; jj_consume_token(-1); throw new ParseException(); } e = UnaryExpression(); if ( t.kind == SUB && e instanceof NumericLiteral ) { Number n = (Number)e.get(null); if ( n instanceof Integer ) { {if (true) return new NumericLiteral(-1*n.intValue());} } if ( n instanceof Double ) { {if (true) return new NumericLiteral(-1*n.doubleValue());} } if ( n instanceof Long ) { {if (true) return new NumericLiteral(-1*n.longValue());} } if ( n instanceof Float ) { {if (true) return new NumericLiteral(-1*n.floatValue());} } else { {if (true) return new ArithmeticExpression(ArithmeticExpression.MUL, new NumericLiteral(-1), e);} } } else if ( t.kind == SUB ) { {if (true) return new ArithmeticExpression(ArithmeticExpression.MUL, new NumericLiteral(-1), e);} } else { {if (true) return e;} } break; case NOT: e = UnaryExpressionNotPlusMinus(); {if (true) return e;} break; case TRUE: case FALSE: case NULL: case IF: case INT: case LONG: case DOUBLE: case FLOAT: case STRING: case QUOTED: case IDENTIFIER: case LPAREN: e = PrimaryExpression(); {if (true) return e;} break; default: jj_la1[13] = jj_gen; jj_consume_token(-1); throw new ParseException(); } throw new Error("Missing return statement in function"); } static final public Expression UnaryExpressionNotPlusMinus() throws ParseException { Expression e; jj_consume_token(NOT); e = UnaryExpression(); if ( e instanceof NotPredicate ) { {if (true) return ((NotPredicate)e).getPredicate();} } else { if ( !(e instanceof Predicate) ) { {if (true) throw new ParseException("Can't negate a non-predicate");} } else { {if (true) return new NotPredicate((Predicate)e);} } } throw new Error("Missing return statement in function"); } static final public Expression PrimaryExpression() throws ParseException { Expression e; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case TRUE: case FALSE: case NULL: case INT: case LONG: case DOUBLE: case FLOAT: case STRING: e = Literal(); {if (true) return e;} break; case IF: e = IfStatement(); {if (true) return e;} break; case QUOTED: case IDENTIFIER: e = Identifier(); {if (true) return e;} break; case LPAREN: jj_consume_token(LPAREN); e = Expression(); jj_consume_token(RPAREN); {if (true) return e;} break; default: jj_la1[14] = jj_gen; jj_consume_token(-1); throw new ParseException(); } throw new Error("Missing return statement in function"); } static final public Expression Literal() throws ParseException { Token t; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case INT: t = jj_consume_token(INT); {if (true) return new NumericLiteral(Integer.parseInt(t.image));} break; case LONG: t = jj_consume_token(LONG); {if (true) return new NumericLiteral(Long.parseLong(t.image));} break; case FLOAT: t = jj_consume_token(FLOAT); {if (true) return new NumericLiteral(Float.parseFloat(t.image));} break; case DOUBLE: t = jj_consume_token(DOUBLE); {if (true) return new NumericLiteral(Double.parseDouble(t.image));} break; case STRING: t = jj_consume_token(STRING); String s = unescape(t.image.substring(1, t.image.length()-1)); {if (true) return new ObjectLiteral(s);} break; case TRUE: jj_consume_token(TRUE); {if (true) return new BooleanLiteral(true);} break; case FALSE: jj_consume_token(FALSE); {if (true) return new BooleanLiteral(false);} break; case NULL: jj_consume_token(NULL); {if (true) return new ObjectLiteral(null);} break; default: jj_la1[15] = jj_gen; jj_consume_token(-1); throw new ParseException(); } throw new Error("Missing return statement in function"); } static final public Expression Identifier() throws ParseException { String s; Function f=null; Expression e; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case QUOTED: s = Quoted(); {if (true) return new ColumnExpression(s);} break; case IDENTIFIER: s = Name(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LPAREN: jj_consume_token(LPAREN); f = FunctionTable.createFunction(s); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case TRUE: case FALSE: case NULL: case IF: case NOT: case INT: case LONG: case DOUBLE: case FLOAT: case STRING: case QUOTED: case IDENTIFIER: case LPAREN: case ADD: case SUB: e = Expression(); f.addParameter(e); label_8: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case 43: ; break; default: jj_la1[16] = jj_gen; break label_8; } jj_consume_token(43); e = Expression(); f.addParameter(e); } break; default: jj_la1[17] = jj_gen; ; } jj_consume_token(RPAREN); break; default: jj_la1[18] = jj_gen; ; } {if (true) return f==null ? new ColumnExpression(s) : (Expression)f;} break; default: jj_la1[19] = jj_gen; jj_consume_token(-1); throw new ParseException(); } throw new Error("Missing return statement in function"); } static final public Expression IfStatement() throws ParseException { Expression p, t, e; jj_consume_token(IF); p = Expression(); jj_consume_token(THEN); t = Expression(); jj_consume_token(ELSE); e = Expression(); if ( !(p instanceof Predicate) ) {if (true) throw new ParseException("IF-statement test must be a predicate");} {if (true) return new IfExpression((Predicate)p, t, e);} throw new Error("Missing return statement in function"); } static private boolean jj_initialized_once = false; static public ExpressionParserTokenManager token_source; static JavaCharStream jj_input_stream; static public Token token, jj_nt; static private int jj_ntk; static private int jj_gen; static final private int[] jj_la1 = new int[20]; static private int[] jj_la1_0; static private int[] jj_la1_1; static { jj_la1_0(); jj_la1_1(); } private static void jj_la1_0() { jj_la1_0 = new int[] {0x277143c1,0x2000,0x8000,0x1000,0x80000000,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x277143c0,0x277103c0,0x17101c0,0x0,0x277143c0,0x20000000,0x6000000,}; } private static void jj_la1_1() { jj_la1_1 = new int[] {0x60,0x0,0x0,0x0,0x10,0x10,0xf,0xf,0x460,0x460,0x380,0x380,0x60,0x60,0x0,0x0,0x800,0x60,0x0,0x0,}; } public ExpressionParser(java.io.InputStream stream) { if (jj_initialized_once) { System.out.println("ERROR: Second call to constructor of static parser. You must"); System.out.println(" either use ReInit() or set the JavaCC option STATIC to false"); System.out.println(" during parser generation."); throw new Error(); } jj_initialized_once = true; jj_input_stream = new JavaCharStream(stream, 1, 1); token_source = new ExpressionParserTokenManager(jj_input_stream); token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 20; i++) jj_la1[i] = -1; } static public void ReInit(java.io.InputStream stream) { jj_input_stream.ReInit(stream, 1, 1); ExpressionParserTokenManager.ReInit(jj_input_stream); token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 20; i++) jj_la1[i] = -1; } public ExpressionParser(java.io.Reader stream) { if (jj_initialized_once) { System.out.println("ERROR: Second call to constructor of static parser. You must"); System.out.println(" either use ReInit() or set the JavaCC option STATIC to false"); System.out.println(" during parser generation."); throw new Error(); } jj_initialized_once = true; jj_input_stream = new JavaCharStream(stream, 1, 1); token_source = new ExpressionParserTokenManager(jj_input_stream); token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 20; i++) jj_la1[i] = -1; } static public void ReInit(java.io.Reader stream) { jj_input_stream.ReInit(stream, 1, 1); ExpressionParserTokenManager.ReInit(jj_input_stream); token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 20; i++) jj_la1[i] = -1; } public ExpressionParser(ExpressionParserTokenManager tm) { if (jj_initialized_once) { System.out.println("ERROR: Second call to constructor of static parser. You must"); System.out.println(" either use ReInit() or set the JavaCC option STATIC to false"); System.out.println(" during parser generation."); throw new Error(); } jj_initialized_once = true; token_source = tm; token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 20; i++) jj_la1[i] = -1; } public void ReInit(ExpressionParserTokenManager tm) { token_source = tm; token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 20; i++) jj_la1[i] = -1; } static final private Token jj_consume_token(int kind) throws ParseException { Token oldToken; if ((oldToken = token).next != null) token = token.next; else token = token.next = ExpressionParserTokenManager.getNextToken(); jj_ntk = -1; if (token.kind == kind) { jj_gen++; return token; } token = oldToken; jj_kind = kind; throw generateParseException(); } static final public Token getNextToken() { if (token.next != null) token = token.next; else token = token.next = ExpressionParserTokenManager.getNextToken(); jj_ntk = -1; jj_gen++; return token; } static final public Token getToken(int index) { Token t = token; for (int i = 0; i < index; i++) { if (t.next != null) t = t.next; else t = t.next = ExpressionParserTokenManager.getNextToken(); } return t; } static final private int jj_ntk() { if ((jj_nt=token.next) == null) return (jj_ntk = (token.next=ExpressionParserTokenManager.getNextToken()).kind); else return (jj_ntk = jj_nt.kind); } static private java.util.Vector jj_expentries = new java.util.Vector(); static private int[] jj_expentry; static private int jj_kind = -1; static public ParseException generateParseException() { jj_expentries.removeAllElements(); boolean[] la1tokens = new boolean[44]; for (int i = 0; i < 44; i++) { la1tokens[i] = false; } if (jj_kind >= 0) { la1tokens[jj_kind] = true; jj_kind = -1; } for (int i = 0; i < 20; i++) { if (jj_la1[i] == jj_gen) { for (int j = 0; j < 32; j++) { if ((jj_la1_0[i] & (1<