diff --git a/python/gen/com/jetbrains/python/lexer/_PythonLexer.java b/python/gen/com/jetbrains/python/lexer/_PythonLexer.java index 0cf5d4331f6d..94a5f252fa3b 100644 --- a/python/gen/com/jetbrains/python/lexer/_PythonLexer.java +++ b/python/gen/com/jetbrains/python/lexer/_PythonLexer.java @@ -125,10 +125,10 @@ class _PythonLexer implements FlexLexer { /* The ZZ_CMAP_A table has 3424 entries */ static final char ZZ_CMAP_A[] = zzUnpackCMap( - "\11\0\1\36\1\45\1\112\1\37\1\14\22\0\1\35\1\33\1\27\1\13\1\0\1\101\1\102\1"+ - "\25\1\40\1\41\1\76\1\75\1\110\1\21\1\17\1\100\1\1\1\5\6\3\2\2\1\44\1\46\1"+ + "\11\0\1\43\1\45\1\112\1\44\1\14\22\0\1\42\1\33\1\27\1\13\1\0\1\101\1\102\1"+ + "\25\1\35\1\36\1\76\1\75\1\110\1\21\1\17\1\100\1\1\1\5\6\3\2\2\1\41\1\46\1"+ "\106\1\34\1\105\1\0\1\77\1\4\1\11\1\23\1\4\1\20\1\30\3\15\1\22\1\15\1\12\2"+ - "\15\1\10\2\15\1\24\2\15\1\24\2\15\1\6\2\15\1\42\1\26\1\43\1\104\1\7\1\111"+ + "\15\1\10\2\15\1\24\2\15\1\24\2\15\1\6\2\15\1\37\1\26\1\40\1\104\1\7\1\111"+ "\1\47\1\56\1\60\1\51\1\53\1\65\1\72\1\74\1\63\1\22\1\57\1\61\1\71\1\50\1\62"+ "\1\67\1\15\1\54\1\52\1\55\1\64\1\15\1\73\1\66\1\70\1\15\1\31\1\103\1\32\1"+ "\107\6\0\1\112\24\0\1\15\12\0\1\15\4\0\1\15\5\0\27\15\1\0\12\15\4\0\14\15"+ @@ -193,32 +193,31 @@ class _PythonLexer implements FlexLexer { "\1\15\1\16\1\17\1\20\1\21\1\22\1\23\1\24"+ "\1\25\20\3\1\26\1\27\1\30\1\31\1\32\1\33"+ "\1\34\1\35\1\36\1\37\1\40\1\41\1\42\2\43"+ - "\1\44\2\45\1\46\1\3\2\47\1\23\3\3\2\50"+ - "\1\51\1\10\1\51\1\52\1\14\1\15\1\16\1\3"+ - "\2\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62"+ - "\1\63\3\3\2\50\1\64\1\10\1\52\1\14\1\15"+ - "\1\16\1\2\5\0\1\2\1\65\1\0\1\66\1\0"+ - "\1\3\1\65\1\67\1\70\3\7\1\71\3\7\1\3"+ - "\2\72\1\73\1\74\15\3\1\75\1\76\1\77\1\100"+ - "\10\3\1\101\1\102\1\103\1\104\1\105\1\106\1\107"+ - "\1\110\1\111\1\112\1\113\1\114\1\115\1\116\1\117"+ - "\1\0\3\45\1\120\3\45\1\3\6\47\2\0\1\121"+ - "\1\3\2\0\2\44\2\51\1\3\10\53\1\56\1\3"+ - "\1\0\1\44\1\64\1\0\1\2\1\0\1\2\1\0"+ - "\1\2\1\0\1\65\1\0\1\3\1\0\1\7\1\122"+ - "\1\123\1\0\1\122\1\3\2\0\1\124\1\3\1\125"+ - "\1\126\1\127\5\3\1\130\6\3\1\131\5\3\1\132"+ - "\1\133\1\134\1\135\1\0\1\45\1\136\1\137\1\0"+ - "\1\136\1\3\1\47\2\140\1\51\1\3\3\53\1\51"+ - "\1\141\1\64\1\0\2\142\1\0\1\3\1\72\1\3"+ - "\1\143\1\144\10\3\1\145\1\3\1\146\3\3\1\0"+ - "\2\137\13\0\2\3\1\147\1\3\1\150\1\151\4\3"+ - "\1\152\1\3\1\153\7\0\1\122\1\154\1\155\1\156"+ - "\1\3\1\157\1\160\1\3\1\161\1\136\1\140\1\141"+ - "\1\142\1\0\1\162\1\3\1\163\1\164"; + "\1\44\2\45\1\46\1\3\2\47\1\20\3\3\2\50"+ + "\1\51\1\10\1\51\1\52\1\3\2\53\1\54\1\55"+ + "\1\56\1\57\1\60\1\61\1\62\1\63\3\3\2\50"+ + "\1\64\1\10\1\52\1\2\5\0\1\2\1\65\1\0"+ + "\1\66\1\0\1\3\1\65\1\67\1\70\3\7\1\71"+ + "\3\7\1\3\2\72\1\73\1\74\15\3\1\75\1\76"+ + "\1\77\1\100\10\3\1\101\1\102\1\103\1\104\1\105"+ + "\1\106\1\107\1\110\1\111\1\112\1\113\1\114\1\115"+ + "\1\116\1\117\1\0\3\45\1\120\3\45\1\3\6\47"+ + "\2\0\1\121\1\3\2\0\2\44\2\51\1\3\10\53"+ + "\1\56\1\3\1\0\1\44\1\64\1\0\1\2\1\0"+ + "\1\2\1\0\1\2\1\0\1\65\1\0\1\3\1\0"+ + "\1\7\1\122\1\123\1\0\1\122\1\3\2\0\1\124"+ + "\1\3\1\125\1\126\1\127\5\3\1\130\6\3\1\131"+ + "\5\3\1\132\1\133\1\134\1\135\1\0\1\45\1\136"+ + "\1\137\1\0\1\136\1\3\1\47\2\140\1\51\1\3"+ + "\3\53\1\51\1\141\1\64\1\0\2\142\1\0\1\3"+ + "\1\72\1\3\1\143\1\144\10\3\1\145\1\3\1\146"+ + "\3\3\1\0\2\137\13\0\2\3\1\147\1\3\1\150"+ + "\1\151\4\3\1\152\1\3\1\153\7\0\1\122\1\154"+ + "\1\155\1\156\1\3\1\157\1\160\1\3\1\161\1\136"+ + "\1\140\1\141\1\142\1\0\1\162\1\3\1\163\1\164"; private static int [] zzUnpackAction() { - int [] result = new int[350]; + int [] result = new int[344]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -253,43 +252,42 @@ class _PythonLexer implements FlexLexer { "\0\u0c99\0\u0ce4\0\u01c2\0\u01c2\0\u01c2\0\u01c2\0\u0d2f\0\u0d7a"+ "\0\u0dc5\0\u0e10\0\u01c2\0\u0e5b\0\u0ea6\0\u0ef1\0\u0f3c\0\u0f87"+ "\0\u0fd2\0\u101d\0\u1068\0\u10b3\0\u10fe\0\u1149\0\u1194\0\u11df"+ - "\0\u1068\0\u1068\0\u1068\0\u122a\0\u1275\0\u12c0\0\u01c2\0\u01c2"+ - "\0\u130b\0\u01c2\0\u01c2\0\u01c2\0\u01c2\0\u01c2\0\u1356\0\u13a1"+ - "\0\u13ec\0\u1437\0\u1482\0\u14cd\0\u1518\0\u01c2\0\u1437\0\u1437"+ - "\0\u1437\0\u1563\0\u15ae\0\u15f9\0\u1644\0\u168f\0\u16da\0\u01c2"+ - "\0\u1725\0\u1770\0\u01c2\0\u17bb\0\u1806\0\u1851\0\u01c2\0\u01c2"+ - "\0\u189c\0\u18e7\0\u1932\0\u01c2\0\u197d\0\u19c8\0\u1a13\0\u1a5e"+ - "\0\u1aa9\0\u1af4\0\u01c2\0\u01c2\0\u1b3f\0\u1b8a\0\u1bd5\0\u1c20"+ - "\0\u1c6b\0\u1cb6\0\u1d01\0\u1d4c\0\u1d97\0\u1de2\0\u1e2d\0\u1e78"+ - "\0\u1ec3\0\u02a3\0\u02a3\0\u02a3\0\u02a3\0\u1f0e\0\u1f59\0\u1fa4"+ - "\0\u1fef\0\u203a\0\u2085\0\u20d0\0\u211b\0\u01c2\0\u01c2\0\u2166"+ - "\0\u01c2\0\u01c2\0\u21b1\0\u01c2\0\u01c2\0\u01c2\0\u01c2\0\u01c2"+ - "\0\u21fc\0\u01c2\0\u01c2\0\u2247\0\u2292\0\u22dd\0\u2328\0\u2373"+ - "\0\u01c2\0\u23be\0\u2409\0\u2454\0\u249f\0\u24ea\0\u2535\0\u2580"+ - "\0\u25cb\0\u2616\0\u2661\0\u26ac\0\u0f3c\0\u01c2\0\u26f7\0\u1149"+ - "\0\u11df\0\u2742\0\u278d\0\u27d8\0\u2823\0\u286e\0\u28b9\0\u2904"+ - "\0\u294f\0\u299a\0\u29e5\0\u2a30\0\u2a7b\0\u2ac6\0\u2b11\0\u2b5c"+ - "\0\u1518\0\u2ba7\0\u2bf2\0\u2c3d\0\u2c88\0\u2cd3\0\u2d1e\0\u2d69"+ - "\0\u2db4\0\u2dff\0\u2e4a\0\u2e95\0\u2ee0\0\u0384\0\u2f2b\0\u2f76"+ - "\0\u01c2\0\u2f2b\0\u2fc1\0\u300c\0\u3057\0\u30a2\0\u02a3\0\u30ed"+ - "\0\u02a3\0\u02a3\0\u02a3\0\u3138\0\u3183\0\u31ce\0\u3219\0\u3264"+ - "\0\u02a3\0\u32af\0\u32fa\0\u3345\0\u3390\0\u33db\0\u3426\0\u02a3"+ - "\0\u3471\0\u34bc\0\u3507\0\u3552\0\u359d\0\u01c2\0\u01c2\0\u01c2"+ - "\0\u01c2\0\u35e8\0\u3633\0\u367e\0\u01c2\0\u3633\0\u36c9\0\u3714"+ - "\0\u01c2\0\u375f\0\u37aa\0\u01c2\0\u37f5\0\u2535\0\u2661\0\u01c2"+ - "\0\u375f\0\u3840\0\u01c2\0\u388b\0\u38d6\0\u3921\0\u396c\0\u39b7"+ - "\0\u01c2\0\u3a02\0\u02a3\0\u02a3\0\u3a4d\0\u3a98\0\u3ae3\0\u3b2e"+ - "\0\u3b79\0\u3bc4\0\u3c0f\0\u3c5a\0\u02a3\0\u3ca5\0\u02a3\0\u3cf0"+ - "\0\u3d3b\0\u3d86\0\u3dd1\0\u3e1c\0\u3e67\0\u3eb2\0\u3efd\0\u3f48"+ - "\0\u3f93\0\u3fde\0\u4029\0\u4074\0\u40bf\0\u38d6\0\u3921\0\u410a"+ - "\0\u4155\0\u41a0\0\u02a3\0\u41eb\0\u02a3\0\u02a3\0\u4236\0\u4281"+ - "\0\u42cc\0\u4317\0\u02a3\0\u4362\0\u02a3\0\u43ad\0\u3e1c\0\u3e67"+ - "\0\u43f8\0\u4443\0\u448e\0\u44d9\0\u4524\0\u02a3\0\u02a3\0\u02a3"+ - "\0\u456f\0\u02a3\0\u02a3\0\u45ba\0\u02a3\0\u3633\0\u01c2\0\u01c2"+ - "\0\u01c2\0\u4524\0\u01c2\0\u4605\0\u02a3\0\u02a3"; + "\0\u122a\0\u1275\0\u12c0\0\u01c2\0\u01c2\0\u130b\0\u01c2\0\u01c2"+ + "\0\u01c2\0\u01c2\0\u01c2\0\u1356\0\u13a1\0\u13ec\0\u1437\0\u1482"+ + "\0\u14cd\0\u1518\0\u01c2\0\u1563\0\u15ae\0\u15f9\0\u1644\0\u168f"+ + "\0\u16da\0\u01c2\0\u1725\0\u1770\0\u01c2\0\u17bb\0\u1806\0\u1851"+ + "\0\u01c2\0\u01c2\0\u189c\0\u18e7\0\u1932\0\u01c2\0\u197d\0\u19c8"+ + "\0\u1a13\0\u1a5e\0\u1aa9\0\u1af4\0\u01c2\0\u01c2\0\u1b3f\0\u1b8a"+ + "\0\u1bd5\0\u1c20\0\u1c6b\0\u1cb6\0\u1d01\0\u1d4c\0\u1d97\0\u1de2"+ + "\0\u1e2d\0\u1e78\0\u1ec3\0\u02a3\0\u02a3\0\u02a3\0\u02a3\0\u1f0e"+ + "\0\u1f59\0\u1fa4\0\u1fef\0\u203a\0\u2085\0\u20d0\0\u211b\0\u01c2"+ + "\0\u01c2\0\u2166\0\u01c2\0\u01c2\0\u21b1\0\u01c2\0\u01c2\0\u01c2"+ + "\0\u01c2\0\u01c2\0\u21fc\0\u01c2\0\u01c2\0\u2247\0\u2292\0\u22dd"+ + "\0\u2328\0\u2373\0\u01c2\0\u23be\0\u2409\0\u2454\0\u249f\0\u24ea"+ + "\0\u2535\0\u2580\0\u25cb\0\u2616\0\u2661\0\u26ac\0\u0f3c\0\u01c2"+ + "\0\u26f7\0\u1149\0\u11df\0\u2742\0\u278d\0\u27d8\0\u2823\0\u286e"+ + "\0\u28b9\0\u2904\0\u294f\0\u299a\0\u29e5\0\u2a30\0\u2a7b\0\u2ac6"+ + "\0\u2b11\0\u2b5c\0\u1518\0\u2ba7\0\u2bf2\0\u2c3d\0\u2c88\0\u2cd3"+ + "\0\u2d1e\0\u2d69\0\u2db4\0\u2dff\0\u2e4a\0\u2e95\0\u2ee0\0\u0384"+ + "\0\u2f2b\0\u2f76\0\u01c2\0\u2f2b\0\u2fc1\0\u300c\0\u3057\0\u30a2"+ + "\0\u02a3\0\u30ed\0\u02a3\0\u02a3\0\u02a3\0\u3138\0\u3183\0\u31ce"+ + "\0\u3219\0\u3264\0\u02a3\0\u32af\0\u32fa\0\u3345\0\u3390\0\u33db"+ + "\0\u3426\0\u02a3\0\u3471\0\u34bc\0\u3507\0\u3552\0\u359d\0\u01c2"+ + "\0\u01c2\0\u01c2\0\u01c2\0\u35e8\0\u3633\0\u367e\0\u01c2\0\u3633"+ + "\0\u36c9\0\u3714\0\u01c2\0\u375f\0\u37aa\0\u01c2\0\u37f5\0\u2535"+ + "\0\u2661\0\u01c2\0\u375f\0\u3840\0\u01c2\0\u388b\0\u38d6\0\u3921"+ + "\0\u396c\0\u39b7\0\u01c2\0\u3a02\0\u02a3\0\u02a3\0\u3a4d\0\u3a98"+ + "\0\u3ae3\0\u3b2e\0\u3b79\0\u3bc4\0\u3c0f\0\u3c5a\0\u02a3\0\u3ca5"+ + "\0\u02a3\0\u3cf0\0\u3d3b\0\u3d86\0\u3dd1\0\u3e1c\0\u3e67\0\u3eb2"+ + "\0\u3efd\0\u3f48\0\u3f93\0\u3fde\0\u4029\0\u4074\0\u40bf\0\u38d6"+ + "\0\u3921\0\u410a\0\u4155\0\u41a0\0\u02a3\0\u41eb\0\u02a3\0\u02a3"+ + "\0\u4236\0\u4281\0\u42cc\0\u4317\0\u02a3\0\u4362\0\u02a3\0\u43ad"+ + "\0\u3e1c\0\u3e67\0\u43f8\0\u4443\0\u448e\0\u44d9\0\u4524\0\u02a3"+ + "\0\u02a3\0\u02a3\0\u456f\0\u02a3\0\u02a3\0\u45ba\0\u02a3\0\u3633"+ + "\0\u01c2\0\u01c2\0\u01c2\0\u4524\0\u01c2\0\u4605\0\u02a3\0\u02a3"; private static int [] zzUnpackRowMap() { - int [] result = new int[350]; + int [] result = new int[344]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -322,340 +320,339 @@ class _PythonLexer implements FlexLexer { "\1\12\1\61\1\62\1\63\1\64\1\65\1\66\1\67"+ "\1\70\1\71\1\72\1\73\1\74\1\75\1\7\11\76"+ "\1\77\1\76\1\100\1\0\6\76\2\77\1\101\1\20"+ - "\1\102\5\76\1\27\1\30\1\31\5\76\1\103\6\76"+ - "\1\77\1\76\1\77\1\76\1\77\3\76\1\77\25\76"+ - "\1\0\1\7\1\10\2\11\1\12\1\11\3\12\1\104"+ - "\1\12\1\100\1\7\1\12\1\7\1\15\1\12\1\16"+ - "\1\12\2\104\1\105\1\20\1\106\1\22\1\23\1\24"+ - "\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34"+ - "\1\35\1\107\1\103\1\40\1\41\1\42\1\43\1\12"+ - "\1\44\1\110\1\46\1\111\1\12\1\112\1\51\1\52"+ - "\1\53\1\104\1\54\1\12\1\55\1\56\1\12\1\57"+ - "\1\60\1\12\1\61\1\62\1\63\1\64\1\65\1\66"+ - "\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\7"+ - "\13\113\1\114\1\0\10\113\1\115\1\116\1\117\1\113"+ - "\1\120\3\113\1\121\1\122\1\123\5\113\1\103\45\113"+ - "\1\7\1\10\2\11\1\12\1\11\3\12\1\124\1\12"+ + "\1\102\12\76\1\34\1\35\1\36\1\103\6\76\1\77"+ + "\1\76\1\77\1\76\1\77\3\76\1\77\25\76\1\0"+ + "\1\7\1\10\2\11\1\12\1\11\3\12\1\104\1\12"+ "\1\100\1\7\1\12\1\7\1\15\1\12\1\16\1\12"+ - "\2\124\1\125\1\20\1\126\1\22\1\127\1\130\1\131"+ - "\1\26\1\27\1\30\1\31\1\132\1\133\1\134\1\135"+ - "\1\136\1\103\1\40\1\41\1\42\1\43\1\12\1\44"+ - "\1\137\1\46\1\140\1\12\1\141\1\51\1\52\1\53"+ - "\1\124\1\54\1\12\1\55\1\56\1\12\1\57\1\60"+ + "\2\104\1\105\1\20\1\106\1\22\1\23\1\24\1\25"+ + "\1\26\1\27\1\30\1\31\1\32\1\107\1\34\1\35"+ + "\1\36\1\103\1\40\1\41\1\42\1\43\1\12\1\44"+ + "\1\110\1\46\1\111\1\12\1\112\1\51\1\52\1\53"+ + "\1\104\1\54\1\12\1\55\1\56\1\12\1\57\1\60"+ "\1\12\1\61\1\62\1\63\1\64\1\65\1\66\1\67"+ - "\1\70\1\71\1\72\1\73\1\74\1\75\1\7\13\142"+ - "\1\143\1\0\10\142\1\144\1\145\2\142\1\146\1\130"+ - "\2\142\1\147\1\150\1\151\5\142\1\103\45\142\114\0"+ - "\1\152\1\153\1\152\1\0\1\152\1\154\1\155\1\156"+ - "\1\157\1\160\4\0\1\161\1\162\1\0\1\163\30\0"+ - "\1\162\2\0\1\157\2\0\1\160\1\156\3\0\1\154"+ - "\25\0\3\11\1\0\1\11\1\0\1\164\2\0\1\160"+ - "\4\0\1\161\1\162\1\0\1\163\30\0\1\162\5\0"+ - "\1\160\32\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\26\12\17\0\10\12\1\165"+ - "\1\12\2\0\2\12\1\0\1\12\1\0\1\12\2\165"+ - "\1\17\1\0\1\21\1\22\16\0\5\12\1\165\1\12"+ - "\1\165\1\12\1\165\3\12\1\165\1\22\7\12\16\0"+ - "\14\14\1\0\30\14\1\0\45\14\1\0\3\166\1\0"+ - "\1\166\141\0\1\167\50\0\1\170\5\0\14\171\1\0"+ - "\10\171\1\172\1\173\16\171\1\174\45\171\14\175\1\0"+ - "\11\175\1\176\1\177\15\175\1\174\45\175\1\0\10\12"+ - "\1\200\1\12\2\0\2\12\1\0\1\12\1\0\1\12"+ - "\2\200\1\201\1\0\1\202\1\12\16\0\5\12\1\200"+ - "\1\12\1\200\1\12\1\200\3\12\1\200\10\12\52\0"+ - "\1\203\112\0\1\204\57\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\1\12\1\205"+ - "\1\12\1\206\22\12\17\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\13\12\1\207"+ - "\12\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\4\12\1\210\21\12\17\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ - "\1\12\16\0\12\12\1\211\4\12\1\212\6\12\17\0"+ - "\10\12\1\165\1\12\2\0\2\12\1\0\1\12\1\0"+ - "\1\12\2\165\1\17\1\0\1\21\1\22\16\0\1\213"+ - "\3\12\1\214\1\165\1\12\1\165\1\12\1\165\3\12"+ - "\1\165\1\22\7\12\17\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\5\12\1\215"+ - "\20\12\17\0\10\12\1\165\1\12\2\0\2\12\1\0"+ - "\1\12\1\0\1\12\2\165\1\17\1\0\1\21\1\22"+ - "\16\0\5\12\1\216\1\12\1\165\1\12\1\165\3\12"+ - "\1\165\1\22\7\12\17\0\10\12\1\165\1\12\2\0"+ - "\2\12\1\0\1\12\1\0\1\12\2\165\1\17\1\0"+ - "\1\21\1\22\16\0\5\12\1\165\1\12\1\165\1\12"+ - "\1\165\1\217\1\220\1\12\1\165\1\22\7\12\17\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ - "\1\12\16\0\1\221\25\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\5\12"+ - "\1\222\20\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\1\12\1\223\1\12"+ - "\1\224\12\12\1\225\3\12\1\226\3\12\17\0\10\12"+ - "\1\200\1\12\2\0\2\12\1\0\1\12\1\0\1\12"+ - "\2\200\1\201\1\0\1\202\1\12\16\0\5\12\1\227"+ - "\1\12\1\200\1\12\1\200\1\12\1\230\1\231\1\200"+ - "\10\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\1\232\25\12\17\0\12\12"+ - "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\14\12\1\233\11\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\12\12"+ - "\1\234\13\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\25\12\1\235\52\0"+ - "\1\236\112\0\1\237\41\0\1\240\50\0\1\241\112\0"+ - "\1\242\43\0\1\243\46\0\1\244\112\0\1\245\112\0"+ - "\1\246\112\0\1\247\112\0\1\250\50\0\1\251\41\0"+ - "\1\252\50\0\1\253\1\254\15\0\1\255\11\0\2\255"+ - "\1\101\1\0\1\102\24\0\1\255\1\0\1\255\1\0"+ - "\1\255\3\0\1\255\26\0\14\100\1\0\30\100\1\0"+ - "\45\100\14\256\1\0\10\256\1\257\1\260\16\256\1\261"+ - "\45\256\14\262\1\0\11\262\1\263\1\264\15\262\1\261"+ - "\45\262\1\0\10\12\1\265\1\12\2\0\2\12\1\0"+ - "\1\12\1\0\1\12\2\265\1\105\1\0\1\106\1\22"+ - "\16\0\5\12\1\265\1\12\1\265\1\12\1\265\3\12"+ - "\1\265\1\22\7\12\16\0\14\266\1\0\10\266\1\267"+ - "\1\270\16\266\1\0\45\266\14\271\1\0\11\271\1\272"+ - "\1\273\15\271\1\0\45\271\13\0\1\274\21\0\1\275"+ - "\7\0\1\276\46\0\10\12\1\265\1\12\2\0\2\12"+ - "\1\0\1\12\1\0\1\12\2\265\1\105\1\0\1\106"+ - "\1\22\16\0\1\213\3\12\1\214\1\265\1\12\1\265"+ - "\1\12\1\265\3\12\1\265\1\22\7\12\17\0\10\12"+ - "\1\265\1\12\2\0\2\12\1\0\1\12\1\0\1\12"+ - "\2\265\1\105\1\0\1\106\1\22\16\0\5\12\1\277"+ - "\1\12\1\265\1\12\1\265\3\12\1\265\1\22\7\12"+ - "\17\0\10\12\1\265\1\12\2\0\2\12\1\0\1\12"+ - "\1\0\1\12\2\265\1\105\1\0\1\106\1\22\16\0"+ - "\5\12\1\265\1\12\1\265\1\12\1\265\1\217\1\220"+ - "\1\12\1\265\1\22\7\12\16\0\14\113\1\0\10\113"+ - "\1\0\1\300\1\0\1\113\1\301\13\113\1\0\45\113"+ - "\14\114\1\0\10\114\1\100\1\302\1\100\1\114\1\303"+ - "\13\114\1\0\45\114\25\0\1\304\65\0\113\113\27\0"+ - "\1\305\114\0\1\113\62\0\10\12\1\306\1\12\2\0"+ - "\2\12\1\0\1\12\1\0\1\12\2\306\1\307\1\0"+ - "\1\310\1\22\16\0\5\12\1\306\1\12\1\306\1\12"+ - "\1\306\3\12\1\306\1\22\7\12\16\0\14\311\1\0"+ - "\10\311\1\312\1\313\16\311\1\0\45\311\14\314\1\0"+ - "\11\314\1\315\1\316\15\314\1\0\45\314\14\317\1\0"+ - "\10\317\1\0\1\317\1\0\2\317\1\0\1\317\1\203"+ - "\2\0\5\317\2\0\45\317\1\0\10\12\1\306\1\12"+ - "\2\0\2\12\1\0\1\12\1\0\1\12\2\306\1\307"+ - "\1\0\1\310\1\22\16\0\1\213\3\12\1\214\1\306"+ - "\1\12\1\306\1\12\1\306\3\12\1\306\1\22\7\12"+ - "\17\0\10\12\1\306\1\12\2\0\2\12\1\0\1\12"+ - "\1\0\1\12\2\306\1\307\1\0\1\310\1\22\16\0"+ - "\5\12\1\320\1\12\1\306\1\12\1\306\3\12\1\306"+ - "\1\22\7\12\17\0\10\12\1\306\1\12\2\0\2\12"+ - "\1\0\1\12\1\0\1\12\2\306\1\307\1\0\1\310"+ - "\1\22\16\0\5\12\1\306\1\12\1\306\1\12\1\306"+ - "\1\217\1\220\1\12\1\306\1\22\7\12\16\0\14\142"+ - "\1\0\10\142\1\0\1\321\2\142\2\0\12\142\1\0"+ - "\45\142\14\143\1\0\10\143\1\100\1\322\2\143\2\100"+ - "\12\143\1\0\45\143\25\0\1\323\101\0\1\142\30\0"+ - "\1\142\46\0\1\152\1\153\1\152\1\0\1\152\1\0"+ - "\1\155\2\0\1\160\4\0\1\161\1\162\1\0\1\163"+ - "\30\0\1\162\5\0\1\160\32\0\3\153\1\0\1\153"+ - "\1\0\1\324\7\0\1\161\1\162\1\0\1\163\30\0"+ - "\1\162\40\0\5\325\1\0\1\326\1\0\1\325\6\0"+ - "\1\325\2\0\1\325\4\0\1\325\16\0\1\325\1\0"+ - "\1\325\1\0\1\325\2\0\1\325\1\0\1\325\4\0"+ - "\1\325\26\0\1\152\1\153\1\152\1\0\1\152\106\0"+ - "\1\327\1\0\1\327\1\0\1\327\1\0\1\330\104\0"+ - "\1\331\3\0\1\331\1\0\1\332\104\0\3\166\1\0"+ - "\1\166\12\0\1\162\1\0\1\163\30\0\1\162\40\0"+ - "\3\333\1\0\1\333\13\0\1\334\53\0\1\334\16\0"+ - "\3\11\1\0\1\11\106\0\10\12\1\335\1\12\2\0"+ - "\2\12\1\0\1\12\1\0\1\12\2\335\1\17\1\0"+ - "\1\21\1\22\16\0\5\12\1\335\1\12\1\335\1\12"+ - "\1\335\3\12\1\335\1\22\7\12\17\0\3\166\1\0"+ - "\1\166\1\0\1\336\10\0\1\162\1\0\1\163\30\0"+ - "\1\162\37\0\14\171\1\0\10\171\1\337\1\173\16\171"+ - "\1\174\45\171\25\0\1\340\1\341\6\0\2\342\6\0"+ - "\2\174\44\0\113\171\14\175\1\0\11\175\1\176\1\337"+ - "\15\175\1\174\160\175\26\0\1\341\1\343\5\0\2\342"+ - "\6\0\2\174\45\0\10\12\1\344\1\12\2\0\2\12"+ - "\1\0\1\12\1\0\1\12\2\344\1\201\1\0\1\202"+ - "\1\12\16\0\5\12\1\344\1\12\1\344\1\12\1\344"+ - "\3\12\1\344\10\12\43\0\1\345\114\0\1\346\64\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ - "\1\12\16\0\2\12\1\347\23\12\17\0\12\12\2\0"+ - "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ - "\3\12\1\350\22\12\17\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\6\12\1\351"+ - "\17\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\12\12\1\352\3\12\1\353"+ - "\7\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\3\12\1\354\10\12\1\355"+ - "\11\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\11\12\1\356\14\12\17\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ - "\1\12\16\0\14\12\1\357\11\12\17\0\12\12\2\0"+ - "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ - "\6\12\1\360\17\12\17\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\21\12\1\361"+ - "\4\12\17\0\10\12\1\335\1\12\2\0\2\12\1\0"+ - "\1\12\1\0\1\12\2\335\1\17\1\0\1\21\1\22"+ - "\16\0\4\12\1\362\1\335\1\12\1\335\1\12\1\335"+ - "\3\12\1\335\1\22\7\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\1\363"+ - "\25\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\1\12\1\364\24\12\17\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ - "\1\12\16\0\22\12\1\365\3\12\17\0\12\12\2\0"+ - "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ - "\20\12\1\366\5\12\17\0\10\12\1\344\1\12\2\0"+ - "\2\12\1\0\1\12\1\0\1\12\2\344\1\201\1\0"+ - "\1\202\1\12\16\0\5\12\1\344\1\12\1\344\1\12"+ - "\1\344\1\12\1\367\1\12\1\344\10\12\17\0\12\12"+ - "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\5\12\1\370\20\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\1\12"+ - "\1\371\24\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\3\12\1\372\22\12"+ + "\1\70\1\71\1\72\1\73\1\74\1\75\1\7\13\113"+ + "\1\114\1\0\10\113\1\115\1\116\1\117\1\113\1\120"+ + "\13\113\1\103\45\113\1\7\1\10\2\11\1\12\1\11"+ + "\3\12\1\121\1\12\1\100\1\7\1\12\1\7\1\15"+ + "\1\12\1\16\1\12\2\121\1\122\1\20\1\123\1\22"+ + "\1\124\1\125\1\126\1\26\1\127\1\130\1\131\1\132"+ + "\1\133\1\34\1\35\1\36\1\103\1\40\1\41\1\42"+ + "\1\43\1\12\1\44\1\134\1\46\1\135\1\12\1\136"+ + "\1\51\1\52\1\53\1\121\1\54\1\12\1\55\1\56"+ + "\1\12\1\57\1\60\1\12\1\61\1\62\1\63\1\64"+ + "\1\65\1\66\1\67\1\70\1\71\1\72\1\73\1\74"+ + "\1\75\1\7\13\137\1\140\1\0\10\137\1\141\1\142"+ + "\2\137\1\143\1\125\12\137\1\103\45\137\114\0\1\144"+ + "\1\145\1\144\1\0\1\144\1\146\1\147\1\150\1\151"+ + "\1\152\4\0\1\153\1\154\1\0\1\155\30\0\1\154"+ + "\2\0\1\151\2\0\1\152\1\150\3\0\1\146\25\0"+ + "\3\11\1\0\1\11\1\0\1\156\2\0\1\152\4\0"+ + "\1\153\1\154\1\0\1\155\30\0\1\154\5\0\1\152"+ + "\32\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\26\12\17\0\10\12\1\157\1\12"+ + "\2\0\2\12\1\0\1\12\1\0\1\12\2\157\1\17"+ + "\1\0\1\21\1\22\16\0\5\12\1\157\1\12\1\157"+ + "\1\12\1\157\3\12\1\157\1\22\7\12\16\0\14\14"+ + "\1\0\30\14\1\0\45\14\1\0\3\160\1\0\1\160"+ + "\141\0\1\161\50\0\1\162\5\0\14\163\1\0\10\163"+ + "\1\164\1\165\16\163\1\166\45\163\14\167\1\0\11\167"+ + "\1\170\1\171\15\167\1\166\45\167\1\0\10\12\1\172"+ + "\1\12\2\0\2\12\1\0\1\12\1\0\1\12\2\172"+ + "\1\173\1\0\1\174\1\12\16\0\5\12\1\172\1\12"+ + "\1\172\1\12\1\172\3\12\1\172\10\12\52\0\1\175"+ + "\112\0\1\176\57\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\1\12\1\177\1\12"+ + "\1\200\22\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\13\12\1\201\12\12"+ "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\3\0\1\12\16\0\4\12\1\373\21\12\17\0\12\12"+ + "\3\0\1\12\16\0\4\12\1\202\21\12\17\0\12\12"+ "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\13\12\1\374\12\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\14\12"+ - "\1\375\11\12\52\0\1\376\112\0\1\377\112\0\1\u0100"+ - "\112\0\1\u0101\67\0\1\u0102\11\0\2\u0102\1\101\1\0"+ - "\1\102\24\0\1\u0102\1\0\1\u0102\1\0\1\u0102\3\0"+ - "\1\u0102\26\0\14\256\1\0\10\256\1\u0103\1\260\16\256"+ - "\1\261\45\256\25\0\1\u0104\1\u0105\6\0\2\u0106\6\0"+ - "\2\261\44\0\113\256\14\262\1\0\11\262\1\263\1\u0103"+ - "\15\262\1\261\160\262\26\0\1\u0105\1\u0107\5\0\2\u0106"+ - "\6\0\2\261\45\0\10\12\1\u0108\1\12\2\0\2\12"+ - "\1\0\1\12\1\0\1\12\2\u0108\1\105\1\0\1\106"+ - "\1\22\16\0\5\12\1\u0108\1\12\1\u0108\1\12\1\u0108"+ - "\3\12\1\u0108\1\22\7\12\16\0\14\266\1\0\10\266"+ - "\1\u0109\1\270\16\266\1\0\45\266\25\0\1\u010a\65\0"+ - "\113\266\14\271\1\0\11\271\1\272\1\u0109\15\271\1\0"+ - "\160\271\27\0\1\u010b\63\0\14\274\1\0\30\274\1\276"+ - "\45\274\1\0\10\12\1\u0108\1\12\2\0\2\12\1\0"+ - "\1\12\1\0\1\12\2\u0108\1\105\1\0\1\106\1\22"+ - "\16\0\4\12\1\362\1\u0108\1\12\1\u0108\1\12\1\u0108"+ - "\3\12\1\u0108\1\22\7\12\16\0\14\114\1\113\30\114"+ - "\1\113\45\114\14\100\1\0\14\100\1\114\13\100\1\0"+ - "\45\100\25\0\1\u010c\114\0\1\u010c\64\0\10\12\1\u010d"+ - "\1\12\2\0\2\12\1\0\1\12\1\0\1\12\2\u010d"+ - "\1\307\1\0\1\310\1\22\16\0\5\12\1\u010d\1\12"+ - "\1\u010d\1\12\1\u010d\3\12\1\u010d\1\22\7\12\16\0"+ - "\14\311\1\0\10\311\1\u010e\1\313\16\311\1\0\45\311"+ - "\14\314\1\0\11\314\1\315\1\u010f\15\314\1\0\45\314"+ - "\14\311\1\0\10\311\1\u0110\1\313\16\311\1\0\45\311"+ - "\25\0\1\u0111\65\0\113\311\14\314\1\0\11\314\1\315"+ - "\1\u0110\15\314\1\0\160\314\27\0\1\u0112\63\0\14\317"+ - "\1\0\10\317\1\0\1\317\1\0\2\317\1\0\1\317"+ - "\3\0\5\317\2\0\45\317\1\0\10\12\1\u010d\1\12"+ - "\2\0\2\12\1\0\1\12\1\0\1\12\2\u010d\1\307"+ - "\1\0\1\310\1\22\16\0\4\12\1\362\1\u010d\1\12"+ - "\1\u010d\1\12\1\u010d\3\12\1\u010d\1\22\7\12\16\0"+ - "\14\100\1\142\30\100\1\142\45\100\25\0\1\u0113\66\0"+ - "\3\153\1\0\1\153\106\0\5\325\1\0\1\326\1\0"+ - "\1\325\1\160\5\0\1\325\2\0\1\325\4\0\1\325"+ - "\16\0\1\325\1\0\1\325\1\0\1\325\2\0\1\325"+ - "\1\0\1\325\1\160\3\0\1\325\26\0\5\325\3\0"+ - "\1\325\6\0\1\325\2\0\1\325\4\0\1\325\16\0"+ - "\1\325\1\0\1\325\1\0\1\325\2\0\1\325\1\0"+ - "\1\325\4\0\1\325\26\0\1\327\1\0\1\327\1\0"+ - "\1\327\1\0\1\330\2\0\1\160\46\0\1\160\32\0"+ - "\1\327\1\0\1\327\1\0\1\327\106\0\1\331\3\0"+ - "\1\331\1\0\1\332\2\0\1\160\46\0\1\160\32\0"+ - "\1\331\3\0\1\331\106\0\3\333\1\0\1\333\1\0"+ - "\1\334\12\0\1\163\71\0\3\333\1\0\1\333\106\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\1\17"+ - "\1\0\1\21\1\22\16\0\16\12\1\22\7\12\44\0"+ - "\1\341\6\0\2\342\6\0\2\174\44\0\25\340\1\u0114"+ - "\1\u0115\64\340\26\343\1\u0116\1\u0117\63\343\1\0\10\12"+ - "\1\u0118\1\12\2\0\2\12\1\0\1\12\1\0\1\12"+ - "\2\u0118\1\201\1\0\1\202\1\12\16\0\5\12\1\u0118"+ - "\1\12\1\u0118\1\12\1\u0118\3\12\1\u0118\10\12\43\0"+ - "\1\u0119\114\0\1\u0119\64\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\4\12\1\u011a"+ - "\21\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\4\12\1\u011b\21\12\17\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ - "\1\12\16\0\16\12\1\u011c\7\12\17\0\12\12\2\0"+ + "\16\0\12\12\1\203\4\12\1\204\6\12\17\0\10\12"+ + "\1\157\1\12\2\0\2\12\1\0\1\12\1\0\1\12"+ + "\2\157\1\17\1\0\1\21\1\22\16\0\1\205\3\12"+ + "\1\206\1\157\1\12\1\157\1\12\1\157\3\12\1\157"+ + "\1\22\7\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\5\12\1\207\20\12"+ + "\17\0\10\12\1\157\1\12\2\0\2\12\1\0\1\12"+ + "\1\0\1\12\2\157\1\17\1\0\1\21\1\22\16\0"+ + "\5\12\1\210\1\12\1\157\1\12\1\157\3\12\1\157"+ + "\1\22\7\12\17\0\10\12\1\157\1\12\2\0\2\12"+ + "\1\0\1\12\1\0\1\12\2\157\1\17\1\0\1\21"+ + "\1\22\16\0\5\12\1\157\1\12\1\157\1\12\1\157"+ + "\1\211\1\212\1\12\1\157\1\22\7\12\17\0\12\12"+ + "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ + "\16\0\1\213\25\12\17\0\12\12\2\0\2\12\1\0"+ + "\1\12\1\0\3\12\3\0\1\12\16\0\5\12\1\214"+ + "\20\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\3\0\1\12\16\0\1\12\1\215\1\12\1\216"+ + "\12\12\1\217\3\12\1\220\3\12\17\0\10\12\1\172"+ + "\1\12\2\0\2\12\1\0\1\12\1\0\1\12\2\172"+ + "\1\173\1\0\1\174\1\12\16\0\5\12\1\221\1\12"+ + "\1\172\1\12\1\172\1\12\1\222\1\223\1\172\10\12"+ + "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\1\224\25\12\17\0\12\12\2\0"+ "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ - "\4\12\1\u011d\21\12\17\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\3\12\1\u011e"+ - "\22\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\15\12\1\u011f\10\12\17\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ - "\1\12\16\0\1\u0120\25\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\3\12"+ - "\1\u0121\22\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\6\12\1\u0122\17\12"+ - "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\3\0\1\12\16\0\7\12\1\u0123\16\12\17\0\12\12"+ - "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\13\12\1\u0124\12\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\22\12"+ - "\1\u0125\3\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\1\u0126\25\12\17\0"+ - "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ - "\1\12\16\0\3\12\1\u0127\22\12\17\0\12\12\2\0"+ - "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ - "\12\12\1\u0128\13\12\17\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\7\12\1\u0129"+ - "\16\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\12\12\1\u012a\13\12\43\0"+ - "\1\101\1\0\1\102\111\0\1\u0105\6\0\2\u0106\6\0"+ - "\2\261\44\0\25\u0104\1\u012b\1\u012c\64\u0104\26\u0107\1\u012d"+ - "\1\u012e\63\u0107\1\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\1\105\1\0\1\106\1\22\16\0\16\12"+ - "\1\22\7\12\16\0\25\u010a\1\u012f\1\u0130\64\u010a\26\u010b"+ - "\1\u0131\1\u0132\63\u010b\1\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\1\307\1\0\1\310\1\22\16\0"+ - "\16\12\1\22\7\12\16\0\26\u0112\1\u0133\1\u0134\63\u0112"+ - "\25\340\1\u0135\1\u0136\177\340\141\343\1\u0137\1\u0138\63\343"+ - "\1\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\1\201\1\0\1\202\1\12\16\0\26\12\17\0\12\12"+ - "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\5\12\1\u0139\20\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\20\12"+ - "\1\u013a\5\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\4\12\1\u013b\21\12"+ - "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\3\0\1\12\16\0\5\12\1\u013c\20\12\17\0\12\12"+ - "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\10\12\1\u013d\15\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\3\12"+ - "\1\u013e\22\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\14\12\1\u013f\11\12"+ - "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\3\0\1\12\16\0\2\12\1\u0140\23\12\17\0\12\12"+ - "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\5\12\1\u0141\20\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\12\12"+ - "\1\u0142\13\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\2\12\1\u0143\23\12"+ - "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\3\0\1\12\16\0\1\u0144\25\12\17\0\12\12\2\0"+ - "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ - "\4\12\1\u0145\21\12\16\0\25\u0104\1\u0146\1\u0147\177\u0104"+ - "\141\u0107\1\u0148\1\u0149\63\u0107\25\u010a\1\u014a\1\u0130\177\u010a"+ - "\141\u010b\1\u0131\1\u014b\63\u010b\141\u0112\1\u0133\1\u014c\63\u0112"+ - "\25\340\1\u014d\1\u0136\64\340\26\343\1\u0137\1\u014d\63\343"+ - "\1\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\3\0\1\12\16\0\6\12\1\u014e\17\12\17\0\12\12"+ - "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\6\12\1\u014f\17\12\17\0\12\12\2\0\2\12"+ - "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\1\12"+ - "\1\u0150\24\12\17\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\1\12\1\u0151\24\12"+ - "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\3\0\1\12\16\0\1\u0152\25\12\17\0\12\12\2\0"+ - "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ - "\6\12\1\u0153\17\12\17\0\12\12\2\0\2\12\1\0"+ - "\1\12\1\0\3\12\3\0\1\12\16\0\12\12\1\u0154"+ + "\14\12\1\225\11\12\17\0\12\12\2\0\2\12\1\0"+ + "\1\12\1\0\3\12\3\0\1\12\16\0\12\12\1\226"+ "\13\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ - "\3\12\3\0\1\12\16\0\12\12\1\u0155\13\12\16\0"+ - "\25\u0104\1\u0156\1\u0147\64\u0104\26\u0107\1\u0148\1\u0156\63\u0107"+ - "\25\u010a\1\u0157\1\u0130\64\u010a\26\u010b\1\u0131\1\u0157\63\u010b"+ - "\26\u0112\1\u0133\1\u0158\63\u0112\26\0\1\u0159\6\0\2\u015a"+ - "\6\0\2\u015b\45\0\12\12\2\0\2\12\1\0\1\12"+ - "\1\0\3\12\3\0\1\12\16\0\15\12\1\u015c\10\12"+ - "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ - "\3\0\1\12\16\0\21\12\1\u015d\4\12\17\0\12\12"+ + "\3\12\3\0\1\12\16\0\25\12\1\227\52\0\1\230"+ + "\112\0\1\231\41\0\1\232\50\0\1\233\112\0\1\234"+ + "\43\0\1\235\46\0\1\236\112\0\1\237\112\0\1\240"+ + "\112\0\1\241\112\0\1\242\50\0\1\243\41\0\1\244"+ + "\50\0\1\245\1\246\15\0\1\247\11\0\2\247\1\101"+ + "\1\0\1\102\24\0\1\247\1\0\1\247\1\0\1\247"+ + "\3\0\1\247\26\0\14\100\1\0\30\100\1\0\45\100"+ + "\14\250\1\0\10\250\1\251\1\252\16\250\1\253\45\250"+ + "\14\254\1\0\11\254\1\255\1\256\15\254\1\253\45\254"+ + "\1\0\10\12\1\257\1\12\2\0\2\12\1\0\1\12"+ + "\1\0\1\12\2\257\1\105\1\0\1\106\1\22\16\0"+ + "\5\12\1\257\1\12\1\257\1\12\1\257\3\12\1\257"+ + "\1\22\7\12\16\0\14\260\1\0\10\260\1\261\1\262"+ + "\16\260\1\0\45\260\14\263\1\0\11\263\1\264\1\265"+ + "\15\263\1\0\45\263\13\0\1\266\26\0\1\267\2\0"+ + "\1\270\46\0\10\12\1\257\1\12\2\0\2\12\1\0"+ + "\1\12\1\0\1\12\2\257\1\105\1\0\1\106\1\22"+ + "\16\0\1\205\3\12\1\206\1\257\1\12\1\257\1\12"+ + "\1\257\3\12\1\257\1\22\7\12\17\0\10\12\1\257"+ + "\1\12\2\0\2\12\1\0\1\12\1\0\1\12\2\257"+ + "\1\105\1\0\1\106\1\22\16\0\5\12\1\271\1\12"+ + "\1\257\1\12\1\257\3\12\1\257\1\22\7\12\17\0"+ + "\10\12\1\257\1\12\2\0\2\12\1\0\1\12\1\0"+ + "\1\12\2\257\1\105\1\0\1\106\1\22\16\0\5\12"+ + "\1\257\1\12\1\257\1\12\1\257\1\211\1\212\1\12"+ + "\1\257\1\22\7\12\16\0\14\113\1\0\10\113\1\0"+ + "\1\272\1\0\1\113\1\273\13\113\1\0\45\113\14\114"+ + "\1\0\10\114\1\100\1\274\1\100\1\114\1\275\13\114"+ + "\1\0\45\114\25\0\1\276\65\0\113\113\27\0\1\277"+ + "\114\0\1\113\62\0\10\12\1\300\1\12\2\0\2\12"+ + "\1\0\1\12\1\0\1\12\2\300\1\301\1\0\1\302"+ + "\1\22\16\0\5\12\1\300\1\12\1\300\1\12\1\300"+ + "\3\12\1\300\1\22\7\12\16\0\14\303\1\0\10\303"+ + "\1\304\1\305\16\303\1\0\45\303\14\306\1\0\11\306"+ + "\1\307\1\310\15\306\1\0\45\306\14\311\1\0\10\311"+ + "\1\0\1\311\1\0\2\311\1\0\1\311\1\175\4\311"+ + "\3\0\1\311\1\0\45\311\1\0\10\12\1\300\1\12"+ + "\2\0\2\12\1\0\1\12\1\0\1\12\2\300\1\301"+ + "\1\0\1\302\1\22\16\0\1\205\3\12\1\206\1\300"+ + "\1\12\1\300\1\12\1\300\3\12\1\300\1\22\7\12"+ + "\17\0\10\12\1\300\1\12\2\0\2\12\1\0\1\12"+ + "\1\0\1\12\2\300\1\301\1\0\1\302\1\22\16\0"+ + "\5\12\1\312\1\12\1\300\1\12\1\300\3\12\1\300"+ + "\1\22\7\12\17\0\10\12\1\300\1\12\2\0\2\12"+ + "\1\0\1\12\1\0\1\12\2\300\1\301\1\0\1\302"+ + "\1\22\16\0\5\12\1\300\1\12\1\300\1\12\1\300"+ + "\1\211\1\212\1\12\1\300\1\22\7\12\16\0\14\137"+ + "\1\0\10\137\1\0\1\313\2\137\2\0\12\137\1\0"+ + "\45\137\14\140\1\0\10\140\1\100\1\314\2\140\2\100"+ + "\12\140\1\0\45\140\25\0\1\315\101\0\1\137\30\0"+ + "\1\137\46\0\1\144\1\145\1\144\1\0\1\144\1\0"+ + "\1\147\2\0\1\152\4\0\1\153\1\154\1\0\1\155"+ + "\30\0\1\154\5\0\1\152\32\0\3\145\1\0\1\145"+ + "\1\0\1\316\7\0\1\153\1\154\1\0\1\155\30\0"+ + "\1\154\40\0\5\317\1\0\1\320\1\0\1\317\6\0"+ + "\1\317\2\0\1\317\4\0\1\317\16\0\1\317\1\0"+ + "\1\317\1\0\1\317\2\0\1\317\1\0\1\317\4\0"+ + "\1\317\26\0\1\144\1\145\1\144\1\0\1\144\106\0"+ + "\1\321\1\0\1\321\1\0\1\321\1\0\1\322\104\0"+ + "\1\323\3\0\1\323\1\0\1\324\104\0\3\160\1\0"+ + "\1\160\12\0\1\154\1\0\1\155\30\0\1\154\40\0"+ + "\3\325\1\0\1\325\13\0\1\326\53\0\1\326\16\0"+ + "\3\11\1\0\1\11\106\0\10\12\1\327\1\12\2\0"+ + "\2\12\1\0\1\12\1\0\1\12\2\327\1\17\1\0"+ + "\1\21\1\22\16\0\5\12\1\327\1\12\1\327\1\12"+ + "\1\327\3\12\1\327\1\22\7\12\17\0\3\160\1\0"+ + "\1\160\1\0\1\330\10\0\1\154\1\0\1\155\30\0"+ + "\1\154\37\0\14\163\1\0\10\163\1\331\1\165\16\163"+ + "\1\166\45\163\25\0\1\332\1\333\13\0\2\334\1\0"+ + "\2\166\44\0\113\163\14\167\1\0\11\167\1\170\1\331"+ + "\15\167\1\166\160\167\26\0\1\333\1\335\12\0\2\334"+ + "\1\0\2\166\45\0\10\12\1\336\1\12\2\0\2\12"+ + "\1\0\1\12\1\0\1\12\2\336\1\173\1\0\1\174"+ + "\1\12\16\0\5\12\1\336\1\12\1\336\1\12\1\336"+ + "\3\12\1\336\10\12\43\0\1\337\114\0\1\340\64\0"+ + "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ + "\1\12\16\0\2\12\1\341\23\12\17\0\12\12\2\0"+ + "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ + "\3\12\1\342\22\12\17\0\12\12\2\0\2\12\1\0"+ + "\1\12\1\0\3\12\3\0\1\12\16\0\6\12\1\343"+ + "\17\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\3\0\1\12\16\0\12\12\1\344\3\12\1\345"+ + "\7\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\3\0\1\12\16\0\3\12\1\346\10\12\1\347"+ + "\11\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\3\0\1\12\16\0\11\12\1\350\14\12\17\0"+ + "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ + "\1\12\16\0\14\12\1\351\11\12\17\0\12\12\2\0"+ + "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ + "\6\12\1\352\17\12\17\0\12\12\2\0\2\12\1\0"+ + "\1\12\1\0\3\12\3\0\1\12\16\0\21\12\1\353"+ + "\4\12\17\0\10\12\1\327\1\12\2\0\2\12\1\0"+ + "\1\12\1\0\1\12\2\327\1\17\1\0\1\21\1\22"+ + "\16\0\4\12\1\354\1\327\1\12\1\327\1\12\1\327"+ + "\3\12\1\327\1\22\7\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\1\355"+ + "\25\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\3\0\1\12\16\0\1\12\1\356\24\12\17\0"+ + "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ + "\1\12\16\0\22\12\1\357\3\12\17\0\12\12\2\0"+ + "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ + "\20\12\1\360\5\12\17\0\10\12\1\336\1\12\2\0"+ + "\2\12\1\0\1\12\1\0\1\12\2\336\1\173\1\0"+ + "\1\174\1\12\16\0\5\12\1\336\1\12\1\336\1\12"+ + "\1\336\1\12\1\361\1\12\1\336\10\12\17\0\12\12"+ "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ - "\16\0\4\12\1\u015e\21\12\16\0"; + "\16\0\5\12\1\362\20\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\1\12"+ + "\1\363\24\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\3\12\1\364\22\12"+ + "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\4\12\1\365\21\12\17\0\12\12"+ + "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ + "\16\0\13\12\1\366\12\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\14\12"+ + "\1\367\11\12\52\0\1\370\112\0\1\371\112\0\1\372"+ + "\112\0\1\373\67\0\1\374\11\0\2\374\1\101\1\0"+ + "\1\102\24\0\1\374\1\0\1\374\1\0\1\374\3\0"+ + "\1\374\26\0\14\250\1\0\10\250\1\375\1\252\16\250"+ + "\1\253\45\250\25\0\1\376\1\377\13\0\2\u0100\1\0"+ + "\2\253\44\0\113\250\14\254\1\0\11\254\1\255\1\375"+ + "\15\254\1\253\160\254\26\0\1\377\1\u0101\12\0\2\u0100"+ + "\1\0\2\253\45\0\10\12\1\u0102\1\12\2\0\2\12"+ + "\1\0\1\12\1\0\1\12\2\u0102\1\105\1\0\1\106"+ + "\1\22\16\0\5\12\1\u0102\1\12\1\u0102\1\12\1\u0102"+ + "\3\12\1\u0102\1\22\7\12\16\0\14\260\1\0\10\260"+ + "\1\u0103\1\262\16\260\1\0\45\260\25\0\1\u0104\65\0"+ + "\113\260\14\263\1\0\11\263\1\264\1\u0103\15\263\1\0"+ + "\160\263\27\0\1\u0105\63\0\14\266\1\0\30\266\1\270"+ + "\45\266\1\0\10\12\1\u0102\1\12\2\0\2\12\1\0"+ + "\1\12\1\0\1\12\2\u0102\1\105\1\0\1\106\1\22"+ + "\16\0\4\12\1\354\1\u0102\1\12\1\u0102\1\12\1\u0102"+ + "\3\12\1\u0102\1\22\7\12\16\0\14\114\1\113\30\114"+ + "\1\113\45\114\14\100\1\0\14\100\1\114\13\100\1\0"+ + "\45\100\25\0\1\u0106\114\0\1\u0106\64\0\10\12\1\u0107"+ + "\1\12\2\0\2\12\1\0\1\12\1\0\1\12\2\u0107"+ + "\1\301\1\0\1\302\1\22\16\0\5\12\1\u0107\1\12"+ + "\1\u0107\1\12\1\u0107\3\12\1\u0107\1\22\7\12\16\0"+ + "\14\303\1\0\10\303\1\u0108\1\305\16\303\1\0\45\303"+ + "\14\306\1\0\11\306\1\307\1\u0109\15\306\1\0\45\306"+ + "\14\303\1\0\10\303\1\u010a\1\305\16\303\1\0\45\303"+ + "\25\0\1\u010b\65\0\113\303\14\306\1\0\11\306\1\307"+ + "\1\u010a\15\306\1\0\160\306\27\0\1\u010c\63\0\14\311"+ + "\1\0\10\311\1\0\1\311\1\0\2\311\1\0\1\311"+ + "\1\0\4\311\3\0\1\311\1\0\45\311\1\0\10\12"+ + "\1\u0107\1\12\2\0\2\12\1\0\1\12\1\0\1\12"+ + "\2\u0107\1\301\1\0\1\302\1\22\16\0\4\12\1\354"+ + "\1\u0107\1\12\1\u0107\1\12\1\u0107\3\12\1\u0107\1\22"+ + "\7\12\16\0\14\100\1\137\30\100\1\137\45\100\25\0"+ + "\1\u010d\66\0\3\145\1\0\1\145\106\0\5\317\1\0"+ + "\1\320\1\0\1\317\1\152\5\0\1\317\2\0\1\317"+ + "\4\0\1\317\16\0\1\317\1\0\1\317\1\0\1\317"+ + "\2\0\1\317\1\0\1\317\1\152\3\0\1\317\26\0"+ + "\5\317\3\0\1\317\6\0\1\317\2\0\1\317\4\0"+ + "\1\317\16\0\1\317\1\0\1\317\1\0\1\317\2\0"+ + "\1\317\1\0\1\317\4\0\1\317\26\0\1\321\1\0"+ + "\1\321\1\0\1\321\1\0\1\322\2\0\1\152\46\0"+ + "\1\152\32\0\1\321\1\0\1\321\1\0\1\321\106\0"+ + "\1\323\3\0\1\323\1\0\1\324\2\0\1\152\46\0"+ + "\1\152\32\0\1\323\3\0\1\323\106\0\3\325\1\0"+ + "\1\325\1\0\1\326\12\0\1\155\71\0\3\325\1\0"+ + "\1\325\106\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\1\17\1\0\1\21\1\22\16\0\16\12\1\22"+ + "\7\12\44\0\1\333\13\0\2\334\1\0\2\166\44\0"+ + "\25\332\1\u010e\1\u010f\64\332\26\335\1\u0110\1\u0111\63\335"+ + "\1\0\10\12\1\u0112\1\12\2\0\2\12\1\0\1\12"+ + "\1\0\1\12\2\u0112\1\173\1\0\1\174\1\12\16\0"+ + "\5\12\1\u0112\1\12\1\u0112\1\12\1\u0112\3\12\1\u0112"+ + "\10\12\43\0\1\u0113\114\0\1\u0113\64\0\12\12\2\0"+ + "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ + "\4\12\1\u0114\21\12\17\0\12\12\2\0\2\12\1\0"+ + "\1\12\1\0\3\12\3\0\1\12\16\0\4\12\1\u0115"+ + "\21\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\3\0\1\12\16\0\16\12\1\u0116\7\12\17\0"+ + "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ + "\1\12\16\0\4\12\1\u0117\21\12\17\0\12\12\2\0"+ + "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ + "\3\12\1\u0118\22\12\17\0\12\12\2\0\2\12\1\0"+ + "\1\12\1\0\3\12\3\0\1\12\16\0\15\12\1\u0119"+ + "\10\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\3\0\1\12\16\0\1\u011a\25\12\17\0\12\12"+ + "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ + "\16\0\3\12\1\u011b\22\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\6\12"+ + "\1\u011c\17\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\7\12\1\u011d\16\12"+ + "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\13\12\1\u011e\12\12\17\0\12\12"+ + "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ + "\16\0\22\12\1\u011f\3\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\1\u0120"+ + "\25\12\17\0\12\12\2\0\2\12\1\0\1\12\1\0"+ + "\3\12\3\0\1\12\16\0\3\12\1\u0121\22\12\17\0"+ + "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ + "\1\12\16\0\12\12\1\u0122\13\12\17\0\12\12\2\0"+ + "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ + "\7\12\1\u0123\16\12\17\0\12\12\2\0\2\12\1\0"+ + "\1\12\1\0\3\12\3\0\1\12\16\0\12\12\1\u0124"+ + "\13\12\43\0\1\101\1\0\1\102\111\0\1\377\13\0"+ + "\2\u0100\1\0\2\253\44\0\25\376\1\u0125\1\u0126\64\376"+ + "\26\u0101\1\u0127\1\u0128\63\u0101\1\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\1\105\1\0\1\106\1\22"+ + "\16\0\16\12\1\22\7\12\16\0\25\u0104\1\u0129\1\u012a"+ + "\64\u0104\26\u0105\1\u012b\1\u012c\63\u0105\1\0\12\12\2\0"+ + "\2\12\1\0\1\12\1\0\3\12\1\301\1\0\1\302"+ + "\1\22\16\0\16\12\1\22\7\12\16\0\26\u010c\1\u012d"+ + "\1\u012e\63\u010c\25\332\1\u012f\1\u0130\177\332\141\335\1\u0131"+ + "\1\u0132\63\335\1\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\1\173\1\0\1\174\1\12\16\0\26\12"+ + "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\5\12\1\u0133\20\12\17\0\12\12"+ + "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ + "\16\0\20\12\1\u0134\5\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\4\12"+ + "\1\u0135\21\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\5\12\1\u0136\20\12"+ + "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\10\12\1\u0137\15\12\17\0\12\12"+ + "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ + "\16\0\3\12\1\u0138\22\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\14\12"+ + "\1\u0139\11\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\2\12\1\u013a\23\12"+ + "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\5\12\1\u013b\20\12\17\0\12\12"+ + "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ + "\16\0\12\12\1\u013c\13\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\2\12"+ + "\1\u013d\23\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\1\u013e\25\12\17\0"+ + "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ + "\1\12\16\0\4\12\1\u013f\21\12\16\0\25\376\1\u0140"+ + "\1\u0141\177\376\141\u0101\1\u0142\1\u0143\63\u0101\25\u0104\1\u0144"+ + "\1\u012a\177\u0104\141\u0105\1\u012b\1\u0145\63\u0105\141\u010c\1\u012d"+ + "\1\u0146\63\u010c\25\332\1\u0147\1\u0130\64\332\26\335\1\u0131"+ + "\1\u0147\63\335\1\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\6\12\1\u0148\17\12"+ + "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\6\12\1\u0149\17\12\17\0\12\12"+ + "\2\0\2\12\1\0\1\12\1\0\3\12\3\0\1\12"+ + "\16\0\1\12\1\u014a\24\12\17\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\1\12"+ + "\1\u014b\24\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\1\u014c\25\12\17\0"+ + "\12\12\2\0\2\12\1\0\1\12\1\0\3\12\3\0"+ + "\1\12\16\0\6\12\1\u014d\17\12\17\0\12\12\2\0"+ + "\2\12\1\0\1\12\1\0\3\12\3\0\1\12\16\0"+ + "\12\12\1\u014e\13\12\17\0\12\12\2\0\2\12\1\0"+ + "\1\12\1\0\3\12\3\0\1\12\16\0\12\12\1\u014f"+ + "\13\12\16\0\25\376\1\u0150\1\u0141\64\376\26\u0101\1\u0142"+ + "\1\u0150\63\u0101\25\u0104\1\u0151\1\u012a\64\u0104\26\u0105\1\u012b"+ + "\1\u0151\63\u0105\26\u010c\1\u012d\1\u0152\63\u010c\26\0\1\u0153"+ + "\13\0\2\u0154\1\0\2\u0155\45\0\12\12\2\0\2\12"+ + "\1\0\1\12\1\0\3\12\3\0\1\12\16\0\15\12"+ + "\1\u0156\10\12\17\0\12\12\2\0\2\12\1\0\1\12"+ + "\1\0\3\12\3\0\1\12\16\0\21\12\1\u0157\4\12"+ + "\17\0\12\12\2\0\2\12\1\0\1\12\1\0\3\12"+ + "\3\0\1\12\16\0\4\12\1\u0158\21\12\16\0"; private static int [] zzUnpackTrans() { int [] result = new int[18000]; @@ -697,8 +694,8 @@ class _PythonLexer implements FlexLexer { private static final String ZZ_ATTRIBUTE_PACKED_0 = "\6\0\1\11\10\1\1\11\2\1\2\11\2\1\12\11"+ - "\32\1\4\11\4\1\1\11\23\1\2\11\1\1\5\11"+ - "\7\1\1\11\4\1\5\0\1\11\1\1\1\0\1\11"+ + "\32\1\4\11\4\1\1\11\20\1\2\11\1\1\5\11"+ + "\7\1\1\11\1\1\5\0\1\11\1\1\1\0\1\11"+ "\1\0\2\1\2\11\3\1\1\11\6\1\2\11\31\1"+ "\2\11\1\1\2\11\1\1\5\11\1\1\2\11\1\1"+ "\1\0\3\1\1\11\12\1\2\0\1\11\1\1\2\0"+ @@ -711,7 +708,7 @@ class _PythonLexer implements FlexLexer { "\3\1"; private static int [] zzUnpackAttribute() { - int [] result = new int[350]; + int [] result = new int[344]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -1194,7 +1191,7 @@ return yylength()-s.length(); case 123: break; case 8: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [211] { return PyTokenTypes.BACKSLASH; }"); + System.out.println("action [250] { return PyTokenTypes.BACKSLASH; }"); { return PyTokenTypes.BACKSLASH; } // fall through @@ -1222,57 +1219,57 @@ return yylength()-s.length(); case 127: break; case 12: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [208] { return PyTokenTypes.SPACE; }"); - { return PyTokenTypes.SPACE; + System.out.println("action [353] { return PyTokenTypes.LPAR; }"); + { return PyTokenTypes.LPAR; } // fall through case 128: break; case 13: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [209] { return PyTokenTypes.TAB; }"); - { return PyTokenTypes.TAB; + System.out.println("action [354] { return PyTokenTypes.RPAR; }"); + { return PyTokenTypes.RPAR; } // fall through case 129: break; case 14: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [210] { return PyTokenTypes.FORMFEED; }"); - { return PyTokenTypes.FORMFEED; + System.out.println("action [355] { return PyTokenTypes.LBRACKET; }"); + { return PyTokenTypes.LBRACKET; } // fall through case 130: break; case 15: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [353] { return PyTokenTypes.LPAR; }"); - { return PyTokenTypes.LPAR; + System.out.println("action [356] { return PyTokenTypes.RBRACKET; }"); + { return PyTokenTypes.RBRACKET; } // fall through case 131: break; case 16: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [354] { return PyTokenTypes.RPAR; }"); - { return PyTokenTypes.RPAR; + System.out.println("action [361] { return PyTokenTypes.COLON; }"); + { return PyTokenTypes.COLON; } // fall through case 132: break; case 17: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [355] { return PyTokenTypes.LBRACKET; }"); - { return PyTokenTypes.LBRACKET; + System.out.println("action [247] { return PyTokenTypes.SPACE; }"); + { return PyTokenTypes.SPACE; } // fall through case 133: break; case 18: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [356] { return PyTokenTypes.RBRACKET; }"); - { return PyTokenTypes.RBRACKET; + System.out.println("action [248] { return PyTokenTypes.TAB; }"); + { return PyTokenTypes.TAB; } // fall through case 134: break; case 19: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [361] { return PyTokenTypes.COLON; }"); - { return PyTokenTypes.COLON; + System.out.println("action [249] { return PyTokenTypes.FORMFEED; }"); + { return PyTokenTypes.FORMFEED; } // fall through case 135: break; @@ -1419,42 +1416,42 @@ return yylength()-s.length(); case 155: break; case 40: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [214] { return PyTokenTypes.FSTRING_TEXT; }"); + System.out.println("action [209] { return PyTokenTypes.FSTRING_TEXT; }"); { return PyTokenTypes.FSTRING_TEXT; } // fall through case 156: break; case 41: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [215] { return hasMatchingFStringStart(yytext().toString()) ? PyTokenTypes.FSTRING_END : PyTokenTypes.FSTRING_TEXT; }"); + System.out.println("action [210] { return hasMatchingFStringStart(yytext().toString()) ? PyTokenTypes.FSTRING_END : PyTokenTypes.FSTRING_TEXT; }"); { return hasMatchingFStringStart(yytext().toString()) ? PyTokenTypes.FSTRING_END : PyTokenTypes.FSTRING_TEXT; } // fall through case 157: break; case 42: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [216] { pushFStringFragment(); return PyTokenTypes.FSTRING_FRAGMENT_START; }"); + System.out.println("action [211] { pushFStringFragment(); return PyTokenTypes.FSTRING_FRAGMENT_START; }"); { pushFStringFragment(); return PyTokenTypes.FSTRING_FRAGMENT_START; } // fall through case 158: break; case 43: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [235] { return findFStringEndInStringLiteral(yytext().toString(), PyTokenTypes.SINGLE_QUOTED_STRING); }"); + System.out.println("action [230] { return findFStringEndInStringLiteral(yytext().toString(), PyTokenTypes.SINGLE_QUOTED_STRING); }"); { return findFStringEndInStringLiteral(yytext().toString(), PyTokenTypes.SINGLE_QUOTED_STRING); } // fall through case 159: break; case 44: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [226] { braceBalance++; return PyTokenTypes.LBRACE; }"); + System.out.println("action [221] { braceBalance++; return PyTokenTypes.LBRACE; }"); { braceBalance++; return PyTokenTypes.LBRACE; } // fall through case 160: break; case 45: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [227] { if (braceBalance == 0) { popFStringFragment(); return PyTokenTypes.FSTRING_FRAGMENT_END; }"+ZZ_NL+" else { braceBalance--; return PyTokenTypes.RBRACE; } }"); + System.out.println("action [222] { if (braceBalance == 0) { popFStringFragment(); return PyTokenTypes.FSTRING_FRAGMENT_END; }"+ZZ_NL+" else { braceBalance--; return PyTokenTypes.RBRACE; } }"); { if (braceBalance == 0) { popFStringFragment(); return PyTokenTypes.FSTRING_FRAGMENT_END; } else { braceBalance--; return PyTokenTypes.RBRACE; } } @@ -1462,42 +1459,42 @@ return yylength()-s.length(); case 161: break; case 46: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [230] { return PyTokenTypes.FSTRING_FRAGMENT_TYPE_CONVERSION; }"); + System.out.println("action [225] { return PyTokenTypes.FSTRING_FRAGMENT_TYPE_CONVERSION; }"); { return PyTokenTypes.FSTRING_FRAGMENT_TYPE_CONVERSION; } // fall through case 162: break; case 47: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [220] { braceBalance++; return PyTokenTypes.LPAR; }"); + System.out.println("action [215] { braceBalance++; return PyTokenTypes.LPAR; }"); { braceBalance++; return PyTokenTypes.LPAR; } // fall through case 163: break; case 48: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [221] { braceBalance--; return PyTokenTypes.RPAR; }"); + System.out.println("action [216] { braceBalance--; return PyTokenTypes.RPAR; }"); { braceBalance--; return PyTokenTypes.RPAR; } // fall through case 164: break; case 49: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [223] { braceBalance++; return PyTokenTypes.LBRACKET; }"); + System.out.println("action [218] { braceBalance++; return PyTokenTypes.LBRACKET; }"); { braceBalance++; return PyTokenTypes.LBRACKET; } // fall through case 165: break; case 50: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [224] { braceBalance--; return PyTokenTypes.RBRACKET; }"); + System.out.println("action [219] { braceBalance--; return PyTokenTypes.RBRACKET; }"); { braceBalance--; return PyTokenTypes.RBRACKET; } // fall through case 166: break; case 51: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [232] { if (braceBalance == 0) { yybegin(FSTRING_FRAGMENT_FORMAT); return PyTokenTypes.FSTRING_FRAGMENT_FORMAT_START; }"+ZZ_NL+" else { return PyTokenTypes.COLON; } }"); + System.out.println("action [227] { if (braceBalance == 0) { yybegin(FSTRING_FRAGMENT_FORMAT); return PyTokenTypes.FSTRING_FRAGMENT_FORMAT_START; }"+ZZ_NL+" else { return PyTokenTypes.COLON; } }"); { if (braceBalance == 0) { yybegin(FSTRING_FRAGMENT_FORMAT); return PyTokenTypes.FSTRING_FRAGMENT_FORMAT_START; } else { return PyTokenTypes.COLON; } } @@ -1505,7 +1502,7 @@ return yylength()-s.length(); case 167: break; case 52: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [249] { return hasMatchingFStringStart(yytext().toString())? PyTokenTypes.FSTRING_END : PyTokenTypes.FSTRING_TEXT; }"); + System.out.println("action [244] { return hasMatchingFStringStart(yytext().toString())? PyTokenTypes.FSTRING_END : PyTokenTypes.FSTRING_TEXT; }"); { return hasMatchingFStringStart(yytext().toString())? PyTokenTypes.FSTRING_END : PyTokenTypes.FSTRING_TEXT; } // fall through @@ -1828,7 +1825,7 @@ return PyTokenTypes.DOCSTRING; case 212: break; case 97: System.out.println("match: --"+zzToPrintable(yytext())+"--"); - System.out.println("action [236] { return findFStringEndInStringLiteral(yytext().toString(), PyTokenTypes.TRIPLE_QUOTED_STRING); }"); + System.out.println("action [231] { return findFStringEndInStringLiteral(yytext().toString(), PyTokenTypes.TRIPLE_QUOTED_STRING); }"); { return findFStringEndInStringLiteral(yytext().toString(), PyTokenTypes.TRIPLE_QUOTED_STRING); } // fall through diff --git a/python/src/com/jetbrains/python/lexer/Python.flex b/python/src/com/jetbrains/python/lexer/Python.flex index 3e030244085f..340ac7bf16de 100644 --- a/python/src/com/jetbrains/python/lexer/Python.flex +++ b/python/src/com/jetbrains/python/lexer/Python.flex @@ -205,11 +205,6 @@ return yylength()-s.length(); %% -[\ ] { return PyTokenTypes.SPACE; } -[\t] { return PyTokenTypes.TAB; } -[\f] { return PyTokenTypes.FORMFEED; } -"\\" { return PyTokenTypes.BACKSLASH; } - { {FSTRING_TEXT_NO_QUOTES} { return PyTokenTypes.FSTRING_TEXT; } {FSTRING_QUOTES} { return hasMatchingFStringStart(yytext().toString()) ? PyTokenTypes.FSTRING_END : PyTokenTypes.FSTRING_TEXT; } @@ -249,6 +244,11 @@ return yylength()-s.length(); {FSTRING_QUOTES} { return hasMatchingFStringStart(yytext().toString())? PyTokenTypes.FSTRING_END : PyTokenTypes.FSTRING_TEXT; } } +[\ ] { return PyTokenTypes.SPACE; } +[\t] { return PyTokenTypes.TAB; } +[\f] { return PyTokenTypes.FORMFEED; } +"\\" { return PyTokenTypes.BACKSLASH; } + { [\n] { if (zzCurrentPos == 0) yybegin(PENDING_DOCSTRING); return PyTokenTypes.LINE_BREAK; } {END_OF_LINE_COMMENT} { if (zzCurrentPos == 0) yybegin(PENDING_DOCSTRING); return PyTokenTypes.END_OF_LINE_COMMENT; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFormattedStringNodeImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFormattedStringNodeImpl.java index d0c8289b78d7..b06d49f014d5 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFormattedStringNodeImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFormattedStringNodeImpl.java @@ -4,12 +4,19 @@ package com.jetbrains.python.psi.impl; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiErrorElement; +import com.intellij.psi.tree.IElementType; import com.jetbrains.python.PyElementTypes; +import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.psi.PyFStringFragment; import com.jetbrains.python.psi.PyFormattedStringNode; import com.jetbrains.python.psi.PyStringLiteralUtil; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import java.util.Set; @@ -39,73 +46,126 @@ public class PyFormattedStringNodeImpl extends PyElementImpl implements PyFormat @NotNull @Override public String getTextWithoutPrefix() { - return null; + final String text = getText(); + return text.substring(PyStringLiteralUtil.getPrefixLength(text)); } @NotNull @Override public TextRange getContentRange() { - return null; + return getAbsoluteContentRange().shiftLeft(getTextRange().getStartOffset()); } @NotNull @Override public TextRange getAbsoluteContentRange() { - return null; + final PsiElement startToken = findNotNullChildByType(PyTokenTypes.FSTRING_START); + final PsiElement endToken = findChildByType(PyTokenTypes.FSTRING_END); + return TextRange.create(startToken.getTextRange().getEndOffset(), + endToken != null ? endToken.getTextRange().getStartOffset() : getTextRange().getEndOffset()); + } @NotNull @Override public String getContent() { - return null; + return getContentRange().substring(getText()); } @NotNull @Override public List> getDecodedFragments() { - return null; - } + final int nodeOffset = getTextRange().getStartOffset(); + final ArrayList> result = new ArrayList<>(); + final PyStringLiteralDecoder decoder = new PyStringLiteralDecoder(this); + int continuousTextStart = -1; + for (PsiElement child = getFirstChild(); child != null; child = child.getNextSibling()) { + final IElementType childType = child.getNode().getElementType(); + if (childType == PyTokenTypes.FSTRING_START) { + continue; + } + final TextRange relChildRange = child.getTextRange().shiftLeft(nodeOffset); + if (childType == PyElementTypes.FSTRING_FRAGMENT || childType == PyTokenTypes.FSTRING_END) { + if (continuousTextStart != -1) { + result.addAll(decoder.decodeRange(TextRange.create(continuousTextStart, relChildRange.getStartOffset()))); + } + continuousTextStart = -1; + if (childType == PyElementTypes.FSTRING_FRAGMENT) { + // There shouldn't be any escaping inside interpolated parts + result.add(Pair.create(relChildRange, child.getText())); + } + } + else if (childType == PyTokenTypes.FSTRING_TEXT) { + if (continuousTextStart == -1) { + continuousTextStart = relChildRange.getStartOffset(); + } + } + else if (!(child instanceof PsiErrorElement)) { + throw new AssertionError("Illegal element " + child + " inside f-string"); + } + } + if (continuousTextStart != -1) { + // There are no closing quotes if we got here + result.addAll(decoder.decodeRange(TextRange.create(continuousTextStart, getTextLength()))); + } + return result; + } + @NotNull @Override public String getQuote() { - return null; + final PsiElement start = findNotNullChildByType(PyTokenTypes.FSTRING_START); + return start.getText().substring(getPrefixLength()); } @Override public char getQuoteChar() { - return 0; + return getQuote().charAt(0); } @Override public boolean isTripleQuoted() { - return false; + return getQuote().length() == 3; } @Override public boolean isTerminated() { - return false; + return findChildrenByType(PyTokenTypes.FSTRING_END) != null; } @NotNull @Override public Set getModifiers() { - return null; + final EnumSet result = EnumSet.noneOf(Modifier.class); + if (isUnicode()) { + result.add(Modifier.UNICODE); + } + if (isBytes()) { + result.add(Modifier.BYTES); + } + if (isRaw()) { + result.add(Modifier.RAW); + } + if (isFormatted()) { + result.add(Modifier.FORMATTED); + } + return result; } @Override public boolean isUnicode() { - return false; + return StringUtil.containsIgnoreCase(getPrefix(), "u"); } @Override public boolean isRaw() { - return false; + return StringUtil.containsIgnoreCase(getPrefix(), "r"); } @Override public boolean isBytes() { - return false; + return StringUtil.containsIgnoreCase(getPrefix(), "b"); } @Override diff --git a/python/src/com/jetbrains/python/psi/impl/PyLiteralStringNodeImpl.java b/python/src/com/jetbrains/python/psi/impl/PyLiteralStringNodeImpl.java index 7a81e417eed6..5f857d5cabfd 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyLiteralStringNodeImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyLiteralStringNodeImpl.java @@ -41,9 +41,7 @@ public class PyLiteralStringNodeImpl extends LeafPsiElement implements PyLiteral @NotNull @Override public List> getDecodedFragments() { - final PyStringLiteralDecoder decoder = new PyStringLiteralDecoder(this); - decoder.decodeContent(); - return decoder.getResult(); + return new PyStringLiteralDecoder(this).decodeContent(); } @NotNull @@ -106,25 +104,16 @@ public class PyLiteralStringNodeImpl extends LeafPsiElement implements PyLiteral return result; } - /** - * @return true if given string node contains "u" or "U" prefix - */ @Override public boolean isUnicode() { return StringUtil.containsIgnoreCase(getPrefix(), "u"); } - /** - * @return true if given string node contains "r" or "R" prefix - */ @Override public boolean isRaw() { return StringUtil.containsIgnoreCase(getPrefix(), "r"); } - /** - * @return true if given string node contains "b" or "B" prefix - */ @Override public boolean isBytes() { return StringUtil.containsIgnoreCase(getPrefix(), "b"); diff --git a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralDecoder.java b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralDecoder.java index 15a648402c34..dd788006233b 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralDecoder.java +++ b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralDecoder.java @@ -19,18 +19,25 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class PyStringLiteralDecoder { - public static final Pattern PATTERN_ESCAPE = Pattern - .compile("\\\\(\n|\\\\|'|\"|a|b|f|n|r|t|v|([0-7]{1,3})|x([0-9a-fA-F]{1,2})" + "|N(\\{.*?\\})|u([0-9a-fA-F]{4})|U([0-9a-fA-F]{8}))"); - // -> 1 -> 2 <--> 3 <- -> 4 <--> 5 <- -> 6 <-<- + public static final Pattern PATTERN_ESCAPE = Pattern.compile("(\\{\\{|}})|" + // 1 + "\\\\(" + + "\n|\\\\|'|\"|a|b|f|n|r|t|v|" + // 2 + "([0-7]{1,3})|" + // 3 + "x([0-9a-fA-F]{1,2})|" + // 4 + "N(\\{.*?})|" + // 5 + "u([0-9a-fA-F]{4})|" + // 6 + "U([0-9a-fA-F]{8})" + // 7 + ")"); private enum EscapeRegexGroup { WHOLE_MATCH, + FSTRING_BRACE, ESCAPED_SUBSTRING, OCTAL, HEXADECIMAL, UNICODE_NAMED, UNICODE_16BIT, - UNICODE_32BIT + UNICODE_32BIT, } private static final Map escapeMap = initializeEscapeMap(); @@ -53,29 +60,26 @@ public class PyStringLiteralDecoder { } private final PyRichStringNode myNode; - private final List> myResult = new ArrayList<>(); public PyStringLiteralDecoder(@NotNull PyRichStringNode node) { myNode = node; } - public void decodeContent() { - decodeRange(myNode.getContentRange()); - } - - public void decodeRange(@NotNull TextRange range) { - myResult.addAll(decodeFragment(range.substring(myNode.getText()), range.getStartOffset())); + @NotNull + public List> decodeContent() { + return decodeRange(myNode.getContentRange()); } @NotNull - public List> getResult() { - return myResult; + public List> decodeRange(@NotNull TextRange range) { + return decodeFragment(range.substring(myNode.getText()), range.getStartOffset()); } @NotNull private List> decodeFragment(@NotNull String encoded, int offset) { final boolean raw = myNode.isRaw(); final boolean unicode = myNode.isUnicode() || isUnicodeByDefault(); + final boolean formatted = myNode.isFormatted(); final List> result = new ArrayList<>(); final Matcher escMatcher = PATTERN_ESCAPE.matcher(encoded); @@ -87,17 +91,22 @@ public class PyStringLiteralDecoder { result.add(Pair.create(offsetRange, range.substring(encoded))); } + final String fStringBrace = escapeRegexGroup(escMatcher, EscapeRegexGroup.FSTRING_BRACE); final String octal = escapeRegexGroup(escMatcher, EscapeRegexGroup.OCTAL); final String hex = escapeRegexGroup(escMatcher, EscapeRegexGroup.HEXADECIMAL); // TODO: Implement unicode character name escapes: EscapeRegexGroup.UNICODE_NAMED final String unicode16 = escapeRegexGroup(escMatcher, EscapeRegexGroup.UNICODE_16BIT); final String unicode32 = escapeRegexGroup(escMatcher, EscapeRegexGroup.UNICODE_32BIT); final String wholeMatch = escapeRegexGroup(escMatcher, EscapeRegexGroup.WHOLE_MATCH); + assert wholeMatch != null; final boolean escapedUnicode = raw && unicode || !raw; final String str; - if (!raw && octal != null) { + if (fStringBrace != null) { + str = formatted ? wholeMatch.substring(0, 1) : wholeMatch; + } + else if (!raw && octal != null) { str = new String(new char[]{(char)Integer.parseInt(octal, 8)}); } else if (!raw && hex != null) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java index d747757598dc..c28248fc8a39 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java @@ -26,10 +26,12 @@ import com.intellij.psi.*; import com.intellij.psi.PsiReferenceService.Hints; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.CachedValueProvider.Result; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.psi.util.PsiTreeUtil; +import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.codeInsight.regexp.PythonVerboseRegexpLanguage; import com.jetbrains.python.lexer.PythonHighlightingLexer; @@ -118,13 +120,15 @@ public class PyStringLiteralExpressionImpl extends PyElementImpl implements PySt @Override @NotNull public List getStringNodes() { - return Arrays.asList(getNode().getChildren(PyTokenTypes.STRING_NODES)); + final TokenSet stringNodeTypes = TokenSet.orSet(PyTokenTypes.STRING_NODES, TokenSet.create(PyElementTypes.FSTRING_NODE)); + return Arrays.asList(getNode().getChildren(stringNodeTypes)); } @NotNull @Override public List getGluedStringNodes() { return StreamEx.of(getStringNodes()) + .map(ASTNode::getPsi) .select(PyRichStringNode.class) .toList(); } diff --git a/python/testData/psi/FStringEscapedBraces.txt b/python/testData/psi/FStringEscapedBraces.txt index ca82208724ec..92b1035c80a1 100644 --- a/python/testData/psi/FStringEscapedBraces.txt +++ b/python/testData/psi/FStringEscapedBraces.txt @@ -5,7 +5,7 @@ PyFile:FStringEscapedBraces.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {} {{42}} } { PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('{{}} {{') diff --git a/python/testData/psi/FStringExpressionContainBraces.txt b/python/testData/psi/FStringExpressionContainBraces.txt index 135896a8a966..054df29d69ce 100644 --- a/python/testData/psi/FStringExpressionContainBraces.txt +++ b/python/testData/psi/FStringExpressionContainBraces.txt @@ -5,7 +5,7 @@ PyFile:FStringExpressionContainBraces.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: { {1, 2} } PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentDuplicateTypeConversion.txt b/python/testData/psi/FStringFragmentDuplicateTypeConversion.txt index b6321abcbac8..955e466694ca 100644 --- a/python/testData/psi/FStringFragmentDuplicateTypeConversion.txt +++ b/python/testData/psi/FStringFragmentDuplicateTypeConversion.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentDuplicateTypeConversion.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42!r!r} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentIllegalTypeConversion.txt b/python/testData/psi/FStringFragmentIllegalTypeConversion.txt index bd442f67e7ba..c5a3d697bcd7 100644 --- a/python/testData/psi/FStringFragmentIllegalTypeConversion.txt +++ b/python/testData/psi/FStringFragmentIllegalTypeConversion.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentIllegalTypeConversion.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42!!} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeClosingBrace.txt b/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeClosingBrace.txt index 7b10c737c969..272292a9e156 100644 --- a/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeClosingBrace.txt +++ b/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeClosingBrace.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentIncompleteTypeConversionBeforeClosingBrace.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42!} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeClosingQuote.txt b/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeClosingQuote.txt index fc238438c382..60d9c9c42b62 100644 --- a/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeClosingQuote.txt +++ b/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeClosingQuote.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentIncompleteTypeConversionBeforeClosingQuote.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42! PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeColon.txt b/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeColon.txt index b28a5fe4e6cb..e5ae7d6e7c6f 100644 --- a/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeColon.txt +++ b/python/testData/psi/FStringFragmentIncompleteTypeConversionBeforeColon.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentIncompleteTypeConversionBeforeColon.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42!:} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentTypeConversion.txt b/python/testData/psi/FStringFragmentTypeConversion.txt index 00803a6e1276..7fe082745b4b 100644 --- a/python/testData/psi/FStringFragmentTypeConversion.txt +++ b/python/testData/psi/FStringFragmentTypeConversion.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentTypeConversion.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42!r} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentTypeConversionAfterFormatPart.txt b/python/testData/psi/FStringFragmentTypeConversionAfterFormatPart.txt index 97e9d4867073..f6be09e8314b 100644 --- a/python/testData/psi/FStringFragmentTypeConversionAfterFormatPart.txt +++ b/python/testData/psi/FStringFragmentTypeConversionAfterFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentTypeConversionAfterFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:{width}!r} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentWithDictLiteral.txt b/python/testData/psi/FStringFragmentWithDictLiteral.txt index e068e6f024f0..1e4f085d9d35 100644 --- a/python/testData/psi/FStringFragmentWithDictLiteral.txt +++ b/python/testData/psi/FStringFragmentWithDictLiteral.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentWithDictLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: { {1: 2} } PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentWithInterpolatedFormatPart.txt b/python/testData/psi/FStringFragmentWithInterpolatedFormatPart.txt index eb615f9938b3..9bbb8b9e851b 100644 --- a/python/testData/psi/FStringFragmentWithInterpolatedFormatPart.txt +++ b/python/testData/psi/FStringFragmentWithInterpolatedFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentWithInterpolatedFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: result: {value:{width}.{precision}} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('result: ') diff --git a/python/testData/psi/FStringFragmentWithLiteralFormatPart.txt b/python/testData/psi/FStringFragmentWithLiteralFormatPart.txt index a46cf71774dd..976379769804 100644 --- a/python/testData/psi/FStringFragmentWithLiteralFormatPart.txt +++ b/python/testData/psi/FStringFragmentWithLiteralFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentWithLiteralFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:foo} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentWithNotParenthesizedLambda.txt b/python/testData/psi/FStringFragmentWithNotParenthesizedLambda.txt index be44133a7356..195e47ef7456 100644 --- a/python/testData/psi/FStringFragmentWithNotParenthesizedLambda.txt +++ b/python/testData/psi/FStringFragmentWithNotParenthesizedLambda.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentWithNotParenthesizedLambda.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {lambda x: 42} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringFragmentWithParenthesizedLambda.txt b/python/testData/psi/FStringFragmentWithParenthesizedLambda.txt index e3785a092441..994ded294687 100644 --- a/python/testData/psi/FStringFragmentWithParenthesizedLambda.txt +++ b/python/testData/psi/FStringFragmentWithParenthesizedLambda.txt @@ -5,7 +5,7 @@ PyFile:FStringFragmentWithParenthesizedLambda.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {(lambda x: 42)} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringGluedWithLiteralStringNodes.txt b/python/testData/psi/FStringGluedWithLiteralStringNodes.txt index 5775e8e3de86..a6cac1e31dbd 100644 --- a/python/testData/psi/FStringGluedWithLiteralStringNodes.txt +++ b/python/testData/psi/FStringGluedWithLiteralStringNodes.txt @@ -7,7 +7,7 @@ PyFile:FStringGluedWithLiteralStringNodes.py PsiWhiteSpace(' ') PyParenthesizedExpression PsiElement(Py:LPAR)('(') - PyStringLiteralExpression: foobar + PyStringLiteralExpression: foo{42} {True}bar PsiElement(Py:SINGLE_QUOTED_STRING)(''foo'') PsiWhiteSpace('\n ') PyFormattedStringNode @@ -17,7 +17,7 @@ PyFile:FStringGluedWithLiteralStringNodes.py PyNumericLiteralExpression PsiElement(Py:INTEGER_LITERAL)('42') PsiElement(Py:FSTRING_FRAGMENT_END)('}') - PsiWhiteSpace(' ') + PsiElement(Py:FSTRING_TEXT)(' ') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') PyBoolLiteralExpression diff --git a/python/testData/psi/FStringIncompleteFragment.txt b/python/testData/psi/FStringIncompleteFragment.txt index b1bed53f12eb..f75be4fa1db3 100644 --- a/python/testData/psi/FStringIncompleteFragment.txt +++ b/python/testData/psi/FStringIncompleteFragment.txt @@ -5,7 +5,7 @@ PyFile:FStringIncompleteFragment.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42 PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringIncompleteFragmentWithFormatPart.txt b/python/testData/psi/FStringIncompleteFragmentWithFormatPart.txt index 046005fd61e7..26e709f8876c 100644 --- a/python/testData/psi/FStringIncompleteFragmentWithFormatPart.txt +++ b/python/testData/psi/FStringIncompleteFragmentWithFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringIncompleteFragmentWithFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:{width} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringIncompleteFragmentWithTypeConversion.txt b/python/testData/psi/FStringIncompleteFragmentWithTypeConversion.txt index 60d51ac9a103..57028be8f10d 100644 --- a/python/testData/psi/FStringIncompleteFragmentWithTypeConversion.txt +++ b/python/testData/psi/FStringIncompleteFragmentWithTypeConversion.txt @@ -5,7 +5,7 @@ PyFile:FStringIncompleteFragmentWithTypeConversion.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42!r PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringIncompleteFragmentWithTypeConversionAndFormatPart.txt b/python/testData/psi/FStringIncompleteFragmentWithTypeConversionAndFormatPart.txt index 76f958a451ce..b1d87f930321 100644 --- a/python/testData/psi/FStringIncompleteFragmentWithTypeConversionAndFormatPart.txt +++ b/python/testData/psi/FStringIncompleteFragmentWithTypeConversionAndFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringIncompleteFragmentWithTypeConversionAndFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42!r:{width} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteInFormatPart.txt index a7332f81980e..5e03320e310a 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42: PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteInLiteralPart.txt b/python/testData/psi/FStringTerminatedByQuoteInLiteralPart.txt index cbddc6f426ac..540d183b5fd6 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInLiteralPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInLiteralPart.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteInLiteralPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: foo PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('foo') diff --git a/python/testData/psi/FStringTerminatedByQuoteInNestedFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteInNestedFormatPart.txt index f149eea85c2a..cb94927cb5e8 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInNestedFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInNestedFormatPart.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteInNestedFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {f"{42: PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: {42: PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteInNestedLiteralPart.txt b/python/testData/psi/FStringTerminatedByQuoteInNestedLiteralPart.txt index e4e9fabd26a2..97fda4962a5a 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInNestedLiteralPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInNestedLiteralPart.txt @@ -5,13 +5,13 @@ PyFile:FStringTerminatedByQuoteInNestedLiteralPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: foo{f"baz PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('foo') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: baz PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"') PsiElement(Py:FSTRING_TEXT)('baz') diff --git a/python/testData/psi/FStringTerminatedByQuoteInsideFStringLiteral.txt b/python/testData/psi/FStringTerminatedByQuoteInsideFStringLiteral.txt index 46eec97f4d6d..ada82f7e92f5 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInsideFStringLiteral.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInsideFStringLiteral.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteInsideFStringLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: }baz' + PyStringLiteralExpression: foo{f"}baz' PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('foo') diff --git a/python/testData/psi/FStringTerminatedByQuoteInsideFStringLiteralInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteInsideFStringLiteralInFormatPart.txt index a2a64f89d536..980f0e2db8d4 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInsideFStringLiteralInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInsideFStringLiteralInFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteInsideFStringLiteralInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: }}' + PyStringLiteralExpression: {42:{f"}}' PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteInsideNestedFStringLiteral.txt b/python/testData/psi/FStringTerminatedByQuoteInsideNestedFStringLiteral.txt index 645f01a2696b..33ad4c73dbbb 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInsideNestedFStringLiteral.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInsideNestedFStringLiteral.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteInsideNestedFStringLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: } + PyStringLiteralExpression: {f"""{f"} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: {f" PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"""') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteInsideNestedFStringLiteralInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteInsideNestedFStringLiteralInFormatPart.txt index 13efa30f9d68..dcd2e0d27ceb 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInsideNestedFStringLiteralInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInsideNestedFStringLiteralInFormatPart.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteInsideNestedFStringLiteralInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: }} + PyStringLiteralExpression: {f"""{42:{f"}} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:{f" PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"""') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteInsideNestedStringLiteral.txt b/python/testData/psi/FStringTerminatedByQuoteInsideNestedStringLiteral.txt index a8f88dfa98a6..a799f4bca0e5 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInsideNestedStringLiteral.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInsideNestedStringLiteral.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteInsideNestedStringLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: } + PyStringLiteralExpression: {f"""{"} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: {" PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"""') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteInsideNestedStringLiteralInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteInsideNestedStringLiteralInFormatPart.txt index 3c7577af19e7..11b9a3830792 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInsideNestedStringLiteralInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInsideNestedStringLiteralInFormatPart.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteInsideNestedStringLiteralInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: }} + PyStringLiteralExpression: {f"""{42:{"}} PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:{" PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"""') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteInsideStringLiteral.txt b/python/testData/psi/FStringTerminatedByQuoteInsideStringLiteral.txt index 5e449acc8605..6bdd043e0be9 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInsideStringLiteral.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInsideStringLiteral.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteInsideStringLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: }baz' + PyStringLiteralExpression: foo{"}baz' PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('foo') diff --git a/python/testData/psi/FStringTerminatedByQuoteInsideStringLiteralInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteInsideStringLiteralInFormatPart.txt index ee60d4d42c9b..77a12f823513 100644 --- a/python/testData/psi/FStringTerminatedByQuoteInsideStringLiteralInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteInsideStringLiteralInFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteInsideStringLiteralInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: }}' + PyStringLiteralExpression: {42:{"}}' PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteOfFStringLiteral.txt b/python/testData/psi/FStringTerminatedByQuoteOfFStringLiteral.txt index 86c1c8c571c8..b794e8a48f34 100644 --- a/python/testData/psi/FStringTerminatedByQuoteOfFStringLiteral.txt +++ b/python/testData/psi/FStringTerminatedByQuoteOfFStringLiteral.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteOfFStringLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: foo{f PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('foo') diff --git a/python/testData/psi/FStringTerminatedByQuoteOfFStringLiteralInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteOfFStringLiteralInFormatPart.txt index e94da3c4a5f3..c5f17b6e90c6 100644 --- a/python/testData/psi/FStringTerminatedByQuoteOfFStringLiteralInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteOfFStringLiteralInFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteOfFStringLiteralInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:{f PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteOfNestedFStringLiteral.txt b/python/testData/psi/FStringTerminatedByQuoteOfNestedFStringLiteral.txt index 8a9b154ed9ad..70c3c6081533 100644 --- a/python/testData/psi/FStringTerminatedByQuoteOfNestedFStringLiteral.txt +++ b/python/testData/psi/FStringTerminatedByQuoteOfNestedFStringLiteral.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteOfNestedFStringLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {f"{f PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: {f PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteOfNestedFStringLiteralInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteOfNestedFStringLiteralInFormatPart.txt index 2400e05f67c7..3bbd4d020f9e 100644 --- a/python/testData/psi/FStringTerminatedByQuoteOfNestedFStringLiteralInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteOfNestedFStringLiteralInFormatPart.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteOfNestedFStringLiteralInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {f"{42:{f PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:{f PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteOfNestedStringLiteral.txt b/python/testData/psi/FStringTerminatedByQuoteOfNestedStringLiteral.txt index 733613548358..f5b7a34b5571 100644 --- a/python/testData/psi/FStringTerminatedByQuoteOfNestedStringLiteral.txt +++ b/python/testData/psi/FStringTerminatedByQuoteOfNestedStringLiteral.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteOfNestedStringLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {f"{ PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: { PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteOfNestedStringLiteralInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteOfNestedStringLiteralInFormatPart.txt index a7883fe03a50..fe15d4289ba2 100644 --- a/python/testData/psi/FStringTerminatedByQuoteOfNestedStringLiteralInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteOfNestedStringLiteralInFormatPart.txt @@ -5,12 +5,12 @@ PyFile:FStringTerminatedByQuoteOfNestedStringLiteralInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {f"{42:{ PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment PsiElement(Py:FSTRING_FRAGMENT_START)('{') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:{ PyFormattedStringNode PsiElement(Py:FSTRING_START)('f"') PyFStringFragment diff --git a/python/testData/psi/FStringTerminatedByQuoteOfStringLiteral.txt b/python/testData/psi/FStringTerminatedByQuoteOfStringLiteral.txt index 0df358842ac5..2873a7e2ade2 100644 --- a/python/testData/psi/FStringTerminatedByQuoteOfStringLiteral.txt +++ b/python/testData/psi/FStringTerminatedByQuoteOfStringLiteral.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteOfStringLiteral.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: foo{ PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('foo') diff --git a/python/testData/psi/FStringTerminatedByQuoteOfStringLiteralInFormatPart.txt b/python/testData/psi/FStringTerminatedByQuoteOfStringLiteralInFormatPart.txt index 30db7b6e1a8f..147dd64155ed 100644 --- a/python/testData/psi/FStringTerminatedByQuoteOfStringLiteralInFormatPart.txt +++ b/python/testData/psi/FStringTerminatedByQuoteOfStringLiteralInFormatPart.txt @@ -5,7 +5,7 @@ PyFile:FStringTerminatedByQuoteOfStringLiteralInFormatPart.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: {42:{ PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PyFStringFragment diff --git a/python/testData/psi/FStringWithSimpleFragment.txt b/python/testData/psi/FStringWithSimpleFragment.txt index 8951a7029e90..b12a9e87a586 100644 --- a/python/testData/psi/FStringWithSimpleFragment.txt +++ b/python/testData/psi/FStringWithSimpleFragment.txt @@ -5,7 +5,7 @@ PyFile:FStringWithSimpleFragment.py PsiWhiteSpace(' ') PsiElement(Py:EQ)('=') PsiWhiteSpace(' ') - PyStringLiteralExpression: + PyStringLiteralExpression: foo{42}bar PyFormattedStringNode PsiElement(Py:FSTRING_START)('f'') PsiElement(Py:FSTRING_TEXT)('foo') diff --git a/python/testSrc/com/jetbrains/python/PyStringLiteralTest.java b/python/testSrc/com/jetbrains/python/PyStringLiteralTest.java index 62e6edfbf023..dc171411cc64 100644 --- a/python/testSrc/com/jetbrains/python/PyStringLiteralTest.java +++ b/python/testSrc/com/jetbrains/python/PyStringLiteralTest.java @@ -15,8 +15,6 @@ */ package com.jetbrains.python; -import com.intellij.lang.ASTFactory; -import com.intellij.lang.LanguageASTFactory; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.LiteralTextEscaper; @@ -149,6 +147,13 @@ public class PyStringLiteralTest extends PyTestCase { assertEquals("\\U12345678", createLiteralFromText("u'\\U12345678'").getStringValue()); } + public void testFStringEscapes() { + assertEquals("{", createLiteralFromText("f'{{'").getStringValue()); + assertEquals("}", createLiteralFromText("f'}}'").getStringValue()); + assertEquals("{{foo}}", createLiteralFromText("f'{{{foo}}}'").getStringValue()); + assertEquals("\n{foo}\r\"", createLiteralFromText("f'\\n{foo}\\r\"'").getStringValue()); + } + private static String decodeRange(PyStringLiteralExpression expr, TextRange range) { final StringBuilder builder = new StringBuilder(); expr.createLiteralTextEscaper().decode(range, builder);