From fdd1f152a73c91cf4f9d90f0365a15895b6417b3 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 16 Jun 2016 11:02:06 -0400 Subject: [PATCH 1/4] improve lambda syntax (allow single expression) --- .../src/main/antlr/PainlessParser.g4 | 2 +- .../painless/antlr/PainlessParser.java | 367 +++++++++--------- .../elasticsearch/painless/antlr/Walker.java | 10 +- .../elasticsearch/painless/LambdaTests.java | 28 +- 4 files changed, 217 insertions(+), 190 deletions(-) diff --git a/modules/lang-painless/src/main/antlr/PainlessParser.g4 b/modules/lang-painless/src/main/antlr/PainlessParser.g4 index a020b0d7d73..6dbaa50c73d 100644 --- a/modules/lang-painless/src/main/antlr/PainlessParser.g4 +++ b/modules/lang-painless/src/main/antlr/PainlessParser.g4 @@ -189,7 +189,7 @@ argument ; lambda - : ( lamtype | LP ( lamtype ( COMMA lamtype )* )? RP ) ARROW block + : ( lamtype | LP ( lamtype ( COMMA lamtype )* )? RP ) ARROW ( block | expression ) ; lamtype diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java index ba3798bb414..7b994e699a2 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java @@ -2754,9 +2754,6 @@ class PainlessParser extends Parser { public static class LambdaContext extends ParserRuleContext { public TerminalNode ARROW() { return getToken(PainlessParser.ARROW, 0); } - public BlockContext block() { - return getRuleContext(BlockContext.class,0); - } public List lamtype() { return getRuleContexts(LamtypeContext.class); } @@ -2765,6 +2762,12 @@ class PainlessParser extends Parser { } public TerminalNode LP() { return getToken(PainlessParser.LP, 0); } public TerminalNode RP() { return getToken(PainlessParser.RP, 0); } + public BlockContext block() { + return getRuleContext(BlockContext.class,0); + } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } public List COMMA() { return getTokens(PainlessParser.COMMA); } public TerminalNode COMMA(int i) { return getToken(PainlessParser.COMMA, i); @@ -2834,8 +2837,21 @@ class PainlessParser extends Parser { } setState(448); match(ARROW); - setState(449); - block(); + setState(451); + switch ( getInterpreter().adaptivePredict(_input,38,_ctx) ) { + case 1: + { + setState(449); + block(); + } + break; + case 2: + { + setState(450); + expression(0); + } + break; + } } } catch (RecognitionException re) { @@ -2872,16 +2888,16 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(452); + setState(454); _la = _input.LA(1); if (_la==TYPE) { { - setState(451); + setState(453); decltype(); } } - setState(454); + setState(456); match(ID); } } @@ -2924,33 +2940,33 @@ class PainlessParser extends Parser { FuncrefContext _localctx = new FuncrefContext(_ctx, getState()); enterRule(_localctx, 50, RULE_funcref); try { - setState(460); - switch ( getInterpreter().adaptivePredict(_input,39,_ctx) ) { + setState(462); + switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(456); + setState(458); classFuncref(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(457); + setState(459); constructorFuncref(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(458); + setState(460); capturingFuncref(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(459); + setState(461); localFuncref(); } break; @@ -2988,11 +3004,11 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(462); - match(TYPE); - setState(463); - match(REF); setState(464); + match(TYPE); + setState(465); + match(REF); + setState(466); match(ID); } } @@ -3030,11 +3046,11 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(466); - decltype(); - setState(467); - match(REF); setState(468); + decltype(); + setState(469); + match(REF); + setState(470); match(NEW); } } @@ -3072,12 +3088,12 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(470); - match(ID); - setState(471); - match(REF); setState(472); match(ID); + setState(473); + match(REF); + setState(474); + match(ID); } } catch (RecognitionException re) { @@ -3112,11 +3128,11 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(474); - match(THIS); - setState(475); - match(REF); setState(476); + match(THIS); + setState(477); + match(REF); + setState(478); match(ID); } } @@ -3223,7 +3239,7 @@ class PainlessParser extends Parser { } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3R\u01e1\4\2\t\2\4"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3R\u01e3\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"+ @@ -3257,152 +3273,153 @@ class PainlessParser extends Parser { "\u019c\n\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\7\27\u01a6\n\27\f"+ "\27\16\27\u01a9\13\27\5\27\u01ab\n\27\3\27\3\27\3\30\3\30\3\30\5\30\u01b2"+ "\n\30\3\31\3\31\3\31\3\31\3\31\7\31\u01b9\n\31\f\31\16\31\u01bc\13\31"+ - "\5\31\u01be\n\31\3\31\5\31\u01c1\n\31\3\31\3\31\3\31\3\32\5\32\u01c7\n"+ - "\32\3\32\3\32\3\33\3\33\3\33\3\33\5\33\u01cf\n\33\3\34\3\34\3\34\3\34"+ - "\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3\37\2\3"+ - "\36 \2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<\2"+ - "\r\3\2:E\3\2\35\37\3\2 !\3\2\66\67\3\2\"$\3\2%(\3\2),\3\289\3\2FI\4\2"+ - "\33\34 !\3\2QR\u020f\2A\3\2\2\2\4L\3\2\2\2\6Q\3\2\2\2\b\u00af\3\2\2\2"+ - "\n\u00b3\3\2\2\2\f\u00b5\3\2\2\2\16\u00be\3\2\2\2\20\u00c2\3\2\2\2\22"+ - "\u00c4\3\2\2\2\24\u00c6\3\2\2\2\26\u00cf\3\2\2\2\30\u00d7\3\2\2\2\32\u00dc"+ - "\3\2\2\2\34\u00e8\3\2\2\2\36\u00f3\3\2\2\2 \u0155\3\2\2\2\"\u0179\3\2"+ - "\2\2$\u018e\3\2\2\2&\u0194\3\2\2\2(\u019b\3\2\2\2*\u019d\3\2\2\2,\u01a1"+ - "\3\2\2\2.\u01b1\3\2\2\2\60\u01c0\3\2\2\2\62\u01c6\3\2\2\2\64\u01ce\3\2"+ - "\2\2\66\u01d0\3\2\2\28\u01d4\3\2\2\2:\u01d8\3\2\2\2<\u01dc\3\2\2\2>@\5"+ - "\4\3\2?>\3\2\2\2@C\3\2\2\2A?\3\2\2\2AB\3\2\2\2BG\3\2\2\2CA\3\2\2\2DF\5"+ - "\b\5\2ED\3\2\2\2FI\3\2\2\2GE\3\2\2\2GH\3\2\2\2HJ\3\2\2\2IG\3\2\2\2JK\7"+ - "\2\2\3K\3\3\2\2\2LM\5\26\f\2MN\7P\2\2NO\5\6\4\2OP\5\f\7\2P\5\3\2\2\2Q"+ - "]\7\t\2\2RS\5\26\f\2SZ\7P\2\2TU\7\f\2\2UV\5\26\f\2VW\7P\2\2WY\3\2\2\2"+ - "XT\3\2\2\2Y\\\3\2\2\2ZX\3\2\2\2Z[\3\2\2\2[^\3\2\2\2\\Z\3\2\2\2]R\3\2\2"+ - "\2]^\3\2\2\2^_\3\2\2\2_`\7\n\2\2`\7\3\2\2\2ab\7\16\2\2bc\7\t\2\2cd\5\36"+ - "\20\2de\7\n\2\2ei\5\n\6\2fg\7\17\2\2gj\5\n\6\2hj\6\5\2\2if\3\2\2\2ih\3"+ - "\2\2\2j\u00b0\3\2\2\2kl\7\20\2\2lm\7\t\2\2mn\5\36\20\2nq\7\n\2\2or\5\n"+ - "\6\2pr\5\16\b\2qo\3\2\2\2qp\3\2\2\2r\u00b0\3\2\2\2st\7\21\2\2tu\5\f\7"+ - "\2uv\7\20\2\2vw\7\t\2\2wx\5\36\20\2xy\7\n\2\2yz\5\34\17\2z\u00b0\3\2\2"+ - "\2{|\7\22\2\2|~\7\t\2\2}\177\5\20\t\2~}\3\2\2\2~\177\3\2\2\2\177\u0080"+ - "\3\2\2\2\u0080\u0082\7\r\2\2\u0081\u0083\5\36\20\2\u0082\u0081\3\2\2\2"+ - "\u0082\u0083\3\2\2\2\u0083\u0084\3\2\2\2\u0084\u0086\7\r\2\2\u0085\u0087"+ - "\5\22\n\2\u0086\u0085\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u0088\3\2\2\2"+ - "\u0088\u008b\7\n\2\2\u0089\u008c\5\n\6\2\u008a\u008c\5\16\b\2\u008b\u0089"+ - "\3\2\2\2\u008b\u008a\3\2\2\2\u008c\u00b0\3\2\2\2\u008d\u008e\7\22\2\2"+ - "\u008e\u008f\7\t\2\2\u008f\u0090\5\26\f\2\u0090\u0091\7P\2\2\u0091\u0092"+ - "\7\63\2\2\u0092\u0093\5\36\20\2\u0093\u0094\7\n\2\2\u0094\u0095\5\n\6"+ - "\2\u0095\u00b0\3\2\2\2\u0096\u0097\5\24\13\2\u0097\u0098\5\34\17\2\u0098"+ - "\u00b0\3\2\2\2\u0099\u009a\7\23\2\2\u009a\u00b0\5\34\17\2\u009b\u009c"+ - "\7\24\2\2\u009c\u00b0\5\34\17\2\u009d\u009e\7\25\2\2\u009e\u009f\5\36"+ - "\20\2\u009f\u00a0\5\34\17\2\u00a0\u00b0\3\2\2\2\u00a1\u00a2\7\27\2\2\u00a2"+ - "\u00a4\5\f\7\2\u00a3\u00a5\5\32\16\2\u00a4\u00a3\3\2\2\2\u00a5\u00a6\3"+ - "\2\2\2\u00a6\u00a4\3\2\2\2\u00a6\u00a7\3\2\2\2\u00a7\u00b0\3\2\2\2\u00a8"+ - "\u00a9\7\31\2\2\u00a9\u00aa\5\36\20\2\u00aa\u00ab\5\34\17\2\u00ab\u00b0"+ - "\3\2\2\2\u00ac\u00ad\5\36\20\2\u00ad\u00ae\5\34\17\2\u00ae\u00b0\3\2\2"+ - "\2\u00afa\3\2\2\2\u00afk\3\2\2\2\u00afs\3\2\2\2\u00af{\3\2\2\2\u00af\u008d"+ - "\3\2\2\2\u00af\u0096\3\2\2\2\u00af\u0099\3\2\2\2\u00af\u009b\3\2\2\2\u00af"+ - "\u009d\3\2\2\2\u00af\u00a1\3\2\2\2\u00af\u00a8\3\2\2\2\u00af\u00ac\3\2"+ - "\2\2\u00b0\t\3\2\2\2\u00b1\u00b4\5\f\7\2\u00b2\u00b4\5\b\5\2\u00b3\u00b1"+ - "\3\2\2\2\u00b3\u00b2\3\2\2\2\u00b4\13\3\2\2\2\u00b5\u00b9\7\5\2\2\u00b6"+ - "\u00b8\5\b\5\2\u00b7\u00b6\3\2\2\2\u00b8\u00bb\3\2\2\2\u00b9\u00b7\3\2"+ - "\2\2\u00b9\u00ba\3\2\2\2\u00ba\u00bc\3\2\2\2\u00bb\u00b9\3\2\2\2\u00bc"+ - "\u00bd\7\6\2\2\u00bd\r\3\2\2\2\u00be\u00bf\7\r\2\2\u00bf\17\3\2\2\2\u00c0"+ - "\u00c3\5\24\13\2\u00c1\u00c3\5\36\20\2\u00c2\u00c0\3\2\2\2\u00c2\u00c1"+ - "\3\2\2\2\u00c3\21\3\2\2\2\u00c4\u00c5\5\36\20\2\u00c5\23\3\2\2\2\u00c6"+ - "\u00c7\5\26\f\2\u00c7\u00cc\5\30\r\2\u00c8\u00c9\7\f\2\2\u00c9\u00cb\5"+ - "\30\r\2\u00ca\u00c8\3\2\2\2\u00cb\u00ce\3\2\2\2\u00cc\u00ca\3\2\2\2\u00cc"+ - "\u00cd\3\2\2\2\u00cd\25\3\2\2\2\u00ce\u00cc\3\2\2\2\u00cf\u00d4\7O\2\2"+ - "\u00d0\u00d1\7\7\2\2\u00d1\u00d3\7\b\2\2\u00d2\u00d0\3\2\2\2\u00d3\u00d6"+ - "\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d4\u00d5\3\2\2\2\u00d5\27\3\2\2\2\u00d6"+ - "\u00d4\3\2\2\2\u00d7\u00da\7P\2\2\u00d8\u00d9\7:\2\2\u00d9\u00db\5\36"+ - "\20\2\u00da\u00d8\3\2\2\2\u00da\u00db\3\2\2\2\u00db\31\3\2\2\2\u00dc\u00dd"+ - "\7\30\2\2\u00dd\u00de\7\t\2\2\u00de\u00df\7O\2\2\u00df\u00e0\7P\2\2\u00e0"+ - "\u00e1\7\n\2\2\u00e1\u00e2\5\f\7\2\u00e2\33\3\2\2\2\u00e3\u00e9\7\r\2"+ - "\2\u00e4\u00e9\7\2\2\3\u00e5\u00e6\b\17\1\2\u00e6\u00e7\7\6\2\2\u00e7"+ - "\u00e9\b\17\1\2\u00e8\u00e3\3\2\2\2\u00e8\u00e4\3\2\2\2\u00e8\u00e5\3"+ - "\2\2\2\u00e9\35\3\2\2\2\u00ea\u00eb\b\20\1\2\u00eb\u00ec\5\"\22\2\u00ec"+ - "\u00ed\t\2\2\2\u00ed\u00ee\5\36\20\3\u00ee\u00ef\b\20\1\2\u00ef\u00f4"+ - "\3\2\2\2\u00f0\u00f1\5 \21\2\u00f1\u00f2\b\20\1\2\u00f2\u00f4\3\2\2\2"+ - "\u00f3\u00ea\3\2\2\2\u00f3\u00f0\3\2\2\2\u00f4\u0135\3\2\2\2\u00f5\u00f6"+ - "\f\17\2\2\u00f6\u00f7\t\3\2\2\u00f7\u00f8\5\36\20\20\u00f8\u00f9\b\20"+ - "\1\2\u00f9\u0134\3\2\2\2\u00fa\u00fb\f\16\2\2\u00fb\u00fc\t\4\2\2\u00fc"+ - "\u00fd\5\36\20\17\u00fd\u00fe\b\20\1\2\u00fe\u0134\3\2\2\2\u00ff\u0100"+ - "\f\r\2\2\u0100\u0101\t\5\2\2\u0101\u0102\5\36\20\16\u0102\u0103\b\20\1"+ - "\2\u0103\u0134\3\2\2\2\u0104\u0105\f\f\2\2\u0105\u0106\t\6\2\2\u0106\u0107"+ - "\5\36\20\r\u0107\u0108\b\20\1\2\u0108\u0134\3\2\2\2\u0109\u010a\f\13\2"+ - "\2\u010a\u010b\t\7\2\2\u010b\u010c\5\36\20\f\u010c\u010d\b\20\1\2\u010d"+ - "\u0134\3\2\2\2\u010e\u010f\f\n\2\2\u010f\u0110\t\b\2\2\u0110\u0111\5\36"+ - "\20\13\u0111\u0112\b\20\1\2\u0112\u0134\3\2\2\2\u0113\u0114\f\t\2\2\u0114"+ - "\u0115\7-\2\2\u0115\u0116\5\36\20\n\u0116\u0117\b\20\1\2\u0117\u0134\3"+ - "\2\2\2\u0118\u0119\f\b\2\2\u0119\u011a\7.\2\2\u011a\u011b\5\36\20\t\u011b"+ - "\u011c\b\20\1\2\u011c\u0134\3\2\2\2\u011d\u011e\f\7\2\2\u011e\u011f\7"+ - "/\2\2\u011f\u0120\5\36\20\b\u0120\u0121\b\20\1\2\u0121\u0134\3\2\2\2\u0122"+ - "\u0123\f\6\2\2\u0123\u0124\7\60\2\2\u0124\u0125\5\36\20\7\u0125\u0126"+ - "\b\20\1\2\u0126\u0134\3\2\2\2\u0127\u0128\f\5\2\2\u0128\u0129\7\61\2\2"+ - "\u0129\u012a\5\36\20\6\u012a\u012b\b\20\1\2\u012b\u0134\3\2\2\2\u012c"+ - "\u012d\f\4\2\2\u012d\u012e\7\62\2\2\u012e\u012f\5\36\20\2\u012f\u0130"+ - "\7\63\2\2\u0130\u0131\5\36\20\4\u0131\u0132\b\20\1\2\u0132\u0134\3\2\2"+ - "\2\u0133\u00f5\3\2\2\2\u0133\u00fa\3\2\2\2\u0133\u00ff\3\2\2\2\u0133\u0104"+ - "\3\2\2\2\u0133\u0109\3\2\2\2\u0133\u010e\3\2\2\2\u0133\u0113\3\2\2\2\u0133"+ - "\u0118\3\2\2\2\u0133\u011d\3\2\2\2\u0133\u0122\3\2\2\2\u0133\u0127\3\2"+ - "\2\2\u0133\u012c\3\2\2\2\u0134\u0137\3\2\2\2\u0135\u0133\3\2\2\2\u0135"+ - "\u0136\3\2\2\2\u0136\37\3\2\2\2\u0137\u0135\3\2\2\2\u0138\u0139\6\21\17"+ - "\3\u0139\u013a\t\t\2\2\u013a\u0156\5\"\22\2\u013b\u013c\6\21\20\3\u013c"+ - "\u013d\5\"\22\2\u013d\u013e\t\t\2\2\u013e\u0156\3\2\2\2\u013f\u0140\6"+ - "\21\21\3\u0140\u0156\5\"\22\2\u0141\u0142\6\21\22\3\u0142\u0143\t\n\2"+ - "\2\u0143\u0156\b\21\1\2\u0144\u0145\6\21\23\3\u0145\u0146\7L\2\2\u0146"+ - "\u0156\b\21\1\2\u0147\u0148\6\21\24\3\u0148\u0149\7M\2\2\u0149\u0156\b"+ - "\21\1\2\u014a\u014b\6\21\25\3\u014b\u014c\7N\2\2\u014c\u0156\b\21\1\2"+ - "\u014d\u014e\6\21\26\3\u014e\u014f\t\13\2\2\u014f\u0156\5 \21\2\u0150"+ - "\u0151\7\t\2\2\u0151\u0152\5\26\f\2\u0152\u0153\7\n\2\2\u0153\u0154\5"+ - " \21\2\u0154\u0156\3\2\2\2\u0155\u0138\3\2\2\2\u0155\u013b\3\2\2\2\u0155"+ - "\u013f\3\2\2\2\u0155\u0141\3\2\2\2\u0155\u0144\3\2\2\2\u0155\u0147\3\2"+ - "\2\2\u0155\u014a\3\2\2\2\u0155\u014d\3\2\2\2\u0155\u0150\3\2\2\2\u0156"+ - "!\3\2\2\2\u0157\u015b\5$\23\2\u0158\u015a\5&\24\2\u0159\u0158\3\2\2\2"+ - "\u015a\u015d\3\2\2\2\u015b\u0159\3\2\2\2\u015b\u015c\3\2\2\2\u015c\u017a"+ - "\3\2\2\2\u015d\u015b\3\2\2\2\u015e\u015f\5\26\f\2\u015f\u0163\5(\25\2"+ - "\u0160\u0162\5&\24\2\u0161\u0160\3\2\2\2\u0162\u0165\3\2\2\2\u0163\u0161"+ - "\3\2\2\2\u0163\u0164\3\2\2\2\u0164\u017a\3\2\2\2\u0165\u0163\3\2\2\2\u0166"+ - "\u0167\7\26\2\2\u0167\u016c\7O\2\2\u0168\u0169\7\7\2\2\u0169\u016a\5\36"+ - "\20\2\u016a\u016b\7\b\2\2\u016b\u016d\3\2\2\2\u016c\u0168\3\2\2\2\u016d"+ - "\u016e\3\2\2\2\u016e\u016c\3\2\2\2\u016e\u016f\3\2\2\2\u016f\u0177\3\2"+ - "\2\2\u0170\u0174\5(\25\2\u0171\u0173\5&\24\2\u0172\u0171\3\2\2\2\u0173"+ - "\u0176\3\2\2\2\u0174\u0172\3\2\2\2\u0174\u0175\3\2\2\2\u0175\u0178\3\2"+ - "\2\2\u0176\u0174\3\2\2\2\u0177\u0170\3\2\2\2\u0177\u0178\3\2\2\2\u0178"+ - "\u017a\3\2\2\2\u0179\u0157\3\2\2\2\u0179\u015e\3\2\2\2\u0179\u0166\3\2"+ - "\2\2\u017a#\3\2\2\2\u017b\u017c\6\23\27\3\u017c\u017d\7\t\2\2\u017d\u017e"+ - "\5\36\20\2\u017e\u017f\7\n\2\2\u017f\u0180\b\23\1\2\u0180\u018f\3\2\2"+ - "\2\u0181\u0182\6\23\30\3\u0182\u0183\7\t\2\2\u0183\u0184\5 \21\2\u0184"+ - "\u0185\7\n\2\2\u0185\u018f\3\2\2\2\u0186\u018f\7J\2\2\u0187\u018f\7K\2"+ - "\2\u0188\u018f\7P\2\2\u0189\u018a\7P\2\2\u018a\u018f\5,\27\2\u018b\u018c"+ - "\7\26\2\2\u018c\u018d\7O\2\2\u018d\u018f\5,\27\2\u018e\u017b\3\2\2\2\u018e"+ - "\u0181\3\2\2\2\u018e\u0186\3\2\2\2\u018e\u0187\3\2\2\2\u018e\u0188\3\2"+ - "\2\2\u018e\u0189\3\2\2\2\u018e\u018b\3\2\2\2\u018f%\3\2\2\2\u0190\u0191"+ - "\6\24\31\3\u0191\u0195\5(\25\2\u0192\u0193\6\24\32\3\u0193\u0195\5*\26"+ - "\2\u0194\u0190\3\2\2\2\u0194\u0192\3\2\2\2\u0195\'\3\2\2\2\u0196\u0197"+ - "\7\13\2\2\u0197\u0198\7R\2\2\u0198\u019c\5,\27\2\u0199\u019a\7\13\2\2"+ - "\u019a\u019c\t\f\2\2\u019b\u0196\3\2\2\2\u019b\u0199\3\2\2\2\u019c)\3"+ - "\2\2\2\u019d\u019e\7\7\2\2\u019e\u019f\5\36\20\2\u019f\u01a0\7\b\2\2\u01a0"+ - "+\3\2\2\2\u01a1\u01aa\7\t\2\2\u01a2\u01a7\5.\30\2\u01a3\u01a4\7\f\2\2"+ - "\u01a4\u01a6\5.\30\2\u01a5\u01a3\3\2\2\2\u01a6\u01a9\3\2\2\2\u01a7\u01a5"+ - "\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01ab\3\2\2\2\u01a9\u01a7\3\2\2\2\u01aa"+ - "\u01a2\3\2\2\2\u01aa\u01ab\3\2\2\2\u01ab\u01ac\3\2\2\2\u01ac\u01ad\7\n"+ - "\2\2\u01ad-\3\2\2\2\u01ae\u01b2\5\36\20\2\u01af\u01b2\5\60\31\2\u01b0"+ - "\u01b2\5\64\33\2\u01b1\u01ae\3\2\2\2\u01b1\u01af\3\2\2\2\u01b1\u01b0\3"+ - "\2\2\2\u01b2/\3\2\2\2\u01b3\u01c1\5\62\32\2\u01b4\u01bd\7\t\2\2\u01b5"+ - "\u01ba\5\62\32\2\u01b6\u01b7\7\f\2\2\u01b7\u01b9\5\62\32\2\u01b8\u01b6"+ - "\3\2\2\2\u01b9\u01bc\3\2\2\2\u01ba\u01b8\3\2\2\2\u01ba\u01bb\3\2\2\2\u01bb"+ - "\u01be\3\2\2\2\u01bc\u01ba\3\2\2\2\u01bd\u01b5\3\2\2\2\u01bd\u01be\3\2"+ - "\2\2\u01be\u01bf\3\2\2\2\u01bf\u01c1\7\n\2\2\u01c0\u01b3\3\2\2\2\u01c0"+ - "\u01b4\3\2\2\2\u01c1\u01c2\3\2\2\2\u01c2\u01c3\7\65\2\2\u01c3\u01c4\5"+ - "\f\7\2\u01c4\61\3\2\2\2\u01c5\u01c7\5\26\f\2\u01c6\u01c5\3\2\2\2\u01c6"+ - "\u01c7\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01c9\7P\2\2\u01c9\63\3\2\2\2"+ - "\u01ca\u01cf\5\66\34\2\u01cb\u01cf\58\35\2\u01cc\u01cf\5:\36\2\u01cd\u01cf"+ - "\5<\37\2\u01ce\u01ca\3\2\2\2\u01ce\u01cb\3\2\2\2\u01ce\u01cc\3\2\2\2\u01ce"+ - "\u01cd\3\2\2\2\u01cf\65\3\2\2\2\u01d0\u01d1\7O\2\2\u01d1\u01d2\7\64\2"+ - "\2\u01d2\u01d3\7P\2\2\u01d3\67\3\2\2\2\u01d4\u01d5\5\26\f\2\u01d5\u01d6"+ - "\7\64\2\2\u01d6\u01d7\7\26\2\2\u01d79\3\2\2\2\u01d8\u01d9\7P\2\2\u01d9"+ - "\u01da\7\64\2\2\u01da\u01db\7P\2\2\u01db;\3\2\2\2\u01dc\u01dd\7\32\2\2"+ - "\u01dd\u01de\7\64\2\2\u01de\u01df\7P\2\2\u01df=\3\2\2\2*AGZ]iq~\u0082"+ + "\5\31\u01be\n\31\3\31\5\31\u01c1\n\31\3\31\3\31\3\31\5\31\u01c6\n\31\3"+ + "\32\5\32\u01c9\n\32\3\32\3\32\3\33\3\33\3\33\3\33\5\33\u01d1\n\33\3\34"+ + "\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37"+ + "\3\37\3\37\2\3\36 \2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60"+ + "\62\64\668:<\2\r\3\2:E\3\2\35\37\3\2 !\3\2\66\67\3\2\"$\3\2%(\3\2),\3"+ + "\289\3\2FI\4\2\33\34 !\3\2QR\u0212\2A\3\2\2\2\4L\3\2\2\2\6Q\3\2\2\2\b"+ + "\u00af\3\2\2\2\n\u00b3\3\2\2\2\f\u00b5\3\2\2\2\16\u00be\3\2\2\2\20\u00c2"+ + "\3\2\2\2\22\u00c4\3\2\2\2\24\u00c6\3\2\2\2\26\u00cf\3\2\2\2\30\u00d7\3"+ + "\2\2\2\32\u00dc\3\2\2\2\34\u00e8\3\2\2\2\36\u00f3\3\2\2\2 \u0155\3\2\2"+ + "\2\"\u0179\3\2\2\2$\u018e\3\2\2\2&\u0194\3\2\2\2(\u019b\3\2\2\2*\u019d"+ + "\3\2\2\2,\u01a1\3\2\2\2.\u01b1\3\2\2\2\60\u01c0\3\2\2\2\62\u01c8\3\2\2"+ + "\2\64\u01d0\3\2\2\2\66\u01d2\3\2\2\28\u01d6\3\2\2\2:\u01da\3\2\2\2<\u01de"+ + "\3\2\2\2>@\5\4\3\2?>\3\2\2\2@C\3\2\2\2A?\3\2\2\2AB\3\2\2\2BG\3\2\2\2C"+ + "A\3\2\2\2DF\5\b\5\2ED\3\2\2\2FI\3\2\2\2GE\3\2\2\2GH\3\2\2\2HJ\3\2\2\2"+ + "IG\3\2\2\2JK\7\2\2\3K\3\3\2\2\2LM\5\26\f\2MN\7P\2\2NO\5\6\4\2OP\5\f\7"+ + "\2P\5\3\2\2\2Q]\7\t\2\2RS\5\26\f\2SZ\7P\2\2TU\7\f\2\2UV\5\26\f\2VW\7P"+ + "\2\2WY\3\2\2\2XT\3\2\2\2Y\\\3\2\2\2ZX\3\2\2\2Z[\3\2\2\2[^\3\2\2\2\\Z\3"+ + "\2\2\2]R\3\2\2\2]^\3\2\2\2^_\3\2\2\2_`\7\n\2\2`\7\3\2\2\2ab\7\16\2\2b"+ + "c\7\t\2\2cd\5\36\20\2de\7\n\2\2ei\5\n\6\2fg\7\17\2\2gj\5\n\6\2hj\6\5\2"+ + "\2if\3\2\2\2ih\3\2\2\2j\u00b0\3\2\2\2kl\7\20\2\2lm\7\t\2\2mn\5\36\20\2"+ + "nq\7\n\2\2or\5\n\6\2pr\5\16\b\2qo\3\2\2\2qp\3\2\2\2r\u00b0\3\2\2\2st\7"+ + "\21\2\2tu\5\f\7\2uv\7\20\2\2vw\7\t\2\2wx\5\36\20\2xy\7\n\2\2yz\5\34\17"+ + "\2z\u00b0\3\2\2\2{|\7\22\2\2|~\7\t\2\2}\177\5\20\t\2~}\3\2\2\2~\177\3"+ + "\2\2\2\177\u0080\3\2\2\2\u0080\u0082\7\r\2\2\u0081\u0083\5\36\20\2\u0082"+ + "\u0081\3\2\2\2\u0082\u0083\3\2\2\2\u0083\u0084\3\2\2\2\u0084\u0086\7\r"+ + "\2\2\u0085\u0087\5\22\n\2\u0086\u0085\3\2\2\2\u0086\u0087\3\2\2\2\u0087"+ + "\u0088\3\2\2\2\u0088\u008b\7\n\2\2\u0089\u008c\5\n\6\2\u008a\u008c\5\16"+ + "\b\2\u008b\u0089\3\2\2\2\u008b\u008a\3\2\2\2\u008c\u00b0\3\2\2\2\u008d"+ + "\u008e\7\22\2\2\u008e\u008f\7\t\2\2\u008f\u0090\5\26\f\2\u0090\u0091\7"+ + "P\2\2\u0091\u0092\7\63\2\2\u0092\u0093\5\36\20\2\u0093\u0094\7\n\2\2\u0094"+ + "\u0095\5\n\6\2\u0095\u00b0\3\2\2\2\u0096\u0097\5\24\13\2\u0097\u0098\5"+ + "\34\17\2\u0098\u00b0\3\2\2\2\u0099\u009a\7\23\2\2\u009a\u00b0\5\34\17"+ + "\2\u009b\u009c\7\24\2\2\u009c\u00b0\5\34\17\2\u009d\u009e\7\25\2\2\u009e"+ + "\u009f\5\36\20\2\u009f\u00a0\5\34\17\2\u00a0\u00b0\3\2\2\2\u00a1\u00a2"+ + "\7\27\2\2\u00a2\u00a4\5\f\7\2\u00a3\u00a5\5\32\16\2\u00a4\u00a3\3\2\2"+ + "\2\u00a5\u00a6\3\2\2\2\u00a6\u00a4\3\2\2\2\u00a6\u00a7\3\2\2\2\u00a7\u00b0"+ + "\3\2\2\2\u00a8\u00a9\7\31\2\2\u00a9\u00aa\5\36\20\2\u00aa\u00ab\5\34\17"+ + "\2\u00ab\u00b0\3\2\2\2\u00ac\u00ad\5\36\20\2\u00ad\u00ae\5\34\17\2\u00ae"+ + "\u00b0\3\2\2\2\u00afa\3\2\2\2\u00afk\3\2\2\2\u00afs\3\2\2\2\u00af{\3\2"+ + "\2\2\u00af\u008d\3\2\2\2\u00af\u0096\3\2\2\2\u00af\u0099\3\2\2\2\u00af"+ + "\u009b\3\2\2\2\u00af\u009d\3\2\2\2\u00af\u00a1\3\2\2\2\u00af\u00a8\3\2"+ + "\2\2\u00af\u00ac\3\2\2\2\u00b0\t\3\2\2\2\u00b1\u00b4\5\f\7\2\u00b2\u00b4"+ + "\5\b\5\2\u00b3\u00b1\3\2\2\2\u00b3\u00b2\3\2\2\2\u00b4\13\3\2\2\2\u00b5"+ + "\u00b9\7\5\2\2\u00b6\u00b8\5\b\5\2\u00b7\u00b6\3\2\2\2\u00b8\u00bb\3\2"+ + "\2\2\u00b9\u00b7\3\2\2\2\u00b9\u00ba\3\2\2\2\u00ba\u00bc\3\2\2\2\u00bb"+ + "\u00b9\3\2\2\2\u00bc\u00bd\7\6\2\2\u00bd\r\3\2\2\2\u00be\u00bf\7\r\2\2"+ + "\u00bf\17\3\2\2\2\u00c0\u00c3\5\24\13\2\u00c1\u00c3\5\36\20\2\u00c2\u00c0"+ + "\3\2\2\2\u00c2\u00c1\3\2\2\2\u00c3\21\3\2\2\2\u00c4\u00c5\5\36\20\2\u00c5"+ + "\23\3\2\2\2\u00c6\u00c7\5\26\f\2\u00c7\u00cc\5\30\r\2\u00c8\u00c9\7\f"+ + "\2\2\u00c9\u00cb\5\30\r\2\u00ca\u00c8\3\2\2\2\u00cb\u00ce\3\2\2\2\u00cc"+ + "\u00ca\3\2\2\2\u00cc\u00cd\3\2\2\2\u00cd\25\3\2\2\2\u00ce\u00cc\3\2\2"+ + "\2\u00cf\u00d4\7O\2\2\u00d0\u00d1\7\7\2\2\u00d1\u00d3\7\b\2\2\u00d2\u00d0"+ + "\3\2\2\2\u00d3\u00d6\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d4\u00d5\3\2\2\2\u00d5"+ + "\27\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d7\u00da\7P\2\2\u00d8\u00d9\7:\2\2"+ + "\u00d9\u00db\5\36\20\2\u00da\u00d8\3\2\2\2\u00da\u00db\3\2\2\2\u00db\31"+ + "\3\2\2\2\u00dc\u00dd\7\30\2\2\u00dd\u00de\7\t\2\2\u00de\u00df\7O\2\2\u00df"+ + "\u00e0\7P\2\2\u00e0\u00e1\7\n\2\2\u00e1\u00e2\5\f\7\2\u00e2\33\3\2\2\2"+ + "\u00e3\u00e9\7\r\2\2\u00e4\u00e9\7\2\2\3\u00e5\u00e6\b\17\1\2\u00e6\u00e7"+ + "\7\6\2\2\u00e7\u00e9\b\17\1\2\u00e8\u00e3\3\2\2\2\u00e8\u00e4\3\2\2\2"+ + "\u00e8\u00e5\3\2\2\2\u00e9\35\3\2\2\2\u00ea\u00eb\b\20\1\2\u00eb\u00ec"+ + "\5\"\22\2\u00ec\u00ed\t\2\2\2\u00ed\u00ee\5\36\20\3\u00ee\u00ef\b\20\1"+ + "\2\u00ef\u00f4\3\2\2\2\u00f0\u00f1\5 \21\2\u00f1\u00f2\b\20\1\2\u00f2"+ + "\u00f4\3\2\2\2\u00f3\u00ea\3\2\2\2\u00f3\u00f0\3\2\2\2\u00f4\u0135\3\2"+ + "\2\2\u00f5\u00f6\f\17\2\2\u00f6\u00f7\t\3\2\2\u00f7\u00f8\5\36\20\20\u00f8"+ + "\u00f9\b\20\1\2\u00f9\u0134\3\2\2\2\u00fa\u00fb\f\16\2\2\u00fb\u00fc\t"+ + "\4\2\2\u00fc\u00fd\5\36\20\17\u00fd\u00fe\b\20\1\2\u00fe\u0134\3\2\2\2"+ + "\u00ff\u0100\f\r\2\2\u0100\u0101\t\5\2\2\u0101\u0102\5\36\20\16\u0102"+ + "\u0103\b\20\1\2\u0103\u0134\3\2\2\2\u0104\u0105\f\f\2\2\u0105\u0106\t"+ + "\6\2\2\u0106\u0107\5\36\20\r\u0107\u0108\b\20\1\2\u0108\u0134\3\2\2\2"+ + "\u0109\u010a\f\13\2\2\u010a\u010b\t\7\2\2\u010b\u010c\5\36\20\f\u010c"+ + "\u010d\b\20\1\2\u010d\u0134\3\2\2\2\u010e\u010f\f\n\2\2\u010f\u0110\t"+ + "\b\2\2\u0110\u0111\5\36\20\13\u0111\u0112\b\20\1\2\u0112\u0134\3\2\2\2"+ + "\u0113\u0114\f\t\2\2\u0114\u0115\7-\2\2\u0115\u0116\5\36\20\n\u0116\u0117"+ + "\b\20\1\2\u0117\u0134\3\2\2\2\u0118\u0119\f\b\2\2\u0119\u011a\7.\2\2\u011a"+ + "\u011b\5\36\20\t\u011b\u011c\b\20\1\2\u011c\u0134\3\2\2\2\u011d\u011e"+ + "\f\7\2\2\u011e\u011f\7/\2\2\u011f\u0120\5\36\20\b\u0120\u0121\b\20\1\2"+ + "\u0121\u0134\3\2\2\2\u0122\u0123\f\6\2\2\u0123\u0124\7\60\2\2\u0124\u0125"+ + "\5\36\20\7\u0125\u0126\b\20\1\2\u0126\u0134\3\2\2\2\u0127\u0128\f\5\2"+ + "\2\u0128\u0129\7\61\2\2\u0129\u012a\5\36\20\6\u012a\u012b\b\20\1\2\u012b"+ + "\u0134\3\2\2\2\u012c\u012d\f\4\2\2\u012d\u012e\7\62\2\2\u012e\u012f\5"+ + "\36\20\2\u012f\u0130\7\63\2\2\u0130\u0131\5\36\20\4\u0131\u0132\b\20\1"+ + "\2\u0132\u0134\3\2\2\2\u0133\u00f5\3\2\2\2\u0133\u00fa\3\2\2\2\u0133\u00ff"+ + "\3\2\2\2\u0133\u0104\3\2\2\2\u0133\u0109\3\2\2\2\u0133\u010e\3\2\2\2\u0133"+ + "\u0113\3\2\2\2\u0133\u0118\3\2\2\2\u0133\u011d\3\2\2\2\u0133\u0122\3\2"+ + "\2\2\u0133\u0127\3\2\2\2\u0133\u012c\3\2\2\2\u0134\u0137\3\2\2\2\u0135"+ + "\u0133\3\2\2\2\u0135\u0136\3\2\2\2\u0136\37\3\2\2\2\u0137\u0135\3\2\2"+ + "\2\u0138\u0139\6\21\17\3\u0139\u013a\t\t\2\2\u013a\u0156\5\"\22\2\u013b"+ + "\u013c\6\21\20\3\u013c\u013d\5\"\22\2\u013d\u013e\t\t\2\2\u013e\u0156"+ + "\3\2\2\2\u013f\u0140\6\21\21\3\u0140\u0156\5\"\22\2\u0141\u0142\6\21\22"+ + "\3\u0142\u0143\t\n\2\2\u0143\u0156\b\21\1\2\u0144\u0145\6\21\23\3\u0145"+ + "\u0146\7L\2\2\u0146\u0156\b\21\1\2\u0147\u0148\6\21\24\3\u0148\u0149\7"+ + "M\2\2\u0149\u0156\b\21\1\2\u014a\u014b\6\21\25\3\u014b\u014c\7N\2\2\u014c"+ + "\u0156\b\21\1\2\u014d\u014e\6\21\26\3\u014e\u014f\t\13\2\2\u014f\u0156"+ + "\5 \21\2\u0150\u0151\7\t\2\2\u0151\u0152\5\26\f\2\u0152\u0153\7\n\2\2"+ + "\u0153\u0154\5 \21\2\u0154\u0156\3\2\2\2\u0155\u0138\3\2\2\2\u0155\u013b"+ + "\3\2\2\2\u0155\u013f\3\2\2\2\u0155\u0141\3\2\2\2\u0155\u0144\3\2\2\2\u0155"+ + "\u0147\3\2\2\2\u0155\u014a\3\2\2\2\u0155\u014d\3\2\2\2\u0155\u0150\3\2"+ + "\2\2\u0156!\3\2\2\2\u0157\u015b\5$\23\2\u0158\u015a\5&\24\2\u0159\u0158"+ + "\3\2\2\2\u015a\u015d\3\2\2\2\u015b\u0159\3\2\2\2\u015b\u015c\3\2\2\2\u015c"+ + "\u017a\3\2\2\2\u015d\u015b\3\2\2\2\u015e\u015f\5\26\f\2\u015f\u0163\5"+ + "(\25\2\u0160\u0162\5&\24\2\u0161\u0160\3\2\2\2\u0162\u0165\3\2\2\2\u0163"+ + "\u0161\3\2\2\2\u0163\u0164\3\2\2\2\u0164\u017a\3\2\2\2\u0165\u0163\3\2"+ + "\2\2\u0166\u0167\7\26\2\2\u0167\u016c\7O\2\2\u0168\u0169\7\7\2\2\u0169"+ + "\u016a\5\36\20\2\u016a\u016b\7\b\2\2\u016b\u016d\3\2\2\2\u016c\u0168\3"+ + "\2\2\2\u016d\u016e\3\2\2\2\u016e\u016c\3\2\2\2\u016e\u016f\3\2\2\2\u016f"+ + "\u0177\3\2\2\2\u0170\u0174\5(\25\2\u0171\u0173\5&\24\2\u0172\u0171\3\2"+ + "\2\2\u0173\u0176\3\2\2\2\u0174\u0172\3\2\2\2\u0174\u0175\3\2\2\2\u0175"+ + "\u0178\3\2\2\2\u0176\u0174\3\2\2\2\u0177\u0170\3\2\2\2\u0177\u0178\3\2"+ + "\2\2\u0178\u017a\3\2\2\2\u0179\u0157\3\2\2\2\u0179\u015e\3\2\2\2\u0179"+ + "\u0166\3\2\2\2\u017a#\3\2\2\2\u017b\u017c\6\23\27\3\u017c\u017d\7\t\2"+ + "\2\u017d\u017e\5\36\20\2\u017e\u017f\7\n\2\2\u017f\u0180\b\23\1\2\u0180"+ + "\u018f\3\2\2\2\u0181\u0182\6\23\30\3\u0182\u0183\7\t\2\2\u0183\u0184\5"+ + " \21\2\u0184\u0185\7\n\2\2\u0185\u018f\3\2\2\2\u0186\u018f\7J\2\2\u0187"+ + "\u018f\7K\2\2\u0188\u018f\7P\2\2\u0189\u018a\7P\2\2\u018a\u018f\5,\27"+ + "\2\u018b\u018c\7\26\2\2\u018c\u018d\7O\2\2\u018d\u018f\5,\27\2\u018e\u017b"+ + "\3\2\2\2\u018e\u0181\3\2\2\2\u018e\u0186\3\2\2\2\u018e\u0187\3\2\2\2\u018e"+ + "\u0188\3\2\2\2\u018e\u0189\3\2\2\2\u018e\u018b\3\2\2\2\u018f%\3\2\2\2"+ + "\u0190\u0191\6\24\31\3\u0191\u0195\5(\25\2\u0192\u0193\6\24\32\3\u0193"+ + "\u0195\5*\26\2\u0194\u0190\3\2\2\2\u0194\u0192\3\2\2\2\u0195\'\3\2\2\2"+ + "\u0196\u0197\7\13\2\2\u0197\u0198\7R\2\2\u0198\u019c\5,\27\2\u0199\u019a"+ + "\7\13\2\2\u019a\u019c\t\f\2\2\u019b\u0196\3\2\2\2\u019b\u0199\3\2\2\2"+ + "\u019c)\3\2\2\2\u019d\u019e\7\7\2\2\u019e\u019f\5\36\20\2\u019f\u01a0"+ + "\7\b\2\2\u01a0+\3\2\2\2\u01a1\u01aa\7\t\2\2\u01a2\u01a7\5.\30\2\u01a3"+ + "\u01a4\7\f\2\2\u01a4\u01a6\5.\30\2\u01a5\u01a3\3\2\2\2\u01a6\u01a9\3\2"+ + "\2\2\u01a7\u01a5\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01ab\3\2\2\2\u01a9"+ + "\u01a7\3\2\2\2\u01aa\u01a2\3\2\2\2\u01aa\u01ab\3\2\2\2\u01ab\u01ac\3\2"+ + "\2\2\u01ac\u01ad\7\n\2\2\u01ad-\3\2\2\2\u01ae\u01b2\5\36\20\2\u01af\u01b2"+ + "\5\60\31\2\u01b0\u01b2\5\64\33\2\u01b1\u01ae\3\2\2\2\u01b1\u01af\3\2\2"+ + "\2\u01b1\u01b0\3\2\2\2\u01b2/\3\2\2\2\u01b3\u01c1\5\62\32\2\u01b4\u01bd"+ + "\7\t\2\2\u01b5\u01ba\5\62\32\2\u01b6\u01b7\7\f\2\2\u01b7\u01b9\5\62\32"+ + "\2\u01b8\u01b6\3\2\2\2\u01b9\u01bc\3\2\2\2\u01ba\u01b8\3\2\2\2\u01ba\u01bb"+ + "\3\2\2\2\u01bb\u01be\3\2\2\2\u01bc\u01ba\3\2\2\2\u01bd\u01b5\3\2\2\2\u01bd"+ + "\u01be\3\2\2\2\u01be\u01bf\3\2\2\2\u01bf\u01c1\7\n\2\2\u01c0\u01b3\3\2"+ + "\2\2\u01c0\u01b4\3\2\2\2\u01c1\u01c2\3\2\2\2\u01c2\u01c5\7\65\2\2\u01c3"+ + "\u01c6\5\f\7\2\u01c4\u01c6\5\36\20\2\u01c5\u01c3\3\2\2\2\u01c5\u01c4\3"+ + "\2\2\2\u01c6\61\3\2\2\2\u01c7\u01c9\5\26\f\2\u01c8\u01c7\3\2\2\2\u01c8"+ + "\u01c9\3\2\2\2\u01c9\u01ca\3\2\2\2\u01ca\u01cb\7P\2\2\u01cb\63\3\2\2\2"+ + "\u01cc\u01d1\5\66\34\2\u01cd\u01d1\58\35\2\u01ce\u01d1\5:\36\2\u01cf\u01d1"+ + "\5<\37\2\u01d0\u01cc\3\2\2\2\u01d0\u01cd\3\2\2\2\u01d0\u01ce\3\2\2\2\u01d0"+ + "\u01cf\3\2\2\2\u01d1\65\3\2\2\2\u01d2\u01d3\7O\2\2\u01d3\u01d4\7\64\2"+ + "\2\u01d4\u01d5\7P\2\2\u01d5\67\3\2\2\2\u01d6\u01d7\5\26\f\2\u01d7\u01d8"+ + "\7\64\2\2\u01d8\u01d9\7\26\2\2\u01d99\3\2\2\2\u01da\u01db\7P\2\2\u01db"+ + "\u01dc\7\64\2\2\u01dc\u01dd\7P\2\2\u01dd;\3\2\2\2\u01de\u01df\7\32\2\2"+ + "\u01df\u01e0\7\64\2\2\u01e0\u01e1\7P\2\2\u01e1=\3\2\2\2+AGZ]iq~\u0082"+ "\u0086\u008b\u00a6\u00af\u00b3\u00b9\u00c2\u00cc\u00d4\u00da\u00e8\u00f3"+ "\u0133\u0135\u0155\u015b\u0163\u016e\u0174\u0177\u0179\u018e\u0194\u019b"+ - "\u01a7\u01aa\u01b1\u01ba\u01bd\u01c0\u01c6\u01ce"; + "\u01a7\u01aa\u01b1\u01ba\u01bd\u01c0\u01c5\u01c8\u01d0"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java index f57e3aef049..b1a5ed3a260 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java @@ -959,8 +959,14 @@ public final class Walker extends PainlessParserBaseVisitor { paramNames.add(lamtype.ID().getText()); } - for (StatementContext statement : ctx.block().statement()) { - statements.add((AStatement)visit(statement)); + if (ctx.expression() != null) { + // single expression + AExpression expression = (AExpression) visitExpression(ctx.expression()); + statements.add(new SReturn(location(ctx), expression)); + } else { + for (StatementContext statement : ctx.block().statement()) { + statements.add((AStatement)visit(statement)); + } } String name = nextLambda(); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/LambdaTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/LambdaTests.java index 1e7eb78be73..9db0e5c93ae 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/LambdaTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/LambdaTests.java @@ -22,59 +22,63 @@ package org.elasticsearch.painless; public class LambdaTests extends ScriptTestCase { public void testNoArgLambda() { - assertEquals(1, exec("Optional.empty().orElseGet(() -> { return 1; });")); + assertEquals(1, exec("Optional.empty().orElseGet(() -> 1);")); } public void testNoArgLambdaDef() { - assertEquals(1, exec("def x = Optional.empty(); x.orElseGet(() -> { return 1; });")); + assertEquals(1, exec("def x = Optional.empty(); x.orElseGet(() -> 1);")); } public void testLambdaWithArgs() { assertEquals("short", exec("List l = new ArrayList(); l.add('looooong'); l.add('short'); " - + "l.sort((a, b) -> { a.length() - b.length(); }); return l.get(0)")); + + "l.sort((a, b) -> a.length() - b.length()); return l.get(0)")); } public void testLambdaWithTypedArgs() { assertEquals("short", exec("List l = new ArrayList(); l.add('looooong'); l.add('short'); " - + "l.sort((String a, String b) -> { (a.length() - b.length()); }); return l.get(0)")); + + "l.sort((String a, String b) -> a.length() - b.length()); return l.get(0)")); } public void testPrimitiveLambdas() { assertEquals(4, exec("List l = new ArrayList(); l.add(1); l.add(1); " - + "return l.stream().mapToInt(x -> { x + 1; }).sum();")); + + "return l.stream().mapToInt(x -> x + 1).sum();")); } public void testPrimitiveLambdasWithTypedArgs() { assertEquals(4, exec("List l = new ArrayList(); l.add(1); l.add(1); " - + "return l.stream().mapToInt(int x -> { x + 1; }).sum();")); + + "return l.stream().mapToInt(int x -> x + 1).sum();")); } public void testPrimitiveLambdasDef() { assertEquals(4, exec("def l = new ArrayList(); l.add(1); l.add(1); " - + "return l.stream().mapToInt(x -> { x + 1; }).sum();")); + + "return l.stream().mapToInt(x -> x + 1).sum();")); } public void testPrimitiveLambdasWithTypedArgsDef() { assertEquals(4, exec("def l = new ArrayList(); l.add(1); l.add(1); " - + "return l.stream().mapToInt(int x -> { x + 1; }).sum();")); + + "return l.stream().mapToInt(int x -> x + 1).sum();")); } public void testPrimitiveLambdasConvertible() { assertEquals(2, exec("List l = new ArrayList(); l.add(1); l.add(1); " - + "return l.stream().mapToInt(byte x -> { return x; }).sum();")); + + "return l.stream().mapToInt(byte x -> x).sum();")); } public void testPrimitiveArgs() { - assertEquals(2, exec("int applyOne(IntFunction arg) { arg.apply(1) } applyOne(x -> { x + 1; })")); + assertEquals(2, exec("int applyOne(IntFunction arg) { arg.apply(1) } applyOne(x -> x + 1)")); } public void testPrimitiveArgsTyped() { - assertEquals(2, exec("int applyOne(IntFunction arg) { arg.apply(1) } applyOne(int x -> { x + 1; })")); + assertEquals(2, exec("int applyOne(IntFunction arg) { arg.apply(1) } applyOne(int x -> x + 1)")); } public void testPrimitiveArgsTypedOddly() { - assertEquals(2L, exec("long applyOne(IntFunction arg) { arg.apply(1) } applyOne(long x -> { x + 1; })")); + assertEquals(2L, exec("long applyOne(IntFunction arg) { arg.apply(1) } applyOne(long x -> x + 1)")); + } + + public void testMultipleStatements() { + assertEquals(2, exec("int applyOne(IntFunction arg) { arg.apply(1) } applyOne(x -> { x = x + 1; return x;})")); } } From 251001e435c8d693f8835423f7f985c0bec4f462 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 16 Jun 2016 12:40:30 -0400 Subject: [PATCH 2/4] add more simple tests --- .../elasticsearch/painless/LambdaTests.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/LambdaTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/LambdaTests.java index 9db0e5c93ae..5001e28a954 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/LambdaTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/LambdaTests.java @@ -81,4 +81,22 @@ public class LambdaTests extends ScriptTestCase { public void testMultipleStatements() { assertEquals(2, exec("int applyOne(IntFunction arg) { arg.apply(1) } applyOne(x -> { x = x + 1; return x;})")); } + + public void testTwoLambdas() { + assertEquals("testingcdefg", exec( + "org.elasticsearch.painless.FeatureTest test = new org.elasticsearch.painless.FeatureTest(2,3);" + + "return test.twoFunctionsOfX(x -> 'testing'.concat(x), y -> 'abcdefg'.substring(y))")); + } + + public void testNestedLambdas() { + assertEquals(1, exec("Optional.empty().orElseGet(() -> Optional.empty().orElseGet(() -> 1));")); + } + + public void testLambdaInLoop() { + assertEquals(100, exec("int sum = 0; " + + "for (int i = 0; i < 100; i++) {" + + " sum += Optional.empty().orElseGet(() -> 1);" + + "}" + + "return sum;")); + } } From b665d8a18752aa3000c1a451472f5dec040eedcf Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Thu, 16 Jun 2016 11:07:09 -0400 Subject: [PATCH 3/4] Painless: Add flag support to regexes Painless: Add support for //m Painless: Add support for //s Painless: Add support for //i Painless: Add support for //u Painless: Add support for //U Painless: Add support for //l This means "literal" and is exposed for completeness sake with the java api. Painless: Add support for //c c enables Java's CANON_EQ (canonical equivalence) flag which makes unicode characters that are canonically equal match. Java's javadoc gives "a\u030A" being equal to "\u00E5". That is that the "a" code point followed by the "combining ring above" code point is equal to the "a with combining ring above" code point. Update docs and add multi-flag test Whitelist most of the Pattern class. --- .../modules/scripting/painless.asciidoc | 30 +- .../src/main/antlr/PainlessLexer.g4 | 2 +- .../painless/WriterConstants.java | 2 +- .../painless/antlr/PainlessLexer.java | 333 +++++++++--------- .../elasticsearch/painless/antlr/Walker.java | 7 +- .../elasticsearch/painless/node/LRegex.java | 25 +- .../painless/java.util.regex.txt | 7 + .../elasticsearch/painless/RegexTests.java | 57 +++ 8 files changed, 289 insertions(+), 174 deletions(-) diff --git a/docs/reference/modules/scripting/painless.asciidoc b/docs/reference/modules/scripting/painless.asciidoc index cb28e735e5c..20b301bda31 100644 --- a/docs/reference/modules/scripting/painless.asciidoc +++ b/docs/reference/modules/scripting/painless.asciidoc @@ -202,12 +202,15 @@ POST hockey/player/1/_update // CONSOLE [float] +[[modules-scripting-painless-regex]] === Regular expressions Painless's native support for regular expressions has syntax constructs: * `/pattern/`: Pattern literals create patterns. This is the only way to create -a pattern in painless. +a pattern in painless. The pattern inside the `/`s are just +http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html[Java regular expressions]. +See <> for more. * `=~`: The find operator return a `boolean`, `true` if a subsequence of the text matches, `false` otherwise. * `==~`: The match operator returns a `boolean`, `true` if the text matches, @@ -265,14 +268,35 @@ Note: all of the `_update_by_query` examples above could really do with a because script queries aren't able to use the inverted index to limit the documents that they have to check. -The pattern syntax is just -http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html[Java regular expressions]. We intentionally don't allow scripts to call `Pattern.compile` to get a new pattern on the fly because building a `Pattern` is (comparatively) slow. Pattern literals (`/apattern/`) have fancy constant extraction so no matter where they show up in the painless script they are built only when the script is first used. It is fairly similar to how `String` literals work in Java. +[float] +[[modules-scripting-painless-regex-flags]] +==== Regular expression flags + +You can define flags on patterns in Painless by adding characters after the +trailing `/` like `/foo/i` or `/foo \w #comment/iUx`. Painless exposes all the +flags from +https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html[Java's Pattern class] +using these characters: + +[cols="<,<,<",options="header",] +|======================================================================= +| Character | Java Constant | Example +|`c` | CANON_EQ | `'å' ==~ /å/c` (open in hex editor to see) +|`i` | CASE_INSENSITIVE | `'A' ==~ /a/i` +|`l` | LITERAL | `'[a]' ==~ /[a]/l` +|`m` | MULTILINE | `'a\nb\nc' =~ /^b$/m` +|`s` | DOTALL (aka single line) | `'a\nb\nc' =~ /.b./s` +|`U` | UNICODE_CHARACTER_CLASS | `'Ɛ' ==~ /\\w/U` +|`u` | UNICODE_CASE | `'Ɛ' ==~ /ɛ/iu` +|`x` | COMMENTS (aka extended) | `'a' ==~ /a #comment/x` +|======================================================================= + [[painless-api]] [float] diff --git a/modules/lang-painless/src/main/antlr/PainlessLexer.g4 b/modules/lang-painless/src/main/antlr/PainlessLexer.g4 index a31c50ee198..62a154db40c 100644 --- a/modules/lang-painless/src/main/antlr/PainlessLexer.g4 +++ b/modules/lang-painless/src/main/antlr/PainlessLexer.g4 @@ -104,7 +104,7 @@ INTEGER: ( '0' | [1-9] [0-9]* ) [lLfFdD]?; DECIMAL: ( '0' | [1-9] [0-9]* ) (DOT [0-9]+)? ( [eE] [+\-]? [0-9]+ )? [fF]?; STRING: ( '"' ( '\\"' | '\\\\' | ~[\\"] )*? '"' ) | ( '\'' ( '\\\'' | '\\\\' | ~[\\"] )*? '\'' ); -REGEX: '/' ( ~('/' | '\n') | '\\' ~'\n' )+ '/' { SlashStrategy.slashIsRegex(_factory) }?; +REGEX: '/' ( ~('/' | '\n') | '\\' ~'\n' )+ '/' [cilmsUux]* { SlashStrategy.slashIsRegex(_factory) }?; TRUE: 'true'; FALSE: 'false'; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java index d798bb5ca68..6960e906339 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java @@ -79,7 +79,7 @@ public final class WriterConstants { * because it can do it statically. This is both faster and prevents the script from doing something super slow like building a regex * per time it is run. */ - public final static Method PATTERN_COMPILE = getAsmMethod(Pattern.class, "compile", String.class); + public final static Method PATTERN_COMPILE = getAsmMethod(Pattern.class, "compile", String.class, int.class); public final static Method PATTERN_MATCHER = getAsmMethod(Matcher.class, "matcher", CharSequence.class); public final static Method MATCHER_MATCHES = getAsmMethod(boolean.class, "matches"); public final static Method MATCHER_FIND = getAsmMethod(boolean.class, "find"); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java index 040d17c521b..cf0ac8605f0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java @@ -160,7 +160,7 @@ class PainlessLexer extends Lexer { } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2R\u0233\b\1\b\1\4"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2R\u0239\b\1\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"+ @@ -191,171 +191,174 @@ class PainlessLexer extends Lexer { "\5H\u01c8\nH\3H\3H\5H\u01cc\nH\3H\6H\u01cf\nH\rH\16H\u01d0\5H\u01d3\n"+ "H\3H\5H\u01d6\nH\3I\3I\3I\3I\3I\3I\7I\u01de\nI\fI\16I\u01e1\13I\3I\3I"+ "\3I\3I\3I\3I\3I\7I\u01ea\nI\fI\16I\u01ed\13I\3I\5I\u01f0\nI\3J\3J\3J\3"+ - "J\6J\u01f6\nJ\rJ\16J\u01f7\3J\3J\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3"+ - "M\3M\3M\3M\3M\3N\3N\3N\3N\7N\u0211\nN\fN\16N\u0214\13N\3N\3N\3O\3O\7O"+ - "\u021a\nO\fO\16O\u021d\13O\3P\3P\3P\7P\u0222\nP\fP\16P\u0225\13P\5P\u0227"+ - "\nP\3P\3P\3Q\3Q\7Q\u022d\nQ\fQ\16Q\u0230\13Q\3Q\3Q\6\u00b1\u00bb\u01df"+ - "\u01eb\2R\4\3\6\4\b\5\n\6\f\7\16\b\20\t\22\n\24\13\26\f\30\r\32\16\34"+ - "\17\36\20 \21\"\22$\23&\24(\25*\26,\27.\30\60\31\62\32\64\33\66\348\35"+ - ":\36<\37> @!B\"D#F$H%J&L\'N(P)R*T+V,X-Z.\\/^\60`\61b\62d\63f\64h\65j\66"+ - "l\67n8p9r:t;v|?~@\u0080A\u0082B\u0084C\u0086D\u0088E\u008aF\u008c"+ - "G\u008eH\u0090I\u0092J\u0094K\u0096L\u0098M\u009aN\u009cO\u009eP\u00a0"+ - "Q\u00a2R\4\2\3\23\5\2\13\f\17\17\"\"\4\2\f\f\17\17\3\2\629\4\2NNnn\4\2"+ - "ZZzz\5\2\62;CHch\3\2\63;\3\2\62;\b\2FFHHNNffhhnn\4\2GGgg\4\2--//\4\2H"+ - "Hhh\4\2$$^^\4\2\f\f\61\61\3\2\f\f\5\2C\\aac|\6\2\62;C\\aac|\u0252\2\4"+ - "\3\2\2\2\2\6\3\2\2\2\2\b\3\2\2\2\2\n\3\2\2\2\2\f\3\2\2\2\2\16\3\2\2\2"+ - "\2\20\3\2\2\2\2\22\3\2\2\2\2\24\3\2\2\2\2\26\3\2\2\2\2\30\3\2\2\2\2\32"+ - "\3\2\2\2\2\34\3\2\2\2\2\36\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\60\3\2\2\2\2\62"+ - "\3\2\2\2\2\64\3\2\2\2\2\66\3\2\2\2\28\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2"+ - ">\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2J\3"+ - "\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2\2\2\2V\3\2\2"+ - "\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2\2\2b\3\2\2\2"+ - "\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2n\3\2\2\2\2p"+ - "\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3\2\2\2\2|\3\2"+ - "\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3\2\2\2\2\u0086"+ - "\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2\2\u008e\3\2\2"+ - "\2\2\u0090\3\2\2\2\2\u0092\3\2\2\2\2\u0094\3\2\2\2\2\u0096\3\2\2\2\2\u0098"+ - "\3\2\2\2\2\u009a\3\2\2\2\2\u009c\3\2\2\2\2\u009e\3\2\2\2\3\u00a0\3\2\2"+ - "\2\3\u00a2\3\2\2\2\4\u00a5\3\2\2\2\6\u00c0\3\2\2\2\b\u00c4\3\2\2\2\n\u00c6"+ - "\3\2\2\2\f\u00c8\3\2\2\2\16\u00ca\3\2\2\2\20\u00cc\3\2\2\2\22\u00ce\3"+ - "\2\2\2\24\u00d0\3\2\2\2\26\u00d4\3\2\2\2\30\u00d6\3\2\2\2\32\u00d8\3\2"+ - "\2\2\34\u00db\3\2\2\2\36\u00e0\3\2\2\2 \u00e6\3\2\2\2\"\u00e9\3\2\2\2"+ - "$\u00ed\3\2\2\2&\u00f6\3\2\2\2(\u00fc\3\2\2\2*\u0103\3\2\2\2,\u0107\3"+ - "\2\2\2.\u010b\3\2\2\2\60\u0111\3\2\2\2\62\u0117\3\2\2\2\64\u011c\3\2\2"+ - "\2\66\u011e\3\2\2\28\u0120\3\2\2\2:\u0122\3\2\2\2<\u0125\3\2\2\2>\u0127"+ - "\3\2\2\2@\u0129\3\2\2\2B\u012b\3\2\2\2D\u012e\3\2\2\2F\u0131\3\2\2\2H"+ - "\u0135\3\2\2\2J\u0137\3\2\2\2L\u013a\3\2\2\2N\u013c\3\2\2\2P\u013f\3\2"+ - "\2\2R\u0142\3\2\2\2T\u0146\3\2\2\2V\u0149\3\2\2\2X\u014d\3\2\2\2Z\u014f"+ - "\3\2\2\2\\\u0151\3\2\2\2^\u0153\3\2\2\2`\u0156\3\2\2\2b\u0159\3\2\2\2"+ - "d\u015b\3\2\2\2f\u015d\3\2\2\2h\u0160\3\2\2\2j\u0163\3\2\2\2l\u0166\3"+ - "\2\2\2n\u016a\3\2\2\2p\u016d\3\2\2\2r\u0170\3\2\2\2t\u0172\3\2\2\2v\u0175"+ - "\3\2\2\2x\u0178\3\2\2\2z\u017b\3\2\2\2|\u017e\3\2\2\2~\u0181\3\2\2\2\u0080"+ - "\u0184\3\2\2\2\u0082\u0187\3\2\2\2\u0084\u018a\3\2\2\2\u0086\u018e\3\2"+ - "\2\2\u0088\u0192\3\2\2\2\u008a\u0197\3\2\2\2\u008c\u01a0\3\2\2\2\u008e"+ - "\u01b2\3\2\2\2\u0090\u01bf\3\2\2\2\u0092\u01ef\3\2\2\2\u0094\u01f1\3\2"+ - "\2\2\u0096\u01fc\3\2\2\2\u0098\u0201\3\2\2\2\u009a\u0207\3\2\2\2\u009c"+ - "\u020c\3\2\2\2\u009e\u0217\3\2\2\2\u00a0\u0226\3\2\2\2\u00a2\u022a\3\2"+ - "\2\2\u00a4\u00a6\t\2\2\2\u00a5\u00a4\3\2\2\2\u00a6\u00a7\3\2\2\2\u00a7"+ - "\u00a5\3\2\2\2\u00a7\u00a8\3\2\2\2\u00a8\u00a9\3\2\2\2\u00a9\u00aa\b\2"+ - "\2\2\u00aa\5\3\2\2\2\u00ab\u00ac\7\61\2\2\u00ac\u00ad\7\61\2\2\u00ad\u00b1"+ - "\3\2\2\2\u00ae\u00b0\13\2\2\2\u00af\u00ae\3\2\2\2\u00b0\u00b3\3\2\2\2"+ - "\u00b1\u00b2\3\2\2\2\u00b1\u00af\3\2\2\2\u00b2\u00b4\3\2\2\2\u00b3\u00b1"+ - "\3\2\2\2\u00b4\u00c1\t\3\2\2\u00b5\u00b6\7\61\2\2\u00b6\u00b7\7,\2\2\u00b7"+ - "\u00bb\3\2\2\2\u00b8\u00ba\13\2\2\2\u00b9\u00b8\3\2\2\2\u00ba\u00bd\3"+ - "\2\2\2\u00bb\u00bc\3\2\2\2\u00bb\u00b9\3\2\2\2\u00bc\u00be\3\2\2\2\u00bd"+ - "\u00bb\3\2\2\2\u00be\u00bf\7,\2\2\u00bf\u00c1\7\61\2\2\u00c0\u00ab\3\2"+ - "\2\2\u00c0\u00b5\3\2\2\2\u00c1\u00c2\3\2\2\2\u00c2\u00c3\b\3\2\2\u00c3"+ - "\7\3\2\2\2\u00c4\u00c5\7}\2\2\u00c5\t\3\2\2\2\u00c6\u00c7\7\177\2\2\u00c7"+ - "\13\3\2\2\2\u00c8\u00c9\7]\2\2\u00c9\r\3\2\2\2\u00ca\u00cb\7_\2\2\u00cb"+ - "\17\3\2\2\2\u00cc\u00cd\7*\2\2\u00cd\21\3\2\2\2\u00ce\u00cf\7+\2\2\u00cf"+ - "\23\3\2\2\2\u00d0\u00d1\7\60\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00d3\b\n\3"+ - "\2\u00d3\25\3\2\2\2\u00d4\u00d5\7.\2\2\u00d5\27\3\2\2\2\u00d6\u00d7\7"+ - "=\2\2\u00d7\31\3\2\2\2\u00d8\u00d9\7k\2\2\u00d9\u00da\7h\2\2\u00da\33"+ - "\3\2\2\2\u00db\u00dc\7g\2\2\u00dc\u00dd\7n\2\2\u00dd\u00de\7u\2\2\u00de"+ - "\u00df\7g\2\2\u00df\35\3\2\2\2\u00e0\u00e1\7y\2\2\u00e1\u00e2\7j\2\2\u00e2"+ - "\u00e3\7k\2\2\u00e3\u00e4\7n\2\2\u00e4\u00e5\7g\2\2\u00e5\37\3\2\2\2\u00e6"+ - "\u00e7\7f\2\2\u00e7\u00e8\7q\2\2\u00e8!\3\2\2\2\u00e9\u00ea\7h\2\2\u00ea"+ - "\u00eb\7q\2\2\u00eb\u00ec\7t\2\2\u00ec#\3\2\2\2\u00ed\u00ee\7e\2\2\u00ee"+ - "\u00ef\7q\2\2\u00ef\u00f0\7p\2\2\u00f0\u00f1\7v\2\2\u00f1\u00f2\7k\2\2"+ - "\u00f2\u00f3\7p\2\2\u00f3\u00f4\7w\2\2\u00f4\u00f5\7g\2\2\u00f5%\3\2\2"+ - "\2\u00f6\u00f7\7d\2\2\u00f7\u00f8\7t\2\2\u00f8\u00f9\7g\2\2\u00f9\u00fa"+ - "\7c\2\2\u00fa\u00fb\7m\2\2\u00fb\'\3\2\2\2\u00fc\u00fd\7t\2\2\u00fd\u00fe"+ - "\7g\2\2\u00fe\u00ff\7v\2\2\u00ff\u0100\7w\2\2\u0100\u0101\7t\2\2\u0101"+ - "\u0102\7p\2\2\u0102)\3\2\2\2\u0103\u0104\7p\2\2\u0104\u0105\7g\2\2\u0105"+ - "\u0106\7y\2\2\u0106+\3\2\2\2\u0107\u0108\7v\2\2\u0108\u0109\7t\2\2\u0109"+ - "\u010a\7{\2\2\u010a-\3\2\2\2\u010b\u010c\7e\2\2\u010c\u010d\7c\2\2\u010d"+ - "\u010e\7v\2\2\u010e\u010f\7e\2\2\u010f\u0110\7j\2\2\u0110/\3\2\2\2\u0111"+ - "\u0112\7v\2\2\u0112\u0113\7j\2\2\u0113\u0114\7t\2\2\u0114\u0115\7q\2\2"+ - "\u0115\u0116\7y\2\2\u0116\61\3\2\2\2\u0117\u0118\7v\2\2\u0118\u0119\7"+ - "j\2\2\u0119\u011a\7k\2\2\u011a\u011b\7u\2\2\u011b\63\3\2\2\2\u011c\u011d"+ - "\7#\2\2\u011d\65\3\2\2\2\u011e\u011f\7\u0080\2\2\u011f\67\3\2\2\2\u0120"+ - "\u0121\7,\2\2\u01219\3\2\2\2\u0122\u0123\7\61\2\2\u0123\u0124\6\35\2\2"+ - "\u0124;\3\2\2\2\u0125\u0126\7\'\2\2\u0126=\3\2\2\2\u0127\u0128\7-\2\2"+ - "\u0128?\3\2\2\2\u0129\u012a\7/\2\2\u012aA\3\2\2\2\u012b\u012c\7>\2\2\u012c"+ - "\u012d\7>\2\2\u012dC\3\2\2\2\u012e\u012f\7@\2\2\u012f\u0130\7@\2\2\u0130"+ - "E\3\2\2\2\u0131\u0132\7@\2\2\u0132\u0133\7@\2\2\u0133\u0134\7@\2\2\u0134"+ - "G\3\2\2\2\u0135\u0136\7>\2\2\u0136I\3\2\2\2\u0137\u0138\7>\2\2\u0138\u0139"+ - "\7?\2\2\u0139K\3\2\2\2\u013a\u013b\7@\2\2\u013bM\3\2\2\2\u013c\u013d\7"+ - "@\2\2\u013d\u013e\7?\2\2\u013eO\3\2\2\2\u013f\u0140\7?\2\2\u0140\u0141"+ - "\7?\2\2\u0141Q\3\2\2\2\u0142\u0143\7?\2\2\u0143\u0144\7?\2\2\u0144\u0145"+ - "\7?\2\2\u0145S\3\2\2\2\u0146\u0147\7#\2\2\u0147\u0148\7?\2\2\u0148U\3"+ - "\2\2\2\u0149\u014a\7#\2\2\u014a\u014b\7?\2\2\u014b\u014c\7?\2\2\u014c"+ - "W\3\2\2\2\u014d\u014e\7(\2\2\u014eY\3\2\2\2\u014f\u0150\7`\2\2\u0150["+ - "\3\2\2\2\u0151\u0152\7~\2\2\u0152]\3\2\2\2\u0153\u0154\7(\2\2\u0154\u0155"+ - "\7(\2\2\u0155_\3\2\2\2\u0156\u0157\7~\2\2\u0157\u0158\7~\2\2\u0158a\3"+ - "\2\2\2\u0159\u015a\7A\2\2\u015ac\3\2\2\2\u015b\u015c\7<\2\2\u015ce\3\2"+ - "\2\2\u015d\u015e\7<\2\2\u015e\u015f\7<\2\2\u015fg\3\2\2\2\u0160\u0161"+ - "\7/\2\2\u0161\u0162\7@\2\2\u0162i\3\2\2\2\u0163\u0164\7?\2\2\u0164\u0165"+ - "\7\u0080\2\2\u0165k\3\2\2\2\u0166\u0167\7?\2\2\u0167\u0168\7?\2\2\u0168"+ - "\u0169\7\u0080\2\2\u0169m\3\2\2\2\u016a\u016b\7-\2\2\u016b\u016c\7-\2"+ - "\2\u016co\3\2\2\2\u016d\u016e\7/\2\2\u016e\u016f\7/\2\2\u016fq\3\2\2\2"+ - "\u0170\u0171\7?\2\2\u0171s\3\2\2\2\u0172\u0173\7-\2\2\u0173\u0174\7?\2"+ - "\2\u0174u\3\2\2\2\u0175\u0176\7/\2\2\u0176\u0177\7?\2\2\u0177w\3\2\2\2"+ - "\u0178\u0179\7,\2\2\u0179\u017a\7?\2\2\u017ay\3\2\2\2\u017b\u017c\7\61"+ - "\2\2\u017c\u017d\7?\2\2\u017d{\3\2\2\2\u017e\u017f\7\'\2\2\u017f\u0180"+ - "\7?\2\2\u0180}\3\2\2\2\u0181\u0182\7(\2\2\u0182\u0183\7?\2\2\u0183\177"+ - "\3\2\2\2\u0184\u0185\7`\2\2\u0185\u0186\7?\2\2\u0186\u0081\3\2\2\2\u0187"+ - "\u0188\7~\2\2\u0188\u0189\7?\2\2\u0189\u0083\3\2\2\2\u018a\u018b\7>\2"+ - "\2\u018b\u018c\7>\2\2\u018c\u018d\7?\2\2\u018d\u0085\3\2\2\2\u018e\u018f"+ - "\7@\2\2\u018f\u0190\7@\2\2\u0190\u0191\7?\2\2\u0191\u0087\3\2\2\2\u0192"+ - "\u0193\7@\2\2\u0193\u0194\7@\2\2\u0194\u0195\7@\2\2\u0195\u0196\7?\2\2"+ - "\u0196\u0089\3\2\2\2\u0197\u0199\7\62\2\2\u0198\u019a\t\4\2\2\u0199\u0198"+ - "\3\2\2\2\u019a\u019b\3\2\2\2\u019b\u0199\3\2\2\2\u019b\u019c\3\2\2\2\u019c"+ - "\u019e\3\2\2\2\u019d\u019f\t\5\2\2\u019e\u019d\3\2\2\2\u019e\u019f\3\2"+ - "\2\2\u019f\u008b\3\2\2\2\u01a0\u01a1\7\62\2\2\u01a1\u01a3\t\6\2\2\u01a2"+ - "\u01a4\t\7\2\2\u01a3\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a3\3\2"+ - "\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a8\3\2\2\2\u01a7\u01a9\t\5\2\2\u01a8"+ - "\u01a7\3\2\2\2\u01a8\u01a9\3\2\2\2\u01a9\u008d\3\2\2\2\u01aa\u01b3\7\62"+ - "\2\2\u01ab\u01af\t\b\2\2\u01ac\u01ae\t\t\2\2\u01ad\u01ac\3\2\2\2\u01ae"+ - "\u01b1\3\2\2\2\u01af\u01ad\3\2\2\2\u01af\u01b0\3\2\2\2\u01b0\u01b3\3\2"+ - "\2\2\u01b1\u01af\3\2\2\2\u01b2\u01aa\3\2\2\2\u01b2\u01ab\3\2\2\2\u01b3"+ - "\u01b5\3\2\2\2\u01b4\u01b6\t\n\2\2\u01b5\u01b4\3\2\2\2\u01b5\u01b6\3\2"+ - "\2\2\u01b6\u008f\3\2\2\2\u01b7\u01c0\7\62\2\2\u01b8\u01bc\t\b\2\2\u01b9"+ - "\u01bb\t\t\2\2\u01ba\u01b9\3\2\2\2\u01bb\u01be\3\2\2\2\u01bc\u01ba\3\2"+ - "\2\2\u01bc\u01bd\3\2\2\2\u01bd\u01c0\3\2\2\2\u01be\u01bc\3\2\2\2\u01bf"+ - "\u01b7\3\2\2\2\u01bf\u01b8\3\2\2\2\u01c0\u01c7\3\2\2\2\u01c1\u01c3\5\24"+ - "\n\2\u01c2\u01c4\t\t\2\2\u01c3\u01c2\3\2\2\2\u01c4\u01c5\3\2\2\2\u01c5"+ - "\u01c3\3\2\2\2\u01c5\u01c6\3\2\2\2\u01c6\u01c8\3\2\2\2\u01c7\u01c1\3\2"+ - "\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01d2\3\2\2\2\u01c9\u01cb\t\13\2\2\u01ca"+ - "\u01cc\t\f\2\2\u01cb\u01ca\3\2\2\2\u01cb\u01cc\3\2\2\2\u01cc\u01ce\3\2"+ - "\2\2\u01cd\u01cf\t\t\2\2\u01ce\u01cd\3\2\2\2\u01cf\u01d0\3\2\2\2\u01d0"+ - "\u01ce\3\2\2\2\u01d0\u01d1\3\2\2\2\u01d1\u01d3\3\2\2\2\u01d2\u01c9\3\2"+ - "\2\2\u01d2\u01d3\3\2\2\2\u01d3\u01d5\3\2\2\2\u01d4\u01d6\t\r\2\2\u01d5"+ - "\u01d4\3\2\2\2\u01d5\u01d6\3\2\2\2\u01d6\u0091\3\2\2\2\u01d7\u01df\7$"+ - "\2\2\u01d8\u01d9\7^\2\2\u01d9\u01de\7$\2\2\u01da\u01db\7^\2\2\u01db\u01de"+ - "\7^\2\2\u01dc\u01de\n\16\2\2\u01dd\u01d8\3\2\2\2\u01dd\u01da\3\2\2\2\u01dd"+ - "\u01dc\3\2\2\2\u01de\u01e1\3\2\2\2\u01df\u01e0\3\2\2\2\u01df\u01dd\3\2"+ - "\2\2\u01e0\u01e2\3\2\2\2\u01e1\u01df\3\2\2\2\u01e2\u01f0\7$\2\2\u01e3"+ - "\u01eb\7)\2\2\u01e4\u01e5\7^\2\2\u01e5\u01ea\7)\2\2\u01e6\u01e7\7^\2\2"+ - "\u01e7\u01ea\7^\2\2\u01e8\u01ea\n\16\2\2\u01e9\u01e4\3\2\2\2\u01e9\u01e6"+ - "\3\2\2\2\u01e9\u01e8\3\2\2\2\u01ea\u01ed\3\2\2\2\u01eb\u01ec\3\2\2\2\u01eb"+ - "\u01e9\3\2\2\2\u01ec\u01ee\3\2\2\2\u01ed\u01eb\3\2\2\2\u01ee\u01f0\7)"+ - "\2\2\u01ef\u01d7\3\2\2\2\u01ef\u01e3\3\2\2\2\u01f0\u0093\3\2\2\2\u01f1"+ - "\u01f5\7\61\2\2\u01f2\u01f6\n\17\2\2\u01f3\u01f4\7^\2\2\u01f4\u01f6\n"+ - "\20\2\2\u01f5\u01f2\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f6\u01f7\3\2\2\2\u01f7"+ - "\u01f5\3\2\2\2\u01f7\u01f8\3\2\2\2\u01f8\u01f9\3\2\2\2\u01f9\u01fa\7\61"+ - "\2\2\u01fa\u01fb\6J\3\2\u01fb\u0095\3\2\2\2\u01fc\u01fd\7v\2\2\u01fd\u01fe"+ - "\7t\2\2\u01fe\u01ff\7w\2\2\u01ff\u0200\7g\2\2\u0200\u0097\3\2\2\2\u0201"+ - "\u0202\7h\2\2\u0202\u0203\7c\2\2\u0203\u0204\7n\2\2\u0204\u0205\7u\2\2"+ - "\u0205\u0206\7g\2\2\u0206\u0099\3\2\2\2\u0207\u0208\7p\2\2\u0208\u0209"+ - "\7w\2\2\u0209\u020a\7n\2\2\u020a\u020b\7n\2\2\u020b\u009b\3\2\2\2\u020c"+ - "\u0212\5\u009eO\2\u020d\u020e\5\24\n\2\u020e\u020f\5\u009eO\2\u020f\u0211"+ - "\3\2\2\2\u0210\u020d\3\2\2\2\u0211\u0214\3\2\2\2\u0212\u0210\3\2\2\2\u0212"+ - "\u0213\3\2\2\2\u0213\u0215\3\2\2\2\u0214\u0212\3\2\2\2\u0215\u0216\6N"+ - "\4\2\u0216\u009d\3\2\2\2\u0217\u021b\t\21\2\2\u0218\u021a\t\22\2\2\u0219"+ - "\u0218\3\2\2\2\u021a\u021d\3\2\2\2\u021b\u0219\3\2\2\2\u021b\u021c\3\2"+ - "\2\2\u021c\u009f\3\2\2\2\u021d\u021b\3\2\2\2\u021e\u0227\7\62\2\2\u021f"+ - "\u0223\t\b\2\2\u0220\u0222\t\t\2\2\u0221\u0220\3\2\2\2\u0222\u0225\3\2"+ - "\2\2\u0223\u0221\3\2\2\2\u0223\u0224\3\2\2\2\u0224\u0227\3\2\2\2\u0225"+ - "\u0223\3\2\2\2\u0226\u021e\3\2\2\2\u0226\u021f\3\2\2\2\u0227\u0228\3\2"+ - "\2\2\u0228\u0229\bP\4\2\u0229\u00a1\3\2\2\2\u022a\u022e\t\21\2\2\u022b"+ - "\u022d\t\22\2\2\u022c\u022b\3\2\2\2\u022d\u0230\3\2\2\2\u022e\u022c\3"+ - "\2\2\2\u022e\u022f\3\2\2\2\u022f\u0231\3\2\2\2\u0230\u022e\3\2\2\2\u0231"+ - "\u0232\bQ\4\2\u0232\u00a3\3\2\2\2#\2\3\u00a7\u00b1\u00bb\u00c0\u019b\u019e"+ + "J\6J\u01f6\nJ\rJ\16J\u01f7\3J\3J\7J\u01fc\nJ\fJ\16J\u01ff\13J\3J\3J\3"+ + "K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3N\3N\3N\3N\7N\u0217\n"+ + "N\fN\16N\u021a\13N\3N\3N\3O\3O\7O\u0220\nO\fO\16O\u0223\13O\3P\3P\3P\7"+ + "P\u0228\nP\fP\16P\u022b\13P\5P\u022d\nP\3P\3P\3Q\3Q\7Q\u0233\nQ\fQ\16"+ + "Q\u0236\13Q\3Q\3Q\6\u00b1\u00bb\u01df\u01eb\2R\4\3\6\4\b\5\n\6\f\7\16"+ + "\b\20\t\22\n\24\13\26\f\30\r\32\16\34\17\36\20 \21\"\22$\23&\24(\25*\26"+ + ",\27.\30\60\31\62\32\64\33\66\348\35:\36<\37> @!B\"D#F$H%J&L\'N(P)R*T"+ + "+V,X-Z.\\/^\60`\61b\62d\63f\64h\65j\66l\67n8p9r:t;v|?~@\u0080A\u0082"+ + "B\u0084C\u0086D\u0088E\u008aF\u008cG\u008eH\u0090I\u0092J\u0094K\u0096"+ + "L\u0098M\u009aN\u009cO\u009eP\u00a0Q\u00a2R\4\2\3\24\5\2\13\f\17\17\""+ + "\"\4\2\f\f\17\17\3\2\629\4\2NNnn\4\2ZZzz\5\2\62;CHch\3\2\63;\3\2\62;\b"+ + "\2FFHHNNffhhnn\4\2GGgg\4\2--//\4\2HHhh\4\2$$^^\4\2\f\f\61\61\3\2\f\f\t"+ + "\2WWeekknouuwwzz\5\2C\\aac|\6\2\62;C\\aac|\u0259\2\4\3\2\2\2\2\6\3\2\2"+ + "\2\2\b\3\2\2\2\2\n\3\2\2\2\2\f\3\2\2\2\2\16\3\2\2\2\2\20\3\2\2\2\2\22"+ + "\3\2\2\2\2\24\3\2\2\2\2\26\3\2\2\2\2\30\3\2\2\2\2\32\3\2\2\2\2\34\3\2"+ + "\2\2\2\36\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\60\3\2\2\2\2\62\3\2\2\2\2\64\3"+ + "\2\2\2\2\66\3\2\2\2\28\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2>\3\2\2\2\2@\3\2"+ + "\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2J\3\2\2\2\2L\3\2\2\2"+ + "\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2\2\2\2V\3\2\2\2\2X\3\2\2\2\2Z"+ + "\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2\2\2b\3\2\2\2\2d\3\2\2\2\2f\3"+ + "\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2n\3\2\2\2\2p\3\2\2\2\2r\3\2\2"+ + "\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3\2\2\2\2|\3\2\2\2\2~\3\2\2\2\2"+ + "\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3\2\2\2\2\u0086\3\2\2\2\2\u0088"+ + "\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2\2\u008e\3\2\2\2\2\u0090\3\2\2"+ + "\2\2\u0092\3\2\2\2\2\u0094\3\2\2\2\2\u0096\3\2\2\2\2\u0098\3\2\2\2\2\u009a"+ + "\3\2\2\2\2\u009c\3\2\2\2\2\u009e\3\2\2\2\3\u00a0\3\2\2\2\3\u00a2\3\2\2"+ + "\2\4\u00a5\3\2\2\2\6\u00c0\3\2\2\2\b\u00c4\3\2\2\2\n\u00c6\3\2\2\2\f\u00c8"+ + "\3\2\2\2\16\u00ca\3\2\2\2\20\u00cc\3\2\2\2\22\u00ce\3\2\2\2\24\u00d0\3"+ + "\2\2\2\26\u00d4\3\2\2\2\30\u00d6\3\2\2\2\32\u00d8\3\2\2\2\34\u00db\3\2"+ + "\2\2\36\u00e0\3\2\2\2 \u00e6\3\2\2\2\"\u00e9\3\2\2\2$\u00ed\3\2\2\2&\u00f6"+ + "\3\2\2\2(\u00fc\3\2\2\2*\u0103\3\2\2\2,\u0107\3\2\2\2.\u010b\3\2\2\2\60"+ + "\u0111\3\2\2\2\62\u0117\3\2\2\2\64\u011c\3\2\2\2\66\u011e\3\2\2\28\u0120"+ + "\3\2\2\2:\u0122\3\2\2\2<\u0125\3\2\2\2>\u0127\3\2\2\2@\u0129\3\2\2\2B"+ + "\u012b\3\2\2\2D\u012e\3\2\2\2F\u0131\3\2\2\2H\u0135\3\2\2\2J\u0137\3\2"+ + "\2\2L\u013a\3\2\2\2N\u013c\3\2\2\2P\u013f\3\2\2\2R\u0142\3\2\2\2T\u0146"+ + "\3\2\2\2V\u0149\3\2\2\2X\u014d\3\2\2\2Z\u014f\3\2\2\2\\\u0151\3\2\2\2"+ + "^\u0153\3\2\2\2`\u0156\3\2\2\2b\u0159\3\2\2\2d\u015b\3\2\2\2f\u015d\3"+ + "\2\2\2h\u0160\3\2\2\2j\u0163\3\2\2\2l\u0166\3\2\2\2n\u016a\3\2\2\2p\u016d"+ + "\3\2\2\2r\u0170\3\2\2\2t\u0172\3\2\2\2v\u0175\3\2\2\2x\u0178\3\2\2\2z"+ + "\u017b\3\2\2\2|\u017e\3\2\2\2~\u0181\3\2\2\2\u0080\u0184\3\2\2\2\u0082"+ + "\u0187\3\2\2\2\u0084\u018a\3\2\2\2\u0086\u018e\3\2\2\2\u0088\u0192\3\2"+ + "\2\2\u008a\u0197\3\2\2\2\u008c\u01a0\3\2\2\2\u008e\u01b2\3\2\2\2\u0090"+ + "\u01bf\3\2\2\2\u0092\u01ef\3\2\2\2\u0094\u01f1\3\2\2\2\u0096\u0202\3\2"+ + "\2\2\u0098\u0207\3\2\2\2\u009a\u020d\3\2\2\2\u009c\u0212\3\2\2\2\u009e"+ + "\u021d\3\2\2\2\u00a0\u022c\3\2\2\2\u00a2\u0230\3\2\2\2\u00a4\u00a6\t\2"+ + "\2\2\u00a5\u00a4\3\2\2\2\u00a6\u00a7\3\2\2\2\u00a7\u00a5\3\2\2\2\u00a7"+ + "\u00a8\3\2\2\2\u00a8\u00a9\3\2\2\2\u00a9\u00aa\b\2\2\2\u00aa\5\3\2\2\2"+ + "\u00ab\u00ac\7\61\2\2\u00ac\u00ad\7\61\2\2\u00ad\u00b1\3\2\2\2\u00ae\u00b0"+ + "\13\2\2\2\u00af\u00ae\3\2\2\2\u00b0\u00b3\3\2\2\2\u00b1\u00b2\3\2\2\2"+ + "\u00b1\u00af\3\2\2\2\u00b2\u00b4\3\2\2\2\u00b3\u00b1\3\2\2\2\u00b4\u00c1"+ + "\t\3\2\2\u00b5\u00b6\7\61\2\2\u00b6\u00b7\7,\2\2\u00b7\u00bb\3\2\2\2\u00b8"+ + "\u00ba\13\2\2\2\u00b9\u00b8\3\2\2\2\u00ba\u00bd\3\2\2\2\u00bb\u00bc\3"+ + "\2\2\2\u00bb\u00b9\3\2\2\2\u00bc\u00be\3\2\2\2\u00bd\u00bb\3\2\2\2\u00be"+ + "\u00bf\7,\2\2\u00bf\u00c1\7\61\2\2\u00c0\u00ab\3\2\2\2\u00c0\u00b5\3\2"+ + "\2\2\u00c1\u00c2\3\2\2\2\u00c2\u00c3\b\3\2\2\u00c3\7\3\2\2\2\u00c4\u00c5"+ + "\7}\2\2\u00c5\t\3\2\2\2\u00c6\u00c7\7\177\2\2\u00c7\13\3\2\2\2\u00c8\u00c9"+ + "\7]\2\2\u00c9\r\3\2\2\2\u00ca\u00cb\7_\2\2\u00cb\17\3\2\2\2\u00cc\u00cd"+ + "\7*\2\2\u00cd\21\3\2\2\2\u00ce\u00cf\7+\2\2\u00cf\23\3\2\2\2\u00d0\u00d1"+ + "\7\60\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00d3\b\n\3\2\u00d3\25\3\2\2\2\u00d4"+ + "\u00d5\7.\2\2\u00d5\27\3\2\2\2\u00d6\u00d7\7=\2\2\u00d7\31\3\2\2\2\u00d8"+ + "\u00d9\7k\2\2\u00d9\u00da\7h\2\2\u00da\33\3\2\2\2\u00db\u00dc\7g\2\2\u00dc"+ + "\u00dd\7n\2\2\u00dd\u00de\7u\2\2\u00de\u00df\7g\2\2\u00df\35\3\2\2\2\u00e0"+ + "\u00e1\7y\2\2\u00e1\u00e2\7j\2\2\u00e2\u00e3\7k\2\2\u00e3\u00e4\7n\2\2"+ + "\u00e4\u00e5\7g\2\2\u00e5\37\3\2\2\2\u00e6\u00e7\7f\2\2\u00e7\u00e8\7"+ + "q\2\2\u00e8!\3\2\2\2\u00e9\u00ea\7h\2\2\u00ea\u00eb\7q\2\2\u00eb\u00ec"+ + "\7t\2\2\u00ec#\3\2\2\2\u00ed\u00ee\7e\2\2\u00ee\u00ef\7q\2\2\u00ef\u00f0"+ + "\7p\2\2\u00f0\u00f1\7v\2\2\u00f1\u00f2\7k\2\2\u00f2\u00f3\7p\2\2\u00f3"+ + "\u00f4\7w\2\2\u00f4\u00f5\7g\2\2\u00f5%\3\2\2\2\u00f6\u00f7\7d\2\2\u00f7"+ + "\u00f8\7t\2\2\u00f8\u00f9\7g\2\2\u00f9\u00fa\7c\2\2\u00fa\u00fb\7m\2\2"+ + "\u00fb\'\3\2\2\2\u00fc\u00fd\7t\2\2\u00fd\u00fe\7g\2\2\u00fe\u00ff\7v"+ + "\2\2\u00ff\u0100\7w\2\2\u0100\u0101\7t\2\2\u0101\u0102\7p\2\2\u0102)\3"+ + "\2\2\2\u0103\u0104\7p\2\2\u0104\u0105\7g\2\2\u0105\u0106\7y\2\2\u0106"+ + "+\3\2\2\2\u0107\u0108\7v\2\2\u0108\u0109\7t\2\2\u0109\u010a\7{\2\2\u010a"+ + "-\3\2\2\2\u010b\u010c\7e\2\2\u010c\u010d\7c\2\2\u010d\u010e\7v\2\2\u010e"+ + "\u010f\7e\2\2\u010f\u0110\7j\2\2\u0110/\3\2\2\2\u0111\u0112\7v\2\2\u0112"+ + "\u0113\7j\2\2\u0113\u0114\7t\2\2\u0114\u0115\7q\2\2\u0115\u0116\7y\2\2"+ + "\u0116\61\3\2\2\2\u0117\u0118\7v\2\2\u0118\u0119\7j\2\2\u0119\u011a\7"+ + "k\2\2\u011a\u011b\7u\2\2\u011b\63\3\2\2\2\u011c\u011d\7#\2\2\u011d\65"+ + "\3\2\2\2\u011e\u011f\7\u0080\2\2\u011f\67\3\2\2\2\u0120\u0121\7,\2\2\u0121"+ + "9\3\2\2\2\u0122\u0123\7\61\2\2\u0123\u0124\6\35\2\2\u0124;\3\2\2\2\u0125"+ + "\u0126\7\'\2\2\u0126=\3\2\2\2\u0127\u0128\7-\2\2\u0128?\3\2\2\2\u0129"+ + "\u012a\7/\2\2\u012aA\3\2\2\2\u012b\u012c\7>\2\2\u012c\u012d\7>\2\2\u012d"+ + "C\3\2\2\2\u012e\u012f\7@\2\2\u012f\u0130\7@\2\2\u0130E\3\2\2\2\u0131\u0132"+ + "\7@\2\2\u0132\u0133\7@\2\2\u0133\u0134\7@\2\2\u0134G\3\2\2\2\u0135\u0136"+ + "\7>\2\2\u0136I\3\2\2\2\u0137\u0138\7>\2\2\u0138\u0139\7?\2\2\u0139K\3"+ + "\2\2\2\u013a\u013b\7@\2\2\u013bM\3\2\2\2\u013c\u013d\7@\2\2\u013d\u013e"+ + "\7?\2\2\u013eO\3\2\2\2\u013f\u0140\7?\2\2\u0140\u0141\7?\2\2\u0141Q\3"+ + "\2\2\2\u0142\u0143\7?\2\2\u0143\u0144\7?\2\2\u0144\u0145\7?\2\2\u0145"+ + "S\3\2\2\2\u0146\u0147\7#\2\2\u0147\u0148\7?\2\2\u0148U\3\2\2\2\u0149\u014a"+ + "\7#\2\2\u014a\u014b\7?\2\2\u014b\u014c\7?\2\2\u014cW\3\2\2\2\u014d\u014e"+ + "\7(\2\2\u014eY\3\2\2\2\u014f\u0150\7`\2\2\u0150[\3\2\2\2\u0151\u0152\7"+ + "~\2\2\u0152]\3\2\2\2\u0153\u0154\7(\2\2\u0154\u0155\7(\2\2\u0155_\3\2"+ + "\2\2\u0156\u0157\7~\2\2\u0157\u0158\7~\2\2\u0158a\3\2\2\2\u0159\u015a"+ + "\7A\2\2\u015ac\3\2\2\2\u015b\u015c\7<\2\2\u015ce\3\2\2\2\u015d\u015e\7"+ + "<\2\2\u015e\u015f\7<\2\2\u015fg\3\2\2\2\u0160\u0161\7/\2\2\u0161\u0162"+ + "\7@\2\2\u0162i\3\2\2\2\u0163\u0164\7?\2\2\u0164\u0165\7\u0080\2\2\u0165"+ + "k\3\2\2\2\u0166\u0167\7?\2\2\u0167\u0168\7?\2\2\u0168\u0169\7\u0080\2"+ + "\2\u0169m\3\2\2\2\u016a\u016b\7-\2\2\u016b\u016c\7-\2\2\u016co\3\2\2\2"+ + "\u016d\u016e\7/\2\2\u016e\u016f\7/\2\2\u016fq\3\2\2\2\u0170\u0171\7?\2"+ + "\2\u0171s\3\2\2\2\u0172\u0173\7-\2\2\u0173\u0174\7?\2\2\u0174u\3\2\2\2"+ + "\u0175\u0176\7/\2\2\u0176\u0177\7?\2\2\u0177w\3\2\2\2\u0178\u0179\7,\2"+ + "\2\u0179\u017a\7?\2\2\u017ay\3\2\2\2\u017b\u017c\7\61\2\2\u017c\u017d"+ + "\7?\2\2\u017d{\3\2\2\2\u017e\u017f\7\'\2\2\u017f\u0180\7?\2\2\u0180}\3"+ + "\2\2\2\u0181\u0182\7(\2\2\u0182\u0183\7?\2\2\u0183\177\3\2\2\2\u0184\u0185"+ + "\7`\2\2\u0185\u0186\7?\2\2\u0186\u0081\3\2\2\2\u0187\u0188\7~\2\2\u0188"+ + "\u0189\7?\2\2\u0189\u0083\3\2\2\2\u018a\u018b\7>\2\2\u018b\u018c\7>\2"+ + "\2\u018c\u018d\7?\2\2\u018d\u0085\3\2\2\2\u018e\u018f\7@\2\2\u018f\u0190"+ + "\7@\2\2\u0190\u0191\7?\2\2\u0191\u0087\3\2\2\2\u0192\u0193\7@\2\2\u0193"+ + "\u0194\7@\2\2\u0194\u0195\7@\2\2\u0195\u0196\7?\2\2\u0196\u0089\3\2\2"+ + "\2\u0197\u0199\7\62\2\2\u0198\u019a\t\4\2\2\u0199\u0198\3\2\2\2\u019a"+ + "\u019b\3\2\2\2\u019b\u0199\3\2\2\2\u019b\u019c\3\2\2\2\u019c\u019e\3\2"+ + "\2\2\u019d\u019f\t\5\2\2\u019e\u019d\3\2\2\2\u019e\u019f\3\2\2\2\u019f"+ + "\u008b\3\2\2\2\u01a0\u01a1\7\62\2\2\u01a1\u01a3\t\6\2\2\u01a2\u01a4\t"+ + "\7\2\2\u01a3\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a3\3\2\2\2\u01a5"+ + "\u01a6\3\2\2\2\u01a6\u01a8\3\2\2\2\u01a7\u01a9\t\5\2\2\u01a8\u01a7\3\2"+ + "\2\2\u01a8\u01a9\3\2\2\2\u01a9\u008d\3\2\2\2\u01aa\u01b3\7\62\2\2\u01ab"+ + "\u01af\t\b\2\2\u01ac\u01ae\t\t\2\2\u01ad\u01ac\3\2\2\2\u01ae\u01b1\3\2"+ + "\2\2\u01af\u01ad\3\2\2\2\u01af\u01b0\3\2\2\2\u01b0\u01b3\3\2\2\2\u01b1"+ + "\u01af\3\2\2\2\u01b2\u01aa\3\2\2\2\u01b2\u01ab\3\2\2\2\u01b3\u01b5\3\2"+ + "\2\2\u01b4\u01b6\t\n\2\2\u01b5\u01b4\3\2\2\2\u01b5\u01b6\3\2\2\2\u01b6"+ + "\u008f\3\2\2\2\u01b7\u01c0\7\62\2\2\u01b8\u01bc\t\b\2\2\u01b9\u01bb\t"+ + "\t\2\2\u01ba\u01b9\3\2\2\2\u01bb\u01be\3\2\2\2\u01bc\u01ba\3\2\2\2\u01bc"+ + "\u01bd\3\2\2\2\u01bd\u01c0\3\2\2\2\u01be\u01bc\3\2\2\2\u01bf\u01b7\3\2"+ + "\2\2\u01bf\u01b8\3\2\2\2\u01c0\u01c7\3\2\2\2\u01c1\u01c3\5\24\n\2\u01c2"+ + "\u01c4\t\t\2\2\u01c3\u01c2\3\2\2\2\u01c4\u01c5\3\2\2\2\u01c5\u01c3\3\2"+ + "\2\2\u01c5\u01c6\3\2\2\2\u01c6\u01c8\3\2\2\2\u01c7\u01c1\3\2\2\2\u01c7"+ + "\u01c8\3\2\2\2\u01c8\u01d2\3\2\2\2\u01c9\u01cb\t\13\2\2\u01ca\u01cc\t"+ + "\f\2\2\u01cb\u01ca\3\2\2\2\u01cb\u01cc\3\2\2\2\u01cc\u01ce\3\2\2\2\u01cd"+ + "\u01cf\t\t\2\2\u01ce\u01cd\3\2\2\2\u01cf\u01d0\3\2\2\2\u01d0\u01ce\3\2"+ + "\2\2\u01d0\u01d1\3\2\2\2\u01d1\u01d3\3\2\2\2\u01d2\u01c9\3\2\2\2\u01d2"+ + "\u01d3\3\2\2\2\u01d3\u01d5\3\2\2\2\u01d4\u01d6\t\r\2\2\u01d5\u01d4\3\2"+ + "\2\2\u01d5\u01d6\3\2\2\2\u01d6\u0091\3\2\2\2\u01d7\u01df\7$\2\2\u01d8"+ + "\u01d9\7^\2\2\u01d9\u01de\7$\2\2\u01da\u01db\7^\2\2\u01db\u01de\7^\2\2"+ + "\u01dc\u01de\n\16\2\2\u01dd\u01d8\3\2\2\2\u01dd\u01da\3\2\2\2\u01dd\u01dc"+ + "\3\2\2\2\u01de\u01e1\3\2\2\2\u01df\u01e0\3\2\2\2\u01df\u01dd\3\2\2\2\u01e0"+ + "\u01e2\3\2\2\2\u01e1\u01df\3\2\2\2\u01e2\u01f0\7$\2\2\u01e3\u01eb\7)\2"+ + "\2\u01e4\u01e5\7^\2\2\u01e5\u01ea\7)\2\2\u01e6\u01e7\7^\2\2\u01e7\u01ea"+ + "\7^\2\2\u01e8\u01ea\n\16\2\2\u01e9\u01e4\3\2\2\2\u01e9\u01e6\3\2\2\2\u01e9"+ + "\u01e8\3\2\2\2\u01ea\u01ed\3\2\2\2\u01eb\u01ec\3\2\2\2\u01eb\u01e9\3\2"+ + "\2\2\u01ec\u01ee\3\2\2\2\u01ed\u01eb\3\2\2\2\u01ee\u01f0\7)\2\2\u01ef"+ + "\u01d7\3\2\2\2\u01ef\u01e3\3\2\2\2\u01f0\u0093\3\2\2\2\u01f1\u01f5\7\61"+ + "\2\2\u01f2\u01f6\n\17\2\2\u01f3\u01f4\7^\2\2\u01f4\u01f6\n\20\2\2\u01f5"+ + "\u01f2\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f6\u01f7\3\2\2\2\u01f7\u01f5\3\2"+ + "\2\2\u01f7\u01f8\3\2\2\2\u01f8\u01f9\3\2\2\2\u01f9\u01fd\7\61\2\2\u01fa"+ + "\u01fc\t\21\2\2\u01fb\u01fa\3\2\2\2\u01fc\u01ff\3\2\2\2\u01fd\u01fb\3"+ + "\2\2\2\u01fd\u01fe\3\2\2\2\u01fe\u0200\3\2\2\2\u01ff\u01fd\3\2\2\2\u0200"+ + "\u0201\6J\3\2\u0201\u0095\3\2\2\2\u0202\u0203\7v\2\2\u0203\u0204\7t\2"+ + "\2\u0204\u0205\7w\2\2\u0205\u0206\7g\2\2\u0206\u0097\3\2\2\2\u0207\u0208"+ + "\7h\2\2\u0208\u0209\7c\2\2\u0209\u020a\7n\2\2\u020a\u020b\7u\2\2\u020b"+ + "\u020c\7g\2\2\u020c\u0099\3\2\2\2\u020d\u020e\7p\2\2\u020e\u020f\7w\2"+ + "\2\u020f\u0210\7n\2\2\u0210\u0211\7n\2\2\u0211\u009b\3\2\2\2\u0212\u0218"+ + "\5\u009eO\2\u0213\u0214\5\24\n\2\u0214\u0215\5\u009eO\2\u0215\u0217\3"+ + "\2\2\2\u0216\u0213\3\2\2\2\u0217\u021a\3\2\2\2\u0218\u0216\3\2\2\2\u0218"+ + "\u0219\3\2\2\2\u0219\u021b\3\2\2\2\u021a\u0218\3\2\2\2\u021b\u021c\6N"+ + "\4\2\u021c\u009d\3\2\2\2\u021d\u0221\t\22\2\2\u021e\u0220\t\23\2\2\u021f"+ + "\u021e\3\2\2\2\u0220\u0223\3\2\2\2\u0221\u021f\3\2\2\2\u0221\u0222\3\2"+ + "\2\2\u0222\u009f\3\2\2\2\u0223\u0221\3\2\2\2\u0224\u022d\7\62\2\2\u0225"+ + "\u0229\t\b\2\2\u0226\u0228\t\t\2\2\u0227\u0226\3\2\2\2\u0228\u022b\3\2"+ + "\2\2\u0229\u0227\3\2\2\2\u0229\u022a\3\2\2\2\u022a\u022d\3\2\2\2\u022b"+ + "\u0229\3\2\2\2\u022c\u0224\3\2\2\2\u022c\u0225\3\2\2\2\u022d\u022e\3\2"+ + "\2\2\u022e\u022f\bP\4\2\u022f\u00a1\3\2\2\2\u0230\u0234\t\22\2\2\u0231"+ + "\u0233\t\23\2\2\u0232\u0231\3\2\2\2\u0233\u0236\3\2\2\2\u0234\u0232\3"+ + "\2\2\2\u0234\u0235\3\2\2\2\u0235\u0237\3\2\2\2\u0236\u0234\3\2\2\2\u0237"+ + "\u0238\bQ\4\2\u0238\u00a3\3\2\2\2$\2\3\u00a7\u00b1\u00bb\u00c0\u019b\u019e"+ "\u01a5\u01a8\u01af\u01b2\u01b5\u01bc\u01bf\u01c5\u01c7\u01cb\u01d0\u01d2"+ - "\u01d5\u01dd\u01df\u01e9\u01eb\u01ef\u01f5\u01f7\u0212\u021b\u0223\u0226"+ - "\u022e\5\b\2\2\4\3\2\4\2\2"; + "\u01d5\u01dd\u01df\u01e9\u01eb\u01ef\u01f5\u01f7\u01fd\u0218\u0221\u0229"+ + "\u022c\u0234\5\b\2\2\4\3\2\4\2\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java index b1a5ed3a260..474e47599a8 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java @@ -834,9 +834,12 @@ public final class Walker extends PainlessParserBaseVisitor { @Override public Object visitRegex(RegexContext ctx) { - String pattern = ctx.REGEX().getText().substring(1, ctx.REGEX().getText().length() - 1); + String text = ctx.REGEX().getText(); + int lastSlash = text.lastIndexOf('/'); + String pattern = text.substring(1, lastSlash); + String flags = text.substring(lastSlash + 1); List links = new ArrayList<>(); - links.add(new LRegex(location(ctx), pattern)); + links.add(new LRegex(location(ctx), pattern, flags)); return links; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LRegex.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LRegex.java index 720e9d45969..324b6d72cf1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LRegex.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LRegex.java @@ -35,14 +35,20 @@ import org.elasticsearch.painless.WriterConstants; */ public final class LRegex extends ALink { private final String pattern; + private final int flags; private Constant constant; - public LRegex(Location location, String pattern) { + public LRegex(Location location, String pattern, String flagsString) { super(location, 1); this.pattern = pattern; + int flags = 0; + for (int c = 0; c < flagsString.length(); c++) { + flags |= flagForChar(flagsString.charAt(c)); + } + this.flags = flags; try { // Compile the pattern early after parsing so we can throw an error to the user with the location - Pattern.compile(pattern); + Pattern.compile(pattern, flags); } catch (PatternSyntaxException e) { throw createError(e); } @@ -82,6 +88,21 @@ public final class LRegex extends ALink { private void initializeConstant(MethodWriter writer) { writer.push(pattern); + writer.push(flags); writer.invokeStatic(Definition.PATTERN_TYPE.type, WriterConstants.PATTERN_COMPILE); } + + private int flagForChar(char c) { + switch (c) { + case 'c': return Pattern.CANON_EQ; + case 'i': return Pattern.CASE_INSENSITIVE; + case 'l': return Pattern.LITERAL; + case 'm': return Pattern.MULTILINE; + case 's': return Pattern.DOTALL; + case 'U': return Pattern.UNICODE_CHARACTER_CLASS; + case 'u': return Pattern.UNICODE_CASE; + case 'x': return Pattern.COMMENTS; + default: throw new IllegalArgumentException("Unknown flag [" + c + "]"); + } + } } diff --git a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/java.util.regex.txt b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/java.util.regex.txt index a8982871a33..6befc865731 100644 --- a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/java.util.regex.txt +++ b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/java.util.regex.txt @@ -25,7 +25,14 @@ class Pattern -> java.util.regex.Pattern extends Object { # Pattern compile(String) Intentionally not included. We don't want dynamic patterns because they allow regexes to be generated per time # the script is run which is super slow. LRegex generates code that calls this method but it skips these checks. + Predicate asPredicate() + int flags() Matcher matcher(CharSequence) + String pattern() + String quote(String) + String[] split(CharSequence) + String[] split(CharSequence,int) + Stream splitAsStream(CharSequence) } class Matcher -> java.util.regex.Matcher extends Object { diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java index ee281e4656b..a36eedd7058 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java @@ -19,8 +19,12 @@ package org.elasticsearch.painless; +import java.util.Arrays; +import java.util.HashSet; +import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; import static org.hamcrest.Matchers.containsString; @@ -125,6 +129,52 @@ public class RegexTests extends ScriptTestCase { assertEquals("o", exec("Matcher m = /(?f)(?o)o/.matcher('foo'); m.find(); return m.namedGroup('second')")); } + // Make sure some methods on Pattern are whitelisted + public void testSplit() { + assertArrayEquals(new String[] {"cat", "dog"}, (String[]) exec("/,/.split('cat,dog')")); + } + + public void testSplitAsStream() { + assertEquals(new HashSet<>(Arrays.asList("cat", "dog")), exec("/,/.splitAsStream('cat,dog').collect(Collectors.toSet())")); + } + + // Make sure the flags are set + public void testMultilineFlag() { + assertEquals(Pattern.MULTILINE, exec("/./m.flags()")); + } + + public void testSinglelineFlag() { + assertEquals(Pattern.DOTALL, exec("/./s.flags()")); + } + + public void testInsensitiveFlag() { + assertEquals(Pattern.CASE_INSENSITIVE, exec("/./i.flags()")); + } + + public void testExtendedFlag() { + assertEquals(Pattern.COMMENTS, exec("/./x.flags()")); + } + + public void testUnicodeCaseFlag() { + assertEquals(Pattern.UNICODE_CASE, exec("/./u.flags()")); + } + + public void testUnicodeCharacterClassFlag() { + assertEquals(Pattern.UNICODE_CASE | Pattern.UNICODE_CHARACTER_CLASS, exec("/./U.flags()")); + } + + public void testLiteralFlag() { + assertEquals(Pattern.LITERAL, exec("/./l.flags()")); + } + + public void testCanonicalEquivalenceFlag() { + assertEquals(Pattern.CANON_EQ, exec("/./c.flags()")); + } + + public void testManyFlags() { + assertEquals(Pattern.CANON_EQ | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.COMMENTS, exec("/./ciux.flags()")); + } + public void testCantUsePatternCompile() { IllegalArgumentException e = expectScriptThrows(IllegalArgumentException.class, () -> { exec("Pattern.compile('aa')"); @@ -146,4 +196,11 @@ public class RegexTests extends ScriptTestCase { }); assertEquals("Cannot cast from [int] to [String].", e.getMessage()); } + + public void testBogusRegexFlag() { + IllegalArgumentException e = expectScriptThrows(IllegalArgumentException.class, () -> { + exec("/asdf/b", emptyMap(), emptyMap(), null); // Not picky so we get a non-assertion error + }); + assertEquals("invalid sequence of tokens near ['b'].", e.getMessage()); + } } From 13d16fbf41e0cf90c9051e015681cc2198bb0334 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Thu, 16 Jun 2016 15:06:01 -0400 Subject: [PATCH 4/4] Painless: Disable java-9 indy string thing It is breaking some of the doc tests. Also add a unit test that shows the failure. Relates to #18929 --- .../main/java/org/elasticsearch/painless/WriterConstants.java | 2 +- .../src/test/java/org/elasticsearch/painless/StringTests.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java index 6960e906339..7906a125f35 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java @@ -131,7 +131,7 @@ public final class WriterConstants { // not Java 9 - we set it null, so MethodWriter uses StringBuilder: bs = null; } - INDY_STRING_CONCAT_BOOTSTRAP_HANDLE = bs; + INDY_STRING_CONCAT_BOOTSTRAP_HANDLE = null; // Disabled until https://github.com/elastic/elasticsearch/issues/18929 } public final static int MAX_INDY_STRING_CONCAT_ARGS = 200; diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java index 80b5675a6e1..873e773b9a3 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java @@ -221,4 +221,8 @@ public class StringTests extends ScriptTestCase { exec("def x = null; def y = null; x += y"); }); } + + public void testAppendStringIntoMap() { + assertEquals("nullcat", exec("def a = new HashMap(); a.cat += 'cat'")); + } }