You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2015/01/31 21:03:49 UTC

[1/5] lucenenet git commit: Adding Expressions with some failing tests

Repository: lucenenet
Updated Branches:
  refs/heads/master 69f29113e -> b6c1b5d2e


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/TestExpressionSortField.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/TestExpressionSortField.cs b/src/Lucene.Net.Tests.Expressions/TestExpressionSortField.cs
new file mode 100644
index 0000000..fb54d18
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/TestExpressionSortField.cs
@@ -0,0 +1,92 @@
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Search;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions
+{
+	public class TestExpressionSortField : Util.LuceneTestCase
+	{
+		[Test]
+		public virtual void TestToString()
+		{
+			Expression expr = JavascriptCompiler.Compile("sqrt(_score) + ln(popularity)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			bindings.Add(new SortField("popularity", SortField.Type_e.INT));
+			SortField sf = expr.GetSortField(bindings, true);
+			AreEqual("<expr \"sqrt(_score) + ln(popularity)\">!", sf.ToString());
+		}
+
+		[Test]
+		public virtual void TestEquals()
+		{
+			Expression expr = JavascriptCompiler.Compile("sqrt(_score) + ln(popularity)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			bindings.Add(new SortField("popularity", SortField.Type_e.INT));
+			SimpleBindings otherBindings = new SimpleBindings();
+			otherBindings.Add(new SortField("_score", SortField.Type_e.LONG));
+			otherBindings.Add(new SortField("popularity", SortField.Type_e.INT));
+			SortField sf1 = expr.GetSortField(bindings, true);
+			// different order
+			SortField sf2 = expr.GetSortField(bindings, false);
+			IsFalse(sf1.Equals(sf2));
+			// different bindings
+			sf2 = expr.GetSortField(otherBindings, true);
+			IsFalse(sf1.Equals(sf2));
+			// different expression
+			Expression other = JavascriptCompiler.Compile("popularity/2");
+			sf2 = other.GetSortField(bindings, true);
+			IsFalse(sf1.Equals(sf2));
+			// null
+			IsFalse(sf1.Equals(null));
+			// same instance:
+			AreEqual(sf1, sf1);
+		}
+
+		[Test]
+		public virtual void TestNeedsScores()
+		{
+			SimpleBindings bindings = new SimpleBindings();
+			// refers to score directly
+			Expression exprA = JavascriptCompiler.Compile("_score");
+			// constant
+			Expression exprB = JavascriptCompiler.Compile("0");
+			// field
+			Expression exprC = JavascriptCompiler.Compile("intfield");
+			// score + constant
+			Expression exprD = JavascriptCompiler.Compile("_score + 0");
+			// field + constant
+			Expression exprE = JavascriptCompiler.Compile("intfield + 0");
+			// expression + constant (score ref'd)
+			Expression exprF = JavascriptCompiler.Compile("a + 0");
+			// expression + constant
+			Expression exprG = JavascriptCompiler.Compile("e + 0");
+			// several variables (score ref'd)
+			Expression exprH = JavascriptCompiler.Compile("b / c + e * g - sqrt(f)");
+			// several variables
+			Expression exprI = JavascriptCompiler.Compile("b / c + e * g");
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			bindings.Add(new SortField("intfield", SortField.Type_e.INT));
+			bindings.Add("a", exprA);
+			bindings.Add("b", exprB);
+			bindings.Add("c", exprC);
+			bindings.Add("d", exprD);
+			bindings.Add("e", exprE);
+			bindings.Add("f", exprF);
+			bindings.Add("g", exprG);
+			bindings.Add("h", exprH);
+			bindings.Add("i", exprI);
+			IsTrue(exprA.GetSortField(bindings, true).NeedsScores());
+			IsFalse(exprB.GetSortField(bindings, true).NeedsScores());
+			IsFalse(exprC.GetSortField(bindings, true).NeedsScores());
+			IsTrue(exprD.GetSortField(bindings, true).NeedsScores());
+			IsFalse(exprE.GetSortField(bindings, true).NeedsScores());
+			IsTrue(exprF.GetSortField(bindings, true).NeedsScores());
+			IsFalse(exprG.GetSortField(bindings, true).NeedsScores());
+			IsTrue(exprH.GetSortField(bindings, true).NeedsScores());
+			IsFalse(exprI.GetSortField(bindings, false).NeedsScores());
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/TestExpressionSorts.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/TestExpressionSorts.cs b/src/Lucene.Net.Tests.Expressions/TestExpressionSorts.cs
new file mode 100644
index 0000000..d6b0fef
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/TestExpressionSorts.cs
@@ -0,0 +1,151 @@
+using Lucene.Net.Documents;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Index;
+using Lucene.Net.Randomized.Generators;
+using Lucene.Net.Search;
+using Lucene.Net.Store;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions
+{
+    /// <summary>
+    /// Tests some basic expressions against different queries,
+    /// and fieldcache/docvalues fields against an equivalent sort.
+    /// </summary>
+    /// <remarks>
+    /// Tests some basic expressions against different queries,
+    /// and fieldcache/docvalues fields against an equivalent sort.
+    /// </remarks>
+    public class TestExpressionSorts : Util.LuceneTestCase
+    {
+        private Directory dir;
+
+        private IndexReader reader;
+
+        private IndexSearcher searcher;
+
+        [SetUp]
+        public override void SetUp()
+        {
+            base.SetUp();
+            dir = NewDirectory();
+            var iw = new RandomIndexWriter(Random(), dir);
+            int numDocs = TestUtil.NextInt(Random(), 2049, 4000);
+            for (int i = 0; i < numDocs; i++)
+            {
+                var document = new Document
+				{
+				    NewTextField("english", English.IntToEnglish(i), Field.Store.NO),
+				    NewTextField("oddeven", (i%2 == 0) ? "even" : "odd", Field.Store.NO
+				        ),
+				    NewStringField("byte", string.Empty + (unchecked((byte) Random().Next
+				        ())), Field.Store.NO),
+				    NewStringField("short", string.Empty + ((short) Random().Next()), Field.Store
+				        .NO),
+				    new IntField("int", Random().Next(), Field.Store.NO),
+				    new LongField("long", Random().NextLong(), Field.Store.NO),
+				    new FloatField("float", Random().NextFloat(), Field.Store.NO),
+				    new DoubleField("double", Random().NextDouble(), Field.Store.NO),
+				    new NumericDocValuesField("intdocvalues", Random().Next()),
+				    new FloatDocValuesField("floatdocvalues", Random().NextFloat())
+				};
+                iw.AddDocument(document);
+            }
+            reader = iw.Reader;
+            iw.Dispose();
+            searcher = NewSearcher(reader);
+        }
+
+        [TearDown]
+        public override void TearDown()
+        {
+            reader.Dispose();
+            dir.Dispose();
+            base.TearDown();
+        }
+
+        [Test]
+        public virtual void TestQueries()
+        {
+            int n = AtLeast(4);
+            for (int i = 0; i < n; i++)
+            {
+                Filter odd = new QueryWrapperFilter(new TermQuery(new Term("oddeven", "odd")));
+                AssertQuery(new MatchAllDocsQuery(), null);
+                AssertQuery(new TermQuery(new Term("english", "one")), null);
+                AssertQuery(new MatchAllDocsQuery(), odd);
+                AssertQuery(new TermQuery(new Term("english", "four")), odd);
+                BooleanQuery bq = new BooleanQuery();
+                bq.Add(new TermQuery(new Term("english", "one")), BooleanClause.Occur.SHOULD);
+                bq.Add(new TermQuery(new Term("oddeven", "even")), BooleanClause.Occur.SHOULD);
+                AssertQuery(bq, null);
+                // force in order
+                bq.Add(new TermQuery(new Term("english", "two")), BooleanClause.Occur.SHOULD);
+                bq.MinimumNumberShouldMatch = 2;
+                AssertQuery(bq, null);
+            }
+        }
+
+        
+        internal virtual void AssertQuery(Query query, Filter filter)
+        {
+            for (int i = 0; i < 10; i++)
+            {
+                bool reversed = Random().NextBoolean();
+                SortField[] fields =
+				{ new SortField("int", SortField.Type_e.INT, reversed
+				    ), new SortField("long", SortField.Type_e.LONG, reversed), new SortField("float", 
+				        SortField.Type_e.FLOAT, reversed), new SortField("double", SortField.Type_e.DOUBLE, 
+				            reversed), new SortField("intdocvalues", SortField.Type_e.INT, reversed), new SortField
+				                ("floatdocvalues", SortField.Type_e.FLOAT, reversed), new SortField("score", SortField.Type_e.SCORE) };
+                //TODO: Add Shuffle extension
+                //Collections.Shuffle(Arrays.AsList(fields), Random());
+                int numSorts = TestUtil.NextInt(Random(), 1, fields.Length);
+                AssertQuery(query, filter, new Sort(Arrays.CopyOfRange(fields, 0, numSorts)));
+            }
+        }
+
+        
+        internal virtual void AssertQuery(Query query, Filter filter, Sort sort)
+        {
+            int size = TestUtil.NextInt(Random(), 1, searcher.IndexReader.MaxDoc / 5);
+            TopDocs expected = searcher.Search(query, filter, size, sort, Random().NextBoolean
+                (), Random().NextBoolean());
+            // make our actual sort, mutating original by replacing some of the 
+            // sortfields with equivalent expressions
+            SortField[] original = sort.GetSort();
+            SortField[] mutated = new SortField[original.Length];
+            for (int i = 0; i < mutated.Length; i++)
+            {
+                if (Random().Next(3) > 0)
+                {
+                    SortField s = original[i];
+                    Expression expr = JavascriptCompiler.Compile(s.Field);
+                    SimpleBindings simpleBindings = new SimpleBindings();
+                    simpleBindings.Add(s);
+                    bool reverse = s.Type == SortField.Type_e.SCORE || s.Reverse;
+                    mutated[i] = expr.GetSortField(simpleBindings, reverse);
+                }
+                else
+                {
+                    mutated[i] = original[i];
+                }
+            }
+            Sort mutatedSort = new Sort(mutated);
+            TopDocs actual = searcher.Search(query, filter, size, mutatedSort, Random().NextBoolean
+                (), Random().NextBoolean());
+            CheckHits.CheckEqual(query, expected.ScoreDocs, actual.ScoreDocs);
+            if (size < actual.TotalHits)
+            {
+                expected = searcher.SearchAfter(expected.ScoreDocs[size - 1], query, filter, size
+                    , sort);
+                actual = searcher.SearchAfter(actual.ScoreDocs[size - 1], query, filter, size, mutatedSort
+                    );
+                CheckHits.CheckEqual(query, expected.ScoreDocs, actual.ScoreDocs);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/TestExpressionValidation.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/TestExpressionValidation.cs b/src/Lucene.Net.Tests.Expressions/TestExpressionValidation.cs
new file mode 100644
index 0000000..dfb6c95
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/TestExpressionValidation.cs
@@ -0,0 +1,151 @@
+using System;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Search;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions
+{
+	/// <summary>Tests validation of bindings</summary>
+	public class TestExpressionValidation : Util.LuceneTestCase
+	{
+		[Test]
+		public virtual void TestValidExternals()
+		{
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("valid0", SortField.Type_e.INT));
+			bindings.Add(new SortField("valid1", SortField.Type_e.INT));
+			bindings.Add(new SortField("valid2", SortField.Type_e.INT));
+			bindings.Add(new SortField("_score", SortField.Type_e.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();
+		}
+
+		[Test]
+		public virtual void TestInvalidExternal()
+		{
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("valid", SortField.Type_e.INT));
+			bindings.Add("invalid", JavascriptCompiler.Compile("badreference"));
+			try
+			{
+				bindings.Validate();
+				Fail("didn't get expected exception");
+			}
+			catch (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("Invalid reference"));
+			}
+		}
+
+		[Test]
+		public virtual void TestInvalidExternal2()
+		{
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("valid", SortField.Type_e.INT));
+			bindings.Add("invalid", JavascriptCompiler.Compile("valid + badreference"));
+			try
+			{
+				bindings.Validate();
+				Fail("didn't get expected exception");
+			}
+			catch (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("Invalid reference"));
+			}
+		}
+
+        [Test, Ignore("Causing the runner to crash. revisit after all tests are fixed")]
+		public virtual void TestSelfRecursion()
+		{
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add("cycle0", JavascriptCompiler.Compile("cycle0"));
+			try
+			{
+				bindings.Validate();
+				Fail("didn't get expected exception");
+			}
+			catch (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("Cycle detected"));
+			}
+		}
+
+		[Test, Ignore("Causing the runner to crash. revisit after all tests are fixed")]
+		public virtual void TestCoRecursion()
+		{
+			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 (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("Cycle detected"));
+			}
+		}
+
+        [Test, Ignore("Causing the runner to crash. revisit after all tests are fixed")]
+		public virtual void TestCoRecursion2()
+		{
+			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 (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("Cycle detected"));
+			}
+		}
+
+        [Test, Ignore("Causing the runner to crash. revisit after all tests are fixed")]
+		public virtual void TestCoRecursion3()
+		{
+			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 (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("Cycle detected"));
+			}
+		}
+
+        [Test, Ignore("Causing the runner to crash. revisit after all tests are fixed")]
+		public virtual void TestCoRecursion4()
+		{
+			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 (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("Cycle detected"));
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/TestExpressionValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/TestExpressionValueSource.cs b/src/Lucene.Net.Tests.Expressions/TestExpressionValueSource.cs
new file mode 100644
index 0000000..b6a7df2
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/TestExpressionValueSource.cs
@@ -0,0 +1,157 @@
+using System.Collections.Generic;
+using Lucene.Net.Analysis;
+using Lucene.Net.Documents;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Index;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Search;
+using Lucene.Net.Store;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions
+{
+	public class TestExpressionValueSource : Util.LuceneTestCase
+	{
+		internal DirectoryReader reader;
+
+		internal Directory dir;
+
+		[SetUp]
+		public override void SetUp()
+		{
+			base.SetUp();
+			dir = NewDirectory();
+			IndexWriterConfig iwc = NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer
+				(Random()));
+			iwc.SetMergePolicy(NewLogMergePolicy());
+			var iw = new RandomIndexWriter(Random(), dir, iwc);
+			var doc = new Document
+			{
+			    NewStringField("id", "1", Field.Store.YES),
+			    NewTextField("body", "some contents and more contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 5)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "2", Field.Store.YES),
+			    NewTextField("body", "another document with different contents", Field.Store
+			        .NO),
+			    new NumericDocValuesField("popularity", 20)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "3", Field.Store.YES),
+			    NewTextField("body", "crappy contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 2)
+			};
+		    iw.AddDocument(doc);
+			iw.ForceMerge(1);
+			reader = iw.Reader;
+			iw.Dispose();
+		}
+
+		[TearDown]
+		public override void TearDown()
+		{
+			reader.Dispose();
+			dir.Dispose();
+			base.TearDown();
+		}
+
+		[Test]
+		public virtual void TestTypes()
+		{
+			Expression expr = JavascriptCompiler.Compile("2*popularity");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("popularity", SortField.Type_e.LONG));
+			ValueSource vs = expr.GetValueSource(bindings);
+			AreEqual(1, reader.Leaves.Count);
+			AtomicReaderContext leaf = reader.Leaves[0];
+			FunctionValues values = vs.GetValues(new Dictionary<string, object>(), leaf);
+			AreEqual(10, values.DoubleVal(0), 0);
+			AreEqual(10, values.FloatVal(0), 0);
+			AreEqual(10, values.LongVal(0));
+			AreEqual(10, values.IntVal(0));
+			AreEqual(10, values.ShortVal(0));
+			AreEqual(10, values.ByteVal(0));
+			AreEqual("10", values.StrVal(0));
+			AreEqual(System.Convert.ToDouble(10), values.ObjectVal(0));
+			AreEqual(40, values.DoubleVal(1), 0);
+			AreEqual(40, values.FloatVal(1), 0);
+			AreEqual(40, values.LongVal(1));
+			AreEqual(40, values.IntVal(1));
+			AreEqual(40, values.ShortVal(1));
+			AreEqual(40, values.ByteVal(1));
+			AreEqual("40", values.StrVal(1));
+			AreEqual(System.Convert.ToDouble(40), values.ObjectVal(1));
+			AreEqual(4, values.DoubleVal(2), 0);
+			AreEqual(4, values.FloatVal(2), 0);
+			AreEqual(4, values.LongVal(2));
+			AreEqual(4, values.IntVal(2));
+			AreEqual(4, values.ShortVal(2));
+			AreEqual(4, values.ByteVal(2));
+			AreEqual("4", values.StrVal(2));
+			AreEqual(System.Convert.ToDouble(4), values.ObjectVal(2));
+		}
+
+		[Test]
+		public virtual void TestRangeScorer()
+		{
+			Expression expr = JavascriptCompiler.Compile("2*popularity");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("popularity", SortField.Type_e.LONG));
+			ValueSource vs = expr.GetValueSource(bindings);
+			AreEqual(1, reader.Leaves.Count);
+			AtomicReaderContext leaf = reader.Leaves[0];
+			FunctionValues values = vs.GetValues(new Dictionary<string, object>(), leaf);
+			// everything
+			ValueSourceScorer scorer = values.GetRangeScorer(leaf.Reader, "4"
+				, "40", true, true);
+			AreEqual(-1, scorer.DocID());
+			AreEqual(0, scorer.NextDoc());
+			AreEqual(1, scorer.NextDoc());
+			AreEqual(2, scorer.NextDoc());
+			AreEqual(DocIdSetIterator.NO_MORE_DOCS, scorer.NextDoc());
+			// just the first doc
+			scorer = values.GetRangeScorer(leaf.Reader, "4", "40", false, false);
+			AreEqual(-1, scorer.DocID());
+			AreEqual(0, scorer.NextDoc());
+			AreEqual(DocIdSetIterator.NO_MORE_DOCS, scorer.NextDoc());
+		}
+
+		[Test]
+		public virtual void TestEquals()
+		{
+			Expression expr = JavascriptCompiler.Compile("sqrt(a) + ln(b)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("a", SortField.Type_e.INT));
+			bindings.Add(new SortField("b", SortField.Type_e.INT));
+			ValueSource vs1 = expr.GetValueSource(bindings);
+			// same instance
+			AreEqual(vs1, vs1);
+			// null
+			IsFalse(vs1.Equals(null));
+			// other object
+			IsFalse(vs1.Equals("foobar"));
+			// same bindings and expression instances
+			ValueSource vs2 = expr.GetValueSource(bindings);
+			AreEqual(vs1.GetHashCode(), vs2.GetHashCode());
+			AreEqual(vs1, vs2);
+			// equiv bindings (different instance)
+			SimpleBindings bindings2 = new SimpleBindings();
+			bindings2.Add(new SortField("a", SortField.Type_e.INT));
+			bindings2.Add(new SortField("b", SortField.Type_e.INT));
+			ValueSource vs3 = expr.GetValueSource(bindings2);
+			AreEqual(vs1, vs3);
+			// different bindings (same names, different types)
+			SimpleBindings bindings3 = new SimpleBindings();
+			bindings3.Add(new SortField("a", SortField.Type_e.LONG));
+			bindings3.Add(new SortField("b", SortField.Type_e.INT));
+			ValueSource vs4 = expr.GetValueSource(bindings3);
+			IsFalse(vs1.Equals(vs4));
+		}
+	}
+}


[3/5] lucenenet git commit: Adding Expressions with some failing tests

Posted by sy...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/JS/JavascriptParser.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/JS/JavascriptParser.cs b/src/Lucene.Net.Expressions/JS/JavascriptParser.cs
new file mode 100644
index 0000000..a06cb0e
--- /dev/null
+++ b/src/Lucene.Net.Expressions/JS/JavascriptParser.cs
@@ -0,0 +1,1879 @@
+using System;
+using Antlr.Runtime;
+using Antlr.Runtime.Tree;
+
+
+namespace Lucene.Net.Expressions.JS
+{
+    internal class JavascriptParser : Parser
+    {
+        public static readonly string[] tokenNames =
+		{ "<invalid>", "<EOR>", 
+		    "<DOWN>", "<UP>", "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"
+		    , "NAMESPACE_ID", "OCTAL", "OCTALDIGIT", "WS" };
+
+        public const int EOF = -1;
+
+        public const int AT_ADD = 4;
+
+        public const int AT_BIT_AND = 5;
+
+        public const int AT_BIT_NOT = 6;
+
+        public const int AT_BIT_OR = 7;
+
+        public const int AT_BIT_SHL = 8;
+
+        public const int AT_BIT_SHR = 9;
+
+        public const int AT_BIT_SHU = 10;
+
+        public const int AT_BIT_XOR = 11;
+
+        public const int AT_BOOL_AND = 12;
+
+        public const int AT_BOOL_NOT = 13;
+
+        public const int AT_BOOL_OR = 14;
+
+        public const int AT_CALL = 15;
+
+        public const int AT_COLON = 16;
+
+        public const int AT_COMMA = 17;
+
+        public const int AT_COMP_EQ = 18;
+
+        public const int AT_COMP_GT = 19;
+
+        public const int AT_COMP_GTE = 20;
+
+        public const int AT_COMP_LT = 21;
+
+        public const int AT_COMP_LTE = 22;
+
+        public const int AT_COMP_NEQ = 23;
+
+        public const int AT_COND_QUE = 24;
+
+        public const int AT_DIVIDE = 25;
+
+        public const int AT_DOT = 26;
+
+        public const int AT_LPAREN = 27;
+
+        public const int AT_MODULO = 28;
+
+        public const int AT_MULTIPLY = 29;
+
+        public const int AT_NEGATE = 30;
+
+        public const int AT_RPAREN = 31;
+
+        public const int AT_SUBTRACT = 32;
+
+        public const int DECIMAL = 33;
+
+        public const int DECIMALDIGIT = 34;
+
+        public const int DECIMALINTEGER = 35;
+
+        public const int EXPONENT = 36;
+
+        public const int HEX = 37;
+
+        public const int HEXDIGIT = 38;
+
+        public const int ID = 39;
+
+        public const int NAMESPACE_ID = 40;
+
+        public const int OCTAL = 41;
+
+        public const int OCTALDIGIT = 42;
+
+        public const int WS = 43;
+
+        // ANTLR GENERATED CODE: DO NOT EDIT
+        // delegates
+        public virtual Parser[] GetDelegates()
+        {
+            return new Parser[] { };
+        }
+
+        public JavascriptParser(CommonTokenStream input)
+            : this(input, new RecognizerSharedState())
+        {
+        }
+
+        public JavascriptParser(CommonTokenStream input, RecognizerSharedState state)
+            : base(input, state)
+        {
+        }
+
+        protected internal ITreeAdaptor adaptor = new CommonTreeAdaptor();
+
+        public virtual ITreeAdaptor TreeAdaptor
+        {
+            get { return adaptor; }
+            set { adaptor = value; }
+        }
+
+        // delegators
+
+
+        public override string[] TokenNames
+        {
+            get { return tokenNames; }
+        }
+
+        public override string GrammarFileName
+        {
+            get { return "src/java/org/apache/lucene/expressions/js/Javascript.g"; }
+        }
+
+        public override void DisplayRecognitionError(string[] tokenNames, RecognitionException re)
+        {
+            string message;
+            if (re.Token == null)
+            {
+                message = " unknown error (missing token).";
+            }
+            else
+            {
+                if (re is UnwantedTokenException)
+                {
+                    message = " extraneous " + GetReadableTokenString(re.Token) + " at position (" + re.CharPositionInLine + ").";
+                }
+                else
+                {
+                    if (re is MissingTokenException)
+                    {
+                        message = " missing " + GetReadableTokenString(re.Token) + " at position (" + re.CharPositionInLine + ").";
+                    }
+                    else
+                    {
+                        if (re is NoViableAltException)
+                        {
+                            switch (re.Token.Type)
+                            {
+                                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);
+
+            throw new SystemException(message);
+        }
+
+        public static string GetReadableTokenString(IToken token)
+        {
+            if (token == null)
+            {
+                return "unknown token";
+            }
+            switch (token.Type)
+            {
+                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 right '>>>'";
+                    }
+
+                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.Text + "'";
+                    }
+
+                case DECIMAL:
+                    {
+                        return "decimal '" + token.Text + "'";
+                    }
+
+                case OCTAL:
+                    {
+                        return "octal '" + token.Text + "'";
+                    }
+
+                case HEX:
+                    {
+                        return "hex '" + token.Text + "'";
+                    }
+
+                case EOF:
+                    {
+                        return "end of expression";
+                    }
+
+                default:
+                    {
+                        return "'" + token.Text + "'";
+                        break;
+                    }
+            }
+        }
+
+        internal class ExpressionReturn<TToken> : ParserRuleReturnScope<TToken>
+        {
+
+        }
+
+        // $ANTLR start "expression"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:250:1: expression : conditional EOF !;
+
+        public AstParserRuleReturnScope<ITree, IToken> Expression()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root = null;
+            IToken EOF2 = null;
+            AstParserRuleReturnScope<ITree, IToken> conditional1;
+            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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_conditional_in_expression737);
+                    conditional1 = Conditional();
+                    state._fsp--;
+                    adaptor.AddChild(root, conditional1.Tree);
+                    EOF2 = (IToken)Match(input, EOF, FOLLOW_EOF_in_expression739);
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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);
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $ANTLR start "conditional"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:254:1: conditional : logical_or ( AT_COND_QUE ^ conditional AT_COLON ! conditional )? ;
+        /// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+        public AstParserRuleReturnScope<ITree, IToken> Conditional()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root_0;
+            IToken AT_COND_QUE4;
+            IToken AT_COLON6 = null;
+            AstParserRuleReturnScope<ITree, IToken> logical_or3;
+            AstParserRuleReturnScope<ITree, IToken> conditional5;
+            AstParserRuleReturnScope<ITree, IToken> conditional7;
+            CommonTree AT_COND_QUE4_tree;
+            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.Tree);
+                    // 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 = (IToken)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.Tree);
+                                AT_COLON6 = (IToken)Match(input, AT_COLON, FOLLOW_AT_COLON_in_conditional765);
+                                PushFollow(FOLLOW_conditional_in_conditional768);
+                                conditional7 = Conditional();
+                                state._fsp--;
+                                adaptor.AddChild(root_0, conditional7.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);
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+        // $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 AstParserRuleReturnScope<ITree, IToken> Logical_or()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root_0;
+            IToken AT_BOOL_OR9;
+            AstParserRuleReturnScope<ITree, IToken> logical_and8;
+            AstParserRuleReturnScope<ITree, IToken> logical_and10;
+            CommonTree AT_BOOL_OR9_tree;
+            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.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:259:19: ( AT_BOOL_OR ^ logical_and )*
+                    while (true)
+                    {
+                        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 = (IToken)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.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop2_break;
+                                    break;
+                                }
+                        }
+                    loop2_continue: ;
+                    }
+                loop2_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);
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+
+        // $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 AstParserRuleReturnScope<ITree, IToken> Logical_and()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root;
+            IToken AT_BOOL_AND12;
+            AstParserRuleReturnScope<ITree, IToken> bitwise_or11;
+            AstParserRuleReturnScope<ITree, IToken> bitwise_or13;
+            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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_bitwise_or_in_logical_and812);
+                    bitwise_or11 = Bitwise_or();
+                    state._fsp--;
+                    adaptor.AddChild(root, bitwise_or11.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:263:18: ( AT_BOOL_AND ^ bitwise_or )*
+                    while (true)
+                    {
+                        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 = (IToken)Match(input, AT_BOOL_AND, FOLLOW_AT_BOOL_AND_in_logical_and815);
+                                    AT_BOOL_AND12_tree = (CommonTree)adaptor.Create(AT_BOOL_AND12);
+                                    root = (CommonTree)adaptor.BecomeRoot(AT_BOOL_AND12_tree, root);
+                                    PushFollow(FOLLOW_bitwise_or_in_logical_and818);
+                                    bitwise_or13 = Bitwise_or();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, bitwise_or13.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop3_break;
+                                    break;
+                                }
+                        }
+                    loop3_continue: ;
+                    }
+                loop3_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+        // $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 AstParserRuleReturnScope<ITree, IToken> Bitwise_or()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            try
+            {
+                CommonTree root = null;
+                {
+                    // 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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_bitwise_xor_in_bitwise_or837);
+                    AstParserRuleReturnScope<ITree, IToken> bitwise_xor14 = Bitwise_xor();
+                    state._fsp--;
+                    adaptor.AddChild(root, bitwise_xor14.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:267:19: ( AT_BIT_OR ^ bitwise_xor )*
+                    while (true)
+                    {
+                        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
+                                    IToken AT_BIT_OR15 = (IToken)Match(input, AT_BIT_OR, FOLLOW_AT_BIT_OR_in_bitwise_or840);
+                                    CommonTree AT_BIT_OR15_tree = (CommonTree)adaptor.Create(AT_BIT_OR15);
+                                    root = (CommonTree)adaptor.BecomeRoot(AT_BIT_OR15_tree, root);
+                                    PushFollow(FOLLOW_bitwise_xor_in_bitwise_or843);
+                                    AstParserRuleReturnScope<ITree, IToken> bitwise_xor16 = Bitwise_xor();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, bitwise_xor16.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop4_break;
+                                    break;
+                                }
+                        }
+                    loop4_continue: ;
+                    }
+                loop4_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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);
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+        // $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 AstParserRuleReturnScope<ITree, IToken> Bitwise_xor()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            try
+            {
+                CommonTree root = null;
+                {
+                    // 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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_bitwise_and_in_bitwise_xor862);
+                    AstParserRuleReturnScope<ITree, IToken> bitwise_and17 = Bitwise_and();
+                    state._fsp--;
+                    adaptor.AddChild(root, bitwise_and17.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:271:19: ( AT_BIT_XOR ^ bitwise_and )*
+                    while (true)
+                    {
+                        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
+                                    IToken AT_BIT_XOR18 = (IToken)Match(input, AT_BIT_XOR, FOLLOW_AT_BIT_XOR_in_bitwise_xor865
+                                        );
+                                    CommonTree AT_BIT_XOR18_tree = (CommonTree)adaptor.Create(AT_BIT_XOR18);
+                                    root = (CommonTree)adaptor.BecomeRoot(AT_BIT_XOR18_tree, root);
+                                    PushFollow(FOLLOW_bitwise_and_in_bitwise_xor868);
+                                    AstParserRuleReturnScope<ITree, IToken> bitwise_and19 = Bitwise_and();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, bitwise_and19.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop5_break;
+                                    break;
+                                }
+                        }
+                    loop5_continue: ;
+                    }
+                loop5_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $ANTLR start "bitwise_and"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:274:1: bitwise_and : equality ( AT_BIT_AND ^ equality )* ;
+
+        public AstParserRuleReturnScope<ITree, IToken> Bitwise_and()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            try
+            {
+                CommonTree root = null;
+                {
+                    // 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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_equality_in_bitwise_and888);
+                    AstParserRuleReturnScope<ITree, IToken> equality20 = Equality();
+                    state._fsp--;
+                    adaptor.AddChild(root, equality20.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:275:17: ( AT_BIT_AND ^ equality )*
+                    while (true)
+                    {
+                        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
+                                    IToken AT_BIT_AND21 = (IToken)Match(input, AT_BIT_AND, FOLLOW_AT_BIT_AND_in_bitwise_and891
+                                        );
+                                    CommonTree AT_BIT_AND21_tree = (CommonTree)adaptor.Create(AT_BIT_AND21);
+                                    root = (CommonTree)adaptor.BecomeRoot(AT_BIT_AND21_tree, root);
+                                    PushFollow(FOLLOW_equality_in_bitwise_and894);
+                                    AstParserRuleReturnScope<ITree, IToken> equality22 = Equality();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, equality22.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop6_break;
+                                    break;
+                                }
+                        }
+                    loop6_continue: ;
+                    }
+                loop6_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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);
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+        // $ANTLR start "equality"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:278:1: equality : relational ( ( AT_COMP_EQ | AT_COMP_NEQ ) ^ relational )* ;
+
+        public AstParserRuleReturnScope<ITree, IToken> Equality()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree set24_tree = null;
+            try
+            {
+                CommonTree root = null;
+                {
+                    // 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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_relational_in_equality913);
+                    AstParserRuleReturnScope<ITree, IToken> relational23 = Relational();
+                    state._fsp--;
+                    adaptor.AddChild(root, relational23.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:279:18: ( ( AT_COMP_EQ | AT_COMP_NEQ ) ^ relational )*
+                    while (true)
+                    {
+                        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
+                                    IToken set24 = input.LT(1);
+                                    set24 = input.LT(1);
+                                    if (input.LA(1) == AT_COMP_EQ || input.LA(1) == AT_COMP_NEQ)
+                                    {
+                                        input.Consume();
+                                        root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(set24), root
+                                            );
+                                        state.errorRecovery = false;
+                                    }
+                                    else
+                                    {
+                                        MismatchedSetException mse = new MismatchedSetException(null, input);
+                                        throw mse;
+                                    }
+                                    PushFollow(FOLLOW_relational_in_equality925);
+                                    AstParserRuleReturnScope<ITree, IToken> relational25 = Relational();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, relational25.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop7_break;
+                                    break;
+                                }
+                        }
+                    loop7_continue: ;
+                    }
+                loop7_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $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 AstParserRuleReturnScope<ITree, IToken> Relational()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree set27_tree = null;
+            try
+            {
+                CommonTree root = null;
+                {
+                    // 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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_shift_in_relational944);
+                    AstParserRuleReturnScope<ITree, IToken> shift26 = Shift();
+                    state._fsp--;
+                    adaptor.AddChild(root, shift26.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:283:13: ( ( AT_COMP_LT | AT_COMP_GT | AT_COMP_LTE | AT_COMP_GTE ) ^ shift )*
+                    while (true)
+                    {
+                        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
+                                    IToken set27 = input.LT(1);
+                                    set27 = input.LT(1);
+                                    if ((input.LA(1) >= AT_COMP_GT && input.LA(1) <= AT_COMP_LTE))
+                                    {
+                                        input.Consume();
+                                        root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(set27), root
+                                            );
+                                        state.errorRecovery = false;
+                                    }
+                                    else
+                                    {
+                                        MismatchedSetException mse = new MismatchedSetException(null, input);
+                                        throw mse;
+                                    }
+                                    PushFollow(FOLLOW_shift_in_relational964);
+                                    AstParserRuleReturnScope<ITree, IToken> shift28 = Shift();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, shift28.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop8_break;
+                                    break;
+                                }
+                        }
+                    loop8_continue: ;
+                    }
+                loop8_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $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 AstParserRuleReturnScope<ITree, IToken> Shift()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree set30_tree = null;
+            try
+            {
+                CommonTree root = null;
+                {
+                    // 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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_additive_in_shift983);
+                    AstParserRuleReturnScope<ITree, IToken> additive29 = Additive();
+                    state._fsp--;
+                    adaptor.AddChild(root, additive29.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:287:16: ( ( AT_BIT_SHL | AT_BIT_SHR | AT_BIT_SHU ) ^ additive )*
+                    while (true)
+                    {
+                        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
+                                    IToken set30 = input.LT(1);
+                                    set30 = input.LT(1);
+                                    if ((input.LA(1) >= AT_BIT_SHL && input.LA(1) <= AT_BIT_SHU))
+                                    {
+                                        input.Consume();
+                                        root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(set30), root
+                                            );
+                                        state.errorRecovery = false;
+                                    }
+                                    else
+                                    {
+                                        MismatchedSetException mse = new MismatchedSetException(null, input);
+                                        throw mse;
+                                    }
+                                    PushFollow(FOLLOW_additive_in_shift999);
+                                    AstParserRuleReturnScope<ITree, IToken> additive31 = Additive();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, additive31.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop9_break;
+                                    break;
+                                }
+                        }
+                    loop9_continue: ;
+                    }
+                loop9_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $ANTLR start "additive"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:290:1: additive : multiplicative ( ( AT_ADD | AT_SUBTRACT ) ^ multiplicative )* ;
+
+        public AstParserRuleReturnScope<ITree, IToken> Additive()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree set33_tree = null;
+            try
+            {
+                CommonTree root = null;
+                {
+                    // 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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_multiplicative_in_additive1018);
+                    AstParserRuleReturnScope<ITree, IToken> multiplicative32 = Multiplicative();
+                    state._fsp--;
+                    adaptor.AddChild(root, multiplicative32.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:291:22: ( ( AT_ADD | AT_SUBTRACT ) ^ multiplicative )*
+                    while (true)
+                    {
+                        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
+                                    IToken set33 = input.LT(1);
+                                    set33 = input.LT(1);
+                                    if (input.LA(1) == AT_ADD || input.LA(1) == AT_SUBTRACT)
+                                    {
+                                        input.Consume();
+                                        root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(set33), root
+                                            );
+                                        state.errorRecovery = false;
+                                    }
+                                    else
+                                    {
+                                        MismatchedSetException mse = new MismatchedSetException(null, input);
+                                        throw mse;
+                                    }
+                                    PushFollow(FOLLOW_multiplicative_in_additive1030);
+                                    AstParserRuleReturnScope<ITree, IToken> multiplicative34 = Multiplicative();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, multiplicative34.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop10_break;
+                                    break;
+                                }
+                        }
+                    loop10_continue: ;
+                    }
+                loop10_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+        // $ANTLR start "multiplicative"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:294:1: multiplicative : unary ( ( AT_MULTIPLY | AT_DIVIDE | AT_MODULO ) ^ unary )* ;
+
+        public AstParserRuleReturnScope<ITree, IToken> Multiplicative()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree set36_tree = null;
+            try
+            {
+                CommonTree root = null;
+                {
+                    // 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 = (CommonTree)adaptor.Nil();
+                    PushFollow(FOLLOW_unary_in_multiplicative1049);
+                    AstParserRuleReturnScope<ITree, IToken> unary35 = Unary();
+                    state._fsp--;
+                    adaptor.AddChild(root, unary35.Tree);
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:295:13: ( ( AT_MULTIPLY | AT_DIVIDE | AT_MODULO ) ^ unary )*
+                    while (true)
+                    {
+                        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
+                                    IToken set36 = input.LT(1);
+                                    set36 = input.LT(1);
+                                    if (input.LA(1) == AT_DIVIDE || (input.LA(1) >= AT_MODULO && input.LA(1) <= AT_MULTIPLY
+                                        ))
+                                    {
+                                        input.Consume();
+                                        root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(set36), root
+                                            );
+                                        state.errorRecovery = false;
+                                    }
+                                    else
+                                    {
+                                        MismatchedSetException mse = new MismatchedSetException(null, input);
+                                        throw mse;
+                                    }
+                                    PushFollow(FOLLOW_unary_in_multiplicative1065);
+                                    AstParserRuleReturnScope<ITree, IToken> unary37 = Unary();
+                                    state._fsp--;
+                                    adaptor.AddChild(root, unary37.Tree);
+                                    break;
+                                }
+
+                            default:
+                                {
+                                    goto loop11_break;
+                                    break;
+                                }
+                        }
+                    loop11_continue: ;
+                    }
+                loop11_break: ;
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $ANTLR start "unary"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:298:1: unary : ( postfix | AT_ADD ! unary | unary_operator ^ unary );
+
+        public AstParserRuleReturnScope<ITree, IToken> Unary()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root = 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 NAMESPACE_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(string.Empty, 12, 0, input);
+                            throw nvae;
+                        }
+                }
+                switch (alt12)
+                {
+                    case 1:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:299:7: postfix
+                            root = (CommonTree)adaptor.Nil();
+                            PushFollow(FOLLOW_postfix_in_unary1084);
+                            AstParserRuleReturnScope<ITree, IToken> postfix38 = Postfix();
+                            state._fsp--;
+                            adaptor.AddChild(root, postfix38.Tree);
+                            break;
+                        }
+
+                    case 2:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:300:7: AT_ADD ! unary
+                            root = (CommonTree)adaptor.Nil();
+                            IToken AT_ADD39 = (IToken)Match(input, AT_ADD, FOLLOW_AT_ADD_in_unary1092);
+                            PushFollow(FOLLOW_unary_in_unary1095);
+                            AstParserRuleReturnScope<ITree, IToken> unary40 = Unary();
+                            state._fsp--;
+                            adaptor.AddChild(root, unary40.Tree);
+                            break;
+                        }
+
+                    case 3:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:301:7: unary_operator ^ unary
+                            root = (CommonTree)adaptor.Nil();
+                            PushFollow(FOLLOW_unary_operator_in_unary1103);
+                            AstParserRuleReturnScope<ITree, IToken> unary_operator41 = Unary_operator();
+                            state._fsp--;
+                            root = (CommonTree)adaptor.BecomeRoot(unary_operator41.Tree, root);
+                            PushFollow(FOLLOW_unary_in_unary1106);
+                            AstParserRuleReturnScope<ITree, IToken> unary42 = Unary();
+                            state._fsp--;
+                            adaptor.AddChild(root, unary42.Tree);
+                            break;
+                        }
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $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 AstParserRuleReturnScope<ITree, IToken> Unary_operator()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root = null;
+            CommonTree AT_SUBTRACT43_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(string.Empty, 13, 0, input);
+                            throw nvae;
+                        }
+                }
+                switch (alt13)
+                {
+                    case 1:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:305:7: AT_SUBTRACT
+                            IToken AT_SUBTRACT43 = (IToken)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;
+                            RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval"
+                                , retval != null ? ((CommonTree)retval.Tree) : null);
+                            root = (CommonTree)adaptor.Nil();
+                            {
+                                // 305:19: -> AT_NEGATE
+                                adaptor.AddChild(root, (CommonTree)adaptor.Create(AT_NEGATE, "AT_NEGATE"));
+                            }
+                            retval.Tree = root;
+                            break;
+                        }
+
+                    case 2:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:306:7: AT_BIT_NOT
+                            root = (CommonTree)adaptor.Nil();
+                            IToken AT_BIT_NOT44 = (IToken)Match(input, AT_BIT_NOT, FOLLOW_AT_BIT_NOT_in_unary_operator1135
+                                );
+                            CommonTree AT_BIT_NOT44_tree = (CommonTree)adaptor.Create(AT_BIT_NOT44);
+                            adaptor.AddChild(root, AT_BIT_NOT44_tree);
+                            break;
+                        }
+
+                    case 3:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:307:7: AT_BOOL_NOT
+                            root = (CommonTree)adaptor.Nil();
+                            IToken AT_BOOL_NOT45 = (IToken)Match(input, AT_BOOL_NOT, FOLLOW_AT_BOOL_NOT_in_unary_operator1143
+                                );
+                            CommonTree AT_BOOL_NOT45_tree = (CommonTree)adaptor.Create(AT_BOOL_NOT45);
+                            adaptor.AddChild(root, AT_BOOL_NOT45_tree);
+                            break;
+                        }
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+        // $ANTLR start "postfix"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:310:1: postfix : ( primary | NAMESPACE_ID arguments -> ^( AT_CALL NAMESPACE_ID ( arguments )? ) );
+
+        public AstParserRuleReturnScope<ITree, IToken> Postfix()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root = null;
+            CommonTree NAMESPACE_ID47_tree = null;
+            var streamNamespaceId = new RewriteRuleTokenStream(adaptor, "token NAMESPACE_ID");
+            var streamArguments = new RewriteRuleSubtreeStream(adaptor, "rule arguments");
+            try
+            {
+                // src/java/org/apache/lucene/expressions/js/Javascript.g:311:5: ( primary | NAMESPACE_ID arguments -> ^( AT_CALL NAMESPACE_ID ( arguments )? ) )
+                int alt14 = 2;
+                int LA14_0 = input.LA(1);
+                if ((LA14_0 == NAMESPACE_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
+                        {
+                            int nvaeMark = input.Mark();
+                            try
+                            {
+                                input.Consume();
+                                NoViableAltException nvae = new NoViableAltException(string.Empty, 14, 1, input);
+                                throw nvae;
+                            }
+                            finally
+                            {
+                                input.Rewind(nvaeMark);
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    if ((LA14_0 == AT_LPAREN || LA14_0 == DECIMAL || LA14_0 == HEX || LA14_0 == OCTAL
+                        ))
+                    {
+                        alt14 = 1;
+                    }
+                    else
+                    {
+                        NoViableAltException nvae = new NoViableAltException(string.Empty, 14, 0, input);
+                        throw nvae;
+                    }
+                }
+                switch (alt14)
+                {
+                    case 1:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:311:7: primary
+                            root = (CommonTree)adaptor.Nil();
+                            PushFollow(FOLLOW_primary_in_postfix1160);
+                            AstParserRuleReturnScope<ITree, IToken> primary46 = Primary();
+                            state._fsp--;
+                            adaptor.AddChild(root, primary46.Tree);
+                            break;
+                        }
+
+                    case 2:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:312:7: NAMESPACE_ID arguments
+                            IToken NAMESPACE_ID47 = (IToken)Match(input, NAMESPACE_ID, FOLLOW_NAMESPACE_ID_in_postfix1168
+                                );
+                            streamNamespaceId.Add(NAMESPACE_ID47);
+                            PushFollow(FOLLOW_arguments_in_postfix1170);
+                            AstParserRuleReturnScope<ITree, IToken> arguments48 = Arguments();
+                            state._fsp--;
+                            streamArguments.Add(arguments48.Tree);
+                            // AST REWRITE
+                            // elements: NAMESPACE_ID, arguments
+                            // token labels: 
+                            // rule labels: retval
+                            // token list labels: 
+                            // rule list labels: 
+                            // wildcard labels: 
+                            retval.Tree = root;
+                            RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval"
+                                , retval != null ? ((CommonTree)retval.Tree) : null);
+                            root = (CommonTree)adaptor.Nil();
+                            {
+                                {
+                                    // 312:30: -> ^( AT_CALL NAMESPACE_ID ( arguments )? )
+                                    // src/java/org/apache/lucene/expressions/js/Javascript.g:312:33: ^( AT_CALL NAMESPACE_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, streamNamespaceId.NextNode());
+                                    // src/java/org/apache/lucene/expressions/js/Javascript.g:312:56: ( arguments )?
+                                    if (streamArguments.HasNext)
+                                    {
+                                        adaptor.AddChild(root_1, streamArguments.NextTree());
+                                    }
+                                    streamArguments.Reset();
+                                    adaptor.AddChild(root, root_1);
+                                }
+                            }
+                            retval.Tree = root;
+                            break;
+                        }
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $ANTLR start "primary"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:315:1: primary : ( NAMESPACE_ID | numeric | AT_LPAREN ! conditional AT_RPAREN !);
+
+        public AstParserRuleReturnScope<ITree, IToken> Primary()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root = null;
+            IToken AT_LPAREN51 = null;
+            IToken AT_RPAREN53 = null;
+            CommonTree NAMESPACE_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: ( NAMESPACE_ID | numeric | AT_LPAREN ! conditional AT_RPAREN !)
+                int alt15 = 3;
+                switch (input.LA(1))
+                {
+                    case NAMESPACE_ID:
+                        {
+                            alt15 = 1;
+                            break;
+                        }
+
+                    case DECIMAL:
+                    case HEX:
+                    case OCTAL:
+                        {
+                            alt15 = 2;
+                            break;
+                        }
+
+                    case AT_LPAREN:
+                        {
+                            alt15 = 3;
+                            break;
+                        }
+
+                    default:
+                        {
+                            NoViableAltException nvae = new NoViableAltException(string.Empty, 15, 0, input);
+                            throw nvae;
+                        }
+                }
+                switch (alt15)
+                {
+                    case 1:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:316:7: NAMESPACE_ID
+                            root = (CommonTree)adaptor.Nil();
+                            IToken NAMESPACE_ID49 = (IToken)Match(input, NAMESPACE_ID, FOLLOW_NAMESPACE_ID_in_primary1198
+                                );
+                            NAMESPACE_ID49_tree = (CommonTree)adaptor.Create(NAMESPACE_ID49);
+                            adaptor.AddChild(root, NAMESPACE_ID49_tree);
+                            break;
+                        }
+
+                    case 2:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:317:7: numeric
+                            root = (CommonTree)adaptor.Nil();
+                            PushFollow(FOLLOW_numeric_in_primary1206);
+                            AstParserRuleReturnScope<ITree, IToken> numeric50 = Numeric();
+                            state._fsp--;
+                            adaptor.AddChild(root, numeric50.Tree);
+                            break;
+                        }
+
+                    case 3:
+                        {
+                            // src/java/org/apache/lucene/expressions/js/Javascript.g:318:7: AT_LPAREN ! conditional AT_RPAREN !
+                            root = (CommonTree)adaptor.Nil();
+                            AT_LPAREN51 = (IToken)Match(input, AT_LPAREN, FOLLOW_AT_LPAREN_in_primary1214);
+                            PushFollow(FOLLOW_conditional_in_primary1217);
+                            AstParserRuleReturnScope<ITree, IToken> conditional52 = Conditional();
+                            state._fsp--;
+                            adaptor.AddChild(root, conditional52.Tree);
+                            AT_RPAREN53 = (IToken)Match(input, AT_RPAREN, FOLLOW_AT_RPAREN_in_primary1219);
+                            break;
+                        }
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+        // $ANTLR start "arguments"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:321:1: arguments : AT_LPAREN ! ( conditional ( AT_COMMA ! conditional )* )? AT_RPAREN !;
+
+        public AstParserRuleReturnScope<ITree, IToken> Arguments()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree root = null;
+            IToken AT_LPAREN54 = null;
+            IToken AT_COMMA56 = null;
+            IToken AT_RPAREN58 = 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 = (CommonTree)adaptor.Nil();
+                    AT_LPAREN54 = (IToken)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 >= NAMESPACE_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);
+                                AstParserRuleReturnScope<ITree, IToken> conditional55 = Conditional();
+                                state._fsp--;
+                                adaptor.AddChild(root, conditional55.Tree);
+                                // src/java/org/apache/lucene/expressions/js/Javascript.g:322:31: ( AT_COMMA ! conditional )*
+                                while (true)
+                                {
+                                    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 = (IToken)Match(input, AT_COMMA, FOLLOW_AT_COMMA_in_arguments1244);
+                                                PushFollow(FOLLOW_conditional_in_arguments1247);
+                                                AstParserRuleReturnScope<ITree, IToken> conditional57 = Conditional();
+                                                state._fsp--;
+                                                adaptor.AddChild(root, conditional57.Tree);
+                                                break;
+                                            }
+
+                                        default:
+                                            {
+                                                goto loop16_break;
+                                                break;
+                                            }
+                                    }
+                                loop16_continue: ;
+                                }
+                            loop16_break: ;
+                                break;
+                            }
+                    }
+                    AT_RPAREN58 = (IToken)Match(input, AT_RPAREN, FOLLOW_AT_RPAREN_in_arguments1253);
+                }
+                retval.Stop = input.LT(-1);
+                retval.Tree = (CommonTree)adaptor.RulePostProcessing(root);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+
+        // $ANTLR start "numeric"
+        // src/java/org/apache/lucene/expressions/js/Javascript.g:325:1: numeric : ( HEX | OCTAL | DECIMAL );
+
+        public AstParserRuleReturnScope<ITree, IToken> Numeric()
+        {
+            var retval = new AstParserRuleReturnScope<ITree, IToken> { Start = input.LT(1) };
+            CommonTree set59_tree = null;
+            try
+            {
+                CommonTree root = null;
+                {
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:326:5: ( HEX | OCTAL | DECIMAL )
+                    // src/java/org/apache/lucene/expressions/js/Javascript.g:
+                    root = (CommonTree)adaptor.Nil();
+                    IToken set59 = input.LT(1);
+                    if (input.LA(1) == DECIMAL || input.LA(1) == HEX || input.LA(1) == OCTAL)
+                    {
+                        input.Consume();
+                        adaptor.AddChild(root, (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);
+                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
+                    );
+            }
+            // do for sure before leaving
+            return retval;
+        }
+
+        public static readonly BitSet FOLLOW_conditional_in_expression737 = new BitSet(new[] { ((ulong)(0x0000000000000000L)) });
+
+        public static readonly BitSet FOLLOW_EOF_in_expression739 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_logical_or_in_conditional757 = new BitSet(new[] { ((ulong)(0x0000000001000002L)) });
+
+        public static readonly BitSet FOLLOW_AT_COND_QUE_in_conditional760 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_conditional_in_conditional763 = new BitSet(new[] { ((ulong)(0x0000000000010000L)) });
+
+        public static readonly BitSet FOLLOW_AT_COLON_in_conditional765 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_conditional_in_conditional768 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_logical_and_in_logical_or787 = new BitSet(new[] { ((ulong)(0x0000000000004002L)) });
+
+        public static readonly BitSet FOLLOW_AT_BOOL_OR_in_logical_or790 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_logical_and_in_logical_or793 = new BitSet(new[] { ((ulong)(0x0000000000004002L)) });
+
+        public static readonly BitSet FOLLOW_bitwise_or_in_logical_and812 = new BitSet(new[] { ((ulong)(0x0000000000001002L)) });
+
+        public static readonly BitSet FOLLOW_AT_BOOL_AND_in_logical_and815 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_bitwise_or_in_logical_and818 = new BitSet(new[] { ((ulong)(0x0000000000001002L)) });
+
+        public static readonly BitSet FOLLOW_bitwise_xor_in_bitwise_or837 = new BitSet(new[] { ((ulong)(0x0000000000000082L)) });
+
+        public static readonly BitSet FOLLOW_AT_BIT_OR_in_bitwise_or840 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_bitwise_xor_in_bitwise_or843 = new BitSet(new[] { ((ulong)(0x0000000000000082L)) });
+
+        public static readonly BitSet FOLLOW_bitwise_and_in_bitwise_xor862 = new BitSet(new[] { ((ulong)(0x0000000000000802L)) });
+
+        public static readonly BitSet FOLLOW_AT_BIT_XOR_in_bitwise_xor865 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_bitwise_and_in_bitwise_xor868 = new BitSet(new[] { ((ulong)(0x0000000000000802L)) });
+
+        public static readonly BitSet FOLLOW_equality_in_bitwise_and888 = new BitSet(new[] { ((ulong)(0x0000000000000022L)) });
+
+        public static readonly BitSet FOLLOW_AT_BIT_AND_in_bitwise_and891 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_equality_in_bitwise_and894 = new BitSet(new[] { ((ulong)(0x0000000000000022L)) });
+
+        public static readonly BitSet FOLLOW_relational_in_equality913 = new BitSet(new[] { ((ulong)(0x0000000000840002L)) });
+
+        public static readonly BitSet FOLLOW_set_in_equality916 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_relational_in_equality925 = new BitSet(new[] { ((ulong)(0x0000000000840002L)) });
+
+        public static readonly BitSet FOLLOW_shift_in_relational944 = new BitSet(new[] { ((ulong)(0x0000000000780002L)) });
+
+        public static readonly BitSet FOLLOW_set_in_relational947 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_shift_in_relational964 = new BitSet(new[] { ((ulong)(0x0000000000780002L)) });
+
+        public static readonly BitSet FOLLOW_additive_in_shift983 = new BitSet(new[] { ((ulong)(0x0000000000000702L)) });
+
+        public static readonly BitSet FOLLOW_set_in_shift986 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_additive_in_shift999 = new BitSet(new[] { ((ulong)(0x0000000000000702L)) });
+
+        public static readonly BitSet FOLLOW_multiplicative_in_additive1018 = new BitSet(new[] { ((ulong)(0x0000000100000012L)) });
+
+        public static readonly BitSet FOLLOW_set_in_additive1021 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_multiplicative_in_additive1030 = new BitSet(new[] { ((ulong)(0x0000000100000012L)) });
+
+        public static readonly BitSet FOLLOW_unary_in_multiplicative1049 = new BitSet(new[] { ((ulong)(0x0000000032000002L)) });
+
+        public static readonly BitSet FOLLOW_set_in_multiplicative1052 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_unary_in_multiplicative1065 = new BitSet(new[] { ((ulong)(0x0000000032000002L)) });
+
+        public static readonly BitSet FOLLOW_postfix_in_unary1084 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_AT_ADD_in_unary1092 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_unary_in_unary1095 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_unary_operator_in_unary1103 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_unary_in_unary1106 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_AT_SUBTRACT_in_unary_operator1123 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_AT_BIT_NOT_in_unary_operator1135 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_AT_BOOL_NOT_in_unary_operator1143 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_primary_in_postfix1160 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_NAMESPACE_ID_in_postfix1168 = new BitSet(new[] { ((ulong)(0x0000000008000000L)) });
+
+        public static readonly BitSet FOLLOW_arguments_in_postfix1170 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_NAMESPACE_ID_in_primary1198 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_numeric_in_primary1206 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_AT_LPAREN_in_primary1214 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_conditional_in_primary1217 = new BitSet(new[] { ((ulong)(0x0000000080000000L)) });
+
+        public static readonly BitSet FOLLOW_AT_RPAREN_in_primary1219 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+
+        public static readonly BitSet FOLLOW_AT_LPAREN_in_arguments1237 = new BitSet(new[] { ((ulong)(0x0000032388002050L)) });
+
+        public static readonly BitSet FOLLOW_conditional_in_arguments1241 = new BitSet(new[] { ((ulong)(0x0000000080020000L)) });
+
+        public static readonly BitSet FOLLOW_AT_COMMA_in_arguments1244 = new BitSet(new[] { ((ulong)(0x0000032308002050L)) });
+
+        public static readonly BitSet FOLLOW_conditional_in_arguments1247 = new BitSet(new[] { ((ulong)(0x0000000080020000L)) });
+
+        public static readonly BitSet FOLLOW_AT_RPAREN_in_arguments1253 = new BitSet(new[] { ((ulong)(0x0000000000000002L)) });
+        // $ANTLR end "numeric"
+        // Delegated rules
+    }
+
+
+}


