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/11/30 20:19:40 UTC

[1/2] metron git commit: METRON-1277 Add match statement to Stellar language closes apache/incubator-metron#814

Repository: metron
Updated Branches:
  refs/heads/master f08440481 -> c749b5173


http://git-wip-us.apache.org/repos/asf/metron/blob/c749b517/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
index 3ee2603..3bd4ad1 100644
--- a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
+++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarParser.java
@@ -40,10 +40,10 @@ public class StellarParser extends Parser {
 		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, NAN=24, 
-		MINUS=25, PLUS=26, DIV=27, MUL=28, LBRACE=29, RBRACE=30, LBRACKET=31, 
-		RBRACKET=32, LPAREN=33, RPAREN=34, NIN=35, EXISTS=36, EXPONENT=37, INT_LITERAL=38, 
-		DOUBLE_LITERAL=39, FLOAT_LITERAL=40, LONG_LITERAL=41, IDENTIFIER=42, STRING_LITERAL=43, 
-		COMMENT=44, WS=45;
+		MATCH=25, DEFAULT=26, MATCH_ACTION=27, MINUS=28, PLUS=29, DIV=30, MUL=31, 
+		LBRACE=32, RBRACE=33, LBRACKET=34, RBRACKET=35, LPAREN=36, RPAREN=37, 
+		NIN=38, EXISTS=39, EXPONENT=40, INT_LITERAL=41, DOUBLE_LITERAL=42, FLOAT_LITERAL=43, 
+		LONG_LITERAL=44, IDENTIFIER=45, STRING_LITERAL=46, COMMENT=47, WS=48;
 	public static final int
 		RULE_transformation = 0, RULE_transformation_expr = 1, RULE_if_expr = 2, 
 		RULE_then_expr = 3, RULE_else_expr = 4, RULE_conditional_expr = 5, RULE_logical_expr = 6, 
@@ -51,30 +51,35 @@ public class StellarParser extends Parser {
 		RULE_comp_operator = 11, RULE_func_args = 12, RULE_op_list = 13, RULE_list_entity = 14, 
 		RULE_kv_list = 15, RULE_map_entity = 16, RULE_arithmetic_expr = 17, RULE_arithmetic_expr_mul = 18, 
 		RULE_functions = 19, RULE_arithmetic_operands = 20, RULE_identifier_operand = 21, 
-		RULE_lambda_without_args = 22, RULE_lambda_with_args = 23, RULE_lambda_variables = 24, 
-		RULE_single_lambda_variable = 25, RULE_lambda_variable = 26;
+		RULE_default_operand = 22, RULE_lambda_without_args = 23, RULE_lambda_with_args = 24, 
+		RULE_lambda_variables = 25, RULE_single_lambda_variable = 26, RULE_lambda_variable = 27, 
+		RULE_match_expr = 28, RULE_match_clauses = 29, RULE_match_clause = 30, 
+		RULE_match_clause_action = 31, RULE_match_clause_check = 32;
 	public static final String[] ruleNames = {
 		"transformation", "transformation_expr", "if_expr", "then_expr", "else_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", "lambda_without_args", "lambda_with_args", 
-		"lambda_variables", "single_lambda_variable", "lambda_variable"
+		"arithmetic_operands", "identifier_operand", "default_operand", "lambda_without_args", 
+		"lambda_with_args", "lambda_variables", "single_lambda_variable", "lambda_variable", 
+		"match_expr", "match_clauses", "match_clause", "match_clause_action", 
+		"match_clause_check"
 	};
 
 	private static final String[] _LITERAL_NAMES = {
 		null, null, "'->'", "'\"'", "'''", "','", "'.'", null, null, null, null, 
 		null, "'=='", "'!='", "'<'", "'<='", "'>'", "'>='", "'?'", "':'", null, 
-		null, null, null, "'NaN'", "'-'", "'+'", "'/'", "'*'", "'{'", "'}'", "'['", 
-		"']'", "'('", "')'"
+		null, null, null, "'NaN'", null, null, "'=>'", "'-'", "'+'", "'/'", "'*'", 
+		"'{'", "'}'", "'['", "']'", "'('", "')'"
 	};
 	private static final String[] _SYMBOLIC_NAMES = {
 		null, "IN", "LAMBDA_OP", "DOUBLE_QUOTE", "SINGLE_QUOTE", "COMMA", "PERIOD", 
 		"AND", "OR", "NOT", "TRUE", "FALSE", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", 
-		"QUESTION", "COLON", "IF", "THEN", "ELSE", "NULL", "NAN", "MINUS", "PLUS", 
-		"DIV", "MUL", "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "LPAREN", "RPAREN", 
-		"NIN", "EXISTS", "EXPONENT", "INT_LITERAL", "DOUBLE_LITERAL", "FLOAT_LITERAL", 
-		"LONG_LITERAL", "IDENTIFIER", "STRING_LITERAL", "COMMENT", "WS"
+		"QUESTION", "COLON", "IF", "THEN", "ELSE", "NULL", "NAN", "MATCH", "DEFAULT", 
+		"MATCH_ACTION", "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"
 	};
 	public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
 
@@ -150,9 +155,9 @@ public class StellarParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(54);
+			setState(66);
 			transformation_expr();
-			setState(55);
+			setState(67);
 			match(EOF);
 			}
 		}
@@ -278,18 +283,32 @@ public class StellarParser extends Parser {
 			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitConditionalExpr(this);
 		}
 	}
+	public static class MatchExprContext extends Transformation_exprContext {
+		public Match_exprContext match_expr() {
+			return getRuleContext(Match_exprContext.class,0);
+		}
+		public MatchExprContext(Transformation_exprContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterMatchExpr(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitMatchExpr(this);
+		}
+	}
 
 	public final Transformation_exprContext transformation_expr() throws RecognitionException {
 		Transformation_exprContext _localctx = new Transformation_exprContext(_ctx, getState());
 		enterRule(_localctx, 2, RULE_transformation_expr);
 		try {
-			setState(67);
+			setState(80);
 			switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) {
 			case 1:
 				_localctx = new ConditionalExprContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(57);
+				setState(69);
 				conditional_expr();
 				}
 				break;
@@ -297,11 +316,11 @@ public class StellarParser extends Parser {
 				_localctx = new TransformationExprContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(58);
+				setState(70);
 				match(LPAREN);
-				setState(59);
+				setState(71);
 				transformation_expr();
-				setState(60);
+				setState(72);
 				match(RPAREN);
 				}
 				break;
@@ -309,7 +328,7 @@ public class StellarParser extends Parser {
 				_localctx = new ArithExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(62);
+				setState(74);
 				arithmetic_expr(0);
 				}
 				break;
@@ -317,7 +336,7 @@ public class StellarParser extends Parser {
 				_localctx = new TransformationEntityContext(_localctx);
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(63);
+				setState(75);
 				transformation_entity();
 				}
 				break;
@@ -325,7 +344,7 @@ public class StellarParser extends Parser {
 				_localctx = new ComparisonExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(64);
+				setState(76);
 				comparison_expr(0);
 				}
 				break;
@@ -333,7 +352,7 @@ public class StellarParser extends Parser {
 				_localctx = new LogicalExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(65);
+				setState(77);
 				logical_expr();
 				}
 				break;
@@ -341,10 +360,18 @@ public class StellarParser extends Parser {
 				_localctx = new InExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(66);
+				setState(78);
 				in_expr();
 				}
 				break;
+			case 8:
+				_localctx = new MatchExprContext(_localctx);
+				enterOuterAlt(_localctx, 8);
+				{
+				setState(79);
+				match_expr();
+				}
+				break;
 			}
 		}
 		catch (RecognitionException re) {
@@ -382,7 +409,7 @@ public class StellarParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(69);
+			setState(82);
 			logical_expr();
 			}
 		}
@@ -421,7 +448,7 @@ public class StellarParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(71);
+			setState(84);
 			transformation_expr();
 			}
 		}
@@ -460,7 +487,7 @@ public class StellarParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(73);
+			setState(86);
 			transformation_expr();
 			}
 		}
