metron-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ceste...@apache.org
Subject [2/2] incubator-metron git commit: METRON-624: Updated Comparison/Equality Evaluations in Stellar closes apache/incubator-metron#404
Date Fri, 13 Jan 2017 17:59:40 GMT
METRON-624: Updated Comparison/Equality Evaluations in Stellar closes apache/incubator-metron#404


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

Branch: refs/heads/master
Commit: 56ff50c3d2da31992004ea066de356965f7adf4b
Parents: 52aa580
Author: JJ <jjmeyer0@gmail.com>
Authored: Fri Jan 13 12:58:03 2017 -0500
Committer: cstella <cestella@gmail.com>
Committed: Fri Jan 13 12:58:03 2017 -0500

----------------------------------------------------------------------
 metron-platform/metron-common/README.md         |  27 ++
 .../metron/common/stellar/generated/Stellar.g4  |  76 ++--
 .../metron-common/src/main/java/Stellar.tokens  | 128 +++---
 .../src/main/java/StellarLexer.tokens           | 128 +++---
 .../common/stellar/BaseStellarProcessor.java    | 109 ++++-
 .../metron/common/stellar/StellarCompiler.java  |  53 +--
 .../ComparisonExpressionEvaluator.java          |  41 ++
 ...mparisonExpressionWithOperatorEvaluator.java |  95 ++++
 .../ComparisonOperatorsEvaluator.java           | 185 ++++++++
 .../evaluators/EqualityOperatorsEvaluator.java  |  75 ++++
 .../common/stellar/generated/StellarLexer.java  | 330 +++++++-------
 .../common/stellar/generated/StellarParser.java | 149 ++++---
 .../stellar/BaseStellarProcessorTest.java       | 116 +++++
 .../common/stellar/StellarArithmeticTest.java   |  22 +
 ...larComparisonExpressionWithOperatorTest.java | 216 ++++++++-
 .../common/stellar/StellarCompilerTest.java     |  33 +-
 .../stellar/StellarPredicateProcessorTest.java  |  36 ++
 .../metron/common/stellar/StellarTest.java      |  51 +--
 ...isonExpressionWithOperatorEvaluatorTest.java | 126 ++++++
 .../ComparisonOperatorsEvaluatorTest.java       | 446 +++++++++++++++++++
 .../EqualityOperatorsEvaluatorTest.java         | 186 ++++++++
 .../common/utils/StellarProcessorUtils.java     |  51 ++-
 22 files changed, 2151 insertions(+), 528 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/README.md
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/README.md b/metron-platform/metron-common/README.md
index de277bc..019c538 100644
--- a/metron-platform/metron-common/README.md
+++ b/metron-platform/metron-common/README.md
@@ -22,6 +22,7 @@ The query language supports the following:
 * Simple boolean operations: `and`, `not`, `or`
 * Simple arithmetic operations: `*`, `/`, `+`, `-` on real numbers or integers
 * Simple comparison operations `<`, `>`, `<=`, `>=`
+* Simple equality comparison operations `==`, `!=`
 * if/then/else comparisons (i.e. `if var1 < 10 then 'less than 10' else '10 or more'`)
 * Determining whether a field exists (via `exists`)
 * The ability to have parenthesis to make order of operations explicit
@@ -41,6 +42,32 @@ The following keywords need to be single quote escaped in order to be used in St
 
 Using parens such as: "foo" : "\<ok\>" requires escaping; "foo": "\'\<ok\>\'"
 
+
+## Stellar Language Comparisons ('<', '<=', '>', '>=')
+
+1. If either side of the comparison is null then return false.
+2. If both values being compared implement number then the following:
+    * If either side is a double then get double value from both sides and compare using given operator.
+    * Else if either side is a float then get float value from both sides and compare using given operator.
+    * Else if either side is a long then get long value from both sides and compare using given operator.
+    * Otherwise get the int value from both sides and compare using given operator.
+3. If both sides are of the same type and are comparable then use the compareTo method to compare values.
+4. If none of the above are met then an exception is thrown.
+
+## Stellar Language Equality Check ('==', '!=')
+
+Below is how the '==' operator is expected to work:
+
+1. If either side of the expression is null then check equality using Java's '==' expression.
+2. Else if both sides of the expression are of Java's type Number then:
+   * If either side of the expression is a double then use the double value of both sides to test equality.
+   * Else if either side of the expression is a float then use the float value of both sides to test equality.
+   * Else if either side of the expression is a long then use long value of both sides to test equality.
+   * Otherwise use int value of both sides to test equality
+3. Otherwise use equals method compare the left side with the right side.
+
+The '!=' operator is the negation of the above.
+
 ## Stellar Core Functions
 
 |                                                                                                    |

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/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 3722533..7bdc3a7 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
@@ -41,23 +41,17 @@ grammar Stellar;
 
 /* Lexical rules */
 
+DOUBLE_QUOTE : '"';
+SINGLE_QUOTE : '\'';
 COMMA : ',';
-AND : 'and'
-    | '&&'
-    | 'AND'
-    ;
-OR  : 'or'
-    | '||'
-    | 'OR';
+PERIOD : '.';
+EOL : '\n';
 
-NOT : 'not'
-    | 'NOT';
-
-TRUE  : 'true'
-      | 'TRUE' ;
-
-FALSE : 'false'
-      | 'FALSE';
+AND : 'and' | '&&' | 'AND';
+OR : 'or' | '||' | 'OR';
+NOT : 'not' | 'NOT';
+TRUE : 'true' | 'TRUE';
+FALSE : 'false' | 'FALSE';
 
 EQ : '==' ;
 NEQ : '!=' ;
@@ -82,41 +76,49 @@ LBRACKET : '[';
 RBRACKET : ']';
 LPAREN : '(' ;
 RPAREN : ')' ;
-IN : 'in'
-   ;
-NIN : 'not in'
-   ;
+IN : 'in' | 'IN';
+NIN : 'not in' | 'NOT IN';
 EXISTS : 'exists' | 'EXISTS';
-EXPONENT : ('e' | 'E') ( PLUS|MINUS )? ('0'..'9')+;
-INT_LITERAL     :
-  MINUS? '0'
-  | MINUS? '1'..'9''0'..'9'*
+EXPONENT : E ( PLUS|MINUS )? DIGIT+;
+INT_LITERAL :
+  MINUS? ZERO
+  | MINUS? FIRST_DIGIT DIGIT*
   ;
-DOUBLE_LITERAL  :
-  INT_LITERAL '.' '0'..'9'* EXPONENT? ('d'|'D')?
-  | '.' '0'..'9'+ EXPONENT? ('d'|'D')?
-  | INT_LITERAL EXPONENT ('d'|'D')?
-  | INT_LITERAL EXPONENT? ('d'|'D')
+DOUBLE_LITERAL :
+  INT_LITERAL PERIOD DIGIT* EXPONENT? D?
+  | PERIOD DIGIT+ EXPONENT? D?
+  | INT_LITERAL EXPONENT D?
+  | INT_LITERAL EXPONENT? D
   ;
 FLOAT_LITERAL  :
-  INT_LITERAL'.''0'..'9'* EXPONENT? ('f'|'F')
-  | MINUS? '.''0'..'9'+ EXPONENT? ('f'|'F')
-  | INT_LITERAL EXPONENT? ('f'|'F')
+  INT_LITERAL PERIOD DIGIT* EXPONENT? F
+  | MINUS? PERIOD DIGIT+ EXPONENT? F
+  | INT_LITERAL EXPONENT? F
   ;
-LONG_LITERAL  : INT_LITERAL ('l'|'L') ;
+LONG_LITERAL  : INT_LITERAL L ;
 IDENTIFIER : [a-zA-Z_][a-zA-Z_\.:0-9]* ;
