Repository: metron
Updated Branches:
  refs/heads/master e5d876371 -> cc84b6a50


METRON-1079 STELLAR NaN should be a keyword (ottobackwards) closes 
apache/metron#681


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

Branch: refs/heads/master
Commit: cc84b6a50620447959c2ded4957a88ab329ba18c
Parents: e5d8763
Author: ottobackwards <ottobackwa...@gmail.com>
Authored: Fri Sep 29 16:18:46 2017 -0400
Committer: otto <o...@apache.org>
Committed: Fri Sep 29 16:18:46 2017 -0400

----------------------------------------------------------------------
 metron-stellar/stellar-common/README.md         |  14 +-
 .../metron/stellar/common/generated/Stellar.g4  |   2 +
 .../stellar-common/src/main/java/Stellar.tokens |  64 ++--
 .../src/main/java/StellarLexer.tokens           |  64 ++--
 .../metron/stellar/common/StellarCompiler.java  |   5 +
 .../common/generated/StellarBaseListener.java   |  12 +
 .../stellar/common/generated/StellarLexer.java  | 341 ++++++++++---------
 .../common/generated/StellarListener.java       |  12 +
 .../stellar/common/generated/StellarParser.java | 263 +++++++-------
 .../stellar/dsl/functions/MathFunctions.java    |  26 ++
 .../stellar/dsl/functions/BasicStellarTest.java | 136 ++++++++
 .../dsl/functions/MathFunctionsTest.java        |  22 +-
 12 files changed, 604 insertions(+), 357 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/README.md
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/README.md 
b/metron-stellar/stellar-common/README.md
index e13a07c..b35a5c7 100644
--- a/metron-stellar/stellar-common/README.md
+++ b/metron-stellar/stellar-common/README.md
@@ -41,9 +41,10 @@ The following keywords need to be single quote escaped in 
order to be used in St
 |               |               |             |             |             |
 | :-----------: | :-----------: | :---------: | :---------: | :---------: |
 | not           | else          | exists      | if          | then        |
-| and           | or            | in          | ==          | !=          |
-| \<=           | \>            | \>=         | \+          | \-          |
-| \<            | ?             | \*          | /           | ,           |
+| and           | or            | in          | NaN         | ==          |
+| !=            | \<=           | \>          | \>=         | \+          |
+| \-            | \<            | ?           | \*          | /           |
+| ,             |               |             |             |             |
 
 Using parens such as: "foo" : "\<ok\>" requires escaping; "foo": "\'\<ok\>\'"
 
