metron-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From o...@apache.org
Subject metron git commit: METRON-1079 STELLAR NaN should be a keyword (ottobackwards) closes apache/metron#681
Date Fri, 29 Sep 2017 20:46:38 GMT
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 <ottobackwards@gmail.com>
Authored: Fri Sep 29 16:18:46 2017 -0400
Committer: otto <otto@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);
         }


Mime
View raw message