diff --git dev-tools/scripts/smokeTestRelease.py dev-tools/scripts/smokeTestRelease.py
index a1b0f6f..f9328a1 100644
--- dev-tools/scripts/smokeTestRelease.py
+++ dev-tools/scripts/smokeTestRelease.py
@@ -651,7 +651,7 @@ def verifyUnpacked(project, artifact, unpackPath, svnRevision, version, testArgs
if project == 'lucene':
# TODO: clean this up to not be a list of modules that we must maintain
- extras = ('analysis', 'benchmark', 'classification', 'codecs', 'core', 'demo', 'docs', 'facet', 'grouping', 'highlighter', 'join', 'memory', 'misc', 'queries', 'queryparser', 'replicator', 'sandbox', 'spatial', 'suggest', 'test-framework', 'licenses')
+ extras = ('analysis', 'benchmark', 'classification', 'codecs', 'core', 'demo', 'docs', 'expressions', 'facet', 'grouping', 'highlighter', 'join', 'memory', 'misc', 'queries', 'queryparser', 'replicator', 'sandbox', 'spatial', 'suggest', 'test-framework', 'licenses')
if isSrc:
extras += ('build.xml', 'common-build.xml', 'module-build.xml', 'ivy-settings.xml', 'backwards', 'tools', 'site')
else:
diff --git lucene/build.xml lucene/build.xml
index 2034c63..0e50f6f 100644
--- lucene/build.xml
+++ lucene/build.xml
@@ -283,6 +283,7 @@
+
diff --git lucene/common-build.xml lucene/common-build.xml
index 0a14616..64f407c 100644
--- lucene/common-build.xml
+++ lucene/common-build.xml
@@ -1567,6 +1567,8 @@ ${tests-output}/junit4-*.suites - per-JVM executed suites
+
+
diff --git lucene/core/src/java/org/apache/lucene/util/MathUtil.java lucene/core/src/java/org/apache/lucene/util/MathUtil.java
index 9d40f4f..8b17600 100644
--- lucene/core/src/java/org/apache/lucene/util/MathUtil.java
+++ lucene/core/src/java/org/apache/lucene/util/MathUtil.java
@@ -44,6 +44,13 @@ public final class MathUtil {
return ret;
}
+ /**
+ * Calculates logarithm in a given base with doubles.
+ */
+ public static double log(double base, double x) {
+ return Math.log(x) / Math.log(base);
+ }
+
/** Return the greatest common divisor of a and b,
* consistently with {@link BigInteger#gcd(BigInteger)}.
*
NOTE: A greatest common divisor must be positive, but
@@ -78,4 +85,69 @@ public final class MathUtil {
}
return a << commonTrailingZeros;
}
+
+
+ /**
+ * Calculates inverse hyperbolic sine of a {@code double} value.
+ *
+ * Special cases:
+ *
+ *
If the argument is NaN, then the result is NaN.
+ *
If the argument is zero, then the result is a zero with the same sign as the argument.
+ *
If the argument is infinite, then the result is infinity with the same sign as the argument.
+ *
+ */
+ public static double asinh(double a) {
+ final double sign;
+ // check the sign bit of the raw representation to handle -0
+ if (Double.doubleToRawLongBits(a) < 0) {
+ a = Math.abs(a);
+ sign = -1.0d;
+ } else {
+ sign = 1.0d;
+ }
+
+ return sign * Math.log(Math.sqrt(a * a + 1.0d) + a);
+ }
+
+ /**
+ * Calculates inverse hyperbolic cosine of a {@code double} value.
+ *
+ * Special cases:
+ *
+ *
If the argument is NaN, then the result is NaN.
+ *
If the argument is +1, then the result is a zero.
+ *
If the argument is positive infinity, then the result is positive infinity.
+ *
If the argument is less than 1, then the result is NaN.
+ *
+ */
+ public static double acosh(double a) {
+ return Math.log(Math.sqrt(a * a - 1.0d) + a);
+ }
+
+ /**
+ * Calculates inverse hyperbolic tangent of a {@code double} value.
+ *
+ * Special cases:
+ *
+ *
If the argument is NaN, then the result is NaN.
+ *
If the argument is zero, then the result is a zero with the same sign as the argument.
+ *
If the argument is +1, then the result is positive infinity.
+ *
If the argument is -1, then the result is negative infinity.
+ *
If the argument's absolute value is greater than 1, then the result is NaN.
+ *
+ */
+ public static double atanh(double a) {
+ final double mult;
+ // check the sign bit of the raw representation to handle -0
+ if (Double.doubleToRawLongBits(a) < 0) {
+ a = Math.abs(a);
+ mult = -0.5d;
+ } else {
+ mult = 0.5d;
+ }
+ return mult * Math.log((1.0d + a) / (1.0d - a));
+ }
+
+
}
diff --git lucene/core/src/test/org/apache/lucene/util/TestMathUtil.java lucene/core/src/test/org/apache/lucene/util/TestMathUtil.java
index ec1e2b9..f823aad 100644
--- lucene/core/src/test/org/apache/lucene/util/TestMathUtil.java
+++ lucene/core/src/test/org/apache/lucene/util/TestMathUtil.java
@@ -102,4 +102,80 @@ public class TestMathUtil extends LuceneTestCase {
assertEquals(Long.MIN_VALUE, MathUtil.gcd(Long.MIN_VALUE, Long.MIN_VALUE));
}
+ public void testAcoshMethod() {
+ // acosh(NaN) == NaN
+ assertTrue(Double.isNaN(MathUtil.acosh(Double.NaN)));
+ // acosh(1) == +0
+ assertEquals(0, Double.doubleToLongBits(MathUtil.acosh(1D)));
+ // acosh(POSITIVE_INFINITY) == POSITIVE_INFINITY
+ assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY),
+ Double.doubleToLongBits(MathUtil.acosh(Double.POSITIVE_INFINITY)));
+ // acosh(x) : x < 1 == NaN
+ assertTrue(Double.isNaN(MathUtil.acosh(0.9D))); // x < 1
+ assertTrue(Double.isNaN(MathUtil.acosh(0D))); // x == 0
+ assertTrue(Double.isNaN(MathUtil.acosh(-0D))); // x == -0
+ assertTrue(Double.isNaN(MathUtil.acosh(-0.9D))); // x < 0
+ assertTrue(Double.isNaN(MathUtil.acosh(-1D))); // x == -1
+ assertTrue(Double.isNaN(MathUtil.acosh(-10D))); // x < -1
+ assertTrue(Double.isNaN(MathUtil.acosh(Double.NEGATIVE_INFINITY))); // x == -Inf
+
+ double epsilon = 0.000001;
+ assertEquals(0, MathUtil.acosh(1), epsilon);
+ assertEquals(1.5667992369724109, MathUtil.acosh(2.5), epsilon);
+ assertEquals(14.719378760739708, MathUtil.acosh(1234567.89), epsilon);
+ }
+
+ public void testAsinhMethod() {
+
+ // asinh(NaN) == NaN
+ assertTrue(Double.isNaN(MathUtil.asinh(Double.NaN)));
+ // asinh(+0) == +0
+ assertEquals(0, Double.doubleToLongBits(MathUtil.asinh(0D)));
+ // asinh(-0) == -0
+ assertEquals(Double.doubleToLongBits(-0D), Double.doubleToLongBits(MathUtil.asinh(-0D)));
+ // asinh(POSITIVE_INFINITY) == POSITIVE_INFINITY
+ assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY),
+ Double.doubleToLongBits(MathUtil.asinh(Double.POSITIVE_INFINITY)));
+ // asinh(NEGATIVE_INFINITY) == NEGATIVE_INFINITY
+ assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY),
+ Double.doubleToLongBits(MathUtil.asinh(Double.NEGATIVE_INFINITY)));
+
+ double epsilon = 0.000001;
+ assertEquals(-14.719378760740035, MathUtil.asinh(-1234567.89), epsilon);
+ assertEquals(-1.6472311463710958, MathUtil.asinh(-2.5), epsilon);
+ assertEquals(-0.8813735870195429, MathUtil.asinh(-1), epsilon);
+ assertEquals(0, MathUtil.asinh(0), 0);
+ assertEquals(0.8813735870195429, MathUtil.asinh(1), epsilon);
+ assertEquals(1.6472311463710958, MathUtil.asinh(2.5), epsilon);
+ assertEquals(14.719378760740035, MathUtil.asinh(1234567.89), epsilon );
+ }
+
+ public void testAtanhMethod() {
+ // atanh(NaN) == NaN
+ assertTrue(Double.isNaN(MathUtil.atanh(Double.NaN)));
+ // atanh(+0) == +0
+ assertEquals(0, Double.doubleToLongBits(MathUtil.atanh(0D)));
+ // atanh(-0) == -0
+ assertEquals(Double.doubleToLongBits(-0D),
+ Double.doubleToLongBits(MathUtil.atanh(-0D)));
+ // atanh(1) == POSITIVE_INFINITY
+ assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY),
+ Double.doubleToLongBits(MathUtil.atanh(1D)));
+ // atanh(-1) == NEGATIVE_INFINITY
+ assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY),
+ Double.doubleToLongBits(MathUtil.atanh(-1D)));
+ // atanh(x) : Math.abs(x) > 1 == NaN
+ assertTrue(Double.isNaN(MathUtil.atanh(1.1D))); // x > 1
+ assertTrue(Double.isNaN(MathUtil.atanh(Double.POSITIVE_INFINITY))); // x == Inf
+ assertTrue(Double.isNaN(MathUtil.atanh(-1.1D))); // x < -1
+ assertTrue(Double.isNaN(MathUtil.atanh(Double.NEGATIVE_INFINITY))); // x == -Inf
+
+ double epsilon = 0.000001;
+ assertEquals(Double.NEGATIVE_INFINITY, MathUtil.atanh(-1), 0);
+ assertEquals(-0.5493061443340549, MathUtil.atanh(-0.5), epsilon);
+ assertEquals(0, MathUtil.atanh(0), 0);
+ assertEquals(0.5493061443340549, MathUtil.atanh(0.5), epsilon);
+ assertEquals(Double.POSITIVE_INFINITY, MathUtil.atanh(1), 0);
+ }
+
}
diff --git lucene/expressions/build.xml lucene/expressions/build.xml
new file mode 100644
index 0000000..8e8a727
--- /dev/null
+++ lucene/expressions/build.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+ Dynamically computed values to sort/facet/search on based on a pluggable grammar.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git lucene/expressions/ivy.xml lucene/expressions/ivy.xml
new file mode 100644
index 0000000..5d9f1ed
--- /dev/null
+++ lucene/expressions/ivy.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/Bindings.java lucene/expressions/src/java/org/apache/lucene/expressions/Bindings.java
new file mode 100644
index 0000000..8ee56d0
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/Bindings.java
@@ -0,0 +1,87 @@
+package org.apache.lucene.expressions;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.lucene.queries.function.ValueSource;
+
+/**
+ * Binds variable names in expressions to actual data.
+ *
+ * These are typically DocValues fields/FieldCache, the document's
+ * relevance score, or other ValueSources.
+ *
+ * @lucene.experimental
+ */
+public abstract class Bindings implements Iterable {
+
+ /** Sole constructor. (For invocation by subclass
+ * constructors, typically implicit.) */
+ protected Bindings() {}
+
+ /**
+ * Returns a ValueSource bound to the variable name.
+ */
+ public abstract ValueSource getValueSource(String name);
+
+ /** Returns an Iterator over the variable names in this binding */
+ @Override
+ public abstract Iterator iterator();
+
+ /**
+ * Traverses the graph of bindings, checking there are no cycles or missing references
+ * @throws IllegalArgumentException if the bindings is inconsistent
+ */
+ public final void validate() {
+ Set marked = new HashSet();
+ Set chain = new HashSet();
+
+ for (String name : this) {
+ if (!marked.contains(name)) {
+ chain.add(name);
+ validate(name, marked, chain);
+ chain.remove(name);
+ }
+ }
+ }
+
+ private void validate(String name, Set marked, Set chain) {
+ ValueSource vs = getValueSource(name);
+ if (vs == null) {
+ throw new IllegalArgumentException("Invalid reference '" + name + "'");
+ }
+
+ if (vs instanceof ExpressionValueSource) {
+ Expression expr = ((ExpressionValueSource)vs).expression;
+ for (String external : expr.externals) {
+ if (chain.contains(external)) {
+ throw new IllegalArgumentException("Recursion Error: Cycle detected originating in (" + external + ")");
+ }
+ if (!marked.contains(external)) {
+ chain.add(external);
+ validate(external, marked, chain);
+ chain.remove(external);
+ }
+ }
+ }
+
+ marked.add(name);
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/Expression.java lucene/expressions/src/java/org/apache/lucene/expressions/Expression.java
new file mode 100644
index 0000000..a769d3c
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/Expression.java
@@ -0,0 +1,84 @@
+package org.apache.lucene.expressions;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.SortField;
+
+/**
+ * Base class that computes the value of an expression for a document.
+ *
+ * Example usage:
+ *
+ * // compile an expression:
+ * Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
+ *
+ * // SimpleBindings just maps variables to SortField instances
+ * SimpleBindings bindings = new SimpleBindings();
+ * bindings.add(new SortField("_score", SortField.Type.SCORE));
+ * bindings.add(new SortField("popularity", SortField.Type.INT));
+ *
+ * // create a sort field and sort by it (reverse order)
+ * Sort sort = new Sort(expr.getSortField(bindings, true));
+ * Query query = new TermQuery(new Term("body", "contents"));
+ * searcher.search(query, null, 10, sort);
+ *
+ * @lucene.experimental
+ */
+public abstract class Expression {
+
+ /** The original {@link String} expression, before it was compiled */
+ public final String expression;
+
+ /** The names of external references found in the expression */
+ public final String[] externals;
+
+ /**
+ * Creates a new {@code CompiledExpression}.
+ *
+ * @param expression The expression that was compiled
+ * @param externals Names of external references found in the expression
+ */
+ public Expression(String expression, String[] externals) {
+ this.expression = expression;
+ this.externals = externals;
+ }
+
+ /**
+ * Evaluates the expression for the given document.
+ *
+ * @param document docId of the document to compute a value for
+ * @param functionValues {@link FunctionValues} for each element of {@link #externals}.
+ * @return The computed value of the expression for the given document.
+ */
+ public abstract double evaluate(int document, FunctionValues[] functionValues);
+
+ /**
+ * Get a value source which can compute the value of this expression in the context of the given bindings.
+ * @param bindings Bindings to use for external values in this expression
+ * @return A value source which will evaluate this expression when used
+ */
+ public ValueSource getValueSource(Bindings bindings) {
+ return new ExpressionValueSource(bindings, this);
+ }
+
+ /** Get a sort field which can be used to rank documents by this expression. */
+ public SortField getSortField(Bindings bindings, boolean reverse) {
+ return getValueSource(bindings).getSortField(reverse);
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionComparator.java lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionComparator.java
new file mode 100644
index 0000000..fc5df4d
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionComparator.java
@@ -0,0 +1,95 @@
+package org.apache.lucene.expressions;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.FieldComparator;
+import org.apache.lucene.search.Scorer;
+
+/** A custom comparator for sorting documents by an expression */
+class ExpressionComparator extends FieldComparator {
+ private final double[] values;
+ private double bottom;
+
+ private ValueSource source;
+ private FunctionValues scores;
+ private AtomicReaderContext readerContext;
+
+ public ExpressionComparator(ValueSource source, int numHits) {
+ values = new double[numHits];
+ this.source = source;
+ }
+
+ // TODO: change FieldComparator.setScorer to throw IOException and remove this try-catch
+ @Override
+ public void setScorer(Scorer scorer) {
+ super.setScorer(scorer);
+ // TODO: might be cleaner to lazy-init 'source' and set scorer after?
+ assert readerContext != null;
+ try {
+ Map context = new HashMap();
+ assert scorer != null;
+ context.put("scorer", new ScoreFunctionValues(scorer));
+ context.put("valuesCache", new HashMap());
+ scores = source.getValues(context, readerContext);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int compare(int slot1, int slot2) {
+ return Double.compare(values[slot1], values[slot2]);
+ }
+
+ @Override
+ public void setBottom(int slot) {
+ bottom = values[slot];
+ }
+
+ @Override
+ public int compareBottom(int doc) throws IOException {
+ return Double.compare(bottom, scores.doubleVal(doc));
+ }
+
+ @Override
+ public void copy(int slot, int doc) throws IOException {
+ values[slot] = scores.doubleVal(doc);
+ }
+
+ @Override
+ public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
+ this.readerContext = context;
+ return this;
+ }
+
+ @Override
+ public Double value(int slot) {
+ return Double.valueOf(values[slot]);
+ }
+
+ @Override
+ public int compareDocToValue(int doc, Double valueObj) throws IOException {
+ return Double.compare(scores.doubleVal(doc), valueObj.doubleValue());
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionFunctionValues.java lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionFunctionValues.java
new file mode 100644
index 0000000..f710775
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionFunctionValues.java
@@ -0,0 +1,64 @@
+package org.apache.lucene.expressions;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.queries.function.FunctionValues;
+
+/** A {@link FunctionValues} which evaluates an expression */
+class ExpressionFunctionValues extends FunctionValues {
+ final Expression expression;
+ final FunctionValues[] functionValues;
+
+ int currentDocument = -1;
+ double currentValue;
+
+ public ExpressionFunctionValues(Expression expression, FunctionValues[] functionValues) {
+ if (expression == null) {
+ throw new NullPointerException();
+ }
+ if (functionValues == null) {
+ throw new NullPointerException();
+ }
+ this.expression = expression;
+ this.functionValues = functionValues;
+ }
+
+ @Override
+ public double doubleVal(int document) {
+ if (currentDocument != document) {
+ currentDocument = document;
+ currentValue = expression.evaluate(document, functionValues);
+ }
+
+ return currentValue;
+ }
+
+ @Override
+ public Object objectVal(int doc) {
+ return doubleVal(doc);
+ }
+
+ @Override
+ public String toString(int document) {
+ if (currentDocument != document) {
+ currentDocument = document;
+ currentValue = expression.evaluate(document, functionValues);
+ }
+
+ return "ExpressionFunctionValues(" + document + ": " + currentValue + ")";
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionSortField.java lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionSortField.java
new file mode 100644
index 0000000..4c301c8
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionSortField.java
@@ -0,0 +1,38 @@
+package org.apache.lucene.expressions;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.FieldComparator;
+import org.apache.lucene.search.SortField;
+
+/** A {@link SortField} which sorts documents by the evaluated value of an expression for each document */
+class ExpressionSortField extends SortField {
+ private final ValueSource source;
+
+ ExpressionSortField(String name, ValueSource source, boolean reverse) {
+ super(name, Type.CUSTOM, reverse);
+ this.source = source;
+ }
+
+ @Override
+ public FieldComparator> getComparator(final int numHits, final int sortPos) throws IOException {
+ return new ExpressionComparator(source, numHits);
+ }
+}
\ No newline at end of file
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionValueSource.java lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionValueSource.java
new file mode 100644
index 0000000..464f577
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/ExpressionValueSource.java
@@ -0,0 +1,88 @@
+package org.apache.lucene.expressions;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.SortField;
+
+/**
+ * A {@link ValueSource} which evaluates a {@link Expression} given the context of an {@link Bindings}.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+final class ExpressionValueSource extends ValueSource {
+ private final Bindings bindings;
+ final Expression expression;
+
+ public ExpressionValueSource(Bindings bindings, Expression expression) {
+ if (bindings == null) throw new NullPointerException();
+ if (expression == null) throw new NullPointerException();
+ this.bindings = bindings;
+ this.expression = expression;
+ }
+
+ /** context must contain a key "valuesCache" which is a Map<String,FunctionValues>. */
+ @Override
+ public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
+ ValueSource source;
+ Map valuesCache = (Map)context.get("valuesCache");
+ if (valuesCache == null) {
+ throw new NullPointerException();
+ }
+ FunctionValues[] externalValues = new FunctionValues[expression.externals.length];
+
+ for (int i = 0; i < expression.externals.length; ++i) {
+ String externalName = expression.externals[i];
+ FunctionValues values = valuesCache.get(externalName);
+ if (values == null) {
+ source = bindings.getValueSource(externalName);
+ values = source.getValues(context, readerContext);
+ if (values == null) {
+ throw new RuntimeException("Internal error. External (" + externalName + ") does not exist.");
+ }
+ valuesCache.put(externalName, values);
+ }
+ externalValues[i] = values;
+ }
+
+ return new ExpressionFunctionValues(expression, externalValues);
+ }
+
+ @Override
+ public SortField getSortField(boolean reverse) {
+ return new ExpressionSortField(expression.expression, this, reverse);
+ }
+
+ @Override
+ public String description() {
+ return "ExpressionValueSource(" + expression.expression + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this;
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/ScoreFunctionValues.java lucene/expressions/src/java/org/apache/lucene/expressions/ScoreFunctionValues.java
new file mode 100644
index 0000000..23f6a2b
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/ScoreFunctionValues.java
@@ -0,0 +1,48 @@
+package org.apache.lucene.expressions;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.search.Scorer;
+
+/**
+ * A utility class to allow expressions to access the score as a {@link FunctionValues}.
+ */
+class ScoreFunctionValues extends FunctionValues {
+ final Scorer scorer;
+
+ ScoreFunctionValues(Scorer scorer) {
+ this.scorer = scorer;
+ }
+
+ @Override
+ public double doubleVal(int document) {
+ try {
+ assert document == scorer.docID();
+ return scorer.score();
+ } catch (IOException exception) {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ @Override
+ public String toString(int document) {
+ return "ComputedScorerValues(" + document + ": " + doubleVal(document) + ")";
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/ScoreValueSource.java lucene/expressions/src/java/org/apache/lucene/expressions/ScoreValueSource.java
new file mode 100644
index 0000000..6fcee0f
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/ScoreValueSource.java
@@ -0,0 +1,60 @@
+package org.apache.lucene.expressions;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * A {@link ValueSource} which uses the {@link ScoreFunctionValues} passed through
+ * the context map by {@link ExpressionComparator}.
+ */
+@SuppressWarnings({"rawtypes"})
+class ScoreValueSource extends ValueSource {
+
+ /**
+ * context must contain a key "scorer" which is a {@link FunctionValues}.
+ */
+ @Override
+ public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
+ FunctionValues v = (FunctionValues) context.get("scorer");
+ if (v == null) {
+ throw new NullPointerException();
+ }
+ return v;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o == this;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public String description() {
+ return "ValueSource to expose scorer passed by ExpressionComparator";
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/SimpleBindings.java lucene/expressions/src/java/org/apache/lucene/expressions/SimpleBindings.java
new file mode 100644
index 0000000..f62a8eb
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/SimpleBindings.java
@@ -0,0 +1,94 @@
+package org.apache.lucene.expressions;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
+import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
+import org.apache.lucene.queries.function.valuesource.IntFieldSource;
+import org.apache.lucene.queries.function.valuesource.LongFieldSource;
+import org.apache.lucene.search.FieldCache.DoubleParser;
+import org.apache.lucene.search.FieldCache.FloatParser;
+import org.apache.lucene.search.FieldCache.IntParser;
+import org.apache.lucene.search.FieldCache.LongParser;
+import org.apache.lucene.search.SortField;
+
+/**
+ * Simple class that binds expression variable names to {@link SortField}s.
+ *
+ * @lucene.experimental
+ */
+public final class SimpleBindings extends Bindings {
+ final Map map = new HashMap();
+
+ /** Creates a new empty Bindings */
+ public SimpleBindings() {}
+
+ /**
+ * Adds a SortField to the bindings.
+ *
+ * This can be used to reference a DocValuesField, a field from
+ * FieldCache, the document's score, etc.
+ */
+ public void add(SortField sortField) {
+ map.put(sortField.getField(), sortField);
+ }
+
+ /**
+ * Adds an Expression to the bindings.
+ *
+ * This can be used to reference expressions from other expressions.
+ */
+ public void add(String name, Expression expression) {
+ map.put(name, expression);
+ }
+
+ @Override
+ public ValueSource getValueSource(String name) {
+ Object o = map.get(name);
+ if (o == null) {
+ throw new IllegalArgumentException("Invalid reference '" + name + "'");
+ } else if (o instanceof Expression) {
+ return ((Expression)o).getValueSource(this);
+ }
+ SortField field = (SortField) o;
+ switch(field.getType()) {
+ case INT:
+ return new IntFieldSource(field.getField(), (IntParser) field.getParser());
+ case LONG:
+ return new LongFieldSource(field.getField(), (LongParser) field.getParser());
+ case FLOAT:
+ return new FloatFieldSource(field.getField(), (FloatParser) field.getParser());
+ case DOUBLE:
+ return new DoubleFieldSource(field.getField(), (DoubleParser) field.getParser());
+ case SCORE:
+ return new ScoreValueSource();
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Override
+ public Iterator iterator() {
+ return map.keySet().iterator();
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/js/Javascript.g lucene/expressions/src/java/org/apache/lucene/expressions/js/Javascript.g
new file mode 100644
index 0000000..b7d268f
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/js/Javascript.g
@@ -0,0 +1,381 @@
+/*
+ Javascript.g
+ An expression syntax based on ECMAScript/Javascript.
+
+ This file was adapted from a general ECMAScript language definition at http://research.xebic.com/es3.
+ The major changes are the following:
+ * Stripped grammar of all parts not relevant for expression syntax.
+ * Stripped grammar of unicode character support.
+ * Added override function for customized error handling.
+ * Renaming of many grammar rules.
+ * Removal of annotations no longer relevant for stripped pieces.
+
+ The Original Copyright Notice is the following:
+
+ Copyrights 2008-2009 Xebic Reasearch BV. All rights reserved..
+ Original work by Patrick Hulsmeijer.
+
+ This ANTLR 3 LL(*) grammar is based on Ecma-262 3rd edition (JavaScript 1.5, JScript 5.5).
+ The annotations refer to the "A Grammar Summary" section (e.g. A.1 Lexical Grammar)
+ and the numbers in parenthesis to the paragraph numbers (e.g. (7.8) ).
+ This document is best viewed with ANTLRWorks (www.antlr.org).
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2008-2010, Xebic Research B.V.
+ All rights reserved.
+
+ Redistribution and use of this software in source and binary forms, with or without modification, are
+ permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ * Neither the name of Xebic Research B.V. nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of Xebic Research B.V.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// ***********************************************************************
+// * ANTLRv3 grammar for A9 rank expression language.
+// ***********************************************************************
+
+grammar Javascript;
+
+options {
+ language = Java;
+ output = AST;
+ ASTLabelType=CommonTree;
+}
+
+tokens
+{
+ AT_LPAREN = '(' ;
+ AT_RPAREN = ')' ;
+ AT_DOT = '.' ;
+ AT_COMMA = ',' ;
+ AT_COLON = ':' ;
+
+ AT_COMP_LT = '<' ;
+ AT_COMP_LTE = '<=' ;
+ AT_COMP_EQ = '==' ;
+ AT_COMP_NEQ = '!=' ;
+ AT_COMP_GTE = '>=' ;
+ AT_COMP_GT = '>' ;
+
+ AT_BOOL_NOT = '!' ;
+ AT_BOOL_AND = '&&' ;
+ AT_BOOL_OR = '||' ;
+ AT_COND_QUE = '?' ;
+
+ AT_NEGATE ;
+ AT_ADD = '+' ;
+ AT_SUBTRACT = '-' ;
+ AT_MULTIPLY = '*' ;
+ AT_DIVIDE = '/' ;
+ AT_MODULO = '%' ;
+
+ AT_BIT_SHL = '<<' ;
+ AT_BIT_SHR = '>>' ;
+ AT_BIT_SHU = '>>>';
+ AT_BIT_AND = '&' ;
+ AT_BIT_OR = '|' ;
+ AT_BIT_XOR = '^' ;
+ AT_BIT_NOT = '~' ;
+
+ AT_CALL ;
+}
+
+// ***********************************************************************
+// * Java Package
+// ***********************************************************************
+
+@lexer::header {
+package org.apache.lucene.expressions.js;
+
+import java.text.ParseException;
+}
+
+@parser::header {
+package org.apache.lucene.expressions.js;
+
+import java.text.ParseException;
+}
+
+// ***********************************************************************
+// * Error Handling
+// ***********************************************************************
+
+@lexer::members {
+
+@Override
+public void displayRecognitionError(String[] tokenNames, RecognitionException re) {
+ String message = " unexpected character '" + (char)re.c
+ + "' at position (" + re.charPositionInLine + ").";
+ ParseException parseException = new ParseException(message, re.charPositionInLine);
+ parseException.initCause(re);
+ throw new RuntimeException(parseException);
+}
+
+}
+
+@parser::members {
+
+@Override
+public void displayRecognitionError(String[] tokenNames, RecognitionException re) {
+ String message;
+
+ if (re.token == null) {
+ message = " unknown error (missing token).";
+ }
+ else if (re instanceof UnwantedTokenException) {
+ message = " extraneous " + getReadableTokenString(re.token)
+ + " at position (" + re.charPositionInLine + ").";
+ }
+ else if (re instanceof MissingTokenException) {
+ message = " missing " + getReadableTokenString(re.token)
+ + " at position (" + re.charPositionInLine + ").";
+ }
+ else if (re instanceof NoViableAltException) {
+ switch (re.token.getType()) {
+ case EOF:
+ message = " unexpected end of expression.";
+ break;
+ default:
+ message = " invalid sequence of tokens near " + getReadableTokenString(re.token)
+ + " at position (" + re.charPositionInLine + ").";
+ break;
+ }
+ }
+ else {
+ message = " unexpected token " + getReadableTokenString(re.token)
+ + " at position (" + re.charPositionInLine + ").";
+ }
+ ParseException parseException = new ParseException(message, re.charPositionInLine);
+ parseException.initCause(re);
+ throw new RuntimeException(parseException);
+}
+
+public static String getReadableTokenString(Token token) {
+ if (token == null) {
+ return "unknown token";
+ }
+
+ switch (token.getType()) {
+ case AT_LPAREN:
+ return "open parenthesis '('";
+ case AT_RPAREN:
+ return "close parenthesis ')'";
+ case AT_COMP_LT:
+ return "less than '<'";
+ case AT_COMP_LTE:
+ return "less than or equal '<='";
+ case AT_COMP_GT:
+ return "greater than '>'";
+ case AT_COMP_GTE:
+ return "greater than or equal '>='";
+ case AT_COMP_EQ:
+ return "equal '=='";
+ case AT_NEGATE:
+ return "negate '!='";
+ case AT_BOOL_NOT:
+ return "boolean not '!'";
+ case AT_BOOL_AND:
+ return "boolean and '&&'";
+ case AT_BOOL_OR:
+ return "boolean or '||'";
+ case AT_COND_QUE:
+ return "conditional '?'";
+ case AT_ADD:
+ return "addition '+'";
+ case AT_SUBTRACT:
+ return "subtraction '-'";
+ case AT_MULTIPLY:
+ return "multiplication '*'";
+ case AT_DIVIDE:
+ return "division '/'";
+ case AT_MODULO:
+ return "modulo '\%'";
+ case AT_BIT_SHL:
+ return "bit shift left '<<'";
+ case AT_BIT_SHR:
+ return "bit shift right '>>'";
+ case AT_BIT_SHU:
+ return "unsigned bit shift left '<<<'";
+ case AT_BIT_AND:
+ return "bitwise and '&'";
+ case AT_BIT_OR:
+ return "bitwise or '|'";
+ case AT_BIT_XOR:
+ return "bitwise xor '^'";
+ case AT_BIT_NOT:
+ return "bitwise not '~'";
+ case ID:
+ return "identifier '" + token.getText() + "'";
+ case DECIMAL:
+ return "decimal '" + token.getText() + "'";
+ case OCTAL:
+ return "octal '" + token.getText() + "'";
+ case HEX:
+ return "hex '" + token.getText() + "'";
+ case EOF:
+ return "end of expression";
+ default:
+ return "'" + token.getText() + "'";
+ }
+}
+
+}
+
+// ***********************************************************************
+// * Parser Rules
+// ***********************************************************************
+
+expression
+ : conditional EOF!
+ ;
+
+conditional
+ : logical_or (AT_COND_QUE^ conditional AT_COLON! conditional)?
+ ;
+
+logical_or
+ : logical_and (AT_BOOL_OR^ logical_and)*
+ ;
+
+logical_and
+ : bitwise_or (AT_BOOL_AND^ bitwise_or)*
+ ;
+
+bitwise_or
+ : bitwise_xor (AT_BIT_OR^ bitwise_xor)*
+ ;
+
+bitwise_xor
+ : bitwise_and (AT_BIT_XOR^ bitwise_and)*
+ ;
+
+bitwise_and
+ : equality (AT_BIT_AND^ equality)*
+ ;
+
+equality
+ : relational ((AT_COMP_EQ | AT_COMP_NEQ)^ relational)*
+ ;
+
+relational
+ : shift ((AT_COMP_LT | AT_COMP_GT | AT_COMP_LTE | AT_COMP_GTE)^ shift)*
+ ;
+
+shift
+ : additive ((AT_BIT_SHL | AT_BIT_SHR | AT_BIT_SHU)^ additive)*
+ ;
+
+additive
+ : multiplicative ((AT_ADD | AT_SUBTRACT)^ multiplicative)*
+ ;
+
+multiplicative
+ : unary ((AT_MULTIPLY | AT_DIVIDE | AT_MODULO)^ unary)*
+ ;
+
+unary
+ : postfix
+ | AT_ADD! unary
+ | unary_operator^ unary
+ ;
+
+unary_operator
+ : AT_SUBTRACT -> AT_NEGATE
+ | AT_BIT_NOT
+ | AT_BOOL_NOT
+ ;
+
+postfix
+ : primary
+ | ID arguments -> ^(AT_CALL ID arguments?)
+ ;
+
+primary
+ : ID
+ | numeric
+ | AT_LPAREN! conditional AT_RPAREN!
+ ;
+
+arguments
+ : AT_LPAREN! (conditional (AT_COMMA! conditional)*)? AT_RPAREN!
+ ;
+
+numeric
+ : HEX | OCTAL | DECIMAL
+ ;
+
+// ***********************************************************************
+// * Lexer Rules
+// ***********************************************************************
+
+ID
+ : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
+ ;
+
+WS
+ : (' '|'\t'|'\n'|'\r')+ {skip();}
+ ;
+
+DECIMAL
+ : DECIMALINTEGER AT_DOT DECIMALDIGIT* EXPONENT?
+ | AT_DOT DECIMALDIGIT+ EXPONENT?
+ | DECIMALINTEGER EXPONENT?
+ ;
+
+OCTAL
+ : '0' OCTALDIGIT+
+ ;
+
+HEX
+ : ('0x'|'0X') HEXDIGIT+
+ ;
+
+fragment
+DECIMALINTEGER
+ : '0'
+ | '1'..'9' DECIMALDIGIT*
+ ;
+
+fragment
+EXPONENT
+ : ('e'|'E') ('+'|'-')? DECIMALDIGIT+
+ ;
+
+fragment
+DECIMALDIGIT
+ : '0'..'9'
+ ;
+
+fragment
+HEXDIGIT
+ : DECIMALDIGIT
+ | 'a'..'f'
+ | 'A'..'F'
+ ;
+
+fragment
+OCTALDIGIT
+ : '0'..'7'
+ ;
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/js/Javascript.tokens lucene/expressions/src/java/org/apache/lucene/expressions/js/Javascript.tokens
new file mode 100644
index 0000000..dc9a360
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/js/Javascript.tokens
@@ -0,0 +1,66 @@
+AT_ADD=4
+AT_BIT_AND=5
+AT_BIT_NOT=6
+AT_BIT_OR=7
+AT_BIT_SHL=8
+AT_BIT_SHR=9
+AT_BIT_SHU=10
+AT_BIT_XOR=11
+AT_BOOL_AND=12
+AT_BOOL_NOT=13
+AT_BOOL_OR=14
+AT_CALL=15
+AT_COLON=16
+AT_COMMA=17
+AT_COMP_EQ=18
+AT_COMP_GT=19
+AT_COMP_GTE=20
+AT_COMP_LT=21
+AT_COMP_LTE=22
+AT_COMP_NEQ=23
+AT_COND_QUE=24
+AT_DIVIDE=25
+AT_DOT=26
+AT_LPAREN=27
+AT_MODULO=28
+AT_MULTIPLY=29
+AT_NEGATE=30
+AT_RPAREN=31
+AT_SUBTRACT=32
+DECIMAL=33
+DECIMALDIGIT=34
+DECIMALINTEGER=35
+EXPONENT=36
+HEX=37
+HEXDIGIT=38
+ID=39
+OCTAL=40
+OCTALDIGIT=41
+WS=42
+'!'=13
+'!='=23
+'%'=28
+'&&'=12
+'&'=5
+'('=27
+')'=31
+'*'=29
+'+'=4
+','=17
+'-'=32
+'.'=26
+'/'=25
+':'=16
+'<'=21
+'<<'=8
+'<='=22
+'=='=18
+'>'=19
+'>='=20
+'>>'=9
+'>>>'=10
+'?'=24
+'^'=11
+'|'=7
+'||'=14
+'~'=6
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptCompiler.java lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptCompiler.java
new file mode 100644
index 0000000..5931f09
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptCompiler.java
@@ -0,0 +1,630 @@
+package org.apache.lucene.expressions.js;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CharStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.tree.Tree;
+import org.apache.lucene.expressions.Expression;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+import static org.objectweb.asm.Opcodes.AALOAD;
+import static org.objectweb.asm.Opcodes.ACC_FINAL;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.ACC_SUPER;
+import static org.objectweb.asm.Opcodes.ALOAD;
+import static org.objectweb.asm.Opcodes.BIPUSH;
+import static org.objectweb.asm.Opcodes.D2I;
+import static org.objectweb.asm.Opcodes.D2L;
+import static org.objectweb.asm.Opcodes.DADD;
+import static org.objectweb.asm.Opcodes.DCMPG;
+import static org.objectweb.asm.Opcodes.DCMPL;
+import static org.objectweb.asm.Opcodes.DCONST_0;
+import static org.objectweb.asm.Opcodes.DCONST_1;
+import static org.objectweb.asm.Opcodes.DDIV;
+import static org.objectweb.asm.Opcodes.DNEG;
+import static org.objectweb.asm.Opcodes.DREM;
+import static org.objectweb.asm.Opcodes.DRETURN;
+import static org.objectweb.asm.Opcodes.DSUB;
+import static org.objectweb.asm.Opcodes.GOTO;
+import static org.objectweb.asm.Opcodes.I2D;
+import static org.objectweb.asm.Opcodes.I2L;
+import static org.objectweb.asm.Opcodes.ICONST_0;
+import static org.objectweb.asm.Opcodes.ICONST_1;
+import static org.objectweb.asm.Opcodes.ICONST_2;
+import static org.objectweb.asm.Opcodes.ICONST_3;
+import static org.objectweb.asm.Opcodes.ICONST_4;
+import static org.objectweb.asm.Opcodes.ICONST_5;
+import static org.objectweb.asm.Opcodes.IFEQ;
+import static org.objectweb.asm.Opcodes.IFGE;
+import static org.objectweb.asm.Opcodes.IFGT;
+import static org.objectweb.asm.Opcodes.IFLE;
+import static org.objectweb.asm.Opcodes.IFLT;
+import static org.objectweb.asm.Opcodes.IFNE;
+import static org.objectweb.asm.Opcodes.ILOAD;
+import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
+import static org.objectweb.asm.Opcodes.L2D;
+import static org.objectweb.asm.Opcodes.L2I;
+import static org.objectweb.asm.Opcodes.LAND;
+import static org.objectweb.asm.Opcodes.LCONST_0;
+import static org.objectweb.asm.Opcodes.LCONST_1;
+import static org.objectweb.asm.Opcodes.LOR;
+import static org.objectweb.asm.Opcodes.LSHL;
+import static org.objectweb.asm.Opcodes.LSHR;
+import static org.objectweb.asm.Opcodes.LUSHR;
+import static org.objectweb.asm.Opcodes.LXOR;
+import static org.objectweb.asm.Opcodes.RETURN;
+import static org.objectweb.asm.Opcodes.SIPUSH;
+import static org.objectweb.asm.Opcodes.V1_7;
+
+/**
+ * An expression compiler for javascript expressions.
+ *
+ * @lucene.experimental
+ */
+public class JavascriptCompiler {
+ private static enum ComputedType {
+ INT, LONG, DOUBLE
+ }
+
+ class Loader extends ClassLoader {
+
+ Loader(ClassLoader parent) {
+ super(parent);
+ }
+
+ public Class extends Expression> define(String className, byte[] bytecode) {
+ return super.defineClass(className, bytecode, 0, bytecode.length).asSubclass(Expression.class);
+ }
+ }
+
+ private static final String EXPRESSION_CLASS_PREFIX = JavascriptCompiler.class.getPackage().getName() + ".Computed_";
+ private static final String EXPRESSION_INTERNAL_PREFIX = JavascriptCompiler.class.getPackage().getName().replace(".", "/") + "/Computed_";
+ private static final String COMPILED_EXPRESSION_INTERNAL = Type.getInternalName(Expression.class);
+ private static final String FUNCTION_VALUES_INTERNAL = Type.getInternalName(FunctionValues.class);
+
+ private Loader loader;
+ private AtomicLong counter = new AtomicLong();
+
+ private String className;
+ private ClassWriter classWriter;
+ private MethodVisitor methodVisitor;
+ private Map externalsMap;
+ private List externalsList;
+
+ /**
+ * Constructs a compiler for expressions.
+ */
+ public JavascriptCompiler() {
+ this(null);
+ }
+
+ /**
+ * Constructs a compiler for expressions that will be loaded using the given class loader as the parent.
+ * @param parent Class loader to load the dynamically compiled expression
+ */
+ public JavascriptCompiler(ClassLoader parent) {
+ if (parent == null) {
+ parent = getClass().getClassLoader();
+ }
+ loader = new Loader(parent);
+ }
+
+ /**
+ * Compiles the given expression.
+ *
+ * @param expression The expression to compile
+ * @return A new compiled expression
+ * @throws ParseException on failure to compile
+ */
+ public static Expression compile(String expression) throws ParseException {
+ return new JavascriptCompiler().compileExpression(expression);
+ }
+
+ /**
+ * Compiles the given expression.
+ *
+ * @param expression The expression to compile
+ * @return A new compiled expression
+ * @throws ParseException on failure to compile
+ */
+ public Expression compileExpression(String expression) throws ParseException {
+ try {
+ this.className = "Expr" + Long.toString(counter.incrementAndGet());
+ externalsMap = new HashMap();
+ externalsList = new ArrayList();
+
+ Tree antlrTree = getAntlrComputedExpressionTree(expression);
+
+ beginCompile();
+ recursiveCompile(antlrTree, ComputedType.DOUBLE);
+ endCompile();
+
+ Class extends Expression> evaluatorClass = loader.define(EXPRESSION_CLASS_PREFIX + className, classWriter.toByteArray());
+ Constructor extends Expression> constructor = evaluatorClass.getConstructor(String.class, String[].class);
+ return constructor.newInstance(expression, externalsList.toArray(new String[externalsList.size()]));
+ } catch (InstantiationException exception) {
+ throw new IllegalStateException("An internal error occurred attempting to compile the expression (" + className + ").", exception);
+ } catch (IllegalAccessException exception) {
+ throw new IllegalStateException("An internal error occurred attempting to compile the expression (" + className + ").", exception);
+ } catch (NoSuchMethodException exception) {
+ throw new IllegalStateException("An internal error occurred attempting to compile the expression (" + className + ").", exception);
+ } catch (InvocationTargetException exception) {
+ throw new IllegalStateException("An internal error occurred attempting to compile the expression (" + className + ").", exception);
+ }
+ }
+
+ private void beginCompile() {
+ classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ classWriter.visit(V1_7, ACC_PUBLIC + ACC_SUPER + ACC_FINAL, EXPRESSION_INTERNAL_PREFIX + className,
+ null, COMPILED_EXPRESSION_INTERNAL, null);
+ MethodVisitor constructor = classWriter.visitMethod(ACC_PUBLIC, "", "(Ljava/lang/String;[Ljava/lang/String;)V", null, null);
+ constructor.visitCode();
+ constructor.visitVarInsn(ALOAD, 0);
+ constructor.visitVarInsn(ALOAD, 1);
+ constructor.visitVarInsn(ALOAD, 2);
+ constructor.visitMethodInsn(INVOKESPECIAL, COMPILED_EXPRESSION_INTERNAL, "", "(Ljava/lang/String;[Ljava/lang/String;)V");
+ constructor.visitInsn(RETURN);
+ constructor.visitMaxs(0, 0);
+ constructor.visitEnd();
+
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "evaluate", "(I[L" + FUNCTION_VALUES_INTERNAL + ";)D", null, null);
+ methodVisitor.visitCode();
+ }
+
+ private void recursiveCompile(Tree current, ComputedType expected) {
+ int type = current.getType();
+ String text = current.getText();
+
+ switch (type) {
+ case JavascriptParser.AT_CALL:
+ Tree identifier = current.getChild(0);
+ String call = identifier.getText();
+ int arguments = current.getChildCount() - 1;
+
+ JavascriptFunction method = JavascriptFunction.getMethod(call, arguments);
+
+ for (int argument = 1; argument <= arguments; ++argument) {
+ recursiveCompile(current.getChild(argument), ComputedType.DOUBLE);
+ }
+
+ methodVisitor.visitMethodInsn(INVOKESTATIC, method.klass, method.method, method.signature);
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.ID:
+ int index;
+
+ if (externalsMap.containsKey(text)) {
+ index = externalsMap.get(text);
+ } else {
+ index = externalsList.size();
+ externalsList.add(text);
+ externalsMap.put(text, index);
+ }
+
+ methodVisitor.visitVarInsn(ALOAD, 2);
+
+ switch (index) {
+ case 0:
+ methodVisitor.visitInsn(ICONST_0);
+ break;
+ case 1:
+ methodVisitor.visitInsn(ICONST_1);
+ break;
+ case 2:
+ methodVisitor.visitInsn(ICONST_2);
+ break;
+ case 3:
+ methodVisitor.visitInsn(ICONST_3);
+ break;
+ case 4:
+ methodVisitor.visitInsn(ICONST_4);
+ break;
+ case 5:
+ methodVisitor.visitInsn(ICONST_5);
+ break;
+ default:
+ if (index < 128) {
+ methodVisitor.visitIntInsn(BIPUSH, index);
+ } else if (index < 16384) {
+ methodVisitor.visitIntInsn(SIPUSH, index);
+ } else {
+ methodVisitor.visitLdcInsn(index);
+ }
+
+ break;
+ }
+
+ methodVisitor.visitInsn(AALOAD);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitMethodInsn(INVOKEVIRTUAL, FUNCTION_VALUES_INTERNAL, "doubleVal", "(I)D");
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.HEX:
+ long hex = Long.parseLong(text.substring(2), 16);
+
+ if (expected == ComputedType.INT) {
+ methodVisitor.visitLdcInsn((int)hex);
+ } else if (expected == ComputedType.LONG) {
+ methodVisitor.visitLdcInsn(hex);
+ } else {
+ methodVisitor.visitLdcInsn((double)hex);
+ }
+
+ break;
+ case JavascriptParser.OCTAL:
+ long octal = Long.parseLong(text.substring(1), 8);
+
+ if (expected == ComputedType.INT) {
+ methodVisitor.visitLdcInsn((int)octal);
+ } else if (expected == ComputedType.LONG) {
+ methodVisitor.visitLdcInsn(octal);
+ } else {
+ methodVisitor.visitLdcInsn((double)octal);
+ }
+
+ break;
+ case JavascriptParser.DECIMAL:
+ double decimal = Double.parseDouble(text);
+ methodVisitor.visitLdcInsn(decimal);
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.AT_NEGATE:
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DNEG);
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.AT_ADD:
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DADD);
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.AT_SUBTRACT:
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DSUB);
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.AT_MULTIPLY:
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(Opcodes.DMUL);
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.AT_DIVIDE:
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DDIV);
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.AT_MODULO:
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DREM);
+
+ typeCompile(expected, ComputedType.DOUBLE);
+ break;
+ case JavascriptParser.AT_BIT_SHL:
+ recursiveCompile(current.getChild(0), ComputedType.LONG);
+ recursiveCompile(current.getChild(1), ComputedType.INT);
+ methodVisitor.visitInsn(LSHL);
+
+ typeCompile(expected, ComputedType.LONG);
+ break;
+ case JavascriptParser.AT_BIT_SHR:
+ recursiveCompile(current.getChild(0), ComputedType.LONG);
+ recursiveCompile(current.getChild(1), ComputedType.INT);
+ methodVisitor.visitInsn(LSHR);
+
+ typeCompile(expected, ComputedType.LONG);
+ break;
+ case JavascriptParser.AT_BIT_SHU:
+ recursiveCompile(current.getChild(0), ComputedType.LONG);
+ recursiveCompile(current.getChild(1), ComputedType.INT);
+ methodVisitor.visitInsn(LUSHR);
+
+ typeCompile(expected, ComputedType.LONG);
+ break;
+ case JavascriptParser.AT_BIT_AND:
+ recursiveCompile(current.getChild(0), ComputedType.LONG);
+ recursiveCompile(current.getChild(1), ComputedType.LONG);
+ methodVisitor.visitInsn(LAND);
+
+ typeCompile(expected, ComputedType.LONG);
+ break;
+ case JavascriptParser.AT_BIT_OR:
+ recursiveCompile(current.getChild(0), ComputedType.LONG);
+ recursiveCompile(current.getChild(1), ComputedType.LONG);
+ methodVisitor.visitInsn(LOR);
+
+ typeCompile(expected, ComputedType.LONG);
+ break;
+ case JavascriptParser.AT_BIT_XOR:
+ recursiveCompile(current.getChild(0), ComputedType.LONG);
+ recursiveCompile(current.getChild(1), ComputedType.LONG);
+ methodVisitor.visitInsn(LXOR);
+
+ typeCompile(expected, ComputedType.LONG);
+ break;
+ case JavascriptParser.AT_BIT_NOT:
+ recursiveCompile(current.getChild(0), ComputedType.LONG);
+ methodVisitor.visitLdcInsn(new Long(-1));
+ methodVisitor.visitInsn(LXOR);
+
+ typeCompile(expected, ComputedType.LONG);
+ break;
+ case JavascriptParser.AT_COMP_EQ:
+ Label labelEqTrue = new Label();
+ Label labelEqReturn = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DCMPL);
+
+ methodVisitor.visitJumpInsn(IFEQ, labelEqTrue);
+ truthCompile(expected, false);
+ methodVisitor.visitJumpInsn(GOTO, labelEqReturn);
+ methodVisitor.visitLabel(labelEqTrue);
+ truthCompile(expected, true);
+ methodVisitor.visitLabel(labelEqReturn);
+
+ break;
+ case JavascriptParser.AT_COMP_NEQ:
+ Label labelNeqTrue = new Label();
+ Label labelNeqReturn = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DCMPL);
+
+ methodVisitor.visitJumpInsn(IFNE, labelNeqTrue);
+ truthCompile(expected, false);
+ methodVisitor.visitJumpInsn(GOTO, labelNeqReturn);
+ methodVisitor.visitLabel(labelNeqTrue);
+ truthCompile(expected, true);
+ methodVisitor.visitLabel(labelNeqReturn);
+
+ break;
+ case JavascriptParser.AT_COMP_LT:
+ Label labelLtTrue = new Label();
+ Label labelLtReturn = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DCMPG);
+
+ methodVisitor.visitJumpInsn(IFLT, labelLtTrue);
+ truthCompile(expected, false);
+ methodVisitor.visitJumpInsn(GOTO, labelLtReturn);
+ methodVisitor.visitLabel(labelLtTrue);
+ truthCompile(expected, true);
+ methodVisitor.visitLabel(labelLtReturn);
+
+ break;
+ case JavascriptParser.AT_COMP_GT:
+ Label labelGtTrue = new Label();
+ Label labelGtReturn = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DCMPL);
+
+ methodVisitor.visitJumpInsn(IFGT, labelGtTrue);
+ truthCompile(expected, false);
+ methodVisitor.visitJumpInsn(GOTO, labelGtReturn);
+ methodVisitor.visitLabel(labelGtTrue);
+ truthCompile(expected, true);
+ methodVisitor.visitLabel(labelGtReturn);
+
+ break;
+ case JavascriptParser.AT_COMP_LTE:
+ Label labelLteTrue = new Label();
+ Label labelLteReturn = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DCMPG);
+
+ methodVisitor.visitJumpInsn(IFLE, labelLteTrue);
+ truthCompile(expected, false);
+ methodVisitor.visitJumpInsn(GOTO, labelLteReturn);
+ methodVisitor.visitLabel(labelLteTrue);
+ truthCompile(expected, true);
+ methodVisitor.visitLabel(labelLteReturn);
+
+ break;
+ case JavascriptParser.AT_COMP_GTE:
+ Label labelGteTrue = new Label();
+ Label labelGteReturn = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.DOUBLE);
+ recursiveCompile(current.getChild(1), ComputedType.DOUBLE);
+ methodVisitor.visitInsn(DCMPL);
+
+ methodVisitor.visitJumpInsn(IFGE, labelGteTrue);
+ truthCompile(expected, false);
+ methodVisitor.visitJumpInsn(GOTO, labelGteReturn);
+ methodVisitor.visitLabel(labelGteTrue);
+ truthCompile(expected, true);
+ methodVisitor.visitLabel(labelGteReturn);
+
+ break;
+ case JavascriptParser.AT_BOOL_NOT:
+ Label labelNotTrue = new Label();
+ Label labelNotReturn = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.INT);
+ methodVisitor.visitJumpInsn(IFEQ, labelNotTrue);
+ truthCompile(expected, false);
+ methodVisitor.visitJumpInsn(GOTO, labelNotReturn);
+ methodVisitor.visitLabel(labelNotTrue);
+ truthCompile(expected, true);
+ methodVisitor.visitLabel(labelNotReturn);
+
+ break;
+ case JavascriptParser.AT_BOOL_AND:
+ Label andFalse = new Label();
+ Label andEnd = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.INT);
+ methodVisitor.visitJumpInsn(IFEQ, andFalse);
+ recursiveCompile(current.getChild(1), ComputedType.INT);
+ methodVisitor.visitJumpInsn(IFEQ, andFalse);
+ truthCompile(expected, true);
+ methodVisitor.visitJumpInsn(GOTO, andEnd);
+ methodVisitor.visitLabel(andFalse);
+ truthCompile(expected, false);
+ methodVisitor.visitLabel(andEnd);
+
+ break;
+ case JavascriptParser.AT_BOOL_OR:
+ Label orTrue = new Label();
+ Label orEnd = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.INT);
+ methodVisitor.visitJumpInsn(IFNE, orTrue);
+ recursiveCompile(current.getChild(1), ComputedType.INT);
+ methodVisitor.visitJumpInsn(IFNE, orTrue);
+ truthCompile(expected, false);
+ methodVisitor.visitJumpInsn(GOTO, orEnd);
+ methodVisitor.visitLabel(orTrue);
+ truthCompile(expected, true);
+ methodVisitor.visitLabel(orEnd);
+
+ break;
+ case JavascriptParser.AT_COND_QUE:
+ Label condFalse = new Label();
+ Label condEnd = new Label();
+
+ recursiveCompile(current.getChild(0), ComputedType.INT);
+ methodVisitor.visitJumpInsn(IFEQ, condFalse);
+ recursiveCompile(current.getChild(1), expected);
+ methodVisitor.visitJumpInsn(GOTO, condEnd);
+ methodVisitor.visitLabel(condFalse);
+ recursiveCompile(current.getChild(2), expected);
+ methodVisitor.visitLabel(condEnd);
+
+ break;
+ default:
+ throw new IllegalStateException("Unknown operation specified: (" + current.getText() + ").");
+ }
+ }
+
+ private void typeCompile(ComputedType expected, ComputedType actual) {
+ if (expected == actual) {
+ return;
+ }
+
+ switch (expected) {
+ case INT:
+ if (actual == ComputedType.LONG) {
+ methodVisitor.visitInsn(L2I);
+ } else {
+ methodVisitor.visitInsn(D2I);
+ }
+
+ break;
+ case LONG:
+ if (actual == ComputedType.INT) {
+ methodVisitor.visitInsn(I2L);
+ } else {
+ methodVisitor.visitInsn(D2L);
+ }
+
+ break;
+ default:
+ if (actual == ComputedType.INT) {
+ methodVisitor.visitInsn(I2D);
+ } else {
+ methodVisitor.visitInsn(L2D);
+ }
+
+ break;
+ }
+ }
+
+ private void truthCompile(ComputedType expected, boolean truth) {
+ switch (expected) {
+ case INT:
+ methodVisitor.visitInsn(truth ? ICONST_1 : ICONST_0);
+
+ break;
+ case LONG:
+ methodVisitor.visitInsn(truth ? LCONST_1 : LCONST_0);
+
+ break;
+ default:
+ methodVisitor.visitInsn(truth ? DCONST_1 : DCONST_0);
+
+ break;
+ }
+ }
+
+ private void endCompile() {
+ methodVisitor.visitInsn(DRETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ classWriter.visitEnd();
+ }
+
+ private static Tree getAntlrComputedExpressionTree(String expression) throws ParseException {
+ CharStream input = new ANTLRStringStream(expression);
+ JavascriptLexer lexer = new JavascriptLexer(input);
+ CommonTokenStream tokens = new CommonTokenStream(lexer);
+ JavascriptParser parser = new JavascriptParser(tokens);
+
+ try {
+ return parser.expression().tree;
+
+ } catch (RecognitionException exception) {
+ throw new IllegalArgumentException(exception);
+ } catch (RuntimeException exception) {
+ if (exception.getCause() instanceof ParseException) {
+ throw (ParseException)exception.getCause();
+ }
+ throw exception;
+ }
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptFunction.java lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptFunction.java
new file mode 100644
index 0000000..a014df9
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptFunction.java
@@ -0,0 +1,116 @@
+package org.apache.lucene.expressions.js;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.lucene.util.MathUtil;
+import org.objectweb.asm.Type;
+
+/**
+ * A wrapper to delegate function calls from a javascript expression.
+ */
+class JavascriptFunction {
+ private static Map methods = null;
+
+ static {
+ String mathClass = Type.getInternalName(Math.class);
+ String mathUtilClass = Type.getInternalName(MathUtil.class);
+
+ JavascriptFunction abs = new JavascriptFunction("abs", 1, mathClass, "abs", "(D)D" );
+ JavascriptFunction acos = new JavascriptFunction("acos", 1, mathClass, "acos", "(D)D" );
+ JavascriptFunction acosh = new JavascriptFunction("acosh", 1, mathUtilClass, "acosh", "(D)D" );
+ JavascriptFunction asin = new JavascriptFunction("asin", 1, mathClass, "asin", "(D)D" );
+ JavascriptFunction asinh = new JavascriptFunction("asinh", 1, mathUtilClass, "asinh", "(D)D" );
+ JavascriptFunction atan = new JavascriptFunction("atan", 1, mathClass, "atan", "(D)D" );
+ JavascriptFunction atan2 = new JavascriptFunction("atan2", 1, mathClass, "atan2", "(DD)D");
+ JavascriptFunction atanh = new JavascriptFunction("atanh", 1, mathUtilClass, "atanh", "(D)D" );
+ JavascriptFunction ceil = new JavascriptFunction("ceil", 1, mathClass, "ceil", "(D)D" );
+ JavascriptFunction cos = new JavascriptFunction("cos", 1, mathClass, "cos", "(D)D" );
+ JavascriptFunction cosh = new JavascriptFunction("cosh", 1, mathClass, "cosh", "(D)D" );
+ JavascriptFunction exp = new JavascriptFunction("exp", 1, mathClass, "exp", "(D)D" );
+ JavascriptFunction floor = new JavascriptFunction("floor", 1, mathClass, "floor", "(D)D" );
+ JavascriptFunction ln = new JavascriptFunction("ln", 1, mathClass, "log", "(D)D" );
+ JavascriptFunction log10 = new JavascriptFunction("log10", 1, mathClass, "log10", "(D)D" );
+ JavascriptFunction logn = new JavascriptFunction("logn", 2, mathUtilClass, "log", "(DD)D");
+ JavascriptFunction pow = new JavascriptFunction("pow", 2, mathClass, "pow", "(DD)D");
+ JavascriptFunction sin = new JavascriptFunction("sin", 1, mathClass, "sin", "(D)D" );
+ JavascriptFunction sinh = new JavascriptFunction("sinh", 1, mathClass, "sinh", "(D)D" );
+ JavascriptFunction sqrt = new JavascriptFunction("sqrt", 1, mathClass, "sqrt", "(D)D" );
+ JavascriptFunction tan = new JavascriptFunction("tan", 1, mathClass, "tan", "(D)D" );
+ JavascriptFunction tanh = new JavascriptFunction("tanh", 1, mathClass, "tanh", "(D)D" );
+
+ JavascriptFunction min = new JavascriptFunction("min", 2, mathClass, "min", "(DD)D");
+ JavascriptFunction max = new JavascriptFunction("max", 2, mathClass, "max", "(DD)D");
+
+ methods = new HashMap();
+ methods.put( "abs", abs );
+ methods.put( "acos", acos );
+ methods.put( "acosh", acosh );
+ methods.put( "asin", asin );
+ methods.put( "asinh", asinh );
+ methods.put( "atan", atan );
+ methods.put( "atan2", atan2 );
+ methods.put( "atanh", atanh );
+ methods.put( "ceil", ceil );
+ methods.put( "cos", cos );
+ methods.put( "cosh", cosh );
+ methods.put( "exp", exp );
+ methods.put( "floor", floor );
+ methods.put( "ln", ln );
+ methods.put( "log10", log10 );
+ methods.put( "logn", logn );
+ methods.put( "max", max );
+ methods.put( "min", min );
+ methods.put( "pow", pow );
+ methods.put( "sin", sin );
+ methods.put( "sinh", sinh );
+ methods.put( "sqrt", sqrt );
+ methods.put( "tan", tan );
+ methods.put( "tanh", tanh );
+ }
+
+ public static JavascriptFunction getMethod(String call, int arguments) {
+ JavascriptFunction method = methods.get(call);
+
+ if (method == null) {
+ throw new IllegalArgumentException("Unrecognized method call (" + call + ").");
+ }
+
+ if (arguments != method.arguments && method.arguments != -1) {
+ throw new IllegalArgumentException("Expected (" + method.arguments + ") arguments for method call (" +
+ call + "), but found (" + arguments + ").");
+ }
+
+ return method;
+ }
+
+ public final String call;
+ public final int arguments;
+ public final String klass;
+ public final String method;
+ public final String signature;
+
+ private JavascriptFunction(String call, int arguments, String klass, String method, String signature) {
+ this.call = call;
+ this.arguments = arguments;
+ this.klass = klass;
+ this.method = method;
+ this.signature = signature;
+ }
+}
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptLexer.java lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptLexer.java
new file mode 100644
index 0000000..3ca28f4
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptLexer.java
@@ -0,0 +1,1985 @@
+// ANTLR GENERATED CODE: DO NOT EDIT
+
+package org.apache.lucene.expressions.js;
+
+import java.text.ParseException;
+
+
+import org.antlr.runtime.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+@SuppressWarnings({"all", "warnings", "unchecked"})
+class JavascriptLexer extends Lexer {
+ public static final int EOF=-1;
+ public static final int AT_ADD=4;
+ public static final int AT_BIT_AND=5;
+ public static final int AT_BIT_NOT=6;
+ public static final int AT_BIT_OR=7;
+ public static final int AT_BIT_SHL=8;
+ public static final int AT_BIT_SHR=9;
+ public static final int AT_BIT_SHU=10;
+ public static final int AT_BIT_XOR=11;
+ public static final int AT_BOOL_AND=12;
+ public static final int AT_BOOL_NOT=13;
+ public static final int AT_BOOL_OR=14;
+ public static final int AT_CALL=15;
+ public static final int AT_COLON=16;
+ public static final int AT_COMMA=17;
+ public static final int AT_COMP_EQ=18;
+ public static final int AT_COMP_GT=19;
+ public static final int AT_COMP_GTE=20;
+ public static final int AT_COMP_LT=21;
+ public static final int AT_COMP_LTE=22;
+ public static final int AT_COMP_NEQ=23;
+ public static final int AT_COND_QUE=24;
+ public static final int AT_DIVIDE=25;
+ public static final int AT_DOT=26;
+ public static final int AT_LPAREN=27;
+ public static final int AT_MODULO=28;
+ public static final int AT_MULTIPLY=29;
+ public static final int AT_NEGATE=30;
+ public static final int AT_RPAREN=31;
+ public static final int AT_SUBTRACT=32;
+ public static final int DECIMAL=33;
+ public static final int DECIMALDIGIT=34;
+ public static final int DECIMALINTEGER=35;
+ public static final int EXPONENT=36;
+ public static final int HEX=37;
+ public static final int HEXDIGIT=38;
+ public static final int ID=39;
+ public static final int OCTAL=40;
+ public static final int OCTALDIGIT=41;
+ public static final int WS=42;
+
+
+ @Override
+ public void displayRecognitionError(String[] tokenNames, RecognitionException re) {
+ String message = " unexpected character '" + (char)re.c
+ + "' at position (" + re.charPositionInLine + ").";
+ ParseException parseException = new ParseException(message, re.charPositionInLine);
+ parseException.initCause(re);
+ throw new RuntimeException(parseException);
+ }
+
+
+
+ // delegates
+ // delegators
+ public Lexer[] getDelegates() {
+ return new Lexer[] {};
+ }
+
+ public JavascriptLexer() {}
+ public JavascriptLexer(CharStream input) {
+ this(input, new RecognizerSharedState());
+ }
+ public JavascriptLexer(CharStream input, RecognizerSharedState state) {
+ super(input,state);
+ }
+ public String getGrammarFileName() { return "src/java/org/apache/lucene/expressions/js/Javascript.g"; }
+
+ // $ANTLR start "AT_ADD"
+ public final void mAT_ADD() throws RecognitionException {
+ try {
+ int _type = AT_ADD;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:25:8: ( '+' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:25:10: '+'
+ {
+ match('+');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_ADD"
+
+ // $ANTLR start "AT_BIT_AND"
+ public final void mAT_BIT_AND() throws RecognitionException {
+ try {
+ int _type = AT_BIT_AND;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:26:12: ( '&' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:26:14: '&'
+ {
+ match('&');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BIT_AND"
+
+ // $ANTLR start "AT_BIT_NOT"
+ public final void mAT_BIT_NOT() throws RecognitionException {
+ try {
+ int _type = AT_BIT_NOT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:27:12: ( '~' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:27:14: '~'
+ {
+ match('~');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BIT_NOT"
+
+ // $ANTLR start "AT_BIT_OR"
+ public final void mAT_BIT_OR() throws RecognitionException {
+ try {
+ int _type = AT_BIT_OR;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:28:11: ( '|' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:28:13: '|'
+ {
+ match('|');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BIT_OR"
+
+ // $ANTLR start "AT_BIT_SHL"
+ public final void mAT_BIT_SHL() throws RecognitionException {
+ try {
+ int _type = AT_BIT_SHL;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:29:12: ( '<<' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:29:14: '<<'
+ {
+ match("<<");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BIT_SHL"
+
+ // $ANTLR start "AT_BIT_SHR"
+ public final void mAT_BIT_SHR() throws RecognitionException {
+ try {
+ int _type = AT_BIT_SHR;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:30:12: ( '>>' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:30:14: '>>'
+ {
+ match(">>");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BIT_SHR"
+
+ // $ANTLR start "AT_BIT_SHU"
+ public final void mAT_BIT_SHU() throws RecognitionException {
+ try {
+ int _type = AT_BIT_SHU;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:31:12: ( '>>>' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:31:14: '>>>'
+ {
+ match(">>>");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BIT_SHU"
+
+ // $ANTLR start "AT_BIT_XOR"
+ public final void mAT_BIT_XOR() throws RecognitionException {
+ try {
+ int _type = AT_BIT_XOR;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:32:12: ( '^' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:32:14: '^'
+ {
+ match('^');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BIT_XOR"
+
+ // $ANTLR start "AT_BOOL_AND"
+ public final void mAT_BOOL_AND() throws RecognitionException {
+ try {
+ int _type = AT_BOOL_AND;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:33:13: ( '&&' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:33:15: '&&'
+ {
+ match("&&");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BOOL_AND"
+
+ // $ANTLR start "AT_BOOL_NOT"
+ public final void mAT_BOOL_NOT() throws RecognitionException {
+ try {
+ int _type = AT_BOOL_NOT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:34:13: ( '!' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:34:15: '!'
+ {
+ match('!');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BOOL_NOT"
+
+ // $ANTLR start "AT_BOOL_OR"
+ public final void mAT_BOOL_OR() throws RecognitionException {
+ try {
+ int _type = AT_BOOL_OR;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:35:12: ( '||' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:35:14: '||'
+ {
+ match("||");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_BOOL_OR"
+
+ // $ANTLR start "AT_COLON"
+ public final void mAT_COLON() throws RecognitionException {
+ try {
+ int _type = AT_COLON;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:36:10: ( ':' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:36:12: ':'
+ {
+ match(':');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COLON"
+
+ // $ANTLR start "AT_COMMA"
+ public final void mAT_COMMA() throws RecognitionException {
+ try {
+ int _type = AT_COMMA;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:37:10: ( ',' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:37:12: ','
+ {
+ match(',');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COMMA"
+
+ // $ANTLR start "AT_COMP_EQ"
+ public final void mAT_COMP_EQ() throws RecognitionException {
+ try {
+ int _type = AT_COMP_EQ;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:38:12: ( '==' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:38:14: '=='
+ {
+ match("==");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COMP_EQ"
+
+ // $ANTLR start "AT_COMP_GT"
+ public final void mAT_COMP_GT() throws RecognitionException {
+ try {
+ int _type = AT_COMP_GT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:39:12: ( '>' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:39:14: '>'
+ {
+ match('>');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COMP_GT"
+
+ // $ANTLR start "AT_COMP_GTE"
+ public final void mAT_COMP_GTE() throws RecognitionException {
+ try {
+ int _type = AT_COMP_GTE;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:40:13: ( '>=' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:40:15: '>='
+ {
+ match(">=");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COMP_GTE"
+
+ // $ANTLR start "AT_COMP_LT"
+ public final void mAT_COMP_LT() throws RecognitionException {
+ try {
+ int _type = AT_COMP_LT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:41:12: ( '<' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:41:14: '<'
+ {
+ match('<');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COMP_LT"
+
+ // $ANTLR start "AT_COMP_LTE"
+ public final void mAT_COMP_LTE() throws RecognitionException {
+ try {
+ int _type = AT_COMP_LTE;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:42:13: ( '<=' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:42:15: '<='
+ {
+ match("<=");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COMP_LTE"
+
+ // $ANTLR start "AT_COMP_NEQ"
+ public final void mAT_COMP_NEQ() throws RecognitionException {
+ try {
+ int _type = AT_COMP_NEQ;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:43:13: ( '!=' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:43:15: '!='
+ {
+ match("!=");
+
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COMP_NEQ"
+
+ // $ANTLR start "AT_COND_QUE"
+ public final void mAT_COND_QUE() throws RecognitionException {
+ try {
+ int _type = AT_COND_QUE;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:44:13: ( '?' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:44:15: '?'
+ {
+ match('?');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_COND_QUE"
+
+ // $ANTLR start "AT_DIVIDE"
+ public final void mAT_DIVIDE() throws RecognitionException {
+ try {
+ int _type = AT_DIVIDE;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:45:11: ( '/' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:45:13: '/'
+ {
+ match('/');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_DIVIDE"
+
+ // $ANTLR start "AT_DOT"
+ public final void mAT_DOT() throws RecognitionException {
+ try {
+ int _type = AT_DOT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:46:8: ( '.' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:46:10: '.'
+ {
+ match('.');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_DOT"
+
+ // $ANTLR start "AT_LPAREN"
+ public final void mAT_LPAREN() throws RecognitionException {
+ try {
+ int _type = AT_LPAREN;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:47:11: ( '(' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:47:13: '('
+ {
+ match('(');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_LPAREN"
+
+ // $ANTLR start "AT_MODULO"
+ public final void mAT_MODULO() throws RecognitionException {
+ try {
+ int _type = AT_MODULO;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:48:11: ( '%' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:48:13: '%'
+ {
+ match('%');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_MODULO"
+
+ // $ANTLR start "AT_MULTIPLY"
+ public final void mAT_MULTIPLY() throws RecognitionException {
+ try {
+ int _type = AT_MULTIPLY;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:49:13: ( '*' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:49:15: '*'
+ {
+ match('*');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_MULTIPLY"
+
+ // $ANTLR start "AT_RPAREN"
+ public final void mAT_RPAREN() throws RecognitionException {
+ try {
+ int _type = AT_RPAREN;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:50:11: ( ')' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:50:13: ')'
+ {
+ match(')');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_RPAREN"
+
+ // $ANTLR start "AT_SUBTRACT"
+ public final void mAT_SUBTRACT() throws RecognitionException {
+ try {
+ int _type = AT_SUBTRACT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:51:13: ( '-' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:51:15: '-'
+ {
+ match('-');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "AT_SUBTRACT"
+
+ // $ANTLR start "ID"
+ public final void mID() throws RecognitionException {
+ try {
+ int _type = ID;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:334:5: ( ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:334:7: ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
+ {
+ if ( (input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:334:31: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
+ loop1:
+ do {
+ int alt1=2;
+ int LA1_0 = input.LA(1);
+
+ if ( ((LA1_0 >= '0' && LA1_0 <= '9')||(LA1_0 >= 'A' && LA1_0 <= 'Z')||LA1_0=='_'||(LA1_0 >= 'a' && LA1_0 <= 'z')) ) {
+ alt1=1;
+ }
+
+
+ switch (alt1) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ break loop1;
+ }
+ } while (true);
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "ID"
+
+ // $ANTLR start "WS"
+ public final void mWS() throws RecognitionException {
+ try {
+ int _type = WS;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:338:5: ( ( ' ' | '\\t' | '\\n' | '\\r' )+ )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:338:7: ( ' ' | '\\t' | '\\n' | '\\r' )+
+ {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:338:7: ( ' ' | '\\t' | '\\n' | '\\r' )+
+ int cnt2=0;
+ loop2:
+ do {
+ int alt2=2;
+ int LA2_0 = input.LA(1);
+
+ if ( ((LA2_0 >= '\t' && LA2_0 <= '\n')||LA2_0=='\r'||LA2_0==' ') ) {
+ alt2=1;
+ }
+
+
+ switch (alt2) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '\t' && input.LA(1) <= '\n')||input.LA(1)=='\r'||input.LA(1)==' ' ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ if ( cnt2 >= 1 ) break loop2;
+ EarlyExitException eee =
+ new EarlyExitException(2, input);
+ throw eee;
+ }
+ cnt2++;
+ } while (true);
+
+
+ skip();
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "WS"
+
+ // $ANTLR start "DECIMAL"
+ public final void mDECIMAL() throws RecognitionException {
+ try {
+ int _type = DECIMAL;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:342:5: ( DECIMALINTEGER AT_DOT ( DECIMALDIGIT )* ( EXPONENT )? | AT_DOT ( DECIMALDIGIT )+ ( EXPONENT )? | DECIMALINTEGER ( EXPONENT )? )
+ int alt8=3;
+ alt8 = dfa8.predict(input);
+ switch (alt8) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:342:7: DECIMALINTEGER AT_DOT ( DECIMALDIGIT )* ( EXPONENT )?
+ {
+ mDECIMALINTEGER();
+
+
+ mAT_DOT();
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:342:29: ( DECIMALDIGIT )*
+ loop3:
+ do {
+ int alt3=2;
+ int LA3_0 = input.LA(1);
+
+ if ( ((LA3_0 >= '0' && LA3_0 <= '9')) ) {
+ alt3=1;
+ }
+
+
+ switch (alt3) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ break loop3;
+ }
+ } while (true);
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:342:43: ( EXPONENT )?
+ int alt4=2;
+ int LA4_0 = input.LA(1);
+
+ if ( (LA4_0=='E'||LA4_0=='e') ) {
+ alt4=1;
+ }
+ switch (alt4) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:342:43: EXPONENT
+ {
+ mEXPONENT();
+
+
+ }
+ break;
+
+ }
+
+
+ }
+ break;
+ case 2 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:343:7: AT_DOT ( DECIMALDIGIT )+ ( EXPONENT )?
+ {
+ mAT_DOT();
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:343:14: ( DECIMALDIGIT )+
+ int cnt5=0;
+ loop5:
+ do {
+ int alt5=2;
+ int LA5_0 = input.LA(1);
+
+ if ( ((LA5_0 >= '0' && LA5_0 <= '9')) ) {
+ alt5=1;
+ }
+
+
+ switch (alt5) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ if ( cnt5 >= 1 ) break loop5;
+ EarlyExitException eee =
+ new EarlyExitException(5, input);
+ throw eee;
+ }
+ cnt5++;
+ } while (true);
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:343:28: ( EXPONENT )?
+ int alt6=2;
+ int LA6_0 = input.LA(1);
+
+ if ( (LA6_0=='E'||LA6_0=='e') ) {
+ alt6=1;
+ }
+ switch (alt6) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:343:28: EXPONENT
+ {
+ mEXPONENT();
+
+
+ }
+ break;
+
+ }
+
+
+ }
+ break;
+ case 3 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:344:7: DECIMALINTEGER ( EXPONENT )?
+ {
+ mDECIMALINTEGER();
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:344:22: ( EXPONENT )?
+ int alt7=2;
+ int LA7_0 = input.LA(1);
+
+ if ( (LA7_0=='E'||LA7_0=='e') ) {
+ alt7=1;
+ }
+ switch (alt7) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:344:22: EXPONENT
+ {
+ mEXPONENT();
+
+
+ }
+ break;
+
+ }
+
+
+ }
+ break;
+
+ }
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "DECIMAL"
+
+ // $ANTLR start "OCTAL"
+ public final void mOCTAL() throws RecognitionException {
+ try {
+ int _type = OCTAL;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:348:5: ( '0' ( OCTALDIGIT )+ )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:348:7: '0' ( OCTALDIGIT )+
+ {
+ match('0');
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:348:11: ( OCTALDIGIT )+
+ int cnt9=0;
+ loop9:
+ do {
+ int alt9=2;
+ int LA9_0 = input.LA(1);
+
+ if ( ((LA9_0 >= '0' && LA9_0 <= '7')) ) {
+ alt9=1;
+ }
+
+
+ switch (alt9) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '7') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ if ( cnt9 >= 1 ) break loop9;
+ EarlyExitException eee =
+ new EarlyExitException(9, input);
+ throw eee;
+ }
+ cnt9++;
+ } while (true);
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "OCTAL"
+
+ // $ANTLR start "HEX"
+ public final void mHEX() throws RecognitionException {
+ try {
+ int _type = HEX;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:352:5: ( ( '0x' | '0X' ) ( HEXDIGIT )+ )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:352:7: ( '0x' | '0X' ) ( HEXDIGIT )+
+ {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:352:7: ( '0x' | '0X' )
+ int alt10=2;
+ int LA10_0 = input.LA(1);
+
+ if ( (LA10_0=='0') ) {
+ int LA10_1 = input.LA(2);
+
+ if ( (LA10_1=='x') ) {
+ alt10=1;
+ }
+ else if ( (LA10_1=='X') ) {
+ alt10=2;
+ }
+ else {
+ NoViableAltException nvae =
+ new NoViableAltException("", 10, 1, input);
+
+ throw nvae;
+
+ }
+ }
+ else {
+ NoViableAltException nvae =
+ new NoViableAltException("", 10, 0, input);
+
+ throw nvae;
+
+ }
+ switch (alt10) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:352:8: '0x'
+ {
+ match("0x");
+
+
+
+ }
+ break;
+ case 2 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:352:13: '0X'
+ {
+ match("0X");
+
+
+
+ }
+ break;
+
+ }
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:352:19: ( HEXDIGIT )+
+ int cnt11=0;
+ loop11:
+ do {
+ int alt11=2;
+ int LA11_0 = input.LA(1);
+
+ if ( ((LA11_0 >= '0' && LA11_0 <= '9')||(LA11_0 >= 'A' && LA11_0 <= 'F')||(LA11_0 >= 'a' && LA11_0 <= 'f')) ) {
+ alt11=1;
+ }
+
+
+ switch (alt11) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'F')||(input.LA(1) >= 'a' && input.LA(1) <= 'f') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ if ( cnt11 >= 1 ) break loop11;
+ EarlyExitException eee =
+ new EarlyExitException(11, input);
+ throw eee;
+ }
+ cnt11++;
+ } while (true);
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "HEX"
+
+ // $ANTLR start "DECIMALINTEGER"
+ public final void mDECIMALINTEGER() throws RecognitionException {
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:358:5: ( '0' | '1' .. '9' ( DECIMALDIGIT )* )
+ int alt13=2;
+ int LA13_0 = input.LA(1);
+
+ if ( (LA13_0=='0') ) {
+ alt13=1;
+ }
+ else if ( ((LA13_0 >= '1' && LA13_0 <= '9')) ) {
+ alt13=2;
+ }
+ else {
+ NoViableAltException nvae =
+ new NoViableAltException("", 13, 0, input);
+
+ throw nvae;
+
+ }
+ switch (alt13) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:358:7: '0'
+ {
+ match('0');
+
+ }
+ break;
+ case 2 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:359:7: '1' .. '9' ( DECIMALDIGIT )*
+ {
+ matchRange('1','9');
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:359:16: ( DECIMALDIGIT )*
+ loop12:
+ do {
+ int alt12=2;
+ int LA12_0 = input.LA(1);
+
+ if ( ((LA12_0 >= '0' && LA12_0 <= '9')) ) {
+ alt12=1;
+ }
+
+
+ switch (alt12) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ break loop12;
+ }
+ } while (true);
+
+
+ }
+ break;
+
+ }
+
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "DECIMALINTEGER"
+
+ // $ANTLR start "EXPONENT"
+ public final void mEXPONENT() throws RecognitionException {
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:364:5: ( ( 'e' | 'E' ) ( '+' | '-' )? ( DECIMALDIGIT )+ )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:364:7: ( 'e' | 'E' ) ( '+' | '-' )? ( DECIMALDIGIT )+
+ {
+ if ( input.LA(1)=='E'||input.LA(1)=='e' ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:364:17: ( '+' | '-' )?
+ int alt14=2;
+ int LA14_0 = input.LA(1);
+
+ if ( (LA14_0=='+'||LA14_0=='-') ) {
+ alt14=1;
+ }
+ switch (alt14) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( input.LA(1)=='+'||input.LA(1)=='-' ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ }
+
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:364:28: ( DECIMALDIGIT )+
+ int cnt15=0;
+ loop15:
+ do {
+ int alt15=2;
+ int LA15_0 = input.LA(1);
+
+ if ( ((LA15_0 >= '0' && LA15_0 <= '9')) ) {
+ alt15=1;
+ }
+
+
+ switch (alt15) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ if ( cnt15 >= 1 ) break loop15;
+ EarlyExitException eee =
+ new EarlyExitException(15, input);
+ throw eee;
+ }
+ cnt15++;
+ } while (true);
+
+
+ }
+
+
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "EXPONENT"
+
+ // $ANTLR start "DECIMALDIGIT"
+ public final void mDECIMALDIGIT() throws RecognitionException {
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:369:5: ( '0' .. '9' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+
+
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "DECIMALDIGIT"
+
+ // $ANTLR start "HEXDIGIT"
+ public final void mHEXDIGIT() throws RecognitionException {
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:374:5: ( DECIMALDIGIT | 'a' .. 'f' | 'A' .. 'F' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'F')||(input.LA(1) >= 'a' && input.LA(1) <= 'f') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+
+
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "HEXDIGIT"
+
+ // $ANTLR start "OCTALDIGIT"
+ public final void mOCTALDIGIT() throws RecognitionException {
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:381:5: ( '0' .. '7' )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '7') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+
+
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "OCTALDIGIT"
+
+ public void mTokens() throws RecognitionException {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:8: ( AT_ADD | AT_BIT_AND | AT_BIT_NOT | AT_BIT_OR | AT_BIT_SHL | AT_BIT_SHR | AT_BIT_SHU | AT_BIT_XOR | AT_BOOL_AND | AT_BOOL_NOT | AT_BOOL_OR | AT_COLON | AT_COMMA | AT_COMP_EQ | AT_COMP_GT | AT_COMP_GTE | AT_COMP_LT | AT_COMP_LTE | AT_COMP_NEQ | AT_COND_QUE | AT_DIVIDE | AT_DOT | AT_LPAREN | AT_MODULO | AT_MULTIPLY | AT_RPAREN | AT_SUBTRACT | ID | WS | DECIMAL | OCTAL | HEX )
+ int alt16=32;
+ switch ( input.LA(1) ) {
+ case '+':
+ {
+ alt16=1;
+ }
+ break;
+ case '&':
+ {
+ int LA16_2 = input.LA(2);
+
+ if ( (LA16_2=='&') ) {
+ alt16=9;
+ }
+ else {
+ alt16=2;
+ }
+ }
+ break;
+ case '~':
+ {
+ alt16=3;
+ }
+ break;
+ case '|':
+ {
+ int LA16_4 = input.LA(2);
+
+ if ( (LA16_4=='|') ) {
+ alt16=11;
+ }
+ else {
+ alt16=4;
+ }
+ }
+ break;
+ case '<':
+ {
+ switch ( input.LA(2) ) {
+ case '<':
+ {
+ alt16=5;
+ }
+ break;
+ case '=':
+ {
+ alt16=18;
+ }
+ break;
+ default:
+ alt16=17;
+ }
+
+ }
+ break;
+ case '>':
+ {
+ switch ( input.LA(2) ) {
+ case '>':
+ {
+ int LA16_31 = input.LA(3);
+
+ if ( (LA16_31=='>') ) {
+ alt16=7;
+ }
+ else {
+ alt16=6;
+ }
+ }
+ break;
+ case '=':
+ {
+ alt16=16;
+ }
+ break;
+ default:
+ alt16=15;
+ }
+
+ }
+ break;
+ case '^':
+ {
+ alt16=8;
+ }
+ break;
+ case '!':
+ {
+ int LA16_8 = input.LA(2);
+
+ if ( (LA16_8=='=') ) {
+ alt16=19;
+ }
+ else {
+ alt16=10;
+ }
+ }
+ break;
+ case ':':
+ {
+ alt16=12;
+ }
+ break;
+ case ',':
+ {
+ alt16=13;
+ }
+ break;
+ case '=':
+ {
+ alt16=14;
+ }
+ break;
+ case '?':
+ {
+ alt16=20;
+ }
+ break;
+ case '/':
+ {
+ alt16=21;
+ }
+ break;
+ case '.':
+ {
+ int LA16_14 = input.LA(2);
+
+ if ( ((LA16_14 >= '0' && LA16_14 <= '9')) ) {
+ alt16=30;
+ }
+ else {
+ alt16=22;
+ }
+ }
+ break;
+ case '(':
+ {
+ alt16=23;
+ }
+ break;
+ case '%':
+ {
+ alt16=24;
+ }
+ break;
+ case '*':
+ {
+ alt16=25;
+ }
+ break;
+ case ')':
+ {
+ alt16=26;
+ }
+ break;
+ case '-':
+ {
+ alt16=27;
+ }
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ case '_':
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ {
+ alt16=28;
+ }
+ break;
+ case '\t':
+ case '\n':
+ case '\r':
+ case ' ':
+ {
+ alt16=29;
+ }
+ break;
+ case '0':
+ {
+ switch ( input.LA(2) ) {
+ case 'X':
+ case 'x':
+ {
+ alt16=32;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ alt16=31;
+ }
+ break;
+ default:
+ alt16=30;
+ }
+
+ }
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ alt16=30;
+ }
+ break;
+ default:
+ NoViableAltException nvae =
+ new NoViableAltException("", 16, 0, input);
+
+ throw nvae;
+
+ }
+
+ switch (alt16) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:10: AT_ADD
+ {
+ mAT_ADD();
+
+
+ }
+ break;
+ case 2 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:17: AT_BIT_AND
+ {
+ mAT_BIT_AND();
+
+
+ }
+ break;
+ case 3 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:28: AT_BIT_NOT
+ {
+ mAT_BIT_NOT();
+
+
+ }
+ break;
+ case 4 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:39: AT_BIT_OR
+ {
+ mAT_BIT_OR();
+
+
+ }
+ break;
+ case 5 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:49: AT_BIT_SHL
+ {
+ mAT_BIT_SHL();
+
+
+ }
+ break;
+ case 6 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:60: AT_BIT_SHR
+ {
+ mAT_BIT_SHR();
+
+
+ }
+ break;
+ case 7 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:71: AT_BIT_SHU
+ {
+ mAT_BIT_SHU();
+
+
+ }
+ break;
+ case 8 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:82: AT_BIT_XOR
+ {
+ mAT_BIT_XOR();
+
+
+ }
+ break;
+ case 9 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:93: AT_BOOL_AND
+ {
+ mAT_BOOL_AND();
+
+
+ }
+ break;
+ case 10 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:105: AT_BOOL_NOT
+ {
+ mAT_BOOL_NOT();
+
+
+ }
+ break;
+ case 11 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:117: AT_BOOL_OR
+ {
+ mAT_BOOL_OR();
+
+
+ }
+ break;
+ case 12 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:128: AT_COLON
+ {
+ mAT_COLON();
+
+
+ }
+ break;
+ case 13 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:137: AT_COMMA
+ {
+ mAT_COMMA();
+
+
+ }
+ break;
+ case 14 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:146: AT_COMP_EQ
+ {
+ mAT_COMP_EQ();
+
+
+ }
+ break;
+ case 15 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:157: AT_COMP_GT
+ {
+ mAT_COMP_GT();
+
+
+ }
+ break;
+ case 16 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:168: AT_COMP_GTE
+ {
+ mAT_COMP_GTE();
+
+
+ }
+ break;
+ case 17 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:180: AT_COMP_LT
+ {
+ mAT_COMP_LT();
+
+
+ }
+ break;
+ case 18 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:191: AT_COMP_LTE
+ {
+ mAT_COMP_LTE();
+
+
+ }
+ break;
+ case 19 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:203: AT_COMP_NEQ
+ {
+ mAT_COMP_NEQ();
+
+
+ }
+ break;
+ case 20 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:215: AT_COND_QUE
+ {
+ mAT_COND_QUE();
+
+
+ }
+ break;
+ case 21 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:227: AT_DIVIDE
+ {
+ mAT_DIVIDE();
+
+
+ }
+ break;
+ case 22 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:237: AT_DOT
+ {
+ mAT_DOT();
+
+
+ }
+ break;
+ case 23 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:244: AT_LPAREN
+ {
+ mAT_LPAREN();
+
+
+ }
+ break;
+ case 24 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:254: AT_MODULO
+ {
+ mAT_MODULO();
+
+
+ }
+ break;
+ case 25 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:264: AT_MULTIPLY
+ {
+ mAT_MULTIPLY();
+
+
+ }
+ break;
+ case 26 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:276: AT_RPAREN
+ {
+ mAT_RPAREN();
+
+
+ }
+ break;
+ case 27 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:286: AT_SUBTRACT
+ {
+ mAT_SUBTRACT();
+
+
+ }
+ break;
+ case 28 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:298: ID
+ {
+ mID();
+
+
+ }
+ break;
+ case 29 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:301: WS
+ {
+ mWS();
+
+
+ }
+ break;
+ case 30 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:304: DECIMAL
+ {
+ mDECIMAL();
+
+
+ }
+ break;
+ case 31 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:312: OCTAL
+ {
+ mOCTAL();
+
+
+ }
+ break;
+ case 32 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:1:318: HEX
+ {
+ mHEX();
+
+
+ }
+ break;
+
+ }
+
+ }
+
+
+ protected DFA8 dfa8 = new DFA8(this);
+ static final String DFA8_eotS =
+ "\1\uffff\2\4\3\uffff\1\4";
+ static final String DFA8_eofS =
+ "\7\uffff";
+ static final String DFA8_minS =
+ "\3\56\3\uffff\1\56";
+ static final String DFA8_maxS =
+ "\1\71\1\56\1\71\3\uffff\1\71";
+ static final String DFA8_acceptS =
+ "\3\uffff\1\2\1\3\1\1\1\uffff";
+ static final String DFA8_specialS =
+ "\7\uffff}>";
+ static final String[] DFA8_transitionS = {
+ "\1\3\1\uffff\1\1\11\2",
+ "\1\5",
+ "\1\5\1\uffff\12\6",
+ "",
+ "",
+ "",
+ "\1\5\1\uffff\12\6"
+ };
+
+ static final short[] DFA8_eot = DFA.unpackEncodedString(DFA8_eotS);
+ static final short[] DFA8_eof = DFA.unpackEncodedString(DFA8_eofS);
+ static final char[] DFA8_min = DFA.unpackEncodedStringToUnsignedChars(DFA8_minS);
+ static final char[] DFA8_max = DFA.unpackEncodedStringToUnsignedChars(DFA8_maxS);
+ static final short[] DFA8_accept = DFA.unpackEncodedString(DFA8_acceptS);
+ static final short[] DFA8_special = DFA.unpackEncodedString(DFA8_specialS);
+ static final short[][] DFA8_transition;
+
+ static {
+ int numStates = DFA8_transitionS.length;
+ DFA8_transition = new short[numStates][];
+ for (int i=0; i", "", "", "", "AT_ADD", "AT_BIT_AND", "AT_BIT_NOT", "AT_BIT_OR", "AT_BIT_SHL", "AT_BIT_SHR", "AT_BIT_SHU", "AT_BIT_XOR", "AT_BOOL_AND", "AT_BOOL_NOT", "AT_BOOL_OR", "AT_CALL", "AT_COLON", "AT_COMMA", "AT_COMP_EQ", "AT_COMP_GT", "AT_COMP_GTE", "AT_COMP_LT", "AT_COMP_LTE", "AT_COMP_NEQ", "AT_COND_QUE", "AT_DIVIDE", "AT_DOT", "AT_LPAREN", "AT_MODULO", "AT_MULTIPLY", "AT_NEGATE", "AT_RPAREN", "AT_SUBTRACT", "DECIMAL", "DECIMALDIGIT", "DECIMALINTEGER", "EXPONENT", "HEX", "HEXDIGIT", "ID", "OCTAL", "OCTALDIGIT", "WS"
+ };
+
+ public static final int EOF=-1;
+ public static final int AT_ADD=4;
+ public static final int AT_BIT_AND=5;
+ public static final int AT_BIT_NOT=6;
+ public static final int AT_BIT_OR=7;
+ public static final int AT_BIT_SHL=8;
+ public static final int AT_BIT_SHR=9;
+ public static final int AT_BIT_SHU=10;
+ public static final int AT_BIT_XOR=11;
+ public static final int AT_BOOL_AND=12;
+ public static final int AT_BOOL_NOT=13;
+ public static final int AT_BOOL_OR=14;
+ public static final int AT_CALL=15;
+ public static final int AT_COLON=16;
+ public static final int AT_COMMA=17;
+ public static final int AT_COMP_EQ=18;
+ public static final int AT_COMP_GT=19;
+ public static final int AT_COMP_GTE=20;
+ public static final int AT_COMP_LT=21;
+ public static final int AT_COMP_LTE=22;
+ public static final int AT_COMP_NEQ=23;
+ public static final int AT_COND_QUE=24;
+ public static final int AT_DIVIDE=25;
+ public static final int AT_DOT=26;
+ public static final int AT_LPAREN=27;
+ public static final int AT_MODULO=28;
+ public static final int AT_MULTIPLY=29;
+ public static final int AT_NEGATE=30;
+ public static final int AT_RPAREN=31;
+ public static final int AT_SUBTRACT=32;
+ public static final int DECIMAL=33;
+ public static final int DECIMALDIGIT=34;
+ public static final int DECIMALINTEGER=35;
+ public static final int EXPONENT=36;
+ public static final int HEX=37;
+ public static final int HEXDIGIT=38;
+ public static final int ID=39;
+ public static final int OCTAL=40;
+ public static final int OCTALDIGIT=41;
+ public static final int WS=42;
+
+ // delegates
+ public Parser[] getDelegates() {
+ return new Parser[] {};
+ }
+
+ // delegators
+
+
+ public JavascriptParser(TokenStream input) {
+ this(input, new RecognizerSharedState());
+ }
+ public JavascriptParser(TokenStream input, RecognizerSharedState state) {
+ super(input, state);
+ }
+
+protected TreeAdaptor adaptor = new CommonTreeAdaptor();
+
+public void setTreeAdaptor(TreeAdaptor adaptor) {
+ this.adaptor = adaptor;
+}
+public TreeAdaptor getTreeAdaptor() {
+ return adaptor;
+}
+ public String[] getTokenNames() { return JavascriptParser.tokenNames; }
+ public String getGrammarFileName() { return "src/java/org/apache/lucene/expressions/js/Javascript.g"; }
+
+
+
+ @Override
+ public void displayRecognitionError(String[] tokenNames, RecognitionException re) {
+ String message;
+
+ if (re.token == null) {
+ message = " unknown error (missing token).";
+ }
+ else if (re instanceof UnwantedTokenException) {
+ message = " extraneous " + getReadableTokenString(re.token)
+ + " at position (" + re.charPositionInLine + ").";
+ }
+ else if (re instanceof MissingTokenException) {
+ message = " missing " + getReadableTokenString(re.token)
+ + " at position (" + re.charPositionInLine + ").";
+ }
+ else if (re instanceof NoViableAltException) {
+ switch (re.token.getType()) {
+ case EOF:
+ message = " unexpected end of expression.";
+ break;
+ default:
+ message = " invalid sequence of tokens near " + getReadableTokenString(re.token)
+ + " at position (" + re.charPositionInLine + ").";
+ break;
+ }
+ }
+ else {
+ message = " unexpected token " + getReadableTokenString(re.token)
+ + " at position (" + re.charPositionInLine + ").";
+ }
+ ParseException parseException = new ParseException(message, re.charPositionInLine);
+ parseException.initCause(re);
+ throw new RuntimeException(parseException);
+ }
+
+ public static String getReadableTokenString(Token token) {
+ if (token == null) {
+ return "unknown token";
+ }
+
+ switch (token.getType()) {
+ case AT_LPAREN:
+ return "open parenthesis '('";
+ case AT_RPAREN:
+ return "close parenthesis ')'";
+ case AT_COMP_LT:
+ return "less than '<'";
+ case AT_COMP_LTE:
+ return "less than or equal '<='";
+ case AT_COMP_GT:
+ return "greater than '>'";
+ case AT_COMP_GTE:
+ return "greater than or equal '>='";
+ case AT_COMP_EQ:
+ return "equal '=='";
+ case AT_NEGATE:
+ return "negate '!='";
+ case AT_BOOL_NOT:
+ return "boolean not '!'";
+ case AT_BOOL_AND:
+ return "boolean and '&&'";
+ case AT_BOOL_OR:
+ return "boolean or '||'";
+ case AT_COND_QUE:
+ return "conditional '?'";
+ case AT_ADD:
+ return "addition '+'";
+ case AT_SUBTRACT:
+ return "subtraction '-'";
+ case AT_MULTIPLY:
+ return "multiplication '*'";
+ case AT_DIVIDE:
+ return "division '/'";
+ case AT_MODULO:
+ return "modulo '%'";
+ case AT_BIT_SHL:
+ return "bit shift left '<<'";
+ case AT_BIT_SHR:
+ return "bit shift right '>>'";
+ case AT_BIT_SHU:
+ return "unsigned bit shift left '<<<'";
+ case AT_BIT_AND:
+ return "bitwise and '&'";
+ case AT_BIT_OR:
+ return "bitwise or '|'";
+ case AT_BIT_XOR:
+ return "bitwise xor '^'";
+ case AT_BIT_NOT:
+ return "bitwise not '~'";
+ case ID:
+ return "identifier '" + token.getText() + "'";
+ case DECIMAL:
+ return "decimal '" + token.getText() + "'";
+ case OCTAL:
+ return "octal '" + token.getText() + "'";
+ case HEX:
+ return "hex '" + token.getText() + "'";
+ case EOF:
+ return "end of expression";
+ default:
+ return "'" + token.getText() + "'";
+ }
+ }
+
+
+
+ public static class expression_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "expression"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:250:1: expression : conditional EOF !;
+ public final JavascriptParser.expression_return expression() throws RecognitionException {
+ JavascriptParser.expression_return retval = new JavascriptParser.expression_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token EOF2=null;
+ JavascriptParser.conditional_return conditional1 =null;
+
+
+ CommonTree EOF2_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:251:5: ( conditional EOF !)
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:251:7: conditional EOF !
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_conditional_in_expression737);
+ conditional1=conditional();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, conditional1.getTree());
+
+ EOF2=(Token)match(input,EOF,FOLLOW_EOF_in_expression739);
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "expression"
+
+
+ public static class conditional_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "conditional"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:254:1: conditional : logical_or ( AT_COND_QUE ^ conditional AT_COLON ! conditional )? ;
+ public final JavascriptParser.conditional_return conditional() throws RecognitionException {
+ JavascriptParser.conditional_return retval = new JavascriptParser.conditional_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_COND_QUE4=null;
+ Token AT_COLON6=null;
+ JavascriptParser.logical_or_return logical_or3 =null;
+
+ JavascriptParser.conditional_return conditional5 =null;
+
+ JavascriptParser.conditional_return conditional7 =null;
+
+
+ CommonTree AT_COND_QUE4_tree=null;
+ CommonTree AT_COLON6_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:255:5: ( logical_or ( AT_COND_QUE ^ conditional AT_COLON ! conditional )? )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:255:7: logical_or ( AT_COND_QUE ^ conditional AT_COLON ! conditional )?
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_logical_or_in_conditional757);
+ logical_or3=logical_or();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, logical_or3.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:255:18: ( AT_COND_QUE ^ conditional AT_COLON ! conditional )?
+ int alt1=2;
+ int LA1_0 = input.LA(1);
+
+ if ( (LA1_0==AT_COND_QUE) ) {
+ alt1=1;
+ }
+ switch (alt1) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:255:19: AT_COND_QUE ^ conditional AT_COLON ! conditional
+ {
+ AT_COND_QUE4=(Token)match(input,AT_COND_QUE,FOLLOW_AT_COND_QUE_in_conditional760);
+ AT_COND_QUE4_tree =
+ (CommonTree)adaptor.create(AT_COND_QUE4)
+ ;
+ root_0 = (CommonTree)adaptor.becomeRoot(AT_COND_QUE4_tree, root_0);
+
+
+ pushFollow(FOLLOW_conditional_in_conditional763);
+ conditional5=conditional();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, conditional5.getTree());
+
+ AT_COLON6=(Token)match(input,AT_COLON,FOLLOW_AT_COLON_in_conditional765);
+
+ pushFollow(FOLLOW_conditional_in_conditional768);
+ conditional7=conditional();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, conditional7.getTree());
+
+ }
+ break;
+
+ }
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "conditional"
+
+
+ public static class logical_or_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "logical_or"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:258:1: logical_or : logical_and ( AT_BOOL_OR ^ logical_and )* ;
+ public final JavascriptParser.logical_or_return logical_or() throws RecognitionException {
+ JavascriptParser.logical_or_return retval = new JavascriptParser.logical_or_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_BOOL_OR9=null;
+ JavascriptParser.logical_and_return logical_and8 =null;
+
+ JavascriptParser.logical_and_return logical_and10 =null;
+
+
+ CommonTree AT_BOOL_OR9_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:259:5: ( logical_and ( AT_BOOL_OR ^ logical_and )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:259:7: logical_and ( AT_BOOL_OR ^ logical_and )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_logical_and_in_logical_or787);
+ logical_and8=logical_and();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, logical_and8.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:259:19: ( AT_BOOL_OR ^ logical_and )*
+ loop2:
+ do {
+ int alt2=2;
+ int LA2_0 = input.LA(1);
+
+ if ( (LA2_0==AT_BOOL_OR) ) {
+ alt2=1;
+ }
+
+
+ switch (alt2) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:259:20: AT_BOOL_OR ^ logical_and
+ {
+ AT_BOOL_OR9=(Token)match(input,AT_BOOL_OR,FOLLOW_AT_BOOL_OR_in_logical_or790);
+ AT_BOOL_OR9_tree =
+ (CommonTree)adaptor.create(AT_BOOL_OR9)
+ ;
+ root_0 = (CommonTree)adaptor.becomeRoot(AT_BOOL_OR9_tree, root_0);
+
+
+ pushFollow(FOLLOW_logical_and_in_logical_or793);
+ logical_and10=logical_and();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, logical_and10.getTree());
+
+ }
+ break;
+
+ default :
+ break loop2;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "logical_or"
+
+
+ public static class logical_and_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "logical_and"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:262:1: logical_and : bitwise_or ( AT_BOOL_AND ^ bitwise_or )* ;
+ public final JavascriptParser.logical_and_return logical_and() throws RecognitionException {
+ JavascriptParser.logical_and_return retval = new JavascriptParser.logical_and_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_BOOL_AND12=null;
+ JavascriptParser.bitwise_or_return bitwise_or11 =null;
+
+ JavascriptParser.bitwise_or_return bitwise_or13 =null;
+
+
+ CommonTree AT_BOOL_AND12_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:263:5: ( bitwise_or ( AT_BOOL_AND ^ bitwise_or )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:263:7: bitwise_or ( AT_BOOL_AND ^ bitwise_or )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_bitwise_or_in_logical_and812);
+ bitwise_or11=bitwise_or();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, bitwise_or11.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:263:18: ( AT_BOOL_AND ^ bitwise_or )*
+ loop3:
+ do {
+ int alt3=2;
+ int LA3_0 = input.LA(1);
+
+ if ( (LA3_0==AT_BOOL_AND) ) {
+ alt3=1;
+ }
+
+
+ switch (alt3) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:263:19: AT_BOOL_AND ^ bitwise_or
+ {
+ AT_BOOL_AND12=(Token)match(input,AT_BOOL_AND,FOLLOW_AT_BOOL_AND_in_logical_and815);
+ AT_BOOL_AND12_tree =
+ (CommonTree)adaptor.create(AT_BOOL_AND12)
+ ;
+ root_0 = (CommonTree)adaptor.becomeRoot(AT_BOOL_AND12_tree, root_0);
+
+
+ pushFollow(FOLLOW_bitwise_or_in_logical_and818);
+ bitwise_or13=bitwise_or();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, bitwise_or13.getTree());
+
+ }
+ break;
+
+ default :
+ break loop3;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "logical_and"
+
+
+ public static class bitwise_or_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "bitwise_or"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:266:1: bitwise_or : bitwise_xor ( AT_BIT_OR ^ bitwise_xor )* ;
+ public final JavascriptParser.bitwise_or_return bitwise_or() throws RecognitionException {
+ JavascriptParser.bitwise_or_return retval = new JavascriptParser.bitwise_or_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_BIT_OR15=null;
+ JavascriptParser.bitwise_xor_return bitwise_xor14 =null;
+
+ JavascriptParser.bitwise_xor_return bitwise_xor16 =null;
+
+
+ CommonTree AT_BIT_OR15_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:267:5: ( bitwise_xor ( AT_BIT_OR ^ bitwise_xor )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:267:7: bitwise_xor ( AT_BIT_OR ^ bitwise_xor )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_bitwise_xor_in_bitwise_or837);
+ bitwise_xor14=bitwise_xor();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, bitwise_xor14.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:267:19: ( AT_BIT_OR ^ bitwise_xor )*
+ loop4:
+ do {
+ int alt4=2;
+ int LA4_0 = input.LA(1);
+
+ if ( (LA4_0==AT_BIT_OR) ) {
+ alt4=1;
+ }
+
+
+ switch (alt4) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:267:20: AT_BIT_OR ^ bitwise_xor
+ {
+ AT_BIT_OR15=(Token)match(input,AT_BIT_OR,FOLLOW_AT_BIT_OR_in_bitwise_or840);
+ AT_BIT_OR15_tree =
+ (CommonTree)adaptor.create(AT_BIT_OR15)
+ ;
+ root_0 = (CommonTree)adaptor.becomeRoot(AT_BIT_OR15_tree, root_0);
+
+
+ pushFollow(FOLLOW_bitwise_xor_in_bitwise_or843);
+ bitwise_xor16=bitwise_xor();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, bitwise_xor16.getTree());
+
+ }
+ break;
+
+ default :
+ break loop4;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "bitwise_or"
+
+
+ public static class bitwise_xor_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "bitwise_xor"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:270:1: bitwise_xor : bitwise_and ( AT_BIT_XOR ^ bitwise_and )* ;
+ public final JavascriptParser.bitwise_xor_return bitwise_xor() throws RecognitionException {
+ JavascriptParser.bitwise_xor_return retval = new JavascriptParser.bitwise_xor_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_BIT_XOR18=null;
+ JavascriptParser.bitwise_and_return bitwise_and17 =null;
+
+ JavascriptParser.bitwise_and_return bitwise_and19 =null;
+
+
+ CommonTree AT_BIT_XOR18_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:271:5: ( bitwise_and ( AT_BIT_XOR ^ bitwise_and )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:271:7: bitwise_and ( AT_BIT_XOR ^ bitwise_and )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_bitwise_and_in_bitwise_xor862);
+ bitwise_and17=bitwise_and();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, bitwise_and17.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:271:19: ( AT_BIT_XOR ^ bitwise_and )*
+ loop5:
+ do {
+ int alt5=2;
+ int LA5_0 = input.LA(1);
+
+ if ( (LA5_0==AT_BIT_XOR) ) {
+ alt5=1;
+ }
+
+
+ switch (alt5) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:271:20: AT_BIT_XOR ^ bitwise_and
+ {
+ AT_BIT_XOR18=(Token)match(input,AT_BIT_XOR,FOLLOW_AT_BIT_XOR_in_bitwise_xor865);
+ AT_BIT_XOR18_tree =
+ (CommonTree)adaptor.create(AT_BIT_XOR18)
+ ;
+ root_0 = (CommonTree)adaptor.becomeRoot(AT_BIT_XOR18_tree, root_0);
+
+
+ pushFollow(FOLLOW_bitwise_and_in_bitwise_xor868);
+ bitwise_and19=bitwise_and();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, bitwise_and19.getTree());
+
+ }
+ break;
+
+ default :
+ break loop5;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "bitwise_xor"
+
+
+ public static class bitwise_and_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "bitwise_and"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:274:1: bitwise_and : equality ( AT_BIT_AND ^ equality )* ;
+ public final JavascriptParser.bitwise_and_return bitwise_and() throws RecognitionException {
+ JavascriptParser.bitwise_and_return retval = new JavascriptParser.bitwise_and_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_BIT_AND21=null;
+ JavascriptParser.equality_return equality20 =null;
+
+ JavascriptParser.equality_return equality22 =null;
+
+
+ CommonTree AT_BIT_AND21_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:275:5: ( equality ( AT_BIT_AND ^ equality )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:275:8: equality ( AT_BIT_AND ^ equality )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_equality_in_bitwise_and888);
+ equality20=equality();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, equality20.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:275:17: ( AT_BIT_AND ^ equality )*
+ loop6:
+ do {
+ int alt6=2;
+ int LA6_0 = input.LA(1);
+
+ if ( (LA6_0==AT_BIT_AND) ) {
+ alt6=1;
+ }
+
+
+ switch (alt6) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:275:18: AT_BIT_AND ^ equality
+ {
+ AT_BIT_AND21=(Token)match(input,AT_BIT_AND,FOLLOW_AT_BIT_AND_in_bitwise_and891);
+ AT_BIT_AND21_tree =
+ (CommonTree)adaptor.create(AT_BIT_AND21)
+ ;
+ root_0 = (CommonTree)adaptor.becomeRoot(AT_BIT_AND21_tree, root_0);
+
+
+ pushFollow(FOLLOW_equality_in_bitwise_and894);
+ equality22=equality();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, equality22.getTree());
+
+ }
+ break;
+
+ default :
+ break loop6;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "bitwise_and"
+
+
+ public static class equality_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "equality"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:278:1: equality : relational ( ( AT_COMP_EQ | AT_COMP_NEQ ) ^ relational )* ;
+ public final JavascriptParser.equality_return equality() throws RecognitionException {
+ JavascriptParser.equality_return retval = new JavascriptParser.equality_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token set24=null;
+ JavascriptParser.relational_return relational23 =null;
+
+ JavascriptParser.relational_return relational25 =null;
+
+
+ CommonTree set24_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:279:5: ( relational ( ( AT_COMP_EQ | AT_COMP_NEQ ) ^ relational )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:279:7: relational ( ( AT_COMP_EQ | AT_COMP_NEQ ) ^ relational )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_relational_in_equality913);
+ relational23=relational();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, relational23.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:279:18: ( ( AT_COMP_EQ | AT_COMP_NEQ ) ^ relational )*
+ loop7:
+ do {
+ int alt7=2;
+ int LA7_0 = input.LA(1);
+
+ if ( (LA7_0==AT_COMP_EQ||LA7_0==AT_COMP_NEQ) ) {
+ alt7=1;
+ }
+
+
+ switch (alt7) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:279:19: ( AT_COMP_EQ | AT_COMP_NEQ ) ^ relational
+ {
+ set24=(Token)input.LT(1);
+
+ set24=(Token)input.LT(1);
+
+ if ( input.LA(1)==AT_COMP_EQ||input.LA(1)==AT_COMP_NEQ ) {
+ input.consume();
+ root_0 = (CommonTree)adaptor.becomeRoot(
+ (CommonTree)adaptor.create(set24)
+ , root_0);
+ state.errorRecovery=false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ throw mse;
+ }
+
+
+ pushFollow(FOLLOW_relational_in_equality925);
+ relational25=relational();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, relational25.getTree());
+
+ }
+ break;
+
+ default :
+ break loop7;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "equality"
+
+
+ public static class relational_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "relational"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:282:1: relational : shift ( ( AT_COMP_LT | AT_COMP_GT | AT_COMP_LTE | AT_COMP_GTE ) ^ shift )* ;
+ public final JavascriptParser.relational_return relational() throws RecognitionException {
+ JavascriptParser.relational_return retval = new JavascriptParser.relational_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token set27=null;
+ JavascriptParser.shift_return shift26 =null;
+
+ JavascriptParser.shift_return shift28 =null;
+
+
+ CommonTree set27_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:283:5: ( shift ( ( AT_COMP_LT | AT_COMP_GT | AT_COMP_LTE | AT_COMP_GTE ) ^ shift )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:283:7: shift ( ( AT_COMP_LT | AT_COMP_GT | AT_COMP_LTE | AT_COMP_GTE ) ^ shift )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_shift_in_relational944);
+ shift26=shift();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, shift26.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:283:13: ( ( AT_COMP_LT | AT_COMP_GT | AT_COMP_LTE | AT_COMP_GTE ) ^ shift )*
+ loop8:
+ do {
+ int alt8=2;
+ int LA8_0 = input.LA(1);
+
+ if ( ((LA8_0 >= AT_COMP_GT && LA8_0 <= AT_COMP_LTE)) ) {
+ alt8=1;
+ }
+
+
+ switch (alt8) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:283:14: ( AT_COMP_LT | AT_COMP_GT | AT_COMP_LTE | AT_COMP_GTE ) ^ shift
+ {
+ set27=(Token)input.LT(1);
+
+ set27=(Token)input.LT(1);
+
+ if ( (input.LA(1) >= AT_COMP_GT && input.LA(1) <= AT_COMP_LTE) ) {
+ input.consume();
+ root_0 = (CommonTree)adaptor.becomeRoot(
+ (CommonTree)adaptor.create(set27)
+ , root_0);
+ state.errorRecovery=false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ throw mse;
+ }
+
+
+ pushFollow(FOLLOW_shift_in_relational964);
+ shift28=shift();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, shift28.getTree());
+
+ }
+ break;
+
+ default :
+ break loop8;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "relational"
+
+
+ public static class shift_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "shift"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:286:1: shift : additive ( ( AT_BIT_SHL | AT_BIT_SHR | AT_BIT_SHU ) ^ additive )* ;
+ public final JavascriptParser.shift_return shift() throws RecognitionException {
+ JavascriptParser.shift_return retval = new JavascriptParser.shift_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token set30=null;
+ JavascriptParser.additive_return additive29 =null;
+
+ JavascriptParser.additive_return additive31 =null;
+
+
+ CommonTree set30_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:287:5: ( additive ( ( AT_BIT_SHL | AT_BIT_SHR | AT_BIT_SHU ) ^ additive )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:287:7: additive ( ( AT_BIT_SHL | AT_BIT_SHR | AT_BIT_SHU ) ^ additive )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_additive_in_shift983);
+ additive29=additive();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, additive29.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:287:16: ( ( AT_BIT_SHL | AT_BIT_SHR | AT_BIT_SHU ) ^ additive )*
+ loop9:
+ do {
+ int alt9=2;
+ int LA9_0 = input.LA(1);
+
+ if ( ((LA9_0 >= AT_BIT_SHL && LA9_0 <= AT_BIT_SHU)) ) {
+ alt9=1;
+ }
+
+
+ switch (alt9) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:287:17: ( AT_BIT_SHL | AT_BIT_SHR | AT_BIT_SHU ) ^ additive
+ {
+ set30=(Token)input.LT(1);
+
+ set30=(Token)input.LT(1);
+
+ if ( (input.LA(1) >= AT_BIT_SHL && input.LA(1) <= AT_BIT_SHU) ) {
+ input.consume();
+ root_0 = (CommonTree)adaptor.becomeRoot(
+ (CommonTree)adaptor.create(set30)
+ , root_0);
+ state.errorRecovery=false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ throw mse;
+ }
+
+
+ pushFollow(FOLLOW_additive_in_shift999);
+ additive31=additive();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, additive31.getTree());
+
+ }
+ break;
+
+ default :
+ break loop9;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "shift"
+
+
+ public static class additive_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "additive"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:290:1: additive : multiplicative ( ( AT_ADD | AT_SUBTRACT ) ^ multiplicative )* ;
+ public final JavascriptParser.additive_return additive() throws RecognitionException {
+ JavascriptParser.additive_return retval = new JavascriptParser.additive_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token set33=null;
+ JavascriptParser.multiplicative_return multiplicative32 =null;
+
+ JavascriptParser.multiplicative_return multiplicative34 =null;
+
+
+ CommonTree set33_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:291:5: ( multiplicative ( ( AT_ADD | AT_SUBTRACT ) ^ multiplicative )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:291:7: multiplicative ( ( AT_ADD | AT_SUBTRACT ) ^ multiplicative )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_multiplicative_in_additive1018);
+ multiplicative32=multiplicative();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, multiplicative32.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:291:22: ( ( AT_ADD | AT_SUBTRACT ) ^ multiplicative )*
+ loop10:
+ do {
+ int alt10=2;
+ int LA10_0 = input.LA(1);
+
+ if ( (LA10_0==AT_ADD||LA10_0==AT_SUBTRACT) ) {
+ alt10=1;
+ }
+
+
+ switch (alt10) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:291:23: ( AT_ADD | AT_SUBTRACT ) ^ multiplicative
+ {
+ set33=(Token)input.LT(1);
+
+ set33=(Token)input.LT(1);
+
+ if ( input.LA(1)==AT_ADD||input.LA(1)==AT_SUBTRACT ) {
+ input.consume();
+ root_0 = (CommonTree)adaptor.becomeRoot(
+ (CommonTree)adaptor.create(set33)
+ , root_0);
+ state.errorRecovery=false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ throw mse;
+ }
+
+
+ pushFollow(FOLLOW_multiplicative_in_additive1030);
+ multiplicative34=multiplicative();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, multiplicative34.getTree());
+
+ }
+ break;
+
+ default :
+ break loop10;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "additive"
+
+
+ public static class multiplicative_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "multiplicative"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:294:1: multiplicative : unary ( ( AT_MULTIPLY | AT_DIVIDE | AT_MODULO ) ^ unary )* ;
+ public final JavascriptParser.multiplicative_return multiplicative() throws RecognitionException {
+ JavascriptParser.multiplicative_return retval = new JavascriptParser.multiplicative_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token set36=null;
+ JavascriptParser.unary_return unary35 =null;
+
+ JavascriptParser.unary_return unary37 =null;
+
+
+ CommonTree set36_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:295:5: ( unary ( ( AT_MULTIPLY | AT_DIVIDE | AT_MODULO ) ^ unary )* )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:295:7: unary ( ( AT_MULTIPLY | AT_DIVIDE | AT_MODULO ) ^ unary )*
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_unary_in_multiplicative1049);
+ unary35=unary();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, unary35.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:295:13: ( ( AT_MULTIPLY | AT_DIVIDE | AT_MODULO ) ^ unary )*
+ loop11:
+ do {
+ int alt11=2;
+ int LA11_0 = input.LA(1);
+
+ if ( (LA11_0==AT_DIVIDE||(LA11_0 >= AT_MODULO && LA11_0 <= AT_MULTIPLY)) ) {
+ alt11=1;
+ }
+
+
+ switch (alt11) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:295:14: ( AT_MULTIPLY | AT_DIVIDE | AT_MODULO ) ^ unary
+ {
+ set36=(Token)input.LT(1);
+
+ set36=(Token)input.LT(1);
+
+ if ( input.LA(1)==AT_DIVIDE||(input.LA(1) >= AT_MODULO && input.LA(1) <= AT_MULTIPLY) ) {
+ input.consume();
+ root_0 = (CommonTree)adaptor.becomeRoot(
+ (CommonTree)adaptor.create(set36)
+ , root_0);
+ state.errorRecovery=false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ throw mse;
+ }
+
+
+ pushFollow(FOLLOW_unary_in_multiplicative1065);
+ unary37=unary();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, unary37.getTree());
+
+ }
+ break;
+
+ default :
+ break loop11;
+ }
+ } while (true);
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "multiplicative"
+
+
+ public static class unary_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "unary"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:298:1: unary : ( postfix | AT_ADD ! unary | unary_operator ^ unary );
+ public final JavascriptParser.unary_return unary() throws RecognitionException {
+ JavascriptParser.unary_return retval = new JavascriptParser.unary_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_ADD39=null;
+ JavascriptParser.postfix_return postfix38 =null;
+
+ JavascriptParser.unary_return unary40 =null;
+
+ JavascriptParser.unary_operator_return unary_operator41 =null;
+
+ JavascriptParser.unary_return unary42 =null;
+
+
+ CommonTree AT_ADD39_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:299:5: ( postfix | AT_ADD ! unary | unary_operator ^ unary )
+ int alt12=3;
+ switch ( input.LA(1) ) {
+ case AT_LPAREN:
+ case DECIMAL:
+ case HEX:
+ case ID:
+ case OCTAL:
+ {
+ alt12=1;
+ }
+ break;
+ case AT_ADD:
+ {
+ alt12=2;
+ }
+ break;
+ case AT_BIT_NOT:
+ case AT_BOOL_NOT:
+ case AT_SUBTRACT:
+ {
+ alt12=3;
+ }
+ break;
+ default:
+ NoViableAltException nvae =
+ new NoViableAltException("", 12, 0, input);
+
+ throw nvae;
+
+ }
+
+ switch (alt12) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:299:7: postfix
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_postfix_in_unary1084);
+ postfix38=postfix();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, postfix38.getTree());
+
+ }
+ break;
+ case 2 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:300:7: AT_ADD ! unary
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ AT_ADD39=(Token)match(input,AT_ADD,FOLLOW_AT_ADD_in_unary1092);
+
+ pushFollow(FOLLOW_unary_in_unary1095);
+ unary40=unary();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, unary40.getTree());
+
+ }
+ break;
+ case 3 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:301:7: unary_operator ^ unary
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_unary_operator_in_unary1103);
+ unary_operator41=unary_operator();
+
+ state._fsp--;
+
+ root_0 = (CommonTree)adaptor.becomeRoot(unary_operator41.getTree(), root_0);
+
+ pushFollow(FOLLOW_unary_in_unary1106);
+ unary42=unary();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, unary42.getTree());
+
+ }
+ break;
+
+ }
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "unary"
+
+
+ public static class unary_operator_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "unary_operator"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:304:1: unary_operator : ( AT_SUBTRACT -> AT_NEGATE | AT_BIT_NOT | AT_BOOL_NOT );
+ public final JavascriptParser.unary_operator_return unary_operator() throws RecognitionException {
+ JavascriptParser.unary_operator_return retval = new JavascriptParser.unary_operator_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_SUBTRACT43=null;
+ Token AT_BIT_NOT44=null;
+ Token AT_BOOL_NOT45=null;
+
+ CommonTree AT_SUBTRACT43_tree=null;
+ CommonTree AT_BIT_NOT44_tree=null;
+ CommonTree AT_BOOL_NOT45_tree=null;
+ RewriteRuleTokenStream stream_AT_SUBTRACT=new RewriteRuleTokenStream(adaptor,"token AT_SUBTRACT");
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:305:5: ( AT_SUBTRACT -> AT_NEGATE | AT_BIT_NOT | AT_BOOL_NOT )
+ int alt13=3;
+ switch ( input.LA(1) ) {
+ case AT_SUBTRACT:
+ {
+ alt13=1;
+ }
+ break;
+ case AT_BIT_NOT:
+ {
+ alt13=2;
+ }
+ break;
+ case AT_BOOL_NOT:
+ {
+ alt13=3;
+ }
+ break;
+ default:
+ NoViableAltException nvae =
+ new NoViableAltException("", 13, 0, input);
+
+ throw nvae;
+
+ }
+
+ switch (alt13) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:305:7: AT_SUBTRACT
+ {
+ AT_SUBTRACT43=(Token)match(input,AT_SUBTRACT,FOLLOW_AT_SUBTRACT_in_unary_operator1123);
+ stream_AT_SUBTRACT.add(AT_SUBTRACT43);
+
+
+ // AST REWRITE
+ // elements:
+ // token labels:
+ // rule labels: retval
+ // token list labels:
+ // rule list labels:
+ // wildcard labels:
+ retval.tree = root_0;
+ RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);
+
+ root_0 = (CommonTree)adaptor.nil();
+ // 305:19: -> AT_NEGATE
+ {
+ adaptor.addChild(root_0,
+ (CommonTree)adaptor.create(AT_NEGATE, "AT_NEGATE")
+ );
+
+ }
+
+
+ retval.tree = root_0;
+
+ }
+ break;
+ case 2 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:306:7: AT_BIT_NOT
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ AT_BIT_NOT44=(Token)match(input,AT_BIT_NOT,FOLLOW_AT_BIT_NOT_in_unary_operator1135);
+ AT_BIT_NOT44_tree =
+ (CommonTree)adaptor.create(AT_BIT_NOT44)
+ ;
+ adaptor.addChild(root_0, AT_BIT_NOT44_tree);
+
+
+ }
+ break;
+ case 3 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:307:7: AT_BOOL_NOT
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ AT_BOOL_NOT45=(Token)match(input,AT_BOOL_NOT,FOLLOW_AT_BOOL_NOT_in_unary_operator1143);
+ AT_BOOL_NOT45_tree =
+ (CommonTree)adaptor.create(AT_BOOL_NOT45)
+ ;
+ adaptor.addChild(root_0, AT_BOOL_NOT45_tree);
+
+
+ }
+ break;
+
+ }
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "unary_operator"
+
+
+ public static class postfix_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "postfix"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:310:1: postfix : ( primary | ID arguments -> ^( AT_CALL ID ( arguments )? ) );
+ public final JavascriptParser.postfix_return postfix() throws RecognitionException {
+ JavascriptParser.postfix_return retval = new JavascriptParser.postfix_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token ID47=null;
+ JavascriptParser.primary_return primary46 =null;
+
+ JavascriptParser.arguments_return arguments48 =null;
+
+
+ CommonTree ID47_tree=null;
+ RewriteRuleTokenStream stream_ID=new RewriteRuleTokenStream(adaptor,"token ID");
+ RewriteRuleSubtreeStream stream_arguments=new RewriteRuleSubtreeStream(adaptor,"rule arguments");
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:311:5: ( primary | ID arguments -> ^( AT_CALL ID ( arguments )? ) )
+ int alt14=2;
+ int LA14_0 = input.LA(1);
+
+ if ( (LA14_0==ID) ) {
+ int LA14_1 = input.LA(2);
+
+ if ( (LA14_1==EOF||(LA14_1 >= AT_ADD && LA14_1 <= AT_BIT_AND)||(LA14_1 >= AT_BIT_OR && LA14_1 <= AT_BOOL_AND)||LA14_1==AT_BOOL_OR||(LA14_1 >= AT_COLON && LA14_1 <= AT_DIVIDE)||(LA14_1 >= AT_MODULO && LA14_1 <= AT_MULTIPLY)||(LA14_1 >= AT_RPAREN && LA14_1 <= AT_SUBTRACT)) ) {
+ alt14=1;
+ }
+ else if ( (LA14_1==AT_LPAREN) ) {
+ alt14=2;
+ }
+ else {
+ NoViableAltException nvae =
+ new NoViableAltException("", 14, 1, input);
+
+ throw nvae;
+
+ }
+ }
+ else if ( (LA14_0==AT_LPAREN||LA14_0==DECIMAL||LA14_0==HEX||LA14_0==OCTAL) ) {
+ alt14=1;
+ }
+ else {
+ NoViableAltException nvae =
+ new NoViableAltException("", 14, 0, input);
+
+ throw nvae;
+
+ }
+ switch (alt14) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:311:7: primary
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_primary_in_postfix1160);
+ primary46=primary();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, primary46.getTree());
+
+ }
+ break;
+ case 2 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:312:7: ID arguments
+ {
+ ID47=(Token)match(input,ID,FOLLOW_ID_in_postfix1168);
+ stream_ID.add(ID47);
+
+
+ pushFollow(FOLLOW_arguments_in_postfix1170);
+ arguments48=arguments();
+
+ state._fsp--;
+
+ stream_arguments.add(arguments48.getTree());
+
+ // AST REWRITE
+ // elements: arguments, ID
+ // token labels:
+ // rule labels: retval
+ // token list labels:
+ // rule list labels:
+ // wildcard labels:
+ retval.tree = root_0;
+ RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);
+
+ root_0 = (CommonTree)adaptor.nil();
+ // 312:20: -> ^( AT_CALL ID ( arguments )? )
+ {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:312:23: ^( AT_CALL ID ( arguments )? )
+ {
+ CommonTree root_1 = (CommonTree)adaptor.nil();
+ root_1 = (CommonTree)adaptor.becomeRoot(
+ (CommonTree)adaptor.create(AT_CALL, "AT_CALL")
+ , root_1);
+
+ adaptor.addChild(root_1,
+ stream_ID.nextNode()
+ );
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:312:36: ( arguments )?
+ if ( stream_arguments.hasNext() ) {
+ adaptor.addChild(root_1, stream_arguments.nextTree());
+
+ }
+ stream_arguments.reset();
+
+ adaptor.addChild(root_0, root_1);
+ }
+
+ }
+
+
+ retval.tree = root_0;
+
+ }
+ break;
+
+ }
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "postfix"
+
+
+ public static class primary_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "primary"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:315:1: primary : ( ID | numeric | AT_LPAREN ! conditional AT_RPAREN !);
+ public final JavascriptParser.primary_return primary() throws RecognitionException {
+ JavascriptParser.primary_return retval = new JavascriptParser.primary_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token ID49=null;
+ Token AT_LPAREN51=null;
+ Token AT_RPAREN53=null;
+ JavascriptParser.numeric_return numeric50 =null;
+
+ JavascriptParser.conditional_return conditional52 =null;
+
+
+ CommonTree ID49_tree=null;
+ CommonTree AT_LPAREN51_tree=null;
+ CommonTree AT_RPAREN53_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:316:5: ( ID | numeric | AT_LPAREN ! conditional AT_RPAREN !)
+ int alt15=3;
+ switch ( input.LA(1) ) {
+ case ID:
+ {
+ alt15=1;
+ }
+ break;
+ case DECIMAL:
+ case HEX:
+ case OCTAL:
+ {
+ alt15=2;
+ }
+ break;
+ case AT_LPAREN:
+ {
+ alt15=3;
+ }
+ break;
+ default:
+ NoViableAltException nvae =
+ new NoViableAltException("", 15, 0, input);
+
+ throw nvae;
+
+ }
+
+ switch (alt15) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:316:7: ID
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ ID49=(Token)match(input,ID,FOLLOW_ID_in_primary1198);
+ ID49_tree =
+ (CommonTree)adaptor.create(ID49)
+ ;
+ adaptor.addChild(root_0, ID49_tree);
+
+
+ }
+ break;
+ case 2 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:317:7: numeric
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ pushFollow(FOLLOW_numeric_in_primary1206);
+ numeric50=numeric();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, numeric50.getTree());
+
+ }
+ break;
+ case 3 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:318:7: AT_LPAREN ! conditional AT_RPAREN !
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ AT_LPAREN51=(Token)match(input,AT_LPAREN,FOLLOW_AT_LPAREN_in_primary1214);
+
+ pushFollow(FOLLOW_conditional_in_primary1217);
+ conditional52=conditional();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, conditional52.getTree());
+
+ AT_RPAREN53=(Token)match(input,AT_RPAREN,FOLLOW_AT_RPAREN_in_primary1219);
+
+ }
+ break;
+
+ }
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "primary"
+
+
+ public static class arguments_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "arguments"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:321:1: arguments : AT_LPAREN ! ( conditional ( AT_COMMA ! conditional )* )? AT_RPAREN !;
+ public final JavascriptParser.arguments_return arguments() throws RecognitionException {
+ JavascriptParser.arguments_return retval = new JavascriptParser.arguments_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token AT_LPAREN54=null;
+ Token AT_COMMA56=null;
+ Token AT_RPAREN58=null;
+ JavascriptParser.conditional_return conditional55 =null;
+
+ JavascriptParser.conditional_return conditional57 =null;
+
+
+ CommonTree AT_LPAREN54_tree=null;
+ CommonTree AT_COMMA56_tree=null;
+ CommonTree AT_RPAREN58_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:322:5: ( AT_LPAREN ! ( conditional ( AT_COMMA ! conditional )* )? AT_RPAREN !)
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:322:7: AT_LPAREN ! ( conditional ( AT_COMMA ! conditional )* )? AT_RPAREN !
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ AT_LPAREN54=(Token)match(input,AT_LPAREN,FOLLOW_AT_LPAREN_in_arguments1237);
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:322:18: ( conditional ( AT_COMMA ! conditional )* )?
+ int alt17=2;
+ int LA17_0 = input.LA(1);
+
+ if ( (LA17_0==AT_ADD||LA17_0==AT_BIT_NOT||LA17_0==AT_BOOL_NOT||LA17_0==AT_LPAREN||(LA17_0 >= AT_SUBTRACT && LA17_0 <= DECIMAL)||LA17_0==HEX||(LA17_0 >= ID && LA17_0 <= OCTAL)) ) {
+ alt17=1;
+ }
+ switch (alt17) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:322:19: conditional ( AT_COMMA ! conditional )*
+ {
+ pushFollow(FOLLOW_conditional_in_arguments1241);
+ conditional55=conditional();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, conditional55.getTree());
+
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:322:31: ( AT_COMMA ! conditional )*
+ loop16:
+ do {
+ int alt16=2;
+ int LA16_0 = input.LA(1);
+
+ if ( (LA16_0==AT_COMMA) ) {
+ alt16=1;
+ }
+
+
+ switch (alt16) {
+ case 1 :
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:322:32: AT_COMMA ! conditional
+ {
+ AT_COMMA56=(Token)match(input,AT_COMMA,FOLLOW_AT_COMMA_in_arguments1244);
+
+ pushFollow(FOLLOW_conditional_in_arguments1247);
+ conditional57=conditional();
+
+ state._fsp--;
+
+ adaptor.addChild(root_0, conditional57.getTree());
+
+ }
+ break;
+
+ default :
+ break loop16;
+ }
+ } while (true);
+
+
+ }
+ break;
+
+ }
+
+
+ AT_RPAREN58=(Token)match(input,AT_RPAREN,FOLLOW_AT_RPAREN_in_arguments1253);
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "arguments"
+
+
+ public static class numeric_return extends ParserRuleReturnScope {
+ CommonTree tree;
+ public Object getTree() { return tree; }
+ };
+
+
+ // $ANTLR start "numeric"
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:325:1: numeric : ( HEX | OCTAL | DECIMAL );
+ public final JavascriptParser.numeric_return numeric() throws RecognitionException {
+ JavascriptParser.numeric_return retval = new JavascriptParser.numeric_return();
+ retval.start = input.LT(1);
+
+
+ CommonTree root_0 = null;
+
+ Token set59=null;
+
+ CommonTree set59_tree=null;
+
+ try {
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:326:5: ( HEX | OCTAL | DECIMAL )
+ // src/java/org/apache/lucene/expressions/js/Javascript.g:
+ {
+ root_0 = (CommonTree)adaptor.nil();
+
+
+ set59=(Token)input.LT(1);
+
+ if ( input.LA(1)==DECIMAL||input.LA(1)==HEX||input.LA(1)==OCTAL ) {
+ input.consume();
+ adaptor.addChild(root_0,
+ (CommonTree)adaptor.create(set59)
+ );
+ state.errorRecovery=false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ throw mse;
+ }
+
+
+ }
+
+ retval.stop = input.LT(-1);
+
+
+ retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
+ adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
+
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return retval;
+ }
+ // $ANTLR end "numeric"
+
+ // Delegated rules
+
+
+
+
+ public static final BitSet FOLLOW_conditional_in_expression737 = new BitSet(new long[]{0x0000000000000000L});
+ public static final BitSet FOLLOW_EOF_in_expression739 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_logical_or_in_conditional757 = new BitSet(new long[]{0x0000000001000002L});
+ public static final BitSet FOLLOW_AT_COND_QUE_in_conditional760 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_conditional_in_conditional763 = new BitSet(new long[]{0x0000000000010000L});
+ public static final BitSet FOLLOW_AT_COLON_in_conditional765 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_conditional_in_conditional768 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_logical_and_in_logical_or787 = new BitSet(new long[]{0x0000000000004002L});
+ public static final BitSet FOLLOW_AT_BOOL_OR_in_logical_or790 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_logical_and_in_logical_or793 = new BitSet(new long[]{0x0000000000004002L});
+ public static final BitSet FOLLOW_bitwise_or_in_logical_and812 = new BitSet(new long[]{0x0000000000001002L});
+ public static final BitSet FOLLOW_AT_BOOL_AND_in_logical_and815 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_bitwise_or_in_logical_and818 = new BitSet(new long[]{0x0000000000001002L});
+ public static final BitSet FOLLOW_bitwise_xor_in_bitwise_or837 = new BitSet(new long[]{0x0000000000000082L});
+ public static final BitSet FOLLOW_AT_BIT_OR_in_bitwise_or840 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_bitwise_xor_in_bitwise_or843 = new BitSet(new long[]{0x0000000000000082L});
+ public static final BitSet FOLLOW_bitwise_and_in_bitwise_xor862 = new BitSet(new long[]{0x0000000000000802L});
+ public static final BitSet FOLLOW_AT_BIT_XOR_in_bitwise_xor865 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_bitwise_and_in_bitwise_xor868 = new BitSet(new long[]{0x0000000000000802L});
+ public static final BitSet FOLLOW_equality_in_bitwise_and888 = new BitSet(new long[]{0x0000000000000022L});
+ public static final BitSet FOLLOW_AT_BIT_AND_in_bitwise_and891 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_equality_in_bitwise_and894 = new BitSet(new long[]{0x0000000000000022L});
+ public static final BitSet FOLLOW_relational_in_equality913 = new BitSet(new long[]{0x0000000000840002L});
+ public static final BitSet FOLLOW_set_in_equality916 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_relational_in_equality925 = new BitSet(new long[]{0x0000000000840002L});
+ public static final BitSet FOLLOW_shift_in_relational944 = new BitSet(new long[]{0x0000000000780002L});
+ public static final BitSet FOLLOW_set_in_relational947 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_shift_in_relational964 = new BitSet(new long[]{0x0000000000780002L});
+ public static final BitSet FOLLOW_additive_in_shift983 = new BitSet(new long[]{0x0000000000000702L});
+ public static final BitSet FOLLOW_set_in_shift986 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_additive_in_shift999 = new BitSet(new long[]{0x0000000000000702L});
+ public static final BitSet FOLLOW_multiplicative_in_additive1018 = new BitSet(new long[]{0x0000000100000012L});
+ public static final BitSet FOLLOW_set_in_additive1021 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_multiplicative_in_additive1030 = new BitSet(new long[]{0x0000000100000012L});
+ public static final BitSet FOLLOW_unary_in_multiplicative1049 = new BitSet(new long[]{0x0000000032000002L});
+ public static final BitSet FOLLOW_set_in_multiplicative1052 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_unary_in_multiplicative1065 = new BitSet(new long[]{0x0000000032000002L});
+ public static final BitSet FOLLOW_postfix_in_unary1084 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_AT_ADD_in_unary1092 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_unary_in_unary1095 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_unary_operator_in_unary1103 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_unary_in_unary1106 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_AT_SUBTRACT_in_unary_operator1123 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_AT_BIT_NOT_in_unary_operator1135 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_AT_BOOL_NOT_in_unary_operator1143 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_primary_in_postfix1160 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_ID_in_postfix1168 = new BitSet(new long[]{0x0000000008000000L});
+ public static final BitSet FOLLOW_arguments_in_postfix1170 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_ID_in_primary1198 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_numeric_in_primary1206 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_AT_LPAREN_in_primary1214 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_conditional_in_primary1217 = new BitSet(new long[]{0x0000000080000000L});
+ public static final BitSet FOLLOW_AT_RPAREN_in_primary1219 = new BitSet(new long[]{0x0000000000000002L});
+ public static final BitSet FOLLOW_AT_LPAREN_in_arguments1237 = new BitSet(new long[]{0x000001A388002050L});
+ public static final BitSet FOLLOW_conditional_in_arguments1241 = new BitSet(new long[]{0x0000000080020000L});
+ public static final BitSet FOLLOW_AT_COMMA_in_arguments1244 = new BitSet(new long[]{0x000001A308002050L});
+ public static final BitSet FOLLOW_conditional_in_arguments1247 = new BitSet(new long[]{0x0000000080020000L});
+ public static final BitSet FOLLOW_AT_RPAREN_in_arguments1253 = new BitSet(new long[]{0x0000000000000002L});
+
+}
\ No newline at end of file
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/js/package.html lucene/expressions/src/java/org/apache/lucene/expressions/js/package.html
new file mode 100644
index 0000000..4bbd109
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/js/package.html
@@ -0,0 +1,44 @@
+
+
+
+ Javascript expressions
+
+
+
Javascript expressions
+
A Javascript expression is a numeric expression specified using an expression syntax that's based on JavaScript expressions. You can construct expressions using:
+
+
Integer, floating point, hex and octal literals
+
Arithmetic operators: + - * / %
+
Bitwise operators: | & ^ ~ << >> >>>
+
Boolean operators (including the ternary operator): && || ! ?:
+
Comparison operators: < <= == >= >
+
Common mathematic functions: abs ceil erf exp floor ln log2 log10 max min sqrt pow
+
Trigonometric library functions: acosh acos asinh asin atanh atan cosh cos sinh sin tanh tan
+
Miscellaneous functions: min, max
+
Arbitrary external variables - see {@link org.apache.lucene.expressions.Bindings}
+
+
+
+JavaScript order of precedence rules apply for operators. Shortcut evaluation is used for logical operators—the second argument is only evaluated if the value of the expression cannot be determined after evaluating the first argument. For example, in the expression a || b, b is only evaluated if a is not true.
+
+
+
+ To compile an expression, use {@link org.apache.lucene.expressions.js.JavascriptCompiler}.
+
+
+
\ No newline at end of file
diff --git lucene/expressions/src/java/org/apache/lucene/expressions/package.html lucene/expressions/src/java/org/apache/lucene/expressions/package.html
new file mode 100644
index 0000000..8c895a0
--- /dev/null
+++ lucene/expressions/src/java/org/apache/lucene/expressions/package.html
@@ -0,0 +1,39 @@
+
+
+
+ expressions
+
+
+
expressions
+
+{@link org.apache.lucene.expressions.Expression} - result of compiling an expression, which can
+evaluate it for a given document. Each expression can have external variables which evaluate
+will retrieve from passed FunctionValues.
+
+
+
+{@link org.apache.lucene.expressions.Bindings} - abstraction for binding external variables
+to a way to get a value for those variables for a particular document (ValueSource)
+
+
+
+{@link org.apache.lucene.expressions.SimpleBindings} - default implementation of bindings which provide easy ways to bind sort fields and other expressions to external variables
+
+
+
+
\ No newline at end of file
diff --git lucene/expressions/src/java/overview.html lucene/expressions/src/java/overview.html
new file mode 100644
index 0000000..ee21b88
--- /dev/null
+++ lucene/expressions/src/java/overview.html
@@ -0,0 +1,41 @@
+
+
+
+ Apache Lucene Expressions Module
+
+
+
+
The Expressions Module for Apache Lucene
+
+
+ The expressions module is new to Lucene 4.6. It provides an API for dynamically computing per-document values based on string expressions.
+
+
+ The module is organized in two sections:
+
+
{@link org.apache.lucene.expressions} - The abstractions and simple utilities for common operations like sorting on an expression
+
{@link org.apache.lucene.expressions.js} - A compiler for a subset of JavaScript expressions
+
+
+
+ For sample code showing how to use the API, see {@link org.apache.lucene.expressions.TestDemoExpressions}.
+
+
+
+
+
\ No newline at end of file
diff --git lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java
new file mode 100644
index 0000000..96535ec
--- /dev/null
+++ lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java
@@ -0,0 +1,113 @@
+package org.apache.lucene.expressions;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.expressions.js.JavascriptCompiler;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.CheckHits;
+import org.apache.lucene.search.FieldDoc;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopFieldDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.LuceneTestCase;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** simple demo of using expressions */
+public class TestDemoExpressions extends LuceneTestCase {
+ IndexSearcher searcher;
+ DirectoryReader reader;
+ Directory dir;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ dir = newDirectory();
+ RandomIndexWriter iw = new RandomIndexWriter(random(), dir);
+
+ Document doc = new Document();
+ doc.add(newStringField("id", "1", Field.Store.YES));
+ doc.add(newTextField("body", "some contents and more contents", Field.Store.NO));
+ doc.add(new NumericDocValuesField("popularity", 5));
+ iw.addDocument(doc);
+
+ doc = new Document();
+ doc.add(newStringField("id", "2", Field.Store.YES));
+ doc.add(newTextField("body", "another document with different contents", Field.Store.NO));
+ doc.add(new NumericDocValuesField("popularity", 20));
+ iw.addDocument(doc);
+
+ doc = new Document();
+ doc.add(newStringField("id", "3", Field.Store.YES));
+ doc.add(newTextField("body", "crappy contents", Field.Store.NO));
+ doc.add(new NumericDocValuesField("popularity", 2));
+ iw.addDocument(doc);
+
+ reader = iw.getReader();
+ searcher = new IndexSearcher(reader);
+ iw.close();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ reader.close();
+ dir.close();
+ super.tearDown();
+ }
+
+ /** an example of how to rank by an expression */
+ public void test() throws Exception {
+ // compile an expression:
+ Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
+
+ // we use SimpleBindings: which just maps variables to SortField instances
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add(new SortField("_score", SortField.Type.SCORE));
+ bindings.add(new SortField("popularity", SortField.Type.INT));
+
+ // create a sort field and sort by it (reverse order)
+ Sort sort = new Sort(expr.getSortField(bindings, true));
+ Query query = new TermQuery(new Term("body", "contents"));
+ searcher.search(query, null, 3, sort);
+ }
+
+ /** tests the returned sort values are correct */
+ public void testSortValues() throws Exception {
+ Expression expr = JavascriptCompiler.compile("sqrt(_score)");
+
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add(new SortField("_score", SortField.Type.SCORE));
+
+ Sort sort = new Sort(expr.getSortField(bindings, true));
+ Query query = new TermQuery(new Term("body", "contents"));
+ TopFieldDocs td = searcher.search(query, null, 3, sort, true, true);
+ for (int i = 0; i < 3; i++) {
+ FieldDoc d = (FieldDoc) td.scoreDocs[i];
+ float expected = (float) Math.sqrt(d.score);
+ float actual = ((Double)d.fields[0]).floatValue();
+ assertEquals(expected, actual, CheckHits.explainToleranceDelta(expected, actual));
+ }
+ }
+}
diff --git lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java
new file mode 100644
index 0000000..be2a9cb
--- /dev/null
+++ lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java
@@ -0,0 +1,127 @@
+package org.apache.lucene.expressions;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.expressions.js.JavascriptCompiler;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.util.LuceneTestCase;
+
+/** Tests validation of bindings */
+public class TestExpressionValidation extends LuceneTestCase {
+
+ public void testValidExternals() throws Exception {
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add(new SortField("valid0", SortField.Type.INT));
+ bindings.add(new SortField("valid1", SortField.Type.INT));
+ bindings.add(new SortField("valid2", SortField.Type.INT));
+ bindings.add(new SortField("_score", SortField.Type.SCORE));
+ bindings.add("valide0", JavascriptCompiler.compile("valid0 - valid1 + valid2 + _score"));
+ bindings.validate();
+ bindings.add("valide1", JavascriptCompiler.compile("valide0 + valid0"));
+ bindings.validate();
+ bindings.add("valide2", JavascriptCompiler.compile("valide0 * valide1"));
+ bindings.validate();
+ }
+
+ public void testInvalidExternal() throws Exception {
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add(new SortField("valid", SortField.Type.INT));
+ bindings.add("invalid", JavascriptCompiler.compile("badreference"));
+ try {
+ bindings.validate();
+ fail("didn't get expected exception");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(expected.getMessage().contains("Invalid reference"));
+ }
+ }
+
+ public void testInvalidExternal2() throws Exception {
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add(new SortField("valid", SortField.Type.INT));
+ bindings.add("invalid", JavascriptCompiler.compile("valid + badreference"));
+ try {
+ bindings.validate();
+ fail("didn't get expected exception");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(expected.getMessage().contains("Invalid reference"));
+ }
+ }
+
+ public void testSelfRecursion() throws Exception {
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add("cycle0", JavascriptCompiler.compile("cycle0"));
+ try {
+ bindings.validate();
+ fail("didn't get expected exception");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(expected.getMessage().contains("Cycle detected"));
+ }
+ }
+
+ public void testCoRecursion() throws Exception {
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add("cycle0", JavascriptCompiler.compile("cycle1"));
+ bindings.add("cycle1", JavascriptCompiler.compile("cycle0"));
+ try {
+ bindings.validate();
+ fail("didn't get expected exception");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(expected.getMessage().contains("Cycle detected"));
+ }
+ }
+
+ public void testCoRecursion2() throws Exception {
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add("cycle0", JavascriptCompiler.compile("cycle1"));
+ bindings.add("cycle1", JavascriptCompiler.compile("cycle2"));
+ bindings.add("cycle2", JavascriptCompiler.compile("cycle0"));
+ try {
+ bindings.validate();
+ fail("didn't get expected exception");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(expected.getMessage().contains("Cycle detected"));
+ }
+ }
+
+ public void testCoRecursion3() throws Exception {
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add("cycle0", JavascriptCompiler.compile("100"));
+ bindings.add("cycle1", JavascriptCompiler.compile("cycle0 + cycle2"));
+ bindings.add("cycle2", JavascriptCompiler.compile("cycle0 + cycle1"));
+ try {
+ bindings.validate();
+ fail("didn't get expected exception");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(expected.getMessage().contains("Cycle detected"));
+ }
+ }
+
+ public void testCoRecursion4() throws Exception {
+ SimpleBindings bindings = new SimpleBindings();
+ bindings.add("cycle0", JavascriptCompiler.compile("100"));
+ bindings.add("cycle1", JavascriptCompiler.compile("100"));
+ bindings.add("cycle2", JavascriptCompiler.compile("cycle1 + cycle0 + cycle3"));
+ bindings.add("cycle3", JavascriptCompiler.compile("cycle0 + cycle1 + cycle2"));
+ try {
+ bindings.validate();
+ fail("didn't get expected exception");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(expected.getMessage().contains("Cycle detected"));
+ }
+ }
+}
diff --git lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptCompiler.java lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptCompiler.java
new file mode 100644
index 0000000..aea054c
--- /dev/null
+++ lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptCompiler.java
@@ -0,0 +1,46 @@
+package org.apache.lucene.expressions.js;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.text.ParseException;
+
+import org.apache.lucene.util.LuceneTestCase;
+
+public class TestJavascriptCompiler extends LuceneTestCase {
+
+ public void testValidCompiles() throws Exception {
+ assertNotNull(JavascriptCompiler.compile("100"));
+ assertNotNull(JavascriptCompiler.compile("valid0+100"));
+ assertNotNull(JavascriptCompiler.compile("logn(2, 20+10-5.0)"));
+ }
+
+ public void testInvalidCompiles() throws Exception {
+ try {
+ JavascriptCompiler.compile("100 100");
+ fail();
+ } catch (ParseException expected) {
+ // expected exception
+ }
+
+ try {
+ JavascriptCompiler.compile("7*/-8");
+ fail();
+ } catch (ParseException expected) {
+ // expected exception
+ }
+ }
+}
diff --git lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptFunction.java lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptFunction.java
new file mode 100644
index 0000000..a7317ae
--- /dev/null
+++ lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptFunction.java
@@ -0,0 +1,255 @@
+package org.apache.lucene.expressions.js;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.expressions.Expression;
+import org.apache.lucene.util.LuceneTestCase;
+
+public class TestJavascriptFunction extends LuceneTestCase {
+ private static double DELTA = 0.0000001;
+
+ private void testComputedExpressionEvaluation(String name, String expression, double expected) throws Exception {
+ Expression evaluator = JavascriptCompiler.compile(expression);
+ double actual = evaluator.evaluate(0, null);
+ assertEquals(name, expected, actual, DELTA);
+ }
+
+ public void testAbsMethod() throws Exception {
+ testComputedExpressionEvaluation("abs0", "abs(0)", 0);
+ testComputedExpressionEvaluation("abs1", "abs(119)", 119);
+ testComputedExpressionEvaluation("abs2", "abs(119)", 119);
+ testComputedExpressionEvaluation("abs3", "abs(1)", 1);
+ testComputedExpressionEvaluation("abs4", "abs(-1)", 1);
+ }
+
+ public void testAcosMethod() throws Exception {
+ testComputedExpressionEvaluation("acos0", "acos(-1)", Math.PI);
+ testComputedExpressionEvaluation("acos1", "acos(-0.8660254)", Math.PI*5/6);
+ testComputedExpressionEvaluation("acos3", "acos(-0.7071068)", Math.PI*3/4);
+ testComputedExpressionEvaluation("acos4", "acos(-0.5)", Math.PI*2/3);
+ testComputedExpressionEvaluation("acos5", "acos(0)", Math.PI/2);
+ testComputedExpressionEvaluation("acos6", "acos(0.5)", Math.PI/3);
+ testComputedExpressionEvaluation("acos7", "acos(0.7071068)", Math.PI/4);
+ testComputedExpressionEvaluation("acos8", "acos(0.8660254)", Math.PI/6);
+ testComputedExpressionEvaluation("acos9", "acos(1)", 0);
+ }
+
+ public void testAcoshMethod() throws Exception {
+ testComputedExpressionEvaluation("acosh0", "acosh(1)", 0);
+ testComputedExpressionEvaluation("acosh1", "acosh(2.5)", 1.5667992369724109);
+ testComputedExpressionEvaluation("acosh2", "acosh(1234567.89)", 14.719378760739708);
+ }
+
+ public void testAsinMethod() throws Exception {
+ testComputedExpressionEvaluation("asin0", "asin(-1)", -Math.PI/2);
+ testComputedExpressionEvaluation("asin1", "asin(-0.8660254)", -Math.PI/3);
+ testComputedExpressionEvaluation("asin3", "asin(-0.7071068)", -Math.PI/4);
+ testComputedExpressionEvaluation("asin4", "asin(-0.5)", -Math.PI/6);
+ testComputedExpressionEvaluation("asin5", "asin(0)", 0);
+ testComputedExpressionEvaluation("asin6", "asin(0.5)", Math.PI/6);
+ testComputedExpressionEvaluation("asin7", "asin(0.7071068)", Math.PI/4);
+ testComputedExpressionEvaluation("asin8", "asin(0.8660254)", Math.PI/3);
+ testComputedExpressionEvaluation("asin9", "asin(1)", Math.PI/2);
+ }
+
+ public void testAsinhMethod() throws Exception {
+ testComputedExpressionEvaluation("asinh0", "asinh(-1234567.89)", -14.719378760740035);
+ testComputedExpressionEvaluation("asinh1", "asinh(-2.5)", -1.6472311463710958);
+ testComputedExpressionEvaluation("asinh2", "asinh(-1)", -0.8813735870195429);
+ testComputedExpressionEvaluation("asinh3", "asinh(0)", 0);
+ testComputedExpressionEvaluation("asinh4", "asinh(1)", 0.8813735870195429);
+ testComputedExpressionEvaluation("asinh5", "asinh(2.5)", 1.6472311463710958);
+ testComputedExpressionEvaluation("asinh6", "asinh(1234567.89)", 14.719378760740035);
+ }
+
+ public void testAtanMethod() throws Exception {
+ testComputedExpressionEvaluation("atan0", "atan(-1.732050808)", -Math.PI/3);
+ testComputedExpressionEvaluation("atan1", "atan(-1)", -Math.PI/4);
+ testComputedExpressionEvaluation("atan3", "atan(-0.577350269)", -Math.PI/6);
+ testComputedExpressionEvaluation("atan4", "atan(0)", 0);
+ testComputedExpressionEvaluation("atan5", "atan(0.577350269)", Math.PI/6);
+ testComputedExpressionEvaluation("atan6", "atan(1)", Math.PI/4);
+ testComputedExpressionEvaluation("atan7", "atan(1.732050808)", Math.PI/3);
+ }
+
+ public void testAtanhMethod() throws Exception {
+ testComputedExpressionEvaluation("atanh0", "atanh(-1)", Double.NEGATIVE_INFINITY);
+ testComputedExpressionEvaluation("atanh1", "atanh(-0.5)", -0.5493061443340549);
+ testComputedExpressionEvaluation("atanh2", "atanh(0)", 0);
+ testComputedExpressionEvaluation("atanh3", "atanh(0.5)", 0.5493061443340549);
+ testComputedExpressionEvaluation("atanh4", "atanh(1)", Double.POSITIVE_INFINITY);
+ }
+
+ public void testCeilMethod() throws Exception {
+ testComputedExpressionEvaluation("ceil0", "ceil(0)", 0);
+ testComputedExpressionEvaluation("ceil1", "ceil(0.1)", 1);
+ testComputedExpressionEvaluation("ceil2", "ceil(0.9)", 1);
+ testComputedExpressionEvaluation("ceil3", "ceil(25.2)", 26);
+ testComputedExpressionEvaluation("ceil4", "ceil(-0.1)", 0);
+ testComputedExpressionEvaluation("ceil5", "ceil(-0.9)", 0);
+ testComputedExpressionEvaluation("ceil6", "ceil(-1.1)", -1);
+ }
+
+ public void testCosMethod() throws Exception {
+ testComputedExpressionEvaluation("cos0", "cos(0)", 1);
+ testComputedExpressionEvaluation("cos1", "cos(" + Math.PI/2 + ")", 0);
+ testComputedExpressionEvaluation("cos2", "cos(" + -Math.PI/2 + ")", 0);
+ testComputedExpressionEvaluation("cos3", "cos(" + Math.PI/4 + ")", 0.7071068);
+ testComputedExpressionEvaluation("cos4", "cos(" + -Math.PI/4 + ")", 0.7071068);
+ testComputedExpressionEvaluation("cos5", "cos(" + Math.PI*2/3 + ")",-0.5);
+ testComputedExpressionEvaluation("cos6", "cos(" + -Math.PI*2/3 + ")", -0.5);
+ testComputedExpressionEvaluation("cos7", "cos(" + Math.PI/6 + ")", 0.8660254);
+ testComputedExpressionEvaluation("cos8", "cos(" + -Math.PI/6 + ")", 0.8660254);
+ }
+
+ public void testCoshMethod() throws Exception {
+ testComputedExpressionEvaluation("cosh0", "cosh(0)", 1);
+ testComputedExpressionEvaluation("cosh1", "cosh(-1)", 1.5430806348152437);
+ testComputedExpressionEvaluation("cosh2", "cosh(1)", 1.5430806348152437);
+ testComputedExpressionEvaluation("cosh3", "cosh(-0.5)", 1.1276259652063807);
+ testComputedExpressionEvaluation("cosh4", "cosh(0.5)", 1.1276259652063807);
+ testComputedExpressionEvaluation("cosh5", "cosh(-12.3456789)", 114982.09728671524);
+ testComputedExpressionEvaluation("cosh6", "cosh(12.3456789)", 114982.09728671524);
+ }
+
+ public void testExpMethod() throws Exception {
+ testComputedExpressionEvaluation("exp0", "exp(0)", 1);
+ testComputedExpressionEvaluation("exp1", "exp(-1)", 0.36787944117);
+ testComputedExpressionEvaluation("exp2", "exp(1)", 2.71828182846);
+ testComputedExpressionEvaluation("exp3", "exp(-0.5)", 0.60653065971);
+ testComputedExpressionEvaluation("exp4", "exp(0.5)", 1.6487212707);
+ testComputedExpressionEvaluation("exp5", "exp(-12.3456789)", 0.0000043485);
+ testComputedExpressionEvaluation("exp6", "exp(12.3456789)", 229964.194569);
+ }
+
+ public void testFloorMethod() throws Exception {
+ testComputedExpressionEvaluation("floor0", "floor(0)", 0);
+ testComputedExpressionEvaluation("floor1", "floor(0.1)", 0);
+ testComputedExpressionEvaluation("floor2", "floor(0.9)", 0);
+ testComputedExpressionEvaluation("floor3", "floor(25.2)", 25);
+ testComputedExpressionEvaluation("floor4", "floor(-0.1)", -1);
+ testComputedExpressionEvaluation("floor5", "floor(-0.9)", -1);
+ testComputedExpressionEvaluation("floor6", "floor(-1.1)", -2);
+ }
+
+ public void testLnMethod() throws Exception {
+ testComputedExpressionEvaluation("ln0", "ln(0)", Double.NEGATIVE_INFINITY);
+ testComputedExpressionEvaluation("ln1", "ln(" + Math.E + ")", 1);
+ testComputedExpressionEvaluation("ln2", "ln(-1)", Double.NaN);
+ testComputedExpressionEvaluation("ln3", "ln(1)", 0);
+ testComputedExpressionEvaluation("ln4", "ln(0.5)", -0.69314718056);
+ testComputedExpressionEvaluation("ln5", "ln(12.3456789)", 2.51330611521);
+ }
+
+ public void testLog10Method() throws Exception {
+ testComputedExpressionEvaluation("log100", "log10(0)", Double.NEGATIVE_INFINITY);
+ testComputedExpressionEvaluation("log101", "log10(1)", 0);
+ testComputedExpressionEvaluation("log102", "log10(-1)", Double.NaN);
+ testComputedExpressionEvaluation("log103", "log10(0.5)", -0.3010299956639812);
+ testComputedExpressionEvaluation("log104", "log10(12.3456789)", 1.0915149771692705);
+ }
+
+ public void testLognMethod() throws Exception {
+ testComputedExpressionEvaluation("logn0", "logn(2, 0)", Double.NEGATIVE_INFINITY);
+ testComputedExpressionEvaluation("logn1", "logn(2, 1)", 0);
+ testComputedExpressionEvaluation("logn2", "logn(2, -1)", Double.NaN);
+ testComputedExpressionEvaluation("logn3", "logn(2, 0.5)", -1);
+ testComputedExpressionEvaluation("logn4", "logn(2, 12.3456789)", 3.6259342686489378);
+ testComputedExpressionEvaluation("logn5", "logn(2.5, 0)", Double.NEGATIVE_INFINITY);
+ testComputedExpressionEvaluation("logn6", "logn(2.5, 1)", 0);
+ testComputedExpressionEvaluation("logn7", "logn(2.5, -1)", Double.NaN);
+ testComputedExpressionEvaluation("logn8", "logn(2.5, 0.5)", -0.75647079736603);
+ testComputedExpressionEvaluation("logn9", "logn(2.5, 12.3456789)", 2.7429133874016745);
+ }
+
+ public void testMaxMethod() throws Exception {
+ testComputedExpressionEvaluation("max0", "max(0, 0)", 0);
+ testComputedExpressionEvaluation("max1", "max(1, 0)", 1);
+ testComputedExpressionEvaluation("max2", "max(0, -1)", 0);
+ testComputedExpressionEvaluation("max3", "max(-1, 0)", 0);
+ testComputedExpressionEvaluation("max4", "max(25, 23)", 25);
+ }
+
+ public void testMinMethod() throws Exception {
+ testComputedExpressionEvaluation("min0", "min(0, 0)", 0);
+ testComputedExpressionEvaluation("min1", "min(1, 0)", 0);
+ testComputedExpressionEvaluation("min2", "min(0, -1)", -1);
+ testComputedExpressionEvaluation("min3", "min(-1, 0)", -1);
+ testComputedExpressionEvaluation("min4", "min(25, 23)", 23);
+ }
+
+ public void testPowMethod() throws Exception {
+ testComputedExpressionEvaluation("pow0", "pow(0, 0)", 1);
+ testComputedExpressionEvaluation("pow1", "pow(0.1, 2)", 0.01);
+ testComputedExpressionEvaluation("pow2", "pow(0.9, -1)", 1.1111111111111112);
+ testComputedExpressionEvaluation("pow3", "pow(2.2, -2.5)", 0.13929749224447147);
+ testComputedExpressionEvaluation("pow4", "pow(5, 3)", 125);
+ testComputedExpressionEvaluation("pow5", "pow(-0.9, 5)", -0.59049);
+ testComputedExpressionEvaluation("pow6", "pow(-1.1, 2)", 1.21);
+ }
+
+ public void testSinMethod() throws Exception {
+ testComputedExpressionEvaluation("sin0", "sin(0)", 0);
+ testComputedExpressionEvaluation("sin1", "sin(" + Math.PI/2 + ")", 1);
+ testComputedExpressionEvaluation("sin2", "sin(" + -Math.PI/2 + ")", -1);
+ testComputedExpressionEvaluation("sin3", "sin(" + Math.PI/4 + ")", 0.7071068);
+ testComputedExpressionEvaluation("sin4", "sin(" + -Math.PI/4 + ")", -0.7071068);
+ testComputedExpressionEvaluation("sin5", "sin(" + Math.PI*2/3 + ")", 0.8660254);
+ testComputedExpressionEvaluation("sin6", "sin(" + -Math.PI*2/3 + ")", -0.8660254);
+ testComputedExpressionEvaluation("sin7", "sin(" + Math.PI/6 + ")", 0.5);
+ testComputedExpressionEvaluation("sin8", "sin(" + -Math.PI/6 + ")", -0.5);
+ }
+
+ public void testSinhMethod() throws Exception {
+ testComputedExpressionEvaluation("sinh0", "sinh(0)", 0);
+ testComputedExpressionEvaluation("sinh1", "sinh(-1)", -1.1752011936438014);
+ testComputedExpressionEvaluation("sinh2", "sinh(1)", 1.1752011936438014);
+ testComputedExpressionEvaluation("sinh3", "sinh(-0.5)", -0.52109530549);
+ testComputedExpressionEvaluation("sinh4", "sinh(0.5)", 0.52109530549);
+ testComputedExpressionEvaluation("sinh5", "sinh(-12.3456789)", -114982.09728236674);
+ testComputedExpressionEvaluation("sinh6", "sinh(12.3456789)", 114982.09728236674);
+ }
+
+ public void testSqrtMethod() throws Exception {
+ testComputedExpressionEvaluation("sqrt0", "sqrt(0)", 0);
+ testComputedExpressionEvaluation("sqrt1", "sqrt(-1)", Double.NaN);
+ testComputedExpressionEvaluation("sqrt2", "sqrt(0.49)", 0.7);
+ testComputedExpressionEvaluation("sqrt3", "sqrt(49)", 7);
+ }
+
+ public void testTanMethod() throws Exception {
+ testComputedExpressionEvaluation("tan0", "tan(0)", 0);
+ testComputedExpressionEvaluation("tan1", "tan(-1)", -1.55740772465);
+ testComputedExpressionEvaluation("tan2", "tan(1)", 1.55740772465);
+ testComputedExpressionEvaluation("tan3", "tan(-0.5)", -0.54630248984);
+ testComputedExpressionEvaluation("tan4", "tan(0.5)", 0.54630248984);
+ testComputedExpressionEvaluation("tan1", "tan(-1.3)", -3.60210244797);
+ testComputedExpressionEvaluation("tan2", "tan(1.3)", 3.60210244797);
+ }
+
+ public void testTanhMethod() throws Exception {
+ testComputedExpressionEvaluation("tanh0", "tanh(0)", 0);
+ testComputedExpressionEvaluation("tanh1", "tanh(-1)", -0.76159415595);
+ testComputedExpressionEvaluation("tanh2", "tanh(1)", 0.76159415595);
+ testComputedExpressionEvaluation("tanh3", "tanh(-0.5)", -0.46211715726);
+ testComputedExpressionEvaluation("tanh4", "tanh(0.5)", 0.46211715726);
+ testComputedExpressionEvaluation("tanh5", "tanh(-12.3456789)", -0.99999999996);
+ testComputedExpressionEvaluation("tanh6", "tanh(12.3456789)", 0.99999999996);
+ }
+
+
+}
diff --git lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptOperations.java lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptOperations.java
new file mode 100644
index 0000000..bfe56cb
--- /dev/null
+++ lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptOperations.java
@@ -0,0 +1,313 @@
+package org.apache.lucene.expressions.js;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.expressions.Expression;
+import org.apache.lucene.util.LuceneTestCase;
+
+public class TestJavascriptOperations extends LuceneTestCase {
+ private void testComputedExpression(String name, String expression, long expected) throws Exception {
+ Expression evaluator = JavascriptCompiler.compile(expression);
+ long actual = (long)evaluator.evaluate(0, null);
+ assertEquals(name, expected, actual);
+ }
+
+ public void testNegationOperation() throws Exception {
+ testComputedExpression("negate0", "-1", -1);
+ testComputedExpression("negate1", "--1", 1);
+ testComputedExpression("negate1", "-(-1)", 1);
+ testComputedExpression("negate2", "-0", 0);
+ testComputedExpression("negate3", "--0", 0);
+ }
+
+ public void testAddOperation() throws Exception {
+ testComputedExpression("add0", "1+1", 2);
+ testComputedExpression("add1", "1+0.5+0.5", 2);
+ testComputedExpression("add2", "5+10", 15);
+ testComputedExpression("add3", "1+1+2", 4);
+ testComputedExpression("add4", "(1+1)+2", 4);
+ testComputedExpression("add5", "1+(1+2)", 4);
+ testComputedExpression("add6", "0+1", 1);
+ testComputedExpression("add7", "1+0", 1);
+ testComputedExpression("add8", "0+0", 0);
+ }
+
+ public void testSubtractOperation() throws Exception {
+ testComputedExpression("subtract0", "1-1", 0);
+ testComputedExpression("subtract1", "5-10", -5);
+ testComputedExpression("subtract2", "1-0.5-0.5", 0);
+ testComputedExpression("subtract3", "1-1-2", -2);
+ testComputedExpression("subtract4", "(1-1)-2", -2);
+ testComputedExpression("subtract5", "1-(1-2)", 2);
+ testComputedExpression("subtract6", "0-1", -1);
+ testComputedExpression("subtract6", "1-0", 1);
+ testComputedExpression("subtract6", "0-0", 0);
+ }
+
+ public void testMultiplyOperation() throws Exception {
+ testComputedExpression("multiply0", "1*1", 1);
+ testComputedExpression("multiply1", "5*10", 50);
+ testComputedExpression("multiply2", "50*0.1", 5);
+ testComputedExpression("multiply4", "1*1*2", 2);
+ testComputedExpression("multiply4", "(1*1)*2", 2);
+ testComputedExpression("multiply5", "1*(1*2)", 2);
+ testComputedExpression("multiply6", "10*0", 0);
+ testComputedExpression("multiply6", "0*0", 0);
+ }
+
+ public void testDivisionOperation() throws Exception {
+ testComputedExpression("division0", "1*1", 1);
+ testComputedExpression("division1", "10/5", 2);
+ testComputedExpression("division2", "10/0.5", 20);
+ testComputedExpression("division3", "10/5/2", 1);
+ testComputedExpression("division4", "(27/9)/3", 1);
+ testComputedExpression("division5", "27/(9/3)", 9);
+ testComputedExpression("division6", "1/0", 9223372036854775807L);
+ }
+
+ public void testModuloOperation() throws Exception {
+ testComputedExpression("modulo0", "1%1", 0);
+ testComputedExpression("modulo1", "10%3", 1);
+ testComputedExpression("modulo2", "10%3%2", 1);
+ testComputedExpression("modulo3", "(27%10)%4", 3);
+ testComputedExpression("modulo4", "27%(9%5)", 3);
+ }
+
+ public void testLessThanOperation() throws Exception {
+ testComputedExpression("lessthan0", "1 < 1", 0);
+ testComputedExpression("lessthan1", "2 < 1", 0);
+ testComputedExpression("lessthan2", "1 < 2", 1);
+ testComputedExpression("lessthan3", "2 < 1 < 3", 1);
+ testComputedExpression("lessthan4", "2 < (1 < 3)", 0);
+ testComputedExpression("lessthan5", "(2 < 1) < 1", 1);
+ testComputedExpression("lessthan6", "-1 < -2", 0);
+ testComputedExpression("lessthan7", "-1 < 0", 1);
+ }
+
+ public void testLessThanEqualsOperation() throws Exception {
+ testComputedExpression("lessthanequals0", "1 <= 1", 1);
+ testComputedExpression("lessthanequals1", "2 <= 1", 0);
+ testComputedExpression("lessthanequals2", "1 <= 2", 1);
+ testComputedExpression("lessthanequals3", "1 <= 1 <= 0", 0);
+ testComputedExpression("lessthanequals4", "-1 <= -1", 1);
+ testComputedExpression("lessthanequals5", "-1 <= 0", 1);
+ testComputedExpression("lessthanequals6", "-1 <= -2", 0);
+ testComputedExpression("lessthanequals7", "-1 <= 0", 1);
+ }
+
+ public void testGreaterThanOperation() throws Exception {
+ testComputedExpression("greaterthan0", "1 > 1", 0);
+ testComputedExpression("greaterthan1", "2 > 1", 1);
+ testComputedExpression("greaterthan2", "1 > 2", 0);
+ testComputedExpression("greaterthan3", "2 > 1 > 3", 0);
+ testComputedExpression("greaterthan4", "2 > (1 > 3)", 1);
+ testComputedExpression("greaterthan5", "(2 > 1) > 1", 0);
+ testComputedExpression("greaterthan6", "-1 > -2", 1);
+ testComputedExpression("greaterthan7", "-1 > 0", 0);
+ }
+
+ public void testGreaterThanEqualsOperation() throws Exception {
+ testComputedExpression("greaterthanequals0", "1 >= 1", 1);
+ testComputedExpression("greaterthanequals1", "2 >= 1", 1);
+ testComputedExpression("greaterthanequals2", "1 >= 2", 0);
+ testComputedExpression("greaterthanequals3", "1 >= 1 >= 0", 1);
+ testComputedExpression("greaterthanequals4", "-1 >= -1", 1);
+ testComputedExpression("greaterthanequals5", "-1 >= 0", 0);
+ testComputedExpression("greaterthanequals6", "-1 >= -2", 1);
+ testComputedExpression("greaterthanequals7", "-1 >= 0", 0);
+ }
+
+ public void testEqualsOperation() throws Exception {
+ testComputedExpression("equals0", "1 == 1", 1);
+ testComputedExpression("equals1", "0 == 0", 1);
+ testComputedExpression("equals2", "-1 == -1", 1);
+ testComputedExpression("equals3", "1.1 == 1.1", 1);
+ testComputedExpression("equals4", "0.9 == 0.9", 1);
+ testComputedExpression("equals5", "-0 == 0", 1);
+ testComputedExpression("equals6", "0 == 1", 0);
+ testComputedExpression("equals7", "1 == 2", 0);
+ testComputedExpression("equals8", "-1 == 1", 0);
+ testComputedExpression("equals9", "-1 == 0", 0);
+ testComputedExpression("equals10", "-2 == 1", 0);
+ testComputedExpression("equals11", "-2 == -1", 0);
+ }
+
+ public void testNotEqualsOperation() throws Exception {
+ testComputedExpression("notequals0", "1 != 1", 0);
+ testComputedExpression("notequals1", "0 != 0", 0);
+ testComputedExpression("notequals2", "-1 != -1", 0);
+ testComputedExpression("notequals3", "1.1 != 1.1", 0);
+ testComputedExpression("notequals4", "0.9 != 0.9", 0);
+ testComputedExpression("notequals5", "-0 != 0", 0);
+ testComputedExpression("notequals6", "0 != 1", 1);
+ testComputedExpression("notequals7", "1 != 2", 1);
+ testComputedExpression("notequals8", "-1 != 1", 1);
+ testComputedExpression("notequals9", "-1 != 0", 1);
+ testComputedExpression("notequals10", "-2 != 1", 1);
+ testComputedExpression("notequals11", "-2 != -1", 1);
+ }
+
+ public void testBoolNotOperation() throws Exception {
+ testComputedExpression("boolnot0", "!1", 0);
+ testComputedExpression("boolnot0", "!!1", 1);
+ testComputedExpression("boolnot0", "!0", 1);
+ testComputedExpression("boolnot0", "!!0", 0);
+ testComputedExpression("boolnot0", "!-1", 0);
+ testComputedExpression("boolnot0", "!2", 0);
+ testComputedExpression("boolnot0", "!-2", 0);
+ }
+
+ public void testBoolAndOperation() throws Exception {
+ testComputedExpression("booland0", "1 && 1", 1);
+ testComputedExpression("booland1", "1 && 0", 0);
+ testComputedExpression("booland2", "0 && 1", 0);
+ testComputedExpression("booland3", "0 && 0", 0);
+ testComputedExpression("booland4", "-1 && -1", 1);
+ testComputedExpression("booland5", "-1 && 0", 0);
+ testComputedExpression("booland6", "0 && -1", 0);
+ testComputedExpression("booland7", "-0 && -0", 0);
+ }
+
+ public void testBoolOrOperation() throws Exception {
+ testComputedExpression("boolor0", "1 || 1", 1);
+ testComputedExpression("boolor1", "1 || 0", 1);
+ testComputedExpression("boolor2", "0 || 1", 1);
+ testComputedExpression("boolor3", "0 || 0", 0);
+ testComputedExpression("boolor4", "-1 || -1", 1);
+ testComputedExpression("boolor5", "-1 || 0", 1);
+ testComputedExpression("boolor6", "0 || -1", 1);
+ testComputedExpression("boolor7", "-0 || -0", 0);
+ }
+
+ public void testConditionalOperation() throws Exception {
+ testComputedExpression("conditional0", "1 ? 2 : 3", 2);
+ testComputedExpression("conditional1", "-1 ? 2 : 3", 2);
+ testComputedExpression("conditional2", "0 ? 2 : 3", 3);
+ testComputedExpression("conditional3", "1 ? 2 ? 3 : 4 : 5", 3);
+ testComputedExpression("conditional4", "0 ? 2 ? 3 : 4 : 5", 5);
+ testComputedExpression("conditional5", "1 ? 0 ? 3 : 4 : 5", 4);
+ testComputedExpression("conditional6", "1 ? 2 : 3 ? 4 : 5", 2);
+ testComputedExpression("conditional7", "0 ? 2 : 3 ? 4 : 5", 4);
+ testComputedExpression("conditional8", "0 ? 2 : 0 ? 4 : 5", 5);
+ testComputedExpression("conditional9", "(1 ? 1 : 0) ? 3 : 4", 3);
+ testComputedExpression("conditional10", "(0 ? 1 : 0) ? 3 : 4", 4);
+ }
+
+ public void testBitShiftLeft() throws Exception {
+ testComputedExpression("bitshiftleft0", "1 << 1", 2);
+ testComputedExpression("bitshiftleft1", "2 << 1", 4);
+ testComputedExpression("bitshiftleft2", "-1 << 31", -2147483648);
+ testComputedExpression("bitshiftleft3", "3 << 5", 96);
+ testComputedExpression("bitshiftleft4", "-5 << 3", -40);
+ testComputedExpression("bitshiftleft5", "4195 << 7", 536960);
+ testComputedExpression("bitshiftleft6", "4195 << 66", 16780);
+ testComputedExpression("bitshiftleft7", "4195 << 6", 268480);
+ testComputedExpression("bitshiftleft8", "4195 << 70", 268480);
+ testComputedExpression("bitshiftleft9", "-4195 << 70", -268480);
+ testComputedExpression("bitshiftleft10", "-15 << 62", 4611686018427387904L);
+ }
+
+ public void testBitShiftRight() throws Exception {
+ testComputedExpression("bitshiftright0", "1 >> 1", 0);
+ testComputedExpression("bitshiftright1", "2 >> 1", 1);
+ testComputedExpression("bitshiftright2", "-1 >> 5", -1);
+ testComputedExpression("bitshiftright3", "-2 >> 30", -1);
+ testComputedExpression("bitshiftright4", "-5 >> 1", -3);
+ testComputedExpression("bitshiftright5", "536960 >> 7", 4195);
+ testComputedExpression("bitshiftright6", "16780 >> 66", 4195);
+ testComputedExpression("bitshiftright7", "268480 >> 6", 4195);
+ testComputedExpression("bitshiftright8", "268480 >> 70", 4195);
+ testComputedExpression("bitshiftright9", "-268480 >> 70", -4195);
+ testComputedExpression("bitshiftright10", "-2147483646 >> 1", -1073741823);
+ }
+
+ public void testBitShiftRightUnsigned() throws Exception {
+ testComputedExpression("bitshiftrightunsigned0", "1 >>> 1", 0);
+ testComputedExpression("bitshiftrightunsigned1", "2 >>> 1", 1);
+ testComputedExpression("bitshiftrightunsigned2", "-1 >>> 37", 134217727);
+ testComputedExpression("bitshiftrightunsigned3", "-2 >>> 62", 3);
+ testComputedExpression("bitshiftrightunsigned4", "-5 >>> 33", 2147483647);
+ testComputedExpression("bitshiftrightunsigned5", "536960 >>> 7", 4195);
+ testComputedExpression("bitshiftrightunsigned6", "16780 >>> 66", 4195);
+ testComputedExpression("bitshiftrightunsigned7", "268480 >>> 6", 4195);
+ testComputedExpression("bitshiftrightunsigned8", "268480 >>> 70", 4195);
+ testComputedExpression("bitshiftrightunsigned9", "-268480 >>> 102", 67108863);
+ testComputedExpression("bitshiftrightunsigned10", "2147483648 >>> 1", 1073741824);
+ }
+
+ public void testBitwiseAnd() throws Exception {
+ testComputedExpression("bitwiseand0", "4 & 4", 4);
+ testComputedExpression("bitwiseand1", "3 & 2", 2);
+ testComputedExpression("bitwiseand2", "7 & 3", 3);
+ testComputedExpression("bitwiseand3", "-1 & -1", -1);
+ testComputedExpression("bitwiseand4", "-1 & 25", 25);
+ testComputedExpression("bitwiseand5", "3 & 7", 3);
+ testComputedExpression("bitwiseand6", "0 & 1", 0);
+ testComputedExpression("bitwiseand7", "1 & 0", 0);
+ }
+
+ public void testBitwiseOr() throws Exception {
+ testComputedExpression("bitwiseor0", "4 | 4", 4);
+ testComputedExpression("bitwiseor1", "5 | 2", 7);
+ testComputedExpression("bitwiseor2", "7 | 3", 7);
+ testComputedExpression("bitwiseor3", "-1 | -5", -1);
+ testComputedExpression("bitwiseor4", "-1 | 25", -1);
+ testComputedExpression("bitwiseor5", "-100 | 15", -97);
+ testComputedExpression("bitwiseor6", "0 | 1", 1);
+ testComputedExpression("bitwiseor7", "1 | 0", 1);
+ }
+
+ public void testBitwiseXor() throws Exception {
+ testComputedExpression("bitwisexor0", "4 ^ 4", 0);
+ testComputedExpression("bitwisexor1", "5 ^ 2", 7);
+ testComputedExpression("bitwisexor2", "15 ^ 3", 12);
+ testComputedExpression("bitwisexor3", "-1 ^ -5", 4);
+ testComputedExpression("bitwisexor4", "-1 ^ 25", -26);
+ testComputedExpression("bitwisexor5", "-100 ^ 15", -109);
+ testComputedExpression("bitwisexor6", "0 ^ 1", 1);
+ testComputedExpression("bitwisexor7", "1 ^ 0", 1);
+ testComputedExpression("bitwisexor8", "0 ^ 0", 0);
+ }
+
+ public void testBitwiseNot() throws Exception {
+ testComputedExpression("bitwisenot0", "~-5", 4);
+ testComputedExpression("bitwisenot1", "~25", -26);
+ testComputedExpression("bitwisenot2", "~0", -1);
+ testComputedExpression("bitwisenot3", "~-1", 0);
+ }
+
+ public void testDecimalConst() throws Exception {
+ testComputedExpression("decimalconst0", "0", 0);
+ testComputedExpression("decimalconst1", "1", 1);
+ testComputedExpression("decimalconst2", "123456789", 123456789);
+ testComputedExpression("decimalconst3", "5.6E2", 560);
+ }
+
+ public void testHexConst() throws Exception {
+ testComputedExpression("hexconst0", "0x0", 0);
+ testComputedExpression("hexconst1", "0x1", 1);
+ testComputedExpression("hexconst2", "0xF", 15);
+ testComputedExpression("hexconst3", "0x1234ABCDEF", 78193085935L);
+ }
+
+ public void testOctalConst() throws Exception {
+ testComputedExpression("octalconst0", "00", 0);
+ testComputedExpression("octalconst1", "01", 1);
+ testComputedExpression("octalconst2", "010", 8);
+ testComputedExpression("octalconst3", "0123456777", 21913087);
+ }
+}
diff --git lucene/licenses/antlr-3.4.jar.sha1 lucene/licenses/antlr-3.4.jar.sha1
new file mode 100644
index 0000000..f1daf4b
--- /dev/null
+++ lucene/licenses/antlr-3.4.jar.sha1
@@ -0,0 +1 @@
+7797e70e3f5cb4229695f08ff50333266cf81125
diff --git lucene/licenses/antlr-LICENSE-BSD_LIKE.txt lucene/licenses/antlr-LICENSE-BSD_LIKE.txt
new file mode 100644
index 0000000..a6e3ad0
--- /dev/null
+++ lucene/licenses/antlr-LICENSE-BSD_LIKE.txt
@@ -0,0 +1,7 @@
+Copyright (c) 2012 Terence Parr and Sam Harwell
+All rights reserved.
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git lucene/licenses/antlr-NOTICE.txt lucene/licenses/antlr-NOTICE.txt
new file mode 100644
index 0000000..8d1c8b6
--- /dev/null
+++ lucene/licenses/antlr-NOTICE.txt
@@ -0,0 +1 @@
+
diff --git lucene/licenses/asm-4.1.jar.sha1 lucene/licenses/asm-4.1.jar.sha1
new file mode 100644
index 0000000..fca9878
--- /dev/null
+++ lucene/licenses/asm-4.1.jar.sha1
@@ -0,0 +1 @@
+ad568238ee36a820bd6c6806807e8a14ea34684d
diff --git lucene/licenses/asm-LICENSE-BSD_LIKE.txt lucene/licenses/asm-LICENSE-BSD_LIKE.txt
new file mode 100644
index 0000000..afb064f
--- /dev/null
+++ lucene/licenses/asm-LICENSE-BSD_LIKE.txt
@@ -0,0 +1,26 @@
+Copyright (c) 2012 France Télécom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
diff --git lucene/licenses/asm-NOTICE.txt lucene/licenses/asm-NOTICE.txt
new file mode 100644
index 0000000..8d1c8b6
--- /dev/null
+++ lucene/licenses/asm-NOTICE.txt
@@ -0,0 +1 @@
+
diff --git lucene/module-build.xml lucene/module-build.xml
index 6c6d97a..8be1f30 100644
--- lucene/module-build.xml
+++ lucene/module-build.xml
@@ -433,6 +433,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+