You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by ce...@apache.org on 2016/12/14 21:24:52 UTC

[1/2] incubator-metron git commit: METRON-616: Added support for float and long literals in Stellar closes apache/incubator-metron#392

Repository: incubator-metron
Updated Branches:
  refs/heads/master 64a49adad -> ffae676cb


http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java
new file mode 100644
index 0000000..73a44b5
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.metron.common.utils.StellarProcessorUtils.run;
+import static org.apache.metron.common.utils.StellarProcessorUtils.runPredicate;
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+
+public class StellarComparisonExpressionWithOperatorTest {
+  @SuppressWarnings({"RedundantConditionalExpression", "ConstantConditions"})
+  @Test
+  public void checkLessThanComparisonOperators() throws Exception {
+    assertEquals(1 < 2, run("1 < 2", ImmutableMap.of()));
+    assertEquals(1f < 2, run("1f < 2", ImmutableMap.of()));
+    assertEquals(1f < 2d, run("1f < 2d", ImmutableMap.of()));
+    assertEquals(1f < 2e-4d, run("1f < 2e-4d", ImmutableMap.of()));
+    assertEquals(1L < 2e-4d, run("1L < 2e-4d", ImmutableMap.of()));
+    assertEquals(1 < 2e-4d, run("1 < 2e-4d", ImmutableMap.of()));
+    assertEquals(1 < 2L, run("1 < 2L", ImmutableMap.of()));
+    assertEquals(1.0f < 2.0f, run("1.0f < 2.0f", ImmutableMap.of()));
+    assertEquals(1L < 3.0f, run("1L < 3.0f", ImmutableMap.of()));
+    assertEquals(1 < 3.0f, run("1 < 3.0f", ImmutableMap.of()));
+    assertEquals(1.0 < 3.0f, run("1.0 < 3.0f", ImmutableMap.of()));
+    assertEquals(1L < 3.0f ? true : false, run("if 1L < 3.0f then true else false", ImmutableMap.of()));
+  }
+
+  @Test
+  public void checkComparisonOperationsWithFunctions() throws Exception {
+    assertEquals(1f >= 2, run("TO_FLOAT(1) >= 2", ImmutableMap.of()));
+    assertEquals(1f <= 2, run("TO_FLOAT(1) <= TO_FLOAT(2)", ImmutableMap.of()));
+    assertEquals(1f == 2, run("TO_FLOAT(1) == TO_LONG(2)", ImmutableMap.of()));
+    assertEquals(12.31f == 10.2f, run("TO_FLOAT(12.31) < 10.2f", ImmutableMap.of()));
+  }
+
+  @Test
+  public void testSimpleOps() throws Exception {
+    final Map<String, String> variableMap = new HashMap<String, String>() {{
+      put("foo", "casey");
+      put("empty", "");
+      put("spaced", "metron is great");
+      put("foo.bar", "casey");
+    }};
+
+    assertTrue(runPredicate("'casey' == foo.bar", variableMap::get));
+    assertTrue(runPredicate("'casey' == foo", variableMap::get));
+    assertFalse(runPredicate("'casey' != foo", variableMap::get));
+    assertTrue(runPredicate("'stella' == 'stella'", variableMap::get));
+    assertFalse(runPredicate("'stella' == foo", variableMap::get));
+    assertTrue(runPredicate("foo== foo", variableMap::get));
+    assertTrue(runPredicate("empty== ''", variableMap::get));
+    assertTrue(runPredicate("spaced == 'metron is great'", variableMap::get));
+    assertTrue(runPredicate(null, variableMap::get));
+    assertTrue(runPredicate("", variableMap::get));
+    assertTrue(runPredicate(" ", variableMap::get));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java
new file mode 100644
index 0000000..2dafac0
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar;
+
+import org.apache.metron.common.dsl.Context;
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.dsl.VariableResolver;
+import org.apache.metron.common.dsl.functions.resolver.FunctionResolver;
+import org.apache.metron.common.stellar.evaluators.ArithmeticEvaluator;
+import org.apache.metron.common.stellar.evaluators.NumberLiteralEvaluator;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.util.Stack;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verify;
+import static org.powermock.api.mockito.PowerMockito.*;
+
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ArithmeticEvaluator.class, NumberLiteralEvaluator.class})
+public class StellarCompilerTest {
+  VariableResolver variableResolver;
+  FunctionResolver functionResolver;
+  Context context;
+  Stack<Token<?>> tokenStack;
+  ArithmeticEvaluator arithmeticEvaluator;
+  NumberLiteralEvaluator numberLiteralEvaluator;
+  StellarCompiler compiler;
+
+  @SuppressWarnings("unchecked")
+  @Before
+  public void setUp() throws Exception {
+    variableResolver = mock(VariableResolver.class);
+    functionResolver = mock(FunctionResolver.class);
+    context = mock(Context.class);
+    tokenStack = mock(Stack.class);
+    arithmeticEvaluator = mock(ArithmeticEvaluator.class);
+    numberLiteralEvaluator = mock(NumberLiteralEvaluator.class);
+
+    compiler = new StellarCompiler(variableResolver, functionResolver, context, tokenStack, arithmeticEvaluator, numberLiteralEvaluator);
+  }
+
+  @Test
+  public void exitIntLiteralShouldProperlyParseStringsAsIntegers() throws Exception {
+    StellarParser.IntLiteralContext ctx = mock(StellarParser.IntLiteralContext.class);
+    when(ctx.getText()).thenReturn("1000");
+
+    compiler.exitIntLiteral(ctx);
+
+    verify(numberLiteralEvaluator).evaluate(ctx);
+    verify(tokenStack).push(any(Token.class));
+    verifyNoMoreInteractions(tokenStack);
+    verifyZeroInteractions(variableResolver);
+    verifyZeroInteractions(functionResolver);
+    verifyZeroInteractions(context);
+    verifyZeroInteractions(arithmeticEvaluator);
+  }
+
+  @Test
+  public void exitDoubleLiteralShouldProperlyParseStringsAsDoubles() throws Exception {
+    StellarParser.DoubleLiteralContext ctx = mock(StellarParser.DoubleLiteralContext.class);
+    when(ctx.getText()).thenReturn("1000D");
+
+    compiler.exitDoubleLiteral(ctx);
+
+    verify(numberLiteralEvaluator).evaluate(ctx);
+    verify(tokenStack).push(any(Token.class));
+    verifyNoMoreInteractions(tokenStack);
+    verifyZeroInteractions(variableResolver);
+    verifyZeroInteractions(functionResolver);
+    verifyZeroInteractions(context);
+    verifyZeroInteractions(arithmeticEvaluator);
+  }
+
+  @Test
+  public void exitFloatLiteralShouldProperlyParseStringsAsFloats() throws Exception {
+    StellarParser.FloatLiteralContext ctx = mock(StellarParser.FloatLiteralContext.class);
+    when(ctx.getText()).thenReturn("1000f");
+
+    compiler.exitFloatLiteral(ctx);
+
+    verify(numberLiteralEvaluator).evaluate(ctx);
+    verify(tokenStack).push(any(Token.class));
+    verifyNoMoreInteractions(tokenStack);
+    verifyZeroInteractions(variableResolver);
+    verifyZeroInteractions(functionResolver);
+    verifyZeroInteractions(context);
+    verifyZeroInteractions(arithmeticEvaluator);
+  }
+
+  @Test
+  public void exitLongLiteralShouldProperlyParseStringsAsLongs() throws Exception {
+    StellarParser.LongLiteralContext ctx = mock(StellarParser.LongLiteralContext.class);
+    when(ctx.getText()).thenReturn("1000l");
+
+    compiler.exitLongLiteral(ctx);
+
+    verify(numberLiteralEvaluator).evaluate(ctx);
+    verify(tokenStack).push(any(Token.class));
+    verifyNoMoreInteractions(tokenStack);
+    verifyZeroInteractions(variableResolver);
+    verifyZeroInteractions(functionResolver);
+    verifyZeroInteractions(context);
+    verifyZeroInteractions(arithmeticEvaluator);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
index 1f68e5d..2163f85 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
@@ -404,28 +404,6 @@ public class StellarTest {
     }
   }
 
-
-  @Test
-  public void testSimpleOps() throws Exception {
-    final Map<String, String> variableMap = new HashMap<String, String>() {{
-      put("foo", "casey");
-      put("empty", "");
-      put("spaced", "metron is great");
-      put("foo.bar", "casey");
-    }};
-    Assert.assertTrue(runPredicate("'casey' == foo.bar", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("'casey' == foo", v -> variableMap.get(v)));
-    Assert.assertFalse(runPredicate("'casey' != foo", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("'stella' == 'stella'", v -> variableMap.get(v)));
-    Assert.assertFalse(runPredicate("'stella' == foo", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("foo== foo", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("empty== ''", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("spaced == 'metron is great'", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate(null, v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate(" ", v -> variableMap.get(v)));
-  }
-
   @Test
   public void testBooleanOps() throws Exception {
     final Map<String, String> variableMap = new HashMap<String, String>() {{

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluatorTest.java
index 042f9ac..f914c3c 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluatorTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluatorTest.java
@@ -32,7 +32,7 @@ import static org.mockito.Mockito.when;
 
 @SuppressWarnings("unchecked")
 public class ArithmeticEvaluatorTest {
-  ArithmeticEvaluator evaluator = new ArithmeticEvaluator();
+  ArithmeticEvaluator evaluator = ArithmeticEvaluator.INSTANCE;
 
   @Test
   public void evaluateDoubleShouldReturnDoubleAdd() throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluatorTest.java
new file mode 100644
index 0000000..6f2fd40
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluatorTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.*;
+
+public class DoubleLiteralEvaluatorTest {
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
+
+  NumberEvaluator<StellarParser.DoubleLiteralContext> evaluator;
+  StellarParser.DoubleLiteralContext context;
+
+  @Before
+  public void setUp() throws Exception {
+    evaluator = new DoubleLiteralEvaluator();
+    context = mock(StellarParser.DoubleLiteralContext.class);
+  }
+
+  @Test
+  public void verifyHappyPathEvaluation() throws Exception {
+    when(context.getText()).thenReturn("100D");
+
+    Token<? extends Number> evaluated = evaluator.evaluate(context);
+    assertEquals(new Token<>(100D, Double.class), evaluated);
+
+    verify(context).getText();
+    verifyNoMoreInteractions(context);
+  }
+
+  @Test
+  public void verifyNumberFormationExceptionWithEmptyString() throws Exception {
+    exception.expect(NumberFormatException.class);
+
+    when(context.getText()).thenReturn("");
+    evaluator.evaluate(context);
+  }
+
+  @Test
+  public void throwIllegalArgumentExceptionWhenContextIsNull() throws Exception {
+    exception.expect(IllegalArgumentException.class);
+    exception.expectMessage("Cannot evaluate a context that is null.");
+
+    evaluator.evaluate(null);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluatorTest.java
new file mode 100644
index 0000000..4f7117a
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluatorTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class FloatLiteralEvaluatorTest {
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
+
+  NumberEvaluator<StellarParser.FloatLiteralContext> evaluator;
+  StellarParser.FloatLiteralContext context;
+
+  @Before
+  public void setUp() throws Exception {
+    evaluator = new FloatLiteralEvaluator();
+    context = mock(StellarParser.FloatLiteralContext.class);
+  }
+
+  @Test
+  public void verifyHappyPathEvaluation() throws Exception {
+    when(context.getText()).thenReturn("100f");
+
+    Token<? extends Number> evaluated = evaluator.evaluate(context);
+    assertEquals(new Token<>(100f, Float.class), evaluated);
+
+    verify(context).getText();
+    verifyNoMoreInteractions(context);
+  }
+
+  @Test
+  public void verifyNumberFormationExceptionWithEmptyString() throws Exception {
+    exception.expect(NumberFormatException.class);
+
+    when(context.getText()).thenReturn("");
+    evaluator.evaluate(context);
+  }
+
+  @Test
+  public void throwIllegalArgumentExceptionWhenContextIsNull() throws Exception {
+    exception.expect(IllegalArgumentException.class);
+    exception.expectMessage("Cannot evaluate a context that is null.");
+
+    evaluator.evaluate(null);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluatorTest.java
new file mode 100644
index 0000000..2fd081f
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluatorTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class IntLiteralEvaluatorTest {
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
+
+  NumberEvaluator<StellarParser.IntLiteralContext> evaluator;
+  StellarParser.IntLiteralContext context;
+
+  @Before
+  public void setUp() throws Exception {
+    evaluator = new IntLiteralEvaluator();
+    context = mock(StellarParser.IntLiteralContext.class);
+  }
+
+  @Test
+  public void verifyHappyPathEvaluation() throws Exception {
+    when(context.getText()).thenReturn("100");
+
+    Token<? extends Number> evaluated = evaluator.evaluate(context);
+    assertEquals(new Token<>(100, Integer.class), evaluated);
+
+    verify(context).getText();
+    verifyNoMoreInteractions(context);
+  }
+
+  @Test
+  public void verifyNumberFormationExceptionWithEmptyString() throws Exception {
+    exception.expect(NumberFormatException.class);
+
+    when(context.getText()).thenReturn("");
+    evaluator.evaluate(context);
+  }
+
+  @Test
+  public void throwIllegalArgumentExceptionWhenContextIsNull() throws Exception {
+    exception.expect(IllegalArgumentException.class);
+    exception.expectMessage("Cannot evaluate a context that is null.");
+
+    evaluator.evaluate(null);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluatorTest.java
new file mode 100644
index 0000000..21f75d4
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluatorTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.ParseException;
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class LongLiteralEvaluatorTest {
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
+
+  NumberEvaluator<StellarParser.LongLiteralContext> evaluator;
+  StellarParser.LongLiteralContext context;
+
+  @Before
+  public void setUp() throws Exception {
+    evaluator = new LongLiteralEvaluator();
+    context = mock(StellarParser.LongLiteralContext.class);
+  }
+
+  @Test
+  public void verifyHappyPathEvaluation() throws Exception {
+    when(context.getText()).thenReturn("100L");
+
+    Token<? extends Number> evaluated = evaluator.evaluate(context);
+    assertEquals(new Token<>(100L, Long.class), evaluated);
+
+    verify(context).getText();
+    verifyNoMoreInteractions(context);
+  }
+
+  @Test
+  public void verifyNumberFormationExceptionWithEmptyString() throws Exception {
+    exception.expect(ParseException.class);
+    exception.expectMessage("Invalid format for long. Failed trying to parse a long with the following value: ");
+
+    when(context.getText()).thenReturn("");
+    evaluator.evaluate(context);
+  }
+
+  @Test
+  public void throwIllegalArgumentExceptionWhenContextIsNull() throws Exception {
+    exception.expect(IllegalArgumentException.class);
+    exception.expectMessage("Cannot evaluate a context that is null.");
+
+    evaluator.evaluate(null);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluatorTest.java
new file mode 100644
index 0000000..8317737
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluatorTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.ParseException;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+public class NumberLiteralEvaluatorTest {
+  NumberEvaluator<StellarParser.IntLiteralContext> intLiteralContextNumberEvaluator;
+  NumberEvaluator<StellarParser.DoubleLiteralContext> doubleLiteralContextNumberEvaluator;
+  NumberEvaluator<StellarParser.FloatLiteralContext> floatLiteralContextNumberEvaluator;
+  NumberEvaluator<StellarParser.LongLiteralContext> longLiteralContextNumberEvaluator;
+
+  Map<Class<? extends StellarParser.Arithmetic_operandsContext>, NumberEvaluator> instanceMap;
+
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
+
+  @Before
+  public void setUp() throws Exception {
+    intLiteralContextNumberEvaluator = mock(IntLiteralEvaluator.class);
+    doubleLiteralContextNumberEvaluator = mock(DoubleLiteralEvaluator.class);
+    floatLiteralContextNumberEvaluator = mock(FloatLiteralEvaluator.class);
+    longLiteralContextNumberEvaluator = mock(LongLiteralEvaluator.class);
+    instanceMap = new HashMap<Class<? extends StellarParser.Arithmetic_operandsContext>, NumberEvaluator>() {{
+      put(mock(StellarParser.IntLiteralContext.class).getClass(), intLiteralContextNumberEvaluator);
+      put(mock(StellarParser.DoubleLiteralContext.class).getClass(), doubleLiteralContextNumberEvaluator);
+      put(mock(StellarParser.FloatLiteralContext.class).getClass(), floatLiteralContextNumberEvaluator);
+      put(mock(StellarParser.LongLiteralContext.class).getClass(), longLiteralContextNumberEvaluator);
+    }};
+  }
+
+  @Test
+  public void verifyIntLiteralContextIsProperlyEvaluated() throws Exception {
+    StellarParser.IntLiteralContext context = mock(StellarParser.IntLiteralContext.class);
+    NumberLiteralEvaluator.INSTANCE.evaluate(context, instanceMap);
+
+    verify(intLiteralContextNumberEvaluator).evaluate(context);
+    verifyZeroInteractions(doubleLiteralContextNumberEvaluator, floatLiteralContextNumberEvaluator, longLiteralContextNumberEvaluator);
+  }
+
+  @Test
+  public void verifyDoubleLiteralContextIsProperlyEvaluated() throws Exception {
+    StellarParser.DoubleLiteralContext context = mock(StellarParser.DoubleLiteralContext.class);
+    NumberLiteralEvaluator.INSTANCE.evaluate(context, instanceMap);
+
+    verify(doubleLiteralContextNumberEvaluator).evaluate(context);
+    verifyZeroInteractions(intLiteralContextNumberEvaluator, floatLiteralContextNumberEvaluator, longLiteralContextNumberEvaluator);
+  }
+
+  @Test
+  public void verifyFloatLiteralContextIsProperlyEvaluated() throws Exception {
+    StellarParser.FloatLiteralContext context = mock(StellarParser.FloatLiteralContext.class);
+    NumberLiteralEvaluator.INSTANCE.evaluate(context, instanceMap);
+
+    verify(floatLiteralContextNumberEvaluator).evaluate(context);
+    verifyZeroInteractions(doubleLiteralContextNumberEvaluator, intLiteralContextNumberEvaluator, longLiteralContextNumberEvaluator);
+  }
+
+  @Test
+  public void verifyLongLiteralContextIsProperlyEvaluated() throws Exception {
+    StellarParser.LongLiteralContext context = mock(StellarParser.LongLiteralContext.class);
+    NumberLiteralEvaluator.INSTANCE.evaluate(context, instanceMap);
+
+    verify(longLiteralContextNumberEvaluator).evaluate(context);
+    verifyZeroInteractions(doubleLiteralContextNumberEvaluator, floatLiteralContextNumberEvaluator, intLiteralContextNumberEvaluator);
+  }
+
+  @Test
+  public void verifyExceptionThrownForUnsupportedContextType() throws Exception {
+    StellarParser.VariableContext context = mock(StellarParser.VariableContext.class);
+
+    exception.expect(ParseException.class);
+    exception.expectMessage("Does not support evaluation for type " + context.getClass());
+
+    NumberLiteralEvaluator.INSTANCE.evaluate(context, instanceMap);
+
+    verifyZeroInteractions(longLiteralContextNumberEvaluator, doubleLiteralContextNumberEvaluator, floatLiteralContextNumberEvaluator, intLiteralContextNumberEvaluator);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/pom.xml
----------------------------------------------------------------------
diff --git a/metron-platform/pom.xml b/metron-platform/pom.xml
index fc00edd..001cb5a 100644
--- a/metron-platform/pom.xml
+++ b/metron-platform/pom.xml
@@ -76,6 +76,18 @@
 			<scope>test</scope>
 		</dependency>
 		<dependency>
+			<groupId>org.powermock</groupId>
+			<artifactId>powermock-module-junit4</artifactId>
+			<version>1.6.6</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.powermock</groupId>
+			<artifactId>powermock-api-mockito</artifactId>
+			<version>1.6.6</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
 			<groupId>org.adrianwalker</groupId>
 			<artifactId>multiline-string</artifactId>
 			<version>0.1.2</version>


[2/2] incubator-metron git commit: METRON-616: Added support for float and long literals in Stellar closes apache/incubator-metron#392

Posted by ce...@apache.org.
METRON-616: Added support for float and long literals in Stellar closes apache/incubator-metron#392


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

Branch: refs/heads/master
Commit: ffae676cb10caf14b8e3e5ca9c87ea1d5d08f4d1
Parents: 64a49ad
Author: JJ <jj...@gmail.com>
Authored: Wed Dec 14 16:24:40 2016 -0500
Committer: cstella <ce...@gmail.com>
Committed: Wed Dec 14 16:24:40 2016 -0500

----------------------------------------------------------------------
 metron-platform/metron-common/README.md         |   9 +-
 .../metron/common/stellar/generated/Stellar.g4  |  20 +-
 .../metron-common/src/main/java/Stellar.tokens  |  10 +-
 .../src/main/java/StellarLexer.tokens           |  10 +-
 .../common/stellar/BaseStellarProcessor.java    |  10 +-
 .../metron/common/stellar/StellarCompiler.java  |  39 ++-
 .../stellar/evaluators/ArithmeticEvaluator.java |   3 +-
 .../evaluators/DoubleLiteralEvaluator.java      |  33 +++
 .../evaluators/FloatLiteralEvaluator.java       |  33 +++
 .../stellar/evaluators/IntLiteralEvaluator.java |  33 +++
 .../evaluators/LongLiteralEvaluator.java        |  41 ++++
 .../stellar/evaluators/NumberEvaluator.java     |  26 ++
 .../evaluators/NumberLiteralEvaluator.java      |  69 ++++++
 .../stellar/generated/StellarBaseListener.java  |  24 ++
 .../common/stellar/generated/StellarLexer.java  | 243 +++++++++++--------
 .../stellar/generated/StellarListener.java      |  24 ++
 .../common/stellar/generated/StellarParser.java | 220 ++++++++++-------
 .../common/stellar/StellarArithmeticTest.java   | 189 ++++++++++++---
 ...larComparisonExpressionWithOperatorTest.java |  79 ++++++
 .../common/stellar/StellarCompilerTest.java     | 128 ++++++++++
 .../metron/common/stellar/StellarTest.java      |  22 --
 .../evaluators/ArithmeticEvaluatorTest.java     |   2 +-
 .../evaluators/DoubleLiteralEvaluatorTest.java  |  70 ++++++
 .../evaluators/FloatLiteralEvaluatorTest.java   |  74 ++++++
 .../evaluators/IntLiteralEvaluatorTest.java     |  74 ++++++
 .../evaluators/LongLiteralEvaluatorTest.java    |  75 ++++++
 .../evaluators/NumberLiteralEvaluatorTest.java  | 107 ++++++++
 metron-platform/pom.xml                         |  12 +
 28 files changed, 1409 insertions(+), 270 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/README.md
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/README.md b/metron-platform/metron-common/README.md
index e73cd8a..a6eec3d 100644
--- a/metron-platform/metron-common/README.md
+++ b/metron-platform/metron-common/README.md
@@ -108,6 +108,7 @@ Using parens such as: "foo" : "\<ok\>" requires escaping; "foo": "\'\<ok\>\'"
 | [ `SYSTEM_PROPERTY_GET`](#system_property_get)|
 | [ `TO_DOUBLE`](#to_double)|
 | [ `TO_EPOCH_TIMESTAMP`](#to_epoch_timestamp)|
+| [ `TO_FLOAT`](#to_float)|
 | [ `TO_INTEGER`](#to_integer)|
 | [ `TO_LONG`](#to_long)|
 | [ `TO_LOWER`](#to_lower)|
@@ -436,6 +437,12 @@ MAP_GET`
     * format - DateTime format as a String
     * timezone - Optional timezone in String format
   * Returns: Epoch timestamp
+  
+### `TO_FOAT`
+  * Description: Transforms the first argument to a float
+  * Input:
+    * input - Object of string or numeric type
+  * Returns: Float version of the first argument
 
 ### `TO_INTEGER`
   * Description: Transforms the first argument to an integer
@@ -643,7 +650,7 @@ JOIN, LENGTH, MAAS_GET_ENDPOINT, MAAS_MODEL_APPLY, MAP_EXISTS, MAP_GET, MONTH, P
 REGEXP_MATCH, SPLIT, STARTS_WITH, STATS_ADD, STATS_COUNT, STATS_GEOMETRIC_MEAN, STATS_INIT, 
 STATS_KURTOSIS, STATS_MAX, STATS_MEAN, STATS_MERGE, STATS_MIN, STATS_PERCENTILE, 
 STATS_POPULATION_VARIANCE, STATS_QUADRATIC_MEAN, STATS_SD, STATS_SKEWNESS, STATS_SUM, 
-STATS_SUM_LOGS, STATS_SUM_SQUARES, STATS_VARIANCE, TO_DOUBLE, TO_EPOCH_TIMESTAMP, 
+STATS_SUM_LOGS, STATS_SUM_SQUARES, STATS_VARIANCE, TO_DOUBLE, TO_EPOCH_TIMESTAMP, TO_FLOAT, 
 TO_INTEGER, TO_LOWER, TO_STRING, TO_UPPER, TRIM, URL_TO_HOST, URL_TO_PATH, URL_TO_PORT, 
 URL_TO_PROTOCOL, WEEK_OF_MONTH, WEEK_OF_YEAR, YEAR
 [Stellar]>>> 

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4 b/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4
index 55f900a..3722533 100644
--- a/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4
+++ b/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4
@@ -88,8 +88,22 @@ NIN : 'not in'
    ;
 EXISTS : 'exists' | 'EXISTS';
 EXPONENT : ('e' | 'E') ( PLUS|MINUS )? ('0'..'9')+;
-INT_LITERAL     : MINUS? '0'..'9'+ ;
-DOUBLE_LITERAL  : MINUS? '0'..'9'+'.''0'..'9'+EXPONENT? ;
+INT_LITERAL     :
+  MINUS? '0'
+  | MINUS? '1'..'9''0'..'9'*
+  ;
+DOUBLE_LITERAL  :
+  INT_LITERAL '.' '0'..'9'* EXPONENT? ('d'|'D')?
+  | '.' '0'..'9'+ EXPONENT? ('d'|'D')?
+  | INT_LITERAL EXPONENT ('d'|'D')?
+  | INT_LITERAL EXPONENT? ('d'|'D')
+  ;
+FLOAT_LITERAL  :
+  INT_LITERAL'.''0'..'9'* EXPONENT? ('f'|'F')
+  | MINUS? '.''0'..'9'+ EXPONENT? ('f'|'F')
+  | INT_LITERAL EXPONENT? ('f'|'F')
+  ;
+LONG_LITERAL  : INT_LITERAL ('l'|'L') ;
 IDENTIFIER : [a-zA-Z_][a-zA-Z_\.:0-9]* ;
 fragment SCHAR:  ~['"\\\r\n];
 STRING_LITERAL : '"' SCHAR* '"'
@@ -168,6 +182,8 @@ functions : IDENTIFIER func_args #TransformationFunc
 arithmetic_operands : functions #NumericFunctions
                     | DOUBLE_LITERAL #DoubleLiteral
                     | INT_LITERAL #IntLiteral
+                    | LONG_LITERAL #LongLiteral
+                    | FLOAT_LITERAL #FloatLiteral
                     | IDENTIFIER #Variable
                     | LPAREN arithmetic_expr RPAREN #ParenArith
                     | LPAREN conditional_expr RPAREN#condExpr

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/Stellar.tokens
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/Stellar.tokens b/metron-platform/metron-common/src/main/java/Stellar.tokens
index d3658b7..10bca58 100644
--- a/metron-platform/metron-common/src/main/java/Stellar.tokens
+++ b/metron-platform/metron-common/src/main/java/Stellar.tokens
@@ -32,10 +32,12 @@ EXISTS=31
 EXPONENT=32
 INT_LITERAL=33
 DOUBLE_LITERAL=34
-IDENTIFIER=35
-STRING_LITERAL=36
-COMMENT=37
-WS=38
+FLOAT_LITERAL=35
+LONG_LITERAL=36
+IDENTIFIER=37
+STRING_LITERAL=38
+COMMENT=39
+WS=40
 ','=1
 '=='=7
 '!='=8

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/StellarLexer.tokens
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/StellarLexer.tokens b/metron-platform/metron-common/src/main/java/StellarLexer.tokens
index d3658b7..10bca58 100644
--- a/metron-platform/metron-common/src/main/java/StellarLexer.tokens
+++ b/metron-platform/metron-common/src/main/java/StellarLexer.tokens
@@ -32,10 +32,12 @@ EXISTS=31
 EXPONENT=32
 INT_LITERAL=33
 DOUBLE_LITERAL=34
-IDENTIFIER=35
-STRING_LITERAL=36
-COMMENT=37
-WS=38
+FLOAT_LITERAL=35
+LONG_LITERAL=36
+IDENTIFIER=37
+STRING_LITERAL=38
+COMMENT=39
+WS=40
 ','=1
 '=='=7
 '!='=8

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java
index f20cf43..742b0c3 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/BaseStellarProcessor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -24,9 +24,12 @@ import org.antlr.v4.runtime.TokenStream;
 
 import java.util.HashSet;
 import java.util.Set;
+import java.util.Stack;
+
 import org.apache.metron.common.dsl.*;
 import org.apache.metron.common.dsl.functions.resolver.FunctionResolver;
 import org.apache.metron.common.stellar.evaluators.ArithmeticEvaluator;
+import org.apache.metron.common.stellar.evaluators.NumberLiteralEvaluator;
 import org.apache.metron.common.stellar.generated.StellarBaseListener;
 import org.apache.metron.common.stellar.generated.StellarLexer;
 import org.apache.metron.common.stellar.generated.StellarParser;
@@ -83,7 +86,10 @@ public class BaseStellarProcessor<T> {
     TokenStream tokens = new CommonTokenStream(lexer);
     StellarParser parser = new StellarParser(tokens);
 
-    StellarCompiler treeBuilder = new StellarCompiler(variableResolver, functionResolver, context, new ArithmeticEvaluator());
+    StellarCompiler treeBuilder = new StellarCompiler(variableResolver, functionResolver, context, new Stack<>(),
+        ArithmeticEvaluator.INSTANCE,
+        NumberLiteralEvaluator.INSTANCE
+    );
     parser.addParseListener(treeBuilder);
     parser.removeErrorListeners();
     parser.addErrorListener(new ErrorListener());

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java
index a5c4cf3..58ac6d6 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -29,6 +29,7 @@ import org.apache.metron.common.dsl.StellarFunction;
 import org.apache.metron.common.dsl.Token;
 import org.apache.metron.common.dsl.VariableResolver;
 import org.apache.metron.common.stellar.evaluators.ArithmeticEvaluator;
+import org.apache.metron.common.stellar.evaluators.NumberLiteralEvaluator;
 import org.apache.metron.common.stellar.generated.StellarBaseListener;
 import org.apache.metron.common.stellar.generated.StellarParser;
 import org.apache.metron.common.utils.ConversionUtils;
@@ -46,18 +47,26 @@ import static java.lang.String.format;
 
 public class StellarCompiler extends StellarBaseListener {
 
-  private Context context = null;
-  private Stack<Token> tokenStack = new Stack<>();
-  private FunctionResolver functionResolver;
-  private VariableResolver variableResolver;
-  private Throwable actualException = null;
+  private final Context context;
+  private final Stack<Token<?>> tokenStack;
+  private final FunctionResolver functionResolver;
+  private final VariableResolver variableResolver;
+  private Throwable actualException;
   private final ArithmeticEvaluator arithmeticEvaluator;
-
-  public StellarCompiler(VariableResolver variableResolver, FunctionResolver functionResolver, Context context, ArithmeticEvaluator arithmeticEvaluator) {
+  private final NumberLiteralEvaluator numberLiteralEvaluator;
+
+  public StellarCompiler(VariableResolver variableResolver,
+                         FunctionResolver functionResolver,
+                         Context context,
+                         Stack<Token<?>> tokenStack,
+                         ArithmeticEvaluator arithmeticEvaluator,
+                         NumberLiteralEvaluator numberLiteralEvaluator) {
     this.variableResolver = variableResolver;
     this.functionResolver = functionResolver;
     this.context = context;
+    this.tokenStack = tokenStack;
     this.arithmeticEvaluator = arithmeticEvaluator;
+    this.numberLiteralEvaluator = numberLiteralEvaluator;
   }
 
   @Override
@@ -174,12 +183,22 @@ public class StellarCompiler extends StellarBaseListener {
 
   @Override
   public void exitIntLiteral(StellarParser.IntLiteralContext ctx) {
-    tokenStack.push(new Token<>(Integer.parseInt(ctx.getText()), Integer.class));
+    tokenStack.push(numberLiteralEvaluator.evaluate(ctx));
   }
 
   @Override
   public void exitDoubleLiteral(StellarParser.DoubleLiteralContext ctx) {
-    tokenStack.push(new Token<>(Double.parseDouble(ctx.getText()), Double.class));
+    tokenStack.push(numberLiteralEvaluator.evaluate(ctx));
+  }
+
+  @Override
+  public void exitFloatLiteral(StellarParser.FloatLiteralContext ctx) {
+    tokenStack.push(numberLiteralEvaluator.evaluate(ctx));
+  }
+
+  @Override
+  public void exitLongLiteral(StellarParser.LongLiteralContext ctx) {
+    tokenStack.push(numberLiteralEvaluator.evaluate(ctx));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java
index 6fd372a..f1264e2 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ArithmeticEvaluator.java
@@ -24,7 +24,8 @@ import org.apache.metron.common.dsl.Token;
 
 import java.util.function.BiFunction;
 
-public class ArithmeticEvaluator {
+public enum ArithmeticEvaluator {
+  INSTANCE;
 
   public Token<? extends Number> evaluate(BiFunction<Number, Number, Token<? extends Number>> function,
                                           Pair<Token<? extends Number>, Token<? extends Number>> p) {

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java
new file mode 100644
index 0000000..1bd1a49
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/DoubleLiteralEvaluator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+
+public class DoubleLiteralEvaluator implements NumberEvaluator<StellarParser.DoubleLiteralContext> {
+  @Override
+  public Token<Double> evaluate(StellarParser.DoubleLiteralContext context) {
+    if (context == null) {
+      throw new IllegalArgumentException("Cannot evaluate a context that is null.");
+    }
+
+    return new Token<>(Double.parseDouble(context.getText()), Double.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java
new file mode 100644
index 0000000..60b312b
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/FloatLiteralEvaluator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+
+public class FloatLiteralEvaluator implements NumberEvaluator<StellarParser.FloatLiteralContext> {
+  @Override
+  public Token<Float> evaluate(StellarParser.FloatLiteralContext context) {
+    if (context == null) {
+      throw new IllegalArgumentException("Cannot evaluate a context that is null.");
+    }
+
+    return new Token<>(Float.parseFloat(context.getText()), Float.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java
new file mode 100644
index 0000000..c928a9a
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/IntLiteralEvaluator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+
+public class IntLiteralEvaluator implements NumberEvaluator<StellarParser.IntLiteralContext> {
+  @Override
+  public Token<Integer> evaluate(StellarParser.IntLiteralContext context) {
+    if (context == null) {
+      throw new IllegalArgumentException("Cannot evaluate a context that is null.");
+    }
+
+    return new Token<>(Integer.parseInt(context.getText()), Integer.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java
new file mode 100644
index 0000000..05ee162
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/LongLiteralEvaluator.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.ParseException;
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+
+public class LongLiteralEvaluator implements NumberEvaluator<StellarParser.LongLiteralContext> {
+  @Override
+  public Token<Long> evaluate(StellarParser.LongLiteralContext context) {
+    if (context == null) {
+      throw new IllegalArgumentException("Cannot evaluate a context that is null.");
+    }
+
+    String value = context.getText();
+    if (value.endsWith("l") || value.endsWith("L")) {
+      value = value.substring(0, value.length() - 1); // Drop the 'L' or 'l'. Long.parseLong does not accept a string with either of these.
+      return new Token<>(Long.parseLong(value), Long.class);
+    } else {
+      // Technically this should never happen, but just being safe.
+      throw new ParseException("Invalid format for long. Failed trying to parse a long with the following value: " + value);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java
new file mode 100644
index 0000000..0007b72
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberEvaluator.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+
+public interface NumberEvaluator<T extends StellarParser.Arithmetic_operandsContext> {
+  Token<? extends Number> evaluate(T context);
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java
new file mode 100644
index 0000000..83d795f
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/NumberLiteralEvaluator.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.apache.metron.common.dsl.ParseException;
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum NumberLiteralEvaluator {
+  INSTANCE;
+  public enum Strategy {
+     INTEGER(StellarParser.IntLiteralContext.class, new IntLiteralEvaluator())
+    , DOUBLE(StellarParser.DoubleLiteralContext.class, new DoubleLiteralEvaluator())
+    , FLOAT(StellarParser.FloatLiteralContext.class, new FloatLiteralEvaluator())
+    , LONG(StellarParser.LongLiteralContext.class, new LongLiteralEvaluator());
+    Class<? extends StellarParser.Arithmetic_operandsContext> context;
+    NumberEvaluator evaluator;
+    private static Map<Class<? extends StellarParser.Arithmetic_operandsContext>, NumberEvaluator> strategyMap;
+
+    static {
+      strategyMap = new HashMap<>();
+      for (Strategy strat : Strategy.values()) {
+        strategyMap.put(strat.context, strat.evaluator);
+      }
+    }
+
+    Strategy(Class<? extends StellarParser.Arithmetic_operandsContext> context
+            , NumberEvaluator<? extends StellarParser.Arithmetic_operandsContext> evaluator
+    ) {
+      this.context = context;
+      this.evaluator = evaluator;
+    }
+  }
+
+  Token<? extends Number> evaluate(StellarParser.Arithmetic_operandsContext context
+                                         , Map<Class<? extends StellarParser.Arithmetic_operandsContext>, NumberEvaluator> instanceMap
+                                         )
+  {
+    NumberEvaluator evaluator = instanceMap.get(context.getClass());
+    if(evaluator == null) {
+      throw new ParseException("Does not support evaluation for type " + context.getClass());
+    }
+    return evaluator.evaluate(context);
+  }
+
+  public Token<? extends Number> evaluate(StellarParser.Arithmetic_operandsContext context) {
+    return evaluate(context, Strategy.strategyMap);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java
index 490d249..e0a8770 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java
@@ -457,6 +457,30 @@ public class StellarBaseListener implements StellarListener {
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
+	@Override public void enterLongLiteral(StellarParser.LongLiteralContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitLongLiteral(StellarParser.LongLiteralContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterFloatLiteral(StellarParser.FloatLiteralContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitFloatLiteral(StellarParser.FloatLiteralContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
 	@Override public void enterVariable(StellarParser.VariableContext ctx) { }
 	/**
 	 * {@inheritDoc}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarLexer.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarLexer.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarLexer.java
index c63fc03..3fe97e2 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarLexer.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarLexer.java
@@ -41,8 +41,8 @@ public class StellarLexer extends Lexer {
 		GT=11, GTE=12, QUESTION=13, COLON=14, IF=15, THEN=16, ELSE=17, NULL=18, 
 		MINUS=19, PLUS=20, DIV=21, MUL=22, LBRACE=23, RBRACE=24, LBRACKET=25, 
 		RBRACKET=26, LPAREN=27, RPAREN=28, IN=29, NIN=30, EXISTS=31, EXPONENT=32, 
-		INT_LITERAL=33, DOUBLE_LITERAL=34, IDENTIFIER=35, STRING_LITERAL=36, COMMENT=37, 
-		WS=38;
+		INT_LITERAL=33, DOUBLE_LITERAL=34, FLOAT_LITERAL=35, LONG_LITERAL=36, 
+		IDENTIFIER=37, STRING_LITERAL=38, COMMENT=39, WS=40;
 	public static String[] modeNames = {
 		"DEFAULT_MODE"
 	};
@@ -52,7 +52,8 @@ public class StellarLexer extends Lexer {
 		"GT", "GTE", "QUESTION", "COLON", "IF", "THEN", "ELSE", "NULL", "MINUS", 
 		"PLUS", "DIV", "MUL", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "LPAREN", 
 		"RPAREN", "IN", "NIN", "EXISTS", "EXPONENT", "INT_LITERAL", "DOUBLE_LITERAL", 
-		"IDENTIFIER", "SCHAR", "STRING_LITERAL", "COMMENT", "WS"
+		"FLOAT_LITERAL", "LONG_LITERAL", "IDENTIFIER", "SCHAR", "STRING_LITERAL", 
+		"COMMENT", "WS"
 	};
 
 	private static final String[] _LITERAL_NAMES = {
@@ -65,7 +66,8 @@ public class StellarLexer extends Lexer {
 		"LTE", "GT", "GTE", "QUESTION", "COLON", "IF", "THEN", "ELSE", "NULL", 
 		"MINUS", "PLUS", "DIV", "MUL", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", 
 		"LPAREN", "RPAREN", "IN", "NIN", "EXISTS", "EXPONENT", "INT_LITERAL", 
-		"DOUBLE_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS"
+		"DOUBLE_LITERAL", "FLOAT_LITERAL", "LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", 
+		"COMMENT", "WS"
 	};
 	public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
 
@@ -122,111 +124,142 @@ public class StellarLexer extends Lexer {
 	public ATN getATN() { return _ATN; }
 
 	public static final String _serializedATN =
-		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2(\u0139\b\1\4\2\t"+
+		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2*\u0180\b\1\4\2\t"+
 		"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
 		"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
 		"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
 		"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
-		"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\3\2\3\2\3\3\3\3\3\3"+
-		"\3\3\3\3\3\3\3\3\3\3\5\3\\\n\3\3\4\3\4\3\4\3\4\3\4\3\4\5\4d\n\4\3\5\3"+
-		"\5\3\5\3\5\3\5\3\5\5\5l\n\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6v\n\6\3"+
-		"\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7\u0082\n\7\3\b\3\b\3\b\3\t\3"+
-		"\t\3\t\3\n\3\n\3\13\3\13\3\13\3\f\3\f\3\r\3\r\3\r\3\16\3\16\3\17\3\17"+
-		"\3\20\3\20\3\20\3\20\5\20\u009c\n\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+
-		"\3\21\5\21\u00a6\n\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\5\22\u00b0"+
-		"\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u00ba\n\23\3\24\3\24"+
-		"\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33"+
-		"\3\34\3\34\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37"+
-		"\3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \5 \u00e6\n \3!\3!\3!\5!\u00eb\n!"+
-		"\3!\6!\u00ee\n!\r!\16!\u00ef\3\"\5\"\u00f3\n\"\3\"\6\"\u00f6\n\"\r\"\16"+
-		"\"\u00f7\3#\5#\u00fb\n#\3#\6#\u00fe\n#\r#\16#\u00ff\3#\3#\6#\u0104\n#"+
-		"\r#\16#\u0105\3#\5#\u0109\n#\3$\3$\7$\u010d\n$\f$\16$\u0110\13$\3%\3%"+
-		"\3&\3&\7&\u0116\n&\f&\16&\u0119\13&\3&\3&\3&\7&\u011e\n&\f&\16&\u0121"+
-		"\13&\3&\5&\u0124\n&\3\'\3\'\3\'\3\'\6\'\u012a\n\'\r\'\16\'\u012b\3\'\5"+
-		"\'\u012f\n\'\3\'\3\'\3(\6(\u0134\n(\r(\16(\u0135\3(\3(\3\u012b\2)\3\3"+
-		"\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21"+
-		"!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!"+
-		"A\"C#E$G%I\2K&M\'O(\3\2\b\4\2GGgg\5\2C\\aac|\b\2\60\60\62<C\\^^aac|\7"+
-		"\2\f\f\17\17$$))^^\3\3\f\f\5\2\13\f\16\17\"\"\u0152\2\3\3\2\2\2\2\5\3"+
-		"\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2"+
-		"\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3"+
-		"\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'"+
-		"\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63"+
-		"\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2"+
-		"?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2K\3\2\2\2\2M\3"+
-		"\2\2\2\2O\3\2\2\2\3Q\3\2\2\2\5[\3\2\2\2\7c\3\2\2\2\tk\3\2\2\2\13u\3\2"+
-		"\2\2\r\u0081\3\2\2\2\17\u0083\3\2\2\2\21\u0086\3\2\2\2\23\u0089\3\2\2"+
-		"\2\25\u008b\3\2\2\2\27\u008e\3\2\2\2\31\u0090\3\2\2\2\33\u0093\3\2\2\2"+
-		"\35\u0095\3\2\2\2\37\u009b\3\2\2\2!\u00a5\3\2\2\2#\u00af\3\2\2\2%\u00b9"+
-		"\3\2\2\2\'\u00bb\3\2\2\2)\u00bd\3\2\2\2+\u00bf\3\2\2\2-\u00c1\3\2\2\2"+
-		"/\u00c3\3\2\2\2\61\u00c5\3\2\2\2\63\u00c7\3\2\2\2\65\u00c9\3\2\2\2\67"+
-		"\u00cb\3\2\2\29\u00cd\3\2\2\2;\u00cf\3\2\2\2=\u00d2\3\2\2\2?\u00e5\3\2"+
-		"\2\2A\u00e7\3\2\2\2C\u00f2\3\2\2\2E\u00fa\3\2\2\2G\u010a\3\2\2\2I\u0111"+
-		"\3\2\2\2K\u0123\3\2\2\2M\u0125\3\2\2\2O\u0133\3\2\2\2QR\7.\2\2R\4\3\2"+
-		"\2\2ST\7c\2\2TU\7p\2\2U\\\7f\2\2VW\7(\2\2W\\\7(\2\2XY\7C\2\2YZ\7P\2\2"+
-		"Z\\\7F\2\2[S\3\2\2\2[V\3\2\2\2[X\3\2\2\2\\\6\3\2\2\2]^\7q\2\2^d\7t\2\2"+
-		"_`\7~\2\2`d\7~\2\2ab\7Q\2\2bd\7T\2\2c]\3\2\2\2c_\3\2\2\2ca\3\2\2\2d\b"+
-		"\3\2\2\2ef\7p\2\2fg\7q\2\2gl\7v\2\2hi\7P\2\2ij\7Q\2\2jl\7V\2\2ke\3\2\2"+
-		"\2kh\3\2\2\2l\n\3\2\2\2mn\7v\2\2no\7t\2\2op\7w\2\2pv\7g\2\2qr\7V\2\2r"+
-		"s\7T\2\2st\7W\2\2tv\7G\2\2um\3\2\2\2uq\3\2\2\2v\f\3\2\2\2wx\7h\2\2xy\7"+
-		"c\2\2yz\7n\2\2z{\7u\2\2{\u0082\7g\2\2|}\7H\2\2}~\7C\2\2~\177\7N\2\2\177"+
-		"\u0080\7U\2\2\u0080\u0082\7G\2\2\u0081w\3\2\2\2\u0081|\3\2\2\2\u0082\16"+
-		"\3\2\2\2\u0083\u0084\7?\2\2\u0084\u0085\7?\2\2\u0085\20\3\2\2\2\u0086"+
-		"\u0087\7#\2\2\u0087\u0088\7?\2\2\u0088\22\3\2\2\2\u0089\u008a\7>\2\2\u008a"+
-		"\24\3\2\2\2\u008b\u008c\7>\2\2\u008c\u008d\7?\2\2\u008d\26\3\2\2\2\u008e"+
-		"\u008f\7@\2\2\u008f\30\3\2\2\2\u0090\u0091\7@\2\2\u0091\u0092\7?\2\2\u0092"+
-		"\32\3\2\2\2\u0093\u0094\7A\2\2\u0094\34\3\2\2\2\u0095\u0096\7<\2\2\u0096"+
-		"\36\3\2\2\2\u0097\u0098\7K\2\2\u0098\u009c\7H\2\2\u0099\u009a\7k\2\2\u009a"+
-		"\u009c\7h\2\2\u009b\u0097\3\2\2\2\u009b\u0099\3\2\2\2\u009c \3\2\2\2\u009d"+
-		"\u009e\7V\2\2\u009e\u009f\7J\2\2\u009f\u00a0\7G\2\2\u00a0\u00a6\7P\2\2"+
-		"\u00a1\u00a2\7v\2\2\u00a2\u00a3\7j\2\2\u00a3\u00a4\7g\2\2\u00a4\u00a6"+
-		"\7p\2\2\u00a5\u009d\3\2\2\2\u00a5\u00a1\3\2\2\2\u00a6\"\3\2\2\2\u00a7"+
-		"\u00a8\7G\2\2\u00a8\u00a9\7N\2\2\u00a9\u00aa\7U\2\2\u00aa\u00b0\7G\2\2"+
-		"\u00ab\u00ac\7g\2\2\u00ac\u00ad\7n\2\2\u00ad\u00ae\7u\2\2\u00ae\u00b0"+
-		"\7g\2\2\u00af\u00a7\3\2\2\2\u00af\u00ab\3\2\2\2\u00b0$\3\2\2\2\u00b1\u00b2"+
-		"\7p\2\2\u00b2\u00b3\7w\2\2\u00b3\u00b4\7n\2\2\u00b4\u00ba\7n\2\2\u00b5"+
-		"\u00b6\7P\2\2\u00b6\u00b7\7W\2\2\u00b7\u00b8\7N\2\2\u00b8\u00ba\7N\2\2"+
-		"\u00b9\u00b1\3\2\2\2\u00b9\u00b5\3\2\2\2\u00ba&\3\2\2\2\u00bb\u00bc\7"+
-		"/\2\2\u00bc(\3\2\2\2\u00bd\u00be\7-\2\2\u00be*\3\2\2\2\u00bf\u00c0\7\61"+
-		"\2\2\u00c0,\3\2\2\2\u00c1\u00c2\7,\2\2\u00c2.\3\2\2\2\u00c3\u00c4\7}\2"+
-		"\2\u00c4\60\3\2\2\2\u00c5\u00c6\7\177\2\2\u00c6\62\3\2\2\2\u00c7\u00c8"+
-		"\7]\2\2\u00c8\64\3\2\2\2\u00c9\u00ca\7_\2\2\u00ca\66\3\2\2\2\u00cb\u00cc"+
-		"\7*\2\2\u00cc8\3\2\2\2\u00cd\u00ce\7+\2\2\u00ce:\3\2\2\2\u00cf\u00d0\7"+
-		"k\2\2\u00d0\u00d1\7p\2\2\u00d1<\3\2\2\2\u00d2\u00d3\7p\2\2\u00d3\u00d4"+
-		"\7q\2\2\u00d4\u00d5\7v\2\2\u00d5\u00d6\7\"\2\2\u00d6\u00d7\7k\2\2\u00d7"+
-		"\u00d8\7p\2\2\u00d8>\3\2\2\2\u00d9\u00da\7g\2\2\u00da\u00db\7z\2\2\u00db"+
-		"\u00dc\7k\2\2\u00dc\u00dd\7u\2\2\u00dd\u00de\7v\2\2\u00de\u00e6\7u\2\2"+
-		"\u00df\u00e0\7G\2\2\u00e0\u00e1\7Z\2\2\u00e1\u00e2\7K\2\2\u00e2\u00e3"+
-		"\7U\2\2\u00e3\u00e4\7V\2\2\u00e4\u00e6\7U\2\2\u00e5\u00d9\3\2\2\2\u00e5"+
-		"\u00df\3\2\2\2\u00e6@\3\2\2\2\u00e7\u00ea\t\2\2\2\u00e8\u00eb\5)\25\2"+
-		"\u00e9\u00eb\5\'\24\2\u00ea\u00e8\3\2\2\2\u00ea\u00e9\3\2\2\2\u00ea\u00eb"+
-		"\3\2\2\2\u00eb\u00ed\3\2\2\2\u00ec\u00ee\4\62;\2\u00ed\u00ec\3\2\2\2\u00ee"+
-		"\u00ef\3\2\2\2\u00ef\u00ed\3\2\2\2\u00ef\u00f0\3\2\2\2\u00f0B\3\2\2\2"+
-		"\u00f1\u00f3\5\'\24\2\u00f2\u00f1\3\2\2\2\u00f2\u00f3\3\2\2\2\u00f3\u00f5"+
-		"\3\2\2\2\u00f4\u00f6\4\62;\2\u00f5\u00f4\3\2\2\2\u00f6\u00f7\3\2\2\2\u00f7"+
-		"\u00f5\3\2\2\2\u00f7\u00f8\3\2\2\2\u00f8D\3\2\2\2\u00f9\u00fb\5\'\24\2"+
-		"\u00fa\u00f9\3\2\2\2\u00fa\u00fb\3\2\2\2\u00fb\u00fd\3\2\2\2\u00fc\u00fe"+
-		"\4\62;\2\u00fd\u00fc\3\2\2\2\u00fe\u00ff\3\2\2\2\u00ff\u00fd\3\2\2\2\u00ff"+
-		"\u0100\3\2\2\2\u0100\u0101\3\2\2\2\u0101\u0103\7\60\2\2\u0102\u0104\4"+
-		"\62;\2\u0103\u0102\3\2\2\2\u0104\u0105\3\2\2\2\u0105\u0103\3\2\2\2\u0105"+
-		"\u0106\3\2\2\2\u0106\u0108\3\2\2\2\u0107\u0109\5A!\2\u0108\u0107\3\2\2"+
-		"\2\u0108\u0109\3\2\2\2\u0109F\3\2\2\2\u010a\u010e\t\3\2\2\u010b\u010d"+
-		"\t\4\2\2\u010c\u010b\3\2\2\2\u010d\u0110\3\2\2\2\u010e\u010c\3\2\2\2\u010e"+
-		"\u010f\3\2\2\2\u010fH\3\2\2\2\u0110\u010e\3\2\2\2\u0111\u0112\n\5\2\2"+
-		"\u0112J\3\2\2\2\u0113\u0117\7$\2\2\u0114\u0116\5I%\2\u0115\u0114\3\2\2"+
-		"\2\u0116\u0119\3\2\2\2\u0117\u0115\3\2\2\2\u0117\u0118\3\2\2\2\u0118\u011a"+
-		"\3\2\2\2\u0119\u0117\3\2\2\2\u011a\u0124\7$\2\2\u011b\u011f\7)\2\2\u011c"+
-		"\u011e\5I%\2\u011d\u011c\3\2\2\2\u011e\u0121\3\2\2\2\u011f\u011d\3\2\2"+
-		"\2\u011f\u0120\3\2\2\2\u0120\u0122\3\2\2\2\u0121\u011f\3\2\2\2\u0122\u0124"+
-		"\7)\2\2\u0123\u0113\3\2\2\2\u0123\u011b\3\2\2\2\u0124L\3\2\2\2\u0125\u0126"+
-		"\7\61\2\2\u0126\u0127\7\61\2\2\u0127\u0129\3\2\2\2\u0128\u012a\13\2\2"+
-		"\2\u0129\u0128\3\2\2\2\u012a\u012b\3\2\2\2\u012b\u012c\3\2\2\2\u012b\u0129"+
-		"\3\2\2\2\u012c\u012e\3\2\2\2\u012d\u012f\t\6\2\2\u012e\u012d\3\2\2\2\u012f"+
-		"\u0130\3\2\2\2\u0130\u0131\b\'\2\2\u0131N\3\2\2\2\u0132\u0134\t\7\2\2"+
-		"\u0133\u0132\3\2\2\2\u0134\u0135\3\2\2\2\u0135\u0133\3\2\2\2\u0135\u0136"+
-		"\3\2\2\2\u0136\u0137\3\2\2\2\u0137\u0138\b(\2\2\u0138P\3\2\2\2\34\2[c"+
-		"ku\u0081\u009b\u00a5\u00af\u00b9\u00e5\u00ea\u00ef\u00f2\u00f7\u00fa\u00ff"+
-		"\u0105\u0108\u010e\u0117\u011f\u0123\u012b\u012e\u0135\3\b\2\2";
+		"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\3\2\3\2"+
+		"\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\5\3`\n\3\3\4\3\4\3\4\3\4\3\4\3\4\5\4"+
+		"h\n\4\3\5\3\5\3\5\3\5\3\5\3\5\5\5p\n\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6"+
+		"\5\6z\n\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7\u0086\n\7\3\b\3"+
+		"\b\3\b\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\f\3\f\3\r\3\r\3\r\3\16\3\16"+
+		"\3\17\3\17\3\20\3\20\3\20\3\20\5\20\u00a0\n\20\3\21\3\21\3\21\3\21\3\21"+
+		"\3\21\3\21\3\21\5\21\u00aa\n\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22"+
+		"\5\22\u00b4\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u00be\n"+
+		"\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31\3\31\3\32\3"+
+		"\32\3\33\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3"+
+		"\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \5 \u00ea\n \3!\3!\3"+
+		"!\5!\u00ef\n!\3!\6!\u00f2\n!\r!\16!\u00f3\3\"\5\"\u00f7\n\"\3\"\3\"\5"+
+		"\"\u00fb\n\"\3\"\3\"\7\"\u00ff\n\"\f\"\16\"\u0102\13\"\5\"\u0104\n\"\3"+
+		"#\3#\3#\7#\u0109\n#\f#\16#\u010c\13#\3#\5#\u010f\n#\3#\5#\u0112\n#\3#"+
+		"\3#\6#\u0116\n#\r#\16#\u0117\3#\5#\u011b\n#\3#\5#\u011e\n#\3#\3#\3#\5"+
+		"#\u0123\n#\3#\3#\5#\u0127\n#\3#\3#\5#\u012b\n#\3$\3$\3$\7$\u0130\n$\f"+
+		"$\16$\u0133\13$\3$\5$\u0136\n$\3$\3$\3$\5$\u013b\n$\3$\3$\6$\u013f\n$"+
+		"\r$\16$\u0140\3$\5$\u0144\n$\3$\3$\3$\5$\u0149\n$\3$\3$\5$\u014d\n$\3"+
+		"%\3%\3%\3&\3&\7&\u0154\n&\f&\16&\u0157\13&\3\'\3\'\3(\3(\7(\u015d\n(\f"+
+		"(\16(\u0160\13(\3(\3(\3(\7(\u0165\n(\f(\16(\u0168\13(\3(\5(\u016b\n(\3"+
+		")\3)\3)\3)\6)\u0171\n)\r)\16)\u0172\3)\5)\u0176\n)\3)\3)\3*\6*\u017b\n"+
+		"*\r*\16*\u017c\3*\3*\3\u0172\2+\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23"+
+		"\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31"+
+		"\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M\2O(Q)S*\3\2\13\4\2"+
+		"GGgg\4\2FFff\4\2HHhh\4\2NNnn\5\2C\\aac|\b\2\60\60\62<C\\^^aac|\7\2\f\f"+
+		"\17\17$$))^^\3\3\f\f\5\2\13\f\16\17\"\"\u01aa\2\3\3\2\2\2\2\5\3\2\2\2"+
+		"\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3"+
+		"\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2"+
+		"\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2"+
+		"\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2"+
+		"\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2"+
+		"\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2"+
+		"\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\3U\3\2\2\2\5_\3\2\2\2\7g\3\2\2\2\to"+
+		"\3\2\2\2\13y\3\2\2\2\r\u0085\3\2\2\2\17\u0087\3\2\2\2\21\u008a\3\2\2\2"+
+		"\23\u008d\3\2\2\2\25\u008f\3\2\2\2\27\u0092\3\2\2\2\31\u0094\3\2\2\2\33"+
+		"\u0097\3\2\2\2\35\u0099\3\2\2\2\37\u009f\3\2\2\2!\u00a9\3\2\2\2#\u00b3"+
+		"\3\2\2\2%\u00bd\3\2\2\2\'\u00bf\3\2\2\2)\u00c1\3\2\2\2+\u00c3\3\2\2\2"+
+		"-\u00c5\3\2\2\2/\u00c7\3\2\2\2\61\u00c9\3\2\2\2\63\u00cb\3\2\2\2\65\u00cd"+
+		"\3\2\2\2\67\u00cf\3\2\2\29\u00d1\3\2\2\2;\u00d3\3\2\2\2=\u00d6\3\2\2\2"+
+		"?\u00e9\3\2\2\2A\u00eb\3\2\2\2C\u0103\3\2\2\2E\u012a\3\2\2\2G\u014c\3"+
+		"\2\2\2I\u014e\3\2\2\2K\u0151\3\2\2\2M\u0158\3\2\2\2O\u016a\3\2\2\2Q\u016c"+
+		"\3\2\2\2S\u017a\3\2\2\2UV\7.\2\2V\4\3\2\2\2WX\7c\2\2XY\7p\2\2Y`\7f\2\2"+
+		"Z[\7(\2\2[`\7(\2\2\\]\7C\2\2]^\7P\2\2^`\7F\2\2_W\3\2\2\2_Z\3\2\2\2_\\"+
+		"\3\2\2\2`\6\3\2\2\2ab\7q\2\2bh\7t\2\2cd\7~\2\2dh\7~\2\2ef\7Q\2\2fh\7T"+
+		"\2\2ga\3\2\2\2gc\3\2\2\2ge\3\2\2\2h\b\3\2\2\2ij\7p\2\2jk\7q\2\2kp\7v\2"+
+		"\2lm\7P\2\2mn\7Q\2\2np\7V\2\2oi\3\2\2\2ol\3\2\2\2p\n\3\2\2\2qr\7v\2\2"+
+		"rs\7t\2\2st\7w\2\2tz\7g\2\2uv\7V\2\2vw\7T\2\2wx\7W\2\2xz\7G\2\2yq\3\2"+
+		"\2\2yu\3\2\2\2z\f\3\2\2\2{|\7h\2\2|}\7c\2\2}~\7n\2\2~\177\7u\2\2\177\u0086"+
+		"\7g\2\2\u0080\u0081\7H\2\2\u0081\u0082\7C\2\2\u0082\u0083\7N\2\2\u0083"+
+		"\u0084\7U\2\2\u0084\u0086\7G\2\2\u0085{\3\2\2\2\u0085\u0080\3\2\2\2\u0086"+
+		"\16\3\2\2\2\u0087\u0088\7?\2\2\u0088\u0089\7?\2\2\u0089\20\3\2\2\2\u008a"+
+		"\u008b\7#\2\2\u008b\u008c\7?\2\2\u008c\22\3\2\2\2\u008d\u008e\7>\2\2\u008e"+
+		"\24\3\2\2\2\u008f\u0090\7>\2\2\u0090\u0091\7?\2\2\u0091\26\3\2\2\2\u0092"+
+		"\u0093\7@\2\2\u0093\30\3\2\2\2\u0094\u0095\7@\2\2\u0095\u0096\7?\2\2\u0096"+
+		"\32\3\2\2\2\u0097\u0098\7A\2\2\u0098\34\3\2\2\2\u0099\u009a\7<\2\2\u009a"+
+		"\36\3\2\2\2\u009b\u009c\7K\2\2\u009c\u00a0\7H\2\2\u009d\u009e\7k\2\2\u009e"+
+		"\u00a0\7h\2\2\u009f\u009b\3\2\2\2\u009f\u009d\3\2\2\2\u00a0 \3\2\2\2\u00a1"+
+		"\u00a2\7V\2\2\u00a2\u00a3\7J\2\2\u00a3\u00a4\7G\2\2\u00a4\u00aa\7P\2\2"+
+		"\u00a5\u00a6\7v\2\2\u00a6\u00a7\7j\2\2\u00a7\u00a8\7g\2\2\u00a8\u00aa"+
+		"\7p\2\2\u00a9\u00a1\3\2\2\2\u00a9\u00a5\3\2\2\2\u00aa\"\3\2\2\2\u00ab"+
+		"\u00ac\7G\2\2\u00ac\u00ad\7N\2\2\u00ad\u00ae\7U\2\2\u00ae\u00b4\7G\2\2"+
+		"\u00af\u00b0\7g\2\2\u00b0\u00b1\7n\2\2\u00b1\u00b2\7u\2\2\u00b2\u00b4"+
+		"\7g\2\2\u00b3\u00ab\3\2\2\2\u00b3\u00af\3\2\2\2\u00b4$\3\2\2\2\u00b5\u00b6"+
+		"\7p\2\2\u00b6\u00b7\7w\2\2\u00b7\u00b8\7n\2\2\u00b8\u00be\7n\2\2\u00b9"+
+		"\u00ba\7P\2\2\u00ba\u00bb\7W\2\2\u00bb\u00bc\7N\2\2\u00bc\u00be\7N\2\2"+
+		"\u00bd\u00b5\3\2\2\2\u00bd\u00b9\3\2\2\2\u00be&\3\2\2\2\u00bf\u00c0\7"+
+		"/\2\2\u00c0(\3\2\2\2\u00c1\u00c2\7-\2\2\u00c2*\3\2\2\2\u00c3\u00c4\7\61"+
+		"\2\2\u00c4,\3\2\2\2\u00c5\u00c6\7,\2\2\u00c6.\3\2\2\2\u00c7\u00c8\7}\2"+
+		"\2\u00c8\60\3\2\2\2\u00c9\u00ca\7\177\2\2\u00ca\62\3\2\2\2\u00cb\u00cc"+
+		"\7]\2\2\u00cc\64\3\2\2\2\u00cd\u00ce\7_\2\2\u00ce\66\3\2\2\2\u00cf\u00d0"+
+		"\7*\2\2\u00d08\3\2\2\2\u00d1\u00d2\7+\2\2\u00d2:\3\2\2\2\u00d3\u00d4\7"+
+		"k\2\2\u00d4\u00d5\7p\2\2\u00d5<\3\2\2\2\u00d6\u00d7\7p\2\2\u00d7\u00d8"+
+		"\7q\2\2\u00d8\u00d9\7v\2\2\u00d9\u00da\7\"\2\2\u00da\u00db\7k\2\2\u00db"+
+		"\u00dc\7p\2\2\u00dc>\3\2\2\2\u00dd\u00de\7g\2\2\u00de\u00df\7z\2\2\u00df"+
+		"\u00e0\7k\2\2\u00e0\u00e1\7u\2\2\u00e1\u00e2\7v\2\2\u00e2\u00ea\7u\2\2"+
+		"\u00e3\u00e4\7G\2\2\u00e4\u00e5\7Z\2\2\u00e5\u00e6\7K\2\2\u00e6\u00e7"+
+		"\7U\2\2\u00e7\u00e8\7V\2\2\u00e8\u00ea\7U\2\2\u00e9\u00dd\3\2\2\2\u00e9"+
+		"\u00e3\3\2\2\2\u00ea@\3\2\2\2\u00eb\u00ee\t\2\2\2\u00ec\u00ef\5)\25\2"+
+		"\u00ed\u00ef\5\'\24\2\u00ee\u00ec\3\2\2\2\u00ee\u00ed\3\2\2\2\u00ee\u00ef"+
+		"\3\2\2\2\u00ef\u00f1\3\2\2\2\u00f0\u00f2\4\62;\2\u00f1\u00f0\3\2\2\2\u00f2"+
+		"\u00f3\3\2\2\2\u00f3\u00f1\3\2\2\2\u00f3\u00f4\3\2\2\2\u00f4B\3\2\2\2"+
+		"\u00f5\u00f7\5\'\24\2\u00f6\u00f5\3\2\2\2\u00f6\u00f7\3\2\2\2\u00f7\u00f8"+
+		"\3\2\2\2\u00f8\u0104\7\62\2\2\u00f9\u00fb\5\'\24\2\u00fa\u00f9\3\2\2\2"+
+		"\u00fa\u00fb\3\2\2\2\u00fb\u00fc\3\2\2\2\u00fc\u0100\4\63;\2\u00fd\u00ff"+
+		"\4\62;\2\u00fe\u00fd\3\2\2\2\u00ff\u0102\3\2\2\2\u0100\u00fe\3\2\2\2\u0100"+
+		"\u0101\3\2\2\2\u0101\u0104\3\2\2\2\u0102\u0100\3\2\2\2\u0103\u00f6\3\2"+
+		"\2\2\u0103\u00fa\3\2\2\2\u0104D\3\2\2\2\u0105\u0106\5C\"\2\u0106\u010a"+
+		"\7\60\2\2\u0107\u0109\4\62;\2\u0108\u0107\3\2\2\2\u0109\u010c\3\2\2\2"+
+		"\u010a\u0108\3\2\2\2\u010a\u010b\3\2\2\2\u010b\u010e\3\2\2\2\u010c\u010a"+
+		"\3\2\2\2\u010d\u010f\5A!\2\u010e\u010d\3\2\2\2\u010e\u010f\3\2\2\2\u010f"+
+		"\u0111\3\2\2\2\u0110\u0112\t\3\2\2\u0111\u0110\3\2\2\2\u0111\u0112\3\2"+
+		"\2\2\u0112\u012b\3\2\2\2\u0113\u0115\7\60\2\2\u0114\u0116\4\62;\2\u0115"+
+		"\u0114\3\2\2\2\u0116\u0117\3\2\2\2\u0117\u0115\3\2\2\2\u0117\u0118\3\2"+
+		"\2\2\u0118\u011a\3\2\2\2\u0119\u011b\5A!\2\u011a\u0119\3\2\2\2\u011a\u011b"+
+		"\3\2\2\2\u011b\u011d\3\2\2\2\u011c\u011e\t\3\2\2\u011d\u011c\3\2\2\2\u011d"+
+		"\u011e\3\2\2\2\u011e\u012b\3\2\2\2\u011f\u0120\5C\"\2\u0120\u0122\5A!"+
+		"\2\u0121\u0123\t\3\2\2\u0122\u0121\3\2\2\2\u0122\u0123\3\2\2\2\u0123\u012b"+
+		"\3\2\2\2\u0124\u0126\5C\"\2\u0125\u0127\5A!\2\u0126\u0125\3\2\2\2\u0126"+
+		"\u0127\3\2\2\2\u0127\u0128\3\2\2\2\u0128\u0129\t\3\2\2\u0129\u012b\3\2"+
+		"\2\2\u012a\u0105\3\2\2\2\u012a\u0113\3\2\2\2\u012a\u011f\3\2\2\2\u012a"+
+		"\u0124\3\2\2\2\u012bF\3\2\2\2\u012c\u012d\5C\"\2\u012d\u0131\7\60\2\2"+
+		"\u012e\u0130\4\62;\2\u012f\u012e\3\2\2\2\u0130\u0133\3\2\2\2\u0131\u012f"+
+		"\3\2\2\2\u0131\u0132\3\2\2\2\u0132\u0135\3\2\2\2\u0133\u0131\3\2\2\2\u0134"+
+		"\u0136\5A!\2\u0135\u0134\3\2\2\2\u0135\u0136\3\2\2\2\u0136\u0137\3\2\2"+
+		"\2\u0137\u0138\t\4\2\2\u0138\u014d\3\2\2\2\u0139\u013b\5\'\24\2\u013a"+
+		"\u0139\3\2\2\2\u013a\u013b\3\2\2\2\u013b\u013c\3\2\2\2\u013c\u013e\7\60"+
+		"\2\2\u013d\u013f\4\62;\2\u013e\u013d\3\2\2\2\u013f\u0140\3\2\2\2\u0140"+
+		"\u013e\3\2\2\2\u0140\u0141\3\2\2\2\u0141\u0143\3\2\2\2\u0142\u0144\5A"+
+		"!\2\u0143\u0142\3\2\2\2\u0143\u0144\3\2\2\2\u0144\u0145\3\2\2\2\u0145"+
+		"\u014d\t\4\2\2\u0146\u0148\5C\"\2\u0147\u0149\5A!\2\u0148\u0147\3\2\2"+
+		"\2\u0148\u0149\3\2\2\2\u0149\u014a\3\2\2\2\u014a\u014b\t\4\2\2\u014b\u014d"+
+		"\3\2\2\2\u014c\u012c\3\2\2\2\u014c\u013a\3\2\2\2\u014c\u0146\3\2\2\2\u014d"+
+		"H\3\2\2\2\u014e\u014f\5C\"\2\u014f\u0150\t\5\2\2\u0150J\3\2\2\2\u0151"+
+		"\u0155\t\6\2\2\u0152\u0154\t\7\2\2\u0153\u0152\3\2\2\2\u0154\u0157\3\2"+
+		"\2\2\u0155\u0153\3\2\2\2\u0155\u0156\3\2\2\2\u0156L\3\2\2\2\u0157\u0155"+
+		"\3\2\2\2\u0158\u0159\n\b\2\2\u0159N\3\2\2\2\u015a\u015e\7$\2\2\u015b\u015d"+
+		"\5M\'\2\u015c\u015b\3\2\2\2\u015d\u0160\3\2\2\2\u015e\u015c\3\2\2\2\u015e"+
+		"\u015f\3\2\2\2\u015f\u0161\3\2\2\2\u0160\u015e\3\2\2\2\u0161\u016b\7$"+
+		"\2\2\u0162\u0166\7)\2\2\u0163\u0165\5M\'\2\u0164\u0163\3\2\2\2\u0165\u0168"+
+		"\3\2\2\2\u0166\u0164\3\2\2\2\u0166\u0167\3\2\2\2\u0167\u0169\3\2\2\2\u0168"+
+		"\u0166\3\2\2\2\u0169\u016b\7)\2\2\u016a\u015a\3\2\2\2\u016a\u0162\3\2"+
+		"\2\2\u016bP\3\2\2\2\u016c\u016d\7\61\2\2\u016d\u016e\7\61\2\2\u016e\u0170"+
+		"\3\2\2\2\u016f\u0171\13\2\2\2\u0170\u016f\3\2\2\2\u0171\u0172\3\2\2\2"+
+		"\u0172\u0173\3\2\2\2\u0172\u0170\3\2\2\2\u0173\u0175\3\2\2\2\u0174\u0176"+
+		"\t\t\2\2\u0175\u0174\3\2\2\2\u0176\u0177\3\2\2\2\u0177\u0178\b)\2\2\u0178"+
+		"R\3\2\2\2\u0179\u017b\t\n\2\2\u017a\u0179\3\2\2\2\u017b\u017c\3\2\2\2"+
+		"\u017c\u017a\3\2\2\2\u017c\u017d\3\2\2\2\u017d\u017e\3\2\2\2\u017e\u017f"+
+		"\b*\2\2\u017fT\3\2\2\2*\2_goy\u0085\u009f\u00a9\u00b3\u00bd\u00e9\u00ee"+
+		"\u00f3\u00f6\u00fa\u0100\u0103\u010a\u010e\u0111\u0117\u011a\u011d\u0122"+
+		"\u0126\u012a\u0131\u0135\u013a\u0140\u0143\u0148\u014c\u0155\u015e\u0166"+
+		"\u016a\u0172\u0175\u017c\3\b\2\2";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java
index 5c2f830..8755e2a 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java
@@ -435,6 +435,30 @@ public interface StellarListener extends ParseTreeListener {
 	 */
 	void exitIntLiteral(StellarParser.IntLiteralContext ctx);
 	/**
+	 * Enter a parse tree produced by the {@code LongLiteral}
+	 * labeled alternative in {@link StellarParser#arithmetic_operands}.
+	 * @param ctx the parse tree
+	 */
+	void enterLongLiteral(StellarParser.LongLiteralContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code LongLiteral}
+	 * labeled alternative in {@link StellarParser#arithmetic_operands}.
+	 * @param ctx the parse tree
+	 */
+	void exitLongLiteral(StellarParser.LongLiteralContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code FloatLiteral}
+	 * labeled alternative in {@link StellarParser#arithmetic_operands}.
+	 * @param ctx the parse tree
+	 */
+	void enterFloatLiteral(StellarParser.FloatLiteralContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code FloatLiteral}
+	 * labeled alternative in {@link StellarParser#arithmetic_operands}.
+	 * @param ctx the parse tree
+	 */
+	void exitFloatLiteral(StellarParser.FloatLiteralContext ctx);
+	/**
 	 * Enter a parse tree produced by the {@code Variable}
 	 * labeled alternative in {@link StellarParser#arithmetic_operands}.
 	 * @param ctx the parse tree

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java
index c1e388b..d41df54 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java
@@ -41,8 +41,8 @@ public class StellarParser extends Parser {
 		GT=11, GTE=12, QUESTION=13, COLON=14, IF=15, THEN=16, ELSE=17, NULL=18, 
 		MINUS=19, PLUS=20, DIV=21, MUL=22, LBRACE=23, RBRACE=24, LBRACKET=25, 
 		RBRACKET=26, LPAREN=27, RPAREN=28, IN=29, NIN=30, EXISTS=31, EXPONENT=32, 
-		INT_LITERAL=33, DOUBLE_LITERAL=34, IDENTIFIER=35, STRING_LITERAL=36, COMMENT=37, 
-		WS=38;
+		INT_LITERAL=33, DOUBLE_LITERAL=34, FLOAT_LITERAL=35, LONG_LITERAL=36, 
+		IDENTIFIER=37, STRING_LITERAL=38, COMMENT=39, WS=40;
 	public static final int
 		RULE_transformation = 0, RULE_transformation_expr = 1, RULE_conditional_expr = 2, 
 		RULE_comparison_expr = 3, RULE_transformation_entity = 4, RULE_comp_operator = 5, 
@@ -67,7 +67,8 @@ public class StellarParser extends Parser {
 		"LTE", "GT", "GTE", "QUESTION", "COLON", "IF", "THEN", "ELSE", "NULL", 
 		"MINUS", "PLUS", "DIV", "MUL", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", 
 		"LPAREN", "RPAREN", "IN", "NIN", "EXISTS", "EXPONENT", "INT_LITERAL", 
-		"DOUBLE_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS"
+		"DOUBLE_LITERAL", "FLOAT_LITERAL", "LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", 
+		"COMMENT", "WS"
 	};
 	public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
 
@@ -380,6 +381,8 @@ public class StellarParser extends Parser {
 			case EXISTS:
 			case INT_LITERAL:
 			case DOUBLE_LITERAL:
+			case FLOAT_LITERAL:
+			case LONG_LITERAL:
 			case IDENTIFIER:
 			case STRING_LITERAL:
 				_localctx = new TernaryFuncWithoutIfContext(_localctx);
@@ -1679,6 +1682,30 @@ public class StellarParser extends Parser {
 			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitNumericFunctions(this);
 		}
 	}
+	public static class LongLiteralContext extends Arithmetic_operandsContext {
+		public TerminalNode LONG_LITERAL() { return getToken(StellarParser.LONG_LITERAL, 0); }
+		public LongLiteralContext(Arithmetic_operandsContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterLongLiteral(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitLongLiteral(this);
+		}
+	}
+	public static class FloatLiteralContext extends Arithmetic_operandsContext {
+		public TerminalNode FLOAT_LITERAL() { return getToken(StellarParser.FLOAT_LITERAL, 0); }
+		public FloatLiteralContext(Arithmetic_operandsContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterFloatLiteral(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitFloatLiteral(this);
+		}
+	}
 	public static class CondExprContext extends Arithmetic_operandsContext {
 		public TerminalNode LPAREN() { return getToken(StellarParser.LPAREN, 0); }
 		public Conditional_exprContext conditional_expr() {
@@ -1740,7 +1767,7 @@ public class StellarParser extends Parser {
 		Arithmetic_operandsContext _localctx = new Arithmetic_operandsContext(_ctx, getState());
 		enterRule(_localctx, 32, RULE_arithmetic_operands);
 		try {
-			setState(207);
+			setState(209);
 			switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) {
 			case 1:
 				_localctx = new NumericFunctionsContext(_localctx);
@@ -1767,34 +1794,50 @@ public class StellarParser extends Parser {
 				}
 				break;
 			case 4:
-				_localctx = new VariableContext(_localctx);
+				_localctx = new LongLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 4);
 				{
 				setState(198);
-				match(IDENTIFIER);
+				match(LONG_LITERAL);
 				}
 				break;
 			case 5:
-				_localctx = new ParenArithContext(_localctx);
+				_localctx = new FloatLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 5);
 				{
 				setState(199);
-				match(LPAREN);
+				match(FLOAT_LITERAL);
+				}
+				break;
+			case 6:
+				_localctx = new VariableContext(_localctx);
+				enterOuterAlt(_localctx, 6);
+				{
 				setState(200);
-				arithmetic_expr(0);
+				match(IDENTIFIER);
+				}
+				break;
+			case 7:
+				_localctx = new ParenArithContext(_localctx);
+				enterOuterAlt(_localctx, 7);
+				{
 				setState(201);
+				match(LPAREN);
+				setState(202);
+				arithmetic_expr(0);
+				setState(203);
 				match(RPAREN);
 				}
 				break;
-			case 6:
+			case 8:
 				_localctx = new CondExprContext(_localctx);
-				enterOuterAlt(_localctx, 6);
+				enterOuterAlt(_localctx, 8);
 				{
-				setState(203);
+				setState(205);
 				match(LPAREN);
-				setState(204);
+				setState(206);
 				conditional_expr();
-				setState(205);
+				setState(207);
 				match(RPAREN);
 				}
 				break;
@@ -1938,13 +1981,13 @@ public class StellarParser extends Parser {
 		enterRule(_localctx, 34, RULE_identifier_operand);
 		int _la;
 		try {
-			setState(223);
+			setState(225);
 			switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) {
 			case 1:
 				_localctx = new LogicalConstContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(209);
+				setState(211);
 				_la = _input.LA(1);
 				if ( !(_la==TRUE || _la==FALSE) ) {
 				_errHandler.recoverInline(this);
@@ -1957,7 +2000,7 @@ public class StellarParser extends Parser {
 				_localctx = new ArithmeticOperandsContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(210);
+				setState(212);
 				arithmetic_expr(0);
 				}
 				break;
@@ -1965,7 +2008,7 @@ public class StellarParser extends Parser {
 				_localctx = new StringLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(211);
+				setState(213);
 				match(STRING_LITERAL);
 				}
 				break;
@@ -1973,7 +2016,7 @@ public class StellarParser extends Parser {
 				_localctx = new ListContext(_localctx);
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(212);
+				setState(214);
 				list_entity();
 				}
 				break;
@@ -1981,7 +2024,7 @@ public class StellarParser extends Parser {
 				_localctx = new MapConstContext(_localctx);
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(213);
+				setState(215);
 				map_entity();
 				}
 				break;
@@ -1989,7 +2032,7 @@ public class StellarParser extends Parser {
 				_localctx = new NullConstContext(_localctx);
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(214);
+				setState(216);
 				match(NULL);
 				}
 				break;
@@ -1997,13 +2040,13 @@ public class StellarParser extends Parser {
 				_localctx = new ExistsFuncContext(_localctx);
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(215);
+				setState(217);
 				match(EXISTS);
-				setState(216);
+				setState(218);
 				match(LPAREN);
-				setState(217);
+				setState(219);
 				match(IDENTIFIER);
-				setState(218);
+				setState(220);
 				match(RPAREN);
 				}
 				break;
@@ -2011,11 +2054,11 @@ public class StellarParser extends Parser {
 				_localctx = new CondExpr_parenContext(_localctx);
 				enterOuterAlt(_localctx, 8);
 				{
-				setState(219);
+				setState(221);
 				match(LPAREN);
-				setState(220);
+				setState(222);
 				conditional_expr();
-				setState(221);
+				setState(223);
 				match(RPAREN);
 				}
 				break;
@@ -2092,7 +2135,7 @@ public class StellarParser extends Parser {
 	}
 
 	public static final String _serializedATN =
-		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3(\u00e4\4\2\t\2\4"+
+		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3*\u00e6\4\2\t\2\4"+
 		"\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+
 		"\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
 		"\4\23\t\23\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\5\3\62\n\3\3\4"+
@@ -2107,65 +2150,66 @@ public class StellarParser extends Parser {
 		"\3\17\3\17\3\17\7\17\u00b0\n\17\f\17\16\17\u00b3\13\17\3\20\3\20\3\20"+
 		"\3\20\3\20\3\20\3\20\3\20\3\20\7\20\u00be\n\20\f\20\16\20\u00c1\13\20"+
 		"\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22"+
-		"\3\22\5\22\u00d2\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+
-		"\3\23\3\23\3\23\3\23\5\23\u00e2\n\23\3\23\2\7\b\24\30\34\36\24\2\4\6\b"+
-		"\n\f\16\20\22\24\26\30\32\34\36 \"$\2\6\3\2\t\16\3\2\25\26\3\2\27\30\3"+
-		"\2\7\b\u00f4\2&\3\2\2\2\4\61\3\2\2\2\6@\3\2\2\2\bY\3\2\2\2\nf\3\2\2\2"+
-		"\fh\3\2\2\2\16j\3\2\2\2\20l\3\2\2\2\22t\3\2\2\2\24y\3\2\2\2\26\u008c\3"+
-		"\2\2\2\30\u008e\3\2\2\2\32\u00a4\3\2\2\2\34\u00a6\3\2\2\2\36\u00b4\3\2"+
-		"\2\2 \u00c2\3\2\2\2\"\u00d1\3\2\2\2$\u00e1\3\2\2\2&\'\5\4\3\2\'(\7\2\2"+
-		"\3(\3\3\2\2\2)\62\5\6\4\2*+\7\35\2\2+,\5\4\3\2,-\7\36\2\2-\62\3\2\2\2"+
-		".\62\5\34\17\2/\62\5\n\6\2\60\62\5\b\5\2\61)\3\2\2\2\61*\3\2\2\2\61.\3"+
-		"\2\2\2\61/\3\2\2\2\61\60\3\2\2\2\62\5\3\2\2\2\63\64\5\b\5\2\64\65\7\17"+
-		"\2\2\65\66\5\4\3\2\66\67\7\20\2\2\678\5\4\3\28A\3\2\2\29:\7\21\2\2:;\5"+
-		"\b\5\2;<\7\22\2\2<=\5\4\3\2=>\7\23\2\2>?\5\4\3\2?A\3\2\2\2@\63\3\2\2\2"+
-		"@9\3\2\2\2A\7\3\2\2\2BC\b\5\1\2CD\5$\23\2DE\5\f\7\2EF\5$\23\2FZ\3\2\2"+
-		"\2GH\5$\23\2HI\7\37\2\2IJ\5$\23\2JZ\3\2\2\2KL\5$\23\2LM\7 \2\2MN\5$\23"+
-		"\2NZ\3\2\2\2OP\7\6\2\2PQ\7\35\2\2QR\5\b\5\2RS\7\36\2\2SZ\3\2\2\2TU\7\35"+
-		"\2\2UV\5\b\5\2VW\7\36\2\2WZ\3\2\2\2XZ\5$\23\2YB\3\2\2\2YG\3\2\2\2YK\3"+
-		"\2\2\2YO\3\2\2\2YT\3\2\2\2YX\3\2\2\2Zc\3\2\2\2[\\\f\7\2\2\\]\7\4\2\2]"+
-		"b\5\b\5\b^_\f\6\2\2_`\7\5\2\2`b\5\b\5\7a[\3\2\2\2a^\3\2\2\2be\3\2\2\2"+
-		"ca\3\2\2\2cd\3\2\2\2d\t\3\2\2\2ec\3\2\2\2fg\5$\23\2g\13\3\2\2\2hi\t\2"+
-		"\2\2i\r\3\2\2\2jk\t\3\2\2k\17\3\2\2\2lm\t\4\2\2m\21\3\2\2\2no\7\35\2\2"+
-		"op\5\24\13\2pq\7\36\2\2qu\3\2\2\2rs\7\35\2\2su\7\36\2\2tn\3\2\2\2tr\3"+
-		"\2\2\2u\23\3\2\2\2vw\b\13\1\2wz\5$\23\2xz\5\6\4\2yv\3\2\2\2yx\3\2\2\2"+
-		"z\u0083\3\2\2\2{|\f\5\2\2|}\7\3\2\2}\u0082\5$\23\2~\177\f\3\2\2\177\u0080"+
-		"\7\3\2\2\u0080\u0082\5\6\4\2\u0081{\3\2\2\2\u0081~\3\2\2\2\u0082\u0085"+
-		"\3\2\2\2\u0083\u0081\3\2\2\2\u0083\u0084\3\2\2\2\u0084\25\3\2\2\2\u0085"+
-		"\u0083\3\2\2\2\u0086\u0087\7\33\2\2\u0087\u0088\5\24\13\2\u0088\u0089"+
-		"\7\34\2\2\u0089\u008d\3\2\2\2\u008a\u008b\7\33\2\2\u008b\u008d\7\34\2"+
-		"\2\u008c\u0086\3\2\2\2\u008c\u008a\3\2\2\2\u008d\27\3\2\2\2\u008e\u008f"+
-		"\b\r\1\2\u008f\u0090\5$\23\2\u0090\u0091\7\20\2\2\u0091\u0092\5\4\3\2"+
-		"\u0092\u009b\3\2\2\2\u0093\u0094\f\3\2\2\u0094\u0095\7\3\2\2\u0095\u0096"+
-		"\5$\23\2\u0096\u0097\7\20\2\2\u0097\u0098\5\4\3\2\u0098\u009a\3\2\2\2"+
-		"\u0099\u0093\3\2\2\2\u009a\u009d\3\2\2\2\u009b\u0099\3\2\2\2\u009b\u009c"+
-		"\3\2\2\2\u009c\31\3\2\2\2\u009d\u009b\3\2\2\2\u009e\u009f\7\31\2\2\u009f"+
-		"\u00a0\5\30\r\2\u00a0\u00a1\7\32\2\2\u00a1\u00a5\3\2\2\2\u00a2\u00a3\7"+
-		"\31\2\2\u00a3\u00a5\7\32\2\2\u00a4\u009e\3\2\2\2\u00a4\u00a2\3\2\2\2\u00a5"+
-		"\33\3\2\2\2\u00a6\u00a7\b\17\1\2\u00a7\u00a8\5\36\20\2\u00a8\u00b1\3\2"+
-		"\2\2\u00a9\u00aa\f\4\2\2\u00aa\u00ab\7\26\2\2\u00ab\u00b0\5\36\20\2\u00ac"+
-		"\u00ad\f\3\2\2\u00ad\u00ae\7\25\2\2\u00ae\u00b0\5\36\20\2\u00af\u00a9"+
-		"\3\2\2\2\u00af\u00ac\3\2\2\2\u00b0\u00b3\3\2\2\2\u00b1\u00af\3\2\2\2\u00b1"+
-		"\u00b2\3\2\2\2\u00b2\35\3\2\2\2\u00b3\u00b1\3\2\2\2\u00b4\u00b5\b\20\1"+
-		"\2\u00b5\u00b6\5\"\22\2\u00b6\u00bf\3\2\2\2\u00b7\u00b8\f\4\2\2\u00b8"+
-		"\u00b9\7\30\2\2\u00b9\u00be\5\36\20\5\u00ba\u00bb\f\3\2\2\u00bb\u00bc"+
-		"\7\27\2\2\u00bc\u00be\5\36\20\4\u00bd\u00b7\3\2\2\2\u00bd\u00ba\3\2\2"+
-		"\2\u00be\u00c1\3\2\2\2\u00bf\u00bd\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\37"+
-		"\3\2\2\2\u00c1\u00bf\3\2\2\2\u00c2\u00c3\7%\2\2\u00c3\u00c4\5\22\n\2\u00c4"+
-		"!\3\2\2\2\u00c5\u00d2\5 \21\2\u00c6\u00d2\7$\2\2\u00c7\u00d2\7#\2\2\u00c8"+
-		"\u00d2\7%\2\2\u00c9\u00ca\7\35\2\2\u00ca\u00cb\5\34\17\2\u00cb\u00cc\7"+
-		"\36\2\2\u00cc\u00d2\3\2\2\2\u00cd\u00ce\7\35\2\2\u00ce\u00cf\5\6\4\2\u00cf"+
-		"\u00d0\7\36\2\2\u00d0\u00d2\3\2\2\2\u00d1\u00c5\3\2\2\2\u00d1\u00c6\3"+
-		"\2\2\2\u00d1\u00c7\3\2\2\2\u00d1\u00c8\3\2\2\2\u00d1\u00c9\3\2\2\2\u00d1"+
-		"\u00cd\3\2\2\2\u00d2#\3\2\2\2\u00d3\u00e2\t\5\2\2\u00d4\u00e2\5\34\17"+
-		"\2\u00d5\u00e2\7&\2\2\u00d6\u00e2\5\26\f\2\u00d7\u00e2\5\32\16\2\u00d8"+
-		"\u00e2\7\24\2\2\u00d9\u00da\7!\2\2\u00da\u00db\7\35\2\2\u00db\u00dc\7"+
-		"%\2\2\u00dc\u00e2\7\36\2\2\u00dd\u00de\7\35\2\2\u00de\u00df\5\6\4\2\u00df"+
-		"\u00e0\7\36\2\2\u00e0\u00e2\3\2\2\2\u00e1\u00d3\3\2\2\2\u00e1\u00d4\3"+
-		"\2\2\2\u00e1\u00d5\3\2\2\2\u00e1\u00d6\3\2\2\2\u00e1\u00d7\3\2\2\2\u00e1"+
-		"\u00d8\3\2\2\2\u00e1\u00d9\3\2\2\2\u00e1\u00dd\3\2\2\2\u00e2%\3\2\2\2"+
-		"\24\61@Yacty\u0081\u0083\u008c\u009b\u00a4\u00af\u00b1\u00bd\u00bf\u00d1"+
-		"\u00e1";
+		"\3\22\3\22\3\22\5\22\u00d4\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+
+		"\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u00e4\n\23\3\23\2\7\b\24\30\34\36"+
+		"\24\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$\2\6\3\2\t\16\3\2\25\26"+
+		"\3\2\27\30\3\2\7\b\u00f8\2&\3\2\2\2\4\61\3\2\2\2\6@\3\2\2\2\bY\3\2\2\2"+
+		"\nf\3\2\2\2\fh\3\2\2\2\16j\3\2\2\2\20l\3\2\2\2\22t\3\2\2\2\24y\3\2\2\2"+
+		"\26\u008c\3\2\2\2\30\u008e\3\2\2\2\32\u00a4\3\2\2\2\34\u00a6\3\2\2\2\36"+
+		"\u00b4\3\2\2\2 \u00c2\3\2\2\2\"\u00d3\3\2\2\2$\u00e3\3\2\2\2&\'\5\4\3"+
+		"\2\'(\7\2\2\3(\3\3\2\2\2)\62\5\6\4\2*+\7\35\2\2+,\5\4\3\2,-\7\36\2\2-"+
+		"\62\3\2\2\2.\62\5\34\17\2/\62\5\n\6\2\60\62\5\b\5\2\61)\3\2\2\2\61*\3"+
+		"\2\2\2\61.\3\2\2\2\61/\3\2\2\2\61\60\3\2\2\2\62\5\3\2\2\2\63\64\5\b\5"+
+		"\2\64\65\7\17\2\2\65\66\5\4\3\2\66\67\7\20\2\2\678\5\4\3\28A\3\2\2\29"+
+		":\7\21\2\2:;\5\b\5\2;<\7\22\2\2<=\5\4\3\2=>\7\23\2\2>?\5\4\3\2?A\3\2\2"+
+		"\2@\63\3\2\2\2@9\3\2\2\2A\7\3\2\2\2BC\b\5\1\2CD\5$\23\2DE\5\f\7\2EF\5"+
+		"$\23\2FZ\3\2\2\2GH\5$\23\2HI\7\37\2\2IJ\5$\23\2JZ\3\2\2\2KL\5$\23\2LM"+
+		"\7 \2\2MN\5$\23\2NZ\3\2\2\2OP\7\6\2\2PQ\7\35\2\2QR\5\b\5\2RS\7\36\2\2"+
+		"SZ\3\2\2\2TU\7\35\2\2UV\5\b\5\2VW\7\36\2\2WZ\3\2\2\2XZ\5$\23\2YB\3\2\2"+
+		"\2YG\3\2\2\2YK\3\2\2\2YO\3\2\2\2YT\3\2\2\2YX\3\2\2\2Zc\3\2\2\2[\\\f\7"+
+		"\2\2\\]\7\4\2\2]b\5\b\5\b^_\f\6\2\2_`\7\5\2\2`b\5\b\5\7a[\3\2\2\2a^\3"+
+		"\2\2\2be\3\2\2\2ca\3\2\2\2cd\3\2\2\2d\t\3\2\2\2ec\3\2\2\2fg\5$\23\2g\13"+
+		"\3\2\2\2hi\t\2\2\2i\r\3\2\2\2jk\t\3\2\2k\17\3\2\2\2lm\t\4\2\2m\21\3\2"+
+		"\2\2no\7\35\2\2op\5\24\13\2pq\7\36\2\2qu\3\2\2\2rs\7\35\2\2su\7\36\2\2"+
+		"tn\3\2\2\2tr\3\2\2\2u\23\3\2\2\2vw\b\13\1\2wz\5$\23\2xz\5\6\4\2yv\3\2"+
+		"\2\2yx\3\2\2\2z\u0083\3\2\2\2{|\f\5\2\2|}\7\3\2\2}\u0082\5$\23\2~\177"+
+		"\f\3\2\2\177\u0080\7\3\2\2\u0080\u0082\5\6\4\2\u0081{\3\2\2\2\u0081~\3"+
+		"\2\2\2\u0082\u0085\3\2\2\2\u0083\u0081\3\2\2\2\u0083\u0084\3\2\2\2\u0084"+
+		"\25\3\2\2\2\u0085\u0083\3\2\2\2\u0086\u0087\7\33\2\2\u0087\u0088\5\24"+
+		"\13\2\u0088\u0089\7\34\2\2\u0089\u008d\3\2\2\2\u008a\u008b\7\33\2\2\u008b"+
+		"\u008d\7\34\2\2\u008c\u0086\3\2\2\2\u008c\u008a\3\2\2\2\u008d\27\3\2\2"+
+		"\2\u008e\u008f\b\r\1\2\u008f\u0090\5$\23\2\u0090\u0091\7\20\2\2\u0091"+
+		"\u0092\5\4\3\2\u0092\u009b\3\2\2\2\u0093\u0094\f\3\2\2\u0094\u0095\7\3"+
+		"\2\2\u0095\u0096\5$\23\2\u0096\u0097\7\20\2\2\u0097\u0098\5\4\3\2\u0098"+
+		"\u009a\3\2\2\2\u0099\u0093\3\2\2\2\u009a\u009d\3\2\2\2\u009b\u0099\3\2"+
+		"\2\2\u009b\u009c\3\2\2\2\u009c\31\3\2\2\2\u009d\u009b\3\2\2\2\u009e\u009f"+
+		"\7\31\2\2\u009f\u00a0\5\30\r\2\u00a0\u00a1\7\32\2\2\u00a1\u00a5\3\2\2"+
+		"\2\u00a2\u00a3\7\31\2\2\u00a3\u00a5\7\32\2\2\u00a4\u009e\3\2\2\2\u00a4"+
+		"\u00a2\3\2\2\2\u00a5\33\3\2\2\2\u00a6\u00a7\b\17\1\2\u00a7\u00a8\5\36"+
+		"\20\2\u00a8\u00b1\3\2\2\2\u00a9\u00aa\f\4\2\2\u00aa\u00ab\7\26\2\2\u00ab"+
+		"\u00b0\5\36\20\2\u00ac\u00ad\f\3\2\2\u00ad\u00ae\7\25\2\2\u00ae\u00b0"+
+		"\5\36\20\2\u00af\u00a9\3\2\2\2\u00af\u00ac\3\2\2\2\u00b0\u00b3\3\2\2\2"+
+		"\u00b1\u00af\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\35\3\2\2\2\u00b3\u00b1"+
+		"\3\2\2\2\u00b4\u00b5\b\20\1\2\u00b5\u00b6\5\"\22\2\u00b6\u00bf\3\2\2\2"+
+		"\u00b7\u00b8\f\4\2\2\u00b8\u00b9\7\30\2\2\u00b9\u00be\5\36\20\5\u00ba"+
+		"\u00bb\f\3\2\2\u00bb\u00bc\7\27\2\2\u00bc\u00be\5\36\20\4\u00bd\u00b7"+
+		"\3\2\2\2\u00bd\u00ba\3\2\2\2\u00be\u00c1\3\2\2\2\u00bf\u00bd\3\2\2\2\u00bf"+
+		"\u00c0\3\2\2\2\u00c0\37\3\2\2\2\u00c1\u00bf\3\2\2\2\u00c2\u00c3\7\'\2"+
+		"\2\u00c3\u00c4\5\22\n\2\u00c4!\3\2\2\2\u00c5\u00d4\5 \21\2\u00c6\u00d4"+
+		"\7$\2\2\u00c7\u00d4\7#\2\2\u00c8\u00d4\7&\2\2\u00c9\u00d4\7%\2\2\u00ca"+
+		"\u00d4\7\'\2\2\u00cb\u00cc\7\35\2\2\u00cc\u00cd\5\34\17\2\u00cd\u00ce"+
+		"\7\36\2\2\u00ce\u00d4\3\2\2\2\u00cf\u00d0\7\35\2\2\u00d0\u00d1\5\6\4\2"+
+		"\u00d1\u00d2\7\36\2\2\u00d2\u00d4\3\2\2\2\u00d3\u00c5\3\2\2\2\u00d3\u00c6"+
+		"\3\2\2\2\u00d3\u00c7\3\2\2\2\u00d3\u00c8\3\2\2\2\u00d3\u00c9\3\2\2\2\u00d3"+
+		"\u00ca\3\2\2\2\u00d3\u00cb\3\2\2\2\u00d3\u00cf\3\2\2\2\u00d4#\3\2\2\2"+
+		"\u00d5\u00e4\t\5\2\2\u00d6\u00e4\5\34\17\2\u00d7\u00e4\7(\2\2\u00d8\u00e4"+
+		"\5\26\f\2\u00d9\u00e4\5\32\16\2\u00da\u00e4\7\24\2\2\u00db\u00dc\7!\2"+
+		"\2\u00dc\u00dd\7\35\2\2\u00dd\u00de\7\'\2\2\u00de\u00e4\7\36\2\2\u00df"+
+		"\u00e0\7\35\2\2\u00e0\u00e1\5\6\4\2\u00e1\u00e2\7\36\2\2\u00e2\u00e4\3"+
+		"\2\2\2\u00e3\u00d5\3\2\2\2\u00e3\u00d6\3\2\2\2\u00e3\u00d7\3\2\2\2\u00e3"+
+		"\u00d8\3\2\2\2\u00e3\u00d9\3\2\2\2\u00e3\u00da\3\2\2\2\u00e3\u00db\3\2"+
+		"\2\2\u00e3\u00df\3\2\2\2\u00e4%\3\2\2\2\24\61@Yacty\u0081\u0083\u008c"+
+		"\u009b\u00a4\u00af\u00b1\u00bd\u00bf\u00d3\u00e3";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ffae676c/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java
index 8f65a6f..60fdc13 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java
@@ -20,117 +20,117 @@ package org.apache.metron.common.stellar;
 
 import com.google.common.collect.ImmutableMap;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.metron.common.dsl.ParseException;
 import org.apache.metron.common.dsl.Token;
 import org.junit.Assert;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 
 import java.util.HashMap;
 import java.util.Map;
 
 import static org.apache.metron.common.utils.StellarProcessorUtils.run;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 @SuppressWarnings("unchecked")
 public class StellarArithmeticTest {
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
 
   @Test
   public void addingLongsShouldYieldLong() throws Exception {
     final long timestamp = 1452013350000L;
     String query = "TO_EPOCH_TIMESTAMP('2016-01-05 17:02:30', 'yyyy-MM-dd HH:mm:ss', 'UTC') + 2";
-    Assert.assertEquals(timestamp + 2, run(query, new HashMap<>()));
+    assertEquals(timestamp + 2, run(query, new HashMap<>()));
   }
 
   @Test
   public void addingIntegersShouldYieldAnInteger() throws Exception {
     String query = "1 + 2";
-    Assert.assertEquals(3, run(query, new HashMap<>()));
+    assertEquals(3, run(query, new HashMap<>()));
   }
 
   @Test
   public void addingDoublesShouldYieldADouble() throws Exception {
     String query = "1.0 + 2.0";
-    Assert.assertEquals(3.0, run(query, new HashMap<>()));
+    assertEquals(3.0, run(query, new HashMap<>()));
   }
 
   @Test
   public void addingDoubleAndIntegerWhereSubjectIsDoubleShouldYieldADouble() throws Exception {
     String query = "2.1 + 1";
-    Assert.assertEquals(3.1, run(query, new HashMap<>()));
+    assertEquals(3.1, run(query, new HashMap<>()));
   }
 
   @Test
   public void addingDoubleAndIntegerWhereSubjectIsIntegerShouldYieldADouble() throws Exception {
     String query = "1 + 2.1";
-    Assert.assertEquals(3.1, run(query, new HashMap<>()));
+    assertEquals(3.1, run(query, new HashMap<>()));
   }
 
   @Test
   public void testArithmetic() {
-    {
-      String query = "1 + 2";
-      Assert.assertEquals(3, ((Number)run(query, new HashMap<>())).doubleValue(), 1e-3);
-    }
-    {
-      String query = "1.2 + 2";
-      Assert.assertEquals(3.2, ((Number)run(query, new HashMap<>())).doubleValue(), 1e-3);
-    }
-    {
-      String query = "1.2e-3 + 2";
-      Assert.assertEquals(1.2e-3 + 2, ((Number)run(query, new HashMap<>())).doubleValue(), 1e-3);
-    }
+    assertEquals(3, run("1 + 2", new HashMap<>()));
+    assertEquals(3.2, run("1.2 + 2", new HashMap<>()));
+    assertEquals(1.2e-3 + 2, run("1.2e-3 + 2", new HashMap<>()));
+    assertEquals(1.2f + 3.7, run("1.2f + 3.7", new HashMap<>()));
+    assertEquals(12L * (1.2f + 7), run("12L*(1.2f + 7)", new HashMap<>()));
+    assertEquals(12.2f * (1.2f + 7L), run("TO_FLOAT(12.2) * (1.2f + 7L)", new HashMap<>()));
   }
 
   @Test
   public void testNumericOperations() {
     {
       String query = "TO_INTEGER(1 + 2*2 + 3 - 4 - 0.5)";
-      Assert.assertEquals(3, (Integer) run(query, new HashMap<>()), 1e-6);
+      assertEquals(3, (Integer) run(query, new HashMap<>()), 1e-6);
     }
     {
       String query = "1 + 2*2 + 3 - 4 - 0.5";
-      Assert.assertEquals(3.5, (Double) run(query, new HashMap<>()), 1e-6);
+      assertEquals(3.5, (Double) run(query, new HashMap<>()), 1e-6);
     }
     {
       String query = "2*one*(1 + 2*2 + 3 - 4)";
-      Assert.assertEquals(8, run(query, ImmutableMap.of("one", 1)));
+      assertEquals(8, run(query, ImmutableMap.of("one", 1)));
     }
     {
       String query = "2*(1 + 2 + 3 - 4)";
-      Assert.assertEquals(4, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
+      assertEquals(4, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
     }
     {
       String query = "1 + 2 + 3 - 4 - 2";
-      Assert.assertEquals(0, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
+      assertEquals(0, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
     }
     {
       String query = "1 + 2 + 3 + 4";
-      Assert.assertEquals(10, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
+      assertEquals(10, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
     }
     {
       String query = "(one + 2)*3";
-      Assert.assertEquals(9, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
+      assertEquals(9, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
     }
     {
       String query = "TO_INTEGER((one + 2)*3.5)";
-      Assert.assertEquals(10, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
+      assertEquals(10, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
     }
     {
       String query = "1 + 2*3";
-      Assert.assertEquals(7, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
+      assertEquals(7, (Integer) run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)), 1e-6);
     }
     {
       String query = "TO_LONG(foo)";
-      Assert.assertNull(run(query,ImmutableMap.of("foo","not a number")));
+      Assert.assertNull(run(query, ImmutableMap.of("foo", "not a number")));
     }
     {
       String query = "TO_LONG(foo)";
-      Assert.assertEquals(232321L,run(query,ImmutableMap.of("foo","00232321")));
+      assertEquals(232321L, run(query, ImmutableMap.of("foo", "00232321")));
     }
     {
       String query = "TO_LONG(foo)";
-      Assert.assertEquals(Long.MAX_VALUE,run(query,ImmutableMap.of("foo", Long.toString(Long.MAX_VALUE))));
+      assertEquals(Long.MAX_VALUE, run(query, ImmutableMap.of("foo", Long.toString(Long.MAX_VALUE))));
     }
   }
 
@@ -171,11 +171,140 @@ public class StellarArithmeticTest {
           put(Pair.of("3", "3"), Integer.class);
         }};
 
-    expectedReturnTypeMappings.forEach( (pair, expectedClass) -> {
+    expectedReturnTypeMappings.forEach((pair, expectedClass) -> {
       assertTrue(run(pair.getLeft() + " * " + pair.getRight(), ImmutableMap.of()).getClass() == expectedClass);
       assertTrue(run(pair.getLeft() + " + " + pair.getRight(), ImmutableMap.of()).getClass() == expectedClass);
       assertTrue(run(pair.getLeft() + " - " + pair.getRight(), ImmutableMap.of()).getClass() == expectedClass);
       assertTrue(run(pair.getLeft() + " / " + pair.getRight(), ImmutableMap.of()).getClass() == expectedClass);
     });
   }
+
+  @Test
+  public void happyPathFloatArithmetic() throws Exception {
+    Object run = run(".0f * 1", ImmutableMap.of());
+    assertEquals(.0f * 1, run);
+    assertEquals(Float.class, run.getClass());
+
+    Object run1 = run("0.f / 1F", ImmutableMap.of());
+    assertEquals(0.f / 1F, run1);
+    assertEquals(Float.class, run1.getClass());
+
+    Object run2 = run(".0F + 1.0f", ImmutableMap.of());
+    assertEquals(.0F + 1.0f, run2);
+    assertEquals(Float.class, run2.getClass());
+
+    Object run3 = run("0.0f - 0.1f", ImmutableMap.of());
+    assertEquals(0.0f - 0.1f, run3);
+    assertEquals(Float.class, run2.getClass());
+  }
+
+  @SuppressWarnings("PointlessArithmeticExpression")
+  @Test
+  public void happyPathLongArithmetic() throws Exception {
+    assertEquals(0L * 1L, run("0L * 1L", ImmutableMap.of()));
+    assertEquals(0l / 1L, run("0l / 1L", ImmutableMap.of()));
+    assertEquals(1L - 1l, run("1L - 1l", ImmutableMap.of()));
+    assertEquals(2147483648L + 1L, run("2147483648L + 1L", ImmutableMap.of()));
+  }
+
+  @SuppressWarnings("NumericOverflow")
+  @Test
+  public void checkInterestingCases() throws Exception {
+    assertEquals((((((1L) + .5d)))) * 6.f, run("(((((1L) + .5d)))) * 6.f", ImmutableMap.of()));
+    assertEquals((((((1L) + .5d)))) * 6.f / 0.f, run("(((((1L) + .5d)))) * 6.f / 0.f", ImmutableMap.of()));
+    assertEquals(Double.class, run("(((((1L) + .5d)))) * 6.f / 0.f", ImmutableMap.of()).getClass());
+  }
+
+  @Test
+  public void makeSureStellarProperlyEvaluatesLiteralsToExpectedTypes() throws Exception {
+    {
+      assertEquals(Float.class, run("6.f", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run(".0f", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("6.0F", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("6f", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("6e-6f", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("6e+6f", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("6e6f", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("TO_FLOAT(1231)", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("TO_FLOAT(12.31)", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("TO_FLOAT(12.31f)", ImmutableMap.of()).getClass());
+      assertEquals(Float.class, run("TO_FLOAT(12L)", ImmutableMap.of()).getClass());
+    }
+    {
+      assertEquals(Double.class, run("6.d", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("6.D", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("6.0d", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("6D", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("6e5D", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("6e-5D", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("6e+5D", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("TO_DOUBLE(1231)", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("TO_DOUBLE(12.31)", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("TO_DOUBLE(12.31f)", ImmutableMap.of()).getClass());
+      assertEquals(Double.class, run("TO_DOUBLE(12L)", ImmutableMap.of()).getClass());
+    }
+    {
+      assertEquals(Integer.class, run("6", ImmutableMap.of()).getClass());
+      assertEquals(Integer.class, run("60000000", ImmutableMap.of()).getClass());
+      assertEquals(Integer.class, run("-0", ImmutableMap.of()).getClass());
+      assertEquals(Integer.class, run("-60000000", ImmutableMap.of()).getClass());
+      assertEquals(Integer.class, run("TO_INTEGER(1231)", ImmutableMap.of()).getClass());
+      assertEquals(Integer.class, run("TO_INTEGER(12.31)", ImmutableMap.of()).getClass());
+      assertEquals(Integer.class, run("TO_INTEGER(12.31f)", ImmutableMap.of()).getClass());
+      assertEquals(Integer.class, run("TO_INTEGER(12L)", ImmutableMap.of()).getClass());
+    }
+    {
+      assertEquals(Long.class, run("12345678910l", ImmutableMap.of()).getClass());
+      assertEquals(Long.class, run("0l", ImmutableMap.of()).getClass());
+      assertEquals(Long.class, run("-0l", ImmutableMap.of()).getClass());
+      assertEquals(Long.class, run("-60000000L", ImmutableMap.of()).getClass());
+      assertEquals(Long.class, run("-60000000L", ImmutableMap.of()).getClass());
+      assertEquals(Long.class, run("TO_LONG(1231)", ImmutableMap.of()).getClass());
+      assertEquals(Long.class, run("TO_LONG(12.31)", ImmutableMap.of()).getClass());
+      assertEquals(Long.class, run("TO_LONG(12.31f)", ImmutableMap.of()).getClass());
+      assertEquals(Long.class, run("TO_LONG(12L)", ImmutableMap.of()).getClass());
+    }
+  }
+
+  @Test
+  public void parseExceptionMultipleLeadingZerosOnInteger() throws Exception {
+    exception.expect(ParseException.class);
+    run("000000", ImmutableMap.of());
+  }
+
+  @Test
+  public void parseExceptionMultipleLeadingZerosOnLong() throws Exception {
+    exception.expect(ParseException.class);
+    run("000000l", ImmutableMap.of());
+  }
+
+  @Test
+  public void parseExceptionMultipleLeadingZerosOnDouble() throws Exception {
+    exception.expect(ParseException.class);
+    run("000000d", ImmutableMap.of());
+  }
+
+  @Test
+  public void parseExceptionMultipleLeadingZerosOnFloat() throws Exception {
+    exception.expect(ParseException.class);
+    run("000000f", ImmutableMap.of());
+  }
+
+  @Test
+  public void parseExceptionMultipleLeadingNegativeSignsFloat() throws Exception {
+    exception.expect(ParseException.class);
+    run("--000000f", ImmutableMap.of());
+  }
+
+  @Test
+  public void parseExceptionMultipleLeadingNegativeSignsDouble() throws Exception {
+    exception.expect(ParseException.class);
+    run("--000000D", ImmutableMap.of());
+  }
+
+  @Test
+  public void parseExceptionMultipleLeadingNegativeSignsLong() throws Exception {
+    exception.expect(ParseException.class);
+    run("--000000L", ImmutableMap.of());
+  }
 }