EQL - parsing IN expressions with named parameters

This commit is contained in:
Robin Bygrave
2016-07-13 10:12:15 +12:00
parent 3f8b389999
commit 83c16ad1c6
6 changed files with 186 additions and 145 deletions
@@ -103,18 +103,18 @@ class EqlAdapter<T> extends EQLBaseListener {
if (op != EqlOperator.BETWEEN) {
throw new IllegalStateException("Expecting BETWEEN operator but got "+op);
}
helper.addBetween(path, ctx.getChild(2).getText(), ctx.getChild(4).getText());
helper.addBetween(path, child(ctx,2), child(ctx,4));
}
@Override
public void enterPropertyBetween_expression(EQLParser.PropertyBetween_expressionContext ctx) {
checkChildren(ctx, 5);
String rawValue = ctx.getChild(0).getText();
String rawValue = child(ctx,0);
EqlOperator op = getOperator(ctx);
if (op != EqlOperator.BETWEEN) {
throw new IllegalStateException("Expecting BETWEEN operator but got "+op);
}
helper.addBetweenProperty(rawValue, ctx.getChild(2).getText(), ctx.getChild(4).getText());
helper.addBetweenProperty(rawValue, child(ctx,2), child(ctx,4));
}
@Override
@@ -127,14 +127,25 @@ class EqlAdapter<T> extends EQLBaseListener {
public void enterIn_value(EQLParser.In_valueContext ctx) {
int childCount = ctx.getChildCount();
for (int i = 0; i < childCount; i++) {
ParseTree child = ctx.getChild(i);
String text = child.getText();
if (!text.equals("(") && !text.equals(")")) {
String text = child(ctx, i);
if (isInValue(text)) {
inValues.add(helper.bind(text));
}
}
}
private String child(ParserRuleContext ctx, int position) {
ParseTree child = ctx.getChild(position);
return child.getText();
}
private boolean isInValue(String text) {
if (text.length() == 1 && (text.equals("(") || text.equals(")") || text.equals(","))) {
return false;
}
return true;
}
@Override
public void exitIn_expression(EQLParser.In_expressionContext ctx) {
helper.addIn(inPropertyName, inValues);
@@ -180,15 +191,14 @@ class EqlAdapter<T> extends EQLBaseListener {
throw new IllegalStateException("expecting 3 children for comparison? " + ctx);
}
String path = getLeftHandSidePath(ctx);
String operator = ctx.getChild(1).getText();
String operator = child(ctx, 1);
EqlOperator op = operatorMapping.get(operator);
if (op == null) {
throw new IllegalStateException("No operator found for " + operator);
}
// RHS is Path, Literal or Named input parameter
ParseTree rhs = ctx.getChild(2);
helper.addExpression(path, op, rhs.getText());
helper.addExpression(path, op, child(ctx, 2));
}
@@ -236,8 +246,7 @@ class EqlAdapter<T> extends EQLBaseListener {
}
private EqlOperator getOperator(ParserRuleContext ctx) {
// the operator text which may be a variation
String operator = ctx.getChild(1).getText();
String operator = child(ctx,1);
EqlOperator op = operatorMapping.get(operator);
if (op == null) {
throw new IllegalStateException("No operator found for " + operator);
@@ -891,54 +891,44 @@ public class EQLParser extends Parser {
enterRule(_localctx, 26, RULE_in_value);
int _la;
try {
setState(149);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) {
case 1:
setState(146);
switch (_input.LA(1)) {
case INPUT_VARIABLE:
enterOuterAlt(_localctx, 1);
{
setState(134);
match(INPUT_VARIABLE);
}
break;
case 2:
case T__1:
enterOuterAlt(_localctx, 2);
{
setState(135);
match(T__1);
setState(136);
match(INPUT_VARIABLE);
setState(137);
match(T__2);
}
break;
case 3:
enterOuterAlt(_localctx, 3);
{
setState(138);
match(T__1);
setState(139);
value_expression();
setState(144);
setState(141);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==T__5) {
{
{
setState(140);
setState(137);
match(T__5);
setState(141);
setState(138);
value_expression();
}
}
setState(146);
setState(143);
_errHandler.sync(this);
_la = _input.LA(1);
}
setState(147);
setState(144);
match(T__2);
}
break;
default:
throw new NoViableAltException(this);
}
}
catch (RecognitionException re) {
@@ -980,15 +970,15 @@ public class EQLParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(151);
setState(148);
match(PATH_VARIABLE);
setState(152);
setState(149);
match(T__10);
setState(153);
setState(150);
value_expression();
setState(154);
setState(151);
match(T__7);
setState(155);
setState(152);
value_expression();
}
}
@@ -1031,15 +1021,15 @@ public class EQLParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(157);
setState(154);
value_expression();
setState(158);
setState(155);
match(T__10);
setState(159);
setState(156);
match(PATH_VARIABLE);
setState(160);
setState(157);
match(T__7);
setState(161);
setState(158);
match(PATH_VARIABLE);
}
}
@@ -1074,26 +1064,26 @@ public class EQLParser extends Parser {
IsNull_expressionContext _localctx = new IsNull_expressionContext(_ctx, getState());
enterRule(_localctx, 32, RULE_isNull_expression);
try {
setState(168);
setState(165);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
setState(163);
setState(160);
match(PATH_VARIABLE);
setState(164);
setState(161);
match(T__11);
setState(165);
setState(162);
match(T__12);
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
setState(166);
setState(163);
match(PATH_VARIABLE);
setState(167);
setState(164);
match(T__13);
}
break;
@@ -1130,37 +1120,37 @@ public class EQLParser extends Parser {
IsNotNull_expressionContext _localctx = new IsNotNull_expressionContext(_ctx, getState());
enterRule(_localctx, 34, RULE_isNotNull_expression);
try {
setState(178);
setState(175);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
setState(170);
setState(167);
match(PATH_VARIABLE);
setState(171);
setState(168);
match(T__11);
setState(172);
setState(169);
match(T__8);
setState(173);
setState(170);
match(T__12);
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
setState(174);
setState(171);
match(PATH_VARIABLE);
setState(175);
setState(172);
match(T__14);
}
break;
case 3:
enterOuterAlt(_localctx, 3);
{
setState(176);
setState(173);
match(PATH_VARIABLE);
setState(177);
setState(174);
match(T__15);
}
break;
@@ -1197,26 +1187,26 @@ public class EQLParser extends Parser {
IsEmpty_expressionContext _localctx = new IsEmpty_expressionContext(_ctx, getState());
enterRule(_localctx, 36, RULE_isEmpty_expression);
try {
setState(185);
setState(182);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
setState(180);
setState(177);
match(PATH_VARIABLE);
setState(181);
setState(178);
match(T__11);
setState(182);
setState(179);
match(T__16);
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
setState(183);
setState(180);
match(PATH_VARIABLE);
setState(184);
setState(181);
match(T__17);
}
break;
@@ -1253,37 +1243,37 @@ public class EQLParser extends Parser {
IsNotEmpty_expressionContext _localctx = new IsNotEmpty_expressionContext(_ctx, getState());
enterRule(_localctx, 38, RULE_isNotEmpty_expression);
try {
setState(195);
setState(192);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
setState(187);
setState(184);
match(PATH_VARIABLE);
setState(188);
setState(185);
match(T__11);
setState(189);
setState(186);
match(T__8);
setState(190);
setState(187);
match(T__16);
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
setState(191);
setState(188);
match(PATH_VARIABLE);
setState(192);
setState(189);
match(T__18);
}
break;
case 3:
enterOuterAlt(_localctx, 3);
{
setState(193);
setState(190);
match(PATH_VARIABLE);
setState(194);
setState(191);
match(T__19);
}
break;
@@ -1328,11 +1318,11 @@ public class EQLParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(197);
setState(194);
match(PATH_VARIABLE);
setState(198);
setState(195);
like_op();
setState(199);
setState(196);
value_expression();
}
}
@@ -1369,7 +1359,7 @@ public class EQLParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(201);
setState(198);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27))) != 0)) ) {
_errHandler.recoverInline(this);
@@ -1417,11 +1407,11 @@ public class EQLParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(203);
setState(200);
match(PATH_VARIABLE);
setState(204);
setState(201);
comparison_operator();
setState(205);
setState(202);
value_expression();
}
}
@@ -1458,7 +1448,7 @@ public class EQLParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(207);
setState(204);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << T__31) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43))) != 0)) ) {
_errHandler.recoverInline(this);
@@ -1501,21 +1491,21 @@ public class EQLParser extends Parser {
Value_expressionContext _localctx = new Value_expressionContext(_ctx, getState());
enterRule(_localctx, 48, RULE_value_expression);
try {
setState(211);
setState(208);
switch (_input.LA(1)) {
case BOOLEAN_LITERAL:
case NUMBER_LITERAL:
case STRING_LITERAL:
enterOuterAlt(_localctx, 1);
{
setState(209);
setState(206);
literal();
}
break;
case INPUT_VARIABLE:
enterOuterAlt(_localctx, 2);
{
setState(210);
setState(207);
match(INPUT_VARIABLE);
}
break;
@@ -1559,7 +1549,7 @@ public class EQLParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(213);
setState(210);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << BOOLEAN_LITERAL) | (1L << NUMBER_LITERAL) | (1L << STRING_LITERAL))) != 0)) ) {
_errHandler.recoverInline(this);
@@ -1580,7 +1570,7 @@ public class EQLParser extends Parser {
}
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\64\u00da\4\2\t\2"+
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\64\u00d7\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"+
@@ -1589,64 +1579,63 @@ public class EQLParser extends Parser {
"S\n\7\f\7\16\7V\13\7\3\b\3\b\3\t\3\t\3\t\7\t]\n\t\f\t\16\t`\13\t\3\n\3"+
"\n\3\n\7\ne\n\n\f\n\16\nh\13\n\3\13\5\13k\n\13\3\13\3\13\3\f\3\f\3\f\3"+
"\f\3\f\5\ft\n\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\5"+
"\r\u0083\n\r\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3"+
"\17\7\17\u0091\n\17\f\17\16\17\u0094\13\17\3\17\3\17\5\17\u0098\n\17\3"+
"\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3"+
"\22\3\22\3\22\5\22\u00ab\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+
"\5\23\u00b5\n\23\3\24\3\24\3\24\3\24\3\24\5\24\u00bc\n\24\3\25\3\25\3"+
"\25\3\25\3\25\3\25\3\25\3\25\5\25\u00c6\n\25\3\26\3\26\3\26\3\26\3\27"+
"\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\32\3\32\5\32\u00d6\n\32\3\33\3\33"+
"\3\33\2\2\34\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64"+
"\2\5\3\2\27\36\3\2\37.\3\2\61\63\u00da\2\67\3\2\2\2\4?\3\2\2\2\6D\3\2"+
"\2\2\bF\3\2\2\2\nI\3\2\2\2\fO\3\2\2\2\16W\3\2\2\2\20Y\3\2\2\2\22a\3\2"+
"\2\2\24j\3\2\2\2\26s\3\2\2\2\30\u0082\3\2\2\2\32\u0084\3\2\2\2\34\u0097"+
"\3\2\2\2\36\u0099\3\2\2\2 \u009f\3\2\2\2\"\u00aa\3\2\2\2$\u00b4\3\2\2"+
"\2&\u00bb\3\2\2\2(\u00c5\3\2\2\2*\u00c7\3\2\2\2,\u00cb\3\2\2\2.\u00cd"+
"\3\2\2\2\60\u00d1\3\2\2\2\62\u00d5\3\2\2\2\64\u00d7\3\2\2\2\668\5\4\3"+
"\2\67\66\3\2\2\2\678\3\2\2\28:\3\2\2\29;\5\6\4\2:9\3\2\2\2:;\3\2\2\2;"+
"=\3\2\2\2<>\5\b\5\2=<\3\2\2\2=>\3\2\2\2>\3\3\2\2\2?@\7\3\2\2@A\7\4\2\2"+
"AB\5\f\7\2BC\7\5\2\2C\5\3\2\2\2DE\5\n\6\2E\7\3\2\2\2FG\7\6\2\2GH\5\20"+
"\t\2H\t\3\2\2\2IJ\7\7\2\2JK\7\60\2\2KL\7\4\2\2LM\5\f\7\2MN\7\5\2\2N\13"+
"\3\2\2\2OT\5\16\b\2PQ\7\b\2\2QS\5\16\b\2RP\3\2\2\2SV\3\2\2\2TR\3\2\2\2"+
"TU\3\2\2\2U\r\3\2\2\2VT\3\2\2\2WX\7\60\2\2X\17\3\2\2\2Y^\5\22\n\2Z[\7"+
"\t\2\2[]\5\22\n\2\\Z\3\2\2\2]`\3\2\2\2^\\\3\2\2\2^_\3\2\2\2_\21\3\2\2"+
"\2`^\3\2\2\2af\5\24\13\2bc\7\n\2\2ce\5\24\13\2db\3\2\2\2eh\3\2\2\2fd\3"+
"\2\2\2fg\3\2\2\2g\23\3\2\2\2hf\3\2\2\2ik\7\13\2\2ji\3\2\2\2jk\3\2\2\2"+
"kl\3\2\2\2lm\5\26\f\2m\25\3\2\2\2nt\5\30\r\2op\7\4\2\2pq\5\20\t\2qr\7"+
"\5\2\2rt\3\2\2\2sn\3\2\2\2so\3\2\2\2t\27\3\2\2\2u\u0083\5.\30\2v\u0083"+
"\5*\26\2w\u0083\5\36\20\2x\u0083\5 \21\2y\u0083\5\32\16\2z\u0083\5\"\22"+
"\2{\u0083\5$\23\2|\u0083\5&\24\2}\u0083\5(\25\2~\177\7\4\2\2\177\u0080"+
"\5\30\r\2\u0080\u0081\7\5\2\2\u0081\u0083\3\2\2\2\u0082u\3\2\2\2\u0082"+
"v\3\2\2\2\u0082w\3\2\2\2\u0082x\3\2\2\2\u0082y\3\2\2\2\u0082z\3\2\2\2"+
"\u0082{\3\2\2\2\u0082|\3\2\2\2\u0082}\3\2\2\2\u0082~\3\2\2\2\u0083\31"+
"\3\2\2\2\u0084\u0085\7\60\2\2\u0085\u0086\7\f\2\2\u0086\u0087\5\34\17"+
"\2\u0087\33\3\2\2\2\u0088\u0098\7/\2\2\u0089\u008a\7\4\2\2\u008a\u008b"+
"\7/\2\2\u008b\u0098\7\5\2\2\u008c\u008d\7\4\2\2\u008d\u0092\5\62\32\2"+
"\u008e\u008f\7\b\2\2\u008f\u0091\5\62\32\2\u0090\u008e\3\2\2\2\u0091\u0094"+
"\3\2\2\2\u0092\u0090\3\2\2\2\u0092\u0093\3\2\2\2\u0093\u0095\3\2\2\2\u0094"+
"\u0092\3\2\2\2\u0095\u0096\7\5\2\2\u0096\u0098\3\2\2\2\u0097\u0088\3\2"+
"\2\2\u0097\u0089\3\2\2\2\u0097\u008c\3\2\2\2\u0098\35\3\2\2\2\u0099\u009a"+
"\7\60\2\2\u009a\u009b\7\r\2\2\u009b\u009c\5\62\32\2\u009c\u009d\7\n\2"+
"\2\u009d\u009e\5\62\32\2\u009e\37\3\2\2\2\u009f\u00a0\5\62\32\2\u00a0"+
"\u00a1\7\r\2\2\u00a1\u00a2\7\60\2\2\u00a2\u00a3\7\n\2\2\u00a3\u00a4\7"+
"\60\2\2\u00a4!\3\2\2\2\u00a5\u00a6\7\60\2\2\u00a6\u00a7\7\16\2\2\u00a7"+
"\u00ab\7\17\2\2\u00a8\u00a9\7\60\2\2\u00a9\u00ab\7\20\2\2\u00aa\u00a5"+
"\3\2\2\2\u00aa\u00a8\3\2\2\2\u00ab#\3\2\2\2\u00ac\u00ad\7\60\2\2\u00ad"+
"\u00ae\7\16\2\2\u00ae\u00af\7\13\2\2\u00af\u00b5\7\17\2\2\u00b0\u00b1"+
"\7\60\2\2\u00b1\u00b5\7\21\2\2\u00b2\u00b3\7\60\2\2\u00b3\u00b5\7\22\2"+
"\2\u00b4\u00ac\3\2\2\2\u00b4\u00b0\3\2\2\2\u00b4\u00b2\3\2\2\2\u00b5%"+
"\3\2\2\2\u00b6\u00b7\7\60\2\2\u00b7\u00b8\7\16\2\2\u00b8\u00bc\7\23\2"+
"\2\u00b9\u00ba\7\60\2\2\u00ba\u00bc\7\24\2\2\u00bb\u00b6\3\2\2\2\u00bb"+
"\u00b9\3\2\2\2\u00bc\'\3\2\2\2\u00bd\u00be\7\60\2\2\u00be\u00bf\7\16\2"+
"\2\u00bf\u00c0\7\13\2\2\u00c0\u00c6\7\23\2\2\u00c1\u00c2\7\60\2\2\u00c2"+
"\u00c6\7\25\2\2\u00c3\u00c4\7\60\2\2\u00c4\u00c6\7\26\2\2\u00c5\u00bd"+
"\3\2\2\2\u00c5\u00c1\3\2\2\2\u00c5\u00c3\3\2\2\2\u00c6)\3\2\2\2\u00c7"+
"\u00c8\7\60\2\2\u00c8\u00c9\5,\27\2\u00c9\u00ca\5\62\32\2\u00ca+\3\2\2"+
"\2\u00cb\u00cc\t\2\2\2\u00cc-\3\2\2\2\u00cd\u00ce\7\60\2\2\u00ce\u00cf"+
"\5\60\31\2\u00cf\u00d0\5\62\32\2\u00d0/\3\2\2\2\u00d1\u00d2\t\3\2\2\u00d2"+
"\61\3\2\2\2\u00d3\u00d6\5\64\33\2\u00d4\u00d6\7/\2\2\u00d5\u00d3\3\2\2"+
"\2\u00d5\u00d4\3\2\2\2\u00d6\63\3\2\2\2\u00d7\u00d8\t\4\2\2\u00d8\65\3"+
"\2\2\2\22\67:=T^fjs\u0082\u0092\u0097\u00aa\u00b4\u00bb\u00c5\u00d5";
"\r\u0083\n\r\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\7\17\u008e\n"+
"\17\f\17\16\17\u0091\13\17\3\17\3\17\5\17\u0095\n\17\3\20\3\20\3\20\3"+
"\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\5"+
"\22\u00a8\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u00b2\n\23"+
"\3\24\3\24\3\24\3\24\3\24\5\24\u00b9\n\24\3\25\3\25\3\25\3\25\3\25\3\25"+
"\3\25\3\25\5\25\u00c3\n\25\3\26\3\26\3\26\3\26\3\27\3\27\3\30\3\30\3\30"+
"\3\30\3\31\3\31\3\32\3\32\5\32\u00d3\n\32\3\33\3\33\3\33\2\2\34\2\4\6"+
"\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\2\5\3\2\27\36\3\2"+
"\37.\3\2\61\63\u00d6\2\67\3\2\2\2\4?\3\2\2\2\6D\3\2\2\2\bF\3\2\2\2\nI"+
"\3\2\2\2\fO\3\2\2\2\16W\3\2\2\2\20Y\3\2\2\2\22a\3\2\2\2\24j\3\2\2\2\26"+
"s\3\2\2\2\30\u0082\3\2\2\2\32\u0084\3\2\2\2\34\u0094\3\2\2\2\36\u0096"+
"\3\2\2\2 \u009c\3\2\2\2\"\u00a7\3\2\2\2$\u00b1\3\2\2\2&\u00b8\3\2\2\2"+
"(\u00c2\3\2\2\2*\u00c4\3\2\2\2,\u00c8\3\2\2\2.\u00ca\3\2\2\2\60\u00ce"+
"\3\2\2\2\62\u00d2\3\2\2\2\64\u00d4\3\2\2\2\668\5\4\3\2\67\66\3\2\2\2\67"+
"8\3\2\2\28:\3\2\2\29;\5\6\4\2:9\3\2\2\2:;\3\2\2\2;=\3\2\2\2<>\5\b\5\2"+
"=<\3\2\2\2=>\3\2\2\2>\3\3\2\2\2?@\7\3\2\2@A\7\4\2\2AB\5\f\7\2BC\7\5\2"+
"\2C\5\3\2\2\2DE\5\n\6\2E\7\3\2\2\2FG\7\6\2\2GH\5\20\t\2H\t\3\2\2\2IJ\7"+
"\7\2\2JK\7\60\2\2KL\7\4\2\2LM\5\f\7\2MN\7\5\2\2N\13\3\2\2\2OT\5\16\b\2"+
"PQ\7\b\2\2QS\5\16\b\2RP\3\2\2\2SV\3\2\2\2TR\3\2\2\2TU\3\2\2\2U\r\3\2\2"+
"\2VT\3\2\2\2WX\7\60\2\2X\17\3\2\2\2Y^\5\22\n\2Z[\7\t\2\2[]\5\22\n\2\\"+
"Z\3\2\2\2]`\3\2\2\2^\\\3\2\2\2^_\3\2\2\2_\21\3\2\2\2`^\3\2\2\2af\5\24"+
"\13\2bc\7\n\2\2ce\5\24\13\2db\3\2\2\2eh\3\2\2\2fd\3\2\2\2fg\3\2\2\2g\23"+
"\3\2\2\2hf\3\2\2\2ik\7\13\2\2ji\3\2\2\2jk\3\2\2\2kl\3\2\2\2lm\5\26\f\2"+
"m\25\3\2\2\2nt\5\30\r\2op\7\4\2\2pq\5\20\t\2qr\7\5\2\2rt\3\2\2\2sn\3\2"+
"\2\2so\3\2\2\2t\27\3\2\2\2u\u0083\5.\30\2v\u0083\5*\26\2w\u0083\5\36\20"+
"\2x\u0083\5 \21\2y\u0083\5\32\16\2z\u0083\5\"\22\2{\u0083\5$\23\2|\u0083"+
"\5&\24\2}\u0083\5(\25\2~\177\7\4\2\2\177\u0080\5\30\r\2\u0080\u0081\7"+
"\5\2\2\u0081\u0083\3\2\2\2\u0082u\3\2\2\2\u0082v\3\2\2\2\u0082w\3\2\2"+
"\2\u0082x\3\2\2\2\u0082y\3\2\2\2\u0082z\3\2\2\2\u0082{\3\2\2\2\u0082|"+
"\3\2\2\2\u0082}\3\2\2\2\u0082~\3\2\2\2\u0083\31\3\2\2\2\u0084\u0085\7"+
"\60\2\2\u0085\u0086\7\f\2\2\u0086\u0087\5\34\17\2\u0087\33\3\2\2\2\u0088"+
"\u0095\7/\2\2\u0089\u008a\7\4\2\2\u008a\u008f\5\62\32\2\u008b\u008c\7"+
"\b\2\2\u008c\u008e\5\62\32\2\u008d\u008b\3\2\2\2\u008e\u0091\3\2\2\2\u008f"+
"\u008d\3\2\2\2\u008f\u0090\3\2\2\2\u0090\u0092\3\2\2\2\u0091\u008f\3\2"+
"\2\2\u0092\u0093\7\5\2\2\u0093\u0095\3\2\2\2\u0094\u0088\3\2\2\2\u0094"+
"\u0089\3\2\2\2\u0095\35\3\2\2\2\u0096\u0097\7\60\2\2\u0097\u0098\7\r\2"+
"\2\u0098\u0099\5\62\32\2\u0099\u009a\7\n\2\2\u009a\u009b\5\62\32\2\u009b"+
"\37\3\2\2\2\u009c\u009d\5\62\32\2\u009d\u009e\7\r\2\2\u009e\u009f\7\60"+
"\2\2\u009f\u00a0\7\n\2\2\u00a0\u00a1\7\60\2\2\u00a1!\3\2\2\2\u00a2\u00a3"+
"\7\60\2\2\u00a3\u00a4\7\16\2\2\u00a4\u00a8\7\17\2\2\u00a5\u00a6\7\60\2"+
"\2\u00a6\u00a8\7\20\2\2\u00a7\u00a2\3\2\2\2\u00a7\u00a5\3\2\2\2\u00a8"+
"#\3\2\2\2\u00a9\u00aa\7\60\2\2\u00aa\u00ab\7\16\2\2\u00ab\u00ac\7\13\2"+
"\2\u00ac\u00b2\7\17\2\2\u00ad\u00ae\7\60\2\2\u00ae\u00b2\7\21\2\2\u00af"+
"\u00b0\7\60\2\2\u00b0\u00b2\7\22\2\2\u00b1\u00a9\3\2\2\2\u00b1\u00ad\3"+
"\2\2\2\u00b1\u00af\3\2\2\2\u00b2%\3\2\2\2\u00b3\u00b4\7\60\2\2\u00b4\u00b5"+
"\7\16\2\2\u00b5\u00b9\7\23\2\2\u00b6\u00b7\7\60\2\2\u00b7\u00b9\7\24\2"+
"\2\u00b8\u00b3\3\2\2\2\u00b8\u00b6\3\2\2\2\u00b9\'\3\2\2\2\u00ba\u00bb"+
"\7\60\2\2\u00bb\u00bc\7\16\2\2\u00bc\u00bd\7\13\2\2\u00bd\u00c3\7\23\2"+
"\2\u00be\u00bf\7\60\2\2\u00bf\u00c3\7\25\2\2\u00c0\u00c1\7\60\2\2\u00c1"+
"\u00c3\7\26\2\2\u00c2\u00ba\3\2\2\2\u00c2\u00be\3\2\2\2\u00c2\u00c0\3"+
"\2\2\2\u00c3)\3\2\2\2\u00c4\u00c5\7\60\2\2\u00c5\u00c6\5,\27\2\u00c6\u00c7"+
"\5\62\32\2\u00c7+\3\2\2\2\u00c8\u00c9\t\2\2\2\u00c9-\3\2\2\2\u00ca\u00cb"+
"\7\60\2\2\u00cb\u00cc\5\60\31\2\u00cc\u00cd\5\62\32\2\u00cd/\3\2\2\2\u00ce"+
"\u00cf\t\3\2\2\u00cf\61\3\2\2\2\u00d0\u00d3\5\64\33\2\u00d1\u00d3\7/\2"+
"\2\u00d2\u00d0\3\2\2\2\u00d2\u00d1\3\2\2\2\u00d3\63\3\2\2\2\u00d4\u00d5"+
"\t\4\2\2\u00d5\65\3\2\2\2\22\67:=T^fjs\u0082\u008f\u0094\u00a7\u00b1\u00b8"+
"\u00c2\u00d2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {