You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by ce...@apache.org on 2017/04/10 13:19:56 UTC

[1/2] incubator-metron git commit: METRON-831: Add lambda expressions and rudimentary functional programming primitives to Stellar. This closes apache/incubator-metron#517

Repository: incubator-metron
Updated Branches:
  refs/heads/master 7e21ad3c7 -> ab80e7b18


http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java
index b8f5173..51c99e4 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarParser.java
@@ -37,37 +37,42 @@ public class StellarParser extends Parser {
 	protected static final PredictionContextCache _sharedContextCache =
 		new PredictionContextCache();
 	public static final int
-		DOUBLE_QUOTE=1, SINGLE_QUOTE=2, COMMA=3, PERIOD=4, AND=5, OR=6, NOT=7, 
-		TRUE=8, FALSE=9, EQ=10, NEQ=11, LT=12, LTE=13, GT=14, GTE=15, QUESTION=16, 
-		COLON=17, IF=18, THEN=19, ELSE=20, NULL=21, MINUS=22, PLUS=23, DIV=24, 
-		MUL=25, LBRACE=26, RBRACE=27, LBRACKET=28, RBRACKET=29, LPAREN=30, RPAREN=31, 
-		IN=32, NIN=33, EXISTS=34, EXPONENT=35, INT_LITERAL=36, DOUBLE_LITERAL=37, 
-		FLOAT_LITERAL=38, LONG_LITERAL=39, IDENTIFIER=40, STRING_LITERAL=41, COMMENT=42, 
-		WS=43;
+		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;
 	public static final int
 		RULE_transformation = 0, RULE_transformation_expr = 1, RULE_conditional_expr = 2, 
 		RULE_logical_expr = 3, RULE_b_expr = 4, RULE_in_expr = 5, RULE_comparison_expr = 6, 
 		RULE_transformation_entity = 7, RULE_comp_operator = 8, RULE_func_args = 9, 
 		RULE_op_list = 10, RULE_list_entity = 11, RULE_kv_list = 12, RULE_map_entity = 13, 
 		RULE_arithmetic_expr = 14, RULE_arithmetic_expr_mul = 15, RULE_functions = 16, 
-		RULE_arithmetic_operands = 17, RULE_identifier_operand = 18;
+		RULE_arithmetic_operands = 17, RULE_identifier_operand = 18, RULE_lambda_without_args = 19, 
+		RULE_lambda_with_args = 20, RULE_lambda_variables = 21, RULE_single_lambda_variable = 22, 
+		RULE_lambda_variable = 23;
 	public static final String[] ruleNames = {
 		"transformation", "transformation_expr", "conditional_expr", "logical_expr", 
 		"b_expr", "in_expr", "comparison_expr", "transformation_entity", "comp_operator", 
 		"func_args", "op_list", "list_entity", "kv_list", "map_entity", "arithmetic_expr", 
-		"arithmetic_expr_mul", "functions", "arithmetic_operands", "identifier_operand"
+		"arithmetic_expr_mul", "functions", "arithmetic_operands", "identifier_operand", 
+		"lambda_without_args", "lambda_with_args", "lambda_variables", "single_lambda_variable", 
+		"lambda_variable"
 	};
 
 	private static final String[] _LITERAL_NAMES = {
-		null, "'\"'", "'''", "','", "'.'", null, null, null, null, null, "'=='", 
-		"'!='", "'<'", "'<='", "'>'", "'>='", "'?'", "':'", null, null, null, 
-		null, "'-'", "'+'", "'/'", "'*'", "'{'", "'}'", "'['", "']'", "'('", "')'"
+		null, null, "'->'", "'\"'", "'''", "','", "'.'", null, null, null, null, 
+		null, "'=='", "'!='", "'<'", "'<='", "'>'", "'>='", "'?'", "':'", null, 
+		null, null, null, "'-'", "'+'", "'/'", "'*'", "'{'", "'}'", "'['", "']'", 
+		"'('", "')'"
 	};
 	private static final String[] _SYMBOLIC_NAMES = {
-		null, "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", "IN", 
+		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", 
 		"NIN", "EXISTS", "EXPONENT", "INT_LITERAL", "DOUBLE_LITERAL", "FLOAT_LITERAL", 
 		"LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS"
 	};
@@ -145,9 +150,9 @@ public class StellarParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(38);
+			setState(48);
 			transformation_expr();
-			setState(39);
+			setState(49);
 			match(EOF);
 			}
 		}