[5/5] lucenenet git commit: Adding Expressions with some failing tests

Posted by sy...@apache.org.
Adding Expressions with some failing tests

Thanks to work by @hakeemsm

Closes #64


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/b6c1b5d2
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/b6c1b5d2
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/b6c1b5d2

Branch: refs/heads/master
Commit: b6c1b5d2e29185e167f37f6f86c711913fe6f0b5
Parents: 69f2911
Author: Itamar Syn-Hershko <it...@code972.com>
Authored: Sat Jan 31 22:03:24 2015 +0200
Committer: Itamar Syn-Hershko <it...@code972.com>
Committed: Sat Jan 31 22:03:24 2015 +0200

----------------------------------------------------------------------
 Lucene.Net.sln                                  |   26 +-
 src/Lucene.Net.Expressions/Bindings.cs          |   38 +
 src/Lucene.Net.Expressions/Expression.cs        |   98 +
 .../ExpressionComparator.cs                     |   94 +
 .../ExpressionFunctionValues.cs                 |   48 +
 .../ExpressionRescorer.cs                       |  120 +
 .../ExpressionSortField.cs                      |   86 +
 .../ExpressionValueSource.cs                    |  169 ++
 .../JS/JavascriptCompiler.cs                    |  749 ++++++
 .../JS/JavascriptLexer.cs                       | 2177 ++++++++++++++++++
 .../JS/JavascriptParser.cs                      | 1879 +++++++++++++++
 .../Lucene.Net.Expressions.csproj               |   92 +
 .../Properties/AssemblyInfo.cs                  |   36 +
 .../Properties/Settings.Designer.cs             |  323 +++
 .../Properties/Settings.settings                |   81 +
 .../ScoreFunctionValues.cs                      |   34 +
 src/Lucene.Net.Expressions/ScoreValueSource.cs  |   59 +
 src/Lucene.Net.Expressions/SimpleBindings.cs    |  130 ++
 src/Lucene.Net.Expressions/app.config           |   94 +
 src/Lucene.Net.Expressions/packages.config      |    4 +
 .../JS/TestCustomFunctions.cs                   |  262 +++
 .../JS/TestJavascriptCompiler.cs                |  187 ++
 .../JS/TestJavascriptFunction.cs                |  309 +++
 .../JS/TestJavascriptOperations.cs              |  373 +++
 .../Lucene.Net.Tests.Expressions.csproj         |   84 +
 .../Properties/AssemblyInfo.cs                  |   36 +
 .../TestDemoExpressions.cs                      |  202 ++
 .../TestExpressionRescorer.cs                   |   92 +
 .../TestExpressionSortField.cs                  |   92 +
 .../TestExpressionSorts.cs                      |  151 ++
 .../TestExpressionValidation.cs                 |  151 ++
 .../TestExpressionValueSource.cs                |  157 ++
 32 files changed, 8432 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/Lucene.Net.sln