@@ -158,6 +159,7 @@ In the core language functions, we support basic functional 
programming primitiv
 | [ `IS_EMPTY`](#is_empty)                                                     
                      |
 | [ `IS_INTEGER`](#is_integer)                                                 
                      |
 | [ `IS_IP`](#is_ip)                                                           
                      |
+| [ `IS_NAN`](#is_nan)                                                         
    |
 | [ `IS_URL`](#is_url)                                                         
                      |
 | [ `JOIN`](#join)                                                             
                      |
 | [ `KAFKA_GET`](#kafka_get)                                                   
                      |
@@ -581,6 +583,12 @@ In the core language functions, we support basic 
functional programming primitiv
     * type (optional) - Object of string or collection type (e.g. list) one of 
IPV4 or IPV6 or both.  The default is IPV4.
   * Returns: True if the string is an IP and false otherwise.
 
+### `IS_NAN`
+  * Description: Evaluates if the passed number is NaN.  The number is 
evaluated as a double.
+  * Input:
+    * number - number to evaluate"
+  * Returns: True if the number is NaN, false if it is 
+
 ### `IS_URL`
   * Description: Tests if a string is a valid URL
   * Input:

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
 
b/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
index 3577377..edd9632 100644
--- 
a/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
+++ 
b/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
@@ -65,6 +65,7 @@ IF : 'IF' | 'if';
 THEN : 'THEN' | 'then';
 ELSE : 'ELSE' | 'else';
 NULL : 'null' | 'NULL';
+NAN : 'NaN';
 
 MINUS : '-';
 PLUS : '+';
@@ -231,6 +232,7 @@ arithmetic_operands :
   | LONG_LITERAL #LongLiteral
   | FLOAT_LITERAL #FloatLiteral
   | IDENTIFIER #Variable
+  | NAN #NaNArith
   | LPAREN arithmetic_expr RPAREN #ParenArith
   | LPAREN conditional_expr RPAREN #condExpr
   ;

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/java/Stellar.tokens
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/main/java/Stellar.tokens 
b/metron-stellar/stellar-common/src/main/java/Stellar.tokens
index 6ba2cda..b2b32fb 100644
--- a/metron-stellar/stellar-common/src/main/java/Stellar.tokens
+++ b/metron-stellar/stellar-common/src/main/java/Stellar.tokens
@@ -21,27 +21,28 @@ IF=20
 THEN=21
 ELSE=22
 NULL=23
-MINUS=24
-PLUS=25
-DIV=26
-MUL=27
-LBRACE=28
-RBRACE=29
-LBRACKET=30
-RBRACKET=31
-LPAREN=32
-RPAREN=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
+NAN=24
+MINUS=25
+PLUS=26
+DIV=27
+MUL=28
+LBRACE=29
+RBRACE=30
+LBRACKET=31
+RBRACKET=32
+LPAREN=33
+RPAREN=34
+NIN=35
+EXISTS=36
+EXPONENT=37
+INT_LITERAL=38
+DOUBLE_LITERAL=39
+FLOAT_LITERAL=40
+LONG_LITERAL=41
+IDENTIFIER=42
+STRING_LITERAL=43
+COMMENT=44
+WS=45
 '->'=2
 '"'=3
 '\''=4
@@ -55,13 +56,14 @@ WS=44
 '>='=17
 '?'=18
 ':'=19
-'-'=24
-'+'=25
-'/'=26
-'*'=27
-'{'=28
-'}'=29
-'['=30
-']'=31
-'('=32
-')'=33
+'NaN'=24
+'-'=25
+'+'=26
+'/'=27
+'*'=28
+'{'=29
+'}'=30
+'['=31
+']'=32
+'('=33
+')'=34

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/java/StellarLexer.tokens
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/main/java/StellarLexer.tokens 
b/metron-stellar/stellar-common/src/main/java/StellarLexer.tokens
index 6ba2cda..b2b32fb 100644
--- a/metron-stellar/stellar-common/src/main/java/StellarLexer.tokens
+++ b/metron-stellar/stellar-common/src/main/java/StellarLexer.tokens
@@ -21,27 +21,28 @@ IF=20
 THEN=21
 ELSE=22
 NULL=23
-MINUS=24
-PLUS=25
-DIV=26
-MUL=27
-LBRACE=28
-RBRACE=29
-LBRACKET=30
-RBRACKET=31
-LPAREN=32
-RPAREN=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
+NAN=24
+MINUS=25
+PLUS=26
+DIV=27
+MUL=28
+LBRACE=29
+RBRACE=30
+LBRACKET=31
+RBRACKET=32
+LPAREN=33
+RPAREN=34
+NIN=35
+EXISTS=36
+EXPONENT=37
+INT_LITERAL=38
+DOUBLE_LITERAL=39
+FLOAT_LITERAL=40
+LONG_LITERAL=41
+IDENTIFIER=42
+STRING_LITERAL=43
+COMMENT=44
+WS=45
 '->'=2
 '"'=3
 '\''=4
@@ -55,13 +56,14 @@ WS=44
 '>='=17
 '?'=18
 ':'=19
-'-'=24
-'+'=25
-'/'=26
-'*'=27
-'{'=28
-'}'=29
-'['=30
-']'=31
-'('=32
-')'=33
+'NaN'=24
+'-'=25
+'+'=26
+'/'=27
+'*'=28
+'{'=29
+'}'=30
+'['=31
+']'=32
+'('=33
+')'=34

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
index 463389f..fbb5bc0 100644
--- 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
+++ 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
@@ -265,6 +265,11 @@ public class StellarCompiler extends StellarBaseListener {
   }
 
   @Override
+  public void exitNaNArith(StellarParser.NaNArithContext ctx) {
+    expression.tokenDeque.push(new Token<>(Double.NaN, Double.class, 
getArgContext()));
+  }
+
+  @Override
   public void exitArithExpr_plus(StellarParser.ArithExpr_plusContext ctx) {
     final FrameContext.Context context = getArgContext();
     expression.tokenDeque.push(new Token<>((tokenDeque, state) -> {

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
index 2a1a406..6e0ae8c 100644
--- 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
+++ 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
@@ -553,6 +553,18 @@ public class StellarBaseListener implements 
StellarListener {
         *
         * <p>The default implementation does nothing.</p>
         */
+       @Override public void enterNaNArith(StellarParser.NaNArithContext ctx) 
{ }
+       /**
+        * {@inheritDoc}
+        *
+        * <p>The default implementation does nothing.</p>
+        */
+       @Override public void exitNaNArith(StellarParser.NaNArithContext ctx) { 
}
+       /**
+        * {@inheritDoc}
+        *
+        * <p>The default implementation does nothing.</p>
+        */
        @Override public void enterParenArith(StellarParser.ParenArithContext 
ctx) { }
        /**
         * {@inheritDoc}

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarLexer.java
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarLexer.java
 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarLexer.java
index b453d4e..330b2ef 100644
--- 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarLexer.java
+++ 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarLexer.java
@@ -39,11 +39,11 @@ public class StellarLexer extends Lexer {
        public static final int
                IN=1, LAMBDA_OP=2, DOUBLE_QUOTE=3, SINGLE_QUOTE=4, COMMA=5, 
PERIOD=6, 
                AND=7, OR=8, NOT=9, TRUE=10, FALSE=11, EQ=12, NEQ=13, LT=14, 
LTE=15, GT=16, 
-               GTE=17, QUESTION=18, COLON=19, IF=20, THEN=21, ELSE=22, 
NULL=23, MINUS=24, 
-               PLUS=25, DIV=26, MUL=27, LBRACE=28, RBRACE=29, LBRACKET=30, 
RBRACKET=31, 
-               LPAREN=32, RPAREN=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;
+               GTE=17, QUESTION=18, COLON=19, IF=20, THEN=21, ELSE=22, 
NULL=23, NAN=24, 
+               MINUS=25, PLUS=26, DIV=27, MUL=28, LBRACE=29, RBRACE=30, 
LBRACKET=31, 
+               RBRACKET=32, LPAREN=33, RPAREN=34, NIN=35, EXISTS=36, 
EXPONENT=37, INT_LITERAL=38, 
+               DOUBLE_LITERAL=39, FLOAT_LITERAL=40, LONG_LITERAL=41, 
IDENTIFIER=42, STRING_LITERAL=43, 
+               COMMENT=44, WS=45;
        public static String[] modeNames = {
                "DEFAULT_MODE"
        };
@@ -51,8 +51,8 @@ public class StellarLexer extends Lexer {
        public static final String[] ruleNames = {
                "IN", "LAMBDA_OP", "DOUBLE_QUOTE", "SINGLE_QUOTE", "COMMA", 
"PERIOD", 
                "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", 
+               "QUESTION", "COLON", "IF", "THEN", "ELSE", "NULL", "NAN", 
"MINUS", "PLUS", 
+               "DIV", "MUL", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", 
"LPAREN", "RPAREN", 
                "NIN", "EXISTS", "EXPONENT", "INT_LITERAL", "DOUBLE_LITERAL", 
"FLOAT_LITERAL", 
                "LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", 
"WS", "ZERO", 
                "FIRST_DIGIT", "DIGIT", "D", "E", "F", "L", "EOL", 
"IDENTIFIER_START", 
@@ -62,14 +62,14 @@ public class StellarLexer extends Lexer {
        private static final String[] _LITERAL_NAMES = {
                null, null, "'->'", "'\"'", "'''", "','", "'.'", null, null, 
null, null, 
                null, "'=='", "'!='", "'<'", "'<='", "'>'", "'>='", "'?'", 
"':'", null, 
-               null, null, null, "'-'", "'+'", "'/'", "'*'", "'{'", "'}'", 
"'['", "']'", 
-               "'('", "')'"
+               null, null, null, "'NaN'", "'-'", "'+'", "'/'", "'*'", "'{'", 
"'}'", "'['", 
+               "']'", "'('", "')'"
        };
        private static final String[] _SYMBOLIC_NAMES = {
                null, "IN", "LAMBDA_OP", "DOUBLE_QUOTE", "SINGLE_QUOTE", 
"COMMA", "PERIOD", 
                "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", 
+               "QUESTION", "COLON", "IF", "THEN", "ELSE", "NULL", "NAN", 
"MINUS", "PLUS", 
+               "DIV", "MUL", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", 
"LPAREN", "RPAREN", 
                "NIN", "EXISTS", "EXPONENT", "INT_LITERAL", "DOUBLE_LITERAL", 
"FLOAT_LITERAL", 
                "LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS"
        };
@@ -128,173 +128,174 @@ 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.\u01d0\b\1\4\2\t"+
+               
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2/\u01d6\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*\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\4\66\t\66\4\67\t\67\48\t8\3\2\3\2\3\2\3\2\5\2v\n\2\3\3\3"+
-               
"\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b"+
-               
"\5\b\u008b\n\b\3\t\3\t\3\t\3\t\3\t\3\t\5\t\u0093\n\t\3\n\3\n\3\n\3\n\3"+
-               
"\n\3\n\5\n\u009b\n\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\5\13\u00a5"+
-               
"\n\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00b1\n\f\3\r\3\r\3"+
-               
"\r\3\16\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\22\3\22\3\22\3"+
-               
"\23\3\23\3\24\3\24\3\25\3\25\3\25\3\25\5\25\u00cb\n\25\3\26\3\26\3\26"+
-               
"\3\26\3\26\3\26\3\26\3\26\5\26\u00d5\n\26\3\27\3\27\3\27\3\27\3\27\3\27"+
-               
"\3\27\3\27\5\27\u00df\n\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\5\30"+
-               
"\u00e9\n\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#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\5#"+
-               
"\u010b\n#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\5$\u0119\n$\3%\3%\3%\5%"+
-               
"\u011e\n%\3%\6%\u0121\n%\r%\16%\u0122\3&\5&\u0126\n&\3&\3&\5&\u012a\n"+
-               
"&\3&\3&\7&\u012e\n&\f&\16&\u0131\13&\5&\u0133\n&\3\'\3\'\3\'\7\'\u0138"+
-               
"\n\'\f\'\16\'\u013b\13\'\3\'\5\'\u013e\n\'\3\'\5\'\u0141\n\'\3\'\3\'\6"+
-               
"\'\u0145\n\'\r\'\16\'\u0146\3\'\5\'\u014a\n\'\3\'\5\'\u014d\n\'\3\'\3"+
-               
"\'\3\'\5\'\u0152\n\'\3\'\3\'\5\'\u0156\n\'\3\'\3\'\5\'\u015a\n\'\3(\3"+
-               
"(\3(\7(\u015f\n(\f(\16(\u0162\13(\3(\5(\u0165\n(\3(\3(\3(\5(\u016a\n("+
-               
"\3(\3(\6(\u016e\n(\r(\16(\u016f\3(\5(\u0173\n(\3(\3(\3(\3(\5(\u0179\n"+
-               
"(\3(\3(\5(\u017d\n(\3)\3)\3)\3*\3*\3*\7*\u0185\n*\f*\16*\u0188\13*\3*"+
-               
"\3*\5*\u018c\n*\3+\3+\3+\3+\7+\u0192\n+\f+\16+\u0195\13+\3+\3+\3+\3+\3"+
-               
"+\3+\7+\u019d\n+\f+\16+\u01a0\13+\3+\3+\5+\u01a4\n+\3,\3,\3,\3,\6,\u01aa"+
-               
"\n,\r,\16,\u01ab\3,\3,\5,\u01b0\n,\3,\3,\3-\6-\u01b5\n-\r-\16-\u01b6\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\66\3\66\3\67\3\67\38\38\3\u01ab\29\3\3\5\4\7\5\t\6\13\7\r\b\17"+
+               
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\3\2\3\2\3\2\3\2\5\2x\n\2"+
+               
"\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3"+
+               
"\b\3\b\5\b\u008d\n\b\3\t\3\t\3\t\3\t\3\t\3\t\5\t\u0095\n\t\3\n\3\n\3\n"+
+               
"\3\n\3\n\3\n\5\n\u009d\n\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\5\13"+
+               
"\u00a7\n\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00b3\n\f\3\r"+
+               
"\3\r\3\r\3\16\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\22\3\22\3"+
+               
"\22\3\23\3\23\3\24\3\24\3\25\3\25\3\25\3\25\5\25\u00cd\n\25\3\26\3\26"+
+               
"\3\26\3\26\3\26\3\26\3\26\3\26\5\26\u00d7\n\26\3\27\3\27\3\27\3\27\3\27"+
+               
"\3\27\3\27\3\27\5\27\u00e1\n\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+
+               
"\5\30\u00eb\n\30\3\31\3\31\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#\3$\3$\3$\3$\3$\3$"+
+               
"\3$\3$\3$\3$\3$\3$\5$\u0111\n$\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\5%"+
+               
"\u011f\n%\3&\3&\3&\5&\u0124\n&\3&\6&\u0127\n&\r&\16&\u0128\3\'\5\'\u012c"+
+               
"\n\'\3\'\3\'\5\'\u0130\n\'\3\'\3\'\7\'\u0134\n\'\f\'\16\'\u0137\13\'\5"+
+               
"\'\u0139\n\'\3(\3(\3(\7(\u013e\n(\f(\16(\u0141\13(\3(\5(\u0144\n(\3(\5"+
+               
"(\u0147\n(\3(\3(\6(\u014b\n(\r(\16(\u014c\3(\5(\u0150\n(\3(\5(\u0153\n"+
+               
"(\3(\3(\3(\5(\u0158\n(\3(\3(\5(\u015c\n(\3(\3(\5(\u0160\n(\3)\3)\3)\7"+
+               
")\u0165\n)\f)\16)\u0168\13)\3)\5)\u016b\n)\3)\3)\3)\5)\u0170\n)\3)\3)"+
+               
"\6)\u0174\n)\r)\16)\u0175\3)\5)\u0179\n)\3)\3)\3)\3)\5)\u017f\n)\3)\3"+
+               
")\5)\u0183\n)\3*\3*\3*\3+\3+\3+\7+\u018b\n+\f+\16+\u018e\13+\3+\3+\5+"+
+               
"\u0192\n+\3,\3,\3,\3,\7,\u0198\n,\f,\16,\u019b\13,\3,\3,\3,\3,\3,\3,\7"+
+               
",\u01a3\n,\f,\16,\u01a6\13,\3,\3,\5,\u01aa\n,\3-\3-\3-\3-\6-\u01b0\n-"+
+               
"\r-\16-\u01b1\3-\3-\5-\u01b6\n-\3-\3-\3.\6.\u01bb\n.\r.\16.\u01bc\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"+
+               
"\66\3\66\3\67\3\67\38\38\39\39\3\u01b1\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(O)Q*S+"+
-               
"U,W-Y.[\2]\2_\2a\2c\2e\2g\2i\2k\2m\2o\2\3\2\16\4\2))^^\7\2))^^ppttvv\4"+
-               
"\2$$^^\7\2$$^^ppttvv\5\2\13\f\16\17\"\"\4\2FFff\4\2GGgg\4\2HHhh\4\2NN"+
-               
"nn\6\2&&C\\aac|\b\2\60\60\62<C\\^^aac|\b\2\60\60\62;C\\^^aac|\u01f6\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\2M\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\3u\3\2\2\2\5w\3\2\2\2\7z\3\2\2\2\t|\3\2"+
-               
"\2\2\13~\3\2\2\2\r\u0080\3\2\2\2\17\u008a\3\2\2\2\21\u0092\3\2\2\2\23"+
-               
"\u009a\3\2\2\2\25\u00a4\3\2\2\2\27\u00b0\3\2\2\2\31\u00b2\3\2\2\2\33\u00b5"+
-               
"\3\2\2\2\35\u00b8\3\2\2\2\37\u00ba\3\2\2\2!\u00bd\3\2\2\2#\u00bf\3\2\2"+
-               
"\2%\u00c2\3\2\2\2\'\u00c4\3\2\2\2)\u00ca\3\2\2\2+\u00d4\3\2\2\2-\u00de"+
-               
"\3\2\2\2/\u00e8\3\2\2\2\61\u00ea\3\2\2\2\63\u00ec\3\2\2\2\65\u00ee\3\2"+
-               
"\2\2\67\u00f0\3\2\2\29\u00f2\3\2\2\2;\u00f4\3\2\2\2=\u00f6\3\2\2\2?\u00f8"+
-               
"\3\2\2\2A\u00fa\3\2\2\2C\u00fc\3\2\2\2E\u010a\3\2\2\2G\u0118\3\2\2\2I"+
-               
"\u011a\3\2\2\2K\u0132\3\2\2\2M\u0159\3\2\2\2O\u017c\3\2\2\2Q\u017e\3\2"+
-               
"\2\2S\u018b\3\2\2\2U\u01a3\3\2\2\2W\u01a5\3\2\2\2Y\u01b4\3\2\2\2[\u01ba"+
-               
"\3\2\2\2]\u01bc\3\2\2\2_\u01be\3\2\2\2a\u01c0\3\2\2\2c\u01c2\3\2\2\2e"+
-               
"\u01c4\3\2\2\2g\u01c6\3\2\2\2i\u01c8\3\2\2\2k\u01ca\3\2\2\2m\u01cc\3\2"+
-               
"\2\2o\u01ce\3\2\2\2qr\7k\2\2rv\7p\2\2st\7K\2\2tv\7P\2\2uq\3\2\2\2us\3"+
-               
"\2\2\2v\4\3\2\2\2wx\7/\2\2xy\7@\2\2y\6\3\2\2\2z{\7$\2\2{\b\3\2\2\2|}\7"+
-               
")\2\2}\n\3\2\2\2~\177\7.\2\2\177\f\3\2\2\2\u0080\u0081\7\60\2\2\u0081"+
-               
"\16\3\2\2\2\u0082\u0083\7c\2\2\u0083\u0084\7p\2\2\u0084\u008b\7f\2\2\u0085"+
-               
"\u0086\7(\2\2\u0086\u008b\7(\2\2\u0087\u0088\7C\2\2\u0088\u0089\7P\2\2"+
-               
"\u0089\u008b\7F\2\2\u008a\u0082\3\2\2\2\u008a\u0085\3\2\2\2\u008a\u0087"+
-               
"\3\2\2\2\u008b\20\3\2\2\2\u008c\u008d\7q\2\2\u008d\u0093\7t\2\2\u008e"+
-               
"\u008f\7~\2\2\u008f\u0093\7~\2\2\u0090\u0091\7Q\2\2\u0091\u0093\7T\2\2"+
-               
"\u0092\u008c\3\2\2\2\u0092\u008e\3\2\2\2\u0092\u0090\3\2\2\2\u0093\22"+
-               
"\3\2\2\2\u0094\u0095\7p\2\2\u0095\u0096\7q\2\2\u0096\u009b\7v\2\2\u0097"+
-               
"\u0098\7P\2\2\u0098\u0099\7Q\2\2\u0099\u009b\7V\2\2\u009a\u0094\3\2\2"+
-               
"\2\u009a\u0097\3\2\2\2\u009b\24\3\2\2\2\u009c\u009d\7v\2\2\u009d\u009e"+
-               
"\7t\2\2\u009e\u009f\7w\2\2\u009f\u00a5\7g\2\2\u00a0\u00a1\7V\2\2\u00a1"+
-               
"\u00a2\7T\2\2\u00a2\u00a3\7W\2\2\u00a3\u00a5\7G\2\2\u00a4\u009c\3\2\2"+
-               
"\2\u00a4\u00a0\3\2\2\2\u00a5\26\3\2\2\2\u00a6\u00a7\7h\2\2\u00a7\u00a8"+
-               
"\7c\2\2\u00a8\u00a9\7n\2\2\u00a9\u00aa\7u\2\2\u00aa\u00b1\7g\2\2\u00ab"+
-               
"\u00ac\7H\2\2\u00ac\u00ad\7C\2\2\u00ad\u00ae\7N\2\2\u00ae\u00af\7U\2\2"+
-               
"\u00af\u00b1\7G\2\2\u00b0\u00a6\3\2\2\2\u00b0\u00ab\3\2\2\2\u00b1\30\3"+
-               
"\2\2\2\u00b2\u00b3\7?\2\2\u00b3\u00b4\7?\2\2\u00b4\32\3\2\2\2\u00b5\u00b6"+
-               
"\7#\2\2\u00b6\u00b7\7?\2\2\u00b7\34\3\2\2\2\u00b8\u00b9\7>\2\2\u00b9\36"+
-               "\3\2\2\2\u00ba\u00bb\7>\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@\2\2\u00c0\u00c1\7?\2\2\u00c1$\3"+
-               
"\2\2\2\u00c2\u00c3\7A\2\2\u00c3&\3\2\2\2\u00c4\u00c5\7<\2\2\u00c5(\3\2"+
-               
"\2\2\u00c6\u00c7\7K\2\2\u00c7\u00cb\7H\2\2\u00c8\u00c9\7k\2\2\u00c9\u00cb"+
-               
"\7h\2\2\u00ca\u00c6\3\2\2\2\u00ca\u00c8\3\2\2\2\u00cb*\3\2\2\2\u00cc\u00cd"+
-               
"\7V\2\2\u00cd\u00ce\7J\2\2\u00ce\u00cf\7G\2\2\u00cf\u00d5\7P\2\2\u00d0"+
-               
"\u00d1\7v\2\2\u00d1\u00d2\7j\2\2\u00d2\u00d3\7g\2\2\u00d3\u00d5\7p\2\2"+
-               
"\u00d4\u00cc\3\2\2\2\u00d4\u00d0\3\2\2\2\u00d5,\3\2\2\2\u00d6\u00d7\7"+
-               
"G\2\2\u00d7\u00d8\7N\2\2\u00d8\u00d9\7U\2\2\u00d9\u00df\7G\2\2\u00da\u00db"+
-               
"\7g\2\2\u00db\u00dc\7n\2\2\u00dc\u00dd\7u\2\2\u00dd\u00df\7g\2\2\u00de"+
-               
"\u00d6\3\2\2\2\u00de\u00da\3\2\2\2\u00df.\3\2\2\2\u00e0\u00e1\7p\2\2\u00e1"+
-               
"\u00e2\7w\2\2\u00e2\u00e3\7n\2\2\u00e3\u00e9\7n\2\2\u00e4\u00e5\7P\2\2"+
-               
"\u00e5\u00e6\7W\2\2\u00e6\u00e7\7N\2\2\u00e7\u00e9\7N\2\2\u00e8\u00e0"+
-               
"\3\2\2\2\u00e8\u00e4\3\2\2\2\u00e9\60\3\2\2\2\u00ea\u00eb\7/\2\2\u00eb"+
-               
"\62\3\2\2\2\u00ec\u00ed\7-\2\2\u00ed\64\3\2\2\2\u00ee\u00ef\7\61\2\2\u00ef"+
-               
"\66\3\2\2\2\u00f0\u00f1\7,\2\2\u00f18\3\2\2\2\u00f2\u00f3\7}\2\2\u00f3"+
-               
":\3\2\2\2\u00f4\u00f5\7\177\2\2\u00f5<\3\2\2\2\u00f6\u00f7\7]\2\2\u00f7"+
-               
">\3\2\2\2\u00f8\u00f9\7_\2\2\u00f9@\3\2\2\2\u00fa\u00fb\7*\2\2\u00fbB"+
-               
"\3\2\2\2\u00fc\u00fd\7+\2\2\u00fdD\3\2\2\2\u00fe\u00ff\7p\2\2\u00ff\u0100"+
-               
"\7q\2\2\u0100\u0101\7v\2\2\u0101\u0102\7\"\2\2\u0102\u0103\7k\2\2\u0103"+
-               
"\u010b\7p\2\2\u0104\u0105\7P\2\2\u0105\u0106\7Q\2\2\u0106\u0107\7V\2\2"+
-               
"\u0107\u0108\7\"\2\2\u0108\u0109\7K\2\2\u0109\u010b\7P\2\2\u010a\u00fe"+
-               
"\3\2\2\2\u010a\u0104\3\2\2\2\u010bF\3\2\2\2\u010c\u010d\7g\2\2\u010d\u010e"+
-               
"\7z\2\2\u010e\u010f\7k\2\2\u010f\u0110\7u\2\2\u0110\u0111\7v\2\2\u0111"+
-               
"\u0119\7u\2\2\u0112\u0113\7G\2\2\u0113\u0114\7Z\2\2\u0114\u0115\7K\2\2"+
-               
"\u0115\u0116\7U\2\2\u0116\u0117\7V\2\2\u0117\u0119\7U\2\2\u0118\u010c"+
-               
"\3\2\2\2\u0118\u0112\3\2\2\2\u0119H\3\2\2\2\u011a\u011d\5c\62\2\u011b"+
-               
"\u011e\5\63\32\2\u011c\u011e\5\61\31\2\u011d\u011b\3\2\2\2\u011d\u011c"+
-               
"\3\2\2\2\u011d\u011e\3\2\2\2\u011e\u0120\3\2\2\2\u011f\u0121\5_\60\2\u0120"+
-               
"\u011f\3\2\2\2\u0121\u0122\3\2\2\2\u0122\u0120\3\2\2\2\u0122\u0123\3\2"+
-               
"\2\2\u0123J\3\2\2\2\u0124\u0126\5\61\31\2\u0125\u0124\3\2\2\2\u0125\u0126"+
-               
"\3\2\2\2\u0126\u0127\3\2\2\2\u0127\u0133\5[.\2\u0128\u012a\5\61\31\2\u0129"+
-               
"\u0128\3\2\2\2\u0129\u012a\3\2\2\2\u012a\u012b\3\2\2\2\u012b\u012f\5]"+
-               
"/\2\u012c\u012e\5_\60\2\u012d\u012c\3\2\2\2\u012e\u0131\3\2\2\2\u012f"+
-               
"\u012d\3\2\2\2\u012f\u0130\3\2\2\2\u0130\u0133\3\2\2\2\u0131\u012f\3\2"+
-               
"\2\2\u0132\u0125\3\2\2\2\u0132\u0129\3\2\2\2\u0133L\3\2\2\2\u0134\u0135"+
-               
"\5K&\2\u0135\u0139\5\r\7\2\u0136\u0138\5_\60\2\u0137\u0136\3\2\2\2\u0138"+
-               
"\u013b\3\2\2\2\u0139\u0137\3\2\2\2\u0139\u013a\3\2\2\2\u013a\u013d\3\2"+
-               
"\2\2\u013b\u0139\3\2\2\2\u013c\u013e\5I%\2\u013d\u013c\3\2\2\2\u013d\u013e"+
-               
"\3\2\2\2\u013e\u0140\3\2\2\2\u013f\u0141\5a\61\2\u0140\u013f\3\2\2\2\u0140"+
-               
"\u0141\3\2\2\2\u0141\u015a\3\2\2\2\u0142\u0144\5\r\7\2\u0143\u0145\5_"+
-               
"\60\2\u0144\u0143\3\2\2\2\u0145\u0146\3\2\2\2\u0146\u0144\3\2\2\2\u0146"+
-               
"\u0147\3\2\2\2\u0147\u0149\3\2\2\2\u0148\u014a\5I%\2\u0149\u0148\3\2\2"+
-               
"\2\u0149\u014a\3\2\2\2\u014a\u014c\3\2\2\2\u014b\u014d\5a\61\2\u014c\u014b"+
-               
"\3\2\2\2\u014c\u014d\3\2\2\2\u014d\u015a\3\2\2\2\u014e\u014f\5K&\2\u014f"+
-               
"\u0151\5I%\2\u0150\u0152\5a\61\2\u0151\u0150\3\2\2\2\u0151\u0152\3\2\2"+
-               
"\2\u0152\u015a\3\2\2\2\u0153\u0155\5K&\2\u0154\u0156\5I%\2\u0155\u0154"+
-               
"\3\2\2\2\u0155\u0156\3\2\2\2\u0156\u0157\3\2\2\2\u0157\u0158\5a\61\2\u0158"+
-               
"\u015a\3\2\2\2\u0159\u0134\3\2\2\2\u0159\u0142\3\2\2\2\u0159\u014e\3\2"+
-               
"\2\2\u0159\u0153\3\2\2\2\u015aN\3\2\2\2\u015b\u015c\5K&\2\u015c\u0160"+
-               
"\5\r\7\2\u015d\u015f\5_\60\2\u015e\u015d\3\2\2\2\u015f\u0162\3\2\2\2\u0160"+
-               
"\u015e\3\2\2\2\u0160\u0161\3\2\2\2\u0161\u0164\3\2\2\2\u0162\u0160\3\2"+
-               
"\2\2\u0163\u0165\5I%\2\u0164\u0163\3\2\2\2\u0164\u0165\3\2\2\2\u0165\u0166"+
-               
"\3\2\2\2\u0166\u0167\5e\63\2\u0167\u017d\3\2\2\2\u0168\u016a\5\61\31\2"+
-               
"\u0169\u0168\3\2\2\2\u0169\u016a\3\2\2\2\u016a\u016b\3\2\2\2\u016b\u016d"+
-               
"\5\r\7\2\u016c\u016e\5_\60\2\u016d\u016c\3\2\2\2\u016e\u016f\3\2\2\2\u016f"+
-               
"\u016d\3\2\2\2\u016f\u0170\3\2\2\2\u0170\u0172\3\2\2\2\u0171\u0173\5I"+
-               
"%\2\u0172\u0171\3\2\2\2\u0172\u0173\3\2\2\2\u0173\u0174\3\2\2\2\u0174"+
-               
"\u0175\5e\63\2\u0175\u017d\3\2\2\2\u0176\u0178\5K&\2\u0177\u0179\5I%\2"+
-               
"\u0178\u0177\3\2\2\2\u0178\u0179\3\2\2\2\u0179\u017a\3\2\2\2\u017a\u017b"+
-               
"\5e\63\2\u017b\u017d\3\2\2\2\u017c\u015b\3\2\2\2\u017c\u0169\3\2\2\2\u017c"+
-               
"\u0176\3\2\2\2\u017dP\3\2\2\2\u017e\u017f\5K&\2\u017f\u0180\5g\64\2\u0180"+
-               
"R\3\2\2\2\u0181\u018c\5k\66\2\u0182\u0186\5k\66\2\u0183\u0185\5m\67\2"+
-               
"\u0184\u0183\3\2\2\2\u0185\u0188\3\2\2\2\u0186\u0184\3\2\2\2\u0186\u0187"+
-               
"\3\2\2\2\u0187\u0189\3\2\2\2\u0188\u0186\3\2\2\2\u0189\u018a\5o8\2\u018a"+
-               
"\u018c\3\2\2\2\u018b\u0181\3\2\2\2\u018b\u0182\3\2\2\2\u018cT\3\2\2\2"+
-               
"\u018d\u0193\5\t\5\2\u018e\u0192\n\2\2\2\u018f\u0190\7^\2\2\u0190\u0192"+
-               
"\t\3\2\2\u0191\u018e\3\2\2\2\u0191\u018f\3\2\2\2\u0192\u0195\3\2\2\2\u0193"+
-               
"\u0191\3\2\2\2\u0193\u0194\3\2\2\2\u0194\u0196\3\2\2\2\u0195\u0193\3\2"+
-               
"\2\2\u0196\u0197\5\t\5\2\u0197\u01a4\3\2\2\2\u0198\u019e\5\7\4\2\u0199"+
-               
"\u019d\n\4\2\2\u019a\u019b\7^\2\2\u019b\u019d\t\5\2\2\u019c\u0199\3\2"+
-               
"\2\2\u019c\u019a\3\2\2\2\u019d\u01a0\3\2\2\2\u019e\u019c\3\2\2\2\u019e"+
-               
"\u019f\3\2\2\2\u019f\u01a1\3\2\2\2\u01a0\u019e\3\2\2\2\u01a1\u01a2\5\7"+
-               
"\4\2\u01a2\u01a4\3\2\2\2\u01a3\u018d\3\2\2\2\u01a3\u0198\3\2\2\2\u01a4"+
-               
"V\3\2\2\2\u01a5\u01a6\7\61\2\2\u01a6\u01a7\7\61\2\2\u01a7\u01a9\3\2\2"+
-               
"\2\u01a8\u01aa\13\2\2\2\u01a9\u01a8\3\2\2\2\u01aa\u01ab\3\2\2\2\u01ab"+
-               
"\u01ac\3\2\2\2\u01ab\u01a9\3\2\2\2\u01ac\u01af\3\2\2\2\u01ad\u01b0\5i"+
-               
"\65\2\u01ae\u01b0\7\2\2\3\u01af\u01ad\3\2\2\2\u01af\u01ae\3\2\2\2\u01b0"+
-               
"\u01b1\3\2\2\2\u01b1\u01b2\b,\2\2\u01b2X\3\2\2\2\u01b3\u01b5\t\6\2\2\u01b4"+
-               
"\u01b3\3\2\2\2\u01b5\u01b6\3\2\2\2\u01b6\u01b4\3\2\2\2\u01b6\u01b7\3\2"+
-               
"\2\2\u01b7\u01b8\3\2\2\2\u01b8\u01b9\b-\2\2\u01b9Z\3\2\2\2\u01ba\u01bb"+
-               
"\7\62\2\2\u01bb\\\3\2\2\2\u01bc\u01bd\4\63;\2\u01bd^\3\2\2\2\u01be\u01bf"+
-               
"\4\62;\2\u01bf`\3\2\2\2\u01c0\u01c1\t\7\2\2\u01c1b\3\2\2\2\u01c2\u01c3"+
-               
"\t\b\2\2\u01c3d\3\2\2\2\u01c4\u01c5\t\t\2\2\u01c5f\3\2\2\2\u01c6\u01c7"+
-               
"\t\n\2\2\u01c7h\3\2\2\2\u01c8\u01c9\7\f\2\2\u01c9j\3\2\2\2\u01ca\u01cb"+
-               
"\t\13\2\2\u01cbl\3\2\2\2\u01cc\u01cd\t\f\2\2\u01cdn\3\2\2\2\u01ce\u01cf"+
-               
"\t\r\2\2\u01cfp\3\2\2\2/\2u\u008a\u0092\u009a\u00a4\u00b0\u00ca\u00d4"+
-               
"\u00de\u00e8\u010a\u0118\u011d\u0122\u0125\u0129\u012f\u0132\u0139\u013d"+
-               
"\u0140\u0146\u0149\u014c\u0151\u0155\u0159\u0160\u0164\u0169\u016f\u0172"+
-               
"\u0178\u017c\u0186\u018b\u0191\u0193\u019c\u019e\u01a3\u01ab\u01af\u01b6"+
-               "\3\b\2\2";
+               
"U,W-Y.[/]\2_\2a\2c\2e\2g\2i\2k\2m\2o\2q\2\3\2\16\4\2))^^\7\2))^^ppttv"+
+               
"v\4\2$$^^\7\2$$^^ppttvv\5\2\13\f\16\17\"\"\4\2FFff\4\2GGgg\4\2HHhh\4\2"+
+               
"NNnn\6\2&&C\\aac|\b\2\60\60\62<C\\^^aac|\b\2\60\60\62;C\\^^aac|\u01fc"+
+               
"\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\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2"+
+               
"U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\3w\3\2\2\2\5y\3\2\2\2\7|\3"+
+               
"\2\2\2\t~\3\2\2\2\13\u0080\3\2\2\2\r\u0082\3\2\2\2\17\u008c\3\2\2\2\21"+
+               
"\u0094\3\2\2\2\23\u009c\3\2\2\2\25\u00a6\3\2\2\2\27\u00b2\3\2\2\2\31\u00b4"+
+               
"\3\2\2\2\33\u00b7\3\2\2\2\35\u00ba\3\2\2\2\37\u00bc\3\2\2\2!\u00bf\3\2"+
+               
"\2\2#\u00c1\3\2\2\2%\u00c4\3\2\2\2\'\u00c6\3\2\2\2)\u00cc\3\2\2\2+\u00d6"+
+               
"\3\2\2\2-\u00e0\3\2\2\2/\u00ea\3\2\2\2\61\u00ec\3\2\2\2\63\u00f0\3\2\2"+
+               
"\2\65\u00f2\3\2\2\2\67\u00f4\3\2\2\29\u00f6\3\2\2\2;\u00f8\3\2\2\2=\u00fa"+
+               
"\3\2\2\2?\u00fc\3\2\2\2A\u00fe\3\2\2\2C\u0100\3\2\2\2E\u0102\3\2\2\2G"+
+               
"\u0110\3\2\2\2I\u011e\3\2\2\2K\u0120\3\2\2\2M\u0138\3\2\2\2O\u015f\3\2"+
+               
"\2\2Q\u0182\3\2\2\2S\u0184\3\2\2\2U\u0191\3\2\2\2W\u01a9\3\2\2\2Y\u01ab"+
+               
"\3\2\2\2[\u01ba\3\2\2\2]\u01c0\3\2\2\2_\u01c2\3\2\2\2a\u01c4\3\2\2\2c"+
+               
"\u01c6\3\2\2\2e\u01c8\3\2\2\2g\u01ca\3\2\2\2i\u01cc\3\2\2\2k\u01ce\3\2"+
+               
"\2\2m\u01d0\3\2\2\2o\u01d2\3\2\2\2q\u01d4\3\2\2\2st\7k\2\2tx\7p\2\2uv"+
+               
"\7K\2\2vx\7P\2\2ws\3\2\2\2wu\3\2\2\2x\4\3\2\2\2yz\7/\2\2z{\7@\2\2{\6\3"+
+               
"\2\2\2|}\7$\2\2}\b\3\2\2\2~\177\7)\2\2\177\n\3\2\2\2\u0080\u0081\7.\2"+
+               
"\2\u0081\f\3\2\2\2\u0082\u0083\7\60\2\2\u0083\16\3\2\2\2\u0084\u0085\7"+
+               
"c\2\2\u0085\u0086\7p\2\2\u0086\u008d\7f\2\2\u0087\u0088\7(\2\2\u0088\u008d"+
+               
"\7(\2\2\u0089\u008a\7C\2\2\u008a\u008b\7P\2\2\u008b\u008d\7F\2\2\u008c"+
+               
"\u0084\3\2\2\2\u008c\u0087\3\2\2\2\u008c\u0089\3\2\2\2\u008d\20\3\2\2"+
+               
"\2\u008e\u008f\7q\2\2\u008f\u0095\7t\2\2\u0090\u0091\7~\2\2\u0091\u0095"+
+               
"\7~\2\2\u0092\u0093\7Q\2\2\u0093\u0095\7T\2\2\u0094\u008e\3\2\2\2\u0094"+
+               
"\u0090\3\2\2\2\u0094\u0092\3\2\2\2\u0095\22\3\2\2\2\u0096\u0097\7p\2\2"+
+               
"\u0097\u0098\7q\2\2\u0098\u009d\7v\2\2\u0099\u009a\7P\2\2\u009a\u009b"+
+               
"\7Q\2\2\u009b\u009d\7V\2\2\u009c\u0096\3\2\2\2\u009c\u0099\3\2\2\2\u009d"+
+               
"\24\3\2\2\2\u009e\u009f\7v\2\2\u009f\u00a0\7t\2\2\u00a0\u00a1\7w\2\2\u00a1"+
+               
"\u00a7\7g\2\2\u00a2\u00a3\7V\2\2\u00a3\u00a4\7T\2\2\u00a4\u00a5\7W\2\2"+
+               
"\u00a5\u00a7\7G\2\2\u00a6\u009e\3\2\2\2\u00a6\u00a2\3\2\2\2\u00a7\26\3"+
+               
"\2\2\2\u00a8\u00a9\7h\2\2\u00a9\u00aa\7c\2\2\u00aa\u00ab\7n\2\2\u00ab"+
+               
"\u00ac\7u\2\2\u00ac\u00b3\7g\2\2\u00ad\u00ae\7H\2\2\u00ae\u00af\7C\2\2"+
+               
"\u00af\u00b0\7N\2\2\u00b0\u00b1\7U\2\2\u00b1\u00b3\7G\2\2\u00b2\u00a8"+
+               
"\3\2\2\2\u00b2\u00ad\3\2\2\2\u00b3\30\3\2\2\2\u00b4\u00b5\7?\2\2\u00b5"+
+               
"\u00b6\7?\2\2\u00b6\32\3\2\2\2\u00b7\u00b8\7#\2\2\u00b8\u00b9\7?\2\2\u00b9"+
+               
"\34\3\2\2\2\u00ba\u00bb\7>\2\2\u00bb\36\3\2\2\2\u00bc\u00bd\7>\2\2\u00bd"+
+               "\u00be\7?\2\2\u00be 
\3\2\2\2\u00bf\u00c0\7@\2\2\u00c0\"\3\2\2\2\u00c1"+
+               
"\u00c2\7@\2\2\u00c2\u00c3\7?\2\2\u00c3$\3\2\2\2\u00c4\u00c5\7A\2\2\u00c5"+
+               
"&\3\2\2\2\u00c6\u00c7\7<\2\2\u00c7(\3\2\2\2\u00c8\u00c9\7K\2\2\u00c9\u00cd"+
+               
"\7H\2\2\u00ca\u00cb\7k\2\2\u00cb\u00cd\7h\2\2\u00cc\u00c8\3\2\2\2\u00cc"+
+               
"\u00ca\3\2\2\2\u00cd*\3\2\2\2\u00ce\u00cf\7V\2\2\u00cf\u00d0\7J\2\2\u00d0"+
+               
"\u00d1\7G\2\2\u00d1\u00d7\7P\2\2\u00d2\u00d3\7v\2\2\u00d3\u00d4\7j\2\2"+
+               
"\u00d4\u00d5\7g\2\2\u00d5\u00d7\7p\2\2\u00d6\u00ce\3\2\2\2\u00d6\u00d2"+
+               
"\3\2\2\2\u00d7,\3\2\2\2\u00d8\u00d9\7G\2\2\u00d9\u00da\7N\2\2\u00da\u00db"+
+               
"\7U\2\2\u00db\u00e1\7G\2\2\u00dc\u00dd\7g\2\2\u00dd\u00de\7n\2\2\u00de"+
+               
"\u00df\7u\2\2\u00df\u00e1\7g\2\2\u00e0\u00d8\3\2\2\2\u00e0\u00dc\3\2\2"+
+               
"\2\u00e1.\3\2\2\2\u00e2\u00e3\7p\2\2\u00e3\u00e4\7w\2\2\u00e4\u00e5\7"+
+               
"n\2\2\u00e5\u00eb\7n\2\2\u00e6\u00e7\7P\2\2\u00e7\u00e8\7W\2\2\u00e8\u00e9"+
+               
"\7N\2\2\u00e9\u00eb\7N\2\2\u00ea\u00e2\3\2\2\2\u00ea\u00e6\3\2\2\2\u00eb"+
+               
"\60\3\2\2\2\u00ec\u00ed\7P\2\2\u00ed\u00ee\7c\2\2\u00ee\u00ef\7P\2\2\u00ef"+
+               
"\62\3\2\2\2\u00f0\u00f1\7/\2\2\u00f1\64\3\2\2\2\u00f2\u00f3\7-\2\2\u00f3"+
+               
"\66\3\2\2\2\u00f4\u00f5\7\61\2\2\u00f58\3\2\2\2\u00f6\u00f7\7,\2\2\u00f7"+
+               
":\3\2\2\2\u00f8\u00f9\7}\2\2\u00f9<\3\2\2\2\u00fa\u00fb\7\177\2\2\u00fb"+
+               
">\3\2\2\2\u00fc\u00fd\7]\2\2\u00fd@\3\2\2\2\u00fe\u00ff\7_\2\2\u00ffB"+
+               
"\3\2\2\2\u0100\u0101\7*\2\2\u0101D\3\2\2\2\u0102\u0103\7+\2\2\u0103F\3"+
+               
"\2\2\2\u0104\u0105\7p\2\2\u0105\u0106\7q\2\2\u0106\u0107\7v\2\2\u0107"+
+               
"\u0108\7\"\2\2\u0108\u0109\7k\2\2\u0109\u0111\7p\2\2\u010a\u010b\7P\2"+
+               
"\2\u010b\u010c\7Q\2\2\u010c\u010d\7V\2\2\u010d\u010e\7\"\2\2\u010e\u010f"+
+               
"\7K\2\2\u010f\u0111\7P\2\2\u0110\u0104\3\2\2\2\u0110\u010a\3\2\2\2\u0111"+
+               
"H\3\2\2\2\u0112\u0113\7g\2\2\u0113\u0114\7z\2\2\u0114\u0115\7k\2\2\u0115"+
+               
"\u0116\7u\2\2\u0116\u0117\7v\2\2\u0117\u011f\7u\2\2\u0118\u0119\7G\2\2"+
+               
"\u0119\u011a\7Z\2\2\u011a\u011b\7K\2\2\u011b\u011c\7U\2\2\u011c\u011d"+
+               
"\7V\2\2\u011d\u011f\7U\2\2\u011e\u0112\3\2\2\2\u011e\u0118\3\2\2\2\u011f"+
+               
"J\3\2\2\2\u0120\u0123\5e\63\2\u0121\u0124\5\65\33\2\u0122\u0124\5\63\32"+
+               
"\2\u0123\u0121\3\2\2\2\u0123\u0122\3\2\2\2\u0123\u0124\3\2\2\2\u0124\u0126"+
+               
"\3\2\2\2\u0125\u0127\5a\61\2\u0126\u0125\3\2\2\2\u0127\u0128\3\2\2\2\u0128"+
+               
"\u0126\3\2\2\2\u0128\u0129\3\2\2\2\u0129L\3\2\2\2\u012a\u012c\5\63\32"+
+               
"\2\u012b\u012a\3\2\2\2\u012b\u012c\3\2\2\2\u012c\u012d\3\2\2\2\u012d\u0139"+
+               
"\5]/\2\u012e\u0130\5\63\32\2\u012f\u012e\3\2\2\2\u012f\u0130\3\2\2\2\u0130"+
+               
"\u0131\3\2\2\2\u0131\u0135\5_\60\2\u0132\u0134\5a\61\2\u0133\u0132\3\2"+
+               
"\2\2\u0134\u0137\3\2\2\2\u0135\u0133\3\2\2\2\u0135\u0136\3\2\2\2\u0136"+
+               
"\u0139\3\2\2\2\u0137\u0135\3\2\2\2\u0138\u012b\3\2\2\2\u0138\u012f\3\2"+
+               
"\2\2\u0139N\3\2\2\2\u013a\u013b\5M\'\2\u013b\u013f\5\r\7\2\u013c\u013e"+
+               
"\5a\61\2\u013d\u013c\3\2\2\2\u013e\u0141\3\2\2\2\u013f\u013d\3\2\2\2\u013f"+
+               
"\u0140\3\2\2\2\u0140\u0143\3\2\2\2\u0141\u013f\3\2\2\2\u0142\u0144\5K"+
+               
"&\2\u0143\u0142\3\2\2\2\u0143\u0144\3\2\2\2\u0144\u0146\3\2\2\2\u0145"+
+               
"\u0147\5c\62\2\u0146\u0145\3\2\2\2\u0146\u0147\3\2\2\2\u0147\u0160\3\2"+
+               
"\2\2\u0148\u014a\5\r\7\2\u0149\u014b\5a\61\2\u014a\u0149\3\2\2\2\u014b"+
+               
"\u014c\3\2\2\2\u014c\u014a\3\2\2\2\u014c\u014d\3\2\2\2\u014d\u014f\3\2"+
+               
"\2\2\u014e\u0150\5K&\2\u014f\u014e\3\2\2\2\u014f\u0150\3\2\2\2\u0150\u0152"+
+               
"\3\2\2\2\u0151\u0153\5c\62\2\u0152\u0151\3\2\2\2\u0152\u0153\3\2\2\2\u0153"+
+               
"\u0160\3\2\2\2\u0154\u0155\5M\'\2\u0155\u0157\5K&\2\u0156\u0158\5c\62"+
+               
"\2\u0157\u0156\3\2\2\2\u0157\u0158\3\2\2\2\u0158\u0160\3\2\2\2\u0159\u015b"+
+               
"\5M\'\2\u015a\u015c\5K&\2\u015b\u015a\3\2\2\2\u015b\u015c\3\2\2\2\u015c"+
+               
"\u015d\3\2\2\2\u015d\u015e\5c\62\2\u015e\u0160\3\2\2\2\u015f\u013a\3\2"+
+               
"\2\2\u015f\u0148\3\2\2\2\u015f\u0154\3\2\2\2\u015f\u0159\3\2\2\2\u0160"+
+               
"P\3\2\2\2\u0161\u0162\5M\'\2\u0162\u0166\5\r\7\2\u0163\u0165\5a\61\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\u016a\3\2\2\2\u0168\u0166\3\2\2\2\u0169\u016b\5K&\2\u016a\u0169"+
+               
"\3\2\2\2\u016a\u016b\3\2\2\2\u016b\u016c\3\2\2\2\u016c\u016d\5g\64\2\u016d"+
+               
"\u0183\3\2\2\2\u016e\u0170\5\63\32\2\u016f\u016e\3\2\2\2\u016f\u0170\3"+
+               
"\2\2\2\u0170\u0171\3\2\2\2\u0171\u0173\5\r\7\2\u0172\u0174\5a\61\2\u0173"+
+               
"\u0172\3\2\2\2\u0174\u0175\3\2\2\2\u0175\u0173\3\2\2\2\u0175\u0176\3\2"+
+               
"\2\2\u0176\u0178\3\2\2\2\u0177\u0179\5K&\2\u0178\u0177\3\2\2\2\u0178\u0179"+
+               
"\3\2\2\2\u0179\u017a\3\2\2\2\u017a\u017b\5g\64\2\u017b\u0183\3\2\2\2\u017c"+
+               
"\u017e\5M\'\2\u017d\u017f\5K&\2\u017e\u017d\3\2\2\2\u017e\u017f\3\2\2"+
+               
"\2\u017f\u0180\3\2\2\2\u0180\u0181\5g\64\2\u0181\u0183\3\2\2\2\u0182\u0161"+
+               
"\3\2\2\2\u0182\u016f\3\2\2\2\u0182\u017c\3\2\2\2\u0183R\3\2\2\2\u0184"+
+               
"\u0185\5M\'\2\u0185\u0186\5i\65\2\u0186T\3\2\2\2\u0187\u0192\5m\67\2\u0188"+
+               
"\u018c\5m\67\2\u0189\u018b\5o8\2\u018a\u0189\3\2\2\2\u018b\u018e\3\2\2"+
+               
"\2\u018c\u018a\3\2\2\2\u018c\u018d\3\2\2\2\u018d\u018f\3\2\2\2\u018e\u018c"+
+               
"\3\2\2\2\u018f\u0190\5q9\2\u0190\u0192\3\2\2\2\u0191\u0187\3\2\2\2\u0191"+
+               
"\u0188\3\2\2\2\u0192V\3\2\2\2\u0193\u0199\5\t\5\2\u0194\u0198\n\2\2\2"+
+               
"\u0195\u0196\7^\2\2\u0196\u0198\t\3\2\2\u0197\u0194\3\2\2\2\u0197\u0195"+
+               
"\3\2\2\2\u0198\u019b\3\2\2\2\u0199\u0197\3\2\2\2\u0199\u019a\3\2\2\2\u019a"+
+               
"\u019c\3\2\2\2\u019b\u0199\3\2\2\2\u019c\u019d\5\t\5\2\u019d\u01aa\3\2"+
+               
"\2\2\u019e\u01a4\5\7\4\2\u019f\u01a3\n\4\2\2\u01a0\u01a1\7^\2\2\u01a1"+
+               
"\u01a3\t\5\2\2\u01a2\u019f\3\2\2\2\u01a2\u01a0\3\2\2\2\u01a3\u01a6\3\2"+
+               
"\2\2\u01a4\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a7\3\2\2\2\u01a6"+
+               
"\u01a4\3\2\2\2\u01a7\u01a8\5\7\4\2\u01a8\u01aa\3\2\2\2\u01a9\u0193\3\2"+
+               
"\2\2\u01a9\u019e\3\2\2\2\u01aaX\3\2\2\2\u01ab\u01ac\7\61\2\2\u01ac\u01ad"+
+               
"\7\61\2\2\u01ad\u01af\3\2\2\2\u01ae\u01b0\13\2\2\2\u01af\u01ae\3\2\2\2"+
+               
"\u01b0\u01b1\3\2\2\2\u01b1\u01b2\3\2\2\2\u01b1\u01af\3\2\2\2\u01b2\u01b5"+
+               
"\3\2\2\2\u01b3\u01b6\5k\66\2\u01b4\u01b6\7\2\2\3\u01b5\u01b3\3\2\2\2\u01b5"+
+               
"\u01b4\3\2\2\2\u01b6\u01b7\3\2\2\2\u01b7\u01b8\b-\2\2\u01b8Z\3\2\2\2\u01b9"+
+               
"\u01bb\t\6\2\2\u01ba\u01b9\3\2\2\2\u01bb\u01bc\3\2\2\2\u01bc\u01ba\3\2"+
+               
"\2\2\u01bc\u01bd\3\2\2\2\u01bd\u01be\3\2\2\2\u01be\u01bf\b.\2\2\u01bf"+
+               
"\\\3\2\2\2\u01c0\u01c1\7\62\2\2\u01c1^\3\2\2\2\u01c2\u01c3\4\63;\2\u01c3"+
+               
"`\3\2\2\2\u01c4\u01c5\4\62;\2\u01c5b\3\2\2\2\u01c6\u01c7\t\7\2\2\u01c7"+
+               
"d\3\2\2\2\u01c8\u01c9\t\b\2\2\u01c9f\3\2\2\2\u01ca\u01cb\t\t\2\2\u01cb"+
+               
"h\3\2\2\2\u01cc\u01cd\t\n\2\2\u01cdj\3\2\2\2\u01ce\u01cf\7\f\2\2\u01cf"+
+               
"l\3\2\2\2\u01d0\u01d1\t\13\2\2\u01d1n\3\2\2\2\u01d2\u01d3\t\f\2\2\u01d3"+
+               
"p\3\2\2\2\u01d4\u01d5\t\r\2\2\u01d5r\3\2\2\2/\2w\u008c\u0094\u009c\u00a6"+
+               
"\u00b2\u00cc\u00d6\u00e0\u00ea\u0110\u011e\u0123\u0128\u012b\u012f\u0135"+
+               
"\u0138\u013f\u0143\u0146\u014c\u014f\u0152\u0157\u015b\u015f\u0166\u016a"+
+               
"\u016f\u0175\u0178\u017e\u0182\u018c\u0191\u0197\u0199\u01a2\u01a4\u01a9"+
+               "\u01b1\u01b5\u01bc\3\b\2\2";
        public static final ATN _ATN =
                new ATNDeserializer().deserialize(_serializedATN.toCharArray());
        static {

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
index 6c70e38..8b16e00 100644
--- 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
+++ 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
@@ -523,6 +523,18 @@ public interface StellarListener extends ParseTreeListener 
{
         */
        void exitVariable(StellarParser.VariableContext ctx);
        /**
+        * Enter a parse tree produced by the {@code NaNArith}
+        * labeled alternative in {@link StellarParser#arithmetic_operands}.
+        * @param ctx the parse tree
+        */
+       void enterNaNArith(StellarParser.NaNArithContext ctx);
+       /**
+        * Exit a parse tree produced by the {@code NaNArith}
+        * labeled alternative in {@link StellarParser#arithmetic_operands}.
+        * @param ctx the parse tree
+        */
+       void exitNaNArith(StellarParser.NaNArithContext ctx);
+       /**
         * Enter a parse tree produced by the {@code ParenArith}
         * labeled alternative in {@link StellarParser#arithmetic_operands}.
         * @param ctx the parse tree

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
index d4c6ba3..1ea8a11 100644
--- 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
+++ 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
@@ -39,11 +39,11 @@ public class StellarParser extends Parser {
        public static final int
                IN=1, LAMBDA_OP=2, DOUBLE_QUOTE=3, SINGLE_QUOTE=4, COMMA=5, 
PERIOD=6, 
                AND=7, OR=8, NOT=9, TRUE=10, FALSE=11, EQ=12, NEQ=13, LT=14, 
LTE=15, GT=16, 
-               GTE=17, QUESTION=18, COLON=19, IF=20, THEN=21, ELSE=22, 
NULL=23, MINUS=24, 
-               PLUS=25, DIV=26, MUL=27, LBRACE=28, RBRACE=29, LBRACKET=30, 
RBRACKET=31, 
-               LPAREN=32, RPAREN=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;
+               GTE=17, QUESTION=18, COLON=19, IF=20, THEN=21, ELSE=22, 
NULL=23, NAN=24, 
+               MINUS=25, PLUS=26, DIV=27, MUL=28, LBRACE=29, RBRACE=30, 
LBRACKET=31, 
+               RBRACKET=32, LPAREN=33, RPAREN=34, NIN=35, EXISTS=36, 
EXPONENT=37, INT_LITERAL=38, 
+               DOUBLE_LITERAL=39, FLOAT_LITERAL=40, LONG_LITERAL=41, 
IDENTIFIER=42, STRING_LITERAL=43, 
+               COMMENT=44, WS=45;
        public static final int
                RULE_transformation = 0, RULE_transformation_expr = 1, 
RULE_if_expr = 2, 
                RULE_then_expr = 3, RULE_else_expr = 4, RULE_conditional_expr = 
5, RULE_logical_expr = 6, 
@@ -65,14 +65,14 @@ public class StellarParser extends Parser {
        private static final String[] _LITERAL_NAMES = {
                null, null, "'->'", "'\"'", "'''", "','", "'.'", null, null, 
null, null, 
                null, "'=='", "'!='", "'<'", "'<='", "'>'", "'>='", "'?'", 
"':'", null, 
-               null, null, null, "'-'", "'+'", "'/'", "'*'", "'{'", "'}'", 
"'['", "']'", 
-               "'('", "')'"
+               null, null, null, "'NaN'", "'-'", "'+'", "'/'", "'*'", "'{'", 
"'}'", "'['", 
+               "']'", "'('", "')'"
        };
        private static final String[] _SYMBOLIC_NAMES = {
                null, "IN", "LAMBDA_OP", "DOUBLE_QUOTE", "SINGLE_QUOTE", 
"COMMA", "PERIOD", 
                "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", 
+               "QUESTION", "COLON", "IF", "THEN", "ELSE", "NULL", "NAN", 
"MINUS", "PLUS", 
+               "DIV", "MUL", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", 
"LPAREN", "RPAREN", 
                "NIN", "EXISTS", "EXPONENT", "INT_LITERAL", "DOUBLE_LITERAL", 
"FLOAT_LITERAL", 
                "LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS"
        };
@@ -542,6 +542,7 @@ public class StellarParser extends Parser {
                        case TRUE:
                        case FALSE:
                        case NULL:
+                       case NAN:
                        case LBRACE:
                        case LBRACKET:
                        case LPAREN:
@@ -1941,6 +1942,18 @@ public class StellarParser extends Parser {
                        if ( listener instanceof StellarListener ) 
((StellarListener)listener).exitIntLiteral(this);
                }
        }
+       public static class NaNArithContext extends Arithmetic_operandsContext {
+               public TerminalNode NAN() { return getToken(StellarParser.NAN, 
0); }
+               public NaNArithContext(Arithmetic_operandsContext ctx) { 
copyFrom(ctx); }
+               @Override
+               public void enterRule(ParseTreeListener listener) {
+                       if ( listener instanceof StellarListener ) 
((StellarListener)listener).enterNaNArith(this);
+               }
+               @Override
+               public void exitRule(ParseTreeListener listener) {
+                       if ( listener instanceof StellarListener ) 
((StellarListener)listener).exitNaNArith(this);
+               }
+       }
        public static class DoubleLiteralContext extends 
Arithmetic_operandsContext {
                public TerminalNode DOUBLE_LITERAL() { return 
getToken(StellarParser.DOUBLE_LITERAL, 0); }
                public DoubleLiteralContext(Arithmetic_operandsContext ctx) { 
copyFrom(ctx); }
@@ -1958,7 +1971,7 @@ public class StellarParser extends Parser {
                Arithmetic_operandsContext _localctx = new 
Arithmetic_operandsContext(_ctx, getState());
                enterRule(_localctx, 40, RULE_arithmetic_operands);
                try {
-                       setState(242);
+                       setState(243);
                        switch ( 
getInterpreter().adaptivePredict(_input,18,_ctx) ) {
                        case 1:
                                _localctx = new 
NumericFunctionsContext(_localctx);
@@ -2009,26 +2022,34 @@ public class StellarParser extends Parser {
                                }
                                break;
                        case 7:
-                               _localctx = new ParenArithContext(_localctx);
+                               _localctx = new NaNArithContext(_localctx);
                                enterOuterAlt(_localctx, 7);
                                {
                                setState(234);
-                               match(LPAREN);
+                               match(NAN);
+                               }
+                               break;
+                       case 8:
+                               _localctx = new ParenArithContext(_localctx);
+                               enterOuterAlt(_localctx, 8);
+                               {
                                setState(235);
-                               arithmetic_expr(0);
+                               match(LPAREN);
                                setState(236);
+                               arithmetic_expr(0);
+                               setState(237);
                                match(RPAREN);
                                }
                                break;
-                       case 8:
+                       case 9:
                                _localctx = new CondExprContext(_localctx);
-                               enterOuterAlt(_localctx, 8);
+                               enterOuterAlt(_localctx, 9);
                                {
-                               setState(238);
-                               match(LPAREN);
                                setState(239);
-                               conditional_expr();
+                               match(LPAREN);
                                setState(240);
+                               conditional_expr();
+                               setState(241);
                                match(RPAREN);
                                }
                                break;
@@ -2200,13 +2221,13 @@ public class StellarParser extends Parser {
                enterRule(_localctx, 42, RULE_identifier_operand);
                int _la;
                try {
-                       setState(260);
+                       setState(261);
                        switch ( 
getInterpreter().adaptivePredict(_input,19,_ctx) ) {
                        case 1:
                                _localctx = new LogicalConstContext(_localctx);
                                enterOuterAlt(_localctx, 1);
                                {
-                               setState(244);
+                               setState(245);
                                _la = _input.LA(1);
                                if ( !(_la==TRUE || _la==FALSE) ) {
                                _errHandler.recoverInline(this);
@@ -2219,7 +2240,7 @@ public class StellarParser extends Parser {
                                _localctx = new 
LambdaWithArgsExprContext(_localctx);
                                enterOuterAlt(_localctx, 2);
                                {
-                               setState(245);
+                               setState(246);
                                lambda_with_args();
                                }
                                break;
@@ -2227,7 +2248,7 @@ public class StellarParser extends Parser {
                                _localctx = new 
LambdaWithoutArgsExprContext(_localctx);
                                enterOuterAlt(_localctx, 3);
                                {
-                               setState(246);
+                               setState(247);
                                lambda_without_args();
                                }
                                break;
@@ -2235,7 +2256,7 @@ public class StellarParser extends Parser {
                                _localctx = new 
ArithmeticOperandsContext(_localctx);
                                enterOuterAlt(_localctx, 4);
                                {
-                               setState(247);
+                               setState(248);
                                arithmetic_expr(0);
                                }
                                break;
@@ -2243,7 +2264,7 @@ public class StellarParser extends Parser {
                                _localctx = new StringLiteralContext(_localctx);
                                enterOuterAlt(_localctx, 5);
                                {
-                               setState(248);
+                               setState(249);
                                match(STRING_LITERAL);
                                }
                                break;
@@ -2251,7 +2272,7 @@ public class StellarParser extends Parser {
                                _localctx = new ListContext(_localctx);
                                enterOuterAlt(_localctx, 6);
                                {
-                               setState(249);
+                               setState(250);
                                list_entity();
                                }
                                break;
@@ -2259,7 +2280,7 @@ public class StellarParser extends Parser {
                                _localctx = new MapConstContext(_localctx);
                                enterOuterAlt(_localctx, 7);
                                {
-                               setState(250);
+                               setState(251);
                                map_entity();
                                }
                                break;
@@ -2267,7 +2288,7 @@ public class StellarParser extends Parser {
                                _localctx = new NullConstContext(_localctx);
                                enterOuterAlt(_localctx, 8);
                                {
-                               setState(251);
+                               setState(252);
                                match(NULL);
                                }
                                break;
@@ -2275,13 +2296,13 @@ public class StellarParser extends Parser {
                                _localctx = new ExistsFuncContext(_localctx);
                                enterOuterAlt(_localctx, 9);
                                {
-                               setState(252);
-                               match(EXISTS);
                                setState(253);
-                               match(LPAREN);
+                               match(EXISTS);
                                setState(254);
-                               match(IDENTIFIER);
+                               match(LPAREN);
                                setState(255);
+                               match(IDENTIFIER);
+                               setState(256);
                                match(RPAREN);
                                }
                                break;
@@ -2289,11 +2310,11 @@ public class StellarParser extends Parser {
                                _localctx = new 
CondExpr_parenContext(_localctx);
                                enterOuterAlt(_localctx, 10);
                                {
-                               setState(256);
-                               match(LPAREN);
                                setState(257);
-                               conditional_expr();
+                               match(LPAREN);
                                setState(258);
+                               conditional_expr();
+                               setState(259);
                                match(RPAREN);
                                }
                                break;
@@ -2337,13 +2358,13 @@ public class StellarParser extends Parser {
                try {
                        enterOuterAlt(_localctx, 1);
                        {
-                       setState(262);
-                       match(LPAREN);
                        setState(263);
-                       match(RPAREN);
+                       match(LPAREN);
                        setState(264);
-                       match(LAMBDA_OP);
+                       match(RPAREN);
                        setState(265);
+                       match(LAMBDA_OP);
+                       setState(266);
                        transformation_expr();
                        }
                }
@@ -2389,31 +2410,31 @@ public class StellarParser extends Parser {
                Lambda_with_argsContext _localctx = new 
Lambda_with_argsContext(_ctx, getState());
                enterRule(_localctx, 46, RULE_lambda_with_args);
                try {
-                       setState(277);
+                       setState(278);
                        switch (_input.LA(1)) {
                        case LPAREN:
                                enterOuterAlt(_localctx, 1);
                                {
-                               setState(267);
-                               match(LPAREN);
                                setState(268);
-                               lambda_variables();
+                               match(LPAREN);
                                setState(269);
-                               match(RPAREN);
+                               lambda_variables();
                                setState(270);
-                               match(LAMBDA_OP);
+                               match(RPAREN);
                                setState(271);
+                               match(LAMBDA_OP);
+                               setState(272);
                                transformation_expr();
                                }
                                break;
                        case IDENTIFIER:
                                enterOuterAlt(_localctx, 2);
                                {
-                               setState(273);
-                               single_lambda_variable();
                                setState(274);
-                               match(LAMBDA_OP);
+                               single_lambda_variable();
                                setState(275);
+                               match(LAMBDA_OP);
+                               setState(276);
                                transformation_expr();
                                }
                                break;
@@ -2464,21 +2485,21 @@ public class StellarParser extends Parser {
                try {
                        enterOuterAlt(_localctx, 1);
                        {
-                       setState(279);
+                       setState(280);
                        lambda_variable();
-                       setState(284);
+                       setState(285);
                        _errHandler.sync(this);
                        _la = _input.LA(1);
                        while (_la==COMMA) {
                                {
                                {
-                               setState(280);
-                               match(COMMA);
                                setState(281);
+                               match(COMMA);
+                               setState(282);
                                lambda_variable();
                                }
                                }
-                               setState(286);
+                               setState(287);
                                _errHandler.sync(this);
                                _la = _input.LA(1);
                        }
@@ -2519,7 +2540,7 @@ public class StellarParser extends Parser {
                try {
                        enterOuterAlt(_localctx, 1);
                        {
-                       setState(287);
+                       setState(288);
                        lambda_variable();
                        }
                }
@@ -2556,7 +2577,7 @@ public class StellarParser extends Parser {
                try {
                        enterOuterAlt(_localctx, 1);
                        {
-                       setState(289);
+                       setState(290);
                        match(IDENTIFIER);
                        }
                }
@@ -2629,7 +2650,7 @@ public class StellarParser extends Parser {
        }
 
        public static final String _serializedATN =
-               
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3.\u0126\4\2\t\2\4"+
+               
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3/\u0127\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"+
@@ -2647,87 +2668,87 @@ public class StellarParser extends Parser {
                
"\3\23\3\23\3\23\3\23\3\23\3\23\3\23\7\23\u00d1\n\23\f\23\16\23\u00d4\13"+
                
"\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\7\24\u00df\n\24\f\24"+
                
"\16\24\u00e2\13\24\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3"+
-               
"\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26\u00f5\n\26\3\27\3\27\3\27\3\27"+
-               
"\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\5\27\u0107"+
-               
"\n\27\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+
-               
"\3\31\3\31\5\31\u0118\n\31\3\32\3\32\3\32\7\32\u011d\n\32\f\32\16\32\u0120"+
-               "\13\32\3\33\3\33\3\34\3\34\3\34\2\7\24\34 
$&\35\2\4\6\b\n\f\16\20\22\24"+
-               "\26\30\32\34\36 
\"$&(*,.\60\62\64\66\2\4\3\2\16\23\3\2\f\r\u0135\28\3"+
-               
"\2\2\2\4E\3\2\2\2\6G\3\2\2\2\bI\3\2\2\2\nK\3\2\2\2\fZ\3\2\2\2\16e\3\2"+
-               
"\2\2\20i\3\2\2\2\22s\3\2\2\2\24\u0080\3\2\2\2\26\u008b\3\2\2\2\30\u008d"+
-               "\3\2\2\2\32\u0095\3\2\2\2\34\u009a\3\2\2\2\36\u00ad\3\2\2\2 
\u00af\3\2"+
-               
"\2\2\"\u00c5\3\2\2\2$\u00c7\3\2\2\2&\u00d5\3\2\2\2(\u00e3\3\2\2\2*\u00f4"+
-               
"\3\2\2\2,\u0106\3\2\2\2.\u0108\3\2\2\2\60\u0117\3\2\2\2\62\u0119\3\2\2"+
-               
"\2\64\u0121\3\2\2\2\66\u0123\3\2\2\289\5\4\3\29:\7\2\2\3:\3\3\2\2\2;F"+
-               
"\5\f\7\2<=\7\"\2\2=>\5\4\3\2>?\7#\2\2?F\3\2\2\2@F\5$\23\2AF\5\26\f\2B"+
-               
"F\5\24\13\2CF\5\16\b\2DF\5\22\n\2E;\3\2\2\2E<\3\2\2\2E@\3\2\2\2EA\3\2"+
-               
"\2\2EB\3\2\2\2EC\3\2\2\2ED\3\2\2\2F\5\3\2\2\2GH\5\16\b\2H\7\3\2\2\2IJ"+
-               
"\5\4\3\2J\t\3\2\2\2KL\5\4\3\2L\13\3\2\2\2MN\5\6\4\2NO\7\24\2\2OP\5\b\5"+
-               
"\2PQ\7\25\2\2QR\5\n\6\2R[\3\2\2\2ST\7\26\2\2TU\5\6\4\2UV\7\27\2\2VW\5"+
-               
"\b\5\2WX\7\30\2\2XY\5\n\6\2Y[\3\2\2\2ZM\3\2\2\2ZS\3\2\2\2[\r\3\2\2\2\\"+
-               
"]\5\20\t\2]^\7\t\2\2^_\5\16\b\2_f\3\2\2\2`a\5\20\t\2ab\7\n\2\2bc\5\16"+
-               
"\b\2cf\3\2\2\2df\5\20\t\2e\\\3\2\2\2e`\3\2\2\2ed\3\2\2\2f\17\3\2\2\2g"+
-               
"j\5\24\13\2hj\5\22\n\2ig\3\2\2\2ih\3\2\2\2j\21\3\2\2\2kl\5,\27\2lm\7\3"+
-               
"\2\2mn\5\20\t\2nt\3\2\2\2op\5,\27\2pq\7$\2\2qr\5\20\t\2rt\3\2\2\2sk\3"+
-               
"\2\2\2so\3\2\2\2t\23\3\2\2\2uv\b\13\1\2vw\7\13\2\2wx\7\"\2\2xy\5\16\b"+
-               
"\2yz\7#\2\2z\u0081\3\2\2\2{|\7\"\2\2|}\5\16\b\2}~\7#\2\2~\u0081\3\2\2"+
+               
"\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26\u00f6\n\26\3\27\3\27\3\27"+
+               
"\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\5\27"+
+               
"\u0108\n\27\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+
+               
"\3\31\3\31\3\31\5\31\u0119\n\31\3\32\3\32\3\32\7\32\u011e\n\32\f\32\16"+
+               "\32\u0121\13\32\3\33\3\33\3\34\3\34\3\34\2\7\24\34 
$&\35\2\4\6\b\n\f\16"+
+               "\20\22\24\26\30\32\34\36 
\"$&(*,.\60\62\64\66\2\4\3\2\16\23\3\2\f\r\u0137"+
+               
"\28\3\2\2\2\4E\3\2\2\2\6G\3\2\2\2\bI\3\2\2\2\nK\3\2\2\2\fZ\3\2\2\2\16"+
+               
"e\3\2\2\2\20i\3\2\2\2\22s\3\2\2\2\24\u0080\3\2\2\2\26\u008b\3\2\2\2\30"+
+               
"\u008d\3\2\2\2\32\u0095\3\2\2\2\34\u009a\3\2\2\2\36\u00ad\3\2\2\2 \u00af"+
+               
"\3\2\2\2\"\u00c5\3\2\2\2$\u00c7\3\2\2\2&\u00d5\3\2\2\2(\u00e3\3\2\2\2"+
+               
"*\u00f5\3\2\2\2,\u0107\3\2\2\2.\u0109\3\2\2\2\60\u0118\3\2\2\2\62\u011a"+
+               
"\3\2\2\2\64\u0122\3\2\2\2\66\u0124\3\2\2\289\5\4\3\29:\7\2\2\3:\3\3\2"+
+               
"\2\2;F\5\f\7\2<=\7#\2\2=>\5\4\3\2>?\7$\2\2?F\3\2\2\2@F\5$\23\2AF\5\26"+
+               
"\f\2BF\5\24\13\2CF\5\16\b\2DF\5\22\n\2E;\3\2\2\2E<\3\2\2\2E@\3\2\2\2E"+
+               
"A\3\2\2\2EB\3\2\2\2EC\3\2\2\2ED\3\2\2\2F\5\3\2\2\2GH\5\16\b\2H\7\3\2\2"+
+               
"\2IJ\5\4\3\2J\t\3\2\2\2KL\5\4\3\2L\13\3\2\2\2MN\5\6\4\2NO\7\24\2\2OP\5"+
+               
"\b\5\2PQ\7\25\2\2QR\5\n\6\2R[\3\2\2\2ST\7\26\2\2TU\5\6\4\2UV\7\27\2\2"+
+               
"VW\5\b\5\2WX\7\30\2\2XY\5\n\6\2Y[\3\2\2\2ZM\3\2\2\2ZS\3\2\2\2[\r\3\2\2"+
+               
"\2\\]\5\20\t\2]^\7\t\2\2^_\5\16\b\2_f\3\2\2\2`a\5\20\t\2ab\7\n\2\2bc\5"+
+               
"\16\b\2cf\3\2\2\2df\5\20\t\2e\\\3\2\2\2e`\3\2\2\2ed\3\2\2\2f\17\3\2\2"+
+               
"\2gj\5\24\13\2hj\5\22\n\2ig\3\2\2\2ih\3\2\2\2j\21\3\2\2\2kl\5,\27\2lm"+
+               
"\7\3\2\2mn\5\20\t\2nt\3\2\2\2op\5,\27\2pq\7%\2\2qr\5\20\t\2rt\3\2\2\2"+
+               
"sk\3\2\2\2so\3\2\2\2t\23\3\2\2\2uv\b\13\1\2vw\7\13\2\2wx\7#\2\2xy\5\16"+
+               
"\b\2yz\7$\2\2z\u0081\3\2\2\2{|\7#\2\2|}\5\16\b\2}~\7$\2\2~\u0081\3\2\2"+
                
"\2\177\u0081\5,\27\2\u0080u\3\2\2\2\u0080{\3\2\2\2\u0080\177\3\2\2\2\u0081"+
                
"\u0088\3\2\2\2\u0082\u0083\f\6\2\2\u0083\u0084\5\30\r\2\u0084\u0085\5"+
                
"\24\13\7\u0085\u0087\3\2\2\2\u0086\u0082\3\2\2\2\u0087\u008a\3\2\2\2\u0088"+
                
"\u0086\3\2\2\2\u0088\u0089\3\2\2\2\u0089\25\3\2\2\2\u008a\u0088\3\2\2"+
                
"\2\u008b\u008c\5,\27\2\u008c\27\3\2\2\2\u008d\u008e\t\2\2\2\u008e\31\3"+
-               
"\2\2\2\u008f\u0090\7\"\2\2\u0090\u0091\5\34\17\2\u0091\u0092\7#\2\2\u0092"+
-               
"\u0096\3\2\2\2\u0093\u0094\7\"\2\2\u0094\u0096\7#\2\2\u0095\u008f\3\2"+
-               
"\2\2\u0095\u0093\3\2\2\2\u0096\33\3\2\2\2\u0097\u0098\b\17\1\2\u0098\u009b"+
+               
"\2\2\2\u008f\u0090\7#\2\2\u0090\u0091\5\34\17\2\u0091\u0092\7$\2\2\u0092"+
+               
"\u0096\3\2\2\2\u0093\u0094\7#\2\2\u0094\u0096\7$\2\2\u0095\u008f\3\2\2"+
+               
"\2\u0095\u0093\3\2\2\2\u0096\33\3\2\2\2\u0097\u0098\b\17\1\2\u0098\u009b"+
                
"\5,\27\2\u0099\u009b\5\f\7\2\u009a\u0097\3\2\2\2\u009a\u0099\3\2\2\2\u009b"+
                
"\u00a4\3\2\2\2\u009c\u009d\f\5\2\2\u009d\u009e\7\7\2\2\u009e\u00a3\5,"+
                
"\27\2\u009f\u00a0\f\3\2\2\u00a0\u00a1\7\7\2\2\u00a1\u00a3\5\f\7\2\u00a2"+
                
"\u009c\3\2\2\2\u00a2\u009f\3\2\2\2\u00a3\u00a6\3\2\2\2\u00a4\u00a2\3\2"+
                
"\2\2\u00a4\u00a5\3\2\2\2\u00a5\35\3\2\2\2\u00a6\u00a4\3\2\2\2\u00a7\u00a8"+
-               "\7 \2\2\u00a8\u00ae\7!\2\2\u00a9\u00aa\7 
\2\2\u00aa\u00ab\5\34\17\2\u00ab"+
-               
"\u00ac\7!\2\2\u00ac\u00ae\3\2\2\2\u00ad\u00a7\3\2\2\2\u00ad\u00a9\3\2"+
+               
"\7!\2\2\u00a8\u00ae\7\"\2\2\u00a9\u00aa\7!\2\2\u00aa\u00ab\5\34\17\2\u00ab"+
+               
"\u00ac\7\"\2\2\u00ac\u00ae\3\2\2\2\u00ad\u00a7\3\2\2\2\u00ad\u00a9\3\2"+
                
"\2\2\u00ae\37\3\2\2\2\u00af\u00b0\b\21\1\2\u00b0\u00b1\5,\27\2\u00b1\u00b2"+
                
"\7\25\2\2\u00b2\u00b3\5\4\3\2\u00b3\u00bc\3\2\2\2\u00b4\u00b5\f\3\2\2"+
                
"\u00b5\u00b6\7\7\2\2\u00b6\u00b7\5,\27\2\u00b7\u00b8\7\25\2\2\u00b8\u00b9"+
                
"\5\4\3\2\u00b9\u00bb\3\2\2\2\u00ba\u00b4\3\2\2\2\u00bb\u00be\3\2\2\2\u00bc"+
                
"\u00ba\3\2\2\2\u00bc\u00bd\3\2\2\2\u00bd!\3\2\2\2\u00be\u00bc\3\2\2\2"+
-               "\u00bf\u00c0\7\36\2\2\u00c0\u00c1\5 
\21\2\u00c1\u00c2\7\37\2\2\u00c2\u00c6"+
-               
"\3\2\2\2\u00c3\u00c4\7\36\2\2\u00c4\u00c6\7\37\2\2\u00c5\u00bf\3\2\2\2"+
-               
"\u00c5\u00c3\3\2\2\2\u00c6#\3\2\2\2\u00c7\u00c8\b\23\1\2\u00c8\u00c9\5"+
-               
"&\24\2\u00c9\u00d2\3\2\2\2\u00ca\u00cb\f\4\2\2\u00cb\u00cc\7\33\2\2\u00cc"+
-               
"\u00d1\5&\24\2\u00cd\u00ce\f\3\2\2\u00ce\u00cf\7\32\2\2\u00cf\u00d1\5"+
-               
"&\24\2\u00d0\u00ca\3\2\2\2\u00d0\u00cd\3\2\2\2\u00d1\u00d4\3\2\2\2\u00d2"+
-               
"\u00d0\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3%\3\2\2\2\u00d4\u00d2\3\2\2\2"+
-               
"\u00d5\u00d6\b\24\1\2\u00d6\u00d7\5*\26\2\u00d7\u00e0\3\2\2\2\u00d8\u00d9"+
-               
"\f\4\2\2\u00d9\u00da\7\35\2\2\u00da\u00df\5&\24\5\u00db\u00dc\f\3\2\2"+
-               
"\u00dc\u00dd\7\34\2\2\u00dd\u00df\5&\24\4\u00de\u00d8\3\2\2\2\u00de\u00db"+
-               
"\3\2\2\2\u00df\u00e2\3\2\2\2\u00e0\u00de\3\2\2\2\u00e0\u00e1\3\2\2\2\u00e1"+
-               
"\'\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3\u00e4\7+\2\2\u00e4\u00e5\5\32\16"+
-               
"\2\u00e5)\3\2\2\2\u00e6\u00f5\5(\25\2\u00e7\u00f5\7(\2\2\u00e8\u00f5\7"+
-               
"\'\2\2\u00e9\u00f5\7*\2\2\u00ea\u00f5\7)\2\2\u00eb\u00f5\7+\2\2\u00ec"+
-               
"\u00ed\7\"\2\2\u00ed\u00ee\5$\23\2\u00ee\u00ef\7#\2\2\u00ef\u00f5\3\2"+
-               
"\2\2\u00f0\u00f1\7\"\2\2\u00f1\u00f2\5\f\7\2\u00f2\u00f3\7#\2\2\u00f3"+
-               
"\u00f5\3\2\2\2\u00f4\u00e6\3\2\2\2\u00f4\u00e7\3\2\2\2\u00f4\u00e8\3\2"+
-               
"\2\2\u00f4\u00e9\3\2\2\2\u00f4\u00ea\3\2\2\2\u00f4\u00eb\3\2\2\2\u00f4"+
-               
"\u00ec\3\2\2\2\u00f4\u00f0\3\2\2\2\u00f5+\3\2\2\2\u00f6\u0107\t\3\2\2"+
-               
"\u00f7\u0107\5\60\31\2\u00f8\u0107\5.\30\2\u00f9\u0107\5$\23\2\u00fa\u0107"+
-               
"\7,\2\2\u00fb\u0107\5\36\20\2\u00fc\u0107\5\"\22\2\u00fd\u0107\7\31\2"+
-               
"\2\u00fe\u00ff\7%\2\2\u00ff\u0100\7\"\2\2\u0100\u0101\7+\2\2\u0101\u0107"+
-               
"\7#\2\2\u0102\u0103\7\"\2\2\u0103\u0104\5\f\7\2\u0104\u0105\7#\2\2\u0105"+
-               
"\u0107\3\2\2\2\u0106\u00f6\3\2\2\2\u0106\u00f7\3\2\2\2\u0106\u00f8\3\2"+
-               
"\2\2\u0106\u00f9\3\2\2\2\u0106\u00fa\3\2\2\2\u0106\u00fb\3\2\2\2\u0106"+
-               
"\u00fc\3\2\2\2\u0106\u00fd\3\2\2\2\u0106\u00fe\3\2\2\2\u0106\u0102\3\2"+
-               
"\2\2\u0107-\3\2\2\2\u0108\u0109\7\"\2\2\u0109\u010a\7#\2\2\u010a\u010b"+
-               
"\7\4\2\2\u010b\u010c\5\4\3\2\u010c/\3\2\2\2\u010d\u010e\7\"\2\2\u010e"+
-               
"\u010f\5\62\32\2\u010f\u0110\7#\2\2\u0110\u0111\7\4\2\2\u0111\u0112\5"+
-               
"\4\3\2\u0112\u0118\3\2\2\2\u0113\u0114\5\64\33\2\u0114\u0115\7\4\2\2\u0115"+
-               
"\u0116\5\4\3\2\u0116\u0118\3\2\2\2\u0117\u010d\3\2\2\2\u0117\u0113\3\2"+
-               
"\2\2\u0118\61\3\2\2\2\u0119\u011e\5\66\34\2\u011a\u011b\7\7\2\2\u011b"+
-               
"\u011d\5\66\34\2\u011c\u011a\3\2\2\2\u011d\u0120\3\2\2\2\u011e\u011c\3"+
-               
"\2\2\2\u011e\u011f\3\2\2\2\u011f\63\3\2\2\2\u0120\u011e\3\2\2\2\u0121"+
-               
"\u0122\5\66\34\2\u0122\65\3\2\2\2\u0123\u0124\7+\2\2\u0124\67\3\2\2\2"+
-               
"\30EZeis\u0080\u0088\u0095\u009a\u00a2\u00a4\u00ad\u00bc\u00c5\u00d0\u00d2"+
-               "\u00de\u00e0\u00f4\u0106\u0117\u011e";
+               "\u00bf\u00c0\7\37\2\2\u00c0\u00c1\5 \21\2\u00c1\u00c2\7 
\2\2\u00c2\u00c6"+
+               "\3\2\2\2\u00c3\u00c4\7\37\2\2\u00c4\u00c6\7 
\2\2\u00c5\u00bf\3\2\2\2\u00c5"+
+               
"\u00c3\3\2\2\2\u00c6#\3\2\2\2\u00c7\u00c8\b\23\1\2\u00c8\u00c9\5&\24\2"+
+               
"\u00c9\u00d2\3\2\2\2\u00ca\u00cb\f\4\2\2\u00cb\u00cc\7\34\2\2\u00cc\u00d1"+
+               
"\5&\24\2\u00cd\u00ce\f\3\2\2\u00ce\u00cf\7\33\2\2\u00cf\u00d1\5&\24\2"+
+               
"\u00d0\u00ca\3\2\2\2\u00d0\u00cd\3\2\2\2\u00d1\u00d4\3\2\2\2\u00d2\u00d0"+
+               
"\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3%\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d5"+
+               
"\u00d6\b\24\1\2\u00d6\u00d7\5*\26\2\u00d7\u00e0\3\2\2\2\u00d8\u00d9\f"+
+               
"\4\2\2\u00d9\u00da\7\36\2\2\u00da\u00df\5&\24\5\u00db\u00dc\f\3\2\2\u00dc"+
+               
"\u00dd\7\35\2\2\u00dd\u00df\5&\24\4\u00de\u00d8\3\2\2\2\u00de\u00db\3"+
+               
"\2\2\2\u00df\u00e2\3\2\2\2\u00e0\u00de\3\2\2\2\u00e0\u00e1\3\2\2\2\u00e1"+
+               
"\'\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3\u00e4\7,\2\2\u00e4\u00e5\5\32\16"+
+               
"\2\u00e5)\3\2\2\2\u00e6\u00f6\5(\25\2\u00e7\u00f6\7)\2\2\u00e8\u00f6\7"+
+               
"(\2\2\u00e9\u00f6\7+\2\2\u00ea\u00f6\7*\2\2\u00eb\u00f6\7,\2\2\u00ec\u00f6"+
+               
"\7\32\2\2\u00ed\u00ee\7#\2\2\u00ee\u00ef\5$\23\2\u00ef\u00f0\7$\2\2\u00f0"+
+               
"\u00f6\3\2\2\2\u00f1\u00f2\7#\2\2\u00f2\u00f3\5\f\7\2\u00f3\u00f4\7$\2"+
+               
"\2\u00f4\u00f6\3\2\2\2\u00f5\u00e6\3\2\2\2\u00f5\u00e7\3\2\2\2\u00f5\u00e8"+
+               
"\3\2\2\2\u00f5\u00e9\3\2\2\2\u00f5\u00ea\3\2\2\2\u00f5\u00eb\3\2\2\2\u00f5"+
+               
"\u00ec\3\2\2\2\u00f5\u00ed\3\2\2\2\u00f5\u00f1\3\2\2\2\u00f6+\3\2\2\2"+
+               
"\u00f7\u0108\t\3\2\2\u00f8\u0108\5\60\31\2\u00f9\u0108\5.\30\2\u00fa\u0108"+
+               
"\5$\23\2\u00fb\u0108\7-\2\2\u00fc\u0108\5\36\20\2\u00fd\u0108\5\"\22\2"+
+               
"\u00fe\u0108\7\31\2\2\u00ff\u0100\7&\2\2\u0100\u0101\7#\2\2\u0101\u0102"+
+               
"\7,\2\2\u0102\u0108\7$\2\2\u0103\u0104\7#\2\2\u0104\u0105\5\f\7\2\u0105"+
+               
"\u0106\7$\2\2\u0106\u0108\3\2\2\2\u0107\u00f7\3\2\2\2\u0107\u00f8\3\2"+
+               
"\2\2\u0107\u00f9\3\2\2\2\u0107\u00fa\3\2\2\2\u0107\u00fb\3\2\2\2\u0107"+
+               
"\u00fc\3\2\2\2\u0107\u00fd\3\2\2\2\u0107\u00fe\3\2\2\2\u0107\u00ff\3\2"+
+               
"\2\2\u0107\u0103\3\2\2\2\u0108-\3\2\2\2\u0109\u010a\7#\2\2\u010a\u010b"+
+               
"\7$\2\2\u010b\u010c\7\4\2\2\u010c\u010d\5\4\3\2\u010d/\3\2\2\2\u010e\u010f"+
+               
"\7#\2\2\u010f\u0110\5\62\32\2\u0110\u0111\7$\2\2\u0111\u0112\7\4\2\2\u0112"+
+               
"\u0113\5\4\3\2\u0113\u0119\3\2\2\2\u0114\u0115\5\64\33\2\u0115\u0116\7"+
+               
"\4\2\2\u0116\u0117\5\4\3\2\u0117\u0119\3\2\2\2\u0118\u010e\3\2\2\2\u0118"+
+               
"\u0114\3\2\2\2\u0119\61\3\2\2\2\u011a\u011f\5\66\34\2\u011b\u011c\7\7"+
+               
"\2\2\u011c\u011e\5\66\34\2\u011d\u011b\3\2\2\2\u011e\u0121\3\2\2\2\u011f"+
+               
"\u011d\3\2\2\2\u011f\u0120\3\2\2\2\u0120\63\3\2\2\2\u0121\u011f\3\2\2"+
+               
"\2\u0122\u0123\5\66\34\2\u0123\65\3\2\2\2\u0124\u0125\7,\2\2\u0125\67"+
+               
"\3\2\2\2\30EZeis\u0080\u0088\u0095\u009a\u00a2\u00a4\u00ad\u00bc\u00c5"+
+               "\u00d0\u00d2\u00de\u00e0\u00f5\u0107\u0118\u011f";
        public static final ATN _ATN =
                new ATNDeserializer().deserialize(_serializedATN.toCharArray());
        static {

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/MathFunctions.java
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/MathFunctions.java
 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/MathFunctions.java
index a5ac366..04116d2 100644
--- 
a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/MathFunctions.java
+++ 
b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/MathFunctions.java
@@ -21,6 +21,7 @@ package org.apache.metron.stellar.dsl.functions;
 
 import org.apache.metron.stellar.common.utils.math.MathOperations;
 import org.apache.metron.stellar.common.utils.math.StellarMathFunction;
+import org.apache.metron.stellar.dsl.BaseStellarFunction;
 import org.apache.metron.stellar.dsl.Context;
 import org.apache.metron.stellar.dsl.ParseException;
 import org.apache.metron.stellar.dsl.Stellar;
@@ -194,4 +195,29 @@ public class MathFunctions {
       super(MathOperations.ROUND);
     }
   }
+
+  @Stellar(name = "IS_NAN",
+      description = "Evaluates if the passed number is NaN.  The number is 
evaluated as a double",
+       params = {
+        "number - number to evaluate"
+       },
+       returns = "True if the value is NaN, false if it is not")
+  public static class IsNaN extends BaseStellarFunction {
+
+    @Override
+    public Object apply(List<Object> args) {
+
+      if (args == null || args.size() != 1) {
+        throw new IllegalStateException(
+            "IS_NAN expects one: [number] ");
+      }
+
+      Object obj = args.get(0);
+      if (obj instanceof Number) {
+        return Double.isNaN(((Number) obj).doubleValue());
+      } else {
+        throw new ParseException("IS_NAN() expects a number argument");
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java
 
b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java
index 2b20feb..21b8a1a 100644
--- 
a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java
+++ 
b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java
@@ -251,6 +251,142 @@ public class BasicStellarTest {
   }
 
   @Test
+  public void testNaN(){
+    // any equity is false
+    // https://docs.oracle.com/javase/specs/jls/se6/html/typesValues.html
+    {
+      String query = "NaN == NaN";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "5.0 == NaN";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NULL == NaN";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "'metron' == NaN";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+
+    // any inequity is true
+    {
+      String query = "NaN != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "5 != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "'metron' != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+
+    //  any > >= < <= is false
+    {
+      String query = "NaN > 5";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN < 5";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN >= 5";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN <= 5";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN > NaN";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN < NaN";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN >= NaN";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN <= NaN";
+      Assert.assertFalse(runPredicate(query,new HashMap<>()));
+    }
+
+    // all operations
+    {
+      String query = "(5 + NaN) != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "5 + NaN";
+      Assert.assertTrue(run(query,new HashMap<>()).toString().equals("NaN"));
+    }
+    {
+      String query = "(5 - NaN) != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "5 - NaN";
+      Assert.assertTrue(run(query,new HashMap<>()).toString().equals("NaN"));
+    }
+    {
+      String query = "(5 / NaN) != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "5 / NaN";
+      Assert.assertTrue(run(query,new HashMap<>()).toString().equals("NaN"));
+    }
+    {
+      String query = "(5 * NaN) != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "5 * NaN";
+      Assert.assertTrue(run(query,new HashMap<>()).toString().equals("NaN"));
+    }
+    {
+      String query = "(NaN + NaN) != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN + NaN";
+      Assert.assertTrue(run(query,new HashMap<>()).toString().equals("NaN"));
+    }
+    {
+      String query = "(NaN - NaN) != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN - NaN";
+      Assert.assertTrue(run(query,new HashMap<>()).toString().equals("NaN"));
+    }
+    {
+      String query = "(NaN * NaN) != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN * NaN";
+      Assert.assertTrue(run(query,new HashMap<>()).toString().equals("NaN"));
+    }
+    {
+      String query = "(NaN / NaN) != NaN";
+      Assert.assertTrue(runPredicate(query,new HashMap<>()));
+    }
+    {
+      String query = "NaN / NaN";
+      Assert.assertTrue(run(query,new HashMap<>()).toString().equals("NaN"));
+    }
+  }
+
+  @Test
   public void testMapConstant() {
     {
       String query = "MAP_GET('bar', { 'foo' : 1, 'bar' : 'bar'})";

http://git-wip-us.apache.org/repos/asf/metron/blob/cc84b6a5/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MathFunctionsTest.java
----------------------------------------------------------------------
diff --git 
a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MathFunctionsTest.java
 
b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MathFunctionsTest.java
index 3f0886c..ad15259 100644
--- 
a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MathFunctionsTest.java
+++ 
b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MathFunctionsTest.java
@@ -19,11 +19,14 @@
  */
 package org.apache.metron.stellar.dsl.functions;
 
+import static 
org.apache.metron.stellar.common.utils.StellarProcessorUtils.runPredicate;
+
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import org.apache.metron.stellar.common.StellarProcessor;
 import org.apache.metron.stellar.dsl.Context;
 import org.apache.metron.stellar.dsl.DefaultVariableResolver;
+import org.apache.metron.stellar.dsl.ParseException;
 import org.apache.metron.stellar.dsl.StellarFunctions;
 import org.junit.Assert;
 import org.junit.Test;
@@ -168,6 +171,23 @@ public class MathFunctionsTest {
     testLog("LOG10", 10);
   }
 
+  @Test
+  public void testIsNaN() {
+    Assert.assertTrue(runPredicate("IS_NAN(NaN)", new HashMap<>()));
+    Assert.assertFalse(runPredicate("IS_NAN(1.0)", new HashMap<>()));
+    Assert.assertTrue(runPredicate("IS_NAN(0.0/0.0)",new HashMap<>()));
+  }
+
+  @Test(expected = ParseException.class)
+  public void testIsNanWithNotNumberType() {
+    runPredicate("IS_NAN('casey')", new HashMap<>());
+  }
+
+  @Test(expected= ParseException.class)
+  public void testIsNanWithNoArgs() {
+    runPredicate("IS_NAN()", new HashMap<>());
+  }
+
   public void assertValues(String func, Map<Double, Double> expected) {
     for(Map.Entry<Double, Double> test : expected.entrySet()) {
       for(String expr : ImmutableList.of(func + "(value)"
@@ -176,7 +196,7 @@ public class MathFunctionsTest {
          )
       {
         if (Double.isNaN(test.getValue())) {
-          Assert.assertTrue(expr + " != NaN, where value == " + test.getKey(), 
Double.isNaN(toDouble(run(expr, ImmutableMap.of("value", 
test.getKey(),"NaN",Double.NaN)))));
+          Assert.assertTrue(expr + " != NaN, where value == " + test.getKey(), 
Double.isNaN(toDouble(run(expr, ImmutableMap.of("value", test.getKey())))));
         } else {
           Assert.assertEquals(expr + " != " + test.getValue() + " (where value 
== " + test.getKey() + ")", test.getValue(), toDouble(run(expr, 
ImmutableMap.of("value", test.getKey()))), EPSILON);
         }

Reply via email to