/* 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 * <a href="https://javacc.dev.java.net/">JavaCC package</a>. 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 <code>true</code> * boolean argument to request that Exceptions be thrown when * errors occur. * * <h1>Prefuse Expression Language Reference</h1> * <p> * 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. * </p> * <p> * 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. * </p> * <p> * 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. * </p> * <p> * 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. * </p> * <p> * 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. * </p> * * <h2>Literal Values and Data Field References</h2> * <p>The fundamental building blocks of the expression language, representing data values * or referencing the contents of a Tuple data field.</p> * <ul> * <li><strong>Boolean literals (<code>TRUE, FALSE</code>)</strong><br/> * The boolean literals representing true and false conditions, parsed to type <code>boolean</code> * </li> * <li><strong>Integer literals (<code>1, -5, 12340</code>)</strong><br/> * Undecorated, non-decimal numbers are parsed as numbers of type <code>int</code> * </li> * <li><strong>Long literals (<code>1L, -5L, 12340L</code>)</strong><br/> * Integer values decorated with the suffix "L" are parsed as numbers of type <code>long</code> * </li> * <li><strong>Double literals (<code>1.0, 3.1415, 1e-35, 2.3e6</code>)</strong><br/> * Numbers with decimals or exponents in scientific notation are parsed as numbers of type <code>double</code> * </li> * <li><strong>Float literals (<code>1.0f, 3.1415f, 1e-35f, 2.3e6f</code>)</strong><br/> * Floating-point values decorated with the suffix "f" are parsed as numbers of type <code>float</code> * </li> * <li><strong>String literals (<code>"some text", 'a label'</code>)</strong><br/> * Text strings placed in double (") or single (') quotations are parsed as <code>String</code> literals * </li> * <li><strong>Null literal (<code>null</code>)</strong><br/> * The string <code>null</code> is parsed as an ObjectLiteral of type null. * </li> * <li><strong>Data field references (<code>_strokeColor, [a data field]</code>)</strong><br/> * Free-standing strings or those placed within brackets are parsed as a reference to the * data field of that name. Brackets are required for any fields that include spaces or other * unusual characters in their name (e.g., characters like +, -, *, etc), or conflict with * an existing keyword For example, <code>true</code> parses to a boolean literal while * <code>[true]</code> parses to a reference to a data field named 'true'. * </li> * </ul> * * <h2>Operators and Control Flow</h2> * <p>Basic operators and control flow structures for the expression language.</p> * <ul> * <li><strong><code>x + y</code> (addition)</strong><br/> * Add <code>x</code> and <code>y</code> * </li> * <li><strong><code>x - y</code> (subtraction)</strong><br/> * Subtract <code>y</code> from <code>x</code> * </li> * <li><strong><code>x * y</code> (multiplication)</strong><br/> * Multiply <code>x</code> and <code>y</code> * </li> * <li><strong><code>x / y</code> (division)</strong><br/> * Divide <code>x</code> by <code>y</code> * </li> * <li><strong><code>x ^ y</code> (exponentiation, pow)</strong><br/> * Raise <code>x</code> to the exponent <code>y</code> * </li> * <li><strong><code>x % y</code> (modulo)</strong><br/> * Return the remainder of <code>x</code> divded by <code>y</code> * </li> * <li><strong><code>x = y, x == y</code> (equality)</strong><br/> * Indicates if <code>x</code> and <code>y</code> are equal * </li> * <li><strong><code>x != y, x <> y</code> (inequality)</strong><br/> * Indicates if <code>x</code> and <code>y</code> are not equal * </li> * <li><strong><code>x > y</code> (greater than)</strong><br/> * Indicates if <code>x</code> is greater than <code>y</code> * </li> * <li><strong><code>x >= y</code> (greater than or equal to)</strong><br/> * Indicates if <code>x</code> is greater than or equal to <code>y</code> * </li> * <li><strong><code>x < y</code> (less than)</strong><br/> * Indicates if <code>x</code> is less than <code>y</code> * </li> * <li><strong><code>x <= y</code> (less than or equal to)</strong><br/> * Indicates if <code>x</code> is less than or equal to <code>y</code> * </li> * <li><strong><code>x AND y, x && y</code> (and)</strong><br/> * Indicates if both <code>x</code> and <code>y</code> are true * </li> * <li><strong><code>x OR y, x || y</code> (or)</strong><br/> * Indicates if either <code>x</code> or <code>y</code> is true * </li> * <li><strong><code>NOT x, !x</code> (not)</strong><br/> * Indicates if the negation of <code>x</code> is true * </li> * <li><strong><code>x XOR y</code> (exclusive or)</strong><br/> * Indicates if one, but not both, of <code>x</code> or <code>y</code> is true * </li> * <li><strong><code>IF test THEN x ELSE y</code> (if-then-else)</strong><br/> * Evaluates the predicate <code>test</code>, and if true evaluates and returns the * expression <code>x</code>, and if false evaluates and returns the expression * <code>y</code> * </li> * <li><strong><code>()</code> (parentheses)</strong><br/> * Groups expressions together to enfore a particular order of evaluation. For example, * <code>1+2*3</code> evaluates to <code>7</code>, while <code>(1+2)*3</code> evaluates * to <code>9</code>. * </li> * </ul> * * <h2>General Functions</h2> * <p>General purpose functions.</p> * <ul> * <li><strong><code>ROW()</code></strong><br/> * Returns the table row number (or -1 if none) of the current Tuple. * </li> * <li><strong><code>ISNODE()</code></strong><br/> * Returns true if the current Tuple is a graph Node. * </li> * <li><strong><code>ISEDGE()</code></strong><br/> * Returns true if the current Tuple is a graph Edge. * </li> * <li><strong><code>DEGREE()</code></strong><br/> * If the current Tuple is graph Node, returns the Node degree * (the total number of incident edges). Otherwise returns 0. * </li> * <li><strong><code>INDEGREE()</code></strong><br/> * If the current Tuple is graph Node, returns the Node indegree * (the number of incident edges pointing towards this node). * Otherwise returns 0. * </li> * <li><strong><code>OUTDEGREE()</code></strong><br/> * If the current Tuple is graph Node, returns the Node outdegree * (the number of incident edges pointing away from the node). * Otherwise returns 0. * </li> * <li><strong><code>CHILDCOUNT()</code></strong><br/> * If the current Tuple is graph Node, returns the number of tree * children nodes. If the Tuple is not a Node, this method returns 0. * If the Node is part of a Graph (not a Tree), the number of children * nodes in the current spanning tree is returned. If no spanning tree has * been computed, a new spanning tree will be computed using the default * method. See {@link prefuse.data.Graph#getSpanningTree()} for more. * </li> * <li><strong><code>TREEDEPTH()</code></strong><br/> * If the current Tuple is graph Node, returns the depth of this Node * in its Tree or SpanningTree. If the Tuple is not a Node, this method * returns 0. If the Node is part of a Graph (not a Tree), the tree depth * of the node in the current spanning tree is returned. If no spanning * tree has been computed, a new spanning tree will be computed using the * default method. See {@link prefuse.data.Graph#getSpanningTree()} for * more. * </li> * </ul> * * <h2>Mathematical Functions</h2> * <p>Functions for performing mathematical calculations.</p> * <ul> * <li><strong><code>ABS(x)</code></strong><br/> * Returns the absolute value of <code>x</code> * </li> * <li><strong><code>ACOS(x)</code></strong><br/> * Returns the inverse cosine (arc cosine) of a <code>x</code> * </li> * <li><strong><code>ASIN(x)</code></strong><br/> * Returns the inverse sine (arc sine) of a <code>x</code> * </li> * <li><strong><code>ATAN(x)</code></strong><br/> * Returns the inverse tangent (arc tangent) of a <code>x</code> * </li> * <li><strong><code>ATAN2(y, x)</code></strong><br/> * For the Cartesian coordinates <code>x</code>, <code>y</code> return the polar coordinate angle theta * </li> * <li><strong><code>CEIL(x), CEILING(x)</code></strong><br/> * Returns the nearest integer value greater than or equal to <code>x</code>. * </li> * <li><strong><code>COS(x)</code></strong><br/> * Returns the cosine of <code>x</code> * </li> * <li><strong><code>COT(x)</code></strong><br/> * Returns the cotangent of <code>x</code> * </li> * <li><strong><code>DEGREES(x)</code></strong><br/> * Converts <code>x</code> from radians to degrees * </li> * <li><strong><code>EXP(x)</code></strong><br/> * Returns the value of <em>e</em> (the base of natural logarithms) raised to the <code>x</code> power * </li> * <li><strong><code>FLOOR(x)</code></strong><br/> * Returns the nearest integer value less than or equal to <code>x</code>. * </li> * <li><strong><code>LOG(x), LOG(b, x)</code></strong><br/> * With one argument, returns the natural logarithm (logarithm base <em>e</em>) of <code>x</code><br/> * With two arguments, returns the logarithm of <code>x</code> for the provided base <code>b</code> * </li> * <li><strong><code>LOG2(x)</code></strong><br/> * Returns the logarithm base 2 of <code>x</code> * </li> * <li><strong><code>LOG10(x)</code></strong><br/> * Returns the logarithm base 10 of <code>x</code> * </li> * <li><strong><code>MAX(a, b, c, ...)</code></strong><br/> * Returns the maximum value among the provided arguments * </li> * <li><strong><code>MIN(a, b, c, ...)</code></strong><br/> * Returns the minimum value among the provided arguments * </li> * <li><strong><code>MOD(x, y)</code></strong><br/> * Returns <code>x</code> modulo <code>y</code> (the remainder of <code>x</code> divided by <code>y</code>) * </li> * <li><strong><code>PI()</code></strong><br/> * Returns the constant π (= 3.1415926535...), the ratio between the circumference and diameter of a circle * </li> * <li><strong><code>POW(x, y), POWER(x, y)</code></strong><br/> * Return the value of <code>x</code> raised to the exponent <code>y</code> * </li> * <li><strong><code>RADIANS(x)</code></strong><br/> * Converts <code>x</code> from degrees to radians * </li> * <li><strong><code>RAND()</code></strong><br/> * Returns a random floating-point value between 0 and 1 * </li> * <li><strong><code>ROUND(x)</code></strong><br/> * Returns the value of <code>x</code> rounded to the nearest integer * </li> * <li><strong><code>SIGN(x)</code></strong><br/> * Returns the sign of <code>x</code>: 1 for positive, -1 for negative * </li> * <li><strong><code>SIN(x)</code></strong><br/> * Returns the sine of <code>x</code> * </li> * <li><strong><code>SQRT(x)</code></strong><br/> * Returns the square root of <code>x</code> * </li> * <li><strong><code>SUM(a, b, c, ...)</code></strong><br/> * Returns the sum of the provided input value * </li> * <li><strong><code>TAN(x)</code></strong><br/> * Returns the tangent of <code>x</code> * </li> * <li><strong><code>SAFELOG10(x)</code></strong><br/> * Returns a "negative safe" logarithm base 10 of <code>x</code>, equivalent to * <code>SIGN(x) * LOG10(ABS(x))</code> * </li> * <li><strong><code>SAFESQRT(x)</code></strong><br/> * Returns a "negative safe" square root of <code>x</code>, equivalent to * <code>SIGN(x) * SQRT(ABS(x))</code> * </li> * </ul> * * <h2>String Functions</h2> * <p>Functions for processing text strings.</p> * <ul> * <li><strong><code>CAP(str)</code></strong><br/> * Capitalize words in the string <code>str</code>. Individual words/names will be given * uppercase first letters, with all other letters in lowercase. * </li> * <li><strong><code>CONCAT(a, b, c, ...)</code></strong><br/> * Concatenate the input strings into one resulting string. * </li> * <li><strong><code>CONCAT_WS(sep, a, b, c, ...)</code></strong><br/> * Concatenate with separator. Concatenates the input strings into one resulting * string, placing the string <code>sep</code> between each of the other arguments * </li> * <li><strong><code>FORMAT(x, d)</code></strong><br/> * Format the number <code>x</code> as a string of the type "#,###.##", showing <code>d</code> decimal places * </li> * <li><strong><code>INSERT(str, pos, len, newstr)</code></strong><br/> * Replaces the substring of length <code>len</code> starting at position <code>pos</code> in input * string <code>str</code> with the string <code>newstr</code> * </li> * <li><strong><code>LEFT(str, len)</code></strong><br/> * Returns the leftmost <code>len</code> characters of string <code>str</code> * </li> * <li><strong><code>LENGTH(str)</code></strong><br/> * Returns the length, in characters, of the input string <code>str</code> * </li> * <li><strong><code>LOWER(str), LCASE(str)</code></strong><br/> * Returns the string <code>str</code> mapped to lowercase letters * </li> * <li><strong><code>LPAD(str, len, pad)</code></strong><br/> * Pad the left side of string <code>str</code> with copies of string <code>pad</code>, * up to a total padding of <code>len</code> characters * </li> * <li><strong><code>MID(str, pos, len)</code></strong><br/> * Return a substring of <code>str</code> of length <code>len</code>, starting at * position <code>pos</code> * </li> * <li><strong><code>POSITION(substr, str)</code></strong><br/> * Returns the starting position of the first occurrence of substring <code>substr</code> * in the string <code>str</code>. Returns -1 if the substring is not found. * </li> * <li><strong><code>REVERSE(str)</code></strong><br/> * Returns a reversed copy of the input string <code>str</code> * </li> * <li><strong><code>REPEAT(str, count)</code></strong><br/> * Returns a string consisting of <code>str</code> repeated <code>count</code> times * </li> * <li><strong><code>REPLACE(str, orig, replace)</code></strong><br/> * Returns a copy of <code>str</code> in which all occurrences of <code>orig</code> have been * replaced by <code>replace</code> * </li> * <li><strong><code>RIGHT(str, len)</code></strong><br/> * Returns the <code>len</code> rightmost characters of string <code>str</code> * </li> * <li><strong><code>RPAD(x)</code></strong><br/> * Pad the right side of string <code>str</code> with copies of string <code>pad</code>, * up to a total padding of <code>len</code> characters * </li> * <li><strong><code>SPACE(n)</code></strong><br/> * Returns a string consisting of <code>n</code> whitespace characters * </li> * <li><strong><code>SUBSTRING(str,pos), SUBSTRING(str,pos,len)</code></strong><br/> * For two arguments, returns the substring of <code>str</code> starting at position * <code>pos</code> and continuing to the end of the string.<br/> * For three arguments, returns the substring of <code>str</code> of length <code>len</code>, * beginning at position <code>pos</code> * </li> * <li><strong><code>UPPER(str), UCASE(str</code></strong><br/> * Returns the string <code>str</code> mapped to uppercase letters * </li> * </ul> * * <h2>Color Functions</h2> * <p>Functions for generating, translating, and interpolating color values.</p> * <ul> * <li><strong><code>RGB(r, g, b)</code></strong><br/> * Returns an integer representing a fully opaque RGB (red, green, blue) color value * </li> * <li><strong><code>RGBA(r, g, b, a)</code></strong><br/> * Returns an integer representing an RGBA (red, green, blue, alpha/transparency) color value * </li> * <li><strong><code>GRAY(v)</code></strong><br/> * Returns an integer representing a grayscale color value of intensity <code>v</code> * </li> * <li><strong><code>HEX(hex)</code></strong><br/> * Returns an integer representing the RGB color value encoded by the hexadecimal number * <code>hex</code> * </li> * <li><strong><code>HSB(h, s, b)</code></strong><br/> * Maps the given hue (<code>hue</code>), saturation (<code>s</code>), and brightness * (<code>b</code>) color space values (as floating point numbers between 0 and 1) to * an integer representing an RGB color value * </li> * <li><strong><code>HSBA(h, s, b, a)</code></strong><br/> * Maps the given hue (<code>hue</code>), saturation (<code>s</code>), brightness * (<code>b</code>), and alpha (<code>a</code>) color space values (as floating point * numbers between 0 and 1) to an integer representing an RGBA color value * </li> * <li><strong><code>COLORINTERP(c1, c2, f)</code></strong><br/> * Returns an interpolated color value between the input colors <code>c1</code> and * <code>c2</code> determined by the mixing proportion <code>f</code>, a value * between 0 and 1 * </li> * </ul> * * <h2>Visualization Functions</h2> * <p>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, <code>_x</code>, <code>_y</code>, * <code>_hover</code>, <code>_highlight</code>, <code>_fillColor</code> would * evaluate to references for the x-coordinate, y-coordinate, mouse hover status, * highlight status, and fill color, respectively.</p> * <ul> * <li><strong><code>GROUPSIZE(group)</code></strong><br/> * Returns the number of members in the data group <code>group</code> * </li> * <li><strong><code>INGROUP(group)</code></strong><br/> * Returns true if the current VisualItem is a member of data group <code>group</code> * </li> * <li><strong><code>MATCH(group, includeAll)</code></strong><br/> * Returns true if the current VisualItem is currently a search match. This is similar * to <code>INGROUP(group)</code>, but also includes a possible special case when no * query has been issued and all items should be counted as "matches" (indicated * by <code>includeAll</code> being true). * </li> * <li><strong><code>QUERY(group)</code></strong><br/> * Returns the current search query string in a search group of name <code>group</code> * </li> * <li><strong><code>VISIBLE()</code></strong><br/> * Returns true if the current VisualItem is visible, equivalent to <code>_visible</code> * </li> * <li><strong><code>VALIDATED()</code></strong><br/> * Returns true if the current VisualItem's bounds have been validated, * equivalent to <code>_validated</code> * </li> * </ul> * * @author <a href="http://jheer.org">jeffrey heer</a> */ 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); } /** * Parse an expression as a predicate. 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 Predicate predicate(String expr) { Expression ex = parse(expr, false); if ( ex == null ) { return null; } else if ( ex instanceof Predicate ) { return (Predicate) ex; } else { s_error = new ClassCastException("Expression is not a predicate"); return null; } } /** * 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.substring(0,t.image.length()-1)));} 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<<j)) != 0) { la1tokens[j] = true; } if ((jj_la1_1[i] & (1<<j)) != 0) { la1tokens[32+j] = true; } } } } for (int i = 0; i < 44; i++) { if (la1tokens[i]) { jj_expentry = new int[1]; jj_expentry[0] = i; jj_expentries.addElement(jj_expentry); } } int[][] exptokseq = new int[jj_expentries.size()][]; for (int i = 0; i < jj_expentries.size(); i++) { exptokseq[i] = (int[])jj_expentries.elementAt(i); } return new ParseException(token, exptokseq, tokenImage); } static final public void enable_tracing() { } static final public void disable_tracing() { } }