----------------------------------------------------------------------
diff --git a/Lucene.Net.sln b/Lucene.Net.sln
index 02dee4a..8fe7746 100644
--- a/Lucene.Net.sln
+++ b/Lucene.Net.sln
@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
-VisualStudioVersion = 12.0.30110.0
+VisualStudioVersion = 12.0.30501.0
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net", "src\Lucene.Net.Core\Lucene.Net.csproj", "{5D4AD9BE-1FFB-41AB-9943-25737971BF57}"
 EndProject
@@ -28,6 +28,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Classifica
 		{69D7956C-C2CC-4708-B399-A188FEC384C4} = {69D7956C-C2CC-4708-B399-A188FEC384C4}
 	EndProjectSection
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Expressions", "src\Lucene.Net.Expressions\Lucene.Net.Expressions.csproj", "{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Expressions", "src\Lucene.Net.Tests.Expressions\Lucene.Net.Tests.Expressions.csproj", "{F4873D95-4300-4E83-AFFA-EF796495D0F0}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -119,6 +123,26 @@ Global
 		{866723F4-E3A4-47C5-A49F-9A68ADD4CFAE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 		{866723F4-E3A4-47C5-A49F-9A68ADD4CFAE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 		{866723F4-E3A4-47C5-A49F-9A68ADD4CFAE}.Release|x86.ActiveCfg = Release|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}.Release|x86.ActiveCfg = Release|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{F4873D95-4300-4E83-AFFA-EF796495D0F0}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Bindings.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Bindings.cs b/src/Lucene.Net.Expressions/Bindings.cs
new file mode 100644
index 0000000..c299f15
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Bindings.cs
@@ -0,0 +1,38 @@
+using Lucene.Net.Queries.Function;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>Binds variable names in expressions to actual data.</summary>
+	/// <remarks>
+	/// Binds variable names in expressions to actual data.
+	/// <p>
+	/// These are typically DocValues fields/FieldCache, the document's
+	/// relevance score, or other ValueSources.
+	/// </remarks>
+	/// <lucene.experimental></lucene.experimental>
+	public abstract class Bindings
+	{
+		/// <summary>Sole constructor.</summary>
+		/// <remarks>
+		/// Sole constructor. (For invocation by subclass
+		/// constructors, typically implicit.)
+		/// </remarks>
+		public Bindings()
+		{
+		}
+
+		/// <summary>Returns a ValueSource bound to the variable name.</summary>
+		
+		public abstract ValueSource GetValueSource(string name);
+
+		/// <summary>
+		/// Returns a
+		/// <code>ValueSource</code>
+		/// over relevance scores
+		/// </summary>
+		protected internal ValueSource GetScoreValueSource()
+		{
+			return new ScoreValueSource();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Expression.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Expression.cs b/src/Lucene.Net.Expressions/Expression.cs
new file mode 100644
index 0000000..cd33d92
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Expression.cs
@@ -0,0 +1,98 @@
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>Base class that computes the value of an expression for a document.</summary>
+	/// <remarks>
+	/// Base class that computes the value of an expression for a document.
+	/// <p>
+	/// Example usage:
+	/// <pre class="prettyprint">
+	/// // 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);
+	/// </pre>
+	/// </remarks>
+	/// <seealso cref="Lucene.Net.Expressions.JS.JavascriptCompiler.Compile(string)">Lucene.Net.Expressions.JS.JavascriptCompiler.Compile(string)</seealso>
+	/// <lucene.experimental></lucene.experimental>
+	public abstract class Expression
+	{
+		/// <summary>The original source text</summary>
+		public readonly string sourceText;
+
+		/// <summary>Named variables referred to by this expression</summary>
+		public readonly string[] variables;
+
+		/// <summary>
+		/// Creates a new
+		/// <code>Expression</code>
+		/// .
+		/// </summary>
+		/// <param name="sourceText">
+		/// Source text for the expression: e.g.
+		/// <code>ln(popularity)</code>
+		/// </param>
+		/// <param name="variables">
+		/// Names of external variables referred to by the expression
+		/// </param>
+		public Expression(string sourceText, string[] variables)
+		{
+			// javadocs
+			this.sourceText = sourceText;
+			this.variables = variables;
+		}
+
+		/// <summary>Evaluates the expression for the given document.</summary>
+		/// <remarks>Evaluates the expression for the given document.</remarks>
+		/// <param name="document"><code>docId</code> of the document to compute a value for</param>
+		/// <param name="functionValues">
+		/// 
+		/// <see cref="Lucene.Net.Queries.Function.FunctionValues">Lucene.Net.Queries.Function.FunctionValues
+		/// 	</see>
+		/// for each element of
+		/// <see cref="variables">variables</see>
+		/// .
+		/// </param>
+		/// <returns>The computed value of the expression for the given document.</returns>
+		public abstract double Evaluate(int document, FunctionValues[] functionValues);
+
+		/// <summary>Get a value source which can compute the value of this expression in the context of the given bindings.
+		/// 	</summary>
+		/// <remarks>Get a value source which can compute the value of this expression in the context of the given bindings.
+		/// 	</remarks>
+		/// <param name="bindings">Bindings to use for external values in this expression</param>
+		/// <returns>A value source which will evaluate this expression when used</returns>
+		public virtual ValueSource GetValueSource(Bindings bindings)
+		{
+			return new ExpressionValueSource(bindings, this);
+		}
+
+		/// <summary>Get a sort field which can be used to rank documents by this expression.
+		/// 	</summary>
+		/// <remarks>Get a sort field which can be used to rank documents by this expression.
+		/// 	</remarks>
+		public virtual SortField GetSortField(Bindings bindings, bool reverse)
+		{
+			return GetValueSource(bindings).GetSortField(reverse);
+		}
+
+		/// <summary>
+		/// Get a
+		/// <see cref="Lucene.Net.Search.Rescorer">Lucene.Net.Search.Rescorer</see>
+		/// , to rescore first-pass hits
+		/// using this expression.
+		/// </summary>
+		public virtual Rescorer GetRescorer(Bindings bindings)
+		{
+			return new ExpressionRescorer(this, bindings);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ExpressionComparator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ExpressionComparator.cs b/src/Lucene.Net.Expressions/ExpressionComparator.cs
new file mode 100644
index 0000000..2f67621
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ExpressionComparator.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using Lucene.Net.Index;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Search;
+using Lucene.Net.Support;
+
+namespace Lucene.Net.Expressions
+{
+    /// <summary>A custom comparator for sorting documents by an expression</summary>
+    internal class ExpressionComparator : FieldComparator<double>
+    {
+        private readonly double[] values;
+
+        private double bottom;
+
+        private double topValue;
+
+        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
+        public override Scorer Scorer
+        {
+            set
+            {
+                base.Scorer = value;
+                // TODO: might be cleaner to lazy-init 'source' and set scorer after?
+
+                Debug.Assert(readerContext != null);
+                var context = new Dictionary<string, object>();
+                Debug.Assert(value != null);
+                context["scorer"] = value;
+                scores = source.GetValues(context, readerContext);
+            }
+        }
+
+        public override int Compare(int slot1, int slot2)
+        {
+            return values[slot1].CompareTo(values[slot2]);
+        }
+
+        public override int Bottom
+        {
+            set { bottom = values[value]; }
+        }
+
+        public override object TopValue
+        {
+            set { topValue = (double)value; }
+        }
+
+
+        public override int CompareBottom(int doc)
+        {
+            return bottom.CompareTo(scores.DoubleVal(doc));
+        }
+
+
+        public override void Copy(int slot, int doc)
+        {
+            values[slot] = scores.DoubleVal(doc);
+        }
+
+
+        public override FieldComparator SetNextReader(AtomicReaderContext context)
+        {
+            this.readerContext = context;
+            return this;
+        }
+
+        public override IComparable Value(int slot)
+        {
+            return (values[slot]);
+        }
+
+
+        public override int CompareTop(int doc)
+        {
+            return topValue.CompareTo(scores.DoubleVal(doc));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ExpressionFunctionValues.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ExpressionFunctionValues.cs b/src/Lucene.Net.Expressions/ExpressionFunctionValues.cs
new file mode 100644
index 0000000..63b8f67
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ExpressionFunctionValues.cs
@@ -0,0 +1,48 @@
+using System;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Queries.Function.DocValues;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>
+	/// A
+	/// <see cref="Lucene.Net.Queries.Function.FunctionValues">Lucene.Net.Queries.Function.FunctionValues
+	/// 	</see>
+	/// which evaluates an expression
+	/// </summary>
+	internal class ExpressionFunctionValues : DoubleDocValues
+	{
+		internal readonly Expression expression;
+
+		internal readonly FunctionValues[] functionValues;
+
+		internal int currentDocument = -1;
+
+		internal double currentValue;
+
+		internal ExpressionFunctionValues(ValueSource parent, Expression expression, FunctionValues
+			[] functionValues) : base(parent)
+		{
+			if (expression == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (functionValues == null)
+			{
+				throw new ArgumentNullException();
+			}
+			this.expression = expression;
+			this.functionValues = functionValues;
+		}
+
+		public override double DoubleVal(int document)
+		{
+			if (currentDocument != document)
+			{
+				currentDocument = document;
+				currentValue = expression.Evaluate(document, functionValues);
+			}
+			return currentValue;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ExpressionRescorer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ExpressionRescorer.cs b/src/Lucene.Net.Expressions/ExpressionRescorer.cs
new file mode 100644
index 0000000..8d0fd7e
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ExpressionRescorer.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+    /// <summary>
+    /// A
+    /// <see cref="Lucene.Net.Search.Rescorer">Lucene.Net.Search.Rescorer</see>
+    /// that uses an expression to re-score
+    /// first pass hits.  Functionally this is the same as
+    /// <see cref="Lucene.Net.Search.SortRescorer">Lucene.Net.Search.SortRescorer
+    /// 	</see>
+    /// (if you build the
+    /// <see cref="Lucene.Net.Search.Sort">Lucene.Net.Search.Sort</see>
+    /// using
+    /// <see cref="Expression.GetSortField(Bindings, bool)">Expression.GetSortField(Bindings, bool)
+    /// 	</see>
+    /// ), except for the explain method
+    /// which gives more detail by showing the value of each
+    /// variable.
+    /// </summary>
+    /// <lucene.experimental></lucene.experimental>
+    internal class ExpressionRescorer : SortRescorer
+    {
+        private readonly Expression expression;
+
+        private readonly Bindings bindings;
+
+        /// <summary>
+        /// Uses the provided
+        /// <see cref="Lucene.Net.Queries.Function.ValueSource">Lucene.Net.Queries.Function.ValueSource
+        /// 	</see>
+        /// to assign second
+        /// pass scores.
+        /// </summary>
+        public ExpressionRescorer(Expression expression, Bindings bindings)
+            : base(new Sort
+                (expression.GetSortField(bindings, true)))
+        {
+            this.expression = expression;
+            this.bindings = bindings;
+        }
+
+        private class FakeScorer : Scorer
+        {
+            internal float score;
+
+            internal int doc = -1;
+
+            internal int freq = 1;
+
+            public FakeScorer()
+                : base(null)
+            {
+            }
+
+            public override int Advance(int target)
+            {
+                throw new NotSupportedException("FakeScorer doesn't support advance(int)");
+            }
+
+            public override int DocID()
+            {
+                return doc;
+            }
+
+            public override int Freq()
+            {
+                return freq;
+            }
+
+            public override int NextDoc()
+            {
+                throw new NotSupportedException("FakeScorer doesn't support nextDoc()");
+            }
+
+            public override float Score()
+            {
+                return score;
+            }
+
+            public override long Cost()
+            {
+                return 1;
+            }
+
+            public override Weight Weight
+            {
+                get { throw new NotSupportedException(); }
+            }
+
+            public override ICollection<Scorer.ChildScorer> Children
+            {
+                get { throw new NotSupportedException(); }
+            }
+        }
+
+
+        public override Explanation Explain(IndexSearcher searcher, Explanation firstPassExplanation, int docID)
+        {
+            Explanation result = base.Explain(searcher, firstPassExplanation, docID);
+            IList<AtomicReaderContext> leaves = searcher.IndexReader.Leaves;
+            int subReader = ReaderUtil.SubIndex(docID, leaves);
+            AtomicReaderContext readerContext = leaves[subReader];
+            int docIDInSegment = docID - readerContext.DocBase;
+            var context = new Dictionary<string, object>();
+            var fakeScorer = new FakeScorer { score = firstPassExplanation.Value, doc = docIDInSegment };
+            context["scorer"] = fakeScorer;
+            foreach (string variable in expression.variables)
+            {
+                result.AddDetail(new Explanation((float)bindings.GetValueSource(variable).GetValues
+                    (context, readerContext).DoubleVal(docIDInSegment), "variable \"" + variable + "\""
+                    ));
+            }
+            return result;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ExpressionSortField.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ExpressionSortField.cs b/src/Lucene.Net.Expressions/ExpressionSortField.cs
new file mode 100644
index 0000000..e7ca2ea
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ExpressionSortField.cs
@@ -0,0 +1,86 @@
+using System.Text;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>
+	/// A
+	/// <see cref="Lucene.Net.Search.SortField">Lucene.Net.Search.SortField
+	/// 	</see>
+	/// which sorts documents by the evaluated value of an expression for each document
+	/// </summary>
+	internal class ExpressionSortField : SortField
+	{
+		private readonly ExpressionValueSource source;
+
+		internal ExpressionSortField(string name, ExpressionValueSource source, bool reverse
+			) : base(name, Type_e.CUSTOM, reverse)
+		{
+			this.source = source;
+		}
+
+		
+		public override FieldComparator GetComparator(int numHits, int sortPos)
+		{
+			return new ExpressionComparator(source, numHits);
+		}
+
+		public override int GetHashCode()
+		{
+			int prime = 31;
+			int result = base.GetHashCode();
+			result = prime * result + ((source == null) ? 0 : source.GetHashCode());
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (!base.Equals(obj))
+			{
+				return false;
+			}
+			if (GetType() != obj.GetType())
+			{
+				return false;
+			}
+			ExpressionSortField other = (ExpressionSortField)obj;
+			if (source == null)
+			{
+				if (other.source != null)
+				{
+					return false;
+				}
+			}
+			else
+			{
+				if (!source.Equals(other.source))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+
+		public override string ToString()
+		{
+			StringBuilder buffer = new StringBuilder();
+			buffer.Append("<expr \"");
+			buffer.Append(Field);
+			buffer.Append("\">");
+			if (Reverse)
+			{
+				buffer.Append('!');
+			}
+			return buffer.ToString();
+		}
+
+		public override bool NeedsScores()
+		{
+			return source.NeedsScores();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ExpressionValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ExpressionValueSource.cs b/src/Lucene.Net.Expressions/ExpressionValueSource.cs
new file mode 100644
index 0000000..e4501a9
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ExpressionValueSource.cs
@@ -0,0 +1,169 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Lucene.Net.Index;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Search;
+using Lucene.Net.Support;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>
+	/// A
+	/// <see cref="Lucene.Net.Queries.Function.ValueSource">Lucene.Net.Queries.Function.ValueSource
+	/// 	</see>
+	/// which evaluates a
+	/// <see cref="Expression">Expression</see>
+	/// given the context of an
+	/// <see cref="Bindings">Bindings</see>
+	/// .
+	/// </summary>
+	internal sealed class ExpressionValueSource : ValueSource
+	{
+		internal readonly ValueSource[] variables;
+
+		internal readonly Expression expression;
+
+		internal readonly bool needsScores;
+
+		internal ExpressionValueSource(Bindings bindings, Expression expression)
+		{
+			if (bindings == null)
+			{
+				throw new ArgumentNullException();
+			}
+			if (expression == null)
+			{
+				throw new ArgumentNullException();
+			}
+			this.expression = expression;
+			variables = new ValueSource[expression.variables.Length];
+			bool needsScores = false;
+			for (int i = 0; i < variables.Length; i++)
+			{
+				ValueSource source = bindings.GetValueSource(expression.variables[i]);
+				if (source is ScoreValueSource)
+				{
+					needsScores = true;
+				}
+				else
+				{
+				    var valueSource = source as ExpressionValueSource;
+				    if (valueSource != null)
+					{
+						if (valueSource.NeedsScores())
+						{
+							needsScores = true;
+						}
+					}
+					else
+					{
+						if (source == null)
+						{
+							throw new SystemException("Internal error. Variable (" + expression.variables[i]
+								 + ") does not exist.");
+						}
+					}
+				}
+			    variables[i] = source;
+			}
+			this.needsScores = needsScores;
+		}
+
+		
+		public override FunctionValues GetValues(IDictionary context, AtomicReaderContext
+			 readerContext)
+		{
+			IDictionary<string, FunctionValues> valuesCache = (IDictionary<string, FunctionValues>)context["valuesCache"];
+			if (valuesCache == null)
+			{
+				valuesCache = new Dictionary<string, FunctionValues>();
+				context = new Hashtable(context);
+				context["valuesCache"] = valuesCache;
+			}
+			FunctionValues[] externalValues = new FunctionValues[expression.variables.Length];
+			for (int i = 0; i < variables.Length; ++i)
+			{
+				string externalName = expression.variables[i];
+				FunctionValues values;
+				if (!valuesCache.TryGetValue(externalName,out values))
+				{
+					values = variables[i].GetValues(context, readerContext);
+					if (values == null)
+					{
+						throw new SystemException("Internal error. External (" + externalName + ") does not exist.");
+					}
+					valuesCache[externalName] = values;
+				}
+				externalValues[i] = values;
+			}
+			return new ExpressionFunctionValues(this, expression, externalValues);
+		}
+
+		public override SortField GetSortField(bool reverse)
+		{
+			return new ExpressionSortField(expression.sourceText, this, reverse);
+		}
+
+		public override string Description
+		{
+		    get { return "expr(" + expression.sourceText + ")"; }
+		}
+
+		public override int GetHashCode()
+		{
+			int prime = 31;
+			int result = 1;
+			result = prime * result + ((expression == null) ? 0 : expression.GetHashCode());
+			result = prime * result + (needsScores ? 1231 : 1237);
+			result = prime * result + Arrays.GetHashCode(variables);
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (obj == null)
+			{
+				return false;
+			}
+			if (GetType() != obj.GetType())
+			{
+				return false;
+			}
+			Lucene.Net.Expressions.ExpressionValueSource other = (Lucene.Net.Expressions.ExpressionValueSource
+				)obj;
+			if (expression == null)
+			{
+				if (other.expression != null)
+				{
+					return false;
+				}
+			}
+			else
+			{
+				if (!expression.Equals(other.expression))
+				{
+					return false;
+				}
+			}
+			if (needsScores != other.needsScores)
+			{
+				return false;
+			}
+			if (!Arrays.Equals(variables, other.variables))
+			{
+				return false;
+			}
+			return true;
+		}
+
+		internal bool NeedsScores()
+		{
+			return needsScores;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs
new file mode 100644
index 0000000..cda3042
--- /dev/null
+++ b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs
@@ -0,0 +1,749 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Configuration;
+using System.Diagnostics;
+using System.Diagnostics.SymbolStore;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Security.AccessControl;
+using Antlr.Runtime;
+using Antlr.Runtime.Tree;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Support;
+
+namespace Lucene.Net.Expressions.JS
+{
+    /// <summary>An expression compiler for javascript expressions.</summary>
+    /// <remarks>
+    /// An expression compiler for javascript expressions.
+    /// <p>
+    /// Example:
+    /// <pre class="prettyprint">
+    /// Expression foo = JavascriptCompiler.compile("((0.3*popularity)/10.0)+(0.7*score)");
+    /// </pre>
+    /// <p>
+    /// See the
+    /// <see cref="Lucene.Net.Expressions.JS">package documentation</see>
+    /// for
+    /// the supported syntax and default functions.
+    /// <p>
+    /// You can compile with an alternate set of functions via
+    /// <see cref="Compile(string, System.Collections.Generic.IDictionary{K, V})
+    /// 	">Compile(string, System.Collections.Generic.IDictionary&lt;K, V&gt;)
+    /// 	</see>
+    /// .
+    /// For example:
+    /// <pre class="prettyprint">
+    /// Map&lt;String,Method&gt; functions = new HashMap&lt;String,Method&gt;();
+    /// // add all the default functions
+    /// functions.putAll(JavascriptCompiler.DEFAULT_FUNCTIONS);
+    /// // add cbrt()
+    /// functions.put("cbrt", Math.class.getMethod("cbrt", double.class));
+    /// // call compile with customized function map
+    /// Expression foo = JavascriptCompiler.compile("cbrt(score)+ln(popularity)",
+    /// functions,
+    /// getClass().getClassLoader());
+    /// </pre>
+    /// </remarks>
+    /// <lucene.experimental></lucene.experimental>
+    public class JavascriptCompiler
+    {
+
+        private static readonly string COMPILED_EXPRESSION_CLASS = typeof(Expression).Namespace + ".CompiledExpression";
+
+        private static readonly string COMPILED_EXPRESSION_INTERNAL = COMPILED_EXPRESSION_CLASS.Replace('.', '/');
+
+        private static readonly Type EXPRESSION_TYPE = Type.GetType(typeof(Expression).FullName);
+
+        private static readonly Type FUNCTION_VALUES_TYPE = typeof(FunctionValues);
+
+        private static readonly ConstructorInfo EXPRESSION_CTOR = typeof(Expression).
+            GetConstructor(new Type[] { typeof(String), typeof(String[]) });
+
+        private static readonly MethodInfo EVALUATE_METHOD = GetMethod(EXPRESSION_TYPE, "Evaluate",
+            new[] { typeof(int), typeof(FunctionValues[]) });
+
+        private static readonly MethodInfo DOUBLE_VAL_METHOD = GetMethod(FUNCTION_VALUES_TYPE, "DoubleVal",
+            new[] { typeof(int) });
+
+
+        // We use the same class name for all generated classes as they all have their own class loader.
+        // The source code is displayed as "source file name" in stack trace.
+        // to work around import clash:
+        private static MethodInfo GetMethod(Type type, string method, Type[] parms)
+        {
+            return type.GetMethod(method, parms);
+        }
+
+        private const int MAX_SOURCE_LENGTH = 16384;
+
+        private readonly string sourceText;
+
+        private readonly IDictionary<string, int> externalsMap = new HashMap<string, int>();
+
+
+
+        private TypeBuilder dynamicType;
+
+        private readonly IDictionary<string, MethodInfo> functions;
+
+        /// <summary>The default set of functions available to expressions.</summary>
+        /// <remarks>
+        /// The default set of functions available to expressions.
+        /// <p>
+        /// See the
+        /// <see cref="Lucene.Net.Expressions.JS">package documentation</see>
+        /// for a list.
+        /// </remarks>
+        public static readonly IDictionary<string, MethodInfo> DEFAULT_FUNCTIONS;
+
+        private ILGenerator gen;
+        private AssemblyBuilder asmBuilder;
+        private string fileName;
+        private ISymbolDocumentWriter debugDoc;
+        private int lineNum = 1;
+        private StreamWriter file;
+        private MethodBuilder evalMethod;
+        private bool negate;
+
+        // This maximum length is theoretically 65535 bytes, but as its CESU-8 encoded we dont know how large it is in bytes, so be safe
+        // rcmuir: "If your ranking function is that large you need to check yourself into a mental institution!"
+        /// <summary>Compiles the given expression.</summary>
+        /// <remarks>Compiles the given expression.</remarks>
+        /// <param name="sourceText">The expression to compile</param>
+        /// <returns>A new compiled expression</returns>
+
+        public static Expression Compile(string sourceText)
+        {
+            return new JavascriptCompiler(sourceText).CompileExpression();
+        }
+
+        /// <summary>Compiles the given expression with the supplied custom functions.</summary>
+        /// <remarks>
+        /// Compiles the given expression with the supplied custom functions.
+        /// <p>
+        /// Functions must be
+        /// <code>public static</code>
+        /// , return
+        /// <code>double</code>
+        /// and
+        /// can take from zero to 256
+        /// <code>double</code>
+        /// parameters.
+        /// </remarks>
+        /// <param name="sourceText">The expression to compile</param>
+        /// <param name="functions">map of String names to functions</param>
+        /// <param name="parent">
+        /// a
+        /// <code>ClassLoader</code>
+        /// that should be used as the parent of the loaded class.
+        /// It must contain all classes referred to by the given
+        /// <code>functions</code>
+        /// .
+        /// </param>
+        /// <returns>A new compiled expression</returns>
+
+        public static Expression Compile(string sourceText, IDictionary<string, MethodInfo> functions)
+        {
+
+            foreach (MethodInfo m in functions.Values)
+            {
+                CheckFunction(m);
+            }
+            return new JavascriptCompiler(sourceText, functions).CompileExpression();
+        }
+
+        /// <summary>This method is unused, it is just here to make sure that the function signatures don't change.
+        /// 	</summary>
+        /// <remarks>
+        /// This method is unused, it is just here to make sure that the function signatures don't change.
+        /// If this method fails to compile, you also have to change the byte code generator to correctly
+        /// use the FunctionValues class.
+        /// </remarks>
+        private static void UnusedTestCompile()
+        {
+            FunctionValues f = null;
+            double ret = f.DoubleVal(2);
+        }
+
+        /// <summary>Constructs a compiler for expressions.</summary>
+
+        /// <param name="sourceText">The expression to compile</param>
+        private JavascriptCompiler(string sourceText)
+            : this(sourceText, DEFAULT_FUNCTIONS
+                )
+        {
+        }
+
+        /// <summary>Constructs a compiler for expressions with specific set of functions</summary>
+        /// <param name="sourceText">The expression to compile</param>
+        private JavascriptCompiler(string sourceText, IDictionary<string, MethodInfo> functions
+            )
+        {
+            if (sourceText == null)
+            {
+                throw new ArgumentNullException();
+            }
+            this.sourceText = sourceText;
+            this.functions = functions;
+        }
+
+        /// <summary>Compiles the given expression with the specified parent classloader</summary>
+        /// <returns>A new compiled expression</returns>
+
+        private Expression CompileExpression()
+        {
+            try
+            {
+
+                ITree antlrTree = GetAntlrComputedExpressionTree();
+                BeginCompile();
+                RecursiveCompile(antlrTree, typeof(double));
+                EndCompile();
+                return
+                    (Expression)
+                        Activator.CreateInstance(dynamicType.CreateType(), sourceText, externalsMap.Keys.ToArray());
+
+            }
+
+            catch (MemberAccessException exception)
+            {
+                throw new InvalidOperationException("An internal error occurred attempting to compile the expression ("
+                                                    + sourceText + ").", exception);
+            }
+            catch (TargetInvocationException exception)
+            {
+                throw new InvalidOperationException("An internal error occurred attempting to compile the expression ("
+                                                    + sourceText + ").", exception);
+            }
+        }
+
+        private void BeginCompile()
+        {
+            var assemblyName = new AssemblyName("Lucene.Net.Expressions.Dynamic" + new Random().Next());
+            asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect);
+
+            ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(assemblyName.Name + ".dll");
+            dynamicType = modBuilder.DefineType(COMPILED_EXPRESSION_CLASS,
+                TypeAttributes.AnsiClass | TypeAttributes.AutoClass | TypeAttributes.Public | TypeAttributes.Class |
+                TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, EXPRESSION_TYPE);
+
+
+            ConstructorBuilder constructorBuilder = dynamicType.DefineConstructor(MethodAttributes.Public,
+                CallingConventions.HasThis,
+                new[] { typeof(string), typeof(string[]) });
+
+            ILGenerator ctorGen = constructorBuilder.GetILGenerator();
+            ctorGen.Emit(OpCodes.Ldarg_0);
+            ctorGen.Emit(OpCodes.Ldarg_1);
+            ctorGen.Emit(OpCodes.Ldarg_2);
+            ctorGen.Emit(OpCodes.Call, EXPRESSION_CTOR);
+            ctorGen.Emit(OpCodes.Nop);
+            ctorGen.Emit(OpCodes.Nop);
+            ctorGen.Emit(OpCodes.Ret);
+
+            evalMethod = dynamicType.DefineMethod("Evaluate", MethodAttributes.Public | MethodAttributes.Virtual,
+                typeof(double), new[] { typeof(int), typeof(FunctionValues[]) });
+            gen = evalMethod.GetILGenerator();
+        }
+
+        private void RecursiveCompile(ITree current, Type expected)
+        {
+            int type = current.Type;
+            string text = current.Text;
+
+
+            switch (type)
+            {
+                case JavascriptParser.AT_CALL:
+                    {
+                        ITree identifier = current.GetChild(0);
+                        string call = identifier.Text;
+                        int arguments = current.ChildCount - 1;
+                        MethodInfo method = functions[call];
+                        if (method == null)
+                        {
+                            throw new ArgumentException("Unrecognized method call (" + call + ").");
+                        }
+                        int arity = method.GetParameters().Length;
+                        if (arguments != arity)
+                        {
+                            throw new ArgumentException("Expected (" + arity + ") arguments for method call ("
+                                                        + call + "), but found (" + arguments + ").");
+                        }
+                        for (int argument = 1; argument <= arguments; ++argument)
+                        {
+                            RecursiveCompile(current.GetChild(argument), typeof(double));
+                        }
+                        gen.Emit(OpCodes.Call, method);
+
+
+
+                        break;
+                    }
+
+                case JavascriptParser.NAMESPACE_ID:
+                    {
+                        int index;
+                        if (externalsMap.ContainsKey(text))
+                        {
+                            index = externalsMap[text];
+                        }
+                        else
+                        {
+                            index = externalsMap.Count;
+                            externalsMap[text] = index;
+                        }
+                        gen.Emit(OpCodes.Nop);
+
+                        gen.Emit(OpCodes.Ldarg_2);
+                        gen.Emit(OpCodes.Ldc_I4, index);
+
+                        gen.Emit(OpCodes.Ldelem_Ref);
+                        gen.Emit(OpCodes.Ldarg_1);
+                        gen.Emit(OpCodes.Callvirt, DOUBLE_VAL_METHOD);
+
+
+                        break;
+                    }
+
+                case JavascriptParser.HEX:
+                    {
+                        PushLong(expected, Convert.ToInt64(text.Substring(2), 16));
+                        break;
+                    }
+
+                case JavascriptParser.OCTAL:
+                    {
+                        PushLong(expected, Convert.ToInt64(text.Substring(2), 8));
+                        break;
+                    }
+
+                case JavascriptParser.DECIMAL:
+                    {
+                        gen.Emit(OpCodes.Ldc_R8, double.Parse(text));
+                        if (negate)
+                        {
+                            gen.Emit(OpCodes.Neg);
+                            negate = false;
+                        }
+                        break;
+                    }
+
+                case JavascriptParser.AT_NEGATE:
+                    {
+                        negate = true;
+                        RecursiveCompile(current.GetChild(0), typeof(double));
+
+                        break;
+                    }
+
+                case JavascriptParser.AT_ADD:
+                    {
+                        PushArith(OpCodes.Add, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_SUBTRACT:
+                    {
+                        PushArith(OpCodes.Sub, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_MULTIPLY:
+                    {
+                        PushArith(OpCodes.Mul, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_DIVIDE:
+                    {
+                        PushArith(OpCodes.Div, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_MODULO:
+                    {
+                        PushArith(OpCodes.Rem, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_BIT_SHL:
+                    {
+                        PushShift(OpCodes.Shl, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_BIT_SHR:
+                    {
+                        PushShift(OpCodes.Shr, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_BIT_SHU:
+                    {
+                        PushShift(OpCodes.Shr_Un, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_BIT_AND:
+                    {
+                        PushBitwise(OpCodes.And, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_BIT_OR:
+                    {
+                        PushBitwise(OpCodes.Or, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_BIT_XOR:
+                    {
+                        PushBitwise(OpCodes.Xor, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_BIT_NOT:
+                    {
+                        RecursiveCompile(current.GetChild(0), typeof(long));
+                        gen.Emit(OpCodes.Ldc_I4_M1);
+                        //dynamicType.Push(-1L);
+                        //dynamicType.VisitInsn(Opcodes.LXOR);
+                        //dynamicType.Cast(typeof(long), expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_COMP_EQ:
+                    {
+                        PushCond(OpCodes.Ceq, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_COMP_NEQ:
+                    {
+                        //PushCond(OpCodes, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_COMP_LT:
+                    {
+                        PushCond(OpCodes.Clt, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_COMP_GT:
+                    {
+                        PushCond(OpCodes.Cgt, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_COMP_LTE:
+                    {
+                        //PushCond(OpCodes.Clt | OpCodes.Ceq, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_COMP_GTE:
+                    {
+                        //PushCond(GeneratorAdapter.GE, current, expected);
+                        break;
+                    }
+
+                case JavascriptParser.AT_BOOL_NOT:
+                    {
+                        /*Label labelNotTrue = new Label();
+					Label labelNotReturn = new Label();
+					RecursiveCompile(current.GetChild(0), Type.INT_TYPE);
+					dynamicType.VisitJumpInsn(Opcodes.IFEQ, labelNotTrue);
+					PushBoolean(expected, false);
+					dynamicType.GoTo(labelNotReturn);
+					dynamicType.VisitLabel(labelNotTrue);
+					PushBoolean(expected, true);
+					dynamicType.VisitLabel(labelNotReturn);*/
+                        break;
+                    }
+
+                case JavascriptParser.AT_BOOL_AND:
+                    {
+                        /*Label andFalse = new Label();
+					Label andEnd = new Label();
+					RecursiveCompile(current.GetChild(0), Type.INT_TYPE);
+					dynamicType.VisitJumpInsn(Opcodes.IFEQ, andFalse);
+					RecursiveCompile(current.GetChild(1), Type.INT_TYPE);
+					dynamicType.VisitJumpInsn(Opcodes.IFEQ, andFalse);
+					PushBoolean(expected, true);
+					dynamicType.GoTo(andEnd);
+					dynamicType.VisitLabel(andFalse);
+					PushBoolean(expected, false);
+					dynamicType.VisitLabel(andEnd);*/
+                        break;
+                    }
+
+                case JavascriptParser.AT_BOOL_OR:
+                    {
+                        Label orTrue = new Label();
+                        Label orEnd = new Label();
+                        /*RecursiveCompile(current.GetChild(0), Type.INT_TYPE);
+					dynamicType.VisitJumpInsn(Opcodes.IFNE, orTrue);
+					RecursiveCompile(current.GetChild(1), Type.INT_TYPE);
+					dynamicType.VisitJumpInsn(Opcodes.IFNE, orTrue);
+					PushBoolean(expected, false);
+					dynamicType.GoTo(orEnd);
+					dynamicType.VisitLabel(orTrue);
+					PushBoolean(expected, true);
+					dynamicType.VisitLabel(orEnd);*/
+                        break;
+                    }
+
+                case JavascriptParser.AT_COND_QUE:
+                    {
+                        /*Label condFalse = new Label();
+					Label condEnd = new Label();
+					RecursiveCompile(current.GetChild(0), Type.INT_TYPE);
+					dynamicType.VisitJumpInsn(Opcodes.IFEQ, condFalse);
+					RecursiveCompile(current.GetChild(1), expected);
+					dynamicType.GoTo(condEnd);
+					dynamicType.VisitLabel(condFalse);
+					RecursiveCompile(current.GetChild(2), expected);
+					dynamicType.VisitLabel(condEnd);*/
+                        break;
+                    }
+
+                default:
+                    {
+                        throw new InvalidOperationException("Unknown operation specified: (" + current.Text + ").");
+                    }
+            }
+
+        }
+
+        private void PushArith(OpCode op, ITree current, Type expected)
+        {
+            PushBinaryOp(op, current, expected, typeof(double), typeof(double), typeof(double));
+        }
+
+        private void PushShift(OpCode op, ITree current, Type expected)
+        {
+            PushBinaryOp(op, current, expected, typeof(long), typeof(int), typeof(long));
+        }
+
+        private void PushBitwise(OpCode op, ITree current, Type expected)
+        {
+            PushBinaryOp(op, current, expected, typeof(long), typeof(long), typeof(long));
+        }
+
+        private void PushBinaryOp(OpCode op, ITree current, Type expected, Type arg1, Type arg2, Type returnType)
+        {
+            gen.Emit(OpCodes.Nop);
+            RecursiveCompile(current.GetChild(0), arg1);
+            RecursiveCompile(current.GetChild(1), arg2);
+            /* gen.Emit(OpCodes.Add, debugDoc, file, lineNum++);
+             gen.Emit(OpCodes.Stloc_0, debugDoc, file, lineNum++);
+             gen.Emit(OpCodes.Br_S, debugDoc, file, lineNum++);
+             gen.Emit(OpCodes.Ldloc_0, debugDoc, file, lineNum++);*/
+            gen.Emit(op);
+            /*dynamicType.VisitInsn(op);
+			dynamicType.Cast(returnType, expected);*/
+        }
+
+        private void PushCond(OpCode @operator, ITree current, Type expected)
+        {
+            Label labelTrue = new Label();
+            Label labelReturn = new Label();
+            RecursiveCompile(current.GetChild(0), typeof(double));
+            RecursiveCompile(current.GetChild(1), typeof(double));
+            /*dynamicType.IfCmp(typeof(double), @operator, labelTrue);
+			PushBoolean(expected, false);
+			dynamicType.GoTo(labelReturn);
+			dynamicType.VisitLabel(labelTrue);
+			PushBoolean(expected, true);
+			dynamicType.VisitLabel(labelReturn);*/
+        }
+
+        /*
+                private void PushBoolean(Type expected, bool truth)
+                {
+                    switch (expected.GetSort())
+                    {
+                        case Type.INT:
+                        {
+                            dynamicType.Push(truth);
+                            break;
+                        }
+
+                        case Type.LONG:
+                        {
+                            dynamicType.Push(truth ? 1L : 0L);
+                            break;
+                        }
+
+                        case Type.DOUBLE:
+                        {
+                            dynamicType.Push(truth ? 1. : 0.);
+                            break;
+                        }
+
+                        default:
+                        {
+                            throw new InvalidOperationException("Invalid expected type: " + expected);
+                        }
+                    }
+                }
+        */
+
+        private void PushLong(Type expected, long i)
+        {
+            /*switch (expected.GetSort())
+			{
+				case Type.INT:
+				{
+					dynamicType.Push((int)i);
+					break;
+				}
+
+				case Type.LONG:
+				{
+					dynamicType.Push(i);
+					break;
+				}
+
+				case Type.DOUBLE:
+				{
+					dynamicType.Push((double)i);
+					break;
+				}
+
+				default:
+				{
+					throw new InvalidOperationException("Invalid expected type: " + expected);
+				}
+			}*/
+            gen.Emit(OpCodes.Ldarg_0);
+        }
+
+        private void EndCompile()
+        {
+            gen.Emit(OpCodes.Ret);
+            dynamicType.DefineMethodOverride(evalMethod, EVALUATE_METHOD);
+        }
+
+
+
+        private ITree GetAntlrComputedExpressionTree()
+        {
+            ICharStream input = new ANTLRStringStream(sourceText);
+            JavascriptLexer lexer = new JavascriptLexer(input);
+            CommonTokenStream tokens = new CommonTokenStream(lexer);
+            JavascriptParser parser = new JavascriptParser(tokens);
+            try
+            {
+                return parser.Expression().Tree;
+            }
+            catch (RecognitionException re)
+            {
+                throw new ArgumentException(re.Message, re);
+            }
+            catch (SystemException exception)
+            {
+                //TODO: Uncomment after implementing ParseException in QueryParsers
+                //if (exception.InnerException is ParseException)
+                //{
+                //    throw (ParseException)exception.InnerException;
+                //}
+                throw;
+            }
+        }
+
+
+
+        static JavascriptCompiler()
+        {
+            IDictionary<string, MethodInfo> map = new Dictionary<string, MethodInfo>();
+            try
+            {
+                var props = Properties.Settings.Default;
+                foreach (SettingsProperty property in props.Properties)
+                {
+                    string[] vals = props[property.Name].ToString().Split(',');
+                    if (vals.Length != 3)
+                    {
+                        throw new Exception("Error reading Javascript functions from settings");
+                    }
+                    string typeName = vals[0];
+                    if (vals[0].Contains("Lucene.Net"))
+                    {
+                        typeName = vals[0] + ",Lucene.Net";
+                    }
+                    Type clazz = Type.GetType(typeName, true);
+                    string methodName = vals[1].Trim();
+                    int arity = int.Parse(vals[2]);
+                    Type[] args = new Type[arity];
+                    Arrays.Fill(args, typeof(double));
+                    MethodInfo method = clazz.GetMethod(methodName, args);
+                    CheckFunction(method);
+                    map[property.Name] = method;
+                }
+
+
+            }
+            catch (Exception e)
+            {
+                throw new Exception("Cannot resolve function", e);
+            }
+            DEFAULT_FUNCTIONS = map;
+        }
+
+        private static void CheckFunction(MethodInfo method)
+        {
+
+            // do some checks if the signature is "compatible":
+            if (!(method.IsStatic))
+            {
+                throw new ArgumentException(method + " is not static.");
+            }
+            if (!(method.IsPublic))
+            {
+                throw new ArgumentException(method + " is not public.");
+            }
+            if (!method.DeclaringType.IsPublic)
+            {
+                //.NET Port. Inner class is being returned as not public even when declared public
+                if (method.DeclaringType.IsNestedAssembly)
+                {
+                    throw new ArgumentException(method.DeclaringType.FullName + " is not public.");
+                }
+            }
+            if (method.GetParameters().Any(parmType => parmType.ParameterType != (typeof(double))))
+            {
+                throw new ArgumentException(method + " must take only double parameters");
+            }
+            if (method.ReturnType != typeof(double))
+            {
+                throw new ArgumentException(method + " does not return a double.");
+            }
+        }
+    }
+
+    
+}


[2/5] lucenenet git commit: Adding Expressions with some failing tests

Posted by sy...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Lucene.Net.Expressions.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Lucene.Net.Expressions.csproj b/src/Lucene.Net.Expressions/Lucene.Net.Expressions.csproj
new file mode 100644
index 0000000..5b7d06b
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Lucene.Net.Expressions.csproj
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Lucene.Net.Expressions</RootNamespace>
+    <AssemblyName>Lucene.Net.Expressions</AssemblyName>
+    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>0478e2ae</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Antlr3.Runtime">
+      <HintPath>..\..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bindings.cs" />
+    <Compile Include="Expression.cs" />
+    <Compile Include="ExpressionComparator.cs" />
+    <Compile Include="ExpressionFunctionValues.cs" />
+    <Compile Include="ExpressionRescorer.cs" />
+    <Compile Include="ExpressionSortField.cs" />
+    <Compile Include="ExpressionValueSource.cs" />
+    <Compile Include="JS\JavascriptCompiler.cs" />
+    <Compile Include="JS\JavascriptLexer.cs" />
+    <Compile Include="JS\JavascriptParser.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+      <DependentUpon>Settings.settings</DependentUpon>
+    </Compile>
+    <Compile Include="ScoreFunctionValues.cs" />
+    <Compile Include="ScoreValueSource.cs" />
+    <Compile Include="SimpleBindings.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Lucene.Net.Core\Lucene.Net.csproj">
+      <Project>{5D4AD9BE-1FFB-41AB-9943-25737971BF57}</Project>
+      <Name>Lucene.Net</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Lucene.Net.Queries\Lucene.Net.Queries.csproj">
+      <Project>{69D7956C-C2CC-4708-B399-A188FEC384C4}</Project>
+      <Name>Lucene.Net.Queries</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Properties/AssemblyInfo.cs b/src/Lucene.Net.Expressions/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..306b537
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Lucene.Net.Expressions")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Lucene.Net.Expressions")]
+[assembly: AssemblyCopyright("Copyright ©  2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6f5d9768-c42b-4dca-881b-001f61618cac")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Properties/Settings.Designer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Properties/Settings.Designer.cs b/src/Lucene.Net.Expressions/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..db95fb0
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Properties/Settings.Designer.cs
@@ -0,0 +1,323 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.0
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Lucene.Net.Expressions.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+        
+        [global::System.Configuration.ApplicationScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Abs, 1")]
+        public string abs {
+            get {
+                return ((string)(this["abs"]));
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Acos, 1")]
+        public string acos {
+            get {
+                return ((string)(this["acos"]));
+            }
+            set {
+                this["acos"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.MathUtil, Acosh, 1")]
+        public string acosh {
+            get {
+                return ((string)(this["acosh"]));
+            }
+            set {
+                this["acosh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Asin, 1")]
+        public string asin {
+            get {
+                return ((string)(this["asin"]));
+            }
+            set {
+                this["asin"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.MathUtil, Asinh, 1")]
+        public string asinh {
+            get {
+                return ((string)(this["asinh"]));
+            }
+            set {
+                this["asinh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Atan, 1")]
+        public string atan {
+            get {
+                return ((string)(this["atan"]));
+            }
+            set {
+                this["atan"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Atan2, 2")]
+        public string atan2 {
+            get {
+                return ((string)(this["atan2"]));
+            }
+            set {
+                this["atan2"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.MathUtil, Atanh, 1")]
+        public string atanh {
+            get {
+                return ((string)(this["atanh"]));
+            }
+            set {
+                this["atanh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Ceiling, 1")]
+        public string ceil {
+            get {
+                return ((string)(this["ceil"]));
+            }
+            set {
+                this["ceil"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Cos, 1")]
+        public string cos {
+            get {
+                return ((string)(this["cos"]));
+            }
+            set {
+                this["cos"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Cosh, 1")]
+        public string cosh {
+            get {
+                return ((string)(this["cosh"]));
+            }
+            set {
+                this["cosh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Exp, 1")]
+        public string exp {
+            get {
+                return ((string)(this["exp"]));
+            }
+            set {
+                this["exp"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Floor, 1")]
+        public string floor {
+            get {
+                return ((string)(this["floor"]));
+            }
+            set {
+                this["floor"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.SloppyMath, Haversin, 4")]
+        public string haversin {
+            get {
+                return ((string)(this["haversin"]));
+            }
+            set {
+                this["haversin"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Log, 1")]
+        public string ln {
+            get {
+                return ((string)(this["ln"]));
+            }
+            set {
+                this["ln"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Log10, 1")]
+        public string log10 {
+            get {
+                return ((string)(this["log10"]));
+            }
+            set {
+                this["log10"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Lucene.Net.Util.MathUtil, Log, 2")]
+        public string logn {
+            get {
+                return ((string)(this["logn"]));
+            }
+            set {
+                this["logn"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Max, 2")]
+        public string max {
+            get {
+                return ((string)(this["max"]));
+            }
+            set {
+                this["max"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Min, 2")]
+        public string min {
+            get {
+                return ((string)(this["min"]));
+            }
+            set {
+                this["min"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Pow, 2")]
+        public string pow {
+            get {
+                return ((string)(this["pow"]));
+            }
+            set {
+                this["pow"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Sin, 1")]
+        public string sin {
+            get {
+                return ((string)(this["sin"]));
+            }
+            set {
+                this["sin"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Sinh, 1")]
+        public string sinh {
+            get {
+                return ((string)(this["sinh"]));
+            }
+            set {
+                this["sinh"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Sqrt, 1")]
+        public string sqrt {
+            get {
+                return ((string)(this["sqrt"]));
+            }
+            set {
+                this["sqrt"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Tan, 1")]
+        public string tan {
+            get {
+                return ((string)(this["tan"]));
+            }
+            set {
+                this["tan"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("System.Math, Tanh, 1")]
+        public string tanh {
+            get {
+                return ((string)(this["tanh"]));
+            }
+            set {
+                this["tanh"] = value;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/Properties/Settings.settings
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/Properties/Settings.settings b/src/Lucene.Net.Expressions/Properties/Settings.settings
new file mode 100644
index 0000000..3fd130f
--- /dev/null
+++ b/src/Lucene.Net.Expressions/Properties/Settings.settings
@@ -0,0 +1,81 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Lucene.Net.Expressions.Properties" GeneratedClassName="Settings">
+  <Profiles />
+  <Settings>
+    <Setting Name="abs" Type="System.String" Scope="Application">
+      <Value Profile="(Default)">System.Math, Abs, 1</Value>
+    </Setting>
+    <Setting Name="acos" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Acos, 1</Value>
+    </Setting>
+    <Setting Name="acosh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.MathUtil, Acosh, 1</Value>
+    </Setting>
+    <Setting Name="asin" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Asin, 1</Value>
+    </Setting>
+    <Setting Name="asinh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.MathUtil, Asinh, 1</Value>
+    </Setting>
+    <Setting Name="atan" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Atan, 1</Value>
+    </Setting>
+    <Setting Name="atan2" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Atan2, 2</Value>
+    </Setting>
+    <Setting Name="atanh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.MathUtil, Atanh, 1</Value>
+    </Setting>
+    <Setting Name="ceil" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Ceiling, 1</Value>
+    </Setting>
+    <Setting Name="cos" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Cos, 1</Value>
+    </Setting>
+    <Setting Name="cosh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Cosh, 1</Value>
+    </Setting>
+    <Setting Name="exp" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Exp, 1</Value>
+    </Setting>
+    <Setting Name="floor" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Floor, 1</Value>
+    </Setting>
+    <Setting Name="haversin" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.SloppyMath, Haversin, 4</Value>
+    </Setting>
+    <Setting Name="ln" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Log, 1</Value>
+    </Setting>
+    <Setting Name="log10" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Log10, 1</Value>
+    </Setting>
+    <Setting Name="logn" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Lucene.Net.Util.MathUtil, Log, 2</Value>
+    </Setting>
+    <Setting Name="max" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Max, 2</Value>
+    </Setting>
+    <Setting Name="min" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Min, 2</Value>
+    </Setting>
+    <Setting Name="pow" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Pow, 2</Value>
+    </Setting>
+    <Setting Name="sin" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Sin, 1</Value>
+    </Setting>
+    <Setting Name="sinh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Sinh, 1</Value>
+    </Setting>
+    <Setting Name="sqrt" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Sqrt, 1</Value>
+    </Setting>
+    <Setting Name="tan" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Tan, 1</Value>
+    </Setting>
+    <Setting Name="tanh" Type="System.String" Scope="User">
+      <Value Profile="(Default)">System.Math, Tanh, 1</Value>
+    </Setting>
+  </Settings>
+</SettingsFile>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ScoreFunctionValues.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ScoreFunctionValues.cs b/src/Lucene.Net.Expressions/ScoreFunctionValues.cs
new file mode 100644
index 0000000..972d8c7
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ScoreFunctionValues.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Queries.Function.DocValues;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+    /// <summary>
+    /// A utility class to allow expressions to access the score as a
+    /// <see cref="Lucene.Net.Queries.Function.FunctionValues">Lucene.Net.Queries.Function.FunctionValues
+    /// 	</see>
+    /// .
+    /// </summary>
+    internal class ScoreFunctionValues : DoubleDocValues
+    {
+        internal readonly Scorer scorer;
+
+        internal ScoreFunctionValues(ValueSource parent, Scorer scorer)
+            : base(parent)
+        {
+            this.scorer = scorer;
+        }
+
+        public override double DoubleVal(int document)
+        {
+            Debug.Assert(document == scorer.DocID());
+            var score = scorer.Score();
+            Console.WriteLine("Score = {0}",score);
+            return score;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/ScoreValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/ScoreValueSource.cs b/src/Lucene.Net.Expressions/ScoreValueSource.cs
new file mode 100644
index 0000000..b9f8d45
--- /dev/null
+++ b/src/Lucene.Net.Expressions/ScoreValueSource.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections;
+using Lucene.Net.Index;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>
+	/// A
+	/// <see cref="Lucene.Net.Queries.Function.ValueSource">Lucene.Net.Queries.Function.ValueSource
+	/// 	</see>
+	/// which uses the
+	/// <see cref="Lucene.Net.Search.Scorer">Lucene.Net.Search.Scorer</see>
+	/// passed through
+	/// the context map by
+	/// <see cref="ExpressionComparator">ExpressionComparator</see>
+	/// .
+	/// </summary>
+	internal class ScoreValueSource : ValueSource
+	{
+	    private Scorer hashCodeObj;
+
+	    /// <summary>
+		/// <code>context</code> must contain a key "scorer" which is a
+		/// <see cref="Lucene.Net.Search.Scorer">Lucene.Net.Search.Scorer</see>
+		/// .
+		/// </summary>
+		/// <exception cref="System.IO.IOException"></exception>
+		public override FunctionValues GetValues(IDictionary context, AtomicReaderContext
+			 readerContext)
+		{
+			Scorer v = (Scorer)context["scorer"];
+		    hashCodeObj = v;
+			if (v == null)
+			{
+				throw new InvalidOperationException("Expressions referencing the score can only be used for sorting"
+					);
+			}
+			return new ScoreFunctionValues(this, v);
+		}
+
+		public override bool Equals(object o)
+		{
+			return o == this;
+		}
+
+		public override int GetHashCode()
+		{
+            //TODO: revist this and return something meaningful
+		    return 777;
+		}
+
+		public override string Description
+		{
+		    get { return "score()"; }
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/SimpleBindings.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/SimpleBindings.cs b/src/Lucene.Net.Expressions/SimpleBindings.cs
new file mode 100644
index 0000000..f317970
--- /dev/null
+++ b/src/Lucene.Net.Expressions/SimpleBindings.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using Lucene.Net.Queries.Function;
+using Lucene.Net.Queries.Function.ValueSources;
+using Lucene.Net.Search;
+
+namespace Lucene.Net.Expressions
+{
+	/// <summary>
+	/// Simple class that binds expression variable names to
+	/// <see cref="Lucene.Net.Search.SortField">Lucene.Net.Search.SortField
+	/// 	</see>
+	/// s
+	/// or other
+	/// <see cref="Expression">Expression</see>
+	/// s.
+	/// <p>
+	/// Example usage:
+	/// <pre class="prettyprint">
+	/// SimpleBindings bindings = new SimpleBindings();
+	/// // document's text relevance score
+	/// bindings.add(new SortField("_score", SortField.Type.SCORE));
+	/// // integer NumericDocValues field (or from FieldCache)
+	/// bindings.add(new SortField("popularity", SortField.Type.INT));
+	/// // another expression
+	/// bindings.add("recency", myRecencyExpression);
+	/// // create a sort field in reverse order
+	/// Sort sort = new Sort(expr.getSortField(bindings, true));
+	/// </pre>
+	/// </summary>
+	/// <lucene.experimental></lucene.experimental>
+	public sealed class SimpleBindings : Bindings
+	{
+		internal readonly IDictionary<string, object> map = new Dictionary<string, object
+			>();
+
+	    /// <summary>Adds a SortField to the bindings.</summary>
+		/// <remarks>
+		/// Adds a SortField to the bindings.
+		/// <p>
+		/// This can be used to reference a DocValuesField, a field from
+		/// FieldCache, the document's score, etc.
+		/// </remarks>
+		public void Add(SortField sortField)
+		{
+			map[sortField.Field] = sortField;
+		}
+
+		/// <summary>Adds an Expression to the bindings.</summary>
+		/// <remarks>
+		/// Adds an Expression to the bindings.
+		/// <p>
+		/// This can be used to reference expressions from other expressions.
+		/// </remarks>
+		public void Add(string name, Expression expression)
+		{
+			map[name] = expression;
+		}
+
+		public override ValueSource GetValueSource(string name)
+		{
+		    object o = map[name];
+			if (o == null)
+			{
+				throw new ArgumentException("Invalid reference '" + name + "'");
+			}
+		    var expression = o as Expression;
+		    if (expression != null)
+		    {
+		        return expression.GetValueSource(this);
+		    }
+		    SortField field = (SortField)o;
+			switch (field.Type)
+			{
+				case SortField.Type_e.INT:
+				{
+					return new IntFieldSource(field.Field, (FieldCache.IIntParser) field.Parser);
+				}
+
+				case SortField.Type_e.LONG:
+				{
+					return new LongFieldSource(field.Field, (FieldCache.ILongParser)field.Parser);
+				}
+
+				case SortField.Type_e.FLOAT:
+				{
+					return new FloatFieldSource(field.Field, (FieldCache.IFloatParser)field.Parser);
+				}
+
+				case SortField.Type_e.DOUBLE:
+				{
+					return new DoubleFieldSource(field.Field, (FieldCache.IDoubleParser)field.Parser);
+				}
+
+				case SortField.Type_e.SCORE:
+				{
+					return GetScoreValueSource();
+				}
+
+				default:
+				{
+					throw new NotSupportedException();
+				}
+			}
+		}
+
+		/// <summary>Traverses the graph of bindings, checking there are no cycles or missing references
+		/// 	</summary>
+		/// <exception cref="System.ArgumentException">if the bindings is inconsistent</exception>
+		public void Validate()
+		{
+			foreach (object o in map.Values)
+			{
+				if (o is Expression)
+				{
+					Expression expr = (Expression)o;
+					try
+					{
+						expr.GetValueSource(this);
+					}
+					catch (StackOverflowException)
+					{
+						throw new ArgumentException("Recursion Error: Cycle detected originating in (" + 
+							expr.sourceText + ")");
+					}
+				}
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/app.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/app.config b/src/Lucene.Net.Expressions/app.config
new file mode 100644
index 0000000..4dcad5c
--- /dev/null
+++ b/src/Lucene.Net.Expressions/app.config
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <configSections>
+        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="Lucene.Net.Expressions.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+        </sectionGroup>
+        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="Lucene.Net.Expressions.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+        </sectionGroup>
+    </configSections>
+    <applicationSettings>
+        <Lucene.Net.Expressions.Properties.Settings>
+            <setting name="abs" serializeAs="String">
+                <value>System.Math, Abs, 1</value>
+            </setting>
+        </Lucene.Net.Expressions.Properties.Settings>
+    </applicationSettings>
+    <userSettings>
+        <Lucene.Net.Expressions.Properties.Settings>
+            <setting name="acos" serializeAs="String">
+                <value>System.Math, Acos, 1</value>
+            </setting>
+            <setting name="acosh" serializeAs="String">
+                <value>Lucene.Net.Util.MathUtil, Acosh, 1</value>
+            </setting>
+            <setting name="asin" serializeAs="String">
+                <value>System.Math, Asin, 1</value>
+            </setting>
+            <setting name="asinh" serializeAs="String">
+                <value>Lucene.Net.Util.MathUtil, Asinh, 1</value>
+            </setting>
+            <setting name="atan" serializeAs="String">
+                <value>System.Math, Atan, 1</value>
+            </setting>
+            <setting name="atan2" serializeAs="String">
+                <value>System.Math, Atan2, 2</value>
+            </setting>
+            <setting name="atanh" serializeAs="String">
+                <value>Lucene.Net.Util.MathUtil, Atanh, 1</value>
+            </setting>
+            <setting name="ceil" serializeAs="String">
+                <value>System.Math, Ceiling, 1</value>
+            </setting>
+            <setting name="cos" serializeAs="String">
+                <value>System.Math, Cos, 1</value>
+            </setting>
+            <setting name="cosh" serializeAs="String">
+                <value>System.Math, Cosh, 1</value>
+            </setting>
+            <setting name="exp" serializeAs="String">
+                <value>System.Math, Exp, 1</value>
+            </setting>
+            <setting name="floor" serializeAs="String">
+                <value>System.Math, Floor, 1</value>
+            </setting>
+            <setting name="haversin" serializeAs="String">
+                <value>Lucene.Net.Util.SloppyMath, Haversin, 4</value>
+            </setting>
+            <setting name="ln" serializeAs="String">
+                <value>System.Math, Log, 1</value>
+            </setting>
+            <setting name="log10" serializeAs="String">
+                <value>System.Math, Log10, 1</value>
+            </setting>
+            <setting name="logn" serializeAs="String">
+                <value>Lucene.Net.Util.MathUtil, Log, 2</value>
+            </setting>
+            <setting name="max" serializeAs="String">
+                <value>System.Math, Max, 2</value>
+            </setting>
+            <setting name="min" serializeAs="String">
+                <value>System.Math, Min, 2</value>
+            </setting>
+            <setting name="pow" serializeAs="String">
+                <value>System.Math, Pow, 2</value>
+            </setting>
+            <setting name="sin" serializeAs="String">
+                <value>System.Math, Sin, 1</value>
+            </setting>
+            <setting name="sinh" serializeAs="String">
+                <value>System.Math, Sinh, 1</value>
+            </setting>
+            <setting name="sqrt" serializeAs="String">
+                <value>System.Math, Sqrt, 1</value>
+            </setting>
+            <setting name="tan" serializeAs="String">
+                <value>System.Math, Tan, 1</value>
+            </setting>
+            <setting name="tanh" serializeAs="String">
+                <value>System.Math, Tanh, 1</value>
+            </setting>
+        </Lucene.Net.Expressions.Properties.Settings>
+    </userSettings>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/packages.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/packages.config b/src/Lucene.Net.Expressions/packages.config
new file mode 100644
index 0000000..8cc9e63
--- /dev/null
+++ b/src/Lucene.Net.Expressions/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Antlr" version="3.5.0.2" targetFramework="net451" />
+</packages>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/JS/TestCustomFunctions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/JS/TestCustomFunctions.cs b/src/Lucene.Net.Tests.Expressions/JS/TestCustomFunctions.cs
new file mode 100644
index 0000000..22e8f12
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/JS/TestCustomFunctions.cs
@@ -0,0 +1,262 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq.Expressions;
+using System.Reflection;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Support;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions.JS
+{
+	[TestFixture]
+	public class TestCustomFunctions : Util.LuceneTestCase
+	{
+		private static double DELTA = 0.0000001;
+
+		/// <summary>empty list of methods</summary>
+		[Test]
+		public virtual void TestEmpty()
+		{
+			IDictionary<string, MethodInfo> functions = new HashMap<string,MethodInfo>();
+			try
+			{
+				JavascriptCompiler.Compile("sqrt(20)", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("Unrecognized method"));
+			}
+		}
+
+		/// <summary>using the default map explicitly</summary>
+		[Test]
+		public virtual void TestDefaultList()
+		{
+			IDictionary<string, MethodInfo> functions = JavascriptCompiler.DEFAULT_FUNCTIONS;
+			var expr = JavascriptCompiler.Compile("sqrt(20)", functions);
+			AreEqual(Math.Sqrt(20), expr.Evaluate(0, null), DELTA);
+		}
+
+		public static double ZeroArgMethod()
+		{
+			return 5;
+		}
+
+		/// <summary>tests a method with no arguments</summary>
+		[Test]
+		public virtual void TestNoArgMethod()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("ZeroArgMethod");
+			var expr = JavascriptCompiler.Compile("foo()", functions);
+			AreEqual(5, expr.Evaluate(0, null), DELTA);
+		}
+
+		public static double OneArgMethod(double arg1)
+		{
+			return 3 + arg1;
+		}
+
+		/// <summary>tests a method with one arguments</summary>
+		[Test]
+		public virtual void TestOneArgMethod()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("OneArgMethod", new []{ typeof(double)});
+			var expr = JavascriptCompiler.Compile("foo(3)", functions);
+			AreEqual(6, expr.Evaluate(0, null), DELTA);
+		}
+
+		public static double ThreeArgMethod(double arg1, double arg2, double arg3)
+		{
+			return arg1 + arg2 + arg3;
+		}
+
+		/// <summary>tests a method with three arguments</summary>
+		[Test]
+		public virtual void TestThreeArgMethod()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("ThreeArgMethod", new []{ typeof(double), typeof(
+				double), typeof(double)});
+			var expr = JavascriptCompiler.Compile("foo(3, 4, 5)", functions);
+			AreEqual(12, expr.Evaluate(0, null), DELTA);
+		}
+
+		/// <summary>tests a map with 2 functions</summary>
+		[Test]
+		public virtual void TestTwoMethods()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("ZeroArgMethod");
+			functions["bar"] = GetType().GetMethod("OneArgMethod", new []{typeof(double)});
+			var expr = JavascriptCompiler.Compile("foo() + bar(3)", functions);
+			AreEqual(11, expr.Evaluate(0, null), DELTA);
+		}
+
+		public static string BogusReturnType()
+		{
+			return "bogus!";
+		}
+
+		/// <summary>wrong return type: must be double</summary>
+		[Test]
+		public virtual void TestWrongReturnType()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("BogusReturnType");
+			try
+			{
+				JavascriptCompiler.Compile("foo()", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("does not return a double"));
+			}
+		}
+
+		public static double BogusParameterType(string s)
+		{
+			return 0;
+		}
+
+		/// <summary>wrong param type: must be doubles</summary>
+		[Test]
+		public virtual void TestWrongParameterType()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("BogusParameterType", new []{ typeof(string)});
+			try
+			{
+				JavascriptCompiler.Compile("foo(2)", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("must take only double parameters"
+					));
+			}
+		}
+
+		public virtual double NonStaticMethod()
+		{
+			return 0;
+		}
+
+		/// <summary>wrong modifiers: must be static</summary>
+		[Test]
+		public virtual void TestWrongNotStatic()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("NonStaticMethod");
+			try
+			{
+				JavascriptCompiler.Compile("foo()", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("is not static"));
+			}
+		}
+
+		internal static double NonPublicMethod()
+		{
+			return 0;
+		}
+
+		/// <summary>wrong modifiers: must be public</summary>
+		[Test]
+		public virtual void TestWrongNotPublic()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = GetType().GetMethod("NonPublicMethod",BindingFlags.NonPublic|BindingFlags.Static);
+				
+			try
+			{
+				JavascriptCompiler.Compile("foo()", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("is not public"));
+			}
+		}
+
+		internal class NestedNotPublic
+		{
+			public static double Method()
+			{
+				return 0;
+			}
+		}
+
+		/// <summary>wrong class modifiers: class containing method is not public</summary>
+		[Test]
+		public virtual void TestWrongNestedNotPublic()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = typeof(NestedNotPublic).GetMethod("Method");
+			try
+			{
+				JavascriptCompiler.Compile("foo()", functions);
+				Fail();
+			}
+			catch (ArgumentException e)
+			{
+				IsTrue(e.Message.Contains("is not public"));
+			}
+		}
+
+		
+		internal static string MESSAGE = "This should not happen but it happens";
+
+		public class StaticThrowingException
+		{
+			public static double Method()
+			{
+				throw new ArithmeticException(MESSAGE);
+			}
+		}
+
+		/// <summary>the method throws an exception.</summary>
+		/// <remarks>the method throws an exception. We should check the stack trace that it contains the source code of the expression as file name.
+		/// 	</remarks>
+		[Test]
+		public virtual void TestThrowingException()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo"] = typeof(StaticThrowingException).GetMethod("Method");
+			string source = "3 * foo() / 5";
+			var expr = JavascriptCompiler.Compile(source, functions);
+			try
+			{
+				expr.Evaluate(0, null);
+				Fail();
+			}
+			catch (ArithmeticException e)
+			{
+				AreEqual(MESSAGE, e.Message);
+				StringWriter sw = new StringWriter();
+				e.printStackTrace();
+                //.NET Port
+                IsTrue(e.StackTrace.Contains("Lucene.Net.Expressions.CompiledExpression.Evaluate(Int32 , FunctionValues[] )"));
+			}
+		}
+
+		/// <summary>test that namespaces work with custom expressions.</summary>
+		/// <remarks>test that namespaces work with custom expressions.</remarks>
+		[Test]
+		public virtual void TestNamespaces()
+		{
+			IDictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
+			functions["foo.bar"] = GetType().GetMethod("ZeroArgMethod");
+			string source = "foo.bar()";
+			var expr = JavascriptCompiler.Compile(source, functions);
+			AreEqual(5, expr.Evaluate(0, null), DELTA);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptCompiler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptCompiler.cs b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptCompiler.cs
new file mode 100644
index 0000000..41da6b3
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptCompiler.cs
@@ -0,0 +1,187 @@
+using System;
+using Lucene.Net.Expressions.JS;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions.JS
+{
+	public class TestJavascriptCompiler : Util.LuceneTestCase
+	{
+		[Test]
+		public virtual void TestValidCompiles()
+		{
+			IsNotNull(JavascriptCompiler.Compile("100"));
+			IsNotNull(JavascriptCompiler.Compile("valid0+100"));
+			IsNotNull(JavascriptCompiler.Compile("valid0+\n100"));
+			IsNotNull(JavascriptCompiler.Compile("logn(2, 20+10-5.0)"));
+		}
+
+		[Test]
+		public virtual void TestValidNamespaces()
+		{
+			IsNotNull(JavascriptCompiler.Compile("object.valid0"));
+			IsNotNull(JavascriptCompiler.Compile("object0.object1.valid1"));
+		}
+
+        //TODO: change all exceptions to ParseExceptions
+		[Test]
+		public virtual void TestInvalidNamespaces()
+		{
+			try
+			{
+				JavascriptCompiler.Compile("object.0invalid");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			//expected
+			try
+			{
+				JavascriptCompiler.Compile("0.invalid");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			//expected
+			try
+			{
+				JavascriptCompiler.Compile("object..invalid");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			//expected
+			try
+			{
+				JavascriptCompiler.Compile(".invalid");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+		}
+
+		//expected
+		[Test]
+		public virtual void TestInvalidCompiles()
+		{
+			try
+			{
+				JavascriptCompiler.Compile("100 100");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("7*/-8");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("0y1234");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("500EE");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("500.5EE");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+		}
+
+		[Test]
+		public virtual void TestEmpty()
+		{
+			try
+			{
+				JavascriptCompiler.Compile(string.Empty);
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("()");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+			// expected exception
+			try
+			{
+				JavascriptCompiler.Compile("   \r\n   \n \t");
+				Fail();
+			}
+			catch (Exception)
+			{
+			}
+		}
+
+		// expected exception
+		[Test]
+		public virtual void TestNull()
+		{
+			try
+			{
+				JavascriptCompiler.Compile(null);
+				Fail();
+			}
+			catch (ArgumentNullException)
+			{
+			}
+		}
+
+		// expected exception
+		[Test]
+		public virtual void TestWrongArity()
+		{
+			try
+			{
+				JavascriptCompiler.Compile("tan()");
+				Fail();
+			}
+			catch (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("arguments for method call"
+					));
+			}
+			try
+			{
+				JavascriptCompiler.Compile("tan(1, 1)");
+				Fail();
+			}
+			catch (ArgumentException expected)
+			{
+				IsTrue(expected.Message.Contains("arguments for method call"
+					));
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptFunction.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptFunction.cs b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptFunction.cs
new file mode 100644
index 0000000..3d39f1d
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptFunction.cs
@@ -0,0 +1,309 @@
+using System;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions.JS
+{
+	public class TestJavascriptFunction : Util.LuceneTestCase
+	{
+		private static double DELTA = 0.0000001;
+
+		
+		private void AssertEvaluatesTo(string expression, double expected)
+		{
+			Expression evaluator = JavascriptCompiler.Compile(expression);
+			double actual = evaluator.Evaluate(0, null);
+			AreEqual(expected, actual, DELTA);
+		}
+
+		[Test]
+		public virtual void TestAbsMethod()
+		{
+			AssertEvaluatesTo("abs(0)", 0);
+			AssertEvaluatesTo("abs(119)", 119);
+			AssertEvaluatesTo("abs(119)", 119);
+			AssertEvaluatesTo("abs(1)", 1);
+			AssertEvaluatesTo("abs(-1)", 1);
+		}
+
+		[Test]
+		public virtual void TestAcosMethod()
+		{
+			AssertEvaluatesTo("acos(-1)", Math.PI);
+			AssertEvaluatesTo("acos(-0.8660254)", Math.PI * 5 / 6);
+			AssertEvaluatesTo("acos(-0.7071068)", Math.PI * 3 / 4);
+			AssertEvaluatesTo("acos(-0.5)", Math.PI * 2 / 3);
+			AssertEvaluatesTo("acos(0)", Math.PI / 2);
+			AssertEvaluatesTo("acos(0.5)", Math.PI / 3);
+			AssertEvaluatesTo("acos(0.7071068)", Math.PI / 4);
+			AssertEvaluatesTo("acos(0.8660254)", Math.PI / 6);
+			AssertEvaluatesTo("acos(1)", 0);
+		}
+
+		[Test]
+		public virtual void TestAcoshMethod()
+		{
+			AssertEvaluatesTo("acosh(1)", 0);
+			AssertEvaluatesTo("acosh(2.5)", 1.5667992369724109);
+			AssertEvaluatesTo("acosh(1234567.89)", 14.719378760739708);
+		}
+
+		[Test]
+		public virtual void TestAsinMethod()
+		{
+			AssertEvaluatesTo("asin(-1)", -Math.PI / 2);
+			AssertEvaluatesTo("asin(-0.8660254)", -Math.PI / 3);
+			AssertEvaluatesTo("asin(-0.7071068)", -Math.PI / 4);
+			AssertEvaluatesTo("asin(-0.5)", -Math.PI / 6);
+			AssertEvaluatesTo("asin(0)", 0);
+			AssertEvaluatesTo("asin(0.5)", Math.PI / 6);
+			AssertEvaluatesTo("asin(0.7071068)", Math.PI / 4);
+			AssertEvaluatesTo("asin(0.8660254)", Math.PI / 3);
+			AssertEvaluatesTo("asin(1)", Math.PI / 2);
+		}
+
+		[Test]
+		public virtual void TestAsinhMethod()
+		{
+			AssertEvaluatesTo("asinh(-1234567.89)", -14.719378760740035);
+			AssertEvaluatesTo("asinh(-2.5)", -1.6472311463710958);
+			AssertEvaluatesTo("asinh(-1)", -0.8813735870195429);
+			AssertEvaluatesTo("asinh(0)", 0);
+			AssertEvaluatesTo("asinh(1)", 0.8813735870195429);
+			AssertEvaluatesTo("asinh(2.5)", 1.6472311463710958);
+			AssertEvaluatesTo("asinh(1234567.89)", 14.719378760740035);
+		}
+
+		[Test]
+		public virtual void TestAtanMethod()
+		{
+			AssertEvaluatesTo("atan(-1.732050808)", -Math.PI / 3);
+			AssertEvaluatesTo("atan(-1)", -Math.PI / 4);
+			AssertEvaluatesTo("atan(-0.577350269)", -Math.PI / 6);
+			AssertEvaluatesTo("atan(0)", 0);
+			AssertEvaluatesTo("atan(0.577350269)", Math.PI / 6);
+			AssertEvaluatesTo("atan(1)", Math.PI / 4);
+			AssertEvaluatesTo("atan(1.732050808)", Math.PI / 3);
+		}
+
+		[Test]
+		public virtual void TestAtan2Method()
+		{
+			AssertEvaluatesTo("atan2(+0,+0)", +0.0);
+			AssertEvaluatesTo("atan2(+0,-0)", +Math.PI);
+			AssertEvaluatesTo("atan2(-0,+0)", -0.0);
+			AssertEvaluatesTo("atan2(-0,-0)", -Math.PI);
+			AssertEvaluatesTo("atan2(2,2)", Math.PI / 4);
+			AssertEvaluatesTo("atan2(-2,2)", -Math.PI / 4);
+			AssertEvaluatesTo("atan2(2,-2)", Math.PI * 3 / 4);
+			AssertEvaluatesTo("atan2(-2,-2)", -Math.PI * 3 / 4);
+		}
+
+		[Test]
+		public virtual void TestAtanhMethod()
+		{
+			AssertEvaluatesTo("atanh(-1)", double.NegativeInfinity);
+			AssertEvaluatesTo("atanh(-0.5)", -0.5493061443340549);
+			AssertEvaluatesTo("atanh(0)", 0);
+			AssertEvaluatesTo("atanh(0.5)", 0.5493061443340549);
+			AssertEvaluatesTo("atanh(1)", double.PositiveInfinity);
+		}
+
+		[Test]
+		public virtual void TestCeilMethod()
+		{
+			AssertEvaluatesTo("ceil(0)", 0);
+			AssertEvaluatesTo("ceil(0.1)", 1);
+			AssertEvaluatesTo("ceil(0.9)", 1);
+			AssertEvaluatesTo("ceil(25.2)", 26);
+			AssertEvaluatesTo("ceil(-0.1)", 0);
+			AssertEvaluatesTo("ceil(-0.9)", 0);
+			AssertEvaluatesTo("ceil(-1.1)", -1);
+		}
+
+		[Test]
+		public virtual void TestCosMethod()
+		{
+			AssertEvaluatesTo("cos(0)", 1);
+			AssertEvaluatesTo("cos(" + Math.PI / 2 + ")", 0);
+			AssertEvaluatesTo("cos(" + -Math.PI / 2 + ")", 0);
+			AssertEvaluatesTo("cos(" + Math.PI / 4 + ")", 0.7071068);
+			AssertEvaluatesTo("cos(" + -Math.PI / 4 + ")", 0.7071068);
+			AssertEvaluatesTo("cos(" + Math.PI * 2 / 3 + ")", -0.5);
+			AssertEvaluatesTo("cos(" + -Math.PI * 2 / 3 + ")", -0.5);
+			AssertEvaluatesTo("cos(" + Math.PI / 6 + ")", 0.8660254);
+			AssertEvaluatesTo("cos(" + -Math.PI / 6 + ")", 0.8660254);
+		}
+
+		[Test]
+		public virtual void TestCoshMethod()
+		{
+			AssertEvaluatesTo("cosh(0)", 1);
+			AssertEvaluatesTo("cosh(-1)", 1.5430806348152437);
+			AssertEvaluatesTo("cosh(1)", 1.5430806348152437);
+			AssertEvaluatesTo("cosh(-0.5)", 1.1276259652063807);
+			AssertEvaluatesTo("cosh(0.5)", 1.1276259652063807);
+			AssertEvaluatesTo("cosh(-12.3456789)", 114982.09728671524);
+			AssertEvaluatesTo("cosh(12.3456789)", 114982.09728671524);
+		}
+
+		[Test]
+		public virtual void TestExpMethod()
+		{
+			AssertEvaluatesTo("exp(0)", 1);
+			AssertEvaluatesTo("exp(-1)", 0.36787944117);
+			AssertEvaluatesTo("exp(1)", 2.71828182846);
+			AssertEvaluatesTo("exp(-0.5)", 0.60653065971);
+			AssertEvaluatesTo("exp(0.5)", 1.6487212707);
+			AssertEvaluatesTo("exp(-12.3456789)", 0.0000043485);
+			AssertEvaluatesTo("exp(12.3456789)", 229964.194569);
+		}
+
+		[Test]
+		public virtual void TestFloorMethod()
+		{
+			AssertEvaluatesTo("floor(0)", 0);
+			AssertEvaluatesTo("floor(0.1)", 0);
+			AssertEvaluatesTo("floor(0.9)", 0);
+			AssertEvaluatesTo("floor(25.2)", 25);
+			AssertEvaluatesTo("floor(-0.1)", -1);
+			AssertEvaluatesTo("floor(-0.9)", -1);
+			AssertEvaluatesTo("floor(-1.1)", -2);
+		}
+
+		[Test]
+		public virtual void TestHaversinMethod()
+		{
+			AssertEvaluatesTo("haversin(40.7143528,-74.0059731,40.759011,-73.9844722)", 5.284299568309
+				);
+		}
+
+		[Test]
+		public virtual void TestLnMethod()
+		{
+			AssertEvaluatesTo("ln(0)", double.NegativeInfinity);
+			AssertEvaluatesTo("ln(" + Math.E + ")", 1);
+			AssertEvaluatesTo("ln(-1)", double.NaN);
+			AssertEvaluatesTo("ln(1)", 0);
+			AssertEvaluatesTo("ln(0.5)", -0.69314718056);
+			AssertEvaluatesTo("ln(12.3456789)", 2.51330611521);
+		}
+
+		[Test]
+		public virtual void TestLog10Method()
+		{
+			AssertEvaluatesTo("log10(0)", double.NegativeInfinity);
+			AssertEvaluatesTo("log10(1)", 0);
+			AssertEvaluatesTo("log10(-1)", double.NaN);
+			AssertEvaluatesTo("log10(0.5)", -0.3010299956639812);
+			AssertEvaluatesTo("log10(12.3456789)", 1.0915149771692705);
+		}
+
+		[Test]
+		public virtual void TestLognMethod()
+		{
+			AssertEvaluatesTo("logn(2, 0)", double.NegativeInfinity);
+			AssertEvaluatesTo("logn(2, 1)", 0);
+			AssertEvaluatesTo("logn(2, -1)", double.NaN);
+			AssertEvaluatesTo("logn(2, 0.5)", -1);
+			AssertEvaluatesTo("logn(2, 12.3456789)", 3.6259342686489378);
+			AssertEvaluatesTo("logn(2.5, 0)", double.NegativeInfinity);
+			AssertEvaluatesTo("logn(2.5, 1)", 0);
+			AssertEvaluatesTo("logn(2.5, -1)", double.NaN);
+			AssertEvaluatesTo("logn(2.5, 0.5)", -0.75647079736603);
+			AssertEvaluatesTo("logn(2.5, 12.3456789)", 2.7429133874016745);
+		}
+
+		[Test]
+		public virtual void TestMaxMethod()
+		{
+			AssertEvaluatesTo("max(0, 0)", 0);
+			AssertEvaluatesTo("max(1, 0)", 1);
+			AssertEvaluatesTo("max(0, -1)", 0);
+			AssertEvaluatesTo("max(-1, 0)", 0);
+			AssertEvaluatesTo("max(25, 23)", 25);
+		}
+
+		[Test]
+		public virtual void TestMinMethod()
+		{
+			AssertEvaluatesTo("min(0, 0)", 0);
+			AssertEvaluatesTo("min(1, 0)", 0);
+			AssertEvaluatesTo("min(0, -1)", -1);
+			AssertEvaluatesTo("min(-1, 0)", -1);
+			AssertEvaluatesTo("min(25, 23)", 23);
+		}
+
+		[Test]
+		public virtual void TestPowMethod()
+		{
+			AssertEvaluatesTo("pow(0, 0)", 1);
+			AssertEvaluatesTo("pow(0.1, 2)", 0.01);
+			AssertEvaluatesTo("pow(0.9, -1)", 1.1111111111111112);
+			AssertEvaluatesTo("pow(2.2, -2.5)", 0.13929749224447147);
+			AssertEvaluatesTo("pow(5, 3)", 125);
+			AssertEvaluatesTo("pow(-0.9, 5)", -0.59049);
+			AssertEvaluatesTo("pow(-1.1, 2)", 1.21);
+		}
+
+		[Test]
+		public virtual void TestSinMethod()
+		{
+			AssertEvaluatesTo("sin(0)", 0);
+			AssertEvaluatesTo("sin(" + Math.PI / 2 + ")", 1);
+			AssertEvaluatesTo("sin(" + -Math.PI / 2 + ")", -1);
+			AssertEvaluatesTo("sin(" + Math.PI / 4 + ")", 0.7071068);
+			AssertEvaluatesTo("sin(" + -Math.PI / 4 + ")", -0.7071068);
+			AssertEvaluatesTo("sin(" + Math.PI * 2 / 3 + ")", 0.8660254);
+			AssertEvaluatesTo("sin(" + -Math.PI * 2 / 3 + ")", -0.8660254);
+			AssertEvaluatesTo("sin(" + Math.PI / 6 + ")", 0.5);
+			AssertEvaluatesTo("sin(" + -Math.PI / 6 + ")", -0.5);
+		}
+
+		[Test]
+		public virtual void TestSinhMethod()
+		{
+			AssertEvaluatesTo("sinh(0)", 0);
+			AssertEvaluatesTo("sinh(-1)", -1.1752011936438014);
+			AssertEvaluatesTo("sinh(1)", 1.1752011936438014);
+			AssertEvaluatesTo("sinh(-0.5)", -0.52109530549);
+			AssertEvaluatesTo("sinh(0.5)", 0.52109530549);
+			AssertEvaluatesTo("sinh(-12.3456789)", -114982.09728236674);
+			AssertEvaluatesTo("sinh(12.3456789)", 114982.09728236674);
+		}
+
+		[Test]
+		public virtual void TestSqrtMethod()
+		{
+			AssertEvaluatesTo("sqrt(0)", 0);
+			AssertEvaluatesTo("sqrt(-1)", double.NaN);
+			AssertEvaluatesTo("sqrt(0.49)", 0.7);
+			AssertEvaluatesTo("sqrt(49)", 7);
+		}
+
+		[Test]
+		public virtual void TestTanMethod()
+		{
+			AssertEvaluatesTo("tan(0)", 0);
+			AssertEvaluatesTo("tan(-1)", -1.55740772465);
+			AssertEvaluatesTo("tan(1)", 1.55740772465);
+			AssertEvaluatesTo("tan(-0.5)", -0.54630248984);
+			AssertEvaluatesTo("tan(0.5)", 0.54630248984);
+			AssertEvaluatesTo("tan(-1.3)", -3.60210244797);
+			AssertEvaluatesTo("tan(1.3)", 3.60210244797);
+		}
+
+		[Test]
+		public virtual void TestTanhMethod()
+		{
+			AssertEvaluatesTo("tanh(0)", 0);
+			AssertEvaluatesTo("tanh(-1)", -0.76159415595);
+			AssertEvaluatesTo("tanh(1)", 0.76159415595);
+			AssertEvaluatesTo("tanh(-0.5)", -0.46211715726);
+			AssertEvaluatesTo("tanh(0.5)", 0.46211715726);
+			AssertEvaluatesTo("tanh(-12.3456789)", -0.99999999996);
+			AssertEvaluatesTo("tanh(12.3456789)", 0.99999999996);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptOperations.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptOperations.cs b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptOperations.cs
new file mode 100644
index 0000000..07b2fa9
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/JS/TestJavascriptOperations.cs
@@ -0,0 +1,373 @@
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions.JS
+{
+	public class TestJavascriptOperations : Util.LuceneTestCase
+	{
+		
+		private void AssertEvaluatesTo(string expression, long expected)
+		{
+			Expression evaluator = JavascriptCompiler.Compile(expression);
+			long actual = (long)evaluator.Evaluate(0, null);
+			AreEqual(expected, actual);
+		}
+
+		[Test]
+		public virtual void TestNegationOperation()
+		{
+			AssertEvaluatesTo("-1", -1);
+			AssertEvaluatesTo("--1", 1);
+			AssertEvaluatesTo("-(-1)", 1);
+			AssertEvaluatesTo("-0", 0);
+			AssertEvaluatesTo("--0", 0);
+		}
+
+		[Test]
+		public virtual void TestAddOperation()
+		{
+			AssertEvaluatesTo("1+1", 2);
+			AssertEvaluatesTo("1+0.5+0.5", 2);
+			AssertEvaluatesTo("5+10", 15);
+			AssertEvaluatesTo("1+1+2", 4);
+			AssertEvaluatesTo("(1+1)+2", 4);
+			AssertEvaluatesTo("1+(1+2)", 4);
+			AssertEvaluatesTo("0+1", 1);
+			AssertEvaluatesTo("1+0", 1);
+			AssertEvaluatesTo("0+0", 0);
+		}
+
+		[Test]
+		public virtual void TestSubtractOperation()
+		{
+			AssertEvaluatesTo("1-1", 0);
+			AssertEvaluatesTo("5-10", -5);
+			AssertEvaluatesTo("1-0.5-0.5", 0);
+			AssertEvaluatesTo("1-1-2", -2);
+			AssertEvaluatesTo("(1-1)-2", -2);
+			AssertEvaluatesTo("1-(1-2)", 2);
+			AssertEvaluatesTo("0-1", -1);
+			AssertEvaluatesTo("1-0", 1);
+			AssertEvaluatesTo("0-0", 0);
+		}
+
+		[Test]
+		public virtual void TestMultiplyOperation()
+		{
+			AssertEvaluatesTo("1*1", 1);
+			AssertEvaluatesTo("5*10", 50);
+			AssertEvaluatesTo("50*0.1", 5);
+			AssertEvaluatesTo("1*1*2", 2);
+			AssertEvaluatesTo("(1*1)*2", 2);
+			AssertEvaluatesTo("1*(1*2)", 2);
+			AssertEvaluatesTo("10*0", 0);
+			AssertEvaluatesTo("0*0", 0);
+		}
+
+		[Test]
+		public virtual void TestDivisionOperation()
+		{
+			AssertEvaluatesTo("1*1", 1);
+			AssertEvaluatesTo("10/5", 2);
+			AssertEvaluatesTo("10/0.5", 20);
+			AssertEvaluatesTo("10/5/2", 1);
+			AssertEvaluatesTo("(27/9)/3", 1);
+			AssertEvaluatesTo("27/(9/3)", 9);
+			AssertEvaluatesTo("1/0", 9223372036854775807L);
+		}
+
+		[Test]
+		public virtual void TestModuloOperation()
+		{
+			AssertEvaluatesTo("1%1", 0);
+			AssertEvaluatesTo("10%3", 1);
+			AssertEvaluatesTo("10%3%2", 1);
+			AssertEvaluatesTo("(27%10)%4", 3);
+			AssertEvaluatesTo("27%(9%5)", 3);
+		}
+
+		[Test]
+		public virtual void TestLessThanOperation()
+		{
+			AssertEvaluatesTo("1 < 1", 0);
+			AssertEvaluatesTo("2 < 1", 0);
+			AssertEvaluatesTo("1 < 2", 1);
+			AssertEvaluatesTo("2 < 1 < 3", 1);
+			AssertEvaluatesTo("2 < (1 < 3)", 0);
+			AssertEvaluatesTo("(2 < 1) < 1", 1);
+			AssertEvaluatesTo("-1 < -2", 0);
+			AssertEvaluatesTo("-1 < 0", 1);
+		}
+
+		[Test]
+		public virtual void TestLessThanEqualsOperation()
+		{
+			AssertEvaluatesTo("1 <= 1", 1);
+			AssertEvaluatesTo("2 <= 1", 0);
+			AssertEvaluatesTo("1 <= 2", 1);
+			AssertEvaluatesTo("1 <= 1 <= 0", 0);
+			AssertEvaluatesTo("-1 <= -1", 1);
+			AssertEvaluatesTo("-1 <= 0", 1);
+			AssertEvaluatesTo("-1 <= -2", 0);
+			AssertEvaluatesTo("-1 <= 0", 1);
+		}
+
+		[Test]
+		public virtual void TestGreaterThanOperation()
+		{
+			AssertEvaluatesTo("1 > 1", 0);
+			AssertEvaluatesTo("2 > 1", 1);
+			AssertEvaluatesTo("1 > 2", 0);
+			AssertEvaluatesTo("2 > 1 > 3", 0);
+			AssertEvaluatesTo("2 > (1 > 3)", 1);
+			AssertEvaluatesTo("(2 > 1) > 1", 0);
+			AssertEvaluatesTo("-1 > -2", 1);
+			AssertEvaluatesTo("-1 > 0", 0);
+		}
+
+		[Test]
+		public virtual void TestGreaterThanEqualsOperation()
+		{
+			AssertEvaluatesTo("1 >= 1", 1);
+			AssertEvaluatesTo("2 >= 1", 1);
+			AssertEvaluatesTo("1 >= 2", 0);
+			AssertEvaluatesTo("1 >= 1 >= 0", 1);
+			AssertEvaluatesTo("-1 >= -1", 1);
+			AssertEvaluatesTo("-1 >= 0", 0);
+			AssertEvaluatesTo("-1 >= -2", 1);
+			AssertEvaluatesTo("-1 >= 0", 0);
+		}
+
+		[Test]
+		public virtual void TestEqualsOperation()
+		{
+			AssertEvaluatesTo("1 == 1", 1);
+			AssertEvaluatesTo("0 == 0", 1);
+			AssertEvaluatesTo("-1 == -1", 1);
+			AssertEvaluatesTo("1.1 == 1.1", 1);
+			AssertEvaluatesTo("0.9 == 0.9", 1);
+			AssertEvaluatesTo("-0 == 0", 1);
+			AssertEvaluatesTo("0 == 1", 0);
+			AssertEvaluatesTo("1 == 2", 0);
+			AssertEvaluatesTo("-1 == 1", 0);
+			AssertEvaluatesTo("-1 == 0", 0);
+			AssertEvaluatesTo("-2 == 1", 0);
+			AssertEvaluatesTo("-2 == -1", 0);
+		}
+
+		[Test]
+		public virtual void TestNotEqualsOperation()
+		{
+			AssertEvaluatesTo("1 != 1", 0);
+			AssertEvaluatesTo("0 != 0", 0);
+			AssertEvaluatesTo("-1 != -1", 0);
+			AssertEvaluatesTo("1.1 != 1.1", 0);
+			AssertEvaluatesTo("0.9 != 0.9", 0);
+			AssertEvaluatesTo("-0 != 0", 0);
+			AssertEvaluatesTo("0 != 1", 1);
+			AssertEvaluatesTo("1 != 2", 1);
+			AssertEvaluatesTo("-1 != 1", 1);
+			AssertEvaluatesTo("-1 != 0", 1);
+			AssertEvaluatesTo("-2 != 1", 1);
+			AssertEvaluatesTo("-2 != -1", 1);
+		}
+
+		[Test]
+		public virtual void TestBoolNotOperation()
+		{
+			AssertEvaluatesTo("!1", 0);
+			AssertEvaluatesTo("!!1", 1);
+			AssertEvaluatesTo("!0", 1);
+			AssertEvaluatesTo("!!0", 0);
+			AssertEvaluatesTo("!-1", 0);
+			AssertEvaluatesTo("!2", 0);
+			AssertEvaluatesTo("!-2", 0);
+		}
+
+		[Test]
+		public virtual void TestBoolAndOperation()
+		{
+			AssertEvaluatesTo("1 && 1", 1);
+			AssertEvaluatesTo("1 && 0", 0);
+			AssertEvaluatesTo("0 && 1", 0);
+			AssertEvaluatesTo("0 && 0", 0);
+			AssertEvaluatesTo("-1 && -1", 1);
+			AssertEvaluatesTo("-1 && 0", 0);
+			AssertEvaluatesTo("0 && -1", 0);
+			AssertEvaluatesTo("-0 && -0", 0);
+		}
+
+		[Test]
+		public virtual void TestBoolOrOperation()
+		{
+			AssertEvaluatesTo("1 || 1", 1);
+			AssertEvaluatesTo("1 || 0", 1);
+			AssertEvaluatesTo("0 || 1", 1);
+			AssertEvaluatesTo("0 || 0", 0);
+			AssertEvaluatesTo("-1 || -1", 1);
+			AssertEvaluatesTo("-1 || 0", 1);
+			AssertEvaluatesTo("0 || -1", 1);
+			AssertEvaluatesTo("-0 || -0", 0);
+		}
+
+		[Test]
+		public virtual void TestConditionalOperation()
+		{
+			AssertEvaluatesTo("1 ? 2 : 3", 2);
+			AssertEvaluatesTo("-1 ? 2 : 3", 2);
+			AssertEvaluatesTo("0 ? 2 : 3", 3);
+			AssertEvaluatesTo("1 ? 2 ? 3 : 4 : 5", 3);
+			AssertEvaluatesTo("0 ? 2 ? 3 : 4 : 5", 5);
+			AssertEvaluatesTo("1 ? 0 ? 3 : 4 : 5", 4);
+			AssertEvaluatesTo("1 ? 2 : 3 ? 4 : 5", 2);
+			AssertEvaluatesTo("0 ? 2 : 3 ? 4 : 5", 4);
+			AssertEvaluatesTo("0 ? 2 : 0 ? 4 : 5", 5);
+			AssertEvaluatesTo("(1 ? 1 : 0) ? 3 : 4", 3);
+			AssertEvaluatesTo("(0 ? 1 : 0) ? 3 : 4", 4);
+		}
+
+		[Test]
+		public virtual void TestBitShiftLeft()
+		{
+			AssertEvaluatesTo("1 << 1", 2);
+			AssertEvaluatesTo("2 << 1", 4);
+			AssertEvaluatesTo("-1 << 31", -2147483648);
+			AssertEvaluatesTo("3 << 5", 96);
+			AssertEvaluatesTo("-5 << 3", -40);
+			AssertEvaluatesTo("4195 << 7", 536960);
+			AssertEvaluatesTo("4195 << 66", 16780);
+			AssertEvaluatesTo("4195 << 6", 268480);
+			AssertEvaluatesTo("4195 << 70", 268480);
+			AssertEvaluatesTo("-4195 << 70", -268480);
+			AssertEvaluatesTo("-15 << 62", 4611686018427387904L);
+		}
+
+		[Test]
+		public virtual void TestBitShiftRight()
+		{
+			AssertEvaluatesTo("1 >> 1", 0);
+			AssertEvaluatesTo("2 >> 1", 1);
+			AssertEvaluatesTo("-1 >> 5", -1);
+			AssertEvaluatesTo("-2 >> 30", -1);
+			AssertEvaluatesTo("-5 >> 1", -3);
+			AssertEvaluatesTo("536960 >> 7", 4195);
+			AssertEvaluatesTo("16780 >> 66", 4195);
+			AssertEvaluatesTo("268480 >> 6", 4195);
+			AssertEvaluatesTo("268480 >> 70", 4195);
+			AssertEvaluatesTo("-268480 >> 70", -4195);
+			AssertEvaluatesTo("-2147483646 >> 1", -1073741823);
+		}
+
+		[Test]
+		public virtual void TestBitShiftRightUnsigned()
+		{
+			AssertEvaluatesTo("1 >>> 1", 0);
+			AssertEvaluatesTo("2 >>> 1", 1);
+			AssertEvaluatesTo("-1 >>> 37", 134217727);
+			AssertEvaluatesTo("-2 >>> 62", 3);
+			AssertEvaluatesTo("-5 >>> 33", 2147483647);
+			AssertEvaluatesTo("536960 >>> 7", 4195);
+			AssertEvaluatesTo("16780 >>> 66", 4195);
+			AssertEvaluatesTo("268480 >>> 6", 4195);
+			AssertEvaluatesTo("268480 >>> 70", 4195);
+			AssertEvaluatesTo("-268480 >>> 102", 67108863);
+			AssertEvaluatesTo("2147483648 >>> 1", 1073741824);
+		}
+
+		[Test]
+		public virtual void TestBitwiseAnd()
+		{
+			AssertEvaluatesTo("4 & 4", 4);
+			AssertEvaluatesTo("3 & 2", 2);
+			AssertEvaluatesTo("7 & 3", 3);
+			AssertEvaluatesTo("-1 & -1", -1);
+			AssertEvaluatesTo("-1 & 25", 25);
+			AssertEvaluatesTo("3 & 7", 3);
+			AssertEvaluatesTo("0 & 1", 0);
+			AssertEvaluatesTo("1 & 0", 0);
+		}
+
+		[Test]
+		public virtual void TestBitwiseOr()
+		{
+			AssertEvaluatesTo("4 | 4", 4);
+			AssertEvaluatesTo("5 | 2", 7);
+			AssertEvaluatesTo("7 | 3", 7);
+			AssertEvaluatesTo("-1 | -5", -1);
+			AssertEvaluatesTo("-1 | 25", -1);
+			AssertEvaluatesTo("-100 | 15", -97);
+			AssertEvaluatesTo("0 | 1", 1);
+			AssertEvaluatesTo("1 | 0", 1);
+		}
+
+		[Test]
+		public virtual void TestBitwiseXor()
+		{
+			AssertEvaluatesTo("4 ^ 4", 0);
+			AssertEvaluatesTo("5 ^ 2", 7);
+			AssertEvaluatesTo("15 ^ 3", 12);
+			AssertEvaluatesTo("-1 ^ -5", 4);
+			AssertEvaluatesTo("-1 ^ 25", -26);
+			AssertEvaluatesTo("-100 ^ 15", -109);
+			AssertEvaluatesTo("0 ^ 1", 1);
+			AssertEvaluatesTo("1 ^ 0", 1);
+			AssertEvaluatesTo("0 ^ 0", 0);
+		}
+
+		[Test]
+		public virtual void TestBitwiseNot()
+		{
+			AssertEvaluatesTo("~-5", 4);
+			AssertEvaluatesTo("~25", -26);
+			AssertEvaluatesTo("~0", -1);
+			AssertEvaluatesTo("~-1", 0);
+		}
+
+		[Test]
+		public virtual void TestDecimalConst()
+		{
+			AssertEvaluatesTo("0", 0);
+			AssertEvaluatesTo("1", 1);
+			AssertEvaluatesTo("123456789", 123456789);
+			AssertEvaluatesTo("5.6E2", 560);
+			AssertEvaluatesTo("5.6E+2", 560);
+			AssertEvaluatesTo("500E-2", 5);
+		}
+
+		[Test]
+		public virtual void TestHexConst()
+		{
+			AssertEvaluatesTo("0x0", 0);
+			AssertEvaluatesTo("0x1", 1);
+			AssertEvaluatesTo("0xF", 15);
+			AssertEvaluatesTo("0x1234ABCDEF", 78193085935L);
+			AssertEvaluatesTo("1 << 0x1", 1 << unchecked((int)(0x1)));
+			AssertEvaluatesTo("1 << 0xA", 1 << unchecked((int)(0xA)));
+			AssertEvaluatesTo("0x1 << 2", unchecked((int)(0x1)) << 2);
+			AssertEvaluatesTo("0xA << 2", unchecked((int)(0xA)) << 2);
+		}
+
+		[Test]
+		public virtual void TestHexConst2()
+		{
+			AssertEvaluatesTo("0X0", 0);
+			AssertEvaluatesTo("0X1", 1);
+			AssertEvaluatesTo("0XF", 15);
+			AssertEvaluatesTo("0X1234ABCDEF", 78193085935L);
+		}
+
+		[Test]
+		public virtual void TestOctalConst()
+		{
+			AssertEvaluatesTo("00", 0);
+			AssertEvaluatesTo("01", 1);
+			AssertEvaluatesTo("010", 8);
+			AssertEvaluatesTo("0123456777", 21913087);
+			AssertEvaluatesTo("1 << 01", 1 << 0x1);
+			AssertEvaluatesTo("1 << 010", 1 << 0x8);
+			AssertEvaluatesTo("01 << 2", 0x1 << 2);
+			AssertEvaluatesTo("010 << 2", 0x8 << 2);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/Lucene.Net.Tests.Expressions.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/Lucene.Net.Tests.Expressions.csproj b/src/Lucene.Net.Tests.Expressions/Lucene.Net.Tests.Expressions.csproj
new file mode 100644
index 0000000..c72edd1
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/Lucene.Net.Tests.Expressions.csproj
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{F4873D95-4300-4E83-AFFA-EF796495D0F0}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Lucene.Net.Tests.Expressions</RootNamespace>
+    <AssemblyName>Lucene.Net.Tests.Expressions</AssemblyName>
+    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="JS\TestCustomFunctions.cs" />
+    <Compile Include="JS\TestJavascriptCompiler.cs" />
+    <Compile Include="JS\TestJavascriptFunction.cs" />
+    <Compile Include="JS\TestJavascriptOperations.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TestDemoExpressions.cs" />
+    <Compile Include="TestExpressionRescorer.cs" />
+    <Compile Include="TestExpressionSortField.cs" />
+    <Compile Include="TestExpressionSorts.cs" />
+    <Compile Include="TestExpressionValidation.cs" />
+    <Compile Include="TestExpressionValueSource.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Lucene.Net.Core\Lucene.Net.csproj">
+      <Project>{5D4AD9BE-1FFB-41AB-9943-25737971BF57}</Project>
+      <Name>Lucene.Net</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Lucene.Net.Expressions\Lucene.Net.Expressions.csproj">
+      <Project>{DC83004C-183A-4E1A-ABEA-4FE95B4BC079}</Project>
+      <Name>Lucene.Net.Expressions</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Lucene.Net.Queries\Lucene.Net.Queries.csproj">
+      <Project>{69D7956C-C2CC-4708-B399-A188FEC384C4}</Project>
+      <Name>Lucene.Net.Queries</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Lucene.Net.TestFramework\Lucene.Net.TestFramework.csproj">
+      <Project>{B2C0D749-CE34-4F62-A15E-00CB2FF5DDB3}</Project>
+      <Name>Lucene.Net.TestFramework</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/Properties/AssemblyInfo.cs b/src/Lucene.Net.Tests.Expressions/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29105
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Lucene.Net.Tests.Expressions")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Lucene.Net.Tests.Expressions")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("0c789606-781d-47dc-b391-5ac367fce258")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/TestDemoExpressions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/TestDemoExpressions.cs b/src/Lucene.Net.Tests.Expressions/TestDemoExpressions.cs
new file mode 100644
index 0000000..3adc45a
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/TestDemoExpressions.cs
@@ -0,0 +1,202 @@
+using System;
+using System.Text;
+using Lucene.Net.Documents;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Store;
+using NUnit.Framework;
+using Expression = System.Linq.Expressions.Expression;
+
+namespace Lucene.Net.Tests.Expressions
+{
+	/// <summary>simple demo of using expressions</summary>
+	public class TestDemoExpressions : Util.LuceneTestCase
+	{
+		internal IndexSearcher searcher;
+
+		internal DirectoryReader reader;
+
+		internal Directory dir;
+
+		[SetUp]
+		public override void SetUp()
+		{
+			base.SetUp();
+			dir = NewDirectory();
+			var iw = new RandomIndexWriter(Random(), dir);
+			var doc = new Document
+			{
+			    NewStringField("id", "1", Field.Store.YES),
+			    NewTextField("body", "some contents and more contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 5),
+			    new DoubleField("latitude", 40.759011, Field.Store.NO),
+			    new DoubleField("longitude", -73.9844722, Field.Store.NO)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "2", Field.Store.YES),
+			    NewTextField("body", "another document with different contents", Field.Store
+			        .NO),
+			    new NumericDocValuesField("popularity", 20),
+			    new DoubleField("latitude", 40.718266, Field.Store.NO),
+			    new DoubleField("longitude", -74.007819, Field.Store.NO)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "3", Field.Store.YES),
+			    NewTextField("body", "crappy contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 2),
+			    new DoubleField("latitude", 40.7051157, Field.Store.NO),
+			    new DoubleField("longitude", -74.0088305, Field.Store.NO)
+			};
+		    iw.AddDocument(doc);
+			reader = iw.Reader;
+			searcher = new IndexSearcher(reader);
+			iw.Dispose();
+		}
+
+		[TearDown]
+		public override void TearDown()
+		{
+			reader.Dispose();
+			dir.Dispose();
+			base.TearDown();
+		}
+
+		/// <summary>an example of how to rank by an expression</summary>
+		[Test]
+		public virtual void Test()
+		{
+			// compile an expression:
+			var 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_e.SCORE));
+			bindings.Add(new SortField("popularity", SortField.Type_e.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);
+		}
+
+		/// <summary>tests the returned sort values are correct</summary>
+		[Test]
+		public virtual void TestSortValues()
+		{
+			var expr = JavascriptCompiler.Compile("sqrt(_score)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.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 = (float)((double)d.Fields[0]);
+				AreEqual(expected, actual, CheckHits.ExplainToleranceDelta(expected, actual));
+			}
+		}
+
+		/// <summary>tests same binding used more than once in an expression</summary>
+		[Test]
+		public virtual void TestTwoOfSameBinding()
+		{
+			var expr = JavascriptCompiler.Compile("_score + _score");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.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 = 2 * d.Score;
+				float actual = (float)((double)d.Fields[0]);
+				AreEqual(expected, actual, CheckHits.ExplainToleranceDelta
+					(expected, actual));
+			}
+		}
+
+		/// <summary>tests expression referring to another expression</summary>
+		[Test]
+		public virtual void TestExpressionRefersToExpression()
+		{
+			var expr1 = JavascriptCompiler.Compile("_score");
+			var expr2 = JavascriptCompiler.Compile("2*expr1");
+			var bindings = new SimpleBindings();
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			bindings.Add("expr1", expr1);
+			Sort sort = new Sort(expr2.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 = 2 * d.Score;
+				float actual = (float)((double)d.Fields[0]);
+				AreEqual(expected, actual, CheckHits.ExplainToleranceDelta
+					(expected, actual));
+			}
+		}
+
+		/// <summary>tests huge amounts of variables in the expression</summary>
+		[Test]
+		public virtual void TestLotsOfBindings()
+		{
+			DoTestLotsOfBindings(byte.MaxValue - 1);
+			DoTestLotsOfBindings(byte.MaxValue);
+			DoTestLotsOfBindings(byte.MaxValue + 1);
+		}
+
+		// TODO: ideally we'd test > Short.MAX_VALUE too, but compilation is currently recursive.
+		// so if we want to test such huge expressions, we need to instead change parser to use an explicit Stack
+		/// <exception cref="System.Exception"></exception>
+		private void DoTestLotsOfBindings(int n)
+		{
+			SimpleBindings bindings = new SimpleBindings();
+			StringBuilder sb = new StringBuilder();
+			for (int i = 0; i < n; i++)
+			{
+				if (i > 0)
+				{
+					sb.Append("+");
+				}
+				sb.Append("x" + i);
+				bindings.Add(new SortField("x" + i, SortField.Type_e.SCORE));
+			}
+			var expr = JavascriptCompiler.Compile(sb.ToString());
+			var 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_1 = 0; i_1 < 3; i_1++)
+			{
+				FieldDoc d = (FieldDoc)td.ScoreDocs[i_1];
+				float expected = n * d.Score;
+				float actual = (float)((double)d.Fields[0]);
+				AreEqual(expected, actual, CheckHits.ExplainToleranceDelta(expected, actual));
+			}
+		}
+
+		[Test]
+		public virtual void TestDistanceSort()
+		{
+			var distance = JavascriptCompiler.Compile("haversin(40.7143528,-74.0059731,latitude,longitude)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("latitude", SortField.Type_e.DOUBLE));
+			bindings.Add(new SortField("longitude", SortField.Type_e.DOUBLE));
+			Sort sort = new Sort(distance.GetSortField(bindings, false));
+			TopFieldDocs td = searcher.Search(new MatchAllDocsQuery(), null, 3, sort);
+			FieldDoc d = (FieldDoc)td.ScoreDocs[0];
+			AreEqual(0.4619D, (double)d.Fields[0], 1E-4);
+			d = (FieldDoc)td.ScoreDocs[1];
+			AreEqual(1.0546D, (double)d.Fields[0], 1E-4);
+			d = (FieldDoc)td.ScoreDocs[2];
+			AreEqual(5.2842D, (double)d.Fields[0], 1E-4);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Tests.Expressions/TestExpressionRescorer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Expressions/TestExpressionRescorer.cs b/src/Lucene.Net.Tests.Expressions/TestExpressionRescorer.cs
new file mode 100644
index 0000000..301e6f9
--- /dev/null
+++ b/src/Lucene.Net.Tests.Expressions/TestExpressionRescorer.cs
@@ -0,0 +1,92 @@
+using Lucene.Net.Documents;
+using Lucene.Net.Expressions;
+using Lucene.Net.Expressions.JS;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Store;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Expressions
+{
+	public class TestExpressionRescorer : Lucene.Net.Util.LuceneTestCase
+	{
+		internal IndexSearcher searcher;
+
+		internal DirectoryReader reader;
+
+		internal Directory dir;
+
+		[SetUp]
+		public override void SetUp()
+		{
+			base.SetUp();
+			dir = NewDirectory();
+			var iw = new RandomIndexWriter(Random(), dir);
+			var doc = new Document
+			{
+			    NewStringField("id", "1", Field.Store.YES),
+			    NewTextField("body", "some contents and more contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 5)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "2", Field.Store.YES),
+			    NewTextField("body", "another document with different contents", Field.Store
+			        .NO),
+			    new NumericDocValuesField("popularity", 20)
+			};
+		    iw.AddDocument(doc);
+			doc = new Document
+			{
+			    NewStringField("id", "3", Field.Store.YES),
+			    NewTextField("body", "crappy contents", Field.Store.NO),
+			    new NumericDocValuesField("popularity", 2)
+			};
+		    iw.AddDocument(doc);
+			reader = iw.Reader;
+			searcher = new IndexSearcher(reader);
+			iw.Dispose();
+		}
+
+		[TearDown]
+		public override void TearDown()
+		{
+			reader.Dispose();
+			dir.Dispose();
+			base.TearDown();
+		}
+
+		[Test]
+		public virtual void TestBasic()
+		{
+			// create a sort field and sort by it (reverse order)
+			Query query = new TermQuery(new Term("body", "contents"));
+			IndexReader r = searcher.IndexReader;
+			// Just first pass query
+			TopDocs hits = searcher.Search(query, 10);
+			AreEqual(3, hits.TotalHits);
+			AreEqual("3", r.Document(hits.ScoreDocs[0].Doc).Get("id"));
+			AreEqual("1", r.Document(hits.ScoreDocs[1].Doc).Get("id"));
+			AreEqual("2", r.Document(hits.ScoreDocs[2].Doc).Get("id"));
+			// Now, rescore:
+			Expression e = JavascriptCompiler.Compile("sqrt(_score) + ln(popularity)");
+			SimpleBindings bindings = new SimpleBindings();
+			bindings.Add(new SortField("popularity", SortField.Type_e.INT));
+			bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
+			Rescorer rescorer = e.GetRescorer(bindings);
+			hits = rescorer.Rescore(searcher, hits, 10);
+			AreEqual(3, hits.TotalHits);
+			AreEqual("2", r.Document(hits.ScoreDocs[0].Doc).Get("id"));
+			AreEqual("1", r.Document(hits.ScoreDocs[1].Doc).Get("id"));
+			AreEqual("3", r.Document(hits.ScoreDocs[2].Doc).Get("id"));
+			string expl = rescorer.Explain(searcher, searcher.Explain(query, hits.ScoreDocs[0].Doc), hits.ScoreDocs[0].Doc).ToString();
+			// Confirm the explanation breaks out the individual
+			// variables:
+			IsTrue(expl.Contains("= variable \"popularity\""));
+			// Confirm the explanation includes first pass details:
+			IsTrue(expl.Contains("= first pass score"));
+			IsTrue(expl.Contains("body:contents in"));
+		}
+	}
+}


[4/5] lucenenet git commit: Adding Expressions with some failing tests

Posted by sy...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b6c1b5d2/src/Lucene.Net.Expressions/JS/JavascriptLexer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Expressions/JS/JavascriptLexer.cs b/src/Lucene.Net.Expressions/JS/JavascriptLexer.cs
new file mode 100644
index 0000000..90c770e
--- /dev/null
+++ b/src/Lucene.Net.Expressions/JS/JavascriptLexer.cs
@@ -0,0 +1,2177 @@
+using System;
+using Antlr.Runtime;
+
+namespace Lucene.Net.Expressions.JS
+{
+	internal class JavascriptLexer : Lexer
+	{
+		public const int EOF = -1;
+
+		public const int AT_ADD = 4;
+
+		public const int AT_BIT_AND = 5;
+
+		public const int AT_BIT_NOT = 6;
+
+		public const int AT_BIT_OR = 7;
+
+		public const int AT_BIT_SHL = 8;
+
+		public const int AT_BIT_SHR = 9;
+
+		public const int AT_BIT_SHU = 10;
+
+		public const int AT_BIT_XOR = 11;
+
+		public const int AT_BOOL_AND = 12;
+
+		public const int AT_BOOL_NOT = 13;
+
+		public const int AT_BOOL_OR = 14;
+
+		public const int AT_CALL = 15;
+
+		public const int AT_COLON = 16;
+
+		public const int AT_COMMA = 17;
+
+		public const int AT_COMP_EQ = 18;
+
+		public const int AT_COMP_GT = 19;
+
+		public const int AT_COMP_GTE = 20;
+
+		public const int AT_COMP_LT = 21;
+
+		public const int AT_COMP_LTE = 22;
+
+		public const int AT_COMP_NEQ = 23;
+
+		public const int AT_COND_QUE = 24;
+
+		public const int AT_DIVIDE = 25;
+
+		public const int AT_DOT = 26;
+
+		public const int AT_LPAREN = 27;
+
+		public const int AT_MODULO = 28;
+
+		public const int AT_MULTIPLY = 29;
+
+		public const int AT_NEGATE = 30;
+
+		public const int AT_RPAREN = 31;
+
+		public const int AT_SUBTRACT = 32;
+
+		public const int DECIMAL = 33;
+
+		public const int DECIMALDIGIT = 34;
+
+		public const int DECIMALINTEGER = 35;
+
+		public const int EXPONENT = 36;
+
+		public const int HEX = 37;
+
+		public const int HEXDIGIT = 38;
+
+		public const int ID = 39;
+
+		public const int NAMESPACE_ID = 40;
+
+		public const int OCTAL = 41;
+
+		public const int OCTALDIGIT = 42;
+
+		public const int WS = 43;
+
+		// ANTLR GENERATED CODE: DO NOT EDIT
+		public override void DisplayRecognitionError(string[] tokenNames, RecognitionException re)
+		{
+			string message = " unexpected character '" + (char)re.Character + "' at position (" + re.CharPositionInLine + ").";
+			ParseException parseException = new ParseException(message, re.CharPositionInLine);
+			
+			throw new SystemException(parseException.Message, parseException);
+		}
+
+		// delegates
+		// delegators
+		public virtual Lexer[] GetDelegates()
+		{
+			return new Lexer[] {  };
+		}
+
+		public JavascriptLexer()
+		{
+			dfa9 = new JavascriptLexer.DFA9(this, this);
+		}
+
+		public JavascriptLexer(ICharStream input) : this(input, new RecognizerSharedState(
+			))
+		{
+			dfa9 = new JavascriptLexer.DFA9(this, this);
+		}
+
+		public JavascriptLexer(ICharStream input, RecognizerSharedState state) : base(input
+			, state)
+		{
+			dfa9 = new JavascriptLexer.DFA9(this, this);
+		}
+
+		public override string GrammarFileName
+		{
+		    get { return ""; }
+		}
+
+		// $ANTLR start "AT_ADD"
+		
+		public void MAT_ADD()
+		{
+			try
+			{
+				int _type = AT_ADD;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BIT_AND()
+		{
+		    int _type = AT_BIT_AND;
+		    int _channel = TokenChannels.Default;
+		    {
+		        // 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;
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "AT_BIT_AND"
+		// $ANTLR start "AT_BIT_NOT"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BIT_NOT()
+		{
+			try
+			{
+				int _type = AT_BIT_NOT;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BIT_OR()
+		{
+			try
+			{
+				int _type = AT_BIT_OR;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BIT_SHL()
+		{
+			try
+			{
+				int _type = AT_BIT_SHL;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BIT_SHR()
+		{
+			try
+			{
+				int _type = AT_BIT_SHR;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BIT_SHU()
+		{
+			try
+			{
+				int _type = AT_BIT_SHU;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BIT_XOR()
+		{
+			try
+			{
+				int _type = AT_BIT_XOR;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BOOL_AND()
+		{
+			try
+			{
+				int _type = AT_BOOL_AND;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BOOL_NOT()
+		{
+			try
+			{
+				int _type = AT_BOOL_NOT;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_BOOL_OR()
+		{
+			try
+			{
+				int _type = AT_BOOL_OR;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COLON()
+		{
+			try
+			{
+				int _type = AT_COLON;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COMMA()
+		{
+			try
+			{
+				int _type = AT_COMMA;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COMP_EQ()
+		{
+			try
+			{
+				int _type = AT_COMP_EQ;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COMP_GT()
+		{
+			try
+			{
+				int _type = AT_COMP_GT;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COMP_GTE()
+		{
+			try
+			{
+				int _type = AT_COMP_GTE;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COMP_LT()
+		{
+			try
+			{
+				int _type = AT_COMP_LT;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COMP_LTE()
+		{
+			try
+			{
+				int _type = AT_COMP_LTE;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COMP_NEQ()
+		{
+			try
+			{
+				int _type = AT_COMP_NEQ;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_COND_QUE()
+		{
+			try
+			{
+				int _type = AT_COND_QUE;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_DIVIDE()
+		{
+			try
+			{
+				int _type = AT_DIVIDE;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_DOT()
+		{
+			try
+			{
+				int _type = AT_DOT;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_LPAREN()
+		{
+			try
+			{
+				int _type = AT_LPAREN;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_MODULO()
+		{
+			try
+			{
+				int _type = AT_MODULO;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_MULTIPLY()
+		{
+			try
+			{
+				int _type = AT_MULTIPLY;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_RPAREN()
+		{
+			try
+			{
+				int _type = AT_RPAREN;
+				int _channel = TokenChannels.Default;
+				{
+					// 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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MAT_SUBTRACT()
+		{
+			try
+			{
+				int _type = AT_SUBTRACT;
+				int _channel = TokenChannels.Default;
+				{
+					// 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 "NAMESPACE_ID"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MNAMESPACE_ID()
+		{
+			try
+			{
+				int _type = NAMESPACE_ID;
+				int _channel = TokenChannels.Default;
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:334:5: ( ID ( AT_DOT ID )* )
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:334:7: ID ( AT_DOT ID )*
+					MID();
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:334:10: ( AT_DOT ID )*
+					while (true)
+					{
+						int alt1 = 2;
+						int LA1_0 = input.LA(1);
+						if ((LA1_0 == '.'))
+						{
+							alt1 = 1;
+						}
+						switch (alt1)
+						{
+							case 1:
+							{
+								// src/java/org/apache/lucene/expressions/js/Javascript.g:334:11: AT_DOT ID
+								MAT_DOT();
+								MID();
+								break;
+							}
+
+							default:
+							{
+								goto loop1_break;
+								break;
+							}
+						}
+loop1_continue: ;
+					}
+loop1_break: ;
+				}
+				state.type = _type;
+				state.channel = _channel;
+			}
+			finally
+			{
+			}
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "NAMESPACE_ID"
+		// $ANTLR start "ID"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MID()
+		{
+			try
+			{
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:340:5: ( ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )* )
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:340: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:340:31: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
+					while (true)
+					{
+						int alt2 = 2;
+						int LA2_0 = input.LA(1);
+						if (((LA2_0 >= '0' && LA2_0 <= '9') || (LA2_0 >= 'A' && LA2_0 <= 'Z') || LA2_0 ==
+							 '_' || (LA2_0 >= 'a' && LA2_0 <= 'z')))
+						{
+							alt2 = 1;
+						}
+						switch (alt2)
+						{
+							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:
+							{
+								goto loop2_break;
+								break;
+							}
+						}
+loop2_continue: ;
+					}
+loop2_break: ;
+				}
+			}
+			finally
+			{
+			}
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "ID"
+		// $ANTLR start "WS"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MWS()
+		{
+			try
+			{
+				int _type = WS;
+				int _channel = TokenChannels.Default;
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:343:5: ( ( ' ' | '\\t' | '\\n' | '\\r' )+ )
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:343:7: ( ' ' | '\\t' | '\\n' | '\\r' )+
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:343:7: ( ' ' | '\\t' | '\\n' | '\\r' )+
+					int cnt3 = 0;
+					while (true)
+					{
+						int alt3 = 2;
+						int LA3_0 = input.LA(1);
+						if (((LA3_0 >= '\t' && LA3_0 <= '\n') || LA3_0 == '\r' || LA3_0 == ' '))
+						{
+							alt3 = 1;
+						}
+						switch (alt3)
+						{
+							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 (cnt3 >= 1)
+								{
+									goto loop3_break;
+								}
+								EarlyExitException eee = new EarlyExitException(3, input);
+								throw eee;
+							}
+						}
+						cnt3++;
+loop3_continue: ;
+					}
+loop3_break: ;
+					Skip();
+				}
+				state.type = _type;
+				state.channel = _channel;
+			}
+			finally
+			{
+			}
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "WS"
+		// $ANTLR start "DECIMAL"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MDECIMAL()
+		{
+			try
+			{
+				int _type = DECIMAL;
+				int _channel = TokenChannels.Default;
+				// src/java/org/apache/lucene/expressions/js/Javascript.g:347:5: ( DECIMALINTEGER AT_DOT ( DECIMALDIGIT )* ( EXPONENT )? | AT_DOT ( DECIMALDIGIT )+ ( EXPONENT )? | DECIMALINTEGER ( EXPONENT )? )
+				int alt9 = 3;
+				alt9 = dfa9.Predict(input);
+				switch (alt9)
+				{
+					case 1:
+					{
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:347:7: DECIMALINTEGER AT_DOT ( DECIMALDIGIT )* ( EXPONENT )?
+						MDECIMALINTEGER();
+						MAT_DOT();
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:347:29: ( DECIMALDIGIT )*
+						while (true)
+						{
+							int alt4 = 2;
+							int LA4_0 = input.LA(1);
+							if (((LA4_0 >= '0' && LA4_0 <= '9')))
+							{
+								alt4 = 1;
+							}
+							switch (alt4)
+							{
+								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:
+								{
+									goto loop4_break;
+									break;
+								}
+							}
+loop4_continue: ;
+						}
+loop4_break: ;
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:347:43: ( EXPONENT )?
+						int alt5 = 2;
+						int LA5_0 = input.LA(1);
+						if ((LA5_0 == 'E' || LA5_0 == 'e'))
+						{
+							alt5 = 1;
+						}
+						switch (alt5)
+						{
+							case 1:
+							{
+								// src/java/org/apache/lucene/expressions/js/Javascript.g:347:43: EXPONENT
+								MEXPONENT();
+								break;
+							}
+						}
+						break;
+					}
+
+					case 2:
+					{
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:348:7: AT_DOT ( DECIMALDIGIT )+ ( EXPONENT )?
+						MAT_DOT();
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:348:14: ( DECIMALDIGIT )+
+						int cnt6 = 0;
+						while (true)
+						{
+							int alt6 = 2;
+							int LA6_0 = input.LA(1);
+							if (((LA6_0 >= '0' && LA6_0 <= '9')))
+							{
+								alt6 = 1;
+							}
+							switch (alt6)
+							{
+								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 (cnt6 >= 1)
+									{
+										goto loop6_break;
+									}
+									EarlyExitException eee = new EarlyExitException(6, input);
+									throw eee;
+								}
+							}
+							cnt6++;
+loop6_continue: ;
+						}
+loop6_break: ;
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:348:28: ( 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:348:28: EXPONENT
+								MEXPONENT();
+								break;
+							}
+						}
+						break;
+					}
+
+					case 3:
+					{
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:349:7: DECIMALINTEGER ( EXPONENT )?
+						MDECIMALINTEGER();
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:349:22: ( EXPONENT )?
+						int alt8 = 2;
+						int LA8_0 = input.LA(1);
+						if ((LA8_0 == 'E' || LA8_0 == 'e'))
+						{
+							alt8 = 1;
+						}
+						switch (alt8)
+						{
+							case 1:
+							{
+								// src/java/org/apache/lucene/expressions/js/Javascript.g:349:22: EXPONENT
+								MEXPONENT();
+								break;
+							}
+						}
+						break;
+					}
+				}
+				state.type = _type;
+				state.channel = _channel;
+			}
+			finally
+			{
+			}
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "DECIMAL"
+		// $ANTLR start "OCTAL"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MOCTAL()
+		{
+			try
+			{
+				int _type = OCTAL;
+				int _channel = TokenChannels.Default;
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:353:5: ( '0' ( OCTALDIGIT )+ )
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:353:7: '0' ( OCTALDIGIT )+
+					Match('0');
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:353:11: ( OCTALDIGIT )+
+					int cnt10 = 0;
+					while (true)
+					{
+						int alt10 = 2;
+						int LA10_0 = input.LA(1);
+						if (((LA10_0 >= '0' && LA10_0 <= '7')))
+						{
+							alt10 = 1;
+						}
+						switch (alt10)
+						{
+							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 (cnt10 >= 1)
+								{
+									goto loop10_break;
+								}
+								EarlyExitException eee = new EarlyExitException(10, input);
+								throw eee;
+							}
+						}
+						cnt10++;
+loop10_continue: ;
+					}
+loop10_break: ;
+				}
+				state.type = _type;
+				state.channel = _channel;
+			}
+			finally
+			{
+			}
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "OCTAL"
+		// $ANTLR start "HEX"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MHEX()
+		{
+			try
+			{
+				int _type = HEX;
+				int _channel = TokenChannels.Default;
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:357:5: ( ( '0x' | '0X' ) ( HEXDIGIT )+ )
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:357:7: ( '0x' | '0X' ) ( HEXDIGIT )+
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:357:7: ( '0x' | '0X' )
+					int alt11 = 2;
+					int LA11_0 = input.LA(1);
+					if ((LA11_0 == '0'))
+					{
+						int LA11_1 = input.LA(2);
+						if ((LA11_1 == 'x'))
+						{
+							alt11 = 1;
+						}
+						else
+						{
+							if ((LA11_1 == 'X'))
+							{
+								alt11 = 2;
+							}
+							else
+							{
+								int nvaeMark = input.Mark();
+								try
+								{
+									input.Consume();
+									NoViableAltException nvae = new NoViableAltException(string.Empty, 11, 1, input);
+									throw nvae;
+								}
+								finally
+								{
+									input.Rewind(nvaeMark);
+								}
+							}
+						}
+					}
+					else
+					{
+						NoViableAltException nvae = new NoViableAltException(string.Empty, 11, 0, input);
+						throw nvae;
+					}
+					switch (alt11)
+					{
+						case 1:
+						{
+							// src/java/org/apache/lucene/expressions/js/Javascript.g:357:8: '0x'
+							Match("0x");
+							break;
+						}
+
+						case 2:
+						{
+							// src/java/org/apache/lucene/expressions/js/Javascript.g:357:13: '0X'
+							Match("0X");
+							break;
+						}
+					}
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:357:19: ( HEXDIGIT )+
+					int cnt12 = 0;
+					while (true)
+					{
+						int alt12 = 2;
+						int LA12_0 = input.LA(1);
+						if (((LA12_0 >= '0' && LA12_0 <= '9') || (LA12_0 >= 'A' && LA12_0 <= 'F') || (LA12_0
+							 >= 'a' && LA12_0 <= 'f')))
+						{
+							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.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 (cnt12 >= 1)
+								{
+									goto loop12_break;
+								}
+								EarlyExitException eee = new EarlyExitException(12, input);
+								throw eee;
+							}
+						}
+						cnt12++;
+loop12_continue: ;
+					}
+loop12_break: ;
+				}
+				state.type = _type;
+				state.channel = _channel;
+			}
+			finally
+			{
+			}
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "HEX"
+		// $ANTLR start "DECIMALINTEGER"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MDECIMALINTEGER()
+		{
+			try
+			{
+				// src/java/org/apache/lucene/expressions/js/Javascript.g:363:5: ( '0' | '1' .. '9' ( DECIMALDIGIT )* )
+				int alt14 = 2;
+				int LA14_0 = input.LA(1);
+				if ((LA14_0 == '0'))
+				{
+					alt14 = 1;
+				}
+				else
+				{
+					if (((LA14_0 >= '1' && LA14_0 <= '9')))
+					{
+						alt14 = 2;
+					}
+					else
+					{
+						NoViableAltException nvae = new NoViableAltException(string.Empty, 14, 0, input);
+						throw nvae;
+					}
+				}
+				switch (alt14)
+				{
+					case 1:
+					{
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:363:7: '0'
+						Match('0');
+						break;
+					}
+
+					case 2:
+					{
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:364:7: '1' .. '9' ( DECIMALDIGIT )*
+						MatchRange('1', '9');
+						// src/java/org/apache/lucene/expressions/js/Javascript.g:364:16: ( DECIMALDIGIT )*
+						while (true)
+						{
+							int alt13 = 2;
+							int LA13_0 = input.LA(1);
+							if (((LA13_0 >= '0' && LA13_0 <= '9')))
+							{
+								alt13 = 1;
+							}
+							switch (alt13)
+							{
+								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:
+								{
+									goto loop13_break;
+									break;
+								}
+							}
+loop13_continue: ;
+						}
+loop13_break: ;
+						break;
+					}
+				}
+			}
+			finally
+			{
+			}
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "DECIMALINTEGER"
+		// $ANTLR start "EXPONENT"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MEXPONENT()
+		{
+			try
+			{
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:369:5: ( ( 'e' | 'E' ) ( '+' | '-' )? ( DECIMALDIGIT )+ )
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:369: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:369:17: ( '+' | '-' )?
+					int alt15 = 2;
+					int LA15_0 = input.LA(1);
+					if ((LA15_0 == '+' || LA15_0 == '-'))
+					{
+						alt15 = 1;
+					}
+					switch (alt15)
+					{
+						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:369:28: ( DECIMALDIGIT )+
+					int cnt16 = 0;
+					while (true)
+					{
+						int alt16 = 2;
+						int LA16_0 = input.LA(1);
+						if (((LA16_0 >= '0' && LA16_0 <= '9')))
+						{
+							alt16 = 1;
+						}
+						switch (alt16)
+						{
+							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 (cnt16 >= 1)
+								{
+									goto loop16_break;
+								}
+								EarlyExitException eee = new EarlyExitException(16, input);
+								throw eee;
+							}
+						}
+						cnt16++;
+loop16_continue: ;
+					}
+loop16_break: ;
+				}
+			}
+			finally
+			{
+			}
+		}
+
+		// do for sure before leaving
+		// $ANTLR end "EXPONENT"
+		// $ANTLR start "DECIMALDIGIT"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MDECIMALDIGIT()
+		{
+			try
+			{
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:374: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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MHEXDIGIT()
+		{
+			try
+			{
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:379: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"
+		/// <exception cref="Org.Antlr.Runtime.RecognitionException"></exception>
+		public void MOCTALDIGIT()
+		{
+			try
+			{
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:386: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 override void mTokens()
+		{
+			// 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 | NAMESPACE_ID | WS | DECIMAL | OCTAL | HEX )
+			int alt17 = 32;
+			switch (input.LA(1))
+			{
+				case '+':
+				{
+					alt17 = 1;
+					break;
+				}
+
+				case '&':
+				{
+					int LA17_2 = input.LA(2);
+					if ((LA17_2 == '&'))
+					{
+						alt17 = 9;
+					}
+					else
+					{
+						alt17 = 2;
+					}
+					break;
+				}
+
+				case '~':
+				{
+					alt17 = 3;
+					break;
+				}
+
+				case '|':
+				{
+					int LA17_4 = input.LA(2);
+					if ((LA17_4 == '|'))
+					{
+						alt17 = 11;
+					}
+					else
+					{
+						alt17 = 4;
+					}
+					break;
+				}
+
+				case '<':
+				{
+					switch (input.LA(2))
+					{
+						case '<':
+						{
+							alt17 = 5;
+							break;
+						}
+
+						case '=':
+						{
+							alt17 = 18;
+							break;
+						}
+
+						default:
+						{
+							alt17 = 17;
+							break;
+						}
+					}
+					break;
+				}
+
+				case '>':
+				{
+					switch (input.LA(2))
+					{
+						case '>':
+						{
+							int LA17_31 = input.LA(3);
+							if ((LA17_31 == '>'))
+							{
+								alt17 = 7;
+							}
+							else
+							{
+								alt17 = 6;
+							}
+							break;
+						}
+
+						case '=':
+						{
+							alt17 = 16;
+							break;
+						}
+
+						default:
+						{
+							alt17 = 15;
+							break;
+						}
+					}
+					break;
+				}
+
+				case '^':
+				{
+					alt17 = 8;
+					break;
+				}
+
+				case '!':
+				{
+					int LA17_8 = input.LA(2);
+					if ((LA17_8 == '='))
+					{
+						alt17 = 19;
+					}
+					else
+					{
+						alt17 = 10;
+					}
+					break;
+				}
+
+				case ':':
+				{
+					alt17 = 12;
+					break;
+				}
+
+				case ',':
+				{
+					alt17 = 13;
+					break;
+				}
+
+				case '=':
+				{
+					alt17 = 14;
+					break;
+				}
+
+				case '?':
+				{
+					alt17 = 20;
+					break;
+				}
+
+				case '/':
+				{
+					alt17 = 21;
+					break;
+				}
+
+				case '.':
+				{
+					int LA17_14 = input.LA(2);
+					if (((LA17_14 >= '0' && LA17_14 <= '9')))
+					{
+						alt17 = 30;
+					}
+					else
+					{
+						alt17 = 22;
+					}
+					break;
+				}
+
+				case '(':
+				{
+					alt17 = 23;
+					break;
+				}
+
+				case '%':
+				{
+					alt17 = 24;
+					break;
+				}
+
+				case '*':
+				{
+					alt17 = 25;
+					break;
+				}
+
+				case ')':
+				{
+					alt17 = 26;
+					break;
+				}
+
+				case '-':
+				{
+					alt17 = 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':
+				{
+					alt17 = 28;
+					break;
+				}
+
+				case '\t':
+				case '\n':
+				case '\r':
+				case ' ':
+				{
+					alt17 = 29;
+					break;
+				}
+
+				case '0':
+				{
+					switch (input.LA(2))
+					{
+						case 'X':
+						case 'x':
+						{
+							alt17 = 32;
+							break;
+						}
+
+						case '0':
+						case '1':
+						case '2':
+						case '3':
+						case '4':
+						case '5':
+						case '6':
+						case '7':
+						{
+							alt17 = 31;
+							break;
+						}
+
+						default:
+						{
+							alt17 = 30;
+							break;
+						}
+					}
+					break;
+				}
+
+				case '1':
+				case '2':
+				case '3':
+				case '4':
+				case '5':
+				case '6':
+				case '7':
+				case '8':
+				case '9':
+				{
+					alt17 = 30;
+					break;
+				}
+
+				default:
+				{
+					NoViableAltException nvae = new NoViableAltException(string.Empty, 17, 0, input);
+					throw nvae;
+				}
+			}
+			switch (alt17)
+			{
+				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: NAMESPACE_ID
+					MNAMESPACE_ID();
+					break;
+				}
+
+				case 29:
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:1:311: WS
+					MWS();
+					break;
+				}
+
+				case 30:
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:1:314: DECIMAL
+					MDECIMAL();
+					break;
+				}
+
+				case 31:
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:1:322: OCTAL
+					MOCTAL();
+					break;
+				}
+
+				case 32:
+				{
+					// src/java/org/apache/lucene/expressions/js/Javascript.g:1:328: HEX
+					MHEX();
+					break;
+				}
+			}
+		}
+
+		protected internal JavascriptLexer.DFA9 dfa9;
+
+		internal static readonly string DFA9_eotS = "\x1\uffff\x2\x4\x3\uffff\x1\x4";
+
+		internal static readonly string DFA9_eofS = "\x7\uffff";
+
+		internal static readonly string DFA9_minS = "\x3\x38\x3\uffff\x1\x38";
+
+		internal static readonly string DFA9_maxS = "\x1\x47\x1\x38\x1\x47\x3\uffff\x1\x47";
+
+		internal static readonly string DFA9_acceptS = "\x3\uffff\x1\x2\x1\x3\x1\x1\x1\uffff";
+
+		internal static readonly string DFA9_specialS = "\x7\uffff}>";
+
+		internal static readonly string[] DFA9_transitionS = new string[] { "\x1\x3\x1\uffff\x1\x1\xb\x2"
+			, "\x1\x5", "\x1\x5\x1\uffff\xc\x6", string.Empty, string.Empty, string.Empty, "\x1\x5\x1\uffff\xc\x6"
+			 };
+
+		internal static readonly short[] DFA9_eot = DFA.UnpackEncodedString(DFA9_eotS);
+
+		internal static readonly short[] DFA9_eof = DFA.UnpackEncodedString(DFA9_eofS);
+
+		internal static readonly char[] DFA9_min = DFA.UnpackEncodedStringToUnsignedChars
+			(DFA9_minS);
+
+		internal static readonly char[] DFA9_max = DFA.UnpackEncodedStringToUnsignedChars
+			(DFA9_maxS);
+
+		internal static readonly short[] DFA9_accept = DFA.UnpackEncodedString(DFA9_acceptS
+			);
+
+		internal static readonly short[] DFA9_special = DFA.UnpackEncodedString(DFA9_specialS
+			);
+
+		internal static readonly short[][] DFA9_transition;
+
+		static JavascriptLexer()
+		{
+			
+			int numStates = DFA9_transitionS.Length;
+			DFA9_transition = new short[numStates][];
+			for (int i = 0; i < numStates; i++)
+			{
+				DFA9_transition[i] = DFA.UnpackEncodedString(DFA9_transitionS[i]);
+			}
+		}
+
+		protected internal class DFA9 : DFA
+		{
+			public DFA9(JavascriptLexer _enclosing, BaseRecognizer recognizer)
+			{
+				this._enclosing = _enclosing;
+				this.recognizer = recognizer;
+				this.decisionNumber = 9;
+				this.eot = JavascriptLexer.DFA9_eot;
+				this.eof = JavascriptLexer.DFA9_eof;
+				this.min = JavascriptLexer.DFA9_min;
+				this.max = JavascriptLexer.DFA9_max;
+				this.accept = JavascriptLexer.DFA9_accept;
+				this.special = JavascriptLexer.DFA9_special;
+				this.transition = JavascriptLexer.DFA9_transition;
+			}
+
+			public override string Description
+			{
+			    get
+			    {
+			        return
+			            "346:1: DECIMAL : ( DECIMALINTEGER AT_DOT ( DECIMALDIGIT )* ( EXPONENT )? | AT_DOT ( DECIMALDIGIT )+ ( EXPONENT )? | DECIMALINTEGER ( EXPONENT )? );";
+			    }
+			}
+
+			private readonly JavascriptLexer _enclosing;
+		}
+	}
+
+    public class ParseException:Exception
+    {
+        public ParseException(string message, int charPositionInLine)
+        {
+            
+        }
+    }
+}