-fragment SCHAR:  ~['"\\\r\n];
-STRING_LITERAL : '"' SCHAR* '"'
-               | '\'' SCHAR* '\'' ;
 
+STRING_LITERAL :
+  DOUBLE_QUOTE SCHAR* DOUBLE_QUOTE
+  | SINGLE_QUOTE SCHAR* SINGLE_QUOTE
+  ;
 
 // COMMENT and WS are stripped from the output token stream by sending
 // to a different channel 'skip'
 
-COMMENT : '//' .+? ('\n'|EOF) -> skip ;
+COMMENT : '//' .+? (EOL|EOF) -> skip ;
 
 WS : [ \r\t\u000C\n]+ -> skip ;
 
+fragment ZERO: '0';
+fragment FIRST_DIGIT: '1'..'9';
+fragment DIGIT: '0'..'9';
+fragment SCHAR:  ~['"\\\r\n];
+fragment D: ('d'|'D');
+fragment E: ('e'|'E');
+fragment F: ('f'|'F');
+fragment L: ('l'|'L');
+
 
 /* Parser rules */
 
@@ -162,7 +164,7 @@ list_entity : LBRACKET op_list RBRACKET
             | LBRACKET RBRACKET;
 
 kv_list : identifier_operand COLON transformation_expr
-        | kv_list COMMA identifier_operand ':' transformation_expr
+        | kv_list COMMA identifier_operand COLON transformation_expr
         ;
 
 map_entity : LBRACE kv_list RBRACE

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/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 10bca58..cbc9c0e 100644
--- a/metron-platform/metron-common/src/main/java/Stellar.tokens
+++ b/metron-platform/metron-common/src/main/java/Stellar.tokens
@@ -1,61 +1,67 @@
-COMMA=1
-AND=2
-OR=3
-NOT=4
-TRUE=5
-FALSE=6
-EQ=7
-NEQ=8
-LT=9
-LTE=10
-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
-FLOAT_LITERAL=35
-LONG_LITERAL=36
-IDENTIFIER=37
-STRING_LITERAL=38
-COMMENT=39
-WS=40
-','=1
-'=='=7
-'!='=8
-'<'=9
-'<='=10
-'>'=11
-'>='=12
-'?'=13
-':'=14
-'-'=19
-'+'=20
-'/'=21
-'*'=22
-'{'=23
-'}'=24
-'['=25
-']'=26
-'('=27
-')'=28
-'in'=29
-'not in'=30
+DOUBLE_QUOTE=1
+SINGLE_QUOTE=2
+COMMA=3
+PERIOD=4
+EOL=5
+AND=6
+OR=7
+NOT=8
+TRUE=9
+FALSE=10
+EQ=11
+NEQ=12
+LT=13
+LTE=14
+GT=15
+GTE=16
+QUESTION=17
+COLON=18
+IF=19
+THEN=20
+ELSE=21
+NULL=22
+MINUS=23
+PLUS=24
+DIV=25
+MUL=26
+LBRACE=27
+RBRACE=28
+LBRACKET=29
+RBRACKET=30
+LPAREN=31
+RPAREN=32
+IN=33
+NIN=34
+EXISTS=35
+EXPONENT=36
+INT_LITERAL=37
+DOUBLE_LITERAL=38
+FLOAT_LITERAL=39
+LONG_LITERAL=40
+IDENTIFIER=41
+STRING_LITERAL=42
+COMMENT=43
+WS=44
+'"'=1
+'\''=2
+','=3
+'.'=4
+'\n'=5
+'=='=11
+'!='=12
+'<'=13
+'<='=14
+'>'=15
+'>='=16
+'?'=17
+':'=18
+'-'=23
+'+'=24
+'/'=25
+'*'=26
+'{'=27
+'}'=28
+'['=29
+']'=30
+'('=31
+')'=32

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/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 10bca58..cbc9c0e 100644
--- a/metron-platform/metron-common/src/main/java/StellarLexer.tokens
+++ b/metron-platform/metron-common/src/main/java/StellarLexer.tokens
@@ -1,61 +1,67 @@
-COMMA=1
-AND=2
-OR=3
-NOT=4
-TRUE=5
-FALSE=6
-EQ=7
-NEQ=8
-LT=9
-LTE=10
-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
-FLOAT_LITERAL=35
-LONG_LITERAL=36
-IDENTIFIER=37
-STRING_LITERAL=38
-COMMENT=39
-WS=40
-','=1
-'=='=7
-'!='=8
-'<'=9
-'<='=10
-'>'=11
-'>='=12
-'?'=13
-':'=14
-'-'=19
-'+'=20
-'/'=21
-'*'=22
-'{'=23
-'}'=24
-'['=25
-']'=26
-'('=27
-')'=28
-'in'=29
-'not in'=30
+DOUBLE_QUOTE=1
+SINGLE_QUOTE=2
+COMMA=3
+PERIOD=4
+EOL=5
+AND=6
+OR=7
+NOT=8
+TRUE=9
+FALSE=10
+EQ=11
+NEQ=12
+LT=13
+LTE=14
+GT=15
+GTE=16
+QUESTION=17
+COLON=18
+IF=19
+THEN=20
+ELSE=21
+NULL=22
+MINUS=23
+PLUS=24
+DIV=25
+MUL=26
+LBRACE=27
+RBRACE=28
+LBRACKET=29
+RBRACKET=30
+LPAREN=31
+RPAREN=32
+IN=33
+NIN=34
+EXISTS=35
+EXPONENT=36
+INT_LITERAL=37
+DOUBLE_LITERAL=38
+FLOAT_LITERAL=39
+LONG_LITERAL=40
+IDENTIFIER=41
+STRING_LITERAL=42
+COMMENT=43
+WS=44
+'"'=1
+'\''=2
+','=3
+'.'=4
+'\n'=5
+'=='=11
+'!='=12
+'<'=13
+'<='=14
+'>'=15
+'>='=16
+'?'=17
+':'=18
+'-'=23
+'+'=24
+'/'=25
+'*'=26
+'{'=27
+'}'=28
+'['=29
+']'=30
+'('=31
+')'=32

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/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 742b0c3..f8052f5 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
@@ -26,9 +26,14 @@ import java.util.HashSet;
 import java.util.Set;
 import java.util.Stack;
 
-import org.apache.metron.common.dsl.*;
+import org.apache.metron.common.dsl.Context;
+import org.apache.metron.common.dsl.ErrorListener;
+import org.apache.metron.common.dsl.ParseException;
+import org.apache.metron.common.dsl.StellarFunctions;
+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.ComparisonExpressionWithOperatorEvaluator;
 import org.apache.metron.common.stellar.evaluators.NumberLiteralEvaluator;
 import org.apache.metron.common.stellar.generated.StellarBaseListener;
 import org.apache.metron.common.stellar.generated.StellarLexer;
@@ -36,13 +41,33 @@ import org.apache.metron.common.stellar.generated.StellarParser;
 
 import static org.apache.commons.lang3.StringUtils.isEmpty;
 
+/**
+ * The base implementation of a Stellar processor. This is used to evaluate Stellar expressions.
+ *
+ * @param <T> The type that the processor expects to return after processing a Stellar expression.
+ * @see StellarProcessor
+ * @see StellarPredicateProcessor
+ */
 public class BaseStellarProcessor<T> {
-  Class<T> clazz;
-  public BaseStellarProcessor(Class<T> clazz) {
+  /**
+   * The class containing the type that the Stellar expression being processed will evaluate to.
+   */
+  private Class<T> clazz;
+
+  /**
+   * @param clazz The class containing the type that the Stellar expression being processed will evaluate to.
+   */
+  BaseStellarProcessor(final Class<T> clazz) {
     this.clazz = clazz;
   }
 
-  public Set<String> variablesUsed(String rule) {
+  /**
+   * Parses the given rule and returns a set of variables that are used in the given Stellar expression, {@code rule}.
+   *
+   * @param rule The Stellar expression to find out what variables are used.
+   * @return A set of variables used in the given Stellar expression.
+   */
+  public Set<String> variablesUsed(final String rule) {
     if (rule == null || isEmpty(rule.trim())) {
       return null;
     }
@@ -55,11 +80,11 @@ public class BaseStellarProcessor<T> {
     final Set<String> ret = new HashSet<>();
     parser.addParseListener(new StellarBaseListener() {
       @Override
-      public void exitVariable(StellarParser.VariableContext ctx) {
+      public void exitVariable(final StellarParser.VariableContext ctx) {
         ret.add(ctx.getText());
       }
       @Override
-      public void exitExistsFunc(StellarParser.ExistsFuncContext ctx) {
+      public void exitExistsFunc(final StellarParser.ExistsFuncContext ctx) {
         String variable = ctx.getChild(2).getText();
         ret.add(variable);
       }
@@ -70,15 +95,19 @@ public class BaseStellarProcessor<T> {
     return ret;
   }
 
-  public T parse( String rule
-                , VariableResolver variableResolver
-                , FunctionResolver functionResolver
-                , Context context
-                )
-  {
+  /**
+   * Parses and evaluates the given Stellar expression, {@code rule}.
+   * @param rule The Stellar expression to parse and evaluate.
+   * @param variableResolver The {@link VariableResolver} to determine values of variables used in the Stellar expression, {@code rule}.
+   * @param functionResolver The {@link FunctionResolver} to determine values of functions used in the Stellar expression, {@code rule}.
+   * @param context The context used during validation.
+   * @return The value of the evaluated Stellar expression, {@code rule}.
+   */
+  public T parse(final String rule, final VariableResolver variableResolver, final FunctionResolver functionResolver, final Context context) {
     if (rule == null || isEmpty(rule.trim())) {
       return null;
     }
+
     ANTLRInputStream input = new ANTLRInputStream(rule);
     StellarLexer lexer = new StellarLexer(input);
     lexer.removeErrorListeners();
@@ -88,7 +117,8 @@ public class BaseStellarProcessor<T> {
 
     StellarCompiler treeBuilder = new StellarCompiler(variableResolver, functionResolver, context, new Stack<>(),
         ArithmeticEvaluator.INSTANCE,
-        NumberLiteralEvaluator.INSTANCE
+        NumberLiteralEvaluator.INSTANCE,
+        ComparisonExpressionWithOperatorEvaluator.INSTANCE
     );
     parser.addParseListener(treeBuilder);
     parser.removeErrorListeners();
@@ -97,26 +127,61 @@ public class BaseStellarProcessor<T> {
     return clazz.cast(treeBuilder.getResult());
   }
 
-  public boolean validate(String rule) throws ParseException {
+  /**
+   * This method determines if a given rule is valid or not. If the given rule is valid then true
+   * will be returned otherwise a {@link ParseException} is thrown. If it is desired that to return a boolean
+   * whether the rule is valid or not see {@link this#validate(String, boolean, Context)}. It is important
+   * to note that all variables will resolve to 'null.'
+   *
+   * @param rule The rule to validate.
+   * @return If the given rule is valid then true otherwise an exception is thrown.
+   * @throws ParseException If the rule is invalid an exception of this type is thrown.
+   */
+  public boolean validate(final String rule) throws ParseException {
     return validate(rule, true, Context.EMPTY_CONTEXT());
   }
 
-  public boolean validate(String rule, Context context) throws ParseException {
+  /**
+   * Validates a given Stellar expression based on given context.
+   * @param rule The Stellar expression to validate.
+   * @param context The context used to validate the Stellar expression.
+   * @return If valid Stellar expression true, otherwise an exception will be thrown.
+   * @throws ParseException The exception containing the information as to why the expression is not valid.
+   */
+  public boolean validate(final String rule, final Context context) throws ParseException {
     return validate(rule, true, context);
   }
 
-  public boolean validate(String rule, boolean throwException, Context context) throws ParseException {
-    try {
-      parse(rule, x -> null, StellarFunctions.FUNCTION_RESOLVER(), context);
+  /**
+   * Here it is not desirable to add our custom listener. It is not the intent to evaluate the rule.
+   * The rule is only meant to be validated. Validate in this instance means check whether or not the
+   * rule is syntactically valid and whether the functions used exist. For example, it will not check
+   * for variables that are not defined. Currently all variables resolve to 'null.' This is mainly to
+   * make sure things function as expected when values are null.
+   *
+   * @param rule The Stellar transformation to validate.
+   * @param throwException If true an invalid Stellar transformation will throw a {@link ParseException} otherwise a boolean will be returned.
+   * @param context The Stellar context to be used when validating the Stellar transformation.
+   * @return If {@code throwException} is true and {@code rule} is invalid a {@link ParseException} is thrown. If
+   *  {@code throwException} is false and {@code rule} is invalid then false is returned. Otherwise true if {@code rule} is valid,
+   *  false if {@code rule} is invalid.
+   * @throws ParseException Thrown if {@code rule} is invalid and {@code throwException} is true.
+   */
+  public boolean validate(final String rule, final boolean throwException, final Context context) throws ParseException {
+    if (rule == null || isEmpty(rule.trim())) {
       return true;
     }
-    catch(Throwable t) {
-      if(throwException) {
+
+    try {
+      parse(rule, x -> null, StellarFunctions.FUNCTION_RESOLVER(), context);
+    } catch (Throwable t) {
+      if (throwException) {
         throw new ParseException("Unable to parse " + rule + ": " + t.getMessage(), t);
-      }
-      else {
+      } else {
         return false;
       }
     }
+
+    return true;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/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 58ac6d6..e6bcf38 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
@@ -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.ComparisonExpressionWithOperatorEvaluator;
 import org.apache.metron.common.stellar.evaluators.NumberLiteralEvaluator;
 import org.apache.metron.common.stellar.generated.StellarBaseListener;
 import org.apache.metron.common.stellar.generated.StellarParser;
@@ -54,19 +55,22 @@ public class StellarCompiler extends StellarBaseListener {
   private Throwable actualException;
   private final ArithmeticEvaluator arithmeticEvaluator;
   private final NumberLiteralEvaluator numberLiteralEvaluator;
+  private final ComparisonExpressionWithOperatorEvaluator comparisonExpressionWithOperatorEvaluator;
 
   public StellarCompiler(VariableResolver variableResolver,
                          FunctionResolver functionResolver,
                          Context context,
                          Stack<Token<?>> tokenStack,
                          ArithmeticEvaluator arithmeticEvaluator,
-                         NumberLiteralEvaluator numberLiteralEvaluator) {
+                         NumberLiteralEvaluator numberLiteralEvaluator,
+                         ComparisonExpressionWithOperatorEvaluator comparisonExpressionWithOperatorEvaluator) {
     this.variableResolver = variableResolver;
     this.functionResolver = functionResolver;
     this.context = context;
     this.tokenStack = tokenStack;
     this.arithmeticEvaluator = arithmeticEvaluator;
     this.numberLiteralEvaluator = numberLiteralEvaluator;
+    this. comparisonExpressionWithOperatorEvaluator = comparisonExpressionWithOperatorEvaluator;
   }
 
   @Override
@@ -370,54 +374,13 @@ public class StellarCompiler extends StellarBaseListener {
     tokenStack.push(new Token<>(args, List.class));
   }
 
-  private <T extends Comparable<T>> boolean compare(T l, T r, String op) {
-    if (op.equals("==")) {
-      return l.compareTo(r) == 0;
-    } else if (op.equals("!=")) {
-      return l.compareTo(r) != 0;
-    } else if (op.equals("<")) {
-      return l.compareTo(r) < 0;
-    } else if (op.equals(">")) {
-      return l.compareTo(r) > 0;
-    } else if (op.equals(">=")) {
-      return l.compareTo(r) >= 0;
-    } else {
-      return l.compareTo(r) <= 0;
-    }
-  }
-
-  private boolean compareDouble(Double l, Double r, String op) {
-    if (op.equals("==")) {
-      return Math.abs(l - r) < 1e-6;
-    } else if (op.equals("!=")) {
-      return Math.abs(l - r) >= 1e-6;
-    } else if (op.equals("<")) {
-      return l.compareTo(r) < 0;
-    } else if (op.equals(">")) {
-      return l.compareTo(r) > 0;
-    } else if (op.equals(">=")) {
-      return l.compareTo(r) >= 0;
-    } else {
-      return l.compareTo(r) <= 0;
-    }
-  }
-
   @Override
   public void exitComparisonExpressionWithOperator(StellarParser.ComparisonExpressionWithOperatorContext ctx) {
-    String op = ctx.getChild(1).getText();
+    StellarParser.Comp_operatorContext op = ctx.comp_operator();
     Token<?> right = popStack();
     Token<?> left = popStack();
-    if (left.getValue() instanceof Number
-            && right.getValue() instanceof Number) {
-      Double l = ((Number) left.getValue()).doubleValue();
-      Double r = ((Number) right.getValue()).doubleValue();
-      tokenStack.push(new Token<>(compareDouble(l, r, op), Boolean.class));
 
-    } else {
-      String l = left.getValue() == null ? "" : left.getValue().toString();
-      String r = right.getValue() == null ? "" : right.getValue().toString();
-      tokenStack.push(new Token<>(compare(l, r, op), Boolean.class));
-    }
+    tokenStack.push(comparisonExpressionWithOperatorEvaluator.evaluate(left, right, (StellarParser.ComparisonOpContext) op));
   }
 
   @Override
@@ -425,7 +388,7 @@ public class StellarCompiler extends StellarBaseListener {
     tokenStack.push(new Token<>(new FunctionMarker(), FunctionMarker.class));
   }
 
-  public Token<?> popStack() {
+  private Token<?> popStack() {
     if (tokenStack.empty()) {
       throw new ParseException("Unable to pop an empty stack");
     }

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionEvaluator.java
new file mode 100644
index 0000000..7374c6b
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionEvaluator.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.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+
+/**
+ * This is used to determine what is needed to evaluate a Stellar comparison expression. A Stellar comparison
+ * expression is an expression that uses operators such as '<', '<=', '>', '>=', '==', '!=' to compare
+ * values in Stellar. There are two main types of comparisons in Stellar equality ('==', '!=') and comparison ('<', '<=', '>', '>=').
+ */
+public interface ComparisonExpressionEvaluator {
+
+  /**
+   * This will compare the values of {@code left} and {@code right} using the {@code op} input to determine a value
+   * to return.
+   * @param left  The token representing the left side of a comparison expression.
+   * @param right The token representing the right side of a comparison expression.
+   * @param op    This is a representation of a comparison operator (eg. <, <=, >, >=, ==, !=)
+   * @return True if the the if the expressions is evaluated to be true, otherwise false. An example of expressions that
+   * should be true are {@code 1 == 1}, {@code 1f > 0}, etc.
+   */
+  boolean evaluate(Token<?> left, Token<?> right, StellarParser.ComparisonOpContext op);
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java
new file mode 100644
index 0000000..4862684
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluator.java
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+/**
+ * This is the evaluator used when evaluating Stellar comparison operators.
+ *
+ * @see EqualityOperatorsEvaluator
+ * @see ComparisonOperatorsEvaluator
+ */
+public enum ComparisonExpressionWithOperatorEvaluator {
+  /**
+   * The instance of {@link ComparisonExpressionWithOperatorEvaluator} used in
+   * order to evaluate Stellar comparison expressions.
+   */
+  INSTANCE;
+
+  /**
+   * The different strategies used to evaluate a Stellar comparison operator. They are broken into
+   * two categories: equality operator comparisons and comparison operator comparisons.
+   */
+  enum Strategy {
+    /**
+     * The evaluator used to evaluate comparison operator expressions.
+     */
+    COMPARISON_OPERATORS(new ComparisonOperatorsEvaluator()),
+    /**
+     * The evaluator used to evaluate equality operator expressions.
+     */
+    EQUALITY_OPERATORS(new EqualityOperatorsEvaluator()),
+    ;
+
+    /**
+     * The evaluator to be used when evaluating Stellar expressions.
+     */
+    private ComparisonExpressionEvaluator evaluator;
+
+    Strategy(final ComparisonExpressionEvaluator evaluator) {
+      this.evaluator = evaluator;
+    }
+
+    /**
+     *
+     * @return The evaluator needed to evaluate Stellar comparison expressions.
+     */
+    public ComparisonExpressionEvaluator evaluator() {
+      return evaluator;
+    }
+  }
+
+  /**
+   * When evaluating comparison expressions with operators, they are broken into four cases:
+   *
+   * 1. Testing equality, see {@link EqualityOperatorsEvaluator}
+   * 2. Testing not equal, see {@link EqualityOperatorsEvaluator}. This will be the negation of {@link EqualityOperatorsEvaluator#evaluate(Token, Token, StellarParser.ComparisonOpContext)}.
+   * 3. Testing less than, less than or equal, greater than, and greater than or equal {@link ComparisonOperatorsEvaluator}
+   * 4. Otherwise thrown {@link ParseException}.
+   *
+   * @param left The value of the left side of the Stellar expression.
+   * @param right The value of the right side of the Stellar expression.
+   * @param op The operator in the Stellar expression.
+   * @return A token with type boolean. This is based on the comparison of the {@code right} and {@code left} values.
+   */
+  public Token<Boolean> evaluate(final Token<?> left, final Token<?> right, final StellarParser.ComparisonOpContext op) {
+    if (op.EQ() != null) {
+      return new Token<>(Strategy.EQUALITY_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class);
+    } else if (op.NEQ() != null) {
+      return new Token<>(!Strategy.EQUALITY_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class);
+    } else if (op.LT() != null || op.GT() != null || op.LTE() != null || op.GTE() != null) {
+      return new Token<>(Strategy.COMPARISON_OPERATORS.evaluator().evaluate(left, right, op), Boolean.class);
+    }
+
+    throw new ParseException("Unsupported operations. The following expression is invalid: " + left.getValue() + op.getText() + right.getValue());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonOperatorsEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonOperatorsEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonOperatorsEvaluator.java
new file mode 100644
index 0000000..11f9950
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/ComparisonOperatorsEvaluator.java
@@ -0,0 +1,185 @@
+/*
+ * 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;
+
+/**
+ * {@link ComparisonOperatorsEvaluator} is used to evaluate comparison expressions using the following operator '<', '<=', '>',
+ * or '>='. There are four major cases when evaluating a comparison expression.
+ */
+public class ComparisonOperatorsEvaluator implements ComparisonExpressionEvaluator {
+
+  /**
+   * 1. If either the left or right's value is null then return false.
+   * 2. If both sides of the expression are instances of {@link Number} then:
+   *    1. If either side is a {@link Double} then get {@link Number#doubleValue()} from both sides and compare using given operator.
+   *    2. Else if either side is a {@link Float} then get {@link Number#floatValue()} from both sides and compare using given operator.
+   *    3. Else if either side is a {@link Long} then get {@link Number#longValue()} from both sides and compare using given operator.
+   *    4. Otherwise get {@link Number#intValue()} from both sides and compare using given operator.
+   * 3. If both sides are of the same type and implement the {@link Comparable} interface then use {@code compareTo} method.
+   * 4. If none of the above are met then a {@link ParseException} is thrown.
+   *
+   * @param left  The token representing the left side of a comparison expression.
+   * @param right The token representing the right side of a comparison expression.
+   * @param op    This is a representation of a comparison operator (eg. <, <=, >, >=, ==, !=)
+   * @return A boolean value based on the comparison of {@code left} and {@code right}.
+   */
+  @Override
+  public boolean evaluate(final Token<?> left, final Token<?> right, final StellarParser.ComparisonOpContext op) {
+    if (left.getValue() == null || right.getValue() == null) {
+      return false;
+    } else if (left.getValue() instanceof Number && right.getValue() instanceof Number) {
+      return compareNumbers((Number) left.getValue(), (Number) right.getValue(), op);
+    } else if (left.getValue().getClass() == right.getValue().getClass()
+        && left.getValue() instanceof Comparable && right.getValue() instanceof Comparable) {
+      return compare((Comparable<?>) left.getValue(), (Comparable<?>) right.getValue(), op);
+    }
+
+    throw new ParseException("Unsupported operations. The following expression is invalid: " + left.getValue() + op + right.getValue());
+  }
+
+  /**
+   * This method uses the inputs' ability to compare with one another's values by using the {@code compareTo} method. It will use this and
+   * the operator to evaluate the output.
+   *
+   * @param l The value of the left side of the expression.
+   * @param r The value of the right side of the expression.
+   * @param op The operator to use when comparing.
+   * @param <T> The type of values being compared.
+   * @return A boolean value representing the comparison of the two values with the given operator. For example, {@code 1 <= 1} would be true.
+   */
+  @SuppressWarnings("unchecked")
+  private <T extends Comparable> boolean compare(final T l, final T r, final StellarParser.ComparisonOpContext op) {
+    int compareTo = l.compareTo(r);
+
+    if (op.LT() != null) {
+      return compareTo < 0;
+    } else if (op.LTE() != null) {
+      return compareTo <= 0;
+    } else if (op.GT() != null) {
+      return compareTo > 0;
+    } else if (op.GTE() != null) {
+      return compareTo >= 0;
+    }
+
+    throw new ParseException("Unsupported operator: " + op);
+  }
+
+  /**
+   * This method uses the inputs' ability to compare with one another's values by using the {@code compareTo} method. It will use this and
+   * the operator to evaluate the output.
+   *
+   * @param l The left side of the expression.
+   * @param r The right side of the expression
+   * @param op The operator used in the expression.
+   * @return A boolean value representing the comparison of the two values with the given operator. For example, {@code 1 <= 1} would be true.
+   */
+  private boolean compareNumbers(final Number l, final Number r, final StellarParser.ComparisonOpContext op) {
+    if (op.LT() != null) {
+      return lessThan(l, r);
+    } else if (op.LTE() != null) {
+      return lessThanEqual(l, r);
+    } else if (op.GT() != null) {
+      return greaterThan(l, r);
+    } else if (op.GTE() != null) {
+      return greaterThanEqual(l, r);
+    }
+
+    throw new ParseException("Unsupported operator: " + op);
+  }
+
+  /**
+   * If the left side of the expression is less than the right then true otherwise false.
+   *
+   * @param l The value of the left side of the expression.
+   * @param r The value of the right side of the expression.
+   * @return If the left side of the expression is less than the right then true otherwise false.
+   */
+  private boolean lessThan(final Number l, final Number r) {
+    if (l instanceof Double || r instanceof Double) {
+      return l.doubleValue() < r.doubleValue();
+    } else if (l instanceof Float || r instanceof Float) {
+      return l.floatValue() < r.floatValue();
+    } else if (l instanceof Long || r instanceof Long) {
+      return l.longValue() < r.longValue();
+    } else {
+      return l.intValue() < r.intValue();
+    }
+  }
+
+  /**
+   * If the left side of the expression is less than or equal to the right then true otherwise false.
+   *
+   * @param l The value of the left side of the expression.
+   * @param r The value of the right side of the expression.
+   * @return If the left side of the expression is less than or equal to the right then true otherwise false.
+   */
+  private boolean lessThanEqual(final Number l, final Number r) {
+    if (l instanceof Double || r instanceof Double) {
+      return l.doubleValue() <= r.doubleValue();
+    } else if (l instanceof Float || r instanceof Float) {
+      return l.floatValue() <= r.floatValue();
+    } else if (l instanceof Long || r instanceof Long) {
+      return l.longValue() <= r.longValue();
+    } else {
+      return l.intValue() <= r.intValue();
+    }
+  }
+
+  /**
+   * If the left side of the expression is greater than the right then true otherwise false.
+   *
+   * @param l The value of the left side of the expression.
+   * @param r The value of the right side of the expression.
+   * @return If the left side of the expression is greater than the right then true otherwise false.
+   */
+  private boolean greaterThan(final Number l, final Number r) {
+    if (l instanceof Double || r instanceof Double) {
+      return l.doubleValue() > r.doubleValue();
+    } else if (l instanceof Float || r instanceof Float) {
+      return l.floatValue() > r.floatValue();
+    } else if (l instanceof Long || r instanceof Long) {
+      return l.longValue() > r.longValue();
+    } else {
+      return l.intValue() > r.intValue();
+    }
+  }
+
+  /**
+   * If the left side of the expression is greater than or equal to the right then true otherwise false.
+   *
+   * @param l The value of the left side of the expression.
+   * @param r The value of the right side of the expression.
+   * @return If the left side of the expression is greater than or equal to the right then true otherwise false.
+   */
+  private boolean greaterThanEqual(final Number l, final Number r) {
+    if (l instanceof Double || r instanceof Double) {
+      return l.doubleValue() >= r.doubleValue();
+    } else if (l instanceof Float || r instanceof Float) {
+      return l.floatValue() >= r.floatValue();
+    } else if (l instanceof Long || r instanceof Long) {
+      return l.longValue() >= r.longValue();
+    } else {
+      return l.intValue() >= r.intValue();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/EqualityOperatorsEvaluator.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/EqualityOperatorsEvaluator.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/EqualityOperatorsEvaluator.java
new file mode 100644
index 0000000..0f0d749
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/evaluators/EqualityOperatorsEvaluator.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.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+
+/**
+ * {@link EqualityOperatorsEvaluator} is used to evaluate equality expressions using the following operator '=='. There are
+ * four major cases when evaluating a equality expression. See {@link EqualityOperatorsEvaluator#evaluate(Token, Token, StellarParser.ComparisonOpContext)}
+ * for a description.
+ */
+public class EqualityOperatorsEvaluator implements ComparisonExpressionEvaluator {
+
+  /**
+   * 1. If either side of the expression is null then check equality using Java's '==' expression.
+   * 2. Else if both sides of the expression are of type {@link Number} then:
+   *    1. If either side of the expression is a {@link Double} then use {@link Number#doubleValue()} to test equality.
+   *    2. Else if either side of the expression is a {@link Float} then use {@link Number#floatValue()} to test equality.
+   *    3. Else if either side of the expression is a {@link Long} then use {@link Number#longValue()} to test equality.
+   *    4. Otherwise use {@link Number#intValue()} to test equality
+   * 3. Otherwise use {@code equals} method compare the left side with the right side.
+   * @param left  The token representing the left side of a comparison expression.
+   * @param right The token representing the right side of a comparison expression.
+   * @param op    This is a representation of a comparison operator (eg. <, <=, >, >=, ==, !=)
+   * @return A boolean value based on the comparison of {@code left} and {@code right}.
+   */
+  @Override
+  public boolean evaluate(final Token<?> left, final Token<?> right, final StellarParser.ComparisonOpContext op) {
+    if (left.getValue() == null || right.getValue() == null) {
+      return left.getValue() == right.getValue();
+    } else if (left.getValue() instanceof Number && right.getValue() instanceof Number) {
+      return eq((Number) left.getValue(), (Number) right.getValue());
+    } else {
+      return left.getValue().equals(right.getValue());
+    }
+  }
+
+  /**
+   * This method follows Java's number promotions when comparing numbers.
+   *
+   * @param l The left side of the equality expression.
+   * @param r The right side of the equality expression.
+   * @return All comparisons use the '==' operator from Java. If either input is a double then compare double values.
+   * If either side is a float compare float values. If either side is a long compare long values. Otherwise compare
+   * int values.
+   */
+  private boolean eq(final Number l, final Number r) {
+    if (l instanceof Double || r instanceof Double) {
+      return l.doubleValue() == r.doubleValue();
+    } else if (l instanceof Float || r instanceof Float) {
+      return l.floatValue() == r.floatValue();
+    } else if (l instanceof Long || r instanceof Long) {
+      return l.longValue() == r.longValue();
+    } else {
+      return l.intValue() == r.intValue();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/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 3fe97e2..62e1683 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
@@ -37,37 +37,40 @@ public class StellarLexer extends Lexer {
 	protected static final PredictionContextCache _sharedContextCache =
 		new PredictionContextCache();
 	public static final int
-		COMMA=1, AND=2, OR=3, NOT=4, TRUE=5, FALSE=6, EQ=7, NEQ=8, LT=9, LTE=10, 
-		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, FLOAT_LITERAL=35, LONG_LITERAL=36, 
-		IDENTIFIER=37, STRING_LITERAL=38, COMMENT=39, WS=40;
+		DOUBLE_QUOTE=1, SINGLE_QUOTE=2, COMMA=3, PERIOD=4, EOL=5, AND=6, OR=7, 
+		NOT=8, TRUE=9, FALSE=10, EQ=11, NEQ=12, LT=13, LTE=14, GT=15, GTE=16, 
+		QUESTION=17, COLON=18, IF=19, THEN=20, ELSE=21, NULL=22, MINUS=23, PLUS=24, 
+		DIV=25, MUL=26, LBRACE=27, RBRACE=28, LBRACKET=29, RBRACKET=30, LPAREN=31, 
+		RPAREN=32, IN=33, NIN=34, EXISTS=35, EXPONENT=36, INT_LITERAL=37, DOUBLE_LITERAL=38, 
+		FLOAT_LITERAL=39, LONG_LITERAL=40, IDENTIFIER=41, STRING_LITERAL=42, COMMENT=43, 
+		WS=44;
 	public static String[] modeNames = {
 		"DEFAULT_MODE"
 	};
 
 	public static final String[] ruleNames = {
-		"COMMA", "AND", "OR", "NOT", "TRUE", "FALSE", "EQ", "NEQ", "LT", "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", 
-		"FLOAT_LITERAL", "LONG_LITERAL", "IDENTIFIER", "SCHAR", "STRING_LITERAL", 
-		"COMMENT", "WS"
+		"DOUBLE_QUOTE", "SINGLE_QUOTE", "COMMA", "PERIOD", "EOL", "AND", "OR", 
+		"NOT", "TRUE", "FALSE", "EQ", "NEQ", "LT", "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", "FLOAT_LITERAL", 
+		"LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS", "ZERO", 
+		"FIRST_DIGIT", "DIGIT", "SCHAR", "D", "E", "F", "L"
 	};
 
 	private static final String[] _LITERAL_NAMES = {
-		null, "','", null, null, null, null, null, "'=='", "'!='", "'<'", "'<='", 
-		"'>'", "'>='", "'?'", "':'", null, null, null, null, "'-'", "'+'", "'/'", 
-		"'*'", "'{'", "'}'", "'['", "']'", "'('", "')'", "'in'", "'not in'"
+		null, "'\"'", "'''", "','", "'.'", "'\n'", null, null, null, null, null, 
+		"'=='", "'!='", "'<'", "'<='", "'>'", "'>='", "'?'", "':'", null, null, 
+		null, null, "'-'", "'+'", "'/'", "'*'", "'{'", "'}'", "'['", "']'", "'('", 
+		"')'"
 	};
 	private static final String[] _SYMBOLIC_NAMES = {
-		null, "COMMA", "AND", "OR", "NOT", "TRUE", "FALSE", "EQ", "NEQ", "LT", 
-		"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", "FLOAT_LITERAL", "LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", 
-		"COMMENT", "WS"
+		null, "DOUBLE_QUOTE", "SINGLE_QUOTE", "COMMA", "PERIOD", "EOL", "AND", 
+		"OR", "NOT", "TRUE", "FALSE", "EQ", "NEQ", "LT", "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", "FLOAT_LITERAL", 
+		"LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS"
 	};
 	public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
 
@@ -124,142 +127,163 @@ 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*\u0180\b\1\4\2\t"+
+		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2.\u01ba\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(\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";
+		"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
+		",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
+		"\64\4\65\t\65\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\7\3\7"+
+		"\3\7\3\7\3\7\3\7\5\7~\n\7\3\b\3\b\3\b\3\b\3\b\3\b\5\b\u0086\n\b\3\t\3"+
+		"\t\3\t\3\t\3\t\3\t\5\t\u008e\n\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\5\n\u0098"+
+		"\n\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\5\13\u00a4\n\13"+
+		"\3\f\3\f\3\f\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\17\3\20\3\20\3\21\3\21"+
+		"\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\24\3\24\5\24\u00be\n\24\3\25\3\25"+
+		"\3\25\3\25\3\25\3\25\3\25\3\25\5\25\u00c8\n\25\3\26\3\26\3\26\3\26\3\26"+
+		"\3\26\3\26\3\26\5\26\u00d2\n\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+
+		"\5\27\u00dc\n\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\37\3\37\3 \3 \3!\3!\3\"\3\"\3\"\3\"\5\"\u00f6\n\"\3"+
+		"#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\5#\u0104\n#\3$\3$\3$\3$\3$\3$\3$\3"+
+		"$\3$\3$\3$\3$\5$\u0112\n$\3%\3%\3%\5%\u0117\n%\3%\6%\u011a\n%\r%\16%\u011b"+
+		"\3&\5&\u011f\n&\3&\3&\5&\u0123\n&\3&\3&\7&\u0127\n&\f&\16&\u012a\13&\5"+
+		"&\u012c\n&\3\'\3\'\3\'\7\'\u0131\n\'\f\'\16\'\u0134\13\'\3\'\5\'\u0137"+
+		"\n\'\3\'\5\'\u013a\n\'\3\'\3\'\6\'\u013e\n\'\r\'\16\'\u013f\3\'\5\'\u0143"+
+		"\n\'\3\'\5\'\u0146\n\'\3\'\3\'\3\'\5\'\u014b\n\'\3\'\3\'\5\'\u014f\n\'"+
+		"\3\'\3\'\5\'\u0153\n\'\3(\3(\3(\7(\u0158\n(\f(\16(\u015b\13(\3(\5(\u015e"+
+		"\n(\3(\3(\3(\5(\u0163\n(\3(\3(\6(\u0167\n(\r(\16(\u0168\3(\5(\u016c\n"+
+		"(\3(\3(\3(\3(\5(\u0172\n(\3(\3(\5(\u0176\n(\3)\3)\3)\3*\3*\7*\u017d\n"+
+		"*\f*\16*\u0180\13*\3+\3+\7+\u0184\n+\f+\16+\u0187\13+\3+\3+\3+\3+\7+\u018d"+
+		"\n+\f+\16+\u0190\13+\3+\3+\5+\u0194\n+\3,\3,\3,\3,\6,\u019a\n,\r,\16,"+
+		"\u019b\3,\3,\5,\u01a0\n,\3,\3,\3-\6-\u01a5\n-\r-\16-\u01a6\3-\3-\3.\3"+
+		".\3/\3/\3\60\3\60\3\61\3\61\3\62\3\62\3\63\3\63\3\64\3\64\3\65\3\65\3"+
+		"\u019b\2\66\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(O)Q*S+U,W-Y.[\2]\2_\2a\2c\2e\2g\2i\2\3"+
+		"\2\n\5\2C\\aac|\b\2\60\60\62<C\\^^aac|\5\2\13\f\16\17\"\"\7\2\f\f\17\17"+
+		"$$))^^\4\2FFff\4\2GGgg\4\2HHhh\4\2NNnn\u01e0\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\2"+
+		"M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3"+
+		"\2\2\2\3k\3\2\2\2\5m\3\2\2\2\7o\3\2\2\2\tq\3\2\2\2\13s\3\2\2\2\r}\3\2"+
+		"\2\2\17\u0085\3\2\2\2\21\u008d\3\2\2\2\23\u0097\3\2\2\2\25\u00a3\3\2\2"+
+		"\2\27\u00a5\3\2\2\2\31\u00a8\3\2\2\2\33\u00ab\3\2\2\2\35\u00ad\3\2\2\2"+
+		"\37\u00b0\3\2\2\2!\u00b2\3\2\2\2#\u00b5\3\2\2\2%\u00b7\3\2\2\2\'\u00bd"+
+		"\3\2\2\2)\u00c7\3\2\2\2+\u00d1\3\2\2\2-\u00db\3\2\2\2/\u00dd\3\2\2\2\61"+
+		"\u00df\3\2\2\2\63\u00e1\3\2\2\2\65\u00e3\3\2\2\2\67\u00e5\3\2\2\29\u00e7"+
+		"\3\2\2\2;\u00e9\3\2\2\2=\u00eb\3\2\2\2?\u00ed\3\2\2\2A\u00ef\3\2\2\2C"+
+		"\u00f5\3\2\2\2E\u0103\3\2\2\2G\u0111\3\2\2\2I\u0113\3\2\2\2K\u012b\3\2"+
+		"\2\2M\u0152\3\2\2\2O\u0175\3\2\2\2Q\u0177\3\2\2\2S\u017a\3\2\2\2U\u0193"+
+		"\3\2\2\2W\u0195\3\2\2\2Y\u01a4\3\2\2\2[\u01aa\3\2\2\2]\u01ac\3\2\2\2_"+
+		"\u01ae\3\2\2\2a\u01b0\3\2\2\2c\u01b2\3\2\2\2e\u01b4\3\2\2\2g\u01b6\3\2"+
+		"\2\2i\u01b8\3\2\2\2kl\7$\2\2l\4\3\2\2\2mn\7)\2\2n\6\3\2\2\2op\7.\2\2p"+
+		"\b\3\2\2\2qr\7\60\2\2r\n\3\2\2\2st\7\f\2\2t\f\3\2\2\2uv\7c\2\2vw\7p\2"+
+		"\2w~\7f\2\2xy\7(\2\2y~\7(\2\2z{\7C\2\2{|\7P\2\2|~\7F\2\2}u\3\2\2\2}x\3"+
+		"\2\2\2}z\3\2\2\2~\16\3\2\2\2\177\u0080\7q\2\2\u0080\u0086\7t\2\2\u0081"+
+		"\u0082\7~\2\2\u0082\u0086\7~\2\2\u0083\u0084\7Q\2\2\u0084\u0086\7T\2\2"+
+		"\u0085\177\3\2\2\2\u0085\u0081\3\2\2\2\u0085\u0083\3\2\2\2\u0086\20\3"+
+		"\2\2\2\u0087\u0088\7p\2\2\u0088\u0089\7q\2\2\u0089\u008e\7v\2\2\u008a"+
+		"\u008b\7P\2\2\u008b\u008c\7Q\2\2\u008c\u008e\7V\2\2\u008d\u0087\3\2\2"+
+		"\2\u008d\u008a\3\2\2\2\u008e\22\3\2\2\2\u008f\u0090\7v\2\2\u0090\u0091"+
+		"\7t\2\2\u0091\u0092\7w\2\2\u0092\u0098\7g\2\2\u0093\u0094\7V\2\2\u0094"+
+		"\u0095\7T\2\2\u0095\u0096\7W\2\2\u0096\u0098\7G\2\2\u0097\u008f\3\2\2"+
+		"\2\u0097\u0093\3\2\2\2\u0098\24\3\2\2\2\u0099\u009a\7h\2\2\u009a\u009b"+
+		"\7c\2\2\u009b\u009c\7n\2\2\u009c\u009d\7u\2\2\u009d\u00a4\7g\2\2\u009e"+
+		"\u009f\7H\2\2\u009f\u00a0\7C\2\2\u00a0\u00a1\7N\2\2\u00a1\u00a2\7U\2\2"+
+		"\u00a2\u00a4\7G\2\2\u00a3\u0099\3\2\2\2\u00a3\u009e\3\2\2\2\u00a4\26\3"+
+		"\2\2\2\u00a5\u00a6\7?\2\2\u00a6\u00a7\7?\2\2\u00a7\30\3\2\2\2\u00a8\u00a9"+
+		"\7#\2\2\u00a9\u00aa\7?\2\2\u00aa\32\3\2\2\2\u00ab\u00ac\7>\2\2\u00ac\34"+
+		"\3\2\2\2\u00ad\u00ae\7>\2\2\u00ae\u00af\7?\2\2\u00af\36\3\2\2\2\u00b0"+
+		"\u00b1\7@\2\2\u00b1 \3\2\2\2\u00b2\u00b3\7@\2\2\u00b3\u00b4\7?\2\2\u00b4"+
+		"\"\3\2\2\2\u00b5\u00b6\7A\2\2\u00b6$\3\2\2\2\u00b7\u00b8\7<\2\2\u00b8"+
+		"&\3\2\2\2\u00b9\u00ba\7K\2\2\u00ba\u00be\7H\2\2\u00bb\u00bc\7k\2\2\u00bc"+
+		"\u00be\7h\2\2\u00bd\u00b9\3\2\2\2\u00bd\u00bb\3\2\2\2\u00be(\3\2\2\2\u00bf"+
+		"\u00c0\7V\2\2\u00c0\u00c1\7J\2\2\u00c1\u00c2\7G\2\2\u00c2\u00c8\7P\2\2"+
+		"\u00c3\u00c4\7v\2\2\u00c4\u00c5\7j\2\2\u00c5\u00c6\7g\2\2\u00c6\u00c8"+
+		"\7p\2\2\u00c7\u00bf\3\2\2\2\u00c7\u00c3\3\2\2\2\u00c8*\3\2\2\2\u00c9\u00ca"+
+		"\7G\2\2\u00ca\u00cb\7N\2\2\u00cb\u00cc\7U\2\2\u00cc\u00d2\7G\2\2\u00cd"+
+		"\u00ce\7g\2\2\u00ce\u00cf\7n\2\2\u00cf\u00d0\7u\2\2\u00d0\u00d2\7g\2\2"+
+		"\u00d1\u00c9\3\2\2\2\u00d1\u00cd\3\2\2\2\u00d2,\3\2\2\2\u00d3\u00d4\7"+
+		"p\2\2\u00d4\u00d5\7w\2\2\u00d5\u00d6\7n\2\2\u00d6\u00dc\7n\2\2\u00d7\u00d8"+
+		"\7P\2\2\u00d8\u00d9\7W\2\2\u00d9\u00da\7N\2\2\u00da\u00dc\7N\2\2\u00db"+
+		"\u00d3\3\2\2\2\u00db\u00d7\3\2\2\2\u00dc.\3\2\2\2\u00dd\u00de\7/\2\2\u00de"+
+		"\60\3\2\2\2\u00df\u00e0\7-\2\2\u00e0\62\3\2\2\2\u00e1\u00e2\7\61\2\2\u00e2"+
+		"\64\3\2\2\2\u00e3\u00e4\7,\2\2\u00e4\66\3\2\2\2\u00e5\u00e6\7}\2\2\u00e6"+
+		"8\3\2\2\2\u00e7\u00e8\7\177\2\2\u00e8:\3\2\2\2\u00e9\u00ea\7]\2\2\u00ea"+
+		"<\3\2\2\2\u00eb\u00ec\7_\2\2\u00ec>\3\2\2\2\u00ed\u00ee\7*\2\2\u00ee@"+
+		"\3\2\2\2\u00ef\u00f0\7+\2\2\u00f0B\3\2\2\2\u00f1\u00f2\7k\2\2\u00f2\u00f6"+
+		"\7p\2\2\u00f3\u00f4\7K\2\2\u00f4\u00f6\7P\2\2\u00f5\u00f1\3\2\2\2\u00f5"+
+		"\u00f3\3\2\2\2\u00f6D\3\2\2\2\u00f7\u00f8\7p\2\2\u00f8\u00f9\7q\2\2\u00f9"+
+		"\u00fa\7v\2\2\u00fa\u00fb\7\"\2\2\u00fb\u00fc\7k\2\2\u00fc\u0104\7p\2"+
+		"\2\u00fd\u00fe\7P\2\2\u00fe\u00ff\7Q\2\2\u00ff\u0100\7V\2\2\u0100\u0101"+
+		"\7\"\2\2\u0101\u0102\7K\2\2\u0102\u0104\7P\2\2\u0103\u00f7\3\2\2\2\u0103"+
+		"\u00fd\3\2\2\2\u0104F\3\2\2\2\u0105\u0106\7g\2\2\u0106\u0107\7z\2\2\u0107"+
+		"\u0108\7k\2\2\u0108\u0109\7u\2\2\u0109\u010a\7v\2\2\u010a\u0112\7u\2\2"+
+		"\u010b\u010c\7G\2\2\u010c\u010d\7Z\2\2\u010d\u010e\7K\2\2\u010e\u010f"+
+		"\7U\2\2\u010f\u0110\7V\2\2\u0110\u0112\7U\2\2\u0111\u0105\3\2\2\2\u0111"+
+		"\u010b\3\2\2\2\u0112H\3\2\2\2\u0113\u0116\5e\63\2\u0114\u0117\5\61\31"+
+		"\2\u0115\u0117\5/\30\2\u0116\u0114\3\2\2\2\u0116\u0115\3\2\2\2\u0116\u0117"+
+		"\3\2\2\2\u0117\u0119\3\2\2\2\u0118\u011a\5_\60\2\u0119\u0118\3\2\2\2\u011a"+
+		"\u011b\3\2\2\2\u011b\u0119\3\2\2\2\u011b\u011c\3\2\2\2\u011cJ\3\2\2\2"+
+		"\u011d\u011f\5/\30\2\u011e\u011d\3\2\2\2\u011e\u011f\3\2\2\2\u011f\u0120"+
+		"\3\2\2\2\u0120\u012c\5[.\2\u0121\u0123\5/\30\2\u0122\u0121\3\2\2\2\u0122"+
+		"\u0123\3\2\2\2\u0123\u0124\3\2\2\2\u0124\u0128\5]/\2\u0125\u0127\5_\60"+
+		"\2\u0126\u0125\3\2\2\2\u0127\u012a\3\2\2\2\u0128\u0126\3\2\2\2\u0128\u0129"+
+		"\3\2\2\2\u0129\u012c\3\2\2\2\u012a\u0128\3\2\2\2\u012b\u011e\3\2\2\2\u012b"+
+		"\u0122\3\2\2\2\u012cL\3\2\2\2\u012d\u012e\5K&\2\u012e\u0132\5\t\5\2\u012f"+
+		"\u0131\5_\60\2\u0130\u012f\3\2\2\2\u0131\u0134\3\2\2\2\u0132\u0130\3\2"+
+		"\2\2\u0132\u0133\3\2\2\2\u0133\u0136\3\2\2\2\u0134\u0132\3\2\2\2\u0135"+
+		"\u0137\5I%\2\u0136\u0135\3\2\2\2\u0136\u0137\3\2\2\2\u0137\u0139\3\2\2"+
+		"\2\u0138\u013a\5c\62\2\u0139\u0138\3\2\2\2\u0139\u013a\3\2\2\2\u013a\u0153"+
+		"\3\2\2\2\u013b\u013d\5\t\5\2\u013c\u013e\5_\60\2\u013d\u013c\3\2\2\2\u013e"+
+		"\u013f\3\2\2\2\u013f\u013d\3\2\2\2\u013f\u0140\3\2\2\2\u0140\u0142\3\2"+
+		"\2\2\u0141\u0143\5I%\2\u0142\u0141\3\2\2\2\u0142\u0143\3\2\2\2\u0143\u0145"+
+		"\3\2\2\2\u0144\u0146\5c\62\2\u0145\u0144\3\2\2\2\u0145\u0146\3\2\2\2\u0146"+
+		"\u0153\3\2\2\2\u0147\u0148\5K&\2\u0148\u014a\5I%\2\u0149\u014b\5c\62\2"+
+		"\u014a\u0149\3\2\2\2\u014a\u014b\3\2\2\2\u014b\u0153\3\2\2\2\u014c\u014e"+
+		"\5K&\2\u014d\u014f\5I%\2\u014e\u014d\3\2\2\2\u014e\u014f\3\2\2\2\u014f"+
+		"\u0150\3\2\2\2\u0150\u0151\5c\62\2\u0151\u0153\3\2\2\2\u0152\u012d\3\2"+
+		"\2\2\u0152\u013b\3\2\2\2\u0152\u0147\3\2\2\2\u0152\u014c\3\2\2\2\u0153"+
+		"N\3\2\2\2\u0154\u0155\5K&\2\u0155\u0159\5\t\5\2\u0156\u0158\5_\60\2\u0157"+
+		"\u0156\3\2\2\2\u0158\u015b\3\2\2\2\u0159\u0157\3\2\2\2\u0159\u015a\3\2"+
+		"\2\2\u015a\u015d\3\2\2\2\u015b\u0159\3\2\2\2\u015c\u015e\5I%\2\u015d\u015c"+
+		"\3\2\2\2\u015d\u015e\3\2\2\2\u015e\u015f\3\2\2\2\u015f\u0160\5g\64\2\u0160"+
+		"\u0176\3\2\2\2\u0161\u0163\5/\30\2\u0162\u0161\3\2\2\2\u0162\u0163\3\2"+
+		"\2\2\u0163\u0164\3\2\2\2\u0164\u0166\5\t\5\2\u0165\u0167\5_\60\2\u0166"+
+		"\u0165\3\2\2\2\u0167\u0168\3\2\2\2\u0168\u0166\3\2\2\2\u0168\u0169\3\2"+
+		"\2\2\u0169\u016b\3\2\2\2\u016a\u016c\5I%\2\u016b\u016a\3\2\2\2\u016b\u016c"+
+		"\3\2\2\2\u016c\u016d\3\2\2\2\u016d\u016e\5g\64\2\u016e\u0176\3\2\2\2\u016f"+
+		"\u0171\5K&\2\u0170\u0172\5I%\2\u0171\u0170\3\2\2\2\u0171\u0172\3\2\2\2"+
+		"\u0172\u0173\3\2\2\2\u0173\u0174\5g\64\2\u0174\u0176\3\2\2\2\u0175\u0154"+
+		"\3\2\2\2\u0175\u0162\3\2\2\2\u0175\u016f\3\2\2\2\u0176P\3\2\2\2\u0177"+
+		"\u0178\5K&\2\u0178\u0179\5i\65\2\u0179R\3\2\2\2\u017a\u017e\t\2\2\2\u017b"+
+		"\u017d\t\3\2\2\u017c\u017b\3\2\2\2\u017d\u0180\3\2\2\2\u017e\u017c\3\2"+
+		"\2\2\u017e\u017f\3\2\2\2\u017fT\3\2\2\2\u0180\u017e\3\2\2\2\u0181\u0185"+
+		"\5\3\2\2\u0182\u0184\5a\61\2\u0183\u0182\3\2\2\2\u0184\u0187\3\2\2\2\u0185"+
+		"\u0183\3\2\2\2\u0185\u0186\3\2\2\2\u0186\u0188\3\2\2\2\u0187\u0185\3\2"+
+		"\2\2\u0188\u0189\5\3\2\2\u0189\u0194\3\2\2\2\u018a\u018e\5\5\3\2\u018b"+
+		"\u018d\5a\61\2\u018c\u018b\3\2\2\2\u018d\u0190\3\2\2\2\u018e\u018c\3\2"+
+		"\2\2\u018e\u018f\3\2\2\2\u018f\u0191\3\2\2\2\u0190\u018e\3\2\2\2\u0191"+
+		"\u0192\5\5\3\2\u0192\u0194\3\2\2\2\u0193\u0181\3\2\2\2\u0193\u018a\3\2"+
+		"\2\2\u0194V\3\2\2\2\u0195\u0196\7\61\2\2\u0196\u0197\7\61\2\2\u0197\u0199"+
+		"\3\2\2\2\u0198\u019a\13\2\2\2\u0199\u0198\3\2\2\2\u019a\u019b\3\2\2\2"+
+		"\u019b\u019c\3\2\2\2\u019b\u0199\3\2\2\2\u019c\u019f\3\2\2\2\u019d\u01a0"+
+		"\5\13\6\2\u019e\u01a0\7\2\2\3\u019f\u019d\3\2\2\2\u019f\u019e\3\2\2\2"+
+		"\u01a0\u01a1\3\2\2\2\u01a1\u01a2\b,\2\2\u01a2X\3\2\2\2\u01a3\u01a5\t\4"+
+		"\2\2\u01a4\u01a3\3\2\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a4\3\2\2\2\u01a6"+
+		"\u01a7\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01a9\b-\2\2\u01a9Z\3\2\2\2\u01aa"+
+		"\u01ab\7\62\2\2\u01ab\\\3\2\2\2\u01ac\u01ad\4\63;\2\u01ad^\3\2\2\2\u01ae"+
+		"\u01af\4\62;\2\u01af`\3\2\2\2\u01b0\u01b1\n\5\2\2\u01b1b\3\2\2\2\u01b2"+
+		"\u01b3\t\6\2\2\u01b3d\3\2\2\2\u01b4\u01b5\t\7\2\2\u01b5f\3\2\2\2\u01b6"+
+		"\u01b7\t\b\2\2\u01b7h\3\2\2\2\u01b8\u01b9\t\t\2\2\u01b9j\3\2\2\2,\2}\u0085"+
+		"\u008d\u0097\u00a3\u00bd\u00c7\u00d1\u00db\u00f5\u0103\u0111\u0116\u011b"+
+		"\u011e\u0122\u0128\u012b\u0132\u0136\u0139\u013f\u0142\u0145\u014a\u014e"+
+		"\u0152\u0159\u015d\u0162\u0168\u016b\u0171\u0175\u017e\u0185\u018e\u0193"+
+		"\u019b\u019f\u01a6\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/56ff50c3/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 d41df54..98c65b3 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
@@ -37,12 +37,13 @@ public class StellarParser extends Parser {
 	protected static final PredictionContextCache _sharedContextCache =
 		new PredictionContextCache();
 	public static final int
-		COMMA=1, AND=2, OR=3, NOT=4, TRUE=5, FALSE=6, EQ=7, NEQ=8, LT=9, LTE=10, 
-		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, FLOAT_LITERAL=35, LONG_LITERAL=36, 
-		IDENTIFIER=37, STRING_LITERAL=38, COMMENT=39, WS=40;
+		DOUBLE_QUOTE=1, SINGLE_QUOTE=2, COMMA=3, PERIOD=4, EOL=5, AND=6, OR=7, 
+		NOT=8, TRUE=9, FALSE=10, EQ=11, NEQ=12, LT=13, LTE=14, GT=15, GTE=16, 
+		QUESTION=17, COLON=18, IF=19, THEN=20, ELSE=21, NULL=22, MINUS=23, PLUS=24, 
+		DIV=25, MUL=26, LBRACE=27, RBRACE=28, LBRACKET=29, RBRACKET=30, LPAREN=31, 
+		RPAREN=32, IN=33, NIN=34, EXISTS=35, EXPONENT=36, INT_LITERAL=37, DOUBLE_LITERAL=38, 
+		FLOAT_LITERAL=39, LONG_LITERAL=40, IDENTIFIER=41, STRING_LITERAL=42, COMMENT=43, 
+		WS=44;
 	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, 
@@ -58,17 +59,18 @@ public class StellarParser extends Parser {
 	};
 
 	private static final String[] _LITERAL_NAMES = {
-		null, "','", null, null, null, null, null, "'=='", "'!='", "'<'", "'<='", 
-		"'>'", "'>='", "'?'", "':'", null, null, null, null, "'-'", "'+'", "'/'", 
-		"'*'", "'{'", "'}'", "'['", "']'", "'('", "')'", "'in'", "'not in'"
+		null, "'\"'", "'''", "','", "'.'", "'\n'", null, null, null, null, null, 
+		"'=='", "'!='", "'<'", "'<='", "'>'", "'>='", "'?'", "':'", null, null, 
+		null, null, "'-'", "'+'", "'/'", "'*'", "'{'", "'}'", "'['", "']'", "'('", 
+		"')'"
 	};
 	private static final String[] _SYMBOLIC_NAMES = {
-		null, "COMMA", "AND", "OR", "NOT", "TRUE", "FALSE", "EQ", "NEQ", "LT", 
-		"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", "FLOAT_LITERAL", "LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", 
-		"COMMENT", "WS"
+		null, "DOUBLE_QUOTE", "SINGLE_QUOTE", "COMMA", "PERIOD", "EOL", "AND", 
+		"OR", "NOT", "TRUE", "FALSE", "EQ", "NEQ", "LT", "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", "FLOAT_LITERAL", 
+		"LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS"
 	};
 	public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
 
@@ -2135,7 +2137,7 @@ public class StellarParser extends Parser {
 	}
 
 	public static final String _serializedATN =
-		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3*\u00e6\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"+
@@ -2152,64 +2154,63 @@ public class StellarParser extends Parser {
 		"\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\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";
+		"\24\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$\2\6\3\2\r\22\3\2\31\32"+
+		"\3\2\33\34\3\2\13\f\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!\2\2+,\5\4\3\2,-\7\"\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\23\2\2\65\66\5\4\3\2\66\67\7\24\2\2\678\5\4\3\28A\3\2\2\29:\7\25"+
+		"\2\2:;\5\b\5\2;<\7\26\2\2<=\5\4\3\2=>\7\27\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\2"+
+		"FZ\3\2\2\2GH\5$\23\2HI\7#\2\2IJ\5$\23\2JZ\3\2\2\2KL\5$\23\2LM\7$\2\2M"+
+		"N\5$\23\2NZ\3\2\2\2OP\7\n\2\2PQ\7!\2\2QR\5\b\5\2RS\7\"\2\2SZ\3\2\2\2T"+
+		"U\7!\2\2UV\5\b\5\2VW\7\"\2\2WZ\3\2\2\2XZ\5$\23\2YB\3\2\2\2YG\3\2\2\2Y"+
+		"K\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\b\2"+
+		"\2]b\5\b\5\b^_\f\6\2\2_`\7\t\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!\2\2"+
+		"op\5\24\13\2pq\7\"\2\2qu\3\2\2\2rs\7!\2\2su\7\"\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\2z\u0083"+
+		"\3\2\2\2{|\f\5\2\2|}\7\5\2\2}\u0082\5$\23\2~\177\f\3\2\2\177\u0080\7\5"+
+		"\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\37\2\2\u0087\u0088\5\24\13\2\u0088\u0089\7 \2\2"+
+		"\u0089\u008d\3\2\2\2\u008a\u008b\7\37\2\2\u008b\u008d\7 \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\24\2\2\u0091\u0092\5\4\3\2\u0092\u009b\3"+
+		"\2\2\2\u0093\u0094\f\3\2\2\u0094\u0095\7\5\2\2\u0095\u0096\5$\23\2\u0096"+
+		"\u0097\7\24\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\35\2\2\u009f\u00a0\5\30"+
+		"\r\2\u00a0\u00a1\7\36\2\2\u00a1\u00a5\3\2\2\2\u00a2\u00a3\7\35\2\2\u00a3"+
+		"\u00a5\7\36\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\32\2\2\u00ab\u00b0\5\36\20\2\u00ac\u00ad"+
+		"\f\3\2\2\u00ad\u00ae\7\31\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"+
+		"\34\2\2\u00b9\u00be\5\36\20\5\u00ba\u00bb\f\3\2\2\u00bb\u00bc\7\33\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!\2\2\u00cc"+
+		"\u00cd\5\34\17\2\u00cd\u00ce\7\"\2\2\u00ce\u00d4\3\2\2\2\u00cf\u00d0\7"+
+		"!\2\2\u00d0\u00d1\5\6\4\2\u00d1\u00d2\7\"\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\30\2\2\u00db\u00dc\7%\2\2\u00dc\u00dd\7!\2\2\u00dd\u00de\7+\2"+
+		"\2\u00de\u00e4\7\"\2\2\u00df\u00e0\7!\2\2\u00e0\u00e1\5\6\4\2\u00e1\u00e2"+
+		"\7\"\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@Yac"+
+		"ty\u0081\u0083\u008c\u009b\u00a4\u00af\u00b1\u00bd\u00bf\u00d3\u00e3";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {


Mime
View raw message