@@ -536,7 +563,7 @@ public class StellarParser extends Parser {
 		Conditional_exprContext _localctx = new Conditional_exprContext(_ctx, getState());
 		enterRule(_localctx, 10, RULE_conditional_expr);
 		try {
-			setState(88);
+			setState(101);
 			switch (_input.LA(1)) {
 			case NOT:
 			case TRUE:
@@ -556,15 +583,15 @@ public class StellarParser extends Parser {
 				_localctx = new TernaryFuncWithoutIfContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(75);
+				setState(88);
 				if_expr();
-				setState(76);
+				setState(89);
 				match(QUESTION);
-				setState(77);
+				setState(90);
 				then_expr();
-				setState(78);
+				setState(91);
 				match(COLON);
-				setState(79);
+				setState(92);
 				else_expr();
 				}
 				break;
@@ -572,17 +599,17 @@ public class StellarParser extends Parser {
 				_localctx = new TernaryFuncWithIfContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(81);
+				setState(94);
 				match(IF);
-				setState(82);
+				setState(95);
 				if_expr();
-				setState(83);
+				setState(96);
 				match(THEN);
-				setState(84);
+				setState(97);
 				then_expr();
-				setState(85);
+				setState(98);
 				match(ELSE);
-				setState(86);
+				setState(99);
 				else_expr();
 				}
 				break;
@@ -667,17 +694,17 @@ public class StellarParser extends Parser {
 		Logical_exprContext _localctx = new Logical_exprContext(_ctx, getState());
 		enterRule(_localctx, 12, RULE_logical_expr);
 		try {
-			setState(99);
+			setState(112);
 			switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) {
 			case 1:
 				_localctx = new LogicalExpressionAndContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(90);
+				setState(103);
 				b_expr();
-				setState(91);
+				setState(104);
 				match(AND);
-				setState(92);
+				setState(105);
 				logical_expr();
 				}
 				break;
@@ -685,11 +712,11 @@ public class StellarParser extends Parser {
 				_localctx = new LogicalExpressionOrContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(94);
+				setState(107);
 				b_expr();
-				setState(95);
+				setState(108);
 				match(OR);
-				setState(96);
+				setState(109);
 				logical_expr();
 				}
 				break;
@@ -697,7 +724,7 @@ public class StellarParser extends Parser {
 				_localctx = new BoleanExpressionContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(98);
+				setState(111);
 				b_expr();
 				}
 				break;
@@ -739,19 +766,19 @@ public class StellarParser extends Parser {
 		B_exprContext _localctx = new B_exprContext(_ctx, getState());
 		enterRule(_localctx, 14, RULE_b_expr);
 		try {
-			setState(103);
+			setState(116);
 			switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(101);
+				setState(114);
 				comparison_expr(0);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(102);
+				setState(115);
 				in_expr();
 				}
 				break;
@@ -820,17 +847,17 @@ public class StellarParser extends Parser {
 		In_exprContext _localctx = new In_exprContext(_ctx, getState());
 		enterRule(_localctx, 16, RULE_in_expr);
 		try {
-			setState(113);
+			setState(126);
 			switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
 			case 1:
 				_localctx = new InExpressionStatementContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(105);
+				setState(118);
 				identifier_operand();
-				setState(106);
+				setState(119);
 				match(IN);
-				setState(107);
+				setState(120);
 				b_expr();
 				}
 				break;
@@ -838,11 +865,11 @@ public class StellarParser extends Parser {
 				_localctx = new NInExpressionStatementContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(109);
+				setState(122);
 				identifier_operand();
-				setState(110);
+				setState(123);
 				match(NIN);
-				setState(111);
+				setState(124);
 				b_expr();
 				}
 				break;
@@ -953,7 +980,7 @@ public class StellarParser extends Parser {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(126);
+			setState(139);
 			switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) {
 			case 1:
 				{
@@ -961,13 +988,13 @@ public class StellarParser extends Parser {
 				_ctx = _localctx;
 				_prevctx = _localctx;
 
-				setState(116);
+				setState(129);
 				match(NOT);
-				setState(117);
+				setState(130);
 				match(LPAREN);
-				setState(118);
+				setState(131);
 				logical_expr();
-				setState(119);
+				setState(132);
 				match(RPAREN);
 				}
 				break;
@@ -976,11 +1003,11 @@ public class StellarParser extends Parser {
 				_localctx = new ComparisonExpressionParensContext(_localctx);
 				_ctx = _localctx;
 				_prevctx = _localctx;
-				setState(121);
+				setState(134);
 				match(LPAREN);
-				setState(122);
+				setState(135);
 				logical_expr();
-				setState(123);
+				setState(136);
 				match(RPAREN);
 				}
 				break;
@@ -989,13 +1016,13 @@ public class StellarParser extends Parser {
 				_localctx = new OperandContext(_localctx);
 				_ctx = _localctx;
 				_prevctx = _localctx;
-				setState(125);
+				setState(138);
 				identifier_operand();
 				}
 				break;
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(134);
+			setState(147);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,6,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1006,16 +1033,16 @@ public class StellarParser extends Parser {
 					{
 					_localctx = new ComparisonExpressionWithOperatorContext(new Comparison_exprContext(_parentctx, _parentState));
 					pushNewRecursionContext(_localctx, _startState, RULE_comparison_expr);
-					setState(128);
+					setState(141);
 					if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
-					setState(129);
+					setState(142);
 					comp_operator();
-					setState(130);
+					setState(143);
 					comparison_expr(5);
 					}
 					} 
 				}
-				setState(136);
+				setState(149);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,6,_ctx);
 			}
@@ -1056,7 +1083,7 @@ public class StellarParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(137);
+			setState(150);
 			identifier_operand();
 			}
 		}
@@ -1108,7 +1135,7 @@ public class StellarParser extends Parser {
 			_localctx = new ComparisonOpContext(_localctx);
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(139);
+			setState(152);
 			_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);
@@ -1152,25 +1179,25 @@ public class StellarParser extends Parser {
 		Func_argsContext _localctx = new Func_argsContext(_ctx, getState());
 		enterRule(_localctx, 24, RULE_func_args);
 		try {
-			setState(147);
+			setState(160);
 			switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(141);
+				setState(154);
 				match(LPAREN);
-				setState(142);
+				setState(155);
 				op_list(0);
-				setState(143);
+				setState(156);
 				match(RPAREN);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(145);
+				setState(158);
 				match(LPAREN);
-				setState(146);
+				setState(159);
 				match(RPAREN);
 				}
 				break;
@@ -1230,29 +1257,29 @@ public class StellarParser extends Parser {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(153);
+			setState(166);
 			switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) {
 			case 1:
 				{
-				setState(150);
+				setState(163);
 				identifier_operand();
 				}
 				break;
 			case 2:
 				{
-				setState(151);
+				setState(164);
 				conditional_expr();
 				}
 				break;
 			case 3:
 				{
-				setState(152);
+				setState(165);
 				comparison_expr(0);
 				}
 				break;
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(166);
+			setState(179);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,10,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1260,17 +1287,17 @@ public class StellarParser extends Parser {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
 					_prevctx = _localctx;
 					{
-					setState(164);
+					setState(177);
 					switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) {
 					case 1:
 						{
 						_localctx = new Op_listContext(_parentctx, _parentState);
 						pushNewRecursionContext(_localctx, _startState, RULE_op_list);
-						setState(155);
+						setState(168);
 						if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)");
-						setState(156);
+						setState(169);
 						match(COMMA);
-						setState(157);
+						setState(170);
 						identifier_operand();
 						}
 						break;
@@ -1278,11 +1305,11 @@ public class StellarParser extends Parser {
 						{
 						_localctx = new Op_listContext(_parentctx, _parentState);
 						pushNewRecursionContext(_localctx, _startState, RULE_op_list);
-						setState(158);
+						setState(171);
 						if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
-						setState(159);
+						setState(172);
 						match(COMMA);
-						setState(160);
+						setState(173);
 						conditional_expr();
 						}
 						break;
@@ -1290,18 +1317,18 @@ public class StellarParser extends Parser {
 						{
 						_localctx = new Op_listContext(_parentctx, _parentState);
 						pushNewRecursionContext(_localctx, _startState, RULE_op_list);
-						setState(161);
+						setState(174);
 						if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-						setState(162);
+						setState(175);
 						match(COMMA);
-						setState(163);
+						setState(176);
 						comparison_expr(0);
 						}
 						break;
 					}
 					} 
 				}
-				setState(168);
+				setState(181);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,10,_ctx);
 			}
@@ -1342,25 +1369,25 @@ public class StellarParser extends Parser {
 		List_entityContext _localctx = new List_entityContext(_ctx, getState());
 		enterRule(_localctx, 28, RULE_list_entity);
 		try {
-			setState(175);
+			setState(188);
 			switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(169);
+				setState(182);
 				match(LBRACKET);
-				setState(170);
+				setState(183);
 				match(RBRACKET);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(171);
+				setState(184);
 				match(LBRACKET);
-				setState(172);
+				setState(185);
 				op_list(0);
-				setState(173);
+				setState(186);
 				match(RBRACKET);
 				}
 				break;
@@ -1421,31 +1448,31 @@ public class StellarParser extends Parser {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(186);
+			setState(199);
 			switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) {
 			case 1:
 				{
-				setState(178);
+				setState(191);
 				identifier_operand();
-				setState(179);
+				setState(192);
 				match(COLON);
-				setState(180);
+				setState(193);
 				transformation_expr();
 				}
 				break;
 			case 2:
 				{
-				setState(182);
+				setState(195);
 				comparison_expr(0);
-				setState(183);
+				setState(196);
 				match(COLON);
-				setState(184);
+				setState(197);
 				transformation_expr();
 				}
 				break;
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(202);
+			setState(215);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,14,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1453,21 +1480,21 @@ public class StellarParser extends Parser {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
 					_prevctx = _localctx;
 					{
-					setState(200);
+					setState(213);
 					switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) {
 					case 1:
 						{
 						_localctx = new Kv_listContext(_parentctx, _parentState);
 						pushNewRecursionContext(_localctx, _startState, RULE_kv_list);
-						setState(188);
+						setState(201);
 						if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
-						setState(189);
+						setState(202);
 						match(COMMA);
-						setState(190);
+						setState(203);
 						identifier_operand();
-						setState(191);
+						setState(204);
 						match(COLON);
-						setState(192);
+						setState(205);
 						transformation_expr();
 						}
 						break;
@@ -1475,22 +1502,22 @@ public class StellarParser extends Parser {
 						{
 						_localctx = new Kv_listContext(_parentctx, _parentState);
 						pushNewRecursionContext(_localctx, _startState, RULE_kv_list);
-						setState(194);
+						setState(207);
 						if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-						setState(195);
+						setState(208);
 						match(COMMA);
-						setState(196);
+						setState(209);
 						comparison_expr(0);
-						setState(197);
+						setState(210);
 						match(COLON);
-						setState(198);
+						setState(211);
 						transformation_expr();
 						}
 						break;
 					}
 					} 
 				}
-				setState(204);
+				setState(217);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,14,_ctx);
 			}
@@ -1531,25 +1558,25 @@ public class StellarParser extends Parser {
 		Map_entityContext _localctx = new Map_entityContext(_ctx, getState());
 		enterRule(_localctx, 32, RULE_map_entity);
 		try {
-			setState(211);
+			setState(224);
 			switch ( getInterpreter().adaptivePredict(_input,15,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(205);
+				setState(218);
 				match(LBRACE);
-				setState(206);
+				setState(219);
 				kv_list(0);
-				setState(207);
+				setState(220);
 				match(RBRACE);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(209);
+				setState(222);
 				match(LBRACE);
-				setState(210);
+				setState(223);
 				match(RBRACE);
 				}
 				break;
@@ -1648,11 +1675,11 @@ public class StellarParser extends Parser {
 			_ctx = _localctx;
 			_prevctx = _localctx;
 
-			setState(214);
+			setState(227);
 			arithmetic_expr_mul(0);
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(224);
+			setState(237);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,17,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1660,17 +1687,17 @@ public class StellarParser extends Parser {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
 					_prevctx = _localctx;
 					{
-					setState(222);
+					setState(235);
 					switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) {
 					case 1:
 						{
 						_localctx = new ArithExpr_plusContext(new Arithmetic_exprContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_arithmetic_expr);
-						setState(216);
+						setState(229);
 						if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
-						setState(217);
+						setState(230);
 						match(PLUS);
-						setState(218);
+						setState(231);
 						arithmetic_expr_mul(0);
 						}
 						break;
@@ -1678,18 +1705,18 @@ public class StellarParser extends Parser {
 						{
 						_localctx = new ArithExpr_minusContext(new Arithmetic_exprContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_arithmetic_expr);
-						setState(219);
+						setState(232);
 						if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-						setState(220);
+						setState(233);
 						match(MINUS);
-						setState(221);
+						setState(234);
 						arithmetic_expr_mul(0);
 						}
 						break;
 					}
 					} 
 				}
-				setState(226);
+				setState(239);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,17,_ctx);
 			}
@@ -1788,11 +1815,11 @@ public class StellarParser extends Parser {
 			_ctx = _localctx;
 			_prevctx = _localctx;
 
-			setState(228);
+			setState(241);
 			arithmetic_operands();
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(238);
+			setState(251);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,19,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1800,17 +1827,17 @@ public class StellarParser extends Parser {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
 					_prevctx = _localctx;
 					{
-					setState(236);
+					setState(249);
 					switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) {
 					case 1:
 						{
 						_localctx = new ArithExpr_mulContext(new Arithmetic_expr_mulContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_arithmetic_expr_mul);
-						setState(230);
+						setState(243);
 						if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
-						setState(231);
+						setState(244);
 						match(MUL);
-						setState(232);
+						setState(245);
 						arithmetic_expr_mul(3);
 						}
 						break;
@@ -1818,18 +1845,18 @@ public class StellarParser extends Parser {
 						{
 						_localctx = new ArithExpr_divContext(new Arithmetic_expr_mulContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_arithmetic_expr_mul);
-						setState(233);
+						setState(246);
 						if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-						setState(234);
+						setState(247);
 						match(DIV);
-						setState(235);
+						setState(248);
 						arithmetic_expr_mul(2);
 						}
 						break;
 					}
 					} 
 				}
-				setState(240);
+				setState(253);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,19,_ctx);
 			}
@@ -1880,9 +1907,9 @@ public class StellarParser extends Parser {
 			_localctx = new TransformationFuncContext(_localctx);
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(241);
+			setState(254);
 			match(IDENTIFIER);
-			setState(242);
+			setState(255);
 			func_args();
 			}
 		}
@@ -2031,13 +2058,13 @@ public class StellarParser extends Parser {
 		Arithmetic_operandsContext _localctx = new Arithmetic_operandsContext(_ctx, getState());
 		enterRule(_localctx, 40, RULE_arithmetic_operands);
 		try {
-			setState(259);
+			setState(272);
 			switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) {
 			case 1:
 				_localctx = new NumericFunctionsContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(244);
+				setState(257);
 				functions();
 				}
 				break;
@@ -2045,7 +2072,7 @@ public class StellarParser extends Parser {
 				_localctx = new DoubleLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(245);
+				setState(258);
 				match(DOUBLE_LITERAL);
 				}
 				break;
@@ -2053,7 +2080,7 @@ public class StellarParser extends Parser {
 				_localctx = new IntLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(246);
+				setState(259);
 				match(INT_LITERAL);
 				}
 				break;
@@ -2061,7 +2088,7 @@ public class StellarParser extends Parser {
 				_localctx = new LongLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(247);
+				setState(260);
 				match(LONG_LITERAL);
 				}
 				break;
@@ -2069,7 +2096,7 @@ public class StellarParser extends Parser {
 				_localctx = new FloatLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(248);
+				setState(261);
 				match(FLOAT_LITERAL);
 				}
 				break;
@@ -2077,7 +2104,7 @@ public class StellarParser extends Parser {
 				_localctx = new VariableContext(_localctx);
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(249);
+				setState(262);
 				match(IDENTIFIER);
 				}
 				break;
@@ -2085,7 +2112,7 @@ public class StellarParser extends Parser {
 				_localctx = new NaNArithContext(_localctx);
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(250);
+				setState(263);
 				match(NAN);
 				}
 				break;
@@ -2093,11 +2120,11 @@ public class StellarParser extends Parser {
 				_localctx = new ParenArithContext(_localctx);
 				enterOuterAlt(_localctx, 8);
 				{
-				setState(251);
+				setState(264);
 				match(LPAREN);
-				setState(252);
+				setState(265);
 				arithmetic_expr(0);
-				setState(253);
+				setState(266);
 				match(RPAREN);
 				}
 				break;
@@ -2105,11 +2132,11 @@ public class StellarParser extends Parser {
 				_localctx = new CondExprContext(_localctx);
 				enterOuterAlt(_localctx, 9);
 				{
-				setState(255);
+				setState(268);
 				match(LPAREN);
-				setState(256);
+				setState(269);
 				conditional_expr();
-				setState(257);
+				setState(270);
 				match(RPAREN);
 				}
 				break;
@@ -2295,13 +2322,13 @@ public class StellarParser extends Parser {
 		enterRule(_localctx, 42, RULE_identifier_operand);
 		int _la;
 		try {
-			setState(278);
+			setState(291);
 			switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) {
 			case 1:
 				_localctx = new LogicalConstContext(_localctx);
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(261);
+				setState(274);
 				_la = _input.LA(1);
 				if ( !(_la==TRUE || _la==FALSE) ) {
 				_errHandler.recoverInline(this);
@@ -2314,7 +2341,7 @@ public class StellarParser extends Parser {
 				_localctx = new LambdaWithArgsExprContext(_localctx);
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(262);
+				setState(275);
 				lambda_with_args();
 				}
 				break;
@@ -2322,7 +2349,7 @@ public class StellarParser extends Parser {
 				_localctx = new LambdaWithoutArgsExprContext(_localctx);
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(263);
+				setState(276);
 				lambda_without_args();
 				}
 				break;
@@ -2330,7 +2357,7 @@ public class StellarParser extends Parser {
 				_localctx = new ArithmeticOperandsContext(_localctx);
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(264);
+				setState(277);
 				arithmetic_expr(0);
 				}
 				break;
@@ -2338,7 +2365,7 @@ public class StellarParser extends Parser {
 				_localctx = new StringLiteralContext(_localctx);
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(265);
+				setState(278);
 				match(STRING_LITERAL);
 				}
 				break;
@@ -2346,7 +2373,7 @@ public class StellarParser extends Parser {
 				_localctx = new ListContext(_localctx);
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(266);
+				setState(279);
 				list_entity();
 				}
 				break;
@@ -2354,7 +2381,7 @@ public class StellarParser extends Parser {
 				_localctx = new MapConstContext(_localctx);
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(267);
+				setState(280);
 				map_entity();
 				}
 				break;
@@ -2362,7 +2389,7 @@ public class StellarParser extends Parser {
 				_localctx = new NullConstContext(_localctx);
 				enterOuterAlt(_localctx, 8);
 				{
-				setState(268);
+				setState(281);
 				match(NULL);
 				}
 				break;
@@ -2370,13 +2397,13 @@ public class StellarParser extends Parser {
 				_localctx = new ExistsFuncContext(_localctx);
 				enterOuterAlt(_localctx, 9);
 				{
-				setState(269);
+				setState(282);
 				match(EXISTS);
-				setState(270);
+				setState(283);
 				match(LPAREN);
-				setState(271);
+				setState(284);
 				match(IDENTIFIER);
-				setState(272);
+				setState(285);
 				match(RPAREN);
 				}
 				break;
@@ -2384,11 +2411,11 @@ public class StellarParser extends Parser {
 				_localctx = new CondExpr_parenContext(_localctx);
 				enterOuterAlt(_localctx, 10);
 				{
-				setState(273);
+				setState(286);
 				match(LPAREN);
-				setState(274);
+				setState(287);
 				conditional_expr();
-				setState(275);
+				setState(288);
 				match(RPAREN);
 				}
 				break;
@@ -2396,7 +2423,7 @@ public class StellarParser extends Parser {
 				_localctx = new FuncContext(_localctx);
 				enterOuterAlt(_localctx, 11);
 				{
-				setState(277);
+				setState(290);
 				functions();
 				}
 				break;
@@ -2413,6 +2440,52 @@ public class StellarParser extends Parser {
 		return _localctx;
 	}
 
+	public static class Default_operandContext extends ParserRuleContext {
+		public Default_operandContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_default_operand; }
+	 
+		public Default_operandContext() { }
+		public void copyFrom(Default_operandContext ctx) {
+			super.copyFrom(ctx);
+		}
+	}
+	public static class DefaultContext extends Default_operandContext {
+		public TerminalNode DEFAULT() { return getToken(StellarParser.DEFAULT, 0); }
+		public DefaultContext(Default_operandContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterDefault(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitDefault(this);
+		}
+	}
+
+	public final Default_operandContext default_operand() throws RecognitionException {
+		Default_operandContext _localctx = new Default_operandContext(_ctx, getState());
+		enterRule(_localctx, 44, RULE_default_operand);
+		try {
+			_localctx = new DefaultContext(_localctx);
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(293);
+			match(DEFAULT);
+			}
+		}
+		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); }
@@ -2436,17 +2509,17 @@ public class StellarParser extends Parser {
 
 	public final Lambda_without_argsContext lambda_without_args() throws RecognitionException {
 		Lambda_without_argsContext _localctx = new Lambda_without_argsContext(_ctx, getState());
-		enterRule(_localctx, 44, RULE_lambda_without_args);
+		enterRule(_localctx, 46, RULE_lambda_without_args);
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(280);
+			setState(295);
 			match(LPAREN);
-			setState(281);
+			setState(296);
 			match(RPAREN);
-			setState(282);
+			setState(297);
 			match(LAMBDA_OP);
-			setState(283);
+			setState(298);
 			transformation_expr();
 			}
 		}
@@ -2490,33 +2563,33 @@ public class StellarParser extends Parser {
 
 	public final Lambda_with_argsContext lambda_with_args() throws RecognitionException {
 		Lambda_with_argsContext _localctx = new Lambda_with_argsContext(_ctx, getState());
-		enterRule(_localctx, 46, RULE_lambda_with_args);
+		enterRule(_localctx, 48, RULE_lambda_with_args);
 		try {
-			setState(295);
+			setState(310);
 			switch (_input.LA(1)) {
 			case LPAREN:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(285);
+				setState(300);
 				match(LPAREN);
-				setState(286);
+				setState(301);
 				lambda_variables();
-				setState(287);
+				setState(302);
 				match(RPAREN);
-				setState(288);
+				setState(303);
 				match(LAMBDA_OP);
-				setState(289);
+				setState(304);
 				transformation_expr();
 				}
 				break;
 			case IDENTIFIER:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(291);
+				setState(306);
 				single_lambda_variable();
-				setState(292);
+				setState(307);
 				match(LAMBDA_OP);
-				setState(293);
+				setState(308);
 				transformation_expr();
 				}
 				break;
@@ -2562,26 +2635,26 @@ public class StellarParser extends Parser {
 
 	public final Lambda_variablesContext lambda_variables() throws RecognitionException {
 		Lambda_variablesContext _localctx = new Lambda_variablesContext(_ctx, getState());
-		enterRule(_localctx, 48, RULE_lambda_variables);
+		enterRule(_localctx, 50, RULE_lambda_variables);
 		int _la;
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(297);
+			setState(312);
 			lambda_variable();
-			setState(302);
+			setState(317);
 			_errHandler.sync(this);
 			_la = _input.LA(1);
 			while (_la==COMMA) {
 				{
 				{
-				setState(298);
+				setState(313);
 				match(COMMA);
-				setState(299);
+				setState(314);
 				lambda_variable();
 				}
 				}
-				setState(304);
+				setState(319);
 				_errHandler.sync(this);
 				_la = _input.LA(1);
 			}
@@ -2618,11 +2691,11 @@ public class StellarParser extends Parser {
 
 	public final Single_lambda_variableContext single_lambda_variable() throws RecognitionException {
 		Single_lambda_variableContext _localctx = new Single_lambda_variableContext(_ctx, getState());
-		enterRule(_localctx, 50, RULE_single_lambda_variable);
+		enterRule(_localctx, 52, RULE_single_lambda_variable);
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(305);
+			setState(320);
 			lambda_variable();
 			}
 		}
@@ -2655,11 +2728,11 @@ public class StellarParser extends Parser {
 
 	public final Lambda_variableContext lambda_variable() throws RecognitionException {
 		Lambda_variableContext _localctx = new Lambda_variableContext(_ctx, getState());
-		enterRule(_localctx, 52, RULE_lambda_variable);
+		enterRule(_localctx, 54, RULE_lambda_variable);
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(307);
+			setState(322);
 			match(IDENTIFIER);
 			}
 		}
@@ -2674,6 +2747,301 @@ public class StellarParser extends Parser {
 		return _localctx;
 	}
 
+	public static class Match_exprContext extends ParserRuleContext {
+		public Match_exprContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_match_expr; }
+	 
+		public Match_exprContext() { }
+		public void copyFrom(Match_exprContext ctx) {
+			super.copyFrom(ctx);
+		}
+	}
+	public static class MatchClausesContext extends Match_exprContext {
+		public TerminalNode MATCH() { return getToken(StellarParser.MATCH, 0); }
+		public TerminalNode LBRACE() { return getToken(StellarParser.LBRACE, 0); }
+		public Match_clausesContext match_clauses() {
+			return getRuleContext(Match_clausesContext.class,0);
+		}
+		public TerminalNode COMMA() { return getToken(StellarParser.COMMA, 0); }
+		public TerminalNode DEFAULT() { return getToken(StellarParser.DEFAULT, 0); }
+		public TerminalNode MATCH_ACTION() { return getToken(StellarParser.MATCH_ACTION, 0); }
+		public Match_clause_actionContext match_clause_action() {
+			return getRuleContext(Match_clause_actionContext.class,0);
+		}
+		public TerminalNode RBRACE() { return getToken(StellarParser.RBRACE, 0); }
+		public MatchClausesContext(Match_exprContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterMatchClauses(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitMatchClauses(this);
+		}
+	}
+
+	public final Match_exprContext match_expr() throws RecognitionException {
+		Match_exprContext _localctx = new Match_exprContext(_ctx, getState());
+		enterRule(_localctx, 56, RULE_match_expr);
+		try {
+			_localctx = new MatchClausesContext(_localctx);
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(324);
+			match(MATCH);
+			setState(325);
+			match(LBRACE);
+			setState(326);
+			match_clauses();
+			setState(327);
+			match(COMMA);
+			setState(328);
+			match(DEFAULT);
+			setState(329);
+			match(MATCH_ACTION);
+			setState(330);
+			match_clause_action();
+			setState(331);
+			match(RBRACE);
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Match_clausesContext extends ParserRuleContext {
+		public List<Match_clauseContext> match_clause() {
+			return getRuleContexts(Match_clauseContext.class);
+		}
+		public Match_clauseContext match_clause(int i) {
+			return getRuleContext(Match_clauseContext.class,i);
+		}
+		public List<TerminalNode> COMMA() { return getTokens(StellarParser.COMMA); }
+		public TerminalNode COMMA(int i) {
+			return getToken(StellarParser.COMMA, i);
+		}
+		public Match_clausesContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_match_clauses; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterMatch_clauses(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitMatch_clauses(this);
+		}
+	}
+
+	public final Match_clausesContext match_clauses() throws RecognitionException {
+		Match_clausesContext _localctx = new Match_clausesContext(_ctx, getState());
+		enterRule(_localctx, 58, RULE_match_clauses);
+		try {
+			int _alt;
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(333);
+			match_clause();
+			setState(338);
+			_errHandler.sync(this);
+			_alt = getInterpreter().adaptivePredict(_input,24,_ctx);
+			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+				if ( _alt==1 ) {
+					{
+					{
+					setState(334);
+					match(COMMA);
+					setState(335);
+					match_clause();
+					}
+					} 
+				}
+				setState(340);
+				_errHandler.sync(this);
+				_alt = getInterpreter().adaptivePredict(_input,24,_ctx);
+			}
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Match_clauseContext extends ParserRuleContext {
+		public Match_clause_checkContext match_clause_check() {
+			return getRuleContext(Match_clause_checkContext.class,0);
+		}
+		public TerminalNode MATCH_ACTION() { return getToken(StellarParser.MATCH_ACTION, 0); }
+		public Match_clause_actionContext match_clause_action() {
+			return getRuleContext(Match_clause_actionContext.class,0);
+		}
+		public Match_clauseContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_match_clause; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterMatch_clause(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitMatch_clause(this);
+		}
+	}
+
+	public final Match_clauseContext match_clause() throws RecognitionException {
+		Match_clauseContext _localctx = new Match_clauseContext(_ctx, getState());
+		enterRule(_localctx, 60, RULE_match_clause);
+		try {
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(341);
+			match_clause_check();
+			setState(342);
+			match(MATCH_ACTION);
+			setState(343);
+			match_clause_action();
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Match_clause_actionContext extends ParserRuleContext {
+		public Match_clause_actionContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_match_clause_action; }
+	 
+		public Match_clause_actionContext() { }
+		public void copyFrom(Match_clause_actionContext ctx) {
+			super.copyFrom(ctx);
+		}
+	}
+	public static class MatchClauseActionContext extends Match_clause_actionContext {
+		public Transformation_exprContext transformation_expr() {
+			return getRuleContext(Transformation_exprContext.class,0);
+		}
+		public MatchClauseActionContext(Match_clause_actionContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterMatchClauseAction(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitMatchClauseAction(this);
+		}
+	}
+
+	public final Match_clause_actionContext match_clause_action() throws RecognitionException {
+		Match_clause_actionContext _localctx = new Match_clause_actionContext(_ctx, getState());
+		enterRule(_localctx, 62, RULE_match_clause_action);
+		try {
+			_localctx = new MatchClauseActionContext(_localctx);
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(345);
+			transformation_expr();
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
+	public static class Match_clause_checkContext extends ParserRuleContext {
+		public Match_clause_checkContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_match_clause_check; }
+	 
+		public Match_clause_checkContext() { }
+		public void copyFrom(Match_clause_checkContext ctx) {
+			super.copyFrom(ctx);
+		}
+	}
+	public static class MatchClauseCheckExprContext extends Match_clause_checkContext {
+		public Logical_exprContext logical_expr() {
+			return getRuleContext(Logical_exprContext.class,0);
+		}
+		public Conditional_exprContext conditional_expr() {
+			return getRuleContext(Conditional_exprContext.class,0);
+		}
+		public MatchClauseCheckExprContext(Match_clause_checkContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).enterMatchClauseCheckExpr(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof StellarListener ) ((StellarListener)listener).exitMatchClauseCheckExpr(this);
+		}
+	}
+
+	public final Match_clause_checkContext match_clause_check() throws RecognitionException {
+		Match_clause_checkContext _localctx = new Match_clause_checkContext(_ctx, getState());
+		enterRule(_localctx, 64, RULE_match_clause_check);
+		try {
+			setState(349);
+			switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) {
+			case 1:
+				_localctx = new MatchClauseCheckExprContext(_localctx);
+				enterOuterAlt(_localctx, 1);
+				{
+				setState(347);
+				logical_expr();
+				}
+				break;
+			case 2:
+				_localctx = new MatchClauseCheckExprContext(_localctx);
+				enterOuterAlt(_localctx, 2);
+				{
+				setState(348);
+				conditional_expr();
+				}
+				break;
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			exitRule();
+		}
+		return _localctx;
+	}
+
 	public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
 		switch (ruleIndex) {
 		case 9:
@@ -2736,113 +3104,128 @@ public class StellarParser extends Parser {
 	}
 
 	public static final String _serializedATN =
-		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3/\u0138\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"+
+		"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\62\u0162\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\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\3F\n\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7"+
-		"\3\7\3\7\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\5\bf\n\b\3\t\3\t\5\tj\n\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\5\nt\n"+
-		"\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\5\13\u0081\n"+
-		"\13\3\13\3\13\3\13\3\13\7\13\u0087\n\13\f\13\16\13\u008a\13\13\3\f\3\f"+
-		"\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\5\16\u0096\n\16\3\17\3\17\3\17"+
-		"\3\17\5\17\u009c\n\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\7\17"+
-		"\u00a7\n\17\f\17\16\17\u00aa\13\17\3\20\3\20\3\20\3\20\3\20\3\20\5\20"+
-		"\u00b2\n\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\5\21\u00bd\n"+
-		"\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\7\21\u00cb"+
-		"\n\21\f\21\16\21\u00ce\13\21\3\22\3\22\3\22\3\22\3\22\3\22\5\22\u00d6"+
-		"\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\7\23\u00e1\n\23\f\23"+
-		"\16\23\u00e4\13\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\7\24\u00ef"+
-		"\n\24\f\24\16\24\u00f2\13\24\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3"+
-		"\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26\u0106\n\26\3\27"+
+		"\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\"\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\3\3\5"+
+		"\3S\n\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\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\5\bs\n\b\3"+
+		"\t\3\t\5\tw\n\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\5\n\u0081\n\n\3\13\3\13"+
+		"\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\5\13\u008e\n\13\3\13\3\13"+
+		"\3\13\3\13\7\13\u0094\n\13\f\13\16\13\u0097\13\13\3\f\3\f\3\r\3\r\3\16"+
+		"\3\16\3\16\3\16\3\16\3\16\5\16\u00a3\n\16\3\17\3\17\3\17\3\17\5\17\u00a9"+
+		"\n\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\7\17\u00b4\n\17\f\17"+
+		"\16\17\u00b7\13\17\3\20\3\20\3\20\3\20\3\20\3\20\5\20\u00bf\n\20\3\21"+
+		"\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\5\21\u00ca\n\21\3\21\3\21\3\21"+
+		"\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\7\21\u00d8\n\21\f\21\16"+
+		"\21\u00db\13\21\3\22\3\22\3\22\3\22\3\22\3\22\5\22\u00e3\n\22\3\23\3\23"+
+		"\3\23\3\23\3\23\3\23\3\23\3\23\3\23\7\23\u00ee\n\23\f\23\16\23\u00f1\13"+
+		"\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\7\24\u00fc\n\24\f\24"+
+		"\16\24\u00ff\13\24\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3"+
+		"\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26\u0113\n\26\3\27\3\27\3\27"+
 		"\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+
-		"\3\27\3\27\5\27\u0119\n\27\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31"+
-		"\3\31\3\31\3\31\3\31\3\31\3\31\5\31\u012a\n\31\3\32\3\32\3\32\7\32\u012f"+
-		"\n\32\f\32\16\32\u0132\13\32\3\33\3\33\3\34\3\34\3\34\2\7\24\34 $&\35"+
-		"\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\66\2\4\3\2\16"+
-		"\23\3\2\f\r\u014d\28\3\2\2\2\4E\3\2\2\2\6G\3\2\2\2\bI\3\2\2\2\nK\3\2\2"+
-		"\2\fZ\3\2\2\2\16e\3\2\2\2\20i\3\2\2\2\22s\3\2\2\2\24\u0080\3\2\2\2\26"+
-		"\u008b\3\2\2\2\30\u008d\3\2\2\2\32\u0095\3\2\2\2\34\u009b\3\2\2\2\36\u00b1"+
-		"\3\2\2\2 \u00bc\3\2\2\2\"\u00d5\3\2\2\2$\u00d7\3\2\2\2&\u00e5\3\2\2\2"+
-		"(\u00f3\3\2\2\2*\u0105\3\2\2\2,\u0118\3\2\2\2.\u011a\3\2\2\2\60\u0129"+
-		"\3\2\2\2\62\u012b\3\2\2\2\64\u0133\3\2\2\2\66\u0135\3\2\2\289\5\4\3\2"+
-		"9:\7\2\2\3:\3\3\2\2\2;F\5\f\7\2<=\7#\2\2=>\5\4\3\2>?\7$\2\2?F\3\2\2\2"+
-		"@F\5$\23\2AF\5\26\f\2BF\5\24\13\2CF\5\16\b\2DF\5\22\n\2E;\3\2\2\2E<\3"+
-		"\2\2\2E@\3\2\2\2EA\3\2\2\2EB\3\2\2\2EC\3\2\2\2ED\3\2\2\2F\5\3\2\2\2GH"+
-		"\5\16\b\2H\7\3\2\2\2IJ\5\4\3\2J\t\3\2\2\2KL\5\4\3\2L\13\3\2\2\2MN\5\6"+
-		"\4\2NO\7\24\2\2OP\5\b\5\2PQ\7\25\2\2QR\5\n\6\2R[\3\2\2\2ST\7\26\2\2TU"+
-		"\5\6\4\2UV\7\27\2\2VW\5\b\5\2WX\7\30\2\2XY\5\n\6\2Y[\3\2\2\2ZM\3\2\2\2"+
-		"ZS\3\2\2\2[\r\3\2\2\2\\]\5\20\t\2]^\7\t\2\2^_\5\16\b\2_f\3\2\2\2`a\5\20"+
-		"\t\2ab\7\n\2\2bc\5\16\b\2cf\3\2\2\2df\5\20\t\2e\\\3\2\2\2e`\3\2\2\2ed"+
-		"\3\2\2\2f\17\3\2\2\2gj\5\24\13\2hj\5\22\n\2ig\3\2\2\2ih\3\2\2\2j\21\3"+
-		"\2\2\2kl\5,\27\2lm\7\3\2\2mn\5\20\t\2nt\3\2\2\2op\5,\27\2pq\7%\2\2qr\5"+
-		"\20\t\2rt\3\2\2\2sk\3\2\2\2so\3\2\2\2t\23\3\2\2\2uv\b\13\1\2vw\7\13\2"+
-		"\2wx\7#\2\2xy\5\16\b\2yz\7$\2\2z\u0081\3\2\2\2{|\7#\2\2|}\5\16\b\2}~\7"+
-		"$\2\2~\u0081\3\2\2\2\177\u0081\5,\27\2\u0080u\3\2\2\2\u0080{\3\2\2\2\u0080"+
-		"\177\3\2\2\2\u0081\u0088\3\2\2\2\u0082\u0083\f\6\2\2\u0083\u0084\5\30"+
-		"\r\2\u0084\u0085\5\24\13\7\u0085\u0087\3\2\2\2\u0086\u0082\3\2\2\2\u0087"+
-		"\u008a\3\2\2\2\u0088\u0086\3\2\2\2\u0088\u0089\3\2\2\2\u0089\25\3\2\2"+
-		"\2\u008a\u0088\3\2\2\2\u008b\u008c\5,\27\2\u008c\27\3\2\2\2\u008d\u008e"+
-		"\t\2\2\2\u008e\31\3\2\2\2\u008f\u0090\7#\2\2\u0090\u0091\5\34\17\2\u0091"+
-		"\u0092\7$\2\2\u0092\u0096\3\2\2\2\u0093\u0094\7#\2\2\u0094\u0096\7$\2"+
-		"\2\u0095\u008f\3\2\2\2\u0095\u0093\3\2\2\2\u0096\33\3\2\2\2\u0097\u0098"+
-		"\b\17\1\2\u0098\u009c\5,\27\2\u0099\u009c\5\f\7\2\u009a\u009c\5\24\13"+
-		"\2\u009b\u0097\3\2\2\2\u009b\u0099\3\2\2\2\u009b\u009a\3\2\2\2\u009c\u00a8"+
-		"\3\2\2\2\u009d\u009e\f\7\2\2\u009e\u009f\7\7\2\2\u009f\u00a7\5,\27\2\u00a0"+
-		"\u00a1\f\5\2\2\u00a1\u00a2\7\7\2\2\u00a2\u00a7\5\f\7\2\u00a3\u00a4\f\3"+
-		"\2\2\u00a4\u00a5\7\7\2\2\u00a5\u00a7\5\24\13\2\u00a6\u009d\3\2\2\2\u00a6"+
-		"\u00a0\3\2\2\2\u00a6\u00a3\3\2\2\2\u00a7\u00aa\3\2\2\2\u00a8\u00a6\3\2"+
-		"\2\2\u00a8\u00a9\3\2\2\2\u00a9\35\3\2\2\2\u00aa\u00a8\3\2\2\2\u00ab\u00ac"+
-		"\7!\2\2\u00ac\u00b2\7\"\2\2\u00ad\u00ae\7!\2\2\u00ae\u00af\5\34\17\2\u00af"+
-		"\u00b0\7\"\2\2\u00b0\u00b2\3\2\2\2\u00b1\u00ab\3\2\2\2\u00b1\u00ad\3\2"+
-		"\2\2\u00b2\37\3\2\2\2\u00b3\u00b4\b\21\1\2\u00b4\u00b5\5,\27\2\u00b5\u00b6"+
-		"\7\25\2\2\u00b6\u00b7\5\4\3\2\u00b7\u00bd\3\2\2\2\u00b8\u00b9\5\24\13"+
-		"\2\u00b9\u00ba\7\25\2\2\u00ba\u00bb\5\4\3\2\u00bb\u00bd\3\2\2\2\u00bc"+
-		"\u00b3\3\2\2\2\u00bc\u00b8\3\2\2\2\u00bd\u00cc\3\2\2\2\u00be\u00bf\f\4"+
-		"\2\2\u00bf\u00c0\7\7\2\2\u00c0\u00c1\5,\27\2\u00c1\u00c2\7\25\2\2\u00c2"+
-		"\u00c3\5\4\3\2\u00c3\u00cb\3\2\2\2\u00c4\u00c5\f\3\2\2\u00c5\u00c6\7\7"+
-		"\2\2\u00c6\u00c7\5\24\13\2\u00c7\u00c8\7\25\2\2\u00c8\u00c9\5\4\3\2\u00c9"+
-		"\u00cb\3\2\2\2\u00ca\u00be\3\2\2\2\u00ca\u00c4\3\2\2\2\u00cb\u00ce\3\2"+
-		"\2\2\u00cc\u00ca\3\2\2\2\u00cc\u00cd\3\2\2\2\u00cd!\3\2\2\2\u00ce\u00cc"+
-		"\3\2\2\2\u00cf\u00d0\7\37\2\2\u00d0\u00d1\5 \21\2\u00d1\u00d2\7 \2\2\u00d2"+
-		"\u00d6\3\2\2\2\u00d3\u00d4\7\37\2\2\u00d4\u00d6\7 \2\2\u00d5\u00cf\3\2"+
-		"\2\2\u00d5\u00d3\3\2\2\2\u00d6#\3\2\2\2\u00d7\u00d8\b\23\1\2\u00d8\u00d9"+
-		"\5&\24\2\u00d9\u00e2\3\2\2\2\u00da\u00db\f\4\2\2\u00db\u00dc\7\34\2\2"+
-		"\u00dc\u00e1\5&\24\2\u00dd\u00de\f\3\2\2\u00de\u00df\7\33\2\2\u00df\u00e1"+
-		"\5&\24\2\u00e0\u00da\3\2\2\2\u00e0\u00dd\3\2\2\2\u00e1\u00e4\3\2\2\2\u00e2"+
-		"\u00e0\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3%\3\2\2\2\u00e4\u00e2\3\2\2\2"+
-		"\u00e5\u00e6\b\24\1\2\u00e6\u00e7\5*\26\2\u00e7\u00f0\3\2\2\2\u00e8\u00e9"+
-		"\f\4\2\2\u00e9\u00ea\7\36\2\2\u00ea\u00ef\5&\24\5\u00eb\u00ec\f\3\2\2"+
-		"\u00ec\u00ed\7\35\2\2\u00ed\u00ef\5&\24\4\u00ee\u00e8\3\2\2\2\u00ee\u00eb"+
-		"\3\2\2\2\u00ef\u00f2\3\2\2\2\u00f0\u00ee\3\2\2\2\u00f0\u00f1\3\2\2\2\u00f1"+
-		"\'\3\2\2\2\u00f2\u00f0\3\2\2\2\u00f3\u00f4\7,\2\2\u00f4\u00f5\5\32\16"+
-		"\2\u00f5)\3\2\2\2\u00f6\u0106\5(\25\2\u00f7\u0106\7)\2\2\u00f8\u0106\7"+
-		"(\2\2\u00f9\u0106\7+\2\2\u00fa\u0106\7*\2\2\u00fb\u0106\7,\2\2\u00fc\u0106"+
-		"\7\32\2\2\u00fd\u00fe\7#\2\2\u00fe\u00ff\5$\23\2\u00ff\u0100\7$\2\2\u0100"+
-		"\u0106\3\2\2\2\u0101\u0102\7#\2\2\u0102\u0103\5\f\7\2\u0103\u0104\7$\2"+
-		"\2\u0104\u0106\3\2\2\2\u0105\u00f6\3\2\2\2\u0105\u00f7\3\2\2\2\u0105\u00f8"+
-		"\3\2\2\2\u0105\u00f9\3\2\2\2\u0105\u00fa\3\2\2\2\u0105\u00fb\3\2\2\2\u0105"+
-		"\u00fc\3\2\2\2\u0105\u00fd\3\2\2\2\u0105\u0101\3\2\2\2\u0106+\3\2\2\2"+
-		"\u0107\u0119\t\3\2\2\u0108\u0119\5\60\31\2\u0109\u0119\5.\30\2\u010a\u0119"+
-		"\5$\23\2\u010b\u0119\7-\2\2\u010c\u0119\5\36\20\2\u010d\u0119\5\"\22\2"+
-		"\u010e\u0119\7\31\2\2\u010f\u0110\7&\2\2\u0110\u0111\7#\2\2\u0111\u0112"+
-		"\7,\2\2\u0112\u0119\7$\2\2\u0113\u0114\7#\2\2\u0114\u0115\5\f\7\2\u0115"+
-		"\u0116\7$\2\2\u0116\u0119\3\2\2\2\u0117\u0119\5(\25\2\u0118\u0107\3\2"+
-		"\2\2\u0118\u0108\3\2\2\2\u0118\u0109\3\2\2\2\u0118\u010a\3\2\2\2\u0118"+
-		"\u010b\3\2\2\2\u0118\u010c\3\2\2\2\u0118\u010d\3\2\2\2\u0118\u010e\3\2"+
-		"\2\2\u0118\u010f\3\2\2\2\u0118\u0113\3\2\2\2\u0118\u0117\3\2\2\2\u0119"+
-		"-\3\2\2\2\u011a\u011b\7#\2\2\u011b\u011c\7$\2\2\u011c\u011d\7\4\2\2\u011d"+
-		"\u011e\5\4\3\2\u011e/\3\2\2\2\u011f\u0120\7#\2\2\u0120\u0121\5\62\32\2"+
-		"\u0121\u0122\7$\2\2\u0122\u0123\7\4\2\2\u0123\u0124\5\4\3\2\u0124\u012a"+
-		"\3\2\2\2\u0125\u0126\5\64\33\2\u0126\u0127\7\4\2\2\u0127\u0128\5\4\3\2"+
-		"\u0128\u012a\3\2\2\2\u0129\u011f\3\2\2\2\u0129\u0125\3\2\2\2\u012a\61"+
-		"\3\2\2\2\u012b\u0130\5\66\34\2\u012c\u012d\7\7\2\2\u012d\u012f\5\66\34"+
-		"\2\u012e\u012c\3\2\2\2\u012f\u0132\3\2\2\2\u0130\u012e\3\2\2\2\u0130\u0131"+
-		"\3\2\2\2\u0131\63\3\2\2\2\u0132\u0130\3\2\2\2\u0133\u0134\5\66\34\2\u0134"+
-		"\65\3\2\2\2\u0135\u0136\7,\2\2\u0136\67\3\2\2\2\32EZeis\u0080\u0088\u0095"+
-		"\u009b\u00a6\u00a8\u00b1\u00bc\u00ca\u00cc\u00d5\u00e0\u00e2\u00ee\u00f0"+
-		"\u0105\u0118\u0129\u0130";
+		"\5\27\u0126\n\27\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32"+
+		"\3\32\3\32\3\32\3\32\3\32\3\32\5\32\u0139\n\32\3\33\3\33\3\33\7\33\u013e"+
+		"\n\33\f\33\16\33\u0141\13\33\3\34\3\34\3\35\3\35\3\36\3\36\3\36\3\36\3"+
+		"\36\3\36\3\36\3\36\3\36\3\37\3\37\3\37\7\37\u0153\n\37\f\37\16\37\u0156"+
+		"\13\37\3 \3 \3 \3 \3!\3!\3\"\3\"\5\"\u0160\n\"\3\"\2\7\24\34 $&#\2\4\6"+
+		"\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@B\2\4\3\2\16"+
+		"\23\3\2\f\r\u0174\2D\3\2\2\2\4R\3\2\2\2\6T\3\2\2\2\bV\3\2\2\2\nX\3\2\2"+
+		"\2\fg\3\2\2\2\16r\3\2\2\2\20v\3\2\2\2\22\u0080\3\2\2\2\24\u008d\3\2\2"+
+		"\2\26\u0098\3\2\2\2\30\u009a\3\2\2\2\32\u00a2\3\2\2\2\34\u00a8\3\2\2\2"+
+		"\36\u00be\3\2\2\2 \u00c9\3\2\2\2\"\u00e2\3\2\2\2$\u00e4\3\2\2\2&\u00f2"+
+		"\3\2\2\2(\u0100\3\2\2\2*\u0112\3\2\2\2,\u0125\3\2\2\2.\u0127\3\2\2\2\60"+
+		"\u0129\3\2\2\2\62\u0138\3\2\2\2\64\u013a\3\2\2\2\66\u0142\3\2\2\28\u0144"+
+		"\3\2\2\2:\u0146\3\2\2\2<\u014f\3\2\2\2>\u0157\3\2\2\2@\u015b\3\2\2\2B"+
+		"\u015f\3\2\2\2DE\5\4\3\2EF\7\2\2\3F\3\3\2\2\2GS\5\f\7\2HI\7&\2\2IJ\5\4"+
+		"\3\2JK\7\'\2\2KS\3\2\2\2LS\5$\23\2MS\5\26\f\2NS\5\24\13\2OS\5\16\b\2P"+
+		"S\5\22\n\2QS\5:\36\2RG\3\2\2\2RH\3\2\2\2RL\3\2\2\2RM\3\2\2\2RN\3\2\2\2"+
+		"RO\3\2\2\2RP\3\2\2\2RQ\3\2\2\2S\5\3\2\2\2TU\5\16\b\2U\7\3\2\2\2VW\5\4"+
+		"\3\2W\t\3\2\2\2XY\5\4\3\2Y\13\3\2\2\2Z[\5\6\4\2[\\\7\24\2\2\\]\5\b\5\2"+
+		"]^\7\25\2\2^_\5\n\6\2_h\3\2\2\2`a\7\26\2\2ab\5\6\4\2bc\7\27\2\2cd\5\b"+
+		"\5\2de\7\30\2\2ef\5\n\6\2fh\3\2\2\2gZ\3\2\2\2g`\3\2\2\2h\r\3\2\2\2ij\5"+
+		"\20\t\2jk\7\t\2\2kl\5\16\b\2ls\3\2\2\2mn\5\20\t\2no\7\n\2\2op\5\16\b\2"+
+		"ps\3\2\2\2qs\5\20\t\2ri\3\2\2\2rm\3\2\2\2rq\3\2\2\2s\17\3\2\2\2tw\5\24"+
+		"\13\2uw\5\22\n\2vt\3\2\2\2vu\3\2\2\2w\21\3\2\2\2xy\5,\27\2yz\7\3\2\2z"+
+		"{\5\20\t\2{\u0081\3\2\2\2|}\5,\27\2}~\7(\2\2~\177\5\20\t\2\177\u0081\3"+
+		"\2\2\2\u0080x\3\2\2\2\u0080|\3\2\2\2\u0081\23\3\2\2\2\u0082\u0083\b\13"+
+		"\1\2\u0083\u0084\7\13\2\2\u0084\u0085\7&\2\2\u0085\u0086\5\16\b\2\u0086"+
+		"\u0087\7\'\2\2\u0087\u008e\3\2\2\2\u0088\u0089\7&\2\2\u0089\u008a\5\16"+
+		"\b\2\u008a\u008b\7\'\2\2\u008b\u008e\3\2\2\2\u008c\u008e\5,\27\2\u008d"+
+		"\u0082\3\2\2\2\u008d\u0088\3\2\2\2\u008d\u008c\3\2\2\2\u008e\u0095\3\2"+
+		"\2\2\u008f\u0090\f\6\2\2\u0090\u0091\5\30\r\2\u0091\u0092\5\24\13\7\u0092"+
+		"\u0094\3\2\2\2\u0093\u008f\3\2\2\2\u0094\u0097\3\2\2\2\u0095\u0093\3\2"+
+		"\2\2\u0095\u0096\3\2\2\2\u0096\25\3\2\2\2\u0097\u0095\3\2\2\2\u0098\u0099"+
+		"\5,\27\2\u0099\27\3\2\2\2\u009a\u009b\t\2\2\2\u009b\31\3\2\2\2\u009c\u009d"+
+		"\7&\2\2\u009d\u009e\5\34\17\2\u009e\u009f\7\'\2\2\u009f\u00a3\3\2\2\2"+
+		"\u00a0\u00a1\7&\2\2\u00a1\u00a3\7\'\2\2\u00a2\u009c\3\2\2\2\u00a2\u00a0"+
+		"\3\2\2\2\u00a3\33\3\2\2\2\u00a4\u00a5\b\17\1\2\u00a5\u00a9\5,\27\2\u00a6"+
+		"\u00a9\5\f\7\2\u00a7\u00a9\5\24\13\2\u00a8\u00a4\3\2\2\2\u00a8\u00a6\3"+
+		"\2\2\2\u00a8\u00a7\3\2\2\2\u00a9\u00b5\3\2\2\2\u00aa\u00ab\f\7\2\2\u00ab"+
+		"\u00ac\7\7\2\2\u00ac\u00b4\5,\27\2\u00ad\u00ae\f\5\2\2\u00ae\u00af\7\7"+
+		"\2\2\u00af\u00b4\5\f\7\2\u00b0\u00b1\f\3\2\2\u00b1\u00b2\7\7\2\2\u00b2"+
+		"\u00b4\5\24\13\2\u00b3\u00aa\3\2\2\2\u00b3\u00ad\3\2\2\2\u00b3\u00b0\3"+
+		"\2\2\2\u00b4\u00b7\3\2\2\2\u00b5\u00b3\3\2\2\2\u00b5\u00b6\3\2\2\2\u00b6"+
+		"\35\3\2\2\2\u00b7\u00b5\3\2\2\2\u00b8\u00b9\7$\2\2\u00b9\u00bf\7%\2\2"+
+		"\u00ba\u00bb\7$\2\2\u00bb\u00bc\5\34\17\2\u00bc\u00bd\7%\2\2\u00bd\u00bf"+
+		"\3\2\2\2\u00be\u00b8\3\2\2\2\u00be\u00ba\3\2\2\2\u00bf\37\3\2\2\2\u00c0"+
+		"\u00c1\b\21\1\2\u00c1\u00c2\5,\27\2\u00c2\u00c3\7\25\2\2\u00c3\u00c4\5"+
+		"\4\3\2\u00c4\u00ca\3\2\2\2\u00c5\u00c6\5\24\13\2\u00c6\u00c7\7\25\2\2"+
+		"\u00c7\u00c8\5\4\3\2\u00c8\u00ca\3\2\2\2\u00c9\u00c0\3\2\2\2\u00c9\u00c5"+
+		"\3\2\2\2\u00ca\u00d9\3\2\2\2\u00cb\u00cc\f\4\2\2\u00cc\u00cd\7\7\2\2\u00cd"+
+		"\u00ce\5,\27\2\u00ce\u00cf\7\25\2\2\u00cf\u00d0\5\4\3\2\u00d0\u00d8\3"+
+		"\2\2\2\u00d1\u00d2\f\3\2\2\u00d2\u00d3\7\7\2\2\u00d3\u00d4\5\24\13\2\u00d4"+
+		"\u00d5\7\25\2\2\u00d5\u00d6\5\4\3\2\u00d6\u00d8\3\2\2\2\u00d7\u00cb\3"+
+		"\2\2\2\u00d7\u00d1\3\2\2\2\u00d8\u00db\3\2\2\2\u00d9\u00d7\3\2\2\2\u00d9"+
+		"\u00da\3\2\2\2\u00da!\3\2\2\2\u00db\u00d9\3\2\2\2\u00dc\u00dd\7\"\2\2"+
+		"\u00dd\u00de\5 \21\2\u00de\u00df\7#\2\2\u00df\u00e3\3\2\2\2\u00e0\u00e1"+
+		"\7\"\2\2\u00e1\u00e3\7#\2\2\u00e2\u00dc\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3"+
+		"#\3\2\2\2\u00e4\u00e5\b\23\1\2\u00e5\u00e6\5&\24\2\u00e6\u00ef\3\2\2\2"+
+		"\u00e7\u00e8\f\4\2\2\u00e8\u00e9\7\37\2\2\u00e9\u00ee\5&\24\2\u00ea\u00eb"+
+		"\f\3\2\2\u00eb\u00ec\7\36\2\2\u00ec\u00ee\5&\24\2\u00ed\u00e7\3\2\2\2"+
+		"\u00ed\u00ea\3\2\2\2\u00ee\u00f1\3\2\2\2\u00ef\u00ed\3\2\2\2\u00ef\u00f0"+
+		"\3\2\2\2\u00f0%\3\2\2\2\u00f1\u00ef\3\2\2\2\u00f2\u00f3\b\24\1\2\u00f3"+
+		"\u00f4\5*\26\2\u00f4\u00fd\3\2\2\2\u00f5\u00f6\f\4\2\2\u00f6\u00f7\7!"+
+		"\2\2\u00f7\u00fc\5&\24\5\u00f8\u00f9\f\3\2\2\u00f9\u00fa\7 \2\2\u00fa"+
+		"\u00fc\5&\24\4\u00fb\u00f5\3\2\2\2\u00fb\u00f8\3\2\2\2\u00fc\u00ff\3\2"+
+		"\2\2\u00fd\u00fb\3\2\2\2\u00fd\u00fe\3\2\2\2\u00fe\'\3\2\2\2\u00ff\u00fd"+
+		"\3\2\2\2\u0100\u0101\7/\2\2\u0101\u0102\5\32\16\2\u0102)\3\2\2\2\u0103"+
+		"\u0113\5(\25\2\u0104\u0113\7,\2\2\u0105\u0113\7+\2\2\u0106\u0113\7.\2"+
+		"\2\u0107\u0113\7-\2\2\u0108\u0113\7/\2\2\u0109\u0113\7\32\2\2\u010a\u010b"+
+		"\7&\2\2\u010b\u010c\5$\23\2\u010c\u010d\7\'\2\2\u010d\u0113\3\2\2\2\u010e"+
+		"\u010f\7&\2\2\u010f\u0110\5\f\7\2\u0110\u0111\7\'\2\2\u0111\u0113\3\2"+
+		"\2\2\u0112\u0103\3\2\2\2\u0112\u0104\3\2\2\2\u0112\u0105\3\2\2\2\u0112"+
+		"\u0106\3\2\2\2\u0112\u0107\3\2\2\2\u0112\u0108\3\2\2\2\u0112\u0109\3\2"+
+		"\2\2\u0112\u010a\3\2\2\2\u0112\u010e\3\2\2\2\u0113+\3\2\2\2\u0114\u0126"+
+		"\t\3\2\2\u0115\u0126\5\62\32\2\u0116\u0126\5\60\31\2\u0117\u0126\5$\23"+
+		"\2\u0118\u0126\7\60\2\2\u0119\u0126\5\36\20\2\u011a\u0126\5\"\22\2\u011b"+
+		"\u0126\7\31\2\2\u011c\u011d\7)\2\2\u011d\u011e\7&\2\2\u011e\u011f\7/\2"+
+		"\2\u011f\u0126\7\'\2\2\u0120\u0121\7&\2\2\u0121\u0122\5\f\7\2\u0122\u0123"+
+		"\7\'\2\2\u0123\u0126\3\2\2\2\u0124\u0126\5(\25\2\u0125\u0114\3\2\2\2\u0125"+
+		"\u0115\3\2\2\2\u0125\u0116\3\2\2\2\u0125\u0117\3\2\2\2\u0125\u0118\3\2"+
+		"\2\2\u0125\u0119\3\2\2\2\u0125\u011a\3\2\2\2\u0125\u011b\3\2\2\2\u0125"+
+		"\u011c\3\2\2\2\u0125\u0120\3\2\2\2\u0125\u0124\3\2\2\2\u0126-\3\2\2\2"+
+		"\u0127\u0128\7\34\2\2\u0128/\3\2\2\2\u0129\u012a\7&\2\2\u012a\u012b\7"+
+		"\'\2\2\u012b\u012c\7\4\2\2\u012c\u012d\5\4\3\2\u012d\61\3\2\2\2\u012e"+
+		"\u012f\7&\2\2\u012f\u0130\5\64\33\2\u0130\u0131\7\'\2\2\u0131\u0132\7"+
+		"\4\2\2\u0132\u0133\5\4\3\2\u0133\u0139\3\2\2\2\u0134\u0135\5\66\34\2\u0135"+
+		"\u0136\7\4\2\2\u0136\u0137\5\4\3\2\u0137\u0139\3\2\2\2\u0138\u012e\3\2"+
+		"\2\2\u0138\u0134\3\2\2\2\u0139\63\3\2\2\2\u013a\u013f\58\35\2\u013b\u013c"+
+		"\7\7\2\2\u013c\u013e\58\35\2\u013d\u013b\3\2\2\2\u013e\u0141\3\2\2\2\u013f"+
+		"\u013d\3\2\2\2\u013f\u0140\3\2\2\2\u0140\65\3\2\2\2\u0141\u013f\3\2\2"+
+		"\2\u0142\u0143\58\35\2\u0143\67\3\2\2\2\u0144\u0145\7/\2\2\u01459\3\2"+
+		"\2\2\u0146\u0147\7\33\2\2\u0147\u0148\7\"\2\2\u0148\u0149\5<\37\2\u0149"+
+		"\u014a\7\7\2\2\u014a\u014b\7\34\2\2\u014b\u014c\7\35\2\2\u014c\u014d\5"+
+		"@!\2\u014d\u014e\7#\2\2\u014e;\3\2\2\2\u014f\u0154\5> \2\u0150\u0151\7"+
+		"\7\2\2\u0151\u0153\5> \2\u0152\u0150\3\2\2\2\u0153\u0156\3\2\2\2\u0154"+
+		"\u0152\3\2\2\2\u0154\u0155\3\2\2\2\u0155=\3\2\2\2\u0156\u0154\3\2\2\2"+
+		"\u0157\u0158\5B\"\2\u0158\u0159\7\35\2\2\u0159\u015a\5@!\2\u015a?\3\2"+
+		"\2\2\u015b\u015c\5\4\3\2\u015cA\3\2\2\2\u015d\u0160\5\16\b\2\u015e\u0160"+
+		"\5\f\7\2\u015f\u015d\3\2\2\2\u015f\u015e\3\2\2\2\u0160C\3\2\2\2\34Rgr"+
+		"v\u0080\u008d\u0095\u00a2\u00a8\u00b3\u00b5\u00be\u00c9\u00d7\u00d9\u00e2"+
+		"\u00ed\u00ef\u00fb\u00fd\u0112\u0125\u0138\u013f\u0154\u015f";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {

http://git-wip-us.apache.org/repos/asf/metron/blob/c749b517/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MatchTest.java
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MatchTest.java b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MatchTest.java
new file mode 100644
index 0000000..54e99a3
--- /dev/null
+++ b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/MatchTest.java
@@ -0,0 +1,377 @@
+/*
+ * 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.stellar.dsl.functions;
+
+import static org.apache.metron.stellar.common.utils.StellarProcessorUtils.run;
+import static org.apache.metron.stellar.common.utils.StellarProcessorUtils.runPredicate;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.metron.stellar.dsl.DefaultVariableResolver;
+import org.apache.metron.stellar.dsl.ParseException;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MatchTest {
+
+  // Short Circuit
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testThreeTrueClausesFirstOnlyFires() {
+    Assert.assertTrue(runPredicate(
+        "match{foo > 0 => true, foo > 5 => false, foo > 10 => false, default => false}",
+        new HashMap() {{
+          put("foo", 100);
+        }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testTwoClausesSecondFires() {
+    Assert.assertTrue(runPredicate("match{foo < 0 => false, foo < 500 => true, default => false}",
+        new HashMap() {{
+          put("foo", 100);
+        }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testThreeClausesFirstFires() {
+    List<String> list = (List<String>) run(
+        "match{ foo > 100 => ['oops'], foo > 200 => ['oh no'], foo >= 500 => MAP(['ok', 'haha'], (a) -> TO_UPPER(a)), default => ['a']}",
+        new HashMap() {{
+          put("foo", 500);
+        }});
+
+    Assert.assertTrue(list.size() == 1);
+    Assert.assertTrue(list.contains("oops"));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testShortCircuitWithThrows() {
+
+    Assert.assertEquals("ok",
+        run("match{ foo > 100 => THROW('oops'), foo > 200 => THROW('oh no'), default => 'ok' }",
+            new HashMap() {{
+              put("foo", 50);
+            }}));
+  }
+
+
+  // LAMBDAS
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testMatchLambda() {
+    Assert.assertTrue(
+        runPredicate("match { 1 >= 0 => ()-> true, default => ()->false }", new HashMap() {{
+          put("foo", 0);
+        }}));
+    Assert.assertTrue(
+        runPredicate("match { foo == 0 => ()-> true, default => ()-> false }", new HashMap() {{
+          put("foo", 0);
+        }}));
+
+    Assert.assertFalse(
+        runPredicate("match { foo == 0 => ()-> true, default => ()-> false }", new HashMap() {{
+          put("foo", 1);
+        }}));
+
+    Assert.assertTrue(runPredicate(
+        "match { foo == 0 => ()-> false, foo == 1 => ()-> true, default => ()-> false }",
+        new HashMap() {{
+          put("foo", 1);
+        }}));
+
+    Assert.assertTrue(runPredicate(
+        "match { foo == 0 => ()-> bFalse, foo == 1 => ()-> bTrue, default => ()-> bFalse }",
+        new HashMap() {{
+          put("foo", 1);
+          put("bFalse", false);
+          put("bTrue", true);
+        }}));
+
+    Assert.assertTrue(runPredicate(
+        "match { foo == 0 => ()-> bFalse, foo == 1 => ()-> bTrue, default => ()-> bFalse }",
+        new HashMap() {{
+          put("foo", 1);
+          put("bFalse", false);
+          put("bTrue", true);
+        }}));
+
+  }
+
+  // GENERAL WITH MAP EVAL
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testMatchMAPEvaluation() {
+
+    String expr = "match{ var1 =>  MAP(['foo', 'bar'], (x) -> TO_UPPER(x)), default => null }";
+
+    Object o = run(expr, ImmutableMap.of("foo", "foo", "bar", "bar", "var1", true));
+
+    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
+  @SuppressWarnings("unchecked")
+  public void workingMatchWithMap() {
+    Assert.assertEquals(Arrays.asList("OK", "HAHA"),
+        run("match{ foo > 100 => THROW('oops'), foo > 200 => THROW('oh no'), foo >= 50 => MAP(['ok', 'haha'], (a) -> TO_UPPER(a)), default=> 'a' }",
+            new HashMap() {{
+              put("foo", 50);
+            }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testMapSmall() {
+    List<String> ret = (List<String>) run(
+        "match{ foo < 100 => ['oops'], default => MAP(['ok', 'haha'], (a) -> TO_UPPER(a))}",
+        new HashMap() {{
+          put("foo", 500);
+        }});
+    Assert.assertTrue(ret.size() == 2);
+    Assert.assertTrue(ret.contains("OK"));
+    Assert.assertTrue(ret.contains("HAHA"));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testMultiClauseMap() {
+    run("match{ foo < 100 => ['oops'], foo < 200 => ['oh no'], foo >= 500 => MAP(['ok', 'haha'], (a) -> TO_UPPER(a)), default => ['a']}",
+        new HashMap() {{
+          put("foo", 500);
+        }});
+  }
+
+
+  // REGEX
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testMatchRegexMatch() {
+    final Map<String, String> variables = new HashMap<String, String>() {{
+      put("numbers", "12345");
+      put("numberPattern", "\\d(\\d)(\\d).*");
+      put("letters", "abcde");
+      put("empty", "");
+    }};
+
+    Assert.assertTrue(
+        runPredicate("match{ REGEXP_MATCH(numbers,numberPattern)=> true, default => false}",
+            new DefaultVariableResolver(variables::get, variables::containsKey)));
+    Assert.assertFalse(
+        runPredicate("match{ REGEXP_MATCH(letters,numberPattern) => true, default =>false}",
+            new DefaultVariableResolver(variables::get, variables::containsKey)));
+  }
+
+  // BARE STATEMENTS
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testMatchBareStatements() {
+
+    Assert.assertTrue(
+        runPredicate("match { foo == 0 => bFalse, foo == 1 => bTrue, default => false }",
+            new HashMap() {{
+              put("foo", 1);
+              put("bFalse", false);
+              put("bTrue", true);
+            }}));
+
+    Assert.assertEquals("warning",
+        run("match{ threat.triage.level < 10 => 'info', threat.triage.level < 20 => 'warning', default => 'critical' }",
+            new HashMap() {{
+              put("threat.triage.level", 15);
+            }}));
+  }
+
+  // FUNCTIONS
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testWithFunction() {
+    Assert.assertEquals("WARNING",
+        run("match{ threat.triage.level < 10 => 'info', threat.triage.level < 20 => TO_UPPER('warning'), default => 'critical' }",
+            new HashMap() {{
+              put("threat.triage.level", 15);
+            }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testWithFunctionMultiArgs() {
+    Assert.assertEquals("false",
+        run("match{ threat.triage.level < 10 => 'info', threat.triage.level < 20 => TO_STRING(IS_ENCODING(other,'BASE32')), default => 'critical' }",
+            new HashMap() {{
+              put("threat.triage.level", 15);
+              put("other", "value");
+            }}));
+
+    Assert.assertEquals(false,
+        run("match{ threat.triage.level < 10 => 'info', threat.triage.level < 20 => IS_ENCODING(other,'BASE32'), default => 'critical' }",
+            new HashMap() {{
+              put("threat.triage.level", 15);
+              put("other", "value");
+            }}));
+
+  }
+
+
+  // LOGICAL EXPRESSIONS IN CHECKS
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testLogical() {
+
+    Assert.assertTrue(
+        runPredicate("match { foo == 0  OR bar == 'yes' => ()-> true, default => ()-> false }",
+            new HashMap() {{
+              put("foo", 1);
+              put("bar", "yes");
+            }}));
+
+    Assert.assertTrue(
+        runPredicate("match { foo == 0  AND bar == 'yes' => ()-> true, default => ()-> false }",
+            new HashMap() {{
+              put("foo", 0);
+              put("bar", "yes");
+            }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testTernaryFuncWithoutIfCheck() {
+    Assert.assertEquals("a",
+        run("match{ foo == 5 ? true : false => 'a', default => 'ok' }", new HashMap() {{
+          put("foo", 5);
+        }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testTernaryFuncAsMatchAction() {
+    Assert.assertEquals(false, run("match{ threat.triage.level < 10 => 'info', threat.triage.level < 20 => IS_ENCODING(other,'BASE32')? true : false, default => 'critical' }",
+        new HashMap() {{
+          put("threat.triage.level", 15);
+          put("other", "value");
+        }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testVariableIFCheck() {
+    Assert.assertEquals("a",
+        run("match{ IF foo == 5 THEN true ELSE false => 'a', default => 'ok' }", new HashMap() {{
+          put("foo", 5);
+        }}));
+  }
+
+  @Test
+  public void testIfThenElseAction() {
+    Assert.assertEquals(2,run("match{ foo == true => IF bar THEN 1 ELSE 2, default => 0}", new HashMap(){{
+      put("foo",true);
+      put("bar",false);
+    }}));
+  }
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testVariableOnly() {
+    Assert.assertEquals("a", run("match{ foo => 'a', default => null}", new HashMap() {{
+      put("foo", true);
+    }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testVariableEqualsCheck() {
+    Assert.assertEquals("a", run("match{ foo == 5 => 'a', default => 'ok' }", new HashMap() {{
+      put("foo", 5);
+    }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testVariableOnlyCheckWithDefault() {
+    Assert.assertEquals("a", run("match{ foo => 'a', default => 'b' }", new HashMap() {{
+      put("foo", true);
+    }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testHandleVariableEqualsCheckWithDefault() {
+    Assert.assertEquals("a", run("match{ foo == true => 'a', default=> 'b' }", new HashMap() {{
+      put("foo", true);
+    }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testNullInCheckedReturnNull() {
+    Assert.assertNull(
+        run(
+            "match{ foo == null => null, foo == true => 'not that null', default => 'really not that null'}",
+            new HashMap(){{
+              put("foo",null);
+            }}));
+  }
+
+  // SYNTAX ERRORS
+
+  @Test(expected = ParseException.class)
+  @SuppressWarnings("unchecked")
+  public void testMatchErrorNoDefault() {
+
+    run("match{ foo > 100 => 'greater than 100', foo > 200 => 'greater than 200' }",
+        new HashMap() {{
+          put("foo", 50);
+        }});
+
+  }
+
+
+  @Test(expected = ParseException.class)
+  @SuppressWarnings("unchecked")
+  public void testNestedMatchNotSupportted() {
+    // we cannot nest short circuit types in stellar
+    Assert.assertEquals(false,
+        run("match{  x == 0 => match{ y == 10 => false, default => true}, default => true}",
+            new HashMap() {{
+              put("x", 0);
+              put("y", 10);
+            }}));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testReturnList() {
+    Object o = run("match{ foo > 100 => ['oops'],default => ['a']}", new HashMap() {{
+      put("foo", 500);
+    }});
+    List l = (List) o;
+    Assert.assertTrue(l.size() == 1);
+  }
+}


[2/2] metron git commit: METRON-1277 Add match statement to Stellar language closes apache/incubator-metron#814

Posted by ce...@apache.org.
METRON-1277 Add match statement to Stellar language closes apache/incubator-metron#814


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

Branch: refs/heads/master
Commit: c749b51730f7fd24a900da31c3fe2072a54086bc
Parents: f084404
Author: Otto Fowler <of...@industrialdefender.com>
Authored: Thu Nov 30 15:16:18 2017 -0500
Committer: cstella <ce...@gmail.com>
Committed: Thu Nov 30 15:16:18 2017 -0500

----------------------------------------------------------------------
 Upgrading.md                                    |   13 +
 metron-stellar/stellar-common/README.md         |   29 +-
 .../metron/stellar/common/generated/Stellar.g4  |   27 +
 .../stellar-common/src/main/java/Stellar.tokens |   66 +-
 .../src/main/java/StellarLexer.tokens           |   66 +-
 .../metron/stellar/common/StellarCompiler.java  |  122 ++-
 .../common/generated/StellarBaseListener.java   |   84 ++
 .../stellar/common/generated/StellarLexer.java  |  379 +++----
 .../common/generated/StellarListener.java       |  180 +++-
 .../stellar/common/generated/StellarParser.java | 1007 ++++++++++++------
 .../metron/stellar/dsl/functions/MatchTest.java |  377 +++++++
 11 files changed, 1736 insertions(+), 614 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metron/blob/c749b517/Upgrading.md
----------------------------------------------------------------------
diff --git a/Upgrading.md b/Upgrading.md
index dd68de0..c3892ce 100644
--- a/Upgrading.md
+++ b/Upgrading.md
@@ -4,6 +4,19 @@ configuration which are non-backwards compatible.
 
 ## 0.4.1 to 0.4.2
 
+### [METRON-1277: STELLAR Add Match functionality to language](https://issues.apache.org/jira/browse/METRON-1277)
+As we continue to evolve the Stellar language, it is possible that new keywords
+will be added to the language.  This may cause compatablity issues where these
+reserved words and symbols are used in existing scripts.
+
+Adding `match` to the Stellar lanaguage has introduced the following new
+reserved keywords and symbols:
+
+`match`, `default`, `{`, `}`, '=>'
+
+Any stellar expressions which use these keywords not in quotes will need to be
+modified.
+
 ### [METRON-1158: Build backend for grouping alerts into meta alerts](https://issues.apache.org/jira/browse/METRON-1158)
 In order to allow for meta alerts to be queries alongside regular alerts in Elasticsearch 2.x,
 it is necessary to add an additional field to the templates and mapping for existing sensors.

http://git-wip-us.apache.org/repos/asf/metron/blob/c749b517/metron-stellar/stellar-common/README.md
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/README.md b/metron-stellar/stellar-common/README.md
index 5fe9ae7..e6bfc7c 100644
--- a/metron-stellar/stellar-common/README.md
+++ b/metron-stellar/stellar-common/README.md
@@ -30,6 +30,7 @@ The Stellar language supports the following:
 * Simple comparison operations `<`, `>`, `<=`, `>=`
 * Simple equality comparison operations `==`, `!=`
 * if/then/else comparisons (i.e. `if var1 < 10 then 'less than 10' else '10 or more'`)
+* Simple match evaluations (i.e. `match{ var1 < 10 => 'warn', var1 >= 10 => 'critical', default => 'info'}`
 * 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
@@ -41,10 +42,11 @@ The following keywords need to be single quote escaped in order to be used in St
 |               |               |             |             |             |
 | :-----------: | :-----------: | :---------: | :---------: | :---------: |
 | not           | else          | exists      | if          | then        |
-| and           | or            | in          | NaN         | ==          |
-| !=            | \<=           | \>          | \>=         | \+          |
-| \-            | \<            | ?           | \*          | /           |
-| ,             |               |             |             |             |
+| and           | or            | in          | NaN         | match       |
+| default       | ==            | !=          | \<=         | \>          | 
+| \>=           | \+            | \-          | \<          | ?           | 
+| \*            | /             | ,           | \{          | \}          |
+| \=>           |               |             |             |             |
 
 Using parens such as: "foo" : "\<ok\>" requires escaping; "foo": "\'\<ok\>\'"
 
@@ -100,6 +102,25 @@ In the core language functions, we support basic functional programming primitiv
 * `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 Language Match Expression
+
+Stellar provides the capability to write match expressions, which are similar to switch statements commonly found in c like languages.
+
+The syntax is:
+* `match{ logical_expression1 => evaluation expression1, logical_expression2 => evaluation_expression2, default => default_expression}` 
+
+Where:
+
+* `logical_expression` is a Stellar expression that evaluates to true or false.  For instance `var > 0` or `var > 0 AND var2 == 'foo'` or `IF ... THEN ... ELSE` 
+* `evaluation_expression` is a Stellar Expression
+* `default` is a required default return value, should no logical expression match
+
+> default is required 
+
+> Lambda expressions are supported, but they must be no argument lambdas such as `() -> STATEMENT`
+
+* Only the first clause that evaluates to true will be executed.
+
 ## Stellar Core Functions
 
 |                                                                                                    |

http://git-wip-us.apache.org/repos/asf/metron/blob/c749b517/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4 b/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
index dd92e3d..fef07ff 100644
--- a/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
+++ b/metron-stellar/stellar-common/src/main/antlr4/org/apache/metron/stellar/common/generated/Stellar.g4
@@ -67,6 +67,10 @@ ELSE : 'ELSE' | 'else';
 NULL : 'null' | 'NULL';
 NAN : 'NaN';
 
+MATCH : 'match' | 'MATCH';
+DEFAULT : 'default' | 'DEFAULT';
+MATCH_ACTION : '=>';
+
 MINUS : '-';
 PLUS : '+';
 DIV : '/';
@@ -138,6 +142,7 @@ transformation_expr:
   | comparison_expr # ComparisonExpression
   | logical_expr #LogicalExpression
   | in_expr #InExpression
+  | match_expr #MatchExpr
   ;
 
 if_expr:
@@ -256,6 +261,9 @@ identifier_operand :
   | functions #func
   ;
 
+default_operand :
+  DEFAULT #default
+  ;
 
 lambda_without_args:
   LPAREN RPAREN LAMBDA_OP transformation_expr
@@ -277,4 +285,23 @@ lambda_variable:
   IDENTIFIER
   ;
 
+match_expr :
+  MATCH LBRACE match_clauses COMMA DEFAULT MATCH_ACTION match_clause_action RBRACE #MatchClauses
+  ;
+
+match_clauses :
+  match_clause (COMMA match_clause)*
+  ;
 
+match_clause :
+  match_clause_check MATCH_ACTION  match_clause_action
+  ;
+
+match_clause_action :
+  transformation_expr #MatchClauseAction
+  ;
+  
+match_clause_check :
+  logical_expr #MatchClauseCheckExpr
+  | conditional_expr #MatchClauseCheckExpr
+  ;

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

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

http://git-wip-us.apache.org/repos/asf/metron/blob/c749b517/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
index 69564df..72f0d0a 100644
--- a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
+++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarCompiler.java
@@ -66,6 +66,9 @@ public class StellarCompiler extends StellarBaseListener {
   public static class ThenExpr implements ShortCircuitOp {}
   public static class ElseExpr implements ShortCircuitOp {}
   public static class EndConditional implements ShortCircuitOp {}
+  public static class MatchClauseCheckExpr implements ShortCircuitOp {}
+  public static class MatchClauseEnd implements ShortCircuitOp {}
+  public static class MatchClausesEnd implements ShortCircuitOp {}
 
   public static class ExpressionState {
     Context context;
@@ -105,59 +108,77 @@ public class StellarCompiler extends StellarBaseListener {
       Deque<Token<?>> instanceDeque = new ArrayDeque<>();
       {
         boolean skipElse = false;
+        boolean skipMatchClauses = false;
         Token<?> token = null;
         for (Iterator<Token<?>> it = getTokenDeque().descendingIterator(); it.hasNext(); ) {
           token = it.next();
           //if we've skipped an else previously, then we need to skip the deferred tokens associated with the else.
-          if(skipElse && token.getUnderlyingType() == ElseExpr.class) {
-            while(it.hasNext()) {
+          if (skipElse && token.getUnderlyingType() == ElseExpr.class) {
+            while (it.hasNext()) {
               token = it.next();
-              if(token.getUnderlyingType() == EndConditional.class) {
+              if (token.getUnderlyingType() == EndConditional.class) {
                 break;
               }
             }
             skipElse = false;
           }
+          if (skipMatchClauses && (token.getUnderlyingType() == MatchClauseEnd.class
+              || token.getUnderlyingType() == MatchClauseCheckExpr.class)) {
+            while (it.hasNext()) {
+              token = it.next();
+              if (token.getUnderlyingType() == MatchClausesEnd.class) {
+                break;
+              }
+            }
+            skipMatchClauses = false;
+          }
           /*
           curr is the current value on the stack.  This is the non-deferred actual evaluation for this expression
           and with the current context.
            */
           Token<?> curr = instanceDeque.peek();
-          if( curr != null
-           && curr.getValue() != null && curr.getValue() instanceof Boolean
-           && ShortCircuitOp.class.isAssignableFrom(token.getUnderlyingType())
-                  ) {
+          if (curr != null && curr.getValue() != null && curr.getValue() instanceof Boolean
+              && ShortCircuitOp.class.isAssignableFrom(token.getUnderlyingType())) {
             //if we have a boolean as the current value and the next non-contextual token is a short circuit op
             //then we need to short circuit possibly
-            if(token.getUnderlyingType() == BooleanArg.class) {
+            if (token.getUnderlyingType() == BooleanArg.class) {
               if (token.getMultiArgContext() != null
-                      && token.getMultiArgContext().getVariety() == FrameContext.BOOLEAN_OR
-                      && (Boolean) (curr.getValue())
-                      ) {
+                  && token.getMultiArgContext().getVariety() == FrameContext.BOOLEAN_OR
+                  && (Boolean) (curr.getValue())) {
                 //short circuit the or
                 FrameContext.Context context = curr.getMultiArgContext();
                 shortCircuit(it, context);
               } else if (token.getMultiArgContext() != null
-                      && token.getMultiArgContext().getVariety() == FrameContext.BOOLEAN_AND
-                      && !(Boolean) (curr.getValue())
-                      ) {
+                  && token.getMultiArgContext().getVariety() == FrameContext.BOOLEAN_AND
+                  && !(Boolean) (curr.getValue())) {
                 //short circuit the and
                 FrameContext.Context context = curr.getMultiArgContext();
                 shortCircuit(it, context);
               }
-            }
-            else if(token.getUnderlyingType() == IfExpr.class) {
+            } else if (token.getUnderlyingType() == IfExpr.class) {
               //short circuit the if/then/else
               instanceDeque.pop();
               if((Boolean)curr.getValue()) {
                 //choose then
                 skipElse = true;
-              }
-              else {
+              } else {
                 //choose else
-                while(it.hasNext()) {
+                while (it.hasNext()) {
+                  Token<?> t = it.next();
+                  if (t.getUnderlyingType() == ElseExpr.class) {
+                    break;
+                  }
+                }
+              }
+            } else if (token.getUnderlyingType() == MatchClauseCheckExpr.class) {
+              instanceDeque.pop();
+              if ((Boolean) curr.getValue()) {
+                //skip everything else after lambda
+                skipMatchClauses = true;
+              } else {
+                while (it.hasNext()) {
                   Token<?> t = it.next();
-                  if(t.getUnderlyingType() == ElseExpr.class) {
+                  if (t.getUnderlyingType() == MatchClauseEnd.class) {
                     break;
                   }
                 }
@@ -697,7 +718,62 @@ public class StellarCompiler extends StellarBaseListener {
     }, DeferredFunction.class, context));
   }
 
+  @Override
+  public void exitDefault(StellarParser.DefaultContext ctx) {
+    expression.tokenDeque.push(new Token<>(true, Boolean.class, getArgContext()));
+  }
 
+  @Override
+  public void exitMatchClauseCheckExpr(StellarParser.MatchClauseCheckExprContext ctx) {
+    final FrameContext.Context context = getArgContext();
+    // if we are validating, and we have a single variable then we will get
+    // a null and we need to protect against that
+    if(ctx.getStart() == ctx.getStop()) {
+      expression.tokenDeque.push(new Token<>((tokenDeque, state) -> {
+        if (state.context.getActivityType().equals(ActivityType.VALIDATION_ACTIVITY)) {
+          if (tokenDeque.size() == 1 && (tokenDeque.peek().getValue() == null
+              || tokenDeque.peek().getUnderlyingType() == Boolean.class)) {
+            tokenDeque.pop();
+            tokenDeque.add(new Token<>(true, Boolean.class, getArgContext()));
+          }
+
+        }
+      }, DeferredFunction.class, context));
+    }
+    expression.tokenDeque.push(new Token<>(new MatchClauseCheckExpr(), MatchClauseCheckExpr.class, getArgContext()));
+  }
+
+  @Override
+  public void exitMatchClauseAction(StellarParser.MatchClauseActionContext ctx) {
+    final FrameContext.Context context = getArgContext();
+    expression.tokenDeque.push(new Token<>( (tokenDeque, state) -> {
+      Token<?> token = popDeque(tokenDeque);
+      Object value = token.getValue();
+      if (value != null && LambdaExpression.class.isAssignableFrom(value.getClass())) {
+        LambdaExpression expr = (LambdaExpression) value;
+        // at this time we don't support lambdas with arguments
+        // there is no context for it as such here
+        // it is possible that we add match variables, and use those
+        // as the context, but that could also be done with plain variables
+        // so it remains to be determined
+        Object result = expr.apply(new ArrayList<>());
+        tokenDeque.push(new Token<>(result, Object.class, context));
+      } else {
+        tokenDeque.push(new Token<>(value, Object.class, context));
+      }
+
+    }, DeferredFunction.class, context));
+  }
+
+  @Override
+  public void exitMatch_clause(StellarParser.Match_clauseContext ctx) {
+    expression.tokenDeque.push(new Token<>(new MatchClauseEnd(), MatchClauseEnd.class, getArgContext()));
+  }
+
+  @Override
+  public void exitMatchClauses(StellarParser.MatchClausesContext ctx) {
+    expression.tokenDeque.push(new Token<>(new MatchClausesEnd(),MatchClausesEnd.class, getArgContext()));
+  }
 
   @Override
   public void exitComparisonExpressionWithOperator(StellarParser.ComparisonExpressionWithOperatorContext ctx) {
@@ -723,7 +799,7 @@ public class StellarCompiler extends StellarBaseListener {
   }
 
   private FrameContext.Context getArgContext() {
-    return expression.multiArgumentState.isEmpty()?null:expression.multiArgumentState.peek();
+    return expression.multiArgumentState.isEmpty() ? null : expression.multiArgumentState.peek();
   }
 
   private Token<?> popDeque(Deque<Token<?>> tokenDeque) {
@@ -733,6 +809,8 @@ public class StellarCompiler extends StellarBaseListener {
     return tokenDeque.pop();
   }
 
-  public Expression getExpression() {return expression;}
+  public Expression getExpression() {
+    return expression;
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/metron/blob/c749b517/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
index d2806b9..3528737 100644
--- a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
+++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarBaseListener.java
@@ -133,6 +133,18 @@ public class StellarBaseListener implements StellarListener {
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
+	@Override public void enterMatchExpr(StellarParser.MatchExprContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitMatchExpr(StellarParser.MatchExprContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
 	@Override public void enterIf_expr(StellarParser.If_exprContext ctx) { }
 	/**
 	 * {@inheritDoc}
@@ -721,6 +733,18 @@ public class StellarBaseListener implements StellarListener {
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
+	@Override public void enterDefault(StellarParser.DefaultContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitDefault(StellarParser.DefaultContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
 	@Override public void enterLambda_without_args(StellarParser.Lambda_without_argsContext ctx) { }
 	/**
 	 * {@inheritDoc}
@@ -776,6 +800,66 @@ public class StellarBaseListener implements StellarListener {
 	 * <p>The default implementation does nothing.</p>
 	 */
 	@Override public void exitLambda_variable(StellarParser.Lambda_variableContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterMatchClauses(StellarParser.MatchClausesContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitMatchClauses(StellarParser.MatchClausesContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterMatch_clauses(StellarParser.Match_clausesContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitMatch_clauses(StellarParser.Match_clausesContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterMatch_clause(StellarParser.Match_clauseContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitMatch_clause(StellarParser.Match_clauseContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterMatchClauseAction(StellarParser.MatchClauseActionContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitMatchClauseAction(StellarParser.MatchClauseActionContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void enterMatchClauseCheckExpr(StellarParser.MatchClauseCheckExprContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitMatchClauseCheckExpr(StellarParser.MatchClauseCheckExprContext ctx) { }
 
 	/**
 	 * {@inheritDoc}

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

http://git-wip-us.apache.org/repos/asf/metron/blob/c749b517/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
index f07efaa..718a4fe 100644
--- a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
+++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/generated/StellarListener.java
@@ -29,12 +29,14 @@ import org.antlr.v4.runtime.tree.ParseTreeListener;
  */
 public interface StellarListener extends ParseTreeListener {
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#transformation}.
+	 * Enter a parse tree produced by the {@code transformation}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterTransformation(StellarParser.TransformationContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#transformation}.
+	 * Exit a parse tree produced by the {@code transformation}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitTransformation(StellarParser.TransformationContext ctx);
@@ -123,32 +125,50 @@ public interface StellarListener extends ParseTreeListener {
 	 */
 	void exitInExpression(StellarParser.InExpressionContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#if_expr}.
+	 * Enter a parse tree produced by the {@code MatchExpr}
+	 * labeled alternative in {@link StellarParser#transformation_expr}.
+	 * @param ctx the parse tree
+	 */
+	void enterMatchExpr(StellarParser.MatchExprContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code MatchExpr}
+	 * labeled alternative in {@link StellarParser#transformation_expr}.
+	 * @param ctx the parse tree
+	 */
+	void exitMatchExpr(StellarParser.MatchExprContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code if_expr}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterIf_expr(StellarParser.If_exprContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#if_expr}.
+	 * Exit a parse tree produced by the {@code if_expr}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitIf_expr(StellarParser.If_exprContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#then_expr}.
+	 * Enter a parse tree produced by the {@code then_expr}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterThen_expr(StellarParser.Then_exprContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#then_expr}.
+	 * Exit a parse tree produced by the {@code then_expr}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitThen_expr(StellarParser.Then_exprContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#else_expr}.
+	 * Enter a parse tree produced by the {@code else_expr}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterElse_expr(StellarParser.Else_exprContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#else_expr}.
+	 * Exit a parse tree produced by the {@code else_expr}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitElse_expr(StellarParser.Else_exprContext ctx);
@@ -213,12 +233,14 @@ public interface StellarListener extends ParseTreeListener {
 	 */
 	void exitBoleanExpression(StellarParser.BoleanExpressionContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#b_expr}.
+	 * Enter a parse tree produced by the {@code b_expr}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterB_expr(StellarParser.B_exprContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#b_expr}.
+	 * Exit a parse tree produced by the {@code b_expr}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitB_expr(StellarParser.B_exprContext ctx);
@@ -295,12 +317,14 @@ public interface StellarListener extends ParseTreeListener {
 	 */
 	void exitOperand(StellarParser.OperandContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#transformation_entity}.
+	 * Enter a parse tree produced by the {@code transformation_entity}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterTransformation_entity(StellarParser.Transformation_entityContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#transformation_entity}.
+	 * Exit a parse tree produced by the {@code transformation_entity}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitTransformation_entity(StellarParser.Transformation_entityContext ctx);
@@ -317,52 +341,62 @@ public interface StellarListener extends ParseTreeListener {
 	 */
 	void exitComparisonOp(StellarParser.ComparisonOpContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#func_args}.
+	 * Enter a parse tree produced by the {@code func_args}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterFunc_args(StellarParser.Func_argsContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#func_args}.
+	 * Exit a parse tree produced by the {@code func_args}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitFunc_args(StellarParser.Func_argsContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#op_list}.
+	 * Enter a parse tree produced by the {@code op_list}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterOp_list(StellarParser.Op_listContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#op_list}.
+	 * Exit a parse tree produced by the {@code op_list}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitOp_list(StellarParser.Op_listContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#list_entity}.
+	 * Enter a parse tree produced by the {@code list_entity}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterList_entity(StellarParser.List_entityContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#list_entity}.
+	 * Exit a parse tree produced by the {@code list_entity}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitList_entity(StellarParser.List_entityContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#kv_list}.
+	 * Enter a parse tree produced by the {@code kv_list}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterKv_list(StellarParser.Kv_listContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#kv_list}.
+	 * Exit a parse tree produced by the {@code kv_list}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitKv_list(StellarParser.Kv_listContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#map_entity}.
+	 * Enter a parse tree produced by the {@code map_entity}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterMap_entity(StellarParser.Map_entityContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#map_entity}.
+	 * Exit a parse tree produced by the {@code map_entity}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitMap_entity(StellarParser.Map_entityContext ctx);
@@ -691,53 +725,135 @@ public interface StellarListener extends ParseTreeListener {
 	 */
 	void exitFunc(StellarParser.FuncContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#lambda_without_args}.
+	 * Enter a parse tree produced by the {@code default}
+	 * labeled alternative in {@link StellarParser#default_operand}.
+	 * @param ctx the parse tree
+	 */
+	void enterDefault(StellarParser.DefaultContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code default}
+	 * labeled alternative in {@link StellarParser#default_operand}.
+	 * @param ctx the parse tree
+	 */
+	void exitDefault(StellarParser.DefaultContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code lambda_without_args}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @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}.
+	 * Exit a parse tree produced by the {@code lambda_without_args}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @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}.
+	 * Enter a parse tree produced by the {@code lambda_with_args}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @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}.
+	 * Exit a parse tree produced by the {@code lambda_with_args}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitLambda_with_args(StellarParser.Lambda_with_argsContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#lambda_variables}.
+	 * Enter a parse tree produced by the {@code lambda_variables}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterLambda_variables(StellarParser.Lambda_variablesContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#lambda_variables}.
+	 * Exit a parse tree produced by the {@code lambda_variables}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitLambda_variables(StellarParser.Lambda_variablesContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#single_lambda_variable}.
+	 * Enter a parse tree produced by the {@code single_lambda_variable}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @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}.
+	 * Exit a parse tree produced by the {@code single_lambda_variable}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitSingle_lambda_variable(StellarParser.Single_lambda_variableContext ctx);
 	/**
-	 * Enter a parse tree produced by {@link StellarParser#lambda_variable}.
+	 * Enter a parse tree produced by the {@code lambda_variable}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void enterLambda_variable(StellarParser.Lambda_variableContext ctx);
 	/**
-	 * Exit a parse tree produced by {@link StellarParser#lambda_variable}.
+	 * Exit a parse tree produced by the {@code lambda_variable}
+	 * labeled alternative in {@link StellarParser#default_operand}.
 	 * @param ctx the parse tree
 	 */
 	void exitLambda_variable(StellarParser.Lambda_variableContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code MatchClauses}
+	 * labeled alternative in {@link StellarParser#match_expr}.
+	 * @param ctx the parse tree
+	 */
+	void enterMatchClauses(StellarParser.MatchClausesContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code MatchClauses}
+	 * labeled alternative in {@link StellarParser#match_expr}.
+	 * @param ctx the parse tree
+	 */
+	void exitMatchClauses(StellarParser.MatchClausesContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code match_clauses}
+	 * labeled alternative in {@link StellarParser#default_operand}.
+	 * @param ctx the parse tree
+	 */
+	void enterMatch_clauses(StellarParser.Match_clausesContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code match_clauses}
+	 * labeled alternative in {@link StellarParser#default_operand}.
+	 * @param ctx the parse tree
+	 */
+	void exitMatch_clauses(StellarParser.Match_clausesContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code match_clause}
+	 * labeled alternative in {@link StellarParser#default_operand}.
+	 * @param ctx the parse tree
+	 */
+	void enterMatch_clause(StellarParser.Match_clauseContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code match_clause}
+	 * labeled alternative in {@link StellarParser#default_operand}.
+	 * @param ctx the parse tree
+	 */
+	void exitMatch_clause(StellarParser.Match_clauseContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code MatchClauseAction}
+	 * labeled alternative in {@link StellarParser#match_clause_action}.
+	 * @param ctx the parse tree
+	 */
+	void enterMatchClauseAction(StellarParser.MatchClauseActionContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code MatchClauseAction}
+	 * labeled alternative in {@link StellarParser#match_clause_action}.
+	 * @param ctx the parse tree
+	 */
+	void exitMatchClauseAction(StellarParser.MatchClauseActionContext ctx);
+	/**
+	 * Enter a parse tree produced by the {@code MatchClauseCheckExpr}
+	 * labeled alternative in {@link StellarParser#match_clause_check}.
+	 * @param ctx the parse tree
+	 */
+	void enterMatchClauseCheckExpr(StellarParser.MatchClauseCheckExprContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code MatchClauseCheckExpr}
+	 * labeled alternative in {@link StellarParser#match_clause_check}.
+	 * @param ctx the parse tree
+	 */
+	void exitMatchClauseCheckExpr(StellarParser.MatchClauseCheckExprContext ctx);
 }
\ No newline at end of file