@@ -278,13 +283,13 @@ public class StellarParser extends Parser {
 		Transformation_exprContext _localctx = new Transformation_exprContext(_ctx, getState());
 		enterRule(_localctx, 2, RULE_transformation_expr);
 		try {
-			setState(51);
+			setState(61);
 			switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) {
 			case 1:
 				_localctx = new ConditionalExprContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(41);
+				setState(51);
 				conditional_expr();
 				}
 				break;
@@ -292,11 +297,11 @@ public class StellarParser extends Parser {
 				_localctx = new TransformationExprContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(42);
+				setState(52);
 				match(LPAREN);
-				setState(43);
+				setState(53);
 				transformation_expr();
-				setState(44);
+				setState(54);
 				match(RPAREN);
 				}
 				break;
@@ -304,7 +309,7 @@ public class StellarParser extends Parser {
 				_localctx = new ArithExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(46);
+				setState(56);
 				arithmetic_expr(0);
 				}
 				break;
@@ -312,7 +317,7 @@ public class StellarParser extends Parser {
 				_localctx = new TransformationEntityContext(_localctx);
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(47);
+				setState(57);
 				transformation_entity();
 				}
 				break;
@@ -320,7 +325,7 @@ public class StellarParser extends Parser {
 				_localctx = new ComparisonExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(48);
+				setState(58);
 				comparison_expr(0);
 				}
 				break;
@@ -328,7 +333,7 @@ public class StellarParser extends Parser {
 				_localctx = new LogicalExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(49);
+				setState(59);
 				logical_expr();
 				}
 				break;
@@ -336,7 +341,7 @@ public class StellarParser extends Parser {
 				_localctx = new InExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(50);
+				setState(60);
 				in_expr();
 				}
 				break;
@@ -414,7 +419,7 @@ public class StellarParser extends Parser {
 		Conditional_exprContext _localctx = new Conditional_exprContext(_ctx, getState());
 		enterRule(_localctx, 4, RULE_conditional_expr);
 		try {
-			setState(66);
+			setState(76);
 			switch (_input.LA(1)) {
 			case NOT:
 			case TRUE:
@@ -433,15 +438,15 @@ public class StellarParser extends Parser {
 				_localctx = new TernaryFuncWithoutIfContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(53);
+				setState(63);
 				logical_expr();
-				setState(54);
+				setState(64);
 				match(QUESTION);
-				setState(55);
+				setState(65);
 				transformation_expr();
-				setState(56);
+				setState(66);
 				match(COLON);
-				setState(57);
+				setState(67);
 				transformation_expr();
 				}
 				break;
@@ -449,17 +454,17 @@ public class StellarParser extends Parser {
 				_localctx = new TernaryFuncWithIfContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(59);
+				setState(69);
 				match(IF);
-				setState(60);
+				setState(70);
 				logical_expr();
-				setState(61);
+				setState(71);
 				match(THEN);
-				setState(62);
+				setState(72);
 				transformation_expr();
-				setState(63);
+				setState(73);
 				match(ELSE);
-				setState(64);
+				setState(74);
 				transformation_expr();
 				}
 				break;
@@ -544,17 +549,17 @@ public class StellarParser extends Parser {
 		Logical_exprContext _localctx = new Logical_exprContext(_ctx, getState());
 		enterRule(_localctx, 6, RULE_logical_expr);
 		try {
-			setState(77);
+			setState(87);
 			switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) {
 			case 1:
 				_localctx = new LogicalExpressionAndContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(68);
+				setState(78);
 				b_expr();
-				setState(69);
+				setState(79);
 				match(AND);
-				setState(70);
+				setState(80);
 				logical_expr();
 				}
 				break;
@@ -562,11 +567,11 @@ public class StellarParser extends Parser {
 				_localctx = new LogicalExpressionOrContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(72);
+				setState(82);
 				b_expr();
-				setState(73);
+				setState(83);
 				match(OR);
-				setState(74);
+				setState(84);
 				logical_expr();
 				}
 				break;
@@ -574,7 +579,7 @@ public class StellarParser extends Parser {
 				_localctx = new BoleanExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(76);
+				setState(86);
 				b_expr();
 				}
 				break;
@@ -616,19 +621,19 @@ public class StellarParser extends Parser {
 		B_exprContext _localctx = new B_exprContext(_ctx, getState());
 		enterRule(_localctx, 8, RULE_b_expr);
 		try {
-			setState(81);
+			setState(91);
 			switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(79);
+				setState(89);
 				comparison_expr(0);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(80);
+				setState(90);
 				in_expr();
 				}
 				break;
@@ -697,17 +702,17 @@ public class StellarParser extends Parser {
 		In_exprContext _localctx = new In_exprContext(_ctx, getState());
 		enterRule(_localctx, 10, RULE_in_expr);
 		try {
-			setState(91);
+			setState(101);
 			switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
 			case 1:
 				_localctx = new InExpressionStatementContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(83);
+				setState(93);
 				identifier_operand();
-				setState(84);
+				setState(94);
 				match(IN);
-				setState(85);
+				setState(95);
 				b_expr();
 				}
 				break;
@@ -715,11 +720,11 @@ public class StellarParser extends Parser {
 				_localctx = new NInExpressionStatementContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(87);
+				setState(97);
 				identifier_operand();
-				setState(88);
+				setState(98);
 				match(NIN);
-				setState(89);
+				setState(99);
 				b_expr();
 				}
 				break;
@@ -830,7 +835,7 @@ public class StellarParser extends Parser {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(104);
+			setState(114);
 			switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) {
 			case 1:
 				{
@@ -838,13 +843,13 @@ public class StellarParser extends Parser {
 				_ctx = _localctx;
 				_prevctx = _localctx;
 
-				setState(94);
+				setState(104);
 				match(NOT);
-				setState(95);
+				setState(105);
 				match(LPAREN);
-				setState(96);
+				setState(106);
 				logical_expr();
-				setState(97);
+				setState(107);
 				match(RPAREN);
 				}
 				break;
@@ -853,11 +858,11 @@ public class StellarParser extends Parser {
 				_localctx = new ComparisonExpressionParensContext(_localctx);
 				_ctx = _localctx;
 				_prevctx = _localctx;
-				setState(99);
+				setState(109);
 				match(LPAREN);
-				setState(100);
+				setState(110);
 				logical_expr();
-				setState(101);
+				setState(111);
 				match(RPAREN);
 				}
 				break;
@@ -866,13 +871,13 @@ public class StellarParser extends Parser {
 				_localctx = new OperandContext(_localctx);
 				_ctx = _localctx;
 				_prevctx = _localctx;
-				setState(103);
+				setState(113);
 				identifier_operand();
 				}
 				break;
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(112);
+			setState(122);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,6,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -883,16 +888,16 @@ public class StellarParser extends Parser {
 					{
 					_localctx = new ComparisonExpressionWithOperatorContext(new Comparison_exprContext(_parentctx, _parentState));
 					pushNewRecursionContext(_localctx, _startState, RULE_comparison_expr);
-					setState(106);
+					setState(116);
 					if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
-					setState(107);
+					setState(117);
 					comp_operator();
-					setState(108);
+					setState(118);
 					comparison_expr(5);
 					}
 					} 
 				}
-				setState(114);
+				setState(124);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,6,_ctx);
 			}
@@ -933,7 +938,7 @@ public class StellarParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(115);
+			setState(125);
 			identifier_operand();
 			}
 		}
@@ -985,7 +990,7 @@ public class StellarParser extends Parser {
 			_localctx = new ComparisonOpContext(_localctx);
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(117);
+			setState(127);
 			_la = _input.LA(1);
 			if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQ) | (1L << NEQ) | (1L << LT) | (1L << LTE) | (1L << GT) | (1L << GTE))) != 0)) ) {
 			_errHandler.recoverInline(this);
@@ -1029,25 +1034,25 @@ public class StellarParser extends Parser {
 		Func_argsContext _localctx = new Func_argsContext(_ctx, getState());
 		enterRule(_localctx, 18, RULE_func_args);
 		try {
-			setState(125);
+			setState(135);
 			switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(119);
+				setState(129);
 				match(LPAREN);
-				setState(120);
+				setState(130);
 				op_list(0);
-				setState(121);
+				setState(131);
 				match(RPAREN);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(123);
+				setState(133);
 				match(LPAREN);
-				setState(124);
+				setState(134);
 				match(RPAREN);
 				}
 				break;
@@ -1104,23 +1109,23 @@ public class StellarParser extends Parser {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(130);
+			setState(140);
 			switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) {
 			case 1:
 				{
-				setState(128);
+				setState(138);
 				identifier_operand();
 				}
 				break;
 			case 2:
 				{
-				setState(129);
+				setState(139);
 				conditional_expr();
 				}
 				break;
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(140);
+			setState(150);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,10,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1128,17 +1133,17 @@ public class StellarParser extends Parser {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
 					_prevctx = _localctx;
 					{
-					setState(138);
+					setState(148);
 					switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) {
 					case 1:
 						{
 						_localctx = new Op_listContext(_parentctx, _parentState);
 						pushNewRecursionContext(_localctx, _startState, RULE_op_list);
-						setState(132);
+						setState(142);
 						if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
-						setState(133);
+						setState(143);
 						match(COMMA);
-						setState(134);
+						setState(144);
 						identifier_operand();
 						}
 						break;
@@ -1146,18 +1151,18 @@ public class StellarParser extends Parser {
 						{
 						_localctx = new Op_listContext(_parentctx, _parentState);
 						pushNewRecursionContext(_localctx, _startState, RULE_op_list);
-						setState(135);
+						setState(145);
 						if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-						setState(136);
+						setState(146);
 						match(COMMA);
-						setState(137);
+						setState(147);
 						conditional_expr();
 						}
 						break;
 					}
 					} 
 				}
-				setState(142);
+				setState(152);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,10,_ctx);
 			}
@@ -1176,10 +1181,10 @@ public class StellarParser extends Parser {
 
 	public static class List_entityContext extends ParserRuleContext {
 		public TerminalNode LBRACKET() { return getToken(StellarParser.LBRACKET, 0); }
+		public TerminalNode RBRACKET() { return getToken(StellarParser.RBRACKET, 0); }
 		public Op_listContext op_list() {
 			return getRuleContext(Op_listContext.class,0);
 		}
-		public TerminalNode RBRACKET() { return getToken(StellarParser.RBRACKET, 0); }
 		public List_entityContext(ParserRuleContext parent, int invokingState) {
 			super(parent, invokingState);
 		}
@@ -1198,25 +1203,25 @@ public class StellarParser extends Parser {
 		List_entityContext _localctx = new List_entityContext(_ctx, getState());
 		enterRule(_localctx, 22, RULE_list_entity);
 		try {
-			setState(149);
+			setState(159);
 			switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(143);
+				setState(153);
 				match(LBRACKET);
-				setState(144);
-				op_list(0);
-				setState(145);
+				setState(154);
 				match(RBRACKET);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(147);
+				setState(155);
 				match(LBRACKET);
-				setState(148);
+				setState(156);
+				op_list(0);
+				setState(157);
 				match(RBRACKET);
 				}
 				break;
@@ -1275,15 +1280,15 @@ public class StellarParser extends Parser {
 			enterOuterAlt(_localctx, 1);
 			{
 			{
-			setState(152);
+			setState(162);
 			identifier_operand();
-			setState(153);
+			setState(163);
 			match(COLON);
-			setState(154);
+			setState(164);
 			transformation_expr();
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(164);
+			setState(174);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,12,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1294,20 +1299,20 @@ public class StellarParser extends Parser {
 					{
 					_localctx = new Kv_listContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_kv_list);
-					setState(156);
+					setState(166);
 					if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-					setState(157);
+					setState(167);
 					match(COMMA);
-					setState(158);
+					setState(168);
 					identifier_operand();
-					setState(159);
+					setState(169);
 					match(COLON);
-					setState(160);
+					setState(170);
 					transformation_expr();
 					}
 					} 
 				}
-				setState(166);
+				setState(176);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,12,_ctx);
 			}
@@ -1348,25 +1353,25 @@ public class StellarParser extends Parser {
 		Map_entityContext _localctx = new Map_entityContext(_ctx, getState());
 		enterRule(_localctx, 26, RULE_map_entity);
 		try {
-			setState(173);
+			setState(183);
 			switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(167);
+				setState(177);
 				match(LBRACE);
-				setState(168);
+				setState(178);
 				kv_list(0);
-				setState(169);
+				setState(179);
 				match(RBRACE);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(171);
+				setState(181);
 				match(LBRACE);
-				setState(172);
+				setState(182);
 				match(RBRACE);
 				}
 				break;
@@ -1465,11 +1470,11 @@ public class StellarParser extends Parser {
 			_ctx = _localctx;
 			_prevctx = _localctx;
 
-			setState(176);
+			setState(186);
 			arithmetic_expr_mul(0);
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(186);
+			setState(196);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,15,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1477,17 +1482,17 @@ public class StellarParser extends Parser {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
 					_prevctx = _localctx;
 					{
-					setState(184);
+					setState(194);
 					switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
 					case 1:
 						{
 						_localctx = new ArithExpr_plusContext(new Arithmetic_exprContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_arithmetic_expr);
-						setState(178);
+						setState(188);
 						if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
-						setState(179);
+						setState(189);
 						match(PLUS);
-						setState(180);
+						setState(190);
 						arithmetic_expr_mul(0);
 						}
 						break;
@@ -1495,18 +1500,18 @@ public class StellarParser extends Parser {
 						{
 						_localctx = new ArithExpr_minusContext(new Arithmetic_exprContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_arithmetic_expr);
-						setState(181);
+						setState(191);
 						if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-						setState(182);
+						setState(192);
 						match(MINUS);
-						setState(183);
+						setState(193);
 						arithmetic_expr_mul(0);
 						}
 						break;
 					}
 					} 
 				}
-				setState(188);
+				setState(198);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,15,_ctx);
 			}
@@ -1605,11 +1610,11 @@ public class StellarParser extends Parser {
 			_ctx = _localctx;
 			_prevctx = _localctx;
 
-			setState(190);
+			setState(200);
 			arithmetic_operands();
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(200);
+			setState(210);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,17,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1617,17 +1622,17 @@ public class StellarParser extends Parser {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
 					_prevctx = _localctx;
 					{
-					setState(198);
+					setState(208);
 					switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) {
 					case 1:
 						{
 						_localctx = new ArithExpr_mulContext(new Arithmetic_expr_mulContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_arithmetic_expr_mul);
-						setState(192);
+						setState(202);
 						if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
-						setState(193);
+						setState(203);
 						match(MUL);
-						setState(194);
+						setState(204);
 						arithmetic_expr_mul(3);
 						}
 						break;
@@ -1635,18 +1640,18 @@ public class StellarParser extends Parser {
 						{
 						_localctx = new ArithExpr_divContext(new Arithmetic_expr_mulContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_arithmetic_expr_mul);
-						setState(195);
+						setState(205);
 						if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-						setState(196);
+						setState(206);
 						match(DIV);
-						setState(197);
+						setState(207);
 						arithmetic_expr_mul(2);
 						}
 						break;
 					}
 					} 
 				}
-				setState(202);
+				setState(212);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,17,_ctx);
 			}
@@ -1697,9 +1702,9 @@ public class StellarParser extends Parser {
 			_localctx = new TransformationFuncContext(_localctx);
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(203);
+			setState(213);
 			match(IDENTIFIER);
-			setState(204);
+			setState(214);
 			func_args();
 			}
 		}
@@ -1836,13 +1841,13 @@ public class StellarParser extends Parser {
 		Arithmetic_operandsContext _localctx = new Arithmetic_operandsContext(_ctx, getState());
 		enterRule(_localctx, 34, RULE_arithmetic_operands);
 		try {
-			setState(220);
+			setState(230);
 			switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) {
 			case 1:
 				_localctx = new NumericFunctionsContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(206);
+				setState(216);
 				functions();
 				}
 				break;
@@ -1850,7 +1855,7 @@ public class StellarParser extends Parser {
 				_localctx = new DoubleLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(207);
+				setState(217);
 				match(DOUBLE_LITERAL);
 				}
 				break;
@@ -1858,7 +1863,7 @@ public class StellarParser extends Parser {
 				_localctx = new IntLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(208);
+				setState(218);
 				match(INT_LITERAL);
 				}
 				break;
@@ -1866,7 +1871,7 @@ public class StellarParser extends Parser {
 				_localctx = new LongLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(209);
+				setState(219);
 				match(LONG_LITERAL);
 				}
 				break;
@@ -1874,7 +1879,7 @@ public class StellarParser extends Parser {
 				_localctx = new FloatLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(210);
+				setState(220);
 				match(FLOAT_LITERAL);
 				}
 				break;
@@ -1882,7 +1887,7 @@ public class StellarParser extends Parser {
 				_localctx = new VariableContext(_localctx);
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(211);
+				setState(221);
 				match(IDENTIFIER);
 				}
 				break;
@@ -1890,11 +1895,11 @@ public class StellarParser extends Parser {
 				_localctx = new ParenArithContext(_localctx);
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(212);
+				setState(222);
 				match(LPAREN);
-				setState(213);
+				setState(223);
 				arithmetic_expr(0);
-				setState(214);
+				setState(224);
 				match(RPAREN);
 				}
 				break;
@@ -1902,11 +1907,11 @@ public class StellarParser extends Parser {
 				_localctx = new CondExprContext(_localctx);
 				enterOuterAlt(_localctx, 8);
 				{
-				setState(216);
+				setState(226);
 				match(LPAREN);
-				setState(217);
+				setState(227);
 				conditional_expr();
-				setState(218);
+				setState(228);
 				match(RPAREN);
 				}
 				break;
@@ -1948,6 +1953,20 @@ public class StellarParser extends Parser {
 			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitArithmeticOperands(this);
 		}
 	}
+	public static class LambdaWithArgsExprContext extends Identifier_operandContext {
+		public Lambda_with_argsContext lambda_with_args() {
+			return getRuleContext(Lambda_with_argsContext.class,0);
+		}
+		public LambdaWithArgsExprContext(Identifier_operandContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterLambdaWithArgsExpr(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitLambdaWithArgsExpr(this);
+		}
+	}
 	public static class StringLiteralContext extends Identifier_operandContext {
 		public TerminalNode STRING_LITERAL() { return getToken(StellarParser.STRING_LITERAL, 0); }
 		public StringLiteralContext(Identifier_operandContext ctx) { copyFrom(ctx); }
@@ -1960,6 +1979,20 @@ public class StellarParser extends Parser {
 			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitStringLiteral(this);
 		}
 	}
+	public static class LambdaWithoutArgsExprContext extends Identifier_operandContext {
+		public Lambda_without_argsContext lambda_without_args() {
+			return getRuleContext(Lambda_without_argsContext.class,0);
+		}
+		public LambdaWithoutArgsExprContext(Identifier_operandContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterLambdaWithoutArgsExpr(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitLambdaWithoutArgsExpr(this);
+		}
+	}
 	public static class ListContext extends Identifier_operandContext {
 		public List_entityContext list_entity() {
 			return getRuleContext(List_entityContext.class,0);
@@ -2050,13 +2083,13 @@ public class StellarParser extends Parser {
 		enterRule(_localctx, 36, RULE_identifier_operand);
 		int _la;
 		try {
-			setState(236);
+			setState(248);
 			switch ( getInterpreter().adaptivePredict(_input,19,_ctx) ) {
 			case 1:
 				_localctx = new LogicalConstContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(222);
+				setState(232);
 				_la = _input.LA(1);
 				if ( !(_la==TRUE || _la==FALSE) ) {
 				_errHandler.recoverInline(this);
@@ -2066,71 +2099,348 @@ public class StellarParser extends Parser {
 				}
 				break;
 			case 2:
-				_localctx = new ArithmeticOperandsContext(_localctx);
+				_localctx = new LambdaWithArgsExprContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(223);
-				arithmetic_expr(0);
+				setState(233);
+				lambda_with_args();
 				}
 				break;
 			case 3:
-				_localctx = new StringLiteralContext(_localctx);
+				_localctx = new LambdaWithoutArgsExprContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(224);
-				match(STRING_LITERAL);
+				setState(234);
+				lambda_without_args();
 				}
 				break;
 			case 4:
-				_localctx = new ListContext(_localctx);
+				_localctx = new ArithmeticOperandsContext(_localctx);
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(225);
-				list_entity();
+				setState(235);
+				arithmetic_expr(0);
 				}
 				break;
 			case 5:
-				_localctx = new MapConstContext(_localctx);
+				_localctx = new StringLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(226);
-				map_entity();
+				setState(236);
+				match(STRING_LITERAL);
 				}
 				break;
 			case 6:
-				_localctx = new NullConstContext(_localctx);
+				_localctx = new ListContext(_localctx);
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(227);
-				match(NULL);
+				setState(237);
+				list_entity();
 				}
 				break;
 			case 7:
-				_localctx = new ExistsFuncContext(_localctx);
+				_localctx = new MapConstContext(_localctx);
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(228);
+				setState(238);
+				map_entity();
+				}
+				break;
+			case 8:
+				_localctx = new NullConstContext(_localctx);
+				enterOuterAlt(_localctx, 8);
+				{
+				setState(239);
+				match(NULL);
+				}
+				break;
+			case 9:
+				_localctx = new ExistsFuncContext(_localctx);
+				enterOuterAlt(_localctx, 9);
+				{
+				setState(240);
 				match(EXISTS);
-				setState(229);
+				setState(241);
 				match(LPAREN);
-				setState(230);
+				setState(242);
 				match(IDENTIFIER);
-				setState(231);
+				setState(243);
 				match(RPAREN);
 				}
 				break;
-			case 8:
+			case 10:
 				_localctx = new CondExpr_parenContext(_localctx);
-				enterOuterAlt(_localctx, 8);
+				enterOuterAlt(_localctx, 10);
 				{
-				setState(232);
+				setState(244);
 				match(LPAREN);
-				setState(233);
+				setState(245);
 				conditional_expr();
-				setState(234);
+				setState(246);
+				match(RPAREN);
+				}
+				break;
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Lambda_without_argsContext extends ParserRuleContext {
+		public TerminalNode LPAREN() { return getToken(StellarParser.LPAREN, 0); }
+		public TerminalNode RPAREN() { return getToken(StellarParser.RPAREN, 0); }
+		public TerminalNode LAMBDA_OP() { return getToken(StellarParser.LAMBDA_OP, 0); }
+		public Transformation_exprContext transformation_expr() {
+			return getRuleContext(Transformation_exprContext.class,0);
+		}
+		public Lambda_without_argsContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_lambda_without_args; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterLambda_without_args(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitLambda_without_args(this);
+		}
+	}
+
+	public final Lambda_without_argsContext lambda_without_args() throws RecognitionException {
+		Lambda_without_argsContext _localctx = new Lambda_without_argsContext(_ctx, getState());
+		enterRule(_localctx, 38, RULE_lambda_without_args);
+		try {
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(250);
+			match(LPAREN);
+			setState(251);
+			match(RPAREN);
+			setState(252);
+			match(LAMBDA_OP);
+			setState(253);
+			transformation_expr();
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Lambda_with_argsContext extends ParserRuleContext {
+		public TerminalNode LPAREN() { return getToken(StellarParser.LPAREN, 0); }
+		public Lambda_variablesContext lambda_variables() {
+			return getRuleContext(Lambda_variablesContext.class,0);
+		}
+		public TerminalNode RPAREN() { return getToken(StellarParser.RPAREN, 0); }
+		public TerminalNode LAMBDA_OP() { return getToken(StellarParser.LAMBDA_OP, 0); }
+		public Transformation_exprContext transformation_expr() {
+			return getRuleContext(Transformation_exprContext.class,0);
+		}
+		public Single_lambda_variableContext single_lambda_variable() {
+			return getRuleContext(Single_lambda_variableContext.class,0);
+		}
+		public Lambda_with_argsContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_lambda_with_args; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterLambda_with_args(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitLambda_with_args(this);
+		}
+	}
+
+	public final Lambda_with_argsContext lambda_with_args() throws RecognitionException {
+		Lambda_with_argsContext _localctx = new Lambda_with_argsContext(_ctx, getState());
+		enterRule(_localctx, 40, RULE_lambda_with_args);
+		try {
+			setState(265);
+			switch (_input.LA(1)) {
+			case LPAREN:
+				enterOuterAlt(_localctx, 1);
+				{
+				setState(255);
+				match(LPAREN);
+				setState(256);
+				lambda_variables();
+				setState(257);
 				match(RPAREN);
+				setState(258);
+				match(LAMBDA_OP);
+				setState(259);
+				transformation_expr();
 				}
 				break;
+			case IDENTIFIER:
+				enterOuterAlt(_localctx, 2);
+				{
+				setState(261);
+				single_lambda_variable();
+				setState(262);
+				match(LAMBDA_OP);
+				setState(263);
+				transformation_expr();
+				}
+				break;
+			default:
+				throw new NoViableAltException(this);
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Lambda_variablesContext extends ParserRuleContext {
+		public List<Lambda_variableContext> lambda_variable() {
+			return getRuleContexts(Lambda_variableContext.class);
+		}
+		public Lambda_variableContext lambda_variable(int i) {
+			return getRuleContext(Lambda_variableContext.class,i);
+		}
+		public List<TerminalNode> COMMA() { return getTokens(StellarParser.COMMA); }
+		public TerminalNode COMMA(int i) {
+			return getToken(StellarParser.COMMA, i);
+		}
+		public Lambda_variablesContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_lambda_variables; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterLambda_variables(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitLambda_variables(this);
+		}
+	}
+
+	public final Lambda_variablesContext lambda_variables() throws RecognitionException {
+		Lambda_variablesContext _localctx = new Lambda_variablesContext(_ctx, getState());
+		enterRule(_localctx, 42, RULE_lambda_variables);
+		int _la;
+		try {
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(267);
+			lambda_variable();
+			setState(272);
+			_errHandler.sync(this);
+			_la = _input.LA(1);
+			while (_la==COMMA) {
+				{
+				{
+				setState(268);
+				match(COMMA);
+				setState(269);
+				lambda_variable();
+				}
+				}
+				setState(274);
+				_errHandler.sync(this);
+				_la = _input.LA(1);
+			}
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Single_lambda_variableContext extends ParserRuleContext {
+		public Lambda_variableContext lambda_variable() {
+			return getRuleContext(Lambda_variableContext.class,0);
+		}
+		public Single_lambda_variableContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_single_lambda_variable; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterSingle_lambda_variable(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitSingle_lambda_variable(this);
+		}
+	}
+
+	public final Single_lambda_variableContext single_lambda_variable() throws RecognitionException {
+		Single_lambda_variableContext _localctx = new Single_lambda_variableContext(_ctx, getState());
+		enterRule(_localctx, 44, RULE_single_lambda_variable);
+		try {
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(275);
+			lambda_variable();
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Lambda_variableContext extends ParserRuleContext {
+		public TerminalNode IDENTIFIER() { return getToken(StellarParser.IDENTIFIER, 0); }
+		public Lambda_variableContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_lambda_variable; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterLambda_variable(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitLambda_variable(this);
+		}
+	}
+
+	public final Lambda_variableContext lambda_variable() throws RecognitionException {
+		Lambda_variableContext _localctx = new Lambda_variableContext(_ctx, getState());
+		enterRule(_localctx, 46, RULE_lambda_variable);
+		try {
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(277);
+			match(IDENTIFIER);
 			}
 		}
 		catch (RecognitionException re) {
@@ -2202,85 +2512,100 @@ public class StellarParser extends Parser {
 	}
 
 	public static final String _serializedATN =
-		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3-\u00f1\4\2\t\2\4"+
+		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3.\u011a\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\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"+
-		"\3\5\3\66\n\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4"+
-		"E\n\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5P\n\5\3\6\3\6\5\6T\n\6\3"+
-		"\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7^\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3"+
-		"\b\3\b\3\b\3\b\5\bk\n\b\3\b\3\b\3\b\3\b\7\bq\n\b\f\b\16\bt\13\b\3\t\3"+
-		"\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\5\13\u0080\n\13\3\f\3\f\3\f\5"+
-		"\f\u0085\n\f\3\f\3\f\3\f\3\f\3\f\3\f\7\f\u008d\n\f\f\f\16\f\u0090\13\f"+
-		"\3\r\3\r\3\r\3\r\3\r\3\r\5\r\u0098\n\r\3\16\3\16\3\16\3\16\3\16\3\16\3"+
-		"\16\3\16\3\16\3\16\3\16\7\16\u00a5\n\16\f\16\16\16\u00a8\13\16\3\17\3"+
-		"\17\3\17\3\17\3\17\3\17\5\17\u00b0\n\17\3\20\3\20\3\20\3\20\3\20\3\20"+
-		"\3\20\3\20\3\20\7\20\u00bb\n\20\f\20\16\20\u00be\13\20\3\21\3\21\3\21"+
-		"\3\21\3\21\3\21\3\21\3\21\3\21\7\21\u00c9\n\21\f\21\16\21\u00cc\13\21"+
-		"\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+
-		"\3\23\3\23\3\23\5\23\u00df\n\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24"+
-		"\3\24\3\24\3\24\3\24\3\24\3\24\5\24\u00ef\n\24\3\24\2\7\16\26\32\36 \25"+
-		"\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&\2\4\3\2\f\21\3\2\n\13\u0104"+
-		"\2(\3\2\2\2\4\65\3\2\2\2\6D\3\2\2\2\bO\3\2\2\2\nS\3\2\2\2\f]\3\2\2\2\16"+
-		"j\3\2\2\2\20u\3\2\2\2\22w\3\2\2\2\24\177\3\2\2\2\26\u0084\3\2\2\2\30\u0097"+
-		"\3\2\2\2\32\u0099\3\2\2\2\34\u00af\3\2\2\2\36\u00b1\3\2\2\2 \u00bf\3\2"+
-		"\2\2\"\u00cd\3\2\2\2$\u00de\3\2\2\2&\u00ee\3\2\2\2()\5\4\3\2)*\7\2\2\3"+
-		"*\3\3\2\2\2+\66\5\6\4\2,-\7 \2\2-.\5\4\3\2./\7!\2\2/\66\3\2\2\2\60\66"+
-		"\5\36\20\2\61\66\5\20\t\2\62\66\5\16\b\2\63\66\5\b\5\2\64\66\5\f\7\2\65"+
-		"+\3\2\2\2\65,\3\2\2\2\65\60\3\2\2\2\65\61\3\2\2\2\65\62\3\2\2\2\65\63"+
-		"\3\2\2\2\65\64\3\2\2\2\66\5\3\2\2\2\678\5\b\5\289\7\22\2\29:\5\4\3\2:"+
-		";\7\23\2\2;<\5\4\3\2<E\3\2\2\2=>\7\24\2\2>?\5\b\5\2?@\7\25\2\2@A\5\4\3"+
-		"\2AB\7\26\2\2BC\5\4\3\2CE\3\2\2\2D\67\3\2\2\2D=\3\2\2\2E\7\3\2\2\2FG\5"+
-		"\n\6\2GH\7\7\2\2HI\5\b\5\2IP\3\2\2\2JK\5\n\6\2KL\7\b\2\2LM\5\b\5\2MP\3"+
-		"\2\2\2NP\5\n\6\2OF\3\2\2\2OJ\3\2\2\2ON\3\2\2\2P\t\3\2\2\2QT\5\16\b\2R"+
-		"T\5\f\7\2SQ\3\2\2\2SR\3\2\2\2T\13\3\2\2\2UV\5&\24\2VW\7\"\2\2WX\5\n\6"+
-		"\2X^\3\2\2\2YZ\5&\24\2Z[\7#\2\2[\\\5\n\6\2\\^\3\2\2\2]U\3\2\2\2]Y\3\2"+
-		"\2\2^\r\3\2\2\2_`\b\b\1\2`a\7\t\2\2ab\7 \2\2bc\5\b\5\2cd\7!\2\2dk\3\2"+
-		"\2\2ef\7 \2\2fg\5\b\5\2gh\7!\2\2hk\3\2\2\2ik\5&\24\2j_\3\2\2\2je\3\2\2"+
-		"\2ji\3\2\2\2kr\3\2\2\2lm\f\6\2\2mn\5\22\n\2no\5\16\b\7oq\3\2\2\2pl\3\2"+
-		"\2\2qt\3\2\2\2rp\3\2\2\2rs\3\2\2\2s\17\3\2\2\2tr\3\2\2\2uv\5&\24\2v\21"+
-		"\3\2\2\2wx\t\2\2\2x\23\3\2\2\2yz\7 \2\2z{\5\26\f\2{|\7!\2\2|\u0080\3\2"+
-		"\2\2}~\7 \2\2~\u0080\7!\2\2\177y\3\2\2\2\177}\3\2\2\2\u0080\25\3\2\2\2"+
-		"\u0081\u0082\b\f\1\2\u0082\u0085\5&\24\2\u0083\u0085\5\6\4\2\u0084\u0081"+
-		"\3\2\2\2\u0084\u0083\3\2\2\2\u0085\u008e\3\2\2\2\u0086\u0087\f\5\2\2\u0087"+
-		"\u0088\7\5\2\2\u0088\u008d\5&\24\2\u0089\u008a\f\3\2\2\u008a\u008b\7\5"+
-		"\2\2\u008b\u008d\5\6\4\2\u008c\u0086\3\2\2\2\u008c\u0089\3\2\2\2\u008d"+
-		"\u0090\3\2\2\2\u008e\u008c\3\2\2\2\u008e\u008f\3\2\2\2\u008f\27\3\2\2"+
-		"\2\u0090\u008e\3\2\2\2\u0091\u0092\7\36\2\2\u0092\u0093\5\26\f\2\u0093"+
-		"\u0094\7\37\2\2\u0094\u0098\3\2\2\2\u0095\u0096\7\36\2\2\u0096\u0098\7"+
-		"\37\2\2\u0097\u0091\3\2\2\2\u0097\u0095\3\2\2\2\u0098\31\3\2\2\2\u0099"+
-		"\u009a\b\16\1\2\u009a\u009b\5&\24\2\u009b\u009c\7\23\2\2\u009c\u009d\5"+
-		"\4\3\2\u009d\u00a6\3\2\2\2\u009e\u009f\f\3\2\2\u009f\u00a0\7\5\2\2\u00a0"+
-		"\u00a1\5&\24\2\u00a1\u00a2\7\23\2\2\u00a2\u00a3\5\4\3\2\u00a3\u00a5\3"+
-		"\2\2\2\u00a4\u009e\3\2\2\2\u00a5\u00a8\3\2\2\2\u00a6\u00a4\3\2\2\2\u00a6"+
-		"\u00a7\3\2\2\2\u00a7\33\3\2\2\2\u00a8\u00a6\3\2\2\2\u00a9\u00aa\7\34\2"+
-		"\2\u00aa\u00ab\5\32\16\2\u00ab\u00ac\7\35\2\2\u00ac\u00b0\3\2\2\2\u00ad"+
-		"\u00ae\7\34\2\2\u00ae\u00b0\7\35\2\2\u00af\u00a9\3\2\2\2\u00af\u00ad\3"+
-		"\2\2\2\u00b0\35\3\2\2\2\u00b1\u00b2\b\20\1\2\u00b2\u00b3\5 \21\2\u00b3"+
-		"\u00bc\3\2\2\2\u00b4\u00b5\f\4\2\2\u00b5\u00b6\7\31\2\2\u00b6\u00bb\5"+
-		" \21\2\u00b7\u00b8\f\3\2\2\u00b8\u00b9\7\30\2\2\u00b9\u00bb\5 \21\2\u00ba"+
-		"\u00b4\3\2\2\2\u00ba\u00b7\3\2\2\2\u00bb\u00be\3\2\2\2\u00bc\u00ba\3\2"+
-		"\2\2\u00bc\u00bd\3\2\2\2\u00bd\37\3\2\2\2\u00be\u00bc\3\2\2\2\u00bf\u00c0"+
-		"\b\21\1\2\u00c0\u00c1\5$\23\2\u00c1\u00ca\3\2\2\2\u00c2\u00c3\f\4\2\2"+
-		"\u00c3\u00c4\7\33\2\2\u00c4\u00c9\5 \21\5\u00c5\u00c6\f\3\2\2\u00c6\u00c7"+
-		"\7\32\2\2\u00c7\u00c9\5 \21\4\u00c8\u00c2\3\2\2\2\u00c8\u00c5\3\2\2\2"+
-		"\u00c9\u00cc\3\2\2\2\u00ca\u00c8\3\2\2\2\u00ca\u00cb\3\2\2\2\u00cb!\3"+
-		"\2\2\2\u00cc\u00ca\3\2\2\2\u00cd\u00ce\7*\2\2\u00ce\u00cf\5\24\13\2\u00cf"+
-		"#\3\2\2\2\u00d0\u00df\5\"\22\2\u00d1\u00df\7\'\2\2\u00d2\u00df\7&\2\2"+
-		"\u00d3\u00df\7)\2\2\u00d4\u00df\7(\2\2\u00d5\u00df\7*\2\2\u00d6\u00d7"+
-		"\7 \2\2\u00d7\u00d8\5\36\20\2\u00d8\u00d9\7!\2\2\u00d9\u00df\3\2\2\2\u00da"+
-		"\u00db\7 \2\2\u00db\u00dc\5\6\4\2\u00dc\u00dd\7!\2\2\u00dd\u00df\3\2\2"+
-		"\2\u00de\u00d0\3\2\2\2\u00de\u00d1\3\2\2\2\u00de\u00d2\3\2\2\2\u00de\u00d3"+
-		"\3\2\2\2\u00de\u00d4\3\2\2\2\u00de\u00d5\3\2\2\2\u00de\u00d6\3\2\2\2\u00de"+
-		"\u00da\3\2\2\2\u00df%\3\2\2\2\u00e0\u00ef\t\3\2\2\u00e1\u00ef\5\36\20"+
-		"\2\u00e2\u00ef\7+\2\2\u00e3\u00ef\5\30\r\2\u00e4\u00ef\5\34\17\2\u00e5"+
-		"\u00ef\7\27\2\2\u00e6\u00e7\7$\2\2\u00e7\u00e8\7 \2\2\u00e8\u00e9\7*\2"+
-		"\2\u00e9\u00ef\7!\2\2\u00ea\u00eb\7 \2\2\u00eb\u00ec\5\6\4\2\u00ec\u00ed"+
-		"\7!\2\2\u00ed\u00ef\3\2\2\2\u00ee\u00e0\3\2\2\2\u00ee\u00e1\3\2\2\2\u00ee"+
-		"\u00e2\3\2\2\2\u00ee\u00e3\3\2\2\2\u00ee\u00e4\3\2\2\2\u00ee\u00e5\3\2"+
-		"\2\2\u00ee\u00e6\3\2\2\2\u00ee\u00ea\3\2\2\2\u00ef\'\3\2\2\2\26\65DOS"+
-		"]jr\177\u0084\u008c\u008e\u0097\u00a6\u00af\u00ba\u00bc\u00c8\u00ca\u00de"+
-		"\u00ee";
+		"\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"+
+		"\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\5\3@\n\3\3\4\3\4"+
+		"\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4O\n\4\3\5\3\5\3\5\3\5"+
+		"\3\5\3\5\3\5\3\5\3\5\5\5Z\n\5\3\6\3\6\5\6^\n\6\3\7\3\7\3\7\3\7\3\7\3\7"+
+		"\3\7\3\7\5\7h\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\5\bu\n\b"+
+		"\3\b\3\b\3\b\3\b\7\b{\n\b\f\b\16\b~\13\b\3\t\3\t\3\n\3\n\3\13\3\13\3\13"+
+		"\3\13\3\13\3\13\5\13\u008a\n\13\3\f\3\f\3\f\5\f\u008f\n\f\3\f\3\f\3\f"+
+		"\3\f\3\f\3\f\7\f\u0097\n\f\f\f\16\f\u009a\13\f\3\r\3\r\3\r\3\r\3\r\3\r"+
+		"\5\r\u00a2\n\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16"+
+		"\7\16\u00af\n\16\f\16\16\16\u00b2\13\16\3\17\3\17\3\17\3\17\3\17\3\17"+
+		"\5\17\u00ba\n\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\7\20\u00c5"+
+		"\n\20\f\20\16\20\u00c8\13\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3"+
+		"\21\7\21\u00d3\n\21\f\21\16\21\u00d6\13\21\3\22\3\22\3\22\3\23\3\23\3"+
+		"\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u00e9"+
+		"\n\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24"+
+		"\3\24\3\24\3\24\5\24\u00fb\n\24\3\25\3\25\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\5\26\u010c\n\26\3\27\3\27\3\27\7\27"+
+		"\u0111\n\27\f\27\16\27\u0114\13\27\3\30\3\30\3\31\3\31\3\31\2\7\16\26"+
+		"\32\36 \32\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\2\4\3\2"+
+		"\16\23\3\2\f\r\u012c\2\62\3\2\2\2\4?\3\2\2\2\6N\3\2\2\2\bY\3\2\2\2\n]"+
+		"\3\2\2\2\fg\3\2\2\2\16t\3\2\2\2\20\177\3\2\2\2\22\u0081\3\2\2\2\24\u0089"+
+		"\3\2\2\2\26\u008e\3\2\2\2\30\u00a1\3\2\2\2\32\u00a3\3\2\2\2\34\u00b9\3"+
+		"\2\2\2\36\u00bb\3\2\2\2 \u00c9\3\2\2\2\"\u00d7\3\2\2\2$\u00e8\3\2\2\2"+
+		"&\u00fa\3\2\2\2(\u00fc\3\2\2\2*\u010b\3\2\2\2,\u010d\3\2\2\2.\u0115\3"+
+		"\2\2\2\60\u0117\3\2\2\2\62\63\5\4\3\2\63\64\7\2\2\3\64\3\3\2\2\2\65@\5"+
+		"\6\4\2\66\67\7\"\2\2\678\5\4\3\289\7#\2\29@\3\2\2\2:@\5\36\20\2;@\5\20"+
+		"\t\2<@\5\16\b\2=@\5\b\5\2>@\5\f\7\2?\65\3\2\2\2?\66\3\2\2\2?:\3\2\2\2"+
+		"?;\3\2\2\2?<\3\2\2\2?=\3\2\2\2?>\3\2\2\2@\5\3\2\2\2AB\5\b\5\2BC\7\24\2"+
+		"\2CD\5\4\3\2DE\7\25\2\2EF\5\4\3\2FO\3\2\2\2GH\7\26\2\2HI\5\b\5\2IJ\7\27"+
+		"\2\2JK\5\4\3\2KL\7\30\2\2LM\5\4\3\2MO\3\2\2\2NA\3\2\2\2NG\3\2\2\2O\7\3"+
+		"\2\2\2PQ\5\n\6\2QR\7\t\2\2RS\5\b\5\2SZ\3\2\2\2TU\5\n\6\2UV\7\n\2\2VW\5"+
+		"\b\5\2WZ\3\2\2\2XZ\5\n\6\2YP\3\2\2\2YT\3\2\2\2YX\3\2\2\2Z\t\3\2\2\2[^"+
+		"\5\16\b\2\\^\5\f\7\2][\3\2\2\2]\\\3\2\2\2^\13\3\2\2\2_`\5&\24\2`a\7\3"+
+		"\2\2ab\5\n\6\2bh\3\2\2\2cd\5&\24\2de\7$\2\2ef\5\n\6\2fh\3\2\2\2g_\3\2"+
+		"\2\2gc\3\2\2\2h\r\3\2\2\2ij\b\b\1\2jk\7\13\2\2kl\7\"\2\2lm\5\b\5\2mn\7"+
+		"#\2\2nu\3\2\2\2op\7\"\2\2pq\5\b\5\2qr\7#\2\2ru\3\2\2\2su\5&\24\2ti\3\2"+
+		"\2\2to\3\2\2\2ts\3\2\2\2u|\3\2\2\2vw\f\6\2\2wx\5\22\n\2xy\5\16\b\7y{\3"+
+		"\2\2\2zv\3\2\2\2{~\3\2\2\2|z\3\2\2\2|}\3\2\2\2}\17\3\2\2\2~|\3\2\2\2\177"+
+		"\u0080\5&\24\2\u0080\21\3\2\2\2\u0081\u0082\t\2\2\2\u0082\23\3\2\2\2\u0083"+
+		"\u0084\7\"\2\2\u0084\u0085\5\26\f\2\u0085\u0086\7#\2\2\u0086\u008a\3\2"+
+		"\2\2\u0087\u0088\7\"\2\2\u0088\u008a\7#\2\2\u0089\u0083\3\2\2\2\u0089"+
+		"\u0087\3\2\2\2\u008a\25\3\2\2\2\u008b\u008c\b\f\1\2\u008c\u008f\5&\24"+
+		"\2\u008d\u008f\5\6\4\2\u008e\u008b\3\2\2\2\u008e\u008d\3\2\2\2\u008f\u0098"+
+		"\3\2\2\2\u0090\u0091\f\5\2\2\u0091\u0092\7\7\2\2\u0092\u0097\5&\24\2\u0093"+
+		"\u0094\f\3\2\2\u0094\u0095\7\7\2\2\u0095\u0097\5\6\4\2\u0096\u0090\3\2"+
+		"\2\2\u0096\u0093\3\2\2\2\u0097\u009a\3\2\2\2\u0098\u0096\3\2\2\2\u0098"+
+		"\u0099\3\2\2\2\u0099\27\3\2\2\2\u009a\u0098\3\2\2\2\u009b\u009c\7 \2\2"+
+		"\u009c\u00a2\7!\2\2\u009d\u009e\7 \2\2\u009e\u009f\5\26\f\2\u009f\u00a0"+
+		"\7!\2\2\u00a0\u00a2\3\2\2\2\u00a1\u009b\3\2\2\2\u00a1\u009d\3\2\2\2\u00a2"+
+		"\31\3\2\2\2\u00a3\u00a4\b\16\1\2\u00a4\u00a5\5&\24\2\u00a5\u00a6\7\25"+
+		"\2\2\u00a6\u00a7\5\4\3\2\u00a7\u00b0\3\2\2\2\u00a8\u00a9\f\3\2\2\u00a9"+
+		"\u00aa\7\7\2\2\u00aa\u00ab\5&\24\2\u00ab\u00ac\7\25\2\2\u00ac\u00ad\5"+
+		"\4\3\2\u00ad\u00af\3\2\2\2\u00ae\u00a8\3\2\2\2\u00af\u00b2\3\2\2\2\u00b0"+
+		"\u00ae\3\2\2\2\u00b0\u00b1\3\2\2\2\u00b1\33\3\2\2\2\u00b2\u00b0\3\2\2"+
+		"\2\u00b3\u00b4\7\36\2\2\u00b4\u00b5\5\32\16\2\u00b5\u00b6\7\37\2\2\u00b6"+
+		"\u00ba\3\2\2\2\u00b7\u00b8\7\36\2\2\u00b8\u00ba\7\37\2\2\u00b9\u00b3\3"+
+		"\2\2\2\u00b9\u00b7\3\2\2\2\u00ba\35\3\2\2\2\u00bb\u00bc\b\20\1\2\u00bc"+
+		"\u00bd\5 \21\2\u00bd\u00c6\3\2\2\2\u00be\u00bf\f\4\2\2\u00bf\u00c0\7\33"+
+		"\2\2\u00c0\u00c5\5 \21\2\u00c1\u00c2\f\3\2\2\u00c2\u00c3\7\32\2\2\u00c3"+
+		"\u00c5\5 \21\2\u00c4\u00be\3\2\2\2\u00c4\u00c1\3\2\2\2\u00c5\u00c8\3\2"+
+		"\2\2\u00c6\u00c4\3\2\2\2\u00c6\u00c7\3\2\2\2\u00c7\37\3\2\2\2\u00c8\u00c6"+
+		"\3\2\2\2\u00c9\u00ca\b\21\1\2\u00ca\u00cb\5$\23\2\u00cb\u00d4\3\2\2\2"+
+		"\u00cc\u00cd\f\4\2\2\u00cd\u00ce\7\35\2\2\u00ce\u00d3\5 \21\5\u00cf\u00d0"+
+		"\f\3\2\2\u00d0\u00d1\7\34\2\2\u00d1\u00d3\5 \21\4\u00d2\u00cc\3\2\2\2"+
+		"\u00d2\u00cf\3\2\2\2\u00d3\u00d6\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d4\u00d5"+
+		"\3\2\2\2\u00d5!\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d7\u00d8\7+\2\2\u00d8\u00d9"+
+		"\5\24\13\2\u00d9#\3\2\2\2\u00da\u00e9\5\"\22\2\u00db\u00e9\7(\2\2\u00dc"+
+		"\u00e9\7\'\2\2\u00dd\u00e9\7*\2\2\u00de\u00e9\7)\2\2\u00df\u00e9\7+\2"+
+		"\2\u00e0\u00e1\7\"\2\2\u00e1\u00e2\5\36\20\2\u00e2\u00e3\7#\2\2\u00e3"+
+		"\u00e9\3\2\2\2\u00e4\u00e5\7\"\2\2\u00e5\u00e6\5\6\4\2\u00e6\u00e7\7#"+
+		"\2\2\u00e7\u00e9\3\2\2\2\u00e8\u00da\3\2\2\2\u00e8\u00db\3\2\2\2\u00e8"+
+		"\u00dc\3\2\2\2\u00e8\u00dd\3\2\2\2\u00e8\u00de\3\2\2\2\u00e8\u00df\3\2"+
+		"\2\2\u00e8\u00e0\3\2\2\2\u00e8\u00e4\3\2\2\2\u00e9%\3\2\2\2\u00ea\u00fb"+
+		"\t\3\2\2\u00eb\u00fb\5*\26\2\u00ec\u00fb\5(\25\2\u00ed\u00fb\5\36\20\2"+
+		"\u00ee\u00fb\7,\2\2\u00ef\u00fb\5\30\r\2\u00f0\u00fb\5\34\17\2\u00f1\u00fb"+
+		"\7\31\2\2\u00f2\u00f3\7%\2\2\u00f3\u00f4\7\"\2\2\u00f4\u00f5\7+\2\2\u00f5"+
+		"\u00fb\7#\2\2\u00f6\u00f7\7\"\2\2\u00f7\u00f8\5\6\4\2\u00f8\u00f9\7#\2"+
+		"\2\u00f9\u00fb\3\2\2\2\u00fa\u00ea\3\2\2\2\u00fa\u00eb\3\2\2\2\u00fa\u00ec"+
+		"\3\2\2\2\u00fa\u00ed\3\2\2\2\u00fa\u00ee\3\2\2\2\u00fa\u00ef\3\2\2\2\u00fa"+
+		"\u00f0\3\2\2\2\u00fa\u00f1\3\2\2\2\u00fa\u00f2\3\2\2\2\u00fa\u00f6\3\2"+
+		"\2\2\u00fb\'\3\2\2\2\u00fc\u00fd\7\"\2\2\u00fd\u00fe\7#\2\2\u00fe\u00ff"+
+		"\7\4\2\2\u00ff\u0100\5\4\3\2\u0100)\3\2\2\2\u0101\u0102\7\"\2\2\u0102"+
+		"\u0103\5,\27\2\u0103\u0104\7#\2\2\u0104\u0105\7\4\2\2\u0105\u0106\5\4"+
+		"\3\2\u0106\u010c\3\2\2\2\u0107\u0108\5.\30\2\u0108\u0109\7\4\2\2\u0109"+
+		"\u010a\5\4\3\2\u010a\u010c\3\2\2\2\u010b\u0101\3\2\2\2\u010b\u0107\3\2"+
+		"\2\2\u010c+\3\2\2\2\u010d\u0112\5\60\31\2\u010e\u010f\7\7\2\2\u010f\u0111"+
+		"\5\60\31\2\u0110\u010e\3\2\2\2\u0111\u0114\3\2\2\2\u0112\u0110\3\2\2\2"+
+		"\u0112\u0113\3\2\2\2\u0113-\3\2\2\2\u0114\u0112\3\2\2\2\u0115\u0116\5"+
+		"\60\31\2\u0116/\3\2\2\2\u0117\u0118\7+\2\2\u0118\61\3\2\2\2\30?NY]gt|"+
+		"\u0089\u008e\u0096\u0098\u00a1\u00b0\u00b9\u00c4\u00c6\u00d2\u00d4\u00e8"+
+		"\u00fa\u010b\u0112";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/DataStructureFunctionsTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/DataStructureFunctionsTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/DataStructureFunctionsTest.java
index b60e117..4426608 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/DataStructureFunctionsTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/DataStructureFunctionsTest.java
@@ -19,10 +19,16 @@
 package org.apache.metron.common.dsl.functions;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import org.hamcrest.CoreMatchers;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.metron.common.utils.StellarProcessorUtils.run;
+
 public class DataStructureFunctionsTest {
 
   @Test
@@ -59,4 +65,57 @@ public class DataStructureFunctionsTest {
     }
   }
 
+  @Test
+  public void listAdd_number() {
+    for(String expr : ImmutableList.of("LIST_ADD(my_list, 1)"
+                                      ,"LIST_ADD([], 1)"
+                                      ,"LIST_ADD([], val)"
+                                      )
+       )
+    {
+      Object o = run(expr, ImmutableMap.of("my_list", new ArrayList<>(), "val", 1));
+      Assert.assertTrue(o instanceof List);
+      List<Number> result = (List<Number>) o;
+      Assert.assertEquals(1, result.size());
+      Assert.assertEquals(1, result.get(0));
+    }
+  }
+
+  @Test
+  public void listAdd_mixed() {
+    for(String expr : ImmutableList.of("LIST_ADD(my_list, 1)"
+                                      ,"LIST_ADD(['foo'], 1)"
+                                      ,"LIST_ADD(['foo'], val)"
+                                      )
+       )
+    {
+      ArrayList<Object> list = new ArrayList<>();
+      list.add("foo");
+      Object o = run(expr, ImmutableMap.of("my_list", list, "val", 1));
+      Assert.assertTrue(o instanceof List);
+      List<Object> result = (List<Object>) o;
+      Assert.assertEquals(2, result.size());
+      Assert.assertEquals("foo", result.get(0));
+      Assert.assertEquals(1, result.get(1));
+    }
+  }
+
+  @Test
+  public void listAdd_number_nonempty() {
+    for(String expr : ImmutableList.of("LIST_ADD(my_list, 2)"
+                                      ,"LIST_ADD([1], 2)"
+                                      ,"LIST_ADD([1], val)"
+                                      )
+       )
+    {
+      ArrayList<Integer> list = new ArrayList<>();
+      list.add(1);
+      Object o = run(expr, ImmutableMap.of("my_list", list, "val", 2));
+      Assert.assertTrue(o instanceof List);
+      List<Number> result = (List<Number>) o;
+      Assert.assertEquals(2, result.size());
+      Assert.assertEquals(1, result.get(0));
+      Assert.assertEquals(2, result.get(1));
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/FunctionalFunctionsTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/FunctionalFunctionsTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/FunctionalFunctionsTest.java
new file mode 100644
index 0000000..2e1859e
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/dsl/functions/FunctionalFunctionsTest.java
@@ -0,0 +1,235 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.metron.common.dsl.functions;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.apache.metron.common.utils.StellarProcessorUtils.run;
+
+public class FunctionalFunctionsTest {
+
+  @Test
+  public void testRecursive() {
+    for (String expr : ImmutableList.of( "MAP(list, inner_list -> REDUCE(inner_list, (x, y) -> x + y, 0) )"
+                                       , "MAP(list, (inner_list) -> REDUCE(inner_list, (x, y) -> x + y, 0) )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("list", ImmutableList.of(ImmutableList.of(1, 2, 3), ImmutableList.of(4, 5, 6))));
+      Assert.assertTrue(o instanceof List);
+      List<Number> result = (List<Number>) o;
+      Assert.assertEquals(2, result.size());
+      Assert.assertEquals(6, result.get(0));
+      Assert.assertEquals(15, result.get(1));
+    }
+  }
+
+  @Test
+  public void testMap_null() {
+    for (String expr : ImmutableList.of( "MAP([ 1, 2, null], x -> if x == null then 0 else 2*x )"
+                                       , "MAP([ 1, 2, null], x -> x == null ? 0 : 2*x )"
+                                       , "MAP([ 1, foo, baz], x -> x == null ? 0 : 2*x )"
+    )
+            )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", 2, "bar", 3));
+      Assert.assertTrue(o instanceof List);
+      List<String> result = (List<String>) o;
+      Assert.assertEquals(3, result.size());
+      Assert.assertEquals(2, result.get(0));
+      Assert.assertEquals(4, result.get(1));
+      Assert.assertEquals(0, result.get(2));
+    }
+  }
+
+
+  @Test
+  public void testMap() {
+    for (String expr : ImmutableList.of( "MAP([ 'foo', 'bar'], (x) -> TO_UPPER(x) )"
+                                       , "MAP([ foo, 'bar'], (x) -> TO_UPPER(x) )"
+                                       , "MAP([ foo, bar], (x) -> TO_UPPER(x) )"
+                                       , "MAP([ foo, bar], x -> TO_UPPER(x) )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", "foo", "bar", "bar"));
+      Assert.assertTrue(o instanceof List);
+      List<String> result = (List<String>) o;
+      Assert.assertEquals(2, result.size());
+      Assert.assertEquals("FOO", result.get(0));
+      Assert.assertEquals("BAR", result.get(1));
+    }
+  }
+
+
+  @Test
+  public void testMap_conditional() {
+    for (String expr : ImmutableList.of("MAP([ 'foo', 'bar'], (item) -> item == 'foo' )"
+                                       ,"MAP([ foo, bar], (item) -> item == 'foo' )"
+                                       ,"MAP([ foo, bar], (item) -> item == foo )"
+                                       ,"MAP([ foo, bar], item -> item == foo )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", "foo", "bar", "bar"));
+      Assert.assertTrue(o instanceof List);
+      List<Boolean> result = (List<Boolean>) o;
+      Assert.assertEquals(2, result.size());
+      Assert.assertEquals(true, result.get(0));
+      Assert.assertEquals(false, result.get(1));
+    }
+  }
+
+  @Test
+  public void testFilter() {
+    for (String expr : ImmutableList.of("FILTER([ 'foo', 'bar'], (item) -> item == 'foo' )"
+                                       ,"FILTER([ 'foo', bar], (item) -> item == 'foo' )"
+                                       ,"FILTER([ foo, bar], (item) -> item == 'foo' )"
+                                       ,"FILTER([ foo, bar], (item) -> (item == 'foo' && true) )"
+                                       ,"FILTER([ foo, bar], (item) -> if item == 'foo' then true else false )"
+                                       ,"FILTER([ foo, bar], item -> if item == 'foo' then true else false )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", "foo", "bar", "bar"));
+      Assert.assertTrue(o instanceof List);
+      List<String> result = (List<String>) o;
+      Assert.assertEquals(1, result.size());
+      Assert.assertEquals("foo", result.get(0));
+    }
+  }
+
+
+  @Test
+  public void testFilter_null() {
+    for (String expr : ImmutableList.of("FILTER([ 'foo', null], item -> item == null )"
+                                       ,"FILTER([ 'foo', baz], (item) -> item == null )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", "foo", "bar", "bar"));
+      Assert.assertTrue(o instanceof List);
+      List<String> result = (List<String>) o;
+      Assert.assertEquals(1, result.size());
+      Assert.assertEquals(null, result.get(0));
+    }
+  }
+
+  @Test
+  public void testFilter_notnull() {
+    for (String expr : ImmutableList.of("FILTER([ 'foo', null], item -> item != null )"
+                                       ,"FILTER([ 'foo', baz], (item) -> item != null )"
+                                       ,"FILTER([ foo, baz], (item) -> item != null )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", "foo", "bar", "bar"));
+      Assert.assertTrue(o instanceof List);
+      List<String> result = (List<String>) o;
+      Assert.assertEquals(1, result.size());
+      Assert.assertEquals("foo", result.get(0));
+    }
+  }
+
+  @Test
+  public void testFilter_none() {
+    for (String expr : ImmutableList.of( "FILTER([ foo, bar], () -> false  )"
+                                       , "FILTER([ 'foo', 'bar'], (item)-> false )"
+                                       ,"FILTER([ 'foo', bar], (item ) -> false )"
+                                       ,"FILTER([ foo, bar], (item) -> false )"
+                                       ,"FILTER([ foo, bar], item -> false )"
+
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", "foo", "bar", "bar"));
+      Assert.assertTrue(o instanceof List);
+      List<String> result = (List<String>) o;
+      Assert.assertEquals(0, result.size());
+    }
+  }
+
+  @Test
+  public void testFilter_all() {
+    for (String expr : ImmutableList.of("FILTER([ 'foo', 'bar'], (item) -> true )"
+                                       ,"FILTER([ 'foo', bar], (item) -> true )"
+                                       ,"FILTER([ foo, bar], (item) -> true )"
+                                       ,"FILTER([ foo, bar], item -> true )"
+                                       ,"FILTER([ foo, bar], ()-> true )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", "foo", "bar", "bar"));
+      Assert.assertTrue(o instanceof List);
+      List<String> result = (List<String>) o;
+      Assert.assertEquals(2, result.size());
+      Assert.assertEquals("foo", result.get(0));
+      Assert.assertEquals("bar", result.get(1));
+    }
+  }
+
+  @Test
+  public void testReduce_null() {
+    for (String expr : ImmutableList.of("REDUCE([ 1, 2, 3, null], (x, y) -> if y != null then x + y else x , 0 )"
+                                       ,"REDUCE([ foo, bar, 3, baz], (sum, y) -> if y != null then sum + y else sum, 0 )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", 1, "bar", 2));
+      Assert.assertTrue(o instanceof Number);
+      Number result = (Number) o;
+      Assert.assertEquals(6, result.intValue());
+    }
+  }
+
+  @Test
+  public void testReduce() {
+    for (String expr : ImmutableList.of("REDUCE([ 1, 2, 3], (x, y) -> x + y , 0 )"
+                                       ,"REDUCE([ foo, bar, 3], (x, y) -> x + y , 0 )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", 1, "bar", 2));
+      Assert.assertTrue(o instanceof Number);
+      Number result = (Number) o;
+      Assert.assertEquals(6, result.intValue());
+    }
+  }
+
+  @Test
+  public void testReduce_NonNumeric() {
+    for (String expr : ImmutableList.of("REDUCE([ 'foo', 'bar', 'grok'], (x, y) -> LIST_ADD(x, y), [] )"
+                                       )
+        )
+    {
+      Object o = run(expr, ImmutableMap.of("foo", 1, "bar", 2));
+      Assert.assertTrue(o instanceof List);
+      List<String> result = (List<String>) o;
+      Assert.assertEquals(3, result.size());
+      Assert.assertEquals("foo", result.get(0));
+      Assert.assertEquals("bar", result.get(1));
+      Assert.assertEquals("grok", result.get(2));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
index e1b455b..4c0a5e9 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
@@ -64,6 +64,7 @@ public class StellarTest {
     Assert.assertTrue(numFound > 0);
   }
 
+
   @Test
   public void testVariableResolution() {
     {
@@ -299,7 +300,7 @@ public class StellarTest {
     HashMap variables = new HashMap<>();
     boolean thrown = false;
     try{
-      run("in in ['','in']" ,variables );
+      Object o = run("in in ['','in']" ,variables );
     }catch(ParseException pe) {
       thrown = true;
     }

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-enrichment/src/test/java/org/apache/metron/enrichment/stellar/SimpleHBaseEnrichmentFunctionsTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-enrichment/src/test/java/org/apache/metron/enrichment/stellar/SimpleHBaseEnrichmentFunctionsTest.java b/metron-platform/metron-enrichment/src/test/java/org/apache/metron/enrichment/stellar/SimpleHBaseEnrichmentFunctionsTest.java
index 1c0838f..9c8df16 100644
--- a/metron-platform/metron-enrichment/src/test/java/org/apache/metron/enrichment/stellar/SimpleHBaseEnrichmentFunctionsTest.java
+++ b/metron-platform/metron-enrichment/src/test/java/org/apache/metron/enrichment/stellar/SimpleHBaseEnrichmentFunctionsTest.java
@@ -37,6 +37,8 @@ import org.junit.Test;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class SimpleHBaseEnrichmentFunctionsTest {
@@ -94,6 +96,7 @@ public class SimpleHBaseEnrichmentFunctionsTest {
     Assert.assertTrue(result instanceof Boolean);
     Assert.assertFalse((Boolean)result);
   }
+
   @Test
   public void testSuccessfulGet() throws Exception {
     String stellar = "ENRICHMENT_GET('et', indicator, 'enrichments', 'cf')";
@@ -104,6 +107,18 @@ public class SimpleHBaseEnrichmentFunctionsTest {
   }
 
   @Test
+  public void testMultiGet() throws Exception {
+    String stellar = "MAP([ 'indicator0', 'indicator1' ], indicator -> ENRICHMENT_GET('et', indicator, 'enrichments', 'cf') )";
+    Object result = run(stellar, new HashMap<>());
+    Assert.assertTrue(result instanceof List);
+    List<Map<String, Object>> out = (List<Map<String, Object>>) result;
+    Assert.assertEquals(2, out.size());
+    for(int i = 0;i < 2;++i) {
+      Map<String, Object> map = out.get(i);
+      Assert.assertEquals("value" +i, map.get("key" + i));
+    }
+  }
+  @Test
   public void testUnsuccessfulGet() throws Exception {
     String stellar = "ENRICHMENT_GET('et', indicator, 'enrichments', 'cf')";
     Object result = run(stellar, ImmutableMap.of("indicator", "indicator7"));


[2/2] incubator-metron git commit: METRON-831: Add lambda expressions and rudimentary functional programming primitives to Stellar. This closes apache/incubator-metron#517

Posted by ce...@apache.org.
METRON-831: Add lambda expressions and rudimentary functional programming primitives to Stellar.  This closes apache/incubator-metron#517


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

Branch: refs/heads/master
Commit: ab80e7b18ba1fb18adeb7645fda9440a9644d34e
Parents: 7e21ad3
Author: cstella <ce...@gmail.com>
Authored: Mon Apr 10 09:19:49 2017 -0400
Committer: cstella <ce...@gmail.com>
Committed: Mon Apr 10 09:19:49 2017 -0400

----------------------------------------------------------------------
 metron-platform/metron-common/README.md         |  56 +-
 .../metron/common/stellar/generated/Stellar.g4  |  45 +-
 .../metron-common/src/main/java/Stellar.tokens  | 132 +--
 .../src/main/java/StellarLexer.tokens           | 132 +--
 .../dsl/functions/DataStructureFunctions.java   |  30 +
 .../dsl/functions/FunctionalFunctions.java      | 121 +++
 .../metron/common/stellar/LambdaExpression.java |  68 ++
 .../metron/common/stellar/StellarCompiler.java  |  90 +-
 .../stellar/generated/StellarBaseListener.java  |  84 ++
 .../common/stellar/generated/StellarLexer.java  | 354 ++++----
 .../stellar/generated/StellarListener.java      |  74 ++
 .../common/stellar/generated/StellarParser.java | 835 +++++++++++++------
 .../functions/DataStructureFunctionsTest.java   |  59 ++
 .../dsl/functions/FunctionalFunctionsTest.java  | 235 ++++++
 .../metron/common/stellar/StellarTest.java      |   3 +-
 .../SimpleHBaseEnrichmentFunctionsTest.java     |  15 +
 16 files changed, 1765 insertions(+), 568 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/README.md
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/README.md b/metron-platform/metron-common/README.md
index c17bb5b..d55843c 100644
--- a/metron-platform/metron-common/README.md
+++ b/metron-platform/metron-common/README.md
@@ -28,7 +28,7 @@ The query language supports the following:
 * Determining whether a field exists (via `exists`)
 * An `in` operator that works like the `in` in Python
 * The ability to have parenthesis to make order of operations explicit
-* User defined functions
+* User defined functions, including Lambda expressions 
 
 ## Stellar Language Keywords
 The following keywords need to be single quote escaped in order to be used in Stellar expressions:
@@ -73,6 +73,27 @@ Below is how the `==` operator is expected to work:
 
 The `!=` operator is the negation of the above.
 
+## Stellar Language Lambda Expressions
+
+Stellar provides the capability to pass lambda expressions to functions
+which wish to support that layer of indirection.  The syntax is:
+* `(named_variables) -> stellar_expression` : Lambda expression with named variables
+  * For instance, the lambda expression which calls `TO_UPPER` on a named argument `x` could be be expressed as `(x) -> TO_UPPER(x)`.
+* `var -> stellar_expression` : Lambda expression with a single named variable, `var`
+  * For instance, the lambda expression which calls `TO_UPPER` on a named argument `x` could be expressed as `x -> TO_UPPER(x)`.  Note, this is more succinct but equivalent to the example directly above.
+* `() -> stellar_expression` : Lambda expression with no named variables.
+  * If no named variables are needed, you may omit the named variable section.  For instance, the lambda expression which returns a constant `false` would be `() -> false`
+
+where 
+* `named_variables` is a comma separated list of variables to use in the Stellar expression
+* `stellar_expression` is an arbitrary stellar expression
+
+
+In the core language functions, we support basic functional programming primitives such as
+* `MAP` - Applies a lambda expression over a list of input.  For instance `MAP([ 'foo', 'bar'], (x) -> TO_UPPER(x) )` returns `[ 'FOO', 'BAR' ]`
+* `FILTER` - Filters a list by a predicate in the form of a lambda expression.  For instance `FILTER([ 'foo', 'bar'], (x ) -> x == 'foo' )` returns `[ 'foo' ]`
+* `REDUCE` - Applies a function over a list of input.  For instance `REDUCE([ 1, 2, 3], (sum, x) -> sum + x, 0 )` returns `6`
+
 ## Stellar Core Functions
 
 |                                                                                                    |
@@ -94,6 +115,7 @@ The `!=` operator is the negation of the above.
 | [ `ENRICHMENT_GET`](#enrichment_get)                                                               |
 | [ `FILL_LEFT`](#fill_left)                                                                         |
 | [ `FILL_RIGHT`](#fill_right)                                                                       |
+| [ `FILTER`](#filter)                                                                         |
 | [ `FORMAT`](#format)                                                                               |
 | [ `HLLP_CARDINALITY`](../../metron-analytics/metron-statistics#hllp_cardinality)                   |
 | [ `HLLP_INIT`](../../metron-analytics/metron-statistics#hllp_init)                                 |
@@ -117,14 +139,17 @@ The `!=` operator is the negation of the above.
 | [ `KAFKA_PUT`](#kafka_put)                                                                         |
 | [ `KAFKA_TAIL`](#kafka_tail)                                                                       |
 | [ `LENGTH`](#length)                                                                               |
+| [ `LIST_ADD`](#list_add)                                                                               |
 | [ `MAAS_GET_ENDPOINT`](#maas_get_endpoint)                                                         |
 | [ `MAAS_MODEL_APPLY`](#maas_model_apply)                                                           |
+| [ `MAP`](#map)                                                                       |
 | [ `MAP_EXISTS`](#map_exists)                                                                       |
 | [ `MONTH`](#month)                                                                                 |
 | [ `PROFILE_GET`](#profile_get)                                                                     |
 | [ `PROFILE_FIXED`](#profile_fixed)                                                                     |
 | [ `PROFILE_WINDOW`](#profile_window)                                                                     |
 | [ `PROTOCOL_TO_NAME`](#protocol_to_name)                                                           |
+| [ `REDUCE`](#reduce)                                                                   |
 | [ `REGEXP_MATCH`](#regexp_match)                                                                   |
 | [ `SPLIT`](#split)                                                                                 |
 | [ `STARTS_WITH`](#starts_with)                                                                     |
@@ -271,6 +296,13 @@ The `!=` operator is the negation of the above.
     * len - the required length
   * Returns: Last element of the list
 
+### `FILTER`
+  * Description: Applies a filter in the form of a lambda expression to a list. e.g. `FILTER( [ 'foo', 'bar' ] , (x) -> x == 'foo')` would yield `[ 'foo']`
+  * Input:
+    * list - List of arguments.
+    * predicate - The lambda expression to apply.  This expression is assumed to take one argument and return a boolean.
+  * Returns: The input list filtered by the predicate.
+
 ### `FORMAT`
   * Description: Returns a formatted string using the specified format string and arguments. Uses Java's string formatting conventions.
   * Input:
@@ -398,6 +430,13 @@ The `!=` operator is the negation of the above.
     * input - Object of string or collection type (e.g. list)
   * Returns: Integer
 
+### `LIST_ADD`
+  * Description: Adds an element to a list.
+  * Input:
+    * list - List to add element to.
+    * element - Element to add to list
+  * Returns: Resulting list with the item added at the end.
+  
 ### `MAAS_GET_ENDPOINT`
   * Description: Inspects ZooKeeper and returns a map containing the name, version and url for the model referred to by the input parameters.
   * Input:
@@ -413,6 +452,13 @@ The `!=` operator is the negation of the above.
     * model_args - A Dictionary of arguments for the model (these become request params)
   * Returns: The output of the model deployed as a REST endpoint in Map form.  Assumes REST endpoint returns a JSON Map.
 
+### `MAP`
+  * Description: Applies lambda expression to a list of arguments. e.g. `MAP( [ 'foo', 'bar' ] , (x) -> TO_UPPER(x) )` would yield `[ 'FOO', 'BAR' ]`
+  * Input:
+    * list - List of arguments.
+    * transform_expression - The lambda expression to apply. This expression is assumed to take one argument.
+  * Returns: The input list transformed item-wise by the lambda expression.
+  
 ### `MAP_EXISTS`
   * Description: Checks for existence of a key in a map.
   * Input:
@@ -466,6 +512,14 @@ The `!=` operator is the negation of the above.
     * IANA Number
   * Returns: The protocol name associated with the IANA number.
 
+### `REDUCE`
+  * Description: Reduces a list by a binary lambda expression. That is, the expression takes two arguments.  Usage example: `REDUCE( [ 1, 2, 3 ] , (x, y) -> x + y, 0)` would sum the input list, yielding `6`.
+  * Input:                      
+    * list - List of arguments.
+    * binary_operation - The lambda expression function to apply to reduce the list. It is assumed that this takes two arguments, the first being the running total and the second being an item from the list.
+    * initial_value - The initial value to use.
+  * Returns: The reduction of the list.
+  
 ### `REGEXP_MATCH`
   * Description: Determines whether a regex matches a string
   * Input:

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4 b/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4
index 3005323..75f5761 100644
--- a/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4
+++ b/metron-platform/metron-common/src/main/antlr4/org/apache/metron/common/stellar/generated/Stellar.g4
@@ -40,7 +40,8 @@ grammar Stellar;
 }
 
 /* Lexical rules */
-
+IN : 'in' | 'IN';
+LAMBDA_OP : '->';
 DOUBLE_QUOTE : '"';
 SINGLE_QUOTE : '\'';
 COMMA : ',';
@@ -75,7 +76,6 @@ LBRACKET : '[';
 RBRACKET : ']';
 LPAREN : '(' ;
 RPAREN : ')' ;
-IN : 'in' | 'IN';
 NIN : 'not in' | 'NOT IN';
 EXISTS : 'exists' | 'EXISTS';
 EXPONENT : E ( PLUS|MINUS )? DIGIT+;
@@ -95,7 +95,9 @@ FLOAT_LITERAL :
   | INT_LITERAL EXPONENT? F
   ;
 LONG_LITERAL : INT_LITERAL L;
-IDENTIFIER : [a-zA-Z_][a-zA-Z_\.:0-9]*;
+IDENTIFIER : IDENTIFIER_START
+           | IDENTIFIER_START IDENTIFIER_MIDDLE* IDENTIFIER_END
+           ;
 
 STRING_LITERAL :
   DOUBLE_QUOTE SCHAR* DOUBLE_QUOTE
@@ -118,6 +120,11 @@ fragment E: ('e'|'E');
 fragment F: ('f'|'F');
 fragment L: ('l'|'L');
 fragment EOL : '\n';
+fragment IDENTIFIER_START : [a-zA-Z_$];
+fragment IDENTIFIER_MIDDLE: [a-zA-Z_\.:0-9];
+//identifiers can't end with a colon, it screws up maps and lambda variables.
+//the following (x,y:x == 'foo') doesn't parse because y:x is considered a variable
+fragment IDENTIFIER_END: [a-zA-Z_\.0-9];
 
 /* Parser rules */
 
@@ -178,8 +185,8 @@ op_list :
   ;
 
 list_entity :
-  LBRACKET op_list RBRACKET
-  | LBRACKET RBRACKET
+  LBRACKET RBRACKET
+  | LBRACKET op_list RBRACKET
   ;
 
 kv_list :
@@ -217,8 +224,11 @@ arithmetic_operands :
   | LPAREN conditional_expr RPAREN #condExpr
   ;
 
+
 identifier_operand :
   (TRUE | FALSE) #LogicalConst
+  | lambda_with_args  #LambdaWithArgsExpr
+  | lambda_without_args  #LambdaWithoutArgsExpr
   | arithmetic_expr #ArithmeticOperands
   | STRING_LITERAL # StringLiteral
   | list_entity #List
@@ -226,4 +236,27 @@ identifier_operand :
   | NULL #NullConst
   | EXISTS LPAREN IDENTIFIER RPAREN #ExistsFunc
   | LPAREN conditional_expr RPAREN #condExpr_paren
-  ;
\ No newline at end of file
+  ;
+
+
+lambda_without_args:
+  LPAREN RPAREN LAMBDA_OP transformation_expr
+  ;
+
+lambda_with_args :
+  LPAREN lambda_variables RPAREN LAMBDA_OP transformation_expr
+  | single_lambda_variable LAMBDA_OP transformation_expr
+  ;
+
+lambda_variables :
+  lambda_variable (COMMA lambda_variable)*
+  ;
+
+single_lambda_variable :
+  lambda_variable;
+
+lambda_variable:
+  IDENTIFIER
+  ;
+
+

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

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

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/DataStructureFunctions.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/DataStructureFunctions.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/DataStructureFunctions.java
index 25976a4..c0f2e8c 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/DataStructureFunctions.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/DataStructureFunctions.java
@@ -162,6 +162,36 @@ public class DataStructureFunctions {
       }
     }
   }
+  @Stellar(name="ADD"
+          ,namespace="LIST"
+          , description="Adds an element to a list."
+          , params = { "list - List to add element to."
+                     , "element - Element to add to list"
+                     }
+          , returns = "Resulting list with the item added at the end."
+  )
+
+  public static class ListAdd extends BaseStellarFunction {
+    @Override
+    public Object apply(List<Object> list) {
+      if (list.size() == 0) {
+        return null;
+      }
+      Object o = list.get(0);
+      if(list.size() == 1) {
+        return o;
+      }
+      if(o instanceof List) {
+        List l = (List)o;
+        Object arg = list.get(1);
+        l.add(arg);
+        return l;
+      }
+      else {
+        return o;
+      }
+    }
+  }
 
   @Stellar(name="LENGTH"
           , description="Returns the length of a string or size of a collection. Returns 0 for empty or null Strings"

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/FunctionalFunctions.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/FunctionalFunctions.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/FunctionalFunctions.java
new file mode 100644
index 0000000..0f39d1d
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/dsl/functions/FunctionalFunctions.java
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.metron.common.dsl.functions;
+
+import org.apache.metron.common.dsl.BaseStellarFunction;
+import org.apache.metron.common.dsl.Stellar;
+import org.apache.metron.common.stellar.LambdaExpression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionalFunctions {
+
+  @Stellar(name="MAP"
+          , description="Applies lambda expression to a list of arguments. e.g. MAP( [ 'foo', 'bar' ] , ( x ) -> TO_UPPER(x) ) would yield [ 'FOO', 'BAR' ]"
+          , params = {
+                      "list - List of arguments."
+                     ,"transform_expression - The lambda expression to apply. This expression is assumed to take one argument."
+                     }
+          , returns = "The input list transformed item-wise by the lambda expression."
+          )
+  public static class Map extends BaseStellarFunction {
+
+    @Override
+    public Object apply(List<Object> args) {
+      List<Object> input = (List<Object>) args.get(0);
+      LambdaExpression expression = (LambdaExpression)args.get(1);
+      if(input == null || expression == null) {
+        return input;
+      }
+      List<Object> ret = new ArrayList<>();
+      for(Object o : input) {
+        ret.add(expression.apply(listOf(o)));
+      }
+      return ret;
+    }
+  }
+
+  @Stellar(name="FILTER"
+          , description="Applies a filter in the form of a lambda expression to a list. e.g. FILTER( [ 'foo', 'bar' ] , (x) -> x == 'foo') would yield [ 'foo']"
+          , params = {
+                      "list - List of arguments."
+                     ,"predicate - The lambda expression to apply.  This expression is assumed to take one argument and return a boolean."
+                     }
+          , returns = "The input list filtered by the predicate."
+          )
+  public static class Filter extends BaseStellarFunction {
+
+    @Override
+    public Object apply(List<Object> args) {
+      List<Object> input = (List<Object>) args.get(0);
+      LambdaExpression expression = (LambdaExpression) args.get(1);
+      if(input == null || expression == null) {
+        return input;
+      }
+      List<Object> ret = new ArrayList<>();
+      for(Object o : input) {
+        Object result = expression.apply(listOf(o));
+        if(result != null && result instanceof Boolean && (Boolean)result) {
+          ret.add(o);
+        }
+      }
+      return ret;
+    }
+  }
+
+  @Stellar(name="REDUCE"
+          , description="Reduces a list by a binary lambda expression. That is, the expression takes two arguments.  Usage example: REDUCE( [ 1, 2, 3 ] , (x, y) -> x + y) would sum the input list, yielding 6."
+          , params = {
+                      "list - List of arguments."
+                     ,"binary_operation - The lambda expression function to apply to reduce the list. It is assumed that this takes two arguments, the first being the running total and the second being an item from the list."
+                     ,"initial_value - The initial value to use."
+                     }
+          , returns = "The reduction of the list."
+          )
+  public static class Reduce extends BaseStellarFunction {
+
+    @Override
+    public Object apply(List<Object> args) {
+      List<Object> input = (List<Object>) args.get(0);
+      if(input == null || input.size() < 3) {
+        return null;
+      }
+      LambdaExpression expression = (LambdaExpression) args.get(1);
+
+      Object runningResult = args.get(2);
+      if(expression == null || runningResult == null) {
+        return null;
+      }
+      for(int i = 0;i < input.size();++i) {
+        Object rhs = input.get(i);
+        runningResult = expression.apply(listOf(runningResult, rhs));
+      }
+      return runningResult;
+    }
+  }
+
+  private static List<Object> listOf(Object... vals) {
+    List<Object> ret = new ArrayList<>(vals.length);
+    for(int i = 0;i < vals.length;++i) {
+      ret.add(vals[i]);
+    }
+    return ret;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/LambdaExpression.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/LambdaExpression.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/LambdaExpression.java
new file mode 100644
index 0000000..f5b0f07
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/LambdaExpression.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.metron.common.stellar;
+
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.dsl.VariableResolver;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+
+public class LambdaExpression extends StellarCompiler.Expression {
+  StellarCompiler.ExpressionState state;
+  List<String> variables;
+  public LambdaExpression(List<String> variables, Deque<Token<?>> tokenDeque, StellarCompiler.ExpressionState state) {
+    super(tokenDeque);
+    this.state = state;
+    this.variables = variables;
+  }
+
+  @Override
+  public Deque<Token<?>> getTokenDeque() {
+    Deque<Token<?>> ret = new ArrayDeque<>(super.getTokenDeque().size());
+    for(Token<?> token : super.getTokenDeque()) {
+      ret.add(token);
+    }
+    return ret;
+  }
+
+  public Object apply(List<Object> variableArgs) {
+    Map<String, Object> lambdaVariables = new HashMap<>();
+    int i = 0;
+    for(;i < Math.min(variables.size(),variableArgs.size()) ;++i) {
+      lambdaVariables.put(variables.get(i), variableArgs.get(i));
+    }
+    for(;i < variables.size();++i) {
+      lambdaVariables.put(variables.get(i), null);
+    }
+
+    VariableResolver variableResolver = variable -> lambdaVariables.getOrDefault(variable
+                                                                                , state.variableResolver.resolve(variable)
+                                                                                );
+    StellarCompiler.ExpressionState localState = new StellarCompiler.ExpressionState(
+            state.context
+          , state.functionResolver
+          , variableResolver);
+    return apply(localState);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java
index 1c37009..044b25a 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/StellarCompiler.java
@@ -33,11 +33,15 @@ import org.apache.metron.common.dsl.ParseException;
 import org.apache.metron.common.dsl.StellarFunction;
 import org.apache.metron.common.utils.ConversionUtils;
 
+import java.io.Serializable;
 import java.util.*;
 
 import static java.lang.String.format;
 
 public class StellarCompiler extends StellarBaseListener {
+  private static Token<?> EXPRESSION_REFERENCE = new Token<>(null, Object.class);
+  private static Token<?> LAMBDA_VARIABLES = new Token<>(null, Object.class);
+
   private Expression expression;
   private final ArithmeticEvaluator arithmeticEvaluator;
   private final NumberLiteralEvaluator numberLiteralEvaluator;
@@ -57,17 +61,21 @@ public class StellarCompiler extends StellarBaseListener {
     }
   }
 
-  public static class Expression {
+  public static class Expression implements Serializable {
     final Deque<Token<?>> tokenDeque;
     final Set<String> variablesUsed;
-    Expression(Deque<Token<?>> tokenDeque) {
+    public Expression(Deque<Token<?>> tokenDeque) {
       this.tokenDeque = tokenDeque;
       this.variablesUsed = new HashSet<>();
     }
 
+    public Deque<Token<?>> getTokenDeque() {
+      return tokenDeque;
+    }
+
     public Object apply(ExpressionState state) {
       Deque<Token<?>> instanceDeque = new ArrayDeque<>();
-      for(Iterator<Token<?>> it = tokenDeque.descendingIterator();it.hasNext();) {
+      for(Iterator<Token<?>> it = getTokenDeque().descendingIterator();it.hasNext();) {
         Token<?> token = it.next();
         if(token.getUnderlyingType() == DeferredFunction.class) {
           DeferredFunction func = (DeferredFunction) token.getValue();
@@ -322,6 +330,82 @@ public class StellarCompiler extends StellarBaseListener {
     return op.op(l, r);
   }
 
+
+  @Override
+  public void enterSingle_lambda_variable(StellarParser.Single_lambda_variableContext ctx) {
+    enterLambdaVariables();
+  }
+
+  @Override
+  public void exitSingle_lambda_variable(StellarParser.Single_lambda_variableContext ctx) {
+    exitLambdaVariables();
+  }
+
+  @Override
+  public void enterLambda_variables(StellarParser.Lambda_variablesContext ctx) {
+    enterLambdaVariables();
+  }
+
+  @Override
+  public void exitLambda_variables(StellarParser.Lambda_variablesContext ctx) {
+    exitLambdaVariables();
+  }
+
+  @Override
+  public void exitLambda_variable(StellarParser.Lambda_variableContext ctx) {
+    expression.tokenDeque.push(new Token<>(ctx.getText(), String.class));
+  }
+
+  private void enterLambdaVariables() {
+    expression.tokenDeque.push(LAMBDA_VARIABLES);
+  }
+
+  private void exitLambdaVariables() {
+    Token<?> t = expression.tokenDeque.pop();
+    LinkedList<String> variables = new LinkedList<>();
+    for(; !expression.tokenDeque.isEmpty() && t != LAMBDA_VARIABLES; t = expression.tokenDeque.pop()) {
+      variables.addFirst(t.getValue().toString());
+    }
+    expression.tokenDeque.push(new Token<>(variables, List.class));
+  }
+
+  private void enterLambda() {
+    expression.tokenDeque.push(EXPRESSION_REFERENCE);
+  }
+
+  private void exitLambda(boolean hasArgs) {
+    Token<?> t = expression.tokenDeque.pop();
+    final Deque<Token<?>> instanceDeque = new ArrayDeque<>();
+    for(; !expression.tokenDeque.isEmpty() && t != EXPRESSION_REFERENCE; t = expression.tokenDeque.pop()) {
+      instanceDeque.addLast(t);
+    }
+    final List<String> variables = hasArgs? (List<String>) instanceDeque.removeLast().getValue() :new ArrayList<>();
+    expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> {
+      LambdaExpression expr = new LambdaExpression(variables, instanceDeque, state);
+      tokenDeque.push(new Token<>(expr, Object.class));
+    }, DeferredFunction.class) );
+  }
+
+  @Override
+  public void enterLambda_with_args(StellarParser.Lambda_with_argsContext ctx) {
+    enterLambda();
+  }
+
+  @Override
+  public void exitLambda_with_args(StellarParser.Lambda_with_argsContext ctx) {
+    exitLambda(true);
+  }
+
+  @Override
+  public void enterLambda_without_args(StellarParser.Lambda_without_argsContext ctx) {
+    enterLambda();
+  }
+
+  @Override
+  public void exitLambda_without_args(StellarParser.Lambda_without_argsContext ctx) {
+    exitLambda(false);
+  }
+
   @Override
   public void exitTransformationFunc(StellarParser.TransformationFuncContext ctx) {
 

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java
index c13930d..2be710b 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarBaseListener.java
@@ -553,6 +553,30 @@ public class StellarBaseListener implements StellarListener {
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
+	@Override public void enterLambdaWithArgsExpr(StellarParser.LambdaWithArgsExprContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitLambdaWithArgsExpr(StellarParser.LambdaWithArgsExprContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterLambdaWithoutArgsExpr(StellarParser.LambdaWithoutArgsExprContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitLambdaWithoutArgsExpr(StellarParser.LambdaWithoutArgsExprContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
 	@Override public void enterArithmeticOperands(StellarParser.ArithmeticOperandsContext ctx) { }
 	/**
 	 * {@inheritDoc}
@@ -632,6 +656,66 @@ public class StellarBaseListener implements StellarListener {
 	 * <p>The default implementation does nothing.</p>
 	 */
 	@Override public void exitCondExpr_paren(StellarParser.CondExpr_parenContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterLambda_without_args(StellarParser.Lambda_without_argsContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitLambda_without_args(StellarParser.Lambda_without_argsContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterLambda_with_args(StellarParser.Lambda_with_argsContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitLambda_with_args(StellarParser.Lambda_with_argsContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterLambda_variables(StellarParser.Lambda_variablesContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitLambda_variables(StellarParser.Lambda_variablesContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterSingle_lambda_variable(StellarParser.Single_lambda_variableContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitSingle_lambda_variable(StellarParser.Single_lambda_variableContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterLambda_variable(StellarParser.Lambda_variableContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitLambda_variable(StellarParser.Lambda_variableContext ctx) { }
 
 	/**
 	 * {@inheritDoc}

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

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/ab80e7b1/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java
index bf3c272..66493f7 100644
--- a/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/stellar/generated/StellarListener.java
@@ -529,6 +529,30 @@ public interface StellarListener extends ParseTreeListener {
 	 */
 	void exitLogicalConst(StellarParser.LogicalConstContext ctx);
 	/**
+	 * Enter a parse tree produced by the {@code LambdaWithArgsExpr}
+	 * labeled alternative in {@link StellarParser#identifier_operand}.
+	 * @param ctx the parse tree
+	 */
+	void enterLambdaWithArgsExpr(StellarParser.LambdaWithArgsExprContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code LambdaWithArgsExpr}
+	 * labeled alternative in {@link StellarParser#identifier_operand}.
+	 * @param ctx the parse tree
+	 */
+	void exitLambdaWithArgsExpr(StellarParser.LambdaWithArgsExprContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code LambdaWithoutArgsExpr}
+	 * labeled alternative in {@link StellarParser#identifier_operand}.
+	 * @param ctx the parse tree
+	 */
+	void enterLambdaWithoutArgsExpr(StellarParser.LambdaWithoutArgsExprContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code LambdaWithoutArgsExpr}
+	 * labeled alternative in {@link StellarParser#identifier_operand}.
+	 * @param ctx the parse tree
+	 */
+	void exitLambdaWithoutArgsExpr(StellarParser.LambdaWithoutArgsExprContext ctx);
+	/**
 	 * Enter a parse tree produced by the {@code ArithmeticOperands}
 	 * labeled alternative in {@link StellarParser#identifier_operand}.
 	 * @param ctx the parse tree
@@ -612,4 +636,54 @@ public interface StellarListener extends ParseTreeListener {
 	 * @param ctx the parse tree
 	 */
 	void exitCondExpr_paren(StellarParser.CondExpr_parenContext ctx);
+	/**
+	 * Enter a parse tree produced by {@link StellarParser#lambda_without_args}.
+	 * @param ctx the parse tree
+	 */
+	void enterLambda_without_args(StellarParser.Lambda_without_argsContext ctx);
+	/**
+	 * Exit a parse tree produced by {@link StellarParser#lambda_without_args}.
+	 * @param ctx the parse tree
+	 */
+	void exitLambda_without_args(StellarParser.Lambda_without_argsContext ctx);
+	/**
+	 * Enter a parse tree produced by {@link StellarParser#lambda_with_args}.
+	 * @param ctx the parse tree
+	 */
+	void enterLambda_with_args(StellarParser.Lambda_with_argsContext ctx);
+	/**
+	 * Exit a parse tree produced by {@link StellarParser#lambda_with_args}.
+	 * @param ctx the parse tree
+	 */
+	void exitLambda_with_args(StellarParser.Lambda_with_argsContext ctx);
+	/**
+	 * Enter a parse tree produced by {@link StellarParser#lambda_variables}.
+	 * @param ctx the parse tree
+	 */
+	void enterLambda_variables(StellarParser.Lambda_variablesContext ctx);
+	/**
+	 * Exit a parse tree produced by {@link StellarParser#lambda_variables}.
+	 * @param ctx the parse tree
+	 */
+	void exitLambda_variables(StellarParser.Lambda_variablesContext ctx);
+	/**
+	 * Enter a parse tree produced by {@link StellarParser#single_lambda_variable}.
+	 * @param ctx the parse tree
+	 */
+	void enterSingle_lambda_variable(StellarParser.Single_lambda_variableContext ctx);
+	/**
+	 * Exit a parse tree produced by {@link StellarParser#single_lambda_variable}.
+	 * @param ctx the parse tree
+	 */
+	void exitSingle_lambda_variable(StellarParser.Single_lambda_variableContext ctx);
+	/**
+	 * Enter a parse tree produced by {@link StellarParser#lambda_variable}.
+	 * @param ctx the parse tree
+	 */
+	void enterLambda_variable(StellarParser.Lambda_variableContext ctx);
+	/**
+	 * Exit a parse tree produced by {@link StellarParser#lambda_variable}.
+	 * @param ctx the parse tree
+	 */
+	void exitLambda_variable(StellarParser.Lambda_variableContext ctx);
 }
\ No newline at end of file