From 001a060c84f9d5fe590afcb58ad8be2815c5f6ee Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Fri, 24 Jun 2016 12:06:41 -0400 Subject: [PATCH 1/2] Bring painless docs closer to reality --- docs/reference/modules/scripting.asciidoc | 2 + .../scripting/painless-syntax.asciidoc | 164 ++++ .../modules/scripting/painless.asciidoc | 558 +----------- .../src/main/antlr/PainlessLexer.g4 | 1 + .../src/main/antlr/PainlessLexer.tokens | 206 ++--- .../src/main/antlr/PainlessParser.g4 | 1 + .../src/main/antlr/PainlessParser.tokens | 206 ++--- .../elasticsearch/painless/Augmentation.java | 35 + .../painless/antlr/PainlessLexer.java | 429 ++++----- .../painless/antlr/PainlessParser.java | 848 +++++++++--------- .../antlr/PainlessParserBaseVisitor.java | 7 + .../painless/antlr/PainlessParserVisitor.java | 7 + .../elasticsearch/painless/antlr/Walker.java | 9 + .../painless/node/EInstanceof.java | 89 ++ .../painless/node/package-info.java | 7 +- .../org/elasticsearch/painless/java.lang.txt | 3 + .../painless/AugmentationTests.java | 13 + .../painless/ComparisonTests.java | 18 + 18 files changed, 1243 insertions(+), 1360 deletions(-) create mode 100644 docs/reference/modules/scripting/painless-syntax.asciidoc create mode 100644 modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java diff --git a/docs/reference/modules/scripting.asciidoc b/docs/reference/modules/scripting.asciidoc index feb8113a6da..76065210569 100644 --- a/docs/reference/modules/scripting.asciidoc +++ b/docs/reference/modules/scripting.asciidoc @@ -96,6 +96,8 @@ include::scripting/groovy.asciidoc[] include::scripting/painless.asciidoc[] +include::scripting/painless-syntax.asciidoc[] + include::scripting/expression.asciidoc[] include::scripting/native.asciidoc[] diff --git a/docs/reference/modules/scripting/painless-syntax.asciidoc b/docs/reference/modules/scripting/painless-syntax.asciidoc new file mode 100644 index 00000000000..500a276c852 --- /dev/null +++ b/docs/reference/modules/scripting/painless-syntax.asciidoc @@ -0,0 +1,164 @@ +[[modules-scripting-painless-syntax]] +=== Painless Syntax + +experimental[The Painless scripting language is new and is still marked as experimental. The syntax or API may be changed in the future in non-backwards compatible ways if required.] + +[float] +[[painless-types]] +=== Variable types + +Painless supports all of https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html[Java's types], +including array types, but adds some additional built-in types. + +[float] +[[painless-def]] +==== Def + +The dynamic type `def` serves as a placeholder for any other type. It adopts the behavior +of whatever runtime type it represents. + +[float] +[[painless-strings]] +==== String + +String constants can be declared with single quotes, to avoid escaping horrors with JSON: + +[source,js] +--------------------------------------------------------- +def mystring = 'foo'; +--------------------------------------------------------- + +[float] +[[painless-lists]] +==== List + +Lists can be created explicitly (e.g. `new ArrayList()`) or initialized similar to Groovy: + +[source,js] +--------------------------------------------------------- +def list = [1,2,3]; +--------------------------------------------------------- + +Lists can also be accessed similar to arrays: they support subscript and `.length`: + +[source,js] +--------------------------------------------------------- +def list = [1,2,3]; +return list[0] +--------------------------------------------------------- + +[float] +[[painless-maps]] +==== Map + +Maps can be created explicitly (e.g. `new HashMap()`) or initialized similar to Groovy: + +[source,js] +--------------------------------------------------------- +def person = ['name': 'Joe', 'age': 63]; +--------------------------------------------------------- + +Map keys can also be accessed as properties. + +[source,js] +--------------------------------------------------------- +def person = ['name': 'Joe', 'age': 63]; +person.retired = true; +return person.name +--------------------------------------------------------- + +Map keys can also be accessed via subscript (for keys containing special characters): + +[source,js] +--------------------------------------------------------- +return map['something-absurd!'] +--------------------------------------------------------- + +[float] +[[painless-pattern]] +==== Pattern + +Regular expression constants are directly supported: + +[source,js] +--------------------------------------------------------- +Pattern p = /[aeiou]/ +--------------------------------------------------------- + +Patterns can only be created via this mechanism. This ensures fast performance, regular expressions +are always constants and compiled efficiently a single time. + +[float] +[[modules-scripting-painless-regex-flags]] +==== Pattern 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/8/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` +|======================================================================= + +[float] +[[painless-operators]] +=== Operators + +All of Java's https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html[operators] are +supported with the same precedence, promotion, and semantics. + +There are only a few minor differences and add-ons: + +* `==` behaves as Java's for numeric types, but for non-numeric types acts as https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-[`Object.equals()`] +* `===` and `!==` support exact reference comparison (e.g. `x === y`) +* `=~` true if a portion of the text matches a pattern (e.g. `x =~ /b/`) +* `==~` true if the entire text matches a pattern (e.g. `x ==~ /[Bb]ob/`) + +[float] +[[painless-control-flow]] +=== Control flow + +Java's https://docs.oracle.com/javase/tutorial/java/nutsandbolts/flow.html[control flow statements] are supported, with the exception +of the `switch` statement. + +[float] +[[painless-functions]] +=== Functions + +Functions can be declared at the beginning of the script, for example: + +[source,js] +--------------------------------------------------------- +boolean isNegative(def x) { x < 0 } +... +if (isNegative(someVar)) { + ... +} +--------------------------------------------------------- + +[float] +[[painless-lambda-expressions]] +=== Lambda expressions +Lambda expressions and method references work the same as https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html[Java's]. + +[source,js] +--------------------------------------------------------- +list.removeIf(item -> item == 2); +list.removeIf((int item) -> item == 2); +list.removeIf((int item) -> { item == 2 }); +list.sort((x, y) -> x - y); +list.sort(Integer::compare); +--------------------------------------------------------- + +Method references to functions within the script can be accomplished using `this`, e.g. `list.sort(this::mycompare)`. diff --git a/docs/reference/modules/scripting/painless.asciidoc b/docs/reference/modules/scripting/painless.asciidoc index 2c753e09039..db68db2c7a3 100644 --- a/docs/reference/modules/scripting/painless.asciidoc +++ b/docs/reference/modules/scripting/painless.asciidoc @@ -8,9 +8,7 @@ by default. It is designed specifically for use with Elasticsearch and can safely be used with `inline` and `stored` scripting, which is enabled by default. -A Painless script is essentially a single function. Painless does not provide support -for defining multiple functions within a script. The Painless syntax is similar to -http://groovy-lang.org/index.html[Groovy]. +The Painless syntax is similar to http://groovy-lang.org/index.html[Groovy]. You can use Painless anywhere a script can be used in Elasticsearch--simply set the `lang` parameter to `painless`. @@ -19,22 +17,15 @@ to `painless`. [float] == Painless Features -* Control flow: `for` loops, `while` loops, `do/while` loops, `if/else` +* Fast performance: https://benchmarks.elastic.co/index.html#search_qps_scripts[several times faster] than the alternatives. -* Fully Typed: all available types/methods described in <> +* Safety: Fine-grained <> with method call/field granularity. -* Arithmetic operators: multiplication `*`, division `/`, addition `+`, subtraction `-`, precedence `( )` +* Optional typing: Variables and parameters can use explicit types or the dynamic `def` type. -* Comparison operators: less than `<`, less than or equal to `<=`, greater than `>`, greater than or equal to `>=`, equal to `==`, and not equal to `!=`, reference equals `===`, reference not equals `!==` - -* Boolean operators: not `!`, and `&&`, or `||` - -* Bitwise operators: shift left `<<`, shift right `>>`, unsigned shift `>>>`, and `&`, or `|`, xor `^`, not `~` - -* Shortcuts for list, map access using the dot `.` operator - -* Native support for regular expressions with `/pattern/`, `=~`, and `==~` +* Syntax: Extends Java's syntax with a subset of Groovy for ease of use. See the <>. +* Optimizations: Designed specifically for Elasticsearch scripting. [[painless-examples]] [float] @@ -74,7 +65,7 @@ PUT hockey/player/_bulk?refresh [float] === Accessing Doc Values from Painless -Document values can be accessed from a `Map` named `doc`. +Document values can be accessed from a `Map` named `doc`. For example, the following script calculates a player's total goals. This example uses a strongly typed `int` and a `for` loop. @@ -268,528 +259,27 @@ 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. -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] == Painless API -The following types are available for use in the Painless language. Most types and methods map directly to their Java equivalents--for more information, see the corresponding https://docs.oracle.com/javase/8/docs/api/java/lang/package-summary.html[Javadoc]. +The following Java packages are available for use in the Painless language: +* https://docs.oracle.com/javase/8/docs/api/java/lang/package-summary.html[java.lang] +* https://docs.oracle.com/javase/8/docs/api/java/math/package-summary.html[java.math] +* https://docs.oracle.com/javase/8/docs/api/java/text/package-summary.html[java.text] +* https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html[java.time] +* https://docs.oracle.com/javase/8/docs/api/java/time/chrono/package-summary.html[java.time.chrono] +* https://docs.oracle.com/javase/8/docs/api/java/time/format/package-summary.html[java.time.format] +* https://docs.oracle.com/javase/8/docs/api/java/time/temporal/package-summary.html[java.time.temporal] +* https://docs.oracle.com/javase/8/docs/api/java/time/zone/package-summary.html[java.time.zone] +* https://docs.oracle.com/javase/8/docs/api/java/util/package-summary.html[java.util] +* https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html[java.util.function] +* https://docs.oracle.com/javase/8/docs/api/java/util/regex/package-summary.html[java.util.regex] +* https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html[java.util.stream] -[float] -=== Dynamic Types +Note that unsafe classes and methods are not included, there is no support for: -* `def` (This type can be used to represent any other type.) - -[float] -=== Basic Types - -* `void` -* `boolean` -* `short` -* `char` -* `int` -* `long` -* `float` -* `double` - -[float] -=== Complex Types - -Non-static methods/members in superclasses are available to subclasses. -Generic types with unspecified generic parameters are parameters of type `def`. - ------ -ArithmeticException extends Exception - () ------ - ------ -ArrayList extends List - () ------ - ------ -ArrayList extends List - () ------ - ------ -ArrayList extends List - () ------ - ------ -Boolean extends Object - (boolean) - static Boolean valueOf(boolean) - boolean booleanValue() ------ - ------ -Character extends Object - (char) - static Character valueOf(char) - char charValue() - static char MIN_VALUE - static char MAX_VALUE ------ - ------ -CharSequence extends Object - char charAt(int) - int length() ------ - ------ -Collection extends Object - boolean add(def) - void clear() - boolean contains(def) - boolean isEmpty() - Iterator iterator() - boolean remove(def) - int size() ------ - ------ -Collection extends Object - boolean add(Object) - void clear() - boolean contains(Object) - boolean isEmpty() - Iterator iterator() - boolean remove(Object) - int size() ------ - ------ -Collection extends Object - boolean add(String) - void clear() - boolean contains(String) - boolean isEmpty() - Iterator iterator() - boolean remove(String) - int size() ------ - ------ -Double extends Number - (double) - static Double valueOf(double) - static double MIN_VALUE - static double MAX_VALUE ------ - ------ -Exception extends Object - String getMessage() ------ - ------ -Float extends Number - (float) - static Float valueOf(float) - static float MIN_VALUE - static float MAX_VALUE ------ - ------ -HashMap extends Map - () ------ - ------ -HashMap extends Map - () ------ - ------ -HashMap extends Map - () ------ - ------ -HashMap extends Map - () ------ - ------ -IllegalArgument extends Exception - () ------ - ------ -IllegalState extends Exception - () ------ - ------ -Integer extends Number - (int) - static Integer valueOf(int) - static int MIN_VALUE - static int MAX_VALUE ------ - ------ -Iterator extends Object - boolean hasNext() - def next() - void remove() ------ - ------ -Iterator extends Object - boolean hasNext() - String next() - void remove() ------ - ------ -List extends Collection - def set(int, def) - def get(int) - def remove(int) ------ - ------ -List extends Collection - Object set(int, Object) - Object get(int) - Object remove(int) ------ - ------ -List extends Collection - String set(int, String) - String get(int) - String remove(int) ------ - ------ -Long extends Number - (long) - static Long valueOf(long) - static long MIN_VALUE - static long MAX_VALUE ------ - ------ -Map extends Object - def put (def, def) - def get (def) - def remove (def) - boolean isEmpty() - int size() - boolean containsKey(def) - boolean containsValue(def) - Set keySet() - Collection values() ------ - ------ -Map extends Object - Object put (Object, Object) - Object get (Object) - Object remove (Object) - boolean isEmpty() - int size() - boolean containsKey(Object) - boolean containsValue(Object) - Set keySet() - Collection values() ------ - ------ -Map extends Object - def put (String, def) - def get (String) - def remove (String) - boolean isEmpty() - int size() - boolean containsKey(String) - boolean containsValue(def) - Set keySet() - Collection values() ------ - ------ -Map extends Object - Object put (String, Object) - Object get (String) - Object remove (String) - boolean isEmpty() - int size() - boolean containsKey(String) - boolean containsValue(Object) - Set keySet() - Collection values() ------ - ------ -Number extends Object - short shortValue() - short shortValue() - int intValue() - long longValue() - float floatValue() - double doubleValue() ------ - ------ -Object - String toString() - boolean equals(Object) - int hashCode() ------ - ------ -Set extends Collection ------ - ------ -Set extends Collection ------ - ------ -Set extends Collection ------ - ------ -Short extends Number - (short) - static Short valueOf(short) - static short MIN_VALUE - static short MAX_VALUE ------ - ------ -String extends CharSequence - (String) - int codePointAt(int) - int compareTo(String) - String concat(String) - boolean endsWith(String) - int indexOf(String, int) - boolean isEmpty() - String replace(CharSequence, CharSequence) - boolean startsWith(String) - String substring(int, int) - char[] toCharArray() - String trim() ------ - ------ -NumberFormatException extends Exception - () ------ - ------ -Void extends Object ------ - -[float] -==== Utility Classes - ------ -Math - static double abs(double) - static float fabs(float) - static long labs(long) - static int iabs(int) - static double acos(double) - static double asin(double) - static double atan(double) - static double atan2(double) - static double cbrt(double) - static double ceil(double) - static double cos(double) - static double cosh(double) - static double exp(double) - static double expm1(double) - static double floor(double) - static double hypt(double, double) - static double abs(double) - static double log(double) - static double log10(double) - static double log1p(double) - static double max(double, double) - static float fmax(float, float) - static long lmax(long, long) - static int imax(int, int) - static double min(double, double) - static float fmin(float, float) - static long lmin(long, long) - static int imin(int, int) - static double pow(double, double) - static double random() - static double rint(double) - static long round(double) - static double sin(double) - static double sinh(double) - static double sqrt(double) - static double tan(double) - static double tanh(double) - static double toDegrees(double) - static double toRadians(double) ------ - ------ -Utility - static boolean NumberToboolean(Number) - static char NumberTochar(Number) - static Boolean NumberToBoolean(Number) - static Short NumberToShort(Number) - static Character NumberToCharacter(Number) - static Integer NumberToInteger(Number) - static Long NumberToLong(Number) - static Float NumberToFloat(Number) - static Double NumberToDouble(Number) - static byte booleanTobyte(boolean) - static short booleanToshort(boolean) - static char booleanTochar(boolean) - static int booleanToint(boolean) - static long booleanTolong(boolean) - static float booleanTofloat(boolean) - static double booleanTodouble(boolean) - static Integer booleanToInteger(boolean) - static byte BooleanTobyte(Boolean) - static short BooleanToshort(Boolean) - static char BooleanTochar(Boolean) - static int BooleanToint(Boolean) - static long BooleanTolong(Boolean) - static float BooleanTofloat(Boolean) - static double BooleanTodouble(Boolean) - static Byte BooleanToByte(Boolean) - static Short BooleanToShort(Boolean) - static Character BooleanToCharacter(Boolean) - static Integer BooleanToInteger(Boolean) - static Long BooleanToLong(Boolean) - static Float BooleanToFloat(Boolean) - static Double BooleanToDouble(Boolean) - static boolean byteToboolean(byte) - static Short byteToShort(byte) - static Character byteToCharacter(byte) - static Integer byteToInteger(byte) - static Long byteToLong(byte) - static Float byteToFloat(byte) - static Double byteToDouble(byte) - static boolean ByteToboolean(Byte) - static char ByteTochar(Byte) - static boolean shortToboolean(short) - static Byte shortToByte(short) - static Character shortToCharacter(short) - static Integer shortToInteger(short) - static Long shortToLong(short) - static Float shortToFloat(short) - static Double shortToDouble(short) - static boolean ShortToboolean(Short) - static char ShortTochar(Short) - static boolean charToboolean(char) - static Byte charToByte(char) - static Short charToShort(char) - static Integer charToInteger(char) - static Long charToLong(char) - static Float charToFloat(char) - static Double charToDouble(char) - static boolean CharacterToboolean(Character) - static byte CharacterTobyte(Character) - static short CharacterToshort(Character) - static int CharacterToint(Character) - static long CharacterTolong(Character) - static float CharacterTofloat(Character) - static double CharacterTodouble(Character) - static Boolean CharacterToBoolean(Character) - static Byte CharacterToByte(Character) - static Short CharacterToShort(Character) - static Integer CharacterToInteger(Character) - static Long CharacterToLong(Character) - static Float CharacterToFloat(Character) - static Double CharacterToDouble(Character) - static boolean intToboolean(int) - static Byte intToByte(int) - static Short intToShort(int) - static Character intToCharacter(int) - static Long intToLong(int) - static Float intToFloat(int) - static Double intToDouble(int) - static boolean IntegerToboolean(Integer) - static char IntegerTochar(Integer) - static boolean longToboolean(long) - static Byte longToByte(long) - static Short longToShort(long) - static Character longToCharacter(long) - static Integer longToInteger(long) - static Float longToFloat(long) - static Double longToDouble(long) - static boolean LongToboolean(Long) - static char LongTochar(Long) - static boolean floatToboolean(float) - static Byte floatToByte(float) - static Short floatToShort(float) - static Character floatToCharacter(float) - static Integer floatToInteger(float) - static Long floatToLong(float) - static Double floatToDouble(float) - static boolean FloatToboolean(Float) - static char FloatTochar(Float) - static boolean doubleToboolean(double) - static Byte doubleToByte(double) - static Short doubleToShort(double) - static Character doubleToCharacter(double) - static Integer doubleToInteger(double) - static Long doubleToLong(double) - static Float doubleToFloat(double) - static boolean DoubleToboolean(Double) - static char DoubleTochar(Double) ------ - ------ -Def - static boolean defToboolean(def) - static byte defTobyte(def) - static short defToshort(def) - static char defTochar(def) - static int defToint(def) - static long defTolong(def) - static float defTofloat(def) - static double defTodouble(def) - static Boolean defToBoolean(def) - static Byte defToByte(def) - static Character defToCharacter(def) - static Integer defToInteger(def) - static Long defToLong(def) - static Float defToFloat(def) - static Double defToDouble(def) ------ +* Manipulation of processes and threads +* Input/Output +* Reflection diff --git a/modules/lang-painless/src/main/antlr/PainlessLexer.g4 b/modules/lang-painless/src/main/antlr/PainlessLexer.g4 index ca469eed69a..027b1b370d1 100644 --- a/modules/lang-painless/src/main/antlr/PainlessLexer.g4 +++ b/modules/lang-painless/src/main/antlr/PainlessLexer.g4 @@ -52,6 +52,7 @@ TRY: 'try'; CATCH: 'catch'; THROW: 'throw'; THIS: 'this'; +INSTANCEOF: 'instanceof'; BOOLNOT: '!'; BWNOT: '~'; diff --git a/modules/lang-painless/src/main/antlr/PainlessLexer.tokens b/modules/lang-painless/src/main/antlr/PainlessLexer.tokens index 3968464f015..8bb8c7e4448 100644 --- a/modules/lang-painless/src/main/antlr/PainlessLexer.tokens +++ b/modules/lang-painless/src/main/antlr/PainlessLexer.tokens @@ -22,62 +22,63 @@ TRY=21 CATCH=22 THROW=23 THIS=24 -BOOLNOT=25 -BWNOT=26 -MUL=27 -DIV=28 -REM=29 -ADD=30 -SUB=31 -LSH=32 -RSH=33 -USH=34 -LT=35 -LTE=36 -GT=37 -GTE=38 -EQ=39 -EQR=40 -NE=41 -NER=42 -BWAND=43 -XOR=44 -BWOR=45 -BOOLAND=46 -BOOLOR=47 -COND=48 -COLON=49 -REF=50 -ARROW=51 -FIND=52 -MATCH=53 -INCR=54 -DECR=55 -ASSIGN=56 -AADD=57 -ASUB=58 -AMUL=59 -ADIV=60 -AREM=61 -AAND=62 -AXOR=63 -AOR=64 -ALSH=65 -ARSH=66 -AUSH=67 -OCTAL=68 -HEX=69 -INTEGER=70 -DECIMAL=71 -STRING=72 -REGEX=73 -TRUE=74 -FALSE=75 -NULL=76 -TYPE=77 -ID=78 -DOTINTEGER=79 -DOTID=80 +INSTANCEOF=25 +BOOLNOT=26 +BWNOT=27 +MUL=28 +DIV=29 +REM=30 +ADD=31 +SUB=32 +LSH=33 +RSH=34 +USH=35 +LT=36 +LTE=37 +GT=38 +GTE=39 +EQ=40 +EQR=41 +NE=42 +NER=43 +BWAND=44 +XOR=45 +BWOR=46 +BOOLAND=47 +BOOLOR=48 +COND=49 +COLON=50 +REF=51 +ARROW=52 +FIND=53 +MATCH=54 +INCR=55 +DECR=56 +ASSIGN=57 +AADD=58 +ASUB=59 +AMUL=60 +ADIV=61 +AREM=62 +AAND=63 +AXOR=64 +AOR=65 +ALSH=66 +ARSH=67 +AUSH=68 +OCTAL=69 +HEX=70 +INTEGER=71 +DECIMAL=72 +STRING=73 +REGEX=74 +TRUE=75 +FALSE=76 +NULL=77 +TYPE=78 +ID=79 +DOTINTEGER=80 +DOTID=81 '{'=3 '}'=4 '['=5 @@ -100,49 +101,50 @@ DOTID=80 'catch'=22 'throw'=23 'this'=24 -'!'=25 -'~'=26 -'*'=27 -'/'=28 -'%'=29 -'+'=30 -'-'=31 -'<<'=32 -'>>'=33 -'>>>'=34 -'<'=35 -'<='=36 -'>'=37 -'>='=38 -'=='=39 -'==='=40 -'!='=41 -'!=='=42 -'&'=43 -'^'=44 -'|'=45 -'&&'=46 -'||'=47 -'?'=48 -':'=49 -'::'=50 -'->'=51 -'=~'=52 -'==~'=53 -'++'=54 -'--'=55 -'='=56 -'+='=57 -'-='=58 -'*='=59 -'/='=60 -'%='=61 -'&='=62 -'^='=63 -'|='=64 -'<<='=65 -'>>='=66 -'>>>='=67 -'true'=74 -'false'=75 -'null'=76 +'instanceof'=25 +'!'=26 +'~'=27 +'*'=28 +'/'=29 +'%'=30 +'+'=31 +'-'=32 +'<<'=33 +'>>'=34 +'>>>'=35 +'<'=36 +'<='=37 +'>'=38 +'>='=39 +'=='=40 +'==='=41 +'!='=42 +'!=='=43 +'&'=44 +'^'=45 +'|'=46 +'&&'=47 +'||'=48 +'?'=49 +':'=50 +'::'=51 +'->'=52 +'=~'=53 +'==~'=54 +'++'=55 +'--'=56 +'='=57 +'+='=58 +'-='=59 +'*='=60 +'/='=61 +'%='=62 +'&='=63 +'^='=64 +'|='=65 +'<<='=66 +'>>='=67 +'>>>='=68 +'true'=75 +'false'=76 +'null'=77 diff --git a/modules/lang-painless/src/main/antlr/PainlessParser.g4 b/modules/lang-painless/src/main/antlr/PainlessParser.g4 index 10471056acd..7e28b0ad258 100644 --- a/modules/lang-painless/src/main/antlr/PainlessParser.g4 +++ b/modules/lang-painless/src/main/antlr/PainlessParser.g4 @@ -105,6 +105,7 @@ expression returns [boolean s = true] | expression ( FIND | MATCH ) expression { $s = false; } # binary | expression ( LSH | RSH | USH ) expression { $s = false; } # binary | expression ( LT | LTE | GT | GTE ) expression { $s = false; } # comp + | expression INSTANCEOF decltype { $s = false; } # instanceof | expression ( EQ | EQR | NE | NER ) expression { $s = false; } # comp | expression BWAND expression { $s = false; } # binary | expression XOR expression { $s = false; } # binary diff --git a/modules/lang-painless/src/main/antlr/PainlessParser.tokens b/modules/lang-painless/src/main/antlr/PainlessParser.tokens index 3968464f015..8bb8c7e4448 100644 --- a/modules/lang-painless/src/main/antlr/PainlessParser.tokens +++ b/modules/lang-painless/src/main/antlr/PainlessParser.tokens @@ -22,62 +22,63 @@ TRY=21 CATCH=22 THROW=23 THIS=24 -BOOLNOT=25 -BWNOT=26 -MUL=27 -DIV=28 -REM=29 -ADD=30 -SUB=31 -LSH=32 -RSH=33 -USH=34 -LT=35 -LTE=36 -GT=37 -GTE=38 -EQ=39 -EQR=40 -NE=41 -NER=42 -BWAND=43 -XOR=44 -BWOR=45 -BOOLAND=46 -BOOLOR=47 -COND=48 -COLON=49 -REF=50 -ARROW=51 -FIND=52 -MATCH=53 -INCR=54 -DECR=55 -ASSIGN=56 -AADD=57 -ASUB=58 -AMUL=59 -ADIV=60 -AREM=61 -AAND=62 -AXOR=63 -AOR=64 -ALSH=65 -ARSH=66 -AUSH=67 -OCTAL=68 -HEX=69 -INTEGER=70 -DECIMAL=71 -STRING=72 -REGEX=73 -TRUE=74 -FALSE=75 -NULL=76 -TYPE=77 -ID=78 -DOTINTEGER=79 -DOTID=80 +INSTANCEOF=25 +BOOLNOT=26 +BWNOT=27 +MUL=28 +DIV=29 +REM=30 +ADD=31 +SUB=32 +LSH=33 +RSH=34 +USH=35 +LT=36 +LTE=37 +GT=38 +GTE=39 +EQ=40 +EQR=41 +NE=42 +NER=43 +BWAND=44 +XOR=45 +BWOR=46 +BOOLAND=47 +BOOLOR=48 +COND=49 +COLON=50 +REF=51 +ARROW=52 +FIND=53 +MATCH=54 +INCR=55 +DECR=56 +ASSIGN=57 +AADD=58 +ASUB=59 +AMUL=60 +ADIV=61 +AREM=62 +AAND=63 +AXOR=64 +AOR=65 +ALSH=66 +ARSH=67 +AUSH=68 +OCTAL=69 +HEX=70 +INTEGER=71 +DECIMAL=72 +STRING=73 +REGEX=74 +TRUE=75 +FALSE=76 +NULL=77 +TYPE=78 +ID=79 +DOTINTEGER=80 +DOTID=81 '{'=3 '}'=4 '['=5 @@ -100,49 +101,50 @@ DOTID=80 'catch'=22 'throw'=23 'this'=24 -'!'=25 -'~'=26 -'*'=27 -'/'=28 -'%'=29 -'+'=30 -'-'=31 -'<<'=32 -'>>'=33 -'>>>'=34 -'<'=35 -'<='=36 -'>'=37 -'>='=38 -'=='=39 -'==='=40 -'!='=41 -'!=='=42 -'&'=43 -'^'=44 -'|'=45 -'&&'=46 -'||'=47 -'?'=48 -':'=49 -'::'=50 -'->'=51 -'=~'=52 -'==~'=53 -'++'=54 -'--'=55 -'='=56 -'+='=57 -'-='=58 -'*='=59 -'/='=60 -'%='=61 -'&='=62 -'^='=63 -'|='=64 -'<<='=65 -'>>='=66 -'>>>='=67 -'true'=74 -'false'=75 -'null'=76 +'instanceof'=25 +'!'=26 +'~'=27 +'*'=28 +'/'=29 +'%'=30 +'+'=31 +'-'=32 +'<<'=33 +'>>'=34 +'>>>'=35 +'<'=36 +'<='=37 +'>'=38 +'>='=39 +'=='=40 +'==='=41 +'!='=42 +'!=='=43 +'&'=44 +'^'=45 +'|'=46 +'&&'=47 +'||'=48 +'?'=49 +':'=50 +'::'=51 +'->'=52 +'=~'=53 +'==~'=54 +'++'=55 +'--'=56 +'='=57 +'+='=58 +'-='=59 +'*='=60 +'/='=61 +'%='=62 +'&='=63 +'^='=64 +'|='=65 +'<<='=66 +'>>='=67 +'>>>='=68 +'true'=75 +'false'=76 +'null'=77 diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Augmentation.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Augmentation.java index 4bca673b4dc..edd0eeab67f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Augmentation.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Augmentation.java @@ -64,6 +64,30 @@ public class Augmentation { return false; } + /** Converts this Iterable to a Collection. Returns the original Iterable if it is already a Collection. */ + public static Collection asCollection(Iterable receiver) { + if (receiver instanceof Collection) { + return (Collection)receiver; + } + List list = new ArrayList<>(); + for (T t : receiver) { + list.add(t); + } + return list; + } + + /** Converts this Iterable to a List. Returns the original Iterable if it is already a List. */ + public static List asList(Iterable receiver) { + if (receiver instanceof List) { + return (List)receiver; + } + List list = new ArrayList<>(); + for (T t : receiver) { + list.add(t); + } + return list; + } + /** Counts the number of occurrences which satisfy the given predicate from inside this Iterable. */ public static int count(Iterable receiver, Predicate predicate) { int count = 0; @@ -155,6 +179,17 @@ public class Augmentation { return sb.toString(); } + /** + * Sums the result of an Iterable + */ + public static double sum(Iterable receiver) { + double sum = 0; + for (T t : receiver) { + sum += t.doubleValue(); + } + return sum; + } + /** * Sums the result of applying a function to each item of an Iterable. */ 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 f512ad20d7e..6d791979243 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 @@ -22,14 +22,14 @@ class PainlessLexer extends Lexer { public static final int WS=1, COMMENT=2, LBRACK=3, RBRACK=4, LBRACE=5, RBRACE=6, LP=7, RP=8, DOT=9, COMMA=10, SEMICOLON=11, IF=12, ELSE=13, WHILE=14, DO=15, FOR=16, CONTINUE=17, - BREAK=18, RETURN=19, NEW=20, TRY=21, CATCH=22, THROW=23, THIS=24, BOOLNOT=25, - BWNOT=26, MUL=27, DIV=28, REM=29, ADD=30, SUB=31, LSH=32, RSH=33, USH=34, - LT=35, LTE=36, GT=37, GTE=38, EQ=39, EQR=40, NE=41, NER=42, BWAND=43, - XOR=44, BWOR=45, BOOLAND=46, BOOLOR=47, COND=48, COLON=49, REF=50, ARROW=51, - FIND=52, MATCH=53, INCR=54, DECR=55, ASSIGN=56, AADD=57, ASUB=58, AMUL=59, - ADIV=60, AREM=61, AAND=62, AXOR=63, AOR=64, ALSH=65, ARSH=66, AUSH=67, - OCTAL=68, HEX=69, INTEGER=70, DECIMAL=71, STRING=72, REGEX=73, TRUE=74, - FALSE=75, NULL=76, TYPE=77, ID=78, DOTINTEGER=79, DOTID=80; + BREAK=18, RETURN=19, NEW=20, TRY=21, CATCH=22, THROW=23, THIS=24, INSTANCEOF=25, + BOOLNOT=26, BWNOT=27, MUL=28, DIV=29, REM=30, ADD=31, SUB=32, LSH=33, + RSH=34, USH=35, LT=36, LTE=37, GT=38, GTE=39, EQ=40, EQR=41, NE=42, NER=43, + BWAND=44, XOR=45, BWOR=46, BOOLAND=47, BOOLOR=48, COND=49, COLON=50, REF=51, + ARROW=52, FIND=53, MATCH=54, INCR=55, DECR=56, ASSIGN=57, AADD=58, ASUB=59, + AMUL=60, ADIV=61, AREM=62, AAND=63, AXOR=64, AOR=65, ALSH=66, ARSH=67, + AUSH=68, OCTAL=69, HEX=70, INTEGER=71, DECIMAL=72, STRING=73, REGEX=74, + TRUE=75, FALSE=76, NULL=77, TYPE=78, ID=79, DOTINTEGER=80, DOTID=81; public static final int AFTER_DOT = 1; public static String[] modeNames = { "DEFAULT_MODE", "AFTER_DOT" @@ -38,9 +38,9 @@ class PainlessLexer extends Lexer { public static final String[] ruleNames = { "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP", "DOT", "COMMA", "SEMICOLON", "IF", "ELSE", "WHILE", "DO", "FOR", "CONTINUE", - "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW", "THIS", "BOOLNOT", - "BWNOT", "MUL", "DIV", "REM", "ADD", "SUB", "LSH", "RSH", "USH", "LT", - "LTE", "GT", "GTE", "EQ", "EQR", "NE", "NER", "BWAND", "XOR", "BWOR", + "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW", "THIS", "INSTANCEOF", + "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD", "SUB", "LSH", "RSH", "USH", + "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE", "NER", "BWAND", "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "REF", "ARROW", "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB", "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH", "OCTAL", "HEX", "INTEGER", "DECIMAL", @@ -51,20 +51,20 @@ class PainlessLexer extends Lexer { private static final String[] _LITERAL_NAMES = { null, null, null, "'{'", "'}'", "'['", "']'", "'('", "')'", "'.'", "','", "';'", "'if'", "'else'", "'while'", "'do'", "'for'", "'continue'", "'break'", - "'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'", "'!'", "'~'", - "'*'", "'/'", "'%'", "'+'", "'-'", "'<<'", "'>>'", "'>>>'", "'<'", "'<='", - "'>'", "'>='", "'=='", "'==='", "'!='", "'!=='", "'&'", "'^'", "'|'", - "'&&'", "'||'", "'?'", "':'", "'::'", "'->'", "'=~'", "'==~'", "'++'", - "'--'", "'='", "'+='", "'-='", "'*='", "'/='", "'%='", "'&='", "'^='", - "'|='", "'<<='", "'>>='", "'>>>='", null, null, null, null, null, null, - "'true'", "'false'", "'null'" + "'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'", "'instanceof'", + "'!'", "'~'", "'*'", "'/'", "'%'", "'+'", "'-'", "'<<'", "'>>'", "'>>>'", + "'<'", "'<='", "'>'", "'>='", "'=='", "'==='", "'!='", "'!=='", "'&'", + "'^'", "'|'", "'&&'", "'||'", "'?'", "':'", "'::'", "'->'", "'=~'", "'==~'", + "'++'", "'--'", "'='", "'+='", "'-='", "'*='", "'/='", "'%='", "'&='", + "'^='", "'|='", "'<<='", "'>>='", "'>>>='", null, null, null, null, null, + null, "'true'", "'false'", "'null'" }; private static final String[] _SYMBOLIC_NAMES = { null, "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP", "DOT", "COMMA", "SEMICOLON", "IF", "ELSE", "WHILE", "DO", "FOR", "CONTINUE", - "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW", "THIS", "BOOLNOT", - "BWNOT", "MUL", "DIV", "REM", "ADD", "SUB", "LSH", "RSH", "USH", "LT", - "LTE", "GT", "GTE", "EQ", "EQR", "NE", "NER", "BWAND", "XOR", "BWOR", + "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW", "THIS", "INSTANCEOF", + "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD", "SUB", "LSH", "RSH", "USH", + "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE", "NER", "BWAND", "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "REF", "ARROW", "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB", "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH", "OCTAL", "HEX", "INTEGER", "DECIMAL", @@ -128,11 +128,11 @@ class PainlessLexer extends Lexer { @Override public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { switch (ruleIndex) { - case 27: + case 28: return DIV_sempred((RuleContext)_localctx, predIndex); - case 72: + case 73: return REGEX_sempred((RuleContext)_localctx, predIndex); - case 76: + case 77: return TYPE_sempred((RuleContext)_localctx, predIndex); } return true; @@ -160,7 +160,7 @@ class PainlessLexer extends Lexer { } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2R\u0239\b\1\b\1\4"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2S\u0246\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"+ @@ -169,196 +169,201 @@ class PainlessLexer extends Lexer { "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64"+ "\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t"+ "=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4"+ - "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\3\2\6\2\u00a6\n\2"+ - "\r\2\16\2\u00a7\3\2\3\2\3\3\3\3\3\3\3\3\7\3\u00b0\n\3\f\3\16\3\u00b3\13"+ - "\3\3\3\3\3\3\3\3\3\3\3\7\3\u00ba\n\3\f\3\16\3\u00bd\13\3\3\3\3\3\5\3\u00c1"+ - "\n\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3"+ - "\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\17\3\17"+ - "\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\22\3\22\3\22"+ - "\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24"+ - "\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\27"+ - "\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31"+ - "\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\37"+ - "\3\37\3 \3 \3!\3!\3!\3\"\3\"\3\"\3#\3#\3#\3#\3$\3$\3%\3%\3%\3&\3&\3\'"+ - "\3\'\3\'\3(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3+\3+\3+\3+\3,\3,\3-\3-\3.\3.\3"+ - "/\3/\3/\3\60\3\60\3\60\3\61\3\61\3\62\3\62\3\63\3\63\3\63\3\64\3\64\3"+ - "\64\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\38\38\38\39\39\3"+ - ":\3:\3:\3;\3;\3;\3<\3<\3<\3=\3=\3=\3>\3>\3>\3?\3?\3?\3@\3@\3@\3A\3A\3"+ - "A\3B\3B\3B\3B\3C\3C\3C\3C\3D\3D\3D\3D\3D\3E\3E\6E\u019a\nE\rE\16E\u019b"+ - "\3E\5E\u019f\nE\3F\3F\3F\6F\u01a4\nF\rF\16F\u01a5\3F\5F\u01a9\nF\3G\3"+ - "G\3G\7G\u01ae\nG\fG\16G\u01b1\13G\5G\u01b3\nG\3G\5G\u01b6\nG\3H\3H\3H"+ - "\7H\u01bb\nH\fH\16H\u01be\13H\5H\u01c0\nH\3H\3H\6H\u01c4\nH\rH\16H\u01c5"+ - "\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\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"+ + "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\3\2\6\2\u00a8"+ + "\n\2\r\2\16\2\u00a9\3\2\3\2\3\3\3\3\3\3\3\3\7\3\u00b2\n\3\f\3\16\3\u00b5"+ + "\13\3\3\3\3\3\3\3\3\3\3\3\7\3\u00bc\n\3\f\3\16\3\u00bf\13\3\3\3\3\3\5"+ + "\3\u00c3\n\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3"+ + "\n\3\n\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16"+ + "\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\22"+ + "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23"+ + "\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\26\3\26\3\26"+ + "\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\31"+ + "\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32"+ + "\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3 \3 \3!"+ + "\3!\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3$\3%\3%\3&\3&\3&\3\'\3\'\3(\3(\3(\3"+ + ")\3)\3)\3*\3*\3*\3*\3+\3+\3+\3,\3,\3,\3,\3-\3-\3.\3.\3/\3/\3\60\3\60\3"+ + "\60\3\61\3\61\3\61\3\62\3\62\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\65\3"+ + "\66\3\66\3\66\3\67\3\67\3\67\3\67\38\38\38\39\39\39\3:\3:\3;\3;\3;\3<"+ + "\3<\3<\3=\3=\3=\3>\3>\3>\3?\3?\3?\3@\3@\3@\3A\3A\3A\3B\3B\3B\3C\3C\3C"+ + "\3C\3D\3D\3D\3D\3E\3E\3E\3E\3E\3F\3F\6F\u01a7\nF\rF\16F\u01a8\3F\5F\u01ac"+ + "\nF\3G\3G\3G\6G\u01b1\nG\rG\16G\u01b2\3G\5G\u01b6\nG\3H\3H\3H\7H\u01bb"+ + "\nH\fH\16H\u01be\13H\5H\u01c0\nH\3H\5H\u01c3\nH\3I\3I\3I\7I\u01c8\nI\f"+ + "I\16I\u01cb\13I\5I\u01cd\nI\3I\3I\6I\u01d1\nI\rI\16I\u01d2\5I\u01d5\n"+ + "I\3I\3I\5I\u01d9\nI\3I\6I\u01dc\nI\rI\16I\u01dd\5I\u01e0\nI\3I\5I\u01e3"+ + "\nI\3J\3J\3J\3J\3J\3J\7J\u01eb\nJ\fJ\16J\u01ee\13J\3J\3J\3J\3J\3J\3J\3"+ + "J\7J\u01f7\nJ\fJ\16J\u01fa\13J\3J\5J\u01fd\nJ\3K\3K\3K\3K\6K\u0203\nK"+ + "\rK\16K\u0204\3K\3K\7K\u0209\nK\fK\16K\u020c\13K\3K\3K\3L\3L\3L\3L\3L"+ + "\3M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3O\3O\3O\3O\7O\u0224\nO\fO\16O\u0227"+ + "\13O\3O\3O\3P\3P\7P\u022d\nP\fP\16P\u0230\13P\3Q\3Q\3Q\7Q\u0235\nQ\fQ"+ + "\16Q\u0238\13Q\5Q\u023a\nQ\3Q\3Q\3R\3R\7R\u0240\nR\fR\16R\u0243\13R\3"+ + "R\3R\6\u00b3\u00bd\u01ec\u01f8\2S\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\u0082B\u0084C\u0086"+ + "D\u0088E\u008aF\u008cG\u008eH\u0090I\u0092J\u0094K\u0096L\u0098M\u009a"+ + "N\u009cO\u009eP\u00a0Q\u00a2R\u00a4S\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\2FFHHN"+ + "Nffhhnn\4\2GGgg\4\2--//\4\2HHhh\4\2$$^^\4\2\f\f\61\61\3\2\f\f\t\2WWee"+ + "kknouuwwzz\5\2C\\aac|\6\2\62;C\\aac|\u0266\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\2"+ + "B\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\2\u00a0\3\2\2\2\3\u00a2\3\2\2\2\3\u00a4"+ + "\3\2\2\2\4\u00a7\3\2\2\2\6\u00c2\3\2\2\2\b\u00c6\3\2\2\2\n\u00c8\3\2\2"+ + "\2\f\u00ca\3\2\2\2\16\u00cc\3\2\2\2\20\u00ce\3\2\2\2\22\u00d0\3\2\2\2"+ + "\24\u00d2\3\2\2\2\26\u00d6\3\2\2\2\30\u00d8\3\2\2\2\32\u00da\3\2\2\2\34"+ + "\u00dd\3\2\2\2\36\u00e2\3\2\2\2 \u00e8\3\2\2\2\"\u00eb\3\2\2\2$\u00ef"+ + "\3\2\2\2&\u00f8\3\2\2\2(\u00fe\3\2\2\2*\u0105\3\2\2\2,\u0109\3\2\2\2."+ + "\u010d\3\2\2\2\60\u0113\3\2\2\2\62\u0119\3\2\2\2\64\u011e\3\2\2\2\66\u0129"+ + "\3\2\2\28\u012b\3\2\2\2:\u012d\3\2\2\2<\u012f\3\2\2\2>\u0132\3\2\2\2@"+ + "\u0134\3\2\2\2B\u0136\3\2\2\2D\u0138\3\2\2\2F\u013b\3\2\2\2H\u013e\3\2"+ + "\2\2J\u0142\3\2\2\2L\u0144\3\2\2\2N\u0147\3\2\2\2P\u0149\3\2\2\2R\u014c"+ + "\3\2\2\2T\u014f\3\2\2\2V\u0153\3\2\2\2X\u0156\3\2\2\2Z\u015a\3\2\2\2\\"+ + "\u015c\3\2\2\2^\u015e\3\2\2\2`\u0160\3\2\2\2b\u0163\3\2\2\2d\u0166\3\2"+ + "\2\2f\u0168\3\2\2\2h\u016a\3\2\2\2j\u016d\3\2\2\2l\u0170\3\2\2\2n\u0173"+ + "\3\2\2\2p\u0177\3\2\2\2r\u017a\3\2\2\2t\u017d\3\2\2\2v\u017f\3\2\2\2x"+ + "\u0182\3\2\2\2z\u0185\3\2\2\2|\u0188\3\2\2\2~\u018b\3\2\2\2\u0080\u018e"+ + "\3\2\2\2\u0082\u0191\3\2\2\2\u0084\u0194\3\2\2\2\u0086\u0197\3\2\2\2\u0088"+ + "\u019b\3\2\2\2\u008a\u019f\3\2\2\2\u008c\u01a4\3\2\2\2\u008e\u01ad\3\2"+ + "\2\2\u0090\u01bf\3\2\2\2\u0092\u01cc\3\2\2\2\u0094\u01fc\3\2\2\2\u0096"+ + "\u01fe\3\2\2\2\u0098\u020f\3\2\2\2\u009a\u0214\3\2\2\2\u009c\u021a\3\2"+ + "\2\2\u009e\u021f\3\2\2\2\u00a0\u022a\3\2\2\2\u00a2\u0239\3\2\2\2\u00a4"+ + "\u023d\3\2\2\2\u00a6\u00a8\t\2\2\2\u00a7\u00a6\3\2\2\2\u00a8\u00a9\3\2"+ + "\2\2\u00a9\u00a7\3\2\2\2\u00a9\u00aa\3\2\2\2\u00aa\u00ab\3\2\2\2\u00ab"+ + "\u00ac\b\2\2\2\u00ac\5\3\2\2\2\u00ad\u00ae\7\61\2\2\u00ae\u00af\7\61\2"+ + "\2\u00af\u00b3\3\2\2\2\u00b0\u00b2\13\2\2\2\u00b1\u00b0\3\2\2\2\u00b2"+ + "\u00b5\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b3\u00b1\3\2\2\2\u00b4\u00b6\3\2"+ + "\2\2\u00b5\u00b3\3\2\2\2\u00b6\u00c3\t\3\2\2\u00b7\u00b8\7\61\2\2\u00b8"+ + "\u00b9\7,\2\2\u00b9\u00bd\3\2\2\2\u00ba\u00bc\13\2\2\2\u00bb\u00ba\3\2"+ + "\2\2\u00bc\u00bf\3\2\2\2\u00bd\u00be\3\2\2\2\u00bd\u00bb\3\2\2\2\u00be"+ + "\u00c0\3\2\2\2\u00bf\u00bd\3\2\2\2\u00c0\u00c1\7,\2\2\u00c1\u00c3\7\61"+ + "\2\2\u00c2\u00ad\3\2\2\2\u00c2\u00b7\3\2\2\2\u00c3\u00c4\3\2\2\2\u00c4"+ + "\u00c5\b\3\2\2\u00c5\7\3\2\2\2\u00c6\u00c7\7}\2\2\u00c7\t\3\2\2\2\u00c8"+ + "\u00c9\7\177\2\2\u00c9\13\3\2\2\2\u00ca\u00cb\7]\2\2\u00cb\r\3\2\2\2\u00cc"+ + "\u00cd\7_\2\2\u00cd\17\3\2\2\2\u00ce\u00cf\7*\2\2\u00cf\21\3\2\2\2\u00d0"+ + "\u00d1\7+\2\2\u00d1\23\3\2\2\2\u00d2\u00d3\7\60\2\2\u00d3\u00d4\3\2\2"+ + "\2\u00d4\u00d5\b\n\3\2\u00d5\25\3\2\2\2\u00d6\u00d7\7.\2\2\u00d7\27\3"+ + "\2\2\2\u00d8\u00d9\7=\2\2\u00d9\31\3\2\2\2\u00da\u00db\7k\2\2\u00db\u00dc"+ + "\7h\2\2\u00dc\33\3\2\2\2\u00dd\u00de\7g\2\2\u00de\u00df\7n\2\2\u00df\u00e0"+ + "\7u\2\2\u00e0\u00e1\7g\2\2\u00e1\35\3\2\2\2\u00e2\u00e3\7y\2\2\u00e3\u00e4"+ + "\7j\2\2\u00e4\u00e5\7k\2\2\u00e5\u00e6\7n\2\2\u00e6\u00e7\7g\2\2\u00e7"+ + "\37\3\2\2\2\u00e8\u00e9\7f\2\2\u00e9\u00ea\7q\2\2\u00ea!\3\2\2\2\u00eb"+ + "\u00ec\7h\2\2\u00ec\u00ed\7q\2\2\u00ed\u00ee\7t\2\2\u00ee#\3\2\2\2\u00ef"+ + "\u00f0\7e\2\2\u00f0\u00f1\7q\2\2\u00f1\u00f2\7p\2\2\u00f2\u00f3\7v\2\2"+ + "\u00f3\u00f4\7k\2\2\u00f4\u00f5\7p\2\2\u00f5\u00f6\7w\2\2\u00f6\u00f7"+ + "\7g\2\2\u00f7%\3\2\2\2\u00f8\u00f9\7d\2\2\u00f9\u00fa\7t\2\2\u00fa\u00fb"+ + "\7g\2\2\u00fb\u00fc\7c\2\2\u00fc\u00fd\7m\2\2\u00fd\'\3\2\2\2\u00fe\u00ff"+ + "\7t\2\2\u00ff\u0100\7g\2\2\u0100\u0101\7v\2\2\u0101\u0102\7w\2\2\u0102"+ + "\u0103\7t\2\2\u0103\u0104\7p\2\2\u0104)\3\2\2\2\u0105\u0106\7p\2\2\u0106"+ + "\u0107\7g\2\2\u0107\u0108\7y\2\2\u0108+\3\2\2\2\u0109\u010a\7v\2\2\u010a"+ + "\u010b\7t\2\2\u010b\u010c\7{\2\2\u010c-\3\2\2\2\u010d\u010e\7e\2\2\u010e"+ + "\u010f\7c\2\2\u010f\u0110\7v\2\2\u0110\u0111\7e\2\2\u0111\u0112\7j\2\2"+ + "\u0112/\3\2\2\2\u0113\u0114\7v\2\2\u0114\u0115\7j\2\2\u0115\u0116\7t\2"+ + "\2\u0116\u0117\7q\2\2\u0117\u0118\7y\2\2\u0118\61\3\2\2\2\u0119\u011a"+ + "\7v\2\2\u011a\u011b\7j\2\2\u011b\u011c\7k\2\2\u011c\u011d\7u\2\2\u011d"+ + "\63\3\2\2\2\u011e\u011f\7k\2\2\u011f\u0120\7p\2\2\u0120\u0121\7u\2\2\u0121"+ + "\u0122\7v\2\2\u0122\u0123\7c\2\2\u0123\u0124\7p\2\2\u0124\u0125\7e\2\2"+ + "\u0125\u0126\7g\2\2\u0126\u0127\7q\2\2\u0127\u0128\7h\2\2\u0128\65\3\2"+ + "\2\2\u0129\u012a\7#\2\2\u012a\67\3\2\2\2\u012b\u012c\7\u0080\2\2\u012c"+ + "9\3\2\2\2\u012d\u012e\7,\2\2\u012e;\3\2\2\2\u012f\u0130\7\61\2\2\u0130"+ + "\u0131\6\36\2\2\u0131=\3\2\2\2\u0132\u0133\7\'\2\2\u0133?\3\2\2\2\u0134"+ + "\u0135\7-\2\2\u0135A\3\2\2\2\u0136\u0137\7/\2\2\u0137C\3\2\2\2\u0138\u0139"+ + "\7>\2\2\u0139\u013a\7>\2\2\u013aE\3\2\2\2\u013b\u013c\7@\2\2\u013c\u013d"+ + "\7@\2\2\u013dG\3\2\2\2\u013e\u013f\7@\2\2\u013f\u0140\7@\2\2\u0140\u0141"+ + "\7@\2\2\u0141I\3\2\2\2\u0142\u0143\7>\2\2\u0143K\3\2\2\2\u0144\u0145\7"+ + ">\2\2\u0145\u0146\7?\2\2\u0146M\3\2\2\2\u0147\u0148\7@\2\2\u0148O\3\2"+ + "\2\2\u0149\u014a\7@\2\2\u014a\u014b\7?\2\2\u014bQ\3\2\2\2\u014c\u014d"+ + "\7?\2\2\u014d\u014e\7?\2\2\u014eS\3\2\2\2\u014f\u0150\7?\2\2\u0150\u0151"+ + "\7?\2\2\u0151\u0152\7?\2\2\u0152U\3\2\2\2\u0153\u0154\7#\2\2\u0154\u0155"+ + "\7?\2\2\u0155W\3\2\2\2\u0156\u0157\7#\2\2\u0157\u0158\7?\2\2\u0158\u0159"+ + "\7?\2\2\u0159Y\3\2\2\2\u015a\u015b\7(\2\2\u015b[\3\2\2\2\u015c\u015d\7"+ + "`\2\2\u015d]\3\2\2\2\u015e\u015f\7~\2\2\u015f_\3\2\2\2\u0160\u0161\7("+ + "\2\2\u0161\u0162\7(\2\2\u0162a\3\2\2\2\u0163\u0164\7~\2\2\u0164\u0165"+ + "\7~\2\2\u0165c\3\2\2\2\u0166\u0167\7A\2\2\u0167e\3\2\2\2\u0168\u0169\7"+ + "<\2\2\u0169g\3\2\2\2\u016a\u016b\7<\2\2\u016b\u016c\7<\2\2\u016ci\3\2"+ + "\2\2\u016d\u016e\7/\2\2\u016e\u016f\7@\2\2\u016fk\3\2\2\2\u0170\u0171"+ + "\7?\2\2\u0171\u0172\7\u0080\2\2\u0172m\3\2\2\2\u0173\u0174\7?\2\2\u0174"+ + "\u0175\7?\2\2\u0175\u0176\7\u0080\2\2\u0176o\3\2\2\2\u0177\u0178\7-\2"+ + "\2\u0178\u0179\7-\2\2\u0179q\3\2\2\2\u017a\u017b\7/\2\2\u017b\u017c\7"+ + "/\2\2\u017cs\3\2\2\2\u017d\u017e\7?\2\2\u017eu\3\2\2\2\u017f\u0180\7-"+ + "\2\2\u0180\u0181\7?\2\2\u0181w\3\2\2\2\u0182\u0183\7/\2\2\u0183\u0184"+ + "\7?\2\2\u0184y\3\2\2\2\u0185\u0186\7,\2\2\u0186\u0187\7?\2\2\u0187{\3"+ + "\2\2\2\u0188\u0189\7\61\2\2\u0189\u018a\7?\2\2\u018a}\3\2\2\2\u018b\u018c"+ + "\7\'\2\2\u018c\u018d\7?\2\2\u018d\177\3\2\2\2\u018e\u018f\7(\2\2\u018f"+ + "\u0190\7?\2\2\u0190\u0081\3\2\2\2\u0191\u0192\7`\2\2\u0192\u0193\7?\2"+ + "\2\u0193\u0083\3\2\2\2\u0194\u0195\7~\2\2\u0195\u0196\7?\2\2\u0196\u0085"+ + "\3\2\2\2\u0197\u0198\7>\2\2\u0198\u0199\7>\2\2\u0199\u019a\7?\2\2\u019a"+ + "\u0087\3\2\2\2\u019b\u019c\7@\2\2\u019c\u019d\7@\2\2\u019d\u019e\7?\2"+ + "\2\u019e\u0089\3\2\2\2\u019f\u01a0\7@\2\2\u01a0\u01a1\7@\2\2\u01a1\u01a2"+ + "\7@\2\2\u01a2\u01a3\7?\2\2\u01a3\u008b\3\2\2\2\u01a4\u01a6\7\62\2\2\u01a5"+ + "\u01a7\t\4\2\2\u01a6\u01a5\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01a6\3\2"+ + "\2\2\u01a8\u01a9\3\2\2\2\u01a9\u01ab\3\2\2\2\u01aa\u01ac\t\5\2\2\u01ab"+ + "\u01aa\3\2\2\2\u01ab\u01ac\3\2\2\2\u01ac\u008d\3\2\2\2\u01ad\u01ae\7\62"+ + "\2\2\u01ae\u01b0\t\6\2\2\u01af\u01b1\t\7\2\2\u01b0\u01af\3\2\2\2\u01b1"+ + "\u01b2\3\2\2\2\u01b2\u01b0\3\2\2\2\u01b2\u01b3\3\2\2\2\u01b3\u01b5\3\2"+ + "\2\2\u01b4\u01b6\t\5\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\u01fd\u0218\u0221\u0229"+ - "\u022c\u0234\5\b\2\2\4\3\2\4\2\2"; + "\2\2\u01bf\u01b8\3\2\2\2\u01c0\u01c2\3\2\2\2\u01c1\u01c3\t\n\2\2\u01c2"+ + "\u01c1\3\2\2\2\u01c2\u01c3\3\2\2\2\u01c3\u0091\3\2\2\2\u01c4\u01cd\7\62"+ + "\2\2\u01c5\u01c9\t\b\2\2\u01c6\u01c8\t\t\2\2\u01c7\u01c6\3\2\2\2\u01c8"+ + "\u01cb\3\2\2\2\u01c9\u01c7\3\2\2\2\u01c9\u01ca\3\2\2\2\u01ca\u01cd\3\2"+ + "\2\2\u01cb\u01c9\3\2\2\2\u01cc\u01c4\3\2\2\2\u01cc\u01c5\3\2\2\2\u01cd"+ + "\u01d4\3\2\2\2\u01ce\u01d0\5\24\n\2\u01cf\u01d1\t\t\2\2\u01d0\u01cf\3"+ + "\2\2\2\u01d1\u01d2\3\2\2\2\u01d2\u01d0\3\2\2\2\u01d2\u01d3\3\2\2\2\u01d3"+ + "\u01d5\3\2\2\2\u01d4\u01ce\3\2\2\2\u01d4\u01d5\3\2\2\2\u01d5\u01df\3\2"+ + "\2\2\u01d6\u01d8\t\13\2\2\u01d7\u01d9\t\f\2\2\u01d8\u01d7\3\2\2\2\u01d8"+ + "\u01d9\3\2\2\2\u01d9\u01db\3\2\2\2\u01da\u01dc\t\t\2\2\u01db\u01da\3\2"+ + "\2\2\u01dc\u01dd\3\2\2\2\u01dd\u01db\3\2\2\2\u01dd\u01de\3\2\2\2\u01de"+ + "\u01e0\3\2\2\2\u01df\u01d6\3\2\2\2\u01df\u01e0\3\2\2\2\u01e0\u01e2\3\2"+ + "\2\2\u01e1\u01e3\t\r\2\2\u01e2\u01e1\3\2\2\2\u01e2\u01e3\3\2\2\2\u01e3"+ + "\u0093\3\2\2\2\u01e4\u01ec\7$\2\2\u01e5\u01e6\7^\2\2\u01e6\u01eb\7$\2"+ + "\2\u01e7\u01e8\7^\2\2\u01e8\u01eb\7^\2\2\u01e9\u01eb\n\16\2\2\u01ea\u01e5"+ + "\3\2\2\2\u01ea\u01e7\3\2\2\2\u01ea\u01e9\3\2\2\2\u01eb\u01ee\3\2\2\2\u01ec"+ + "\u01ed\3\2\2\2\u01ec\u01ea\3\2\2\2\u01ed\u01ef\3\2\2\2\u01ee\u01ec\3\2"+ + "\2\2\u01ef\u01fd\7$\2\2\u01f0\u01f8\7)\2\2\u01f1\u01f2\7^\2\2\u01f2\u01f7"+ + "\7)\2\2\u01f3\u01f4\7^\2\2\u01f4\u01f7\7^\2\2\u01f5\u01f7\n\16\2\2\u01f6"+ + "\u01f1\3\2\2\2\u01f6\u01f3\3\2\2\2\u01f6\u01f5\3\2\2\2\u01f7\u01fa\3\2"+ + "\2\2\u01f8\u01f9\3\2\2\2\u01f8\u01f6\3\2\2\2\u01f9\u01fb\3\2\2\2\u01fa"+ + "\u01f8\3\2\2\2\u01fb\u01fd\7)\2\2\u01fc\u01e4\3\2\2\2\u01fc\u01f0\3\2"+ + "\2\2\u01fd\u0095\3\2\2\2\u01fe\u0202\7\61\2\2\u01ff\u0203\n\17\2\2\u0200"+ + "\u0201\7^\2\2\u0201\u0203\n\20\2\2\u0202\u01ff\3\2\2\2\u0202\u0200\3\2"+ + "\2\2\u0203\u0204\3\2\2\2\u0204\u0202\3\2\2\2\u0204\u0205\3\2\2\2\u0205"+ + "\u0206\3\2\2\2\u0206\u020a\7\61\2\2\u0207\u0209\t\21\2\2\u0208\u0207\3"+ + "\2\2\2\u0209\u020c\3\2\2\2\u020a\u0208\3\2\2\2\u020a\u020b\3\2\2\2\u020b"+ + "\u020d\3\2\2\2\u020c\u020a\3\2\2\2\u020d\u020e\6K\3\2\u020e\u0097\3\2"+ + "\2\2\u020f\u0210\7v\2\2\u0210\u0211\7t\2\2\u0211\u0212\7w\2\2\u0212\u0213"+ + "\7g\2\2\u0213\u0099\3\2\2\2\u0214\u0215\7h\2\2\u0215\u0216\7c\2\2\u0216"+ + "\u0217\7n\2\2\u0217\u0218\7u\2\2\u0218\u0219\7g\2\2\u0219\u009b\3\2\2"+ + "\2\u021a\u021b\7p\2\2\u021b\u021c\7w\2\2\u021c\u021d\7n\2\2\u021d\u021e"+ + "\7n\2\2\u021e\u009d\3\2\2\2\u021f\u0225\5\u00a0P\2\u0220\u0221\5\24\n"+ + "\2\u0221\u0222\5\u00a0P\2\u0222\u0224\3\2\2\2\u0223\u0220\3\2\2\2\u0224"+ + "\u0227\3\2\2\2\u0225\u0223\3\2\2\2\u0225\u0226\3\2\2\2\u0226\u0228\3\2"+ + "\2\2\u0227\u0225\3\2\2\2\u0228\u0229\6O\4\2\u0229\u009f\3\2\2\2\u022a"+ + "\u022e\t\22\2\2\u022b\u022d\t\23\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\u00a1\3\2\2\2\u0230"+ + "\u022e\3\2\2\2\u0231\u023a\7\62\2\2\u0232\u0236\t\b\2\2\u0233\u0235\t"+ + "\t\2\2\u0234\u0233\3\2\2\2\u0235\u0238\3\2\2\2\u0236\u0234\3\2\2\2\u0236"+ + "\u0237\3\2\2\2\u0237\u023a\3\2\2\2\u0238\u0236\3\2\2\2\u0239\u0231\3\2"+ + "\2\2\u0239\u0232\3\2\2\2\u023a\u023b\3\2\2\2\u023b\u023c\bQ\4\2\u023c"+ + "\u00a3\3\2\2\2\u023d\u0241\t\22\2\2\u023e\u0240\t\23\2\2\u023f\u023e\3"+ + "\2\2\2\u0240\u0243\3\2\2\2\u0241\u023f\3\2\2\2\u0241\u0242\3\2\2\2\u0242"+ + "\u0244\3\2\2\2\u0243\u0241\3\2\2\2\u0244\u0245\bR\4\2\u0245\u00a5\3\2"+ + "\2\2$\2\3\u00a9\u00b3\u00bd\u00c2\u01a8\u01ab\u01b2\u01b5\u01bc\u01bf"+ + "\u01c2\u01c9\u01cc\u01d2\u01d4\u01d8\u01dd\u01df\u01e2\u01ea\u01ec\u01f6"+ + "\u01f8\u01fc\u0202\u0204\u020a\u0225\u022e\u0236\u0239\u0241\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/PainlessParser.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java index f6ace39be63..c1b698a9530 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 @@ -19,14 +19,14 @@ class PainlessParser extends Parser { public static final int WS=1, COMMENT=2, LBRACK=3, RBRACK=4, LBRACE=5, RBRACE=6, LP=7, RP=8, DOT=9, COMMA=10, SEMICOLON=11, IF=12, ELSE=13, WHILE=14, DO=15, FOR=16, CONTINUE=17, - BREAK=18, RETURN=19, NEW=20, TRY=21, CATCH=22, THROW=23, THIS=24, BOOLNOT=25, - BWNOT=26, MUL=27, DIV=28, REM=29, ADD=30, SUB=31, LSH=32, RSH=33, USH=34, - LT=35, LTE=36, GT=37, GTE=38, EQ=39, EQR=40, NE=41, NER=42, BWAND=43, - XOR=44, BWOR=45, BOOLAND=46, BOOLOR=47, COND=48, COLON=49, REF=50, ARROW=51, - FIND=52, MATCH=53, INCR=54, DECR=55, ASSIGN=56, AADD=57, ASUB=58, AMUL=59, - ADIV=60, AREM=61, AAND=62, AXOR=63, AOR=64, ALSH=65, ARSH=66, AUSH=67, - OCTAL=68, HEX=69, INTEGER=70, DECIMAL=71, STRING=72, REGEX=73, TRUE=74, - FALSE=75, NULL=76, TYPE=77, ID=78, DOTINTEGER=79, DOTID=80; + BREAK=18, RETURN=19, NEW=20, TRY=21, CATCH=22, THROW=23, THIS=24, INSTANCEOF=25, + BOOLNOT=26, BWNOT=27, MUL=28, DIV=29, REM=30, ADD=31, SUB=32, LSH=33, + RSH=34, USH=35, LT=36, LTE=37, GT=38, GTE=39, EQ=40, EQR=41, NE=42, NER=43, + BWAND=44, XOR=45, BWOR=46, BOOLAND=47, BOOLOR=48, COND=49, COLON=50, REF=51, + ARROW=52, FIND=53, MATCH=54, INCR=55, DECR=56, ASSIGN=57, AADD=58, ASUB=59, + AMUL=60, ADIV=61, AREM=62, AAND=63, AXOR=64, AOR=65, ALSH=66, ARSH=67, + AUSH=68, OCTAL=69, HEX=70, INTEGER=71, DECIMAL=72, STRING=73, REGEX=74, + TRUE=75, FALSE=76, NULL=77, TYPE=78, ID=79, DOTINTEGER=80, DOTID=81; public static final int RULE_source = 0, RULE_function = 1, RULE_parameters = 2, RULE_statement = 3, RULE_trailer = 4, RULE_block = 5, RULE_empty = 6, RULE_initializer = 7, @@ -49,20 +49,20 @@ class PainlessParser extends Parser { private static final String[] _LITERAL_NAMES = { null, null, null, "'{'", "'}'", "'['", "']'", "'('", "')'", "'.'", "','", "';'", "'if'", "'else'", "'while'", "'do'", "'for'", "'continue'", "'break'", - "'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'", "'!'", "'~'", - "'*'", "'/'", "'%'", "'+'", "'-'", "'<<'", "'>>'", "'>>>'", "'<'", "'<='", - "'>'", "'>='", "'=='", "'==='", "'!='", "'!=='", "'&'", "'^'", "'|'", - "'&&'", "'||'", "'?'", "':'", "'::'", "'->'", "'=~'", "'==~'", "'++'", - "'--'", "'='", "'+='", "'-='", "'*='", "'/='", "'%='", "'&='", "'^='", - "'|='", "'<<='", "'>>='", "'>>>='", null, null, null, null, null, null, - "'true'", "'false'", "'null'" + "'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'", "'instanceof'", + "'!'", "'~'", "'*'", "'/'", "'%'", "'+'", "'-'", "'<<'", "'>>'", "'>>>'", + "'<'", "'<='", "'>'", "'>='", "'=='", "'==='", "'!='", "'!=='", "'&'", + "'^'", "'|'", "'&&'", "'||'", "'?'", "':'", "'::'", "'->'", "'=~'", "'==~'", + "'++'", "'--'", "'='", "'+='", "'-='", "'*='", "'/='", "'%='", "'&='", + "'^='", "'|='", "'<<='", "'>>='", "'>>>='", null, null, null, null, null, + null, "'true'", "'false'", "'null'" }; private static final String[] _SYMBOLIC_NAMES = { null, "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP", "DOT", "COMMA", "SEMICOLON", "IF", "ELSE", "WHILE", "DO", "FOR", "CONTINUE", - "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW", "THIS", "BOOLNOT", - "BWNOT", "MUL", "DIV", "REM", "ADD", "SUB", "LSH", "RSH", "USH", "LT", - "LTE", "GT", "GTE", "EQ", "EQR", "NE", "NER", "BWAND", "XOR", "BWOR", + "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW", "THIS", "INSTANCEOF", + "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD", "SUB", "LSH", "RSH", "USH", + "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE", "NER", "BWAND", "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "REF", "ARROW", "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB", "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH", "OCTAL", "HEX", "INTEGER", "DECIMAL", @@ -1150,27 +1150,29 @@ class PainlessParser extends Parser { public final DecltypeContext decltype() throws RecognitionException { DecltypeContext _localctx = new DecltypeContext(_ctx, getState()); enterRule(_localctx, 20, RULE_decltype); - int _la; try { + int _alt; enterOuterAlt(_localctx, 1); { setState(213); match(TYPE); setState(218); _errHandler.sync(this); - _la = _input.LA(1); - while (_la==LBRACE) { - { - { - setState(214); - match(LBRACE); - setState(215); - match(RBRACE); - } + _alt = getInterpreter().adaptivePredict(_input,16,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(214); + match(LBRACE); + setState(215); + match(RBRACE); + } + } } setState(220); _errHandler.sync(this); - _la = _input.LA(1); + _alt = getInterpreter().adaptivePredict(_input,16,_ctx); } } } @@ -1461,6 +1463,21 @@ class PainlessParser extends Parser { else return visitor.visitChildren(this); } } + public static class InstanceofContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode INSTANCEOF() { return getToken(PainlessParser.INSTANCEOF, 0); } + public DecltypeContext decltype() { + return getRuleContext(DecltypeContext.class,0); + } + public InstanceofContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PainlessParserVisitor ) return ((PainlessParserVisitor)visitor).visitInstanceof(this); + else return visitor.visitChildren(this); + } + } public final ExpressionContext expression() throws RecognitionException { return expression(0); @@ -1490,7 +1507,7 @@ class PainlessParser extends Parser { chain(true); setState(237); _la = _input.LA(1); - if ( !(((((_la - 56)) & ~0x3f) == 0 && ((1L << (_la - 56)) & ((1L << (ASSIGN - 56)) | (1L << (AADD - 56)) | (1L << (ASUB - 56)) | (1L << (AMUL - 56)) | (1L << (ADIV - 56)) | (1L << (AREM - 56)) | (1L << (AAND - 56)) | (1L << (AXOR - 56)) | (1L << (AOR - 56)) | (1L << (ALSH - 56)) | (1L << (ARSH - 56)) | (1L << (AUSH - 56)))) != 0)) ) { + if ( !(((((_la - 57)) & ~0x3f) == 0 && ((1L << (_la - 57)) & ((1L << (ASSIGN - 57)) | (1L << (AADD - 57)) | (1L << (ASUB - 57)) | (1L << (AMUL - 57)) | (1L << (ADIV - 57)) | (1L << (AREM - 57)) | (1L << (AAND - 57)) | (1L << (AXOR - 57)) | (1L << (AOR - 57)) | (1L << (ALSH - 57)) | (1L << (ARSH - 57)) | (1L << (AUSH - 57)))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -1512,7 +1529,7 @@ class PainlessParser extends Parser { break; } _ctx.stop = _input.LT(-1); - setState(310); + setState(315); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,20,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -1520,14 +1537,14 @@ class PainlessParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(308); + setState(313); switch ( getInterpreter().adaptivePredict(_input,19,_ctx) ) { case 1: { _localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expression); setState(246); - if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); + if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); setState(247); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << MUL) | (1L << DIV) | (1L << REM))) != 0)) ) { @@ -1536,7 +1553,7 @@ class PainlessParser extends Parser { consume(); } setState(248); - expression(14); + expression(15); ((BinaryContext)_localctx).s = false; } break; @@ -1545,7 +1562,7 @@ class PainlessParser extends Parser { _localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expression); setState(251); - if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); + if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); setState(252); _la = _input.LA(1); if ( !(_la==ADD || _la==SUB) ) { @@ -1554,7 +1571,7 @@ class PainlessParser extends Parser { consume(); } setState(253); - expression(13); + expression(14); ((BinaryContext)_localctx).s = false; } break; @@ -1563,7 +1580,7 @@ class PainlessParser extends Parser { _localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expression); setState(256); - if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); + if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); setState(257); _la = _input.LA(1); if ( !(_la==FIND || _la==MATCH) ) { @@ -1572,7 +1589,7 @@ class PainlessParser extends Parser { consume(); } setState(258); - expression(12); + expression(13); ((BinaryContext)_localctx).s = false; } break; @@ -1581,7 +1598,7 @@ class PainlessParser extends Parser { _localctx = new BinaryContext(new ExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expression); setState(261); - if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); + if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); setState(262); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LSH) | (1L << RSH) | (1L << USH))) != 0)) ) { @@ -1590,7 +1607,7 @@ class PainlessParser extends Parser { consume(); } setState(263); - expression(11); + expression(12); ((BinaryContext)_localctx).s = false; } break; @@ -1599,7 +1616,7 @@ class PainlessParser extends Parser { _localctx = new CompContext(new ExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expression); setState(266); - if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); + if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); setState(267); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LT) | (1L << LTE) | (1L << GT) | (1L << GTE))) != 0)) ) { @@ -1608,7 +1625,7 @@ class PainlessParser extends Parser { consume(); } setState(268); - expression(10); + expression(11); ((CompContext)_localctx).s = false; } break; @@ -1712,10 +1729,23 @@ class PainlessParser extends Parser { ((ConditionalContext)_localctx).s = ((ConditionalContext)_localctx).e0.s && ((ConditionalContext)_localctx).e1.s; } break; + case 13: + { + _localctx = new InstanceofContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(308); + if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); + setState(309); + match(INSTANCEOF); + setState(310); + decltype(); + ((InstanceofContext)_localctx).s = false; + } + break; } } } - setState(312); + setState(317); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,20,_ctx); } @@ -1884,22 +1914,22 @@ class PainlessParser extends Parser { enterRule(_localctx, 30, RULE_unary); int _la; try { - setState(350); + setState(355); switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) { case 1: _localctx = new PreContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(313); + setState(318); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(314); + setState(319); _la = _input.LA(1); if ( !(_la==INCR || _la==DECR) ) { _errHandler.recoverInline(this); } else { consume(); } - setState(315); + setState(320); chain(true); } break; @@ -1907,11 +1937,11 @@ class PainlessParser extends Parser { _localctx = new PostContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(316); + setState(321); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(317); + setState(322); chain(true); - setState(318); + setState(323); _la = _input.LA(1); if ( !(_la==INCR || _la==DECR) ) { _errHandler.recoverInline(this); @@ -1924,9 +1954,9 @@ class PainlessParser extends Parser { _localctx = new ReadContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(320); + setState(325); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(321); + setState(326); chain(false); } break; @@ -1934,11 +1964,11 @@ class PainlessParser extends Parser { _localctx = new NumericContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(322); + setState(327); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(323); + setState(328); _la = _input.LA(1); - if ( !(((((_la - 68)) & ~0x3f) == 0 && ((1L << (_la - 68)) & ((1L << (OCTAL - 68)) | (1L << (HEX - 68)) | (1L << (INTEGER - 68)) | (1L << (DECIMAL - 68)))) != 0)) ) { + if ( !(((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (OCTAL - 69)) | (1L << (HEX - 69)) | (1L << (INTEGER - 69)) | (1L << (DECIMAL - 69)))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -1950,9 +1980,9 @@ class PainlessParser extends Parser { _localctx = new TrueContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(325); + setState(330); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(326); + setState(331); match(TRUE); ((TrueContext)_localctx).s = false; } @@ -1961,9 +1991,9 @@ class PainlessParser extends Parser { _localctx = new FalseContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(328); + setState(333); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(329); + setState(334); match(FALSE); ((FalseContext)_localctx).s = false; } @@ -1972,9 +2002,9 @@ class PainlessParser extends Parser { _localctx = new NullContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(331); + setState(336); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(332); + setState(337); match(NULL); ((NullContext)_localctx).s = false; } @@ -1983,9 +2013,9 @@ class PainlessParser extends Parser { _localctx = new ListinitContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(334); + setState(339); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(335); + setState(340); listinitializer(); ((ListinitContext)_localctx).s = false; } @@ -1994,9 +2024,9 @@ class PainlessParser extends Parser { _localctx = new MapinitContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(338); + setState(343); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(339); + setState(344); mapinitializer(); ((MapinitContext)_localctx).s = false; } @@ -2005,16 +2035,16 @@ class PainlessParser extends Parser { _localctx = new OperatorContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(342); + setState(347); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(343); + setState(348); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); } - setState(344); + setState(349); unary(false); } break; @@ -2022,13 +2052,13 @@ class PainlessParser extends Parser { _localctx = new CastContext(_localctx); enterOuterAlt(_localctx, 11); { - setState(345); + setState(350); match(LP); - setState(346); + setState(351); decltype(); - setState(347); + setState(352); match(RP); - setState(348); + setState(353); unary(_localctx.c); } break; @@ -2115,27 +2145,27 @@ class PainlessParser extends Parser { enterRule(_localctx, 32, RULE_chain); try { int _alt; - setState(368); + setState(373); switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) { case 1: _localctx = new DynamicContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(352); + setState(357); ((DynamicContext)_localctx).p = primary(_localctx.c); - setState(356); + setState(361); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,22,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(353); + setState(358); secondary(((DynamicContext)_localctx).p.s); } } } - setState(358); + setState(363); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,22,_ctx); } @@ -2145,23 +2175,23 @@ class PainlessParser extends Parser { _localctx = new StaticContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(359); - decltype(); - setState(360); - dot(); setState(364); + decltype(); + setState(365); + dot(); + setState(369); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,23,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(361); + setState(366); secondary(true); } } } - setState(366); + setState(371); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,23,_ctx); } @@ -2171,7 +2201,7 @@ class PainlessParser extends Parser { _localctx = new NewarrayContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(367); + setState(372); arrayinitializer(); } break; @@ -2289,19 +2319,19 @@ class PainlessParser extends Parser { PrimaryContext _localctx = new PrimaryContext(_ctx, getState(), c); enterRule(_localctx, 34, RULE_primary); try { - setState(389); + setState(394); switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) { case 1: _localctx = new ExprprecContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(370); + setState(375); if (!( !_localctx.c )) throw new FailedPredicateException(this, " !$c "); - setState(371); + setState(376); match(LP); - setState(372); + setState(377); ((ExprprecContext)_localctx).e = expression(0); - setState(373); + setState(378); match(RP); ((ExprprecContext)_localctx).s = ((ExprprecContext)_localctx).e.s; } @@ -2310,13 +2340,13 @@ class PainlessParser extends Parser { _localctx = new ChainprecContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(376); + setState(381); if (!( _localctx.c )) throw new FailedPredicateException(this, " $c "); - setState(377); + setState(382); match(LP); - setState(378); + setState(383); unary(true); - setState(379); + setState(384); match(RP); } break; @@ -2324,7 +2354,7 @@ class PainlessParser extends Parser { _localctx = new StringContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(381); + setState(386); match(STRING); } break; @@ -2332,7 +2362,7 @@ class PainlessParser extends Parser { _localctx = new RegexContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(382); + setState(387); match(REGEX); } break; @@ -2340,7 +2370,7 @@ class PainlessParser extends Parser { _localctx = new VariableContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(383); + setState(388); match(ID); } break; @@ -2348,9 +2378,9 @@ class PainlessParser extends Parser { _localctx = new CalllocalContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(384); + setState(389); match(ID); - setState(385); + setState(390); arguments(); } break; @@ -2358,11 +2388,11 @@ class PainlessParser extends Parser { _localctx = new NewobjectContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(386); + setState(391); match(NEW); - setState(387); + setState(392); match(TYPE); - setState(388); + setState(393); arguments(); } break; @@ -2404,23 +2434,23 @@ class PainlessParser extends Parser { SecondaryContext _localctx = new SecondaryContext(_ctx, getState(), s); enterRule(_localctx, 36, RULE_secondary); try { - setState(395); + setState(400); switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(391); + setState(396); if (!( _localctx.s )) throw new FailedPredicateException(this, " $s "); - setState(392); + setState(397); dot(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(393); + setState(398); if (!( _localctx.s )) throw new FailedPredicateException(this, " $s "); - setState(394); + setState(399); brace(); } break; @@ -2478,17 +2508,17 @@ class PainlessParser extends Parser { enterRule(_localctx, 38, RULE_dot); int _la; try { - setState(402); + setState(407); switch ( getInterpreter().adaptivePredict(_input,27,_ctx) ) { case 1: _localctx = new CallinvokeContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(397); + setState(402); match(DOT); - setState(398); + setState(403); match(DOTID); - setState(399); + setState(404); arguments(); } break; @@ -2496,9 +2526,9 @@ class PainlessParser extends Parser { _localctx = new FieldaccessContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(400); + setState(405); match(DOT); - setState(401); + setState(406); _la = _input.LA(1); if ( !(_la==DOTINTEGER || _la==DOTID) ) { _errHandler.recoverInline(this); @@ -2552,11 +2582,11 @@ class PainlessParser extends Parser { _localctx = new BraceaccessContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(404); + setState(409); match(LBRACE); - setState(405); + setState(410); expression(0); - setState(406); + setState(411); match(RBRACE); } } @@ -2603,34 +2633,34 @@ class PainlessParser extends Parser { enterOuterAlt(_localctx, 1); { { - setState(408); + setState(413); match(LP); - setState(417); + setState(422); switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) { case 1: { - setState(409); - argument(); setState(414); + argument(); + setState(419); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(410); + setState(415); match(COMMA); - setState(411); + setState(416); argument(); } } - setState(416); + setState(421); _errHandler.sync(this); _la = _input.LA(1); } } break; } - setState(419); + setState(424); match(RP); } } @@ -2671,26 +2701,26 @@ class PainlessParser extends Parser { ArgumentContext _localctx = new ArgumentContext(_ctx, getState()); enterRule(_localctx, 44, RULE_argument); try { - setState(424); + setState(429); switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(421); + setState(426); expression(0); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(422); + setState(427); lambda(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(423); + setState(428); funcref(); } break; @@ -2745,64 +2775,64 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(439); + setState(444); switch (_input.LA(1)) { case TYPE: case ID: { - setState(426); + setState(431); lamtype(); } break; case LP: { - setState(427); + setState(432); match(LP); - setState(436); + setState(441); _la = _input.LA(1); if (_la==TYPE || _la==ID) { { - setState(428); - lamtype(); setState(433); + lamtype(); + setState(438); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(429); + setState(434); match(COMMA); - setState(430); + setState(435); lamtype(); } } - setState(435); + setState(440); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(438); + setState(443); match(RP); } break; default: throw new NoViableAltException(this); } - setState(441); + setState(446); match(ARROW); - setState(444); + setState(449); switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) { case 1: { - setState(442); + setState(447); block(); } break; case 2: { - setState(443); + setState(448); expression(0); } break; @@ -2843,16 +2873,16 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(447); + setState(452); _la = _input.LA(1); if (_la==TYPE) { { - setState(446); + setState(451); decltype(); } } - setState(449); + setState(454); match(ID); } } @@ -2895,33 +2925,33 @@ class PainlessParser extends Parser { FuncrefContext _localctx = new FuncrefContext(_ctx, getState()); enterRule(_localctx, 50, RULE_funcref); try { - setState(455); + setState(460); switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(451); + setState(456); classFuncref(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(452); + setState(457); constructorFuncref(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(453); + setState(458); capturingFuncref(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(454); + setState(459); localFuncref(); } break; @@ -2959,11 +2989,11 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(457); + setState(462); match(TYPE); - setState(458); + setState(463); match(REF); - setState(459); + setState(464); match(ID); } } @@ -3001,11 +3031,11 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(461); + setState(466); decltype(); - setState(462); + setState(467); match(REF); - setState(463); + setState(468); match(NEW); } } @@ -3043,11 +3073,11 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(465); + setState(470); match(ID); - setState(466); + setState(471); match(REF); - setState(467); + setState(472); match(ID); } } @@ -3083,11 +3113,11 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(469); + setState(474); match(THIS); - setState(470); + setState(475); match(REF); - setState(471); + setState(476); match(ID); } } @@ -3178,17 +3208,17 @@ class PainlessParser extends Parser { int _la; try { int _alt; - setState(511); + setState(516); switch ( getInterpreter().adaptivePredict(_input,43,_ctx) ) { case 1: _localctx = new NewstandardarrayContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(473); + setState(478); match(NEW); - setState(474); + setState(479); match(TYPE); - setState(479); + setState(484); _errHandler.sync(this); _alt = 1; do { @@ -3196,11 +3226,11 @@ class PainlessParser extends Parser { case 1: { { - setState(475); + setState(480); match(LBRACE); - setState(476); + setState(481); expression(0); - setState(477); + setState(482); match(RBRACE); } } @@ -3208,29 +3238,29 @@ class PainlessParser extends Parser { default: throw new NoViableAltException(this); } - setState(481); + setState(486); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,37,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); - setState(490); + setState(495); switch ( getInterpreter().adaptivePredict(_input,39,_ctx) ) { case 1: { - setState(483); + setState(488); dot(); - setState(487); + setState(492); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,38,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(484); + setState(489); secondary(true); } } } - setState(489); + setState(494); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,38,_ctx); } @@ -3243,51 +3273,51 @@ class PainlessParser extends Parser { _localctx = new NewinitializedarrayContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(492); + setState(497); match(NEW); - setState(493); + setState(498); match(TYPE); - setState(494); + setState(499); match(LBRACE); - setState(495); + setState(500); match(RBRACE); - setState(496); + setState(501); match(LBRACK); - setState(505); + setState(510); switch ( getInterpreter().adaptivePredict(_input,41,_ctx) ) { case 1: { - setState(497); - expression(0); setState(502); + expression(0); + setState(507); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(498); + setState(503); match(COMMA); - setState(499); + setState(504); expression(0); } } - setState(504); + setState(509); _errHandler.sync(this); _la = _input.LA(1); } } break; } - setState(508); + setState(513); _la = _input.LA(1); if (_la==SEMICOLON) { { - setState(507); + setState(512); match(SEMICOLON); } } - setState(510); + setState(515); match(RBRACK); } break; @@ -3333,41 +3363,41 @@ class PainlessParser extends Parser { enterRule(_localctx, 62, RULE_listinitializer); int _la; try { - setState(526); + setState(531); switch ( getInterpreter().adaptivePredict(_input,45,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(513); + setState(518); match(LBRACE); - setState(514); - expression(0); setState(519); + expression(0); + setState(524); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(515); + setState(520); match(COMMA); - setState(516); + setState(521); expression(0); } } - setState(521); + setState(526); _errHandler.sync(this); _la = _input.LA(1); } - setState(522); + setState(527); match(RBRACE); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(524); + setState(529); match(LBRACE); - setState(525); + setState(530); match(RBRACE); } break; @@ -3414,43 +3444,43 @@ class PainlessParser extends Parser { enterRule(_localctx, 64, RULE_mapinitializer); int _la; try { - setState(542); + setState(547); switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(528); + setState(533); match(LBRACE); - setState(529); - maptoken(); setState(534); + maptoken(); + setState(539); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(530); + setState(535); match(COMMA); - setState(531); + setState(536); maptoken(); } } - setState(536); + setState(541); _errHandler.sync(this); _la = _input.LA(1); } - setState(537); + setState(542); match(RBRACE); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(539); + setState(544); match(LBRACE); - setState(540); + setState(545); match(COLON); - setState(541); + setState(546); match(RBRACE); } break; @@ -3492,11 +3522,11 @@ class PainlessParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(544); + setState(549); expression(0); - setState(545); + setState(550); match(COLON); - setState(546); + setState(551); expression(0); } } @@ -3536,15 +3566,15 @@ class PainlessParser extends Parser { private boolean expression_sempred(ExpressionContext _localctx, int predIndex) { switch (predIndex) { case 1: - return precpred(_ctx, 13); + return precpred(_ctx, 14); case 2: - return precpred(_ctx, 12); + return precpred(_ctx, 13); case 3: - return precpred(_ctx, 11); + return precpred(_ctx, 12); case 4: - return precpred(_ctx, 10); + return precpred(_ctx, 11); case 5: - return precpred(_ctx, 9); + return precpred(_ctx, 10); case 6: return precpred(_ctx, 8); case 7: @@ -3559,13 +3589,13 @@ class PainlessParser extends Parser { return precpred(_ctx, 3); case 12: return precpred(_ctx, 2); + case 13: + return precpred(_ctx, 9); } return true; } private boolean unary_sempred(UnaryContext _localctx, int predIndex) { switch (predIndex) { - case 13: - return !_localctx.c ; case 14: return !_localctx.c ; case 15: @@ -3584,30 +3614,32 @@ class PainlessParser extends Parser { return !_localctx.c ; case 22: return !_localctx.c ; + case 23: + return !_localctx.c ; } return true; } private boolean primary_sempred(PrimaryContext _localctx, int predIndex) { switch (predIndex) { - case 23: - return !_localctx.c ; case 24: + return !_localctx.c ; + case 25: return _localctx.c ; } return true; } private boolean secondary_sempred(SecondaryContext _localctx, int predIndex) { switch (predIndex) { - case 25: - return _localctx.s ; case 26: return _localctx.s ; + case 27: + return _localctx.s ; } return true; } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3R\u0227\4\2\t\2\4"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3S\u022c\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"+ @@ -3629,191 +3661,193 @@ class PainlessParser extends Parser { "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+ "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+ "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+ - "\7\20\u0137\n\20\f\20\16\20\u013a\13\20\3\21\3\21\3\21\3\21\3\21\3\21"+ + "\3\20\3\20\3\20\3\20\3\20\7\20\u013c\n\20\f\20\16\20\u013f\13\20\3\21"+ "\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+ "\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+ - "\3\21\3\21\3\21\5\21\u0161\n\21\3\22\3\22\7\22\u0165\n\22\f\22\16\22\u0168"+ - "\13\22\3\22\3\22\3\22\7\22\u016d\n\22\f\22\16\22\u0170\13\22\3\22\5\22"+ - "\u0173\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+ - "\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u0188\n\23\3\24\3\24\3\24\3\24"+ - "\5\24\u018e\n\24\3\25\3\25\3\25\3\25\3\25\5\25\u0195\n\25\3\26\3\26\3"+ - "\26\3\26\3\27\3\27\3\27\3\27\7\27\u019f\n\27\f\27\16\27\u01a2\13\27\5"+ - "\27\u01a4\n\27\3\27\3\27\3\30\3\30\3\30\5\30\u01ab\n\30\3\31\3\31\3\31"+ - "\3\31\3\31\7\31\u01b2\n\31\f\31\16\31\u01b5\13\31\5\31\u01b7\n\31\3\31"+ - "\5\31\u01ba\n\31\3\31\3\31\3\31\5\31\u01bf\n\31\3\32\5\32\u01c2\n\32\3"+ - "\32\3\32\3\33\3\33\3\33\3\33\5\33\u01ca\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 \3 \3 \3 \3"+ - " \3 \6 \u01e2\n \r \16 \u01e3\3 \3 \7 \u01e8\n \f \16 \u01eb\13 \5 \u01ed"+ - "\n \3 \3 \3 \3 \3 \3 \3 \3 \7 \u01f7\n \f \16 \u01fa\13 \5 \u01fc\n \3"+ - " \5 \u01ff\n \3 \5 \u0202\n \3!\3!\3!\3!\7!\u0208\n!\f!\16!\u020b\13!"+ - "\3!\3!\3!\3!\5!\u0211\n!\3\"\3\"\3\"\3\"\7\"\u0217\n\"\f\"\16\"\u021a"+ - "\13\"\3\"\3\"\3\"\3\"\3\"\5\"\u0221\n\"\3#\3#\3#\3#\3#\2\3\36$\2\4\6\b"+ - "\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BD\2\16\3\3\r"+ - "\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\u025a\2I\3\2\2\2\4T\3\2\2\2\6Y\3\2\2\2\b\u00b7\3\2\2\2"+ - "\n\u00bb\3\2\2\2\f\u00bd\3\2\2\2\16\u00c6\3\2\2\2\20\u00ca\3\2\2\2\22"+ - "\u00cc\3\2\2\2\24\u00ce\3\2\2\2\26\u00d7\3\2\2\2\30\u00df\3\2\2\2\32\u00e4"+ - "\3\2\2\2\34\u00eb\3\2\2\2\36\u00f6\3\2\2\2 \u0160\3\2\2\2\"\u0172\3\2"+ - "\2\2$\u0187\3\2\2\2&\u018d\3\2\2\2(\u0194\3\2\2\2*\u0196\3\2\2\2,\u019a"+ - "\3\2\2\2.\u01aa\3\2\2\2\60\u01b9\3\2\2\2\62\u01c1\3\2\2\2\64\u01c9\3\2"+ - "\2\2\66\u01cb\3\2\2\28\u01cf\3\2\2\2:\u01d3\3\2\2\2<\u01d7\3\2\2\2>\u0201"+ - "\3\2\2\2@\u0210\3\2\2\2B\u0220\3\2\2\2D\u0222\3\2\2\2FH\5\4\3\2GF\3\2"+ - "\2\2HK\3\2\2\2IG\3\2\2\2IJ\3\2\2\2JO\3\2\2\2KI\3\2\2\2LN\5\b\5\2ML\3\2"+ - "\2\2NQ\3\2\2\2OM\3\2\2\2OP\3\2\2\2PR\3\2\2\2QO\3\2\2\2RS\7\2\2\3S\3\3"+ - "\2\2\2TU\5\26\f\2UV\7P\2\2VW\5\6\4\2WX\5\f\7\2X\5\3\2\2\2Ye\7\t\2\2Z["+ - "\5\26\f\2[b\7P\2\2\\]\7\f\2\2]^\5\26\f\2^_\7P\2\2_a\3\2\2\2`\\\3\2\2\2"+ - "ad\3\2\2\2b`\3\2\2\2bc\3\2\2\2cf\3\2\2\2db\3\2\2\2eZ\3\2\2\2ef\3\2\2\2"+ - "fg\3\2\2\2gh\7\n\2\2h\7\3\2\2\2ij\7\16\2\2jk\7\t\2\2kl\5\36\20\2lm\7\n"+ - "\2\2mq\5\n\6\2no\7\17\2\2or\5\n\6\2pr\6\5\2\2qn\3\2\2\2qp\3\2\2\2r\u00b8"+ - "\3\2\2\2st\7\20\2\2tu\7\t\2\2uv\5\36\20\2vy\7\n\2\2wz\5\n\6\2xz\5\16\b"+ - "\2yw\3\2\2\2yx\3\2\2\2z\u00b8\3\2\2\2{|\7\21\2\2|}\5\f\7\2}~\7\20\2\2"+ - "~\177\7\t\2\2\177\u0080\5\36\20\2\u0080\u0081\7\n\2\2\u0081\u0082\5\34"+ - "\17\2\u0082\u00b8\3\2\2\2\u0083\u0084\7\22\2\2\u0084\u0086\7\t\2\2\u0085"+ - "\u0087\5\20\t\2\u0086\u0085\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u0088\3"+ - "\2\2\2\u0088\u008a\7\r\2\2\u0089\u008b\5\36\20\2\u008a\u0089\3\2\2\2\u008a"+ - "\u008b\3\2\2\2\u008b\u008c\3\2\2\2\u008c\u008e\7\r\2\2\u008d\u008f\5\22"+ - "\n\2\u008e\u008d\3\2\2\2\u008e\u008f\3\2\2\2\u008f\u0090\3\2\2\2\u0090"+ - "\u0093\7\n\2\2\u0091\u0094\5\n\6\2\u0092\u0094\5\16\b\2\u0093\u0091\3"+ - "\2\2\2\u0093\u0092\3\2\2\2\u0094\u00b8\3\2\2\2\u0095\u0096\7\22\2\2\u0096"+ - "\u0097\7\t\2\2\u0097\u0098\5\26\f\2\u0098\u0099\7P\2\2\u0099\u009a\7\63"+ - "\2\2\u009a\u009b\5\36\20\2\u009b\u009c\7\n\2\2\u009c\u009d\5\n\6\2\u009d"+ - "\u00b8\3\2\2\2\u009e\u009f\5\24\13\2\u009f\u00a0\5\34\17\2\u00a0\u00b8"+ - "\3\2\2\2\u00a1\u00a2\7\23\2\2\u00a2\u00b8\5\34\17\2\u00a3\u00a4\7\24\2"+ - "\2\u00a4\u00b8\5\34\17\2\u00a5\u00a6\7\25\2\2\u00a6\u00a7\5\36\20\2\u00a7"+ - "\u00a8\5\34\17\2\u00a8\u00b8\3\2\2\2\u00a9\u00aa\7\27\2\2\u00aa\u00ac"+ - "\5\f\7\2\u00ab\u00ad\5\32\16\2\u00ac\u00ab\3\2\2\2\u00ad\u00ae\3\2\2\2"+ - "\u00ae\u00ac\3\2\2\2\u00ae\u00af\3\2\2\2\u00af\u00b8\3\2\2\2\u00b0\u00b1"+ - "\7\31\2\2\u00b1\u00b2\5\36\20\2\u00b2\u00b3\5\34\17\2\u00b3\u00b8\3\2"+ - "\2\2\u00b4\u00b5\5\36\20\2\u00b5\u00b6\5\34\17\2\u00b6\u00b8\3\2\2\2\u00b7"+ - "i\3\2\2\2\u00b7s\3\2\2\2\u00b7{\3\2\2\2\u00b7\u0083\3\2\2\2\u00b7\u0095"+ - "\3\2\2\2\u00b7\u009e\3\2\2\2\u00b7\u00a1\3\2\2\2\u00b7\u00a3\3\2\2\2\u00b7"+ - "\u00a5\3\2\2\2\u00b7\u00a9\3\2\2\2\u00b7\u00b0\3\2\2\2\u00b7\u00b4\3\2"+ - "\2\2\u00b8\t\3\2\2\2\u00b9\u00bc\5\f\7\2\u00ba\u00bc\5\b\5\2\u00bb\u00b9"+ - "\3\2\2\2\u00bb\u00ba\3\2\2\2\u00bc\13\3\2\2\2\u00bd\u00c1\7\5\2\2\u00be"+ - "\u00c0\5\b\5\2\u00bf\u00be\3\2\2\2\u00c0\u00c3\3\2\2\2\u00c1\u00bf\3\2"+ - "\2\2\u00c1\u00c2\3\2\2\2\u00c2\u00c4\3\2\2\2\u00c3\u00c1\3\2\2\2\u00c4"+ - "\u00c5\7\6\2\2\u00c5\r\3\2\2\2\u00c6\u00c7\7\r\2\2\u00c7\17\3\2\2\2\u00c8"+ - "\u00cb\5\24\13\2\u00c9\u00cb\5\36\20\2\u00ca\u00c8\3\2\2\2\u00ca\u00c9"+ - "\3\2\2\2\u00cb\21\3\2\2\2\u00cc\u00cd\5\36\20\2\u00cd\23\3\2\2\2\u00ce"+ - "\u00cf\5\26\f\2\u00cf\u00d4\5\30\r\2\u00d0\u00d1\7\f\2\2\u00d1\u00d3\5"+ - "\30\r\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\25\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d7\u00dc\7O\2\2"+ - "\u00d8\u00d9\7\7\2\2\u00d9\u00db\7\b\2\2\u00da\u00d8\3\2\2\2\u00db\u00de"+ - "\3\2\2\2\u00dc\u00da\3\2\2\2\u00dc\u00dd\3\2\2\2\u00dd\27\3\2\2\2\u00de"+ - "\u00dc\3\2\2\2\u00df\u00e2\7P\2\2\u00e0\u00e1\7:\2\2\u00e1\u00e3\5\36"+ - "\20\2\u00e2\u00e0\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3\31\3\2\2\2\u00e4\u00e5"+ - "\7\30\2\2\u00e5\u00e6\7\t\2\2\u00e6\u00e7\7O\2\2\u00e7\u00e8\7P\2\2\u00e8"+ - "\u00e9\7\n\2\2\u00e9\u00ea\5\f\7\2\u00ea\33\3\2\2\2\u00eb\u00ec\t\2\2"+ - "\2\u00ec\35\3\2\2\2\u00ed\u00ee\b\20\1\2\u00ee\u00ef\5\"\22\2\u00ef\u00f0"+ - "\t\3\2\2\u00f0\u00f1\5\36\20\3\u00f1\u00f2\b\20\1\2\u00f2\u00f7\3\2\2"+ - "\2\u00f3\u00f4\5 \21\2\u00f4\u00f5\b\20\1\2\u00f5\u00f7\3\2\2\2\u00f6"+ - "\u00ed\3\2\2\2\u00f6\u00f3\3\2\2\2\u00f7\u0138\3\2\2\2\u00f8\u00f9\f\17"+ - "\2\2\u00f9\u00fa\t\4\2\2\u00fa\u00fb\5\36\20\20\u00fb\u00fc\b\20\1\2\u00fc"+ - "\u0137\3\2\2\2\u00fd\u00fe\f\16\2\2\u00fe\u00ff\t\5\2\2\u00ff\u0100\5"+ - "\36\20\17\u0100\u0101\b\20\1\2\u0101\u0137\3\2\2\2\u0102\u0103\f\r\2\2"+ - "\u0103\u0104\t\6\2\2\u0104\u0105\5\36\20\16\u0105\u0106\b\20\1\2\u0106"+ - "\u0137\3\2\2\2\u0107\u0108\f\f\2\2\u0108\u0109\t\7\2\2\u0109\u010a\5\36"+ - "\20\r\u010a\u010b\b\20\1\2\u010b\u0137\3\2\2\2\u010c\u010d\f\13\2\2\u010d"+ - "\u010e\t\b\2\2\u010e\u010f\5\36\20\f\u010f\u0110\b\20\1\2\u0110\u0137"+ - "\3\2\2\2\u0111\u0112\f\n\2\2\u0112\u0113\t\t\2\2\u0113\u0114\5\36\20\13"+ - "\u0114\u0115\b\20\1\2\u0115\u0137\3\2\2\2\u0116\u0117\f\t\2\2\u0117\u0118"+ - "\7-\2\2\u0118\u0119\5\36\20\n\u0119\u011a\b\20\1\2\u011a\u0137\3\2\2\2"+ - "\u011b\u011c\f\b\2\2\u011c\u011d\7.\2\2\u011d\u011e\5\36\20\t\u011e\u011f"+ - "\b\20\1\2\u011f\u0137\3\2\2\2\u0120\u0121\f\7\2\2\u0121\u0122\7/\2\2\u0122"+ - "\u0123\5\36\20\b\u0123\u0124\b\20\1\2\u0124\u0137\3\2\2\2\u0125\u0126"+ - "\f\6\2\2\u0126\u0127\7\60\2\2\u0127\u0128\5\36\20\7\u0128\u0129\b\20\1"+ - "\2\u0129\u0137\3\2\2\2\u012a\u012b\f\5\2\2\u012b\u012c\7\61\2\2\u012c"+ - "\u012d\5\36\20\6\u012d\u012e\b\20\1\2\u012e\u0137\3\2\2\2\u012f\u0130"+ - "\f\4\2\2\u0130\u0131\7\62\2\2\u0131\u0132\5\36\20\2\u0132\u0133\7\63\2"+ - "\2\u0133\u0134\5\36\20\4\u0134\u0135\b\20\1\2\u0135\u0137\3\2\2\2\u0136"+ - "\u00f8\3\2\2\2\u0136\u00fd\3\2\2\2\u0136\u0102\3\2\2\2\u0136\u0107\3\2"+ - "\2\2\u0136\u010c\3\2\2\2\u0136\u0111\3\2\2\2\u0136\u0116\3\2\2\2\u0136"+ - "\u011b\3\2\2\2\u0136\u0120\3\2\2\2\u0136\u0125\3\2\2\2\u0136\u012a\3\2"+ - "\2\2\u0136\u012f\3\2\2\2\u0137\u013a\3\2\2\2\u0138\u0136\3\2\2\2\u0138"+ - "\u0139\3\2\2\2\u0139\37\3\2\2\2\u013a\u0138\3\2\2\2\u013b\u013c\6\21\17"+ - "\3\u013c\u013d\t\n\2\2\u013d\u0161\5\"\22\2\u013e\u013f\6\21\20\3\u013f"+ - "\u0140\5\"\22\2\u0140\u0141\t\n\2\2\u0141\u0161\3\2\2\2\u0142\u0143\6"+ - "\21\21\3\u0143\u0161\5\"\22\2\u0144\u0145\6\21\22\3\u0145\u0146\t\13\2"+ - "\2\u0146\u0161\b\21\1\2\u0147\u0148\6\21\23\3\u0148\u0149\7L\2\2\u0149"+ - "\u0161\b\21\1\2\u014a\u014b\6\21\24\3\u014b\u014c\7M\2\2\u014c\u0161\b"+ - "\21\1\2\u014d\u014e\6\21\25\3\u014e\u014f\7N\2\2\u014f\u0161\b\21\1\2"+ - "\u0150\u0151\6\21\26\3\u0151\u0152\5@!\2\u0152\u0153\b\21\1\2\u0153\u0161"+ - "\3\2\2\2\u0154\u0155\6\21\27\3\u0155\u0156\5B\"\2\u0156\u0157\b\21\1\2"+ - "\u0157\u0161\3\2\2\2\u0158\u0159\6\21\30\3\u0159\u015a\t\f\2\2\u015a\u0161"+ - "\5 \21\2\u015b\u015c\7\t\2\2\u015c\u015d\5\26\f\2\u015d\u015e\7\n\2\2"+ - "\u015e\u015f\5 \21\2\u015f\u0161\3\2\2\2\u0160\u013b\3\2\2\2\u0160\u013e"+ - "\3\2\2\2\u0160\u0142\3\2\2\2\u0160\u0144\3\2\2\2\u0160\u0147\3\2\2\2\u0160"+ - "\u014a\3\2\2\2\u0160\u014d\3\2\2\2\u0160\u0150\3\2\2\2\u0160\u0154\3\2"+ - "\2\2\u0160\u0158\3\2\2\2\u0160\u015b\3\2\2\2\u0161!\3\2\2\2\u0162\u0166"+ - "\5$\23\2\u0163\u0165\5&\24\2\u0164\u0163\3\2\2\2\u0165\u0168\3\2\2\2\u0166"+ - "\u0164\3\2\2\2\u0166\u0167\3\2\2\2\u0167\u0173\3\2\2\2\u0168\u0166\3\2"+ - "\2\2\u0169\u016a\5\26\f\2\u016a\u016e\5(\25\2\u016b\u016d\5&\24\2\u016c"+ - "\u016b\3\2\2\2\u016d\u0170\3\2\2\2\u016e\u016c\3\2\2\2\u016e\u016f\3\2"+ - "\2\2\u016f\u0173\3\2\2\2\u0170\u016e\3\2\2\2\u0171\u0173\5> \2\u0172\u0162"+ - "\3\2\2\2\u0172\u0169\3\2\2\2\u0172\u0171\3\2\2\2\u0173#\3\2\2\2\u0174"+ - "\u0175\6\23\31\3\u0175\u0176\7\t\2\2\u0176\u0177\5\36\20\2\u0177\u0178"+ - "\7\n\2\2\u0178\u0179\b\23\1\2\u0179\u0188\3\2\2\2\u017a\u017b\6\23\32"+ - "\3\u017b\u017c\7\t\2\2\u017c\u017d\5 \21\2\u017d\u017e\7\n\2\2\u017e\u0188"+ - "\3\2\2\2\u017f\u0188\7J\2\2\u0180\u0188\7K\2\2\u0181\u0188\7P\2\2\u0182"+ - "\u0183\7P\2\2\u0183\u0188\5,\27\2\u0184\u0185\7\26\2\2\u0185\u0186\7O"+ - "\2\2\u0186\u0188\5,\27\2\u0187\u0174\3\2\2\2\u0187\u017a\3\2\2\2\u0187"+ - "\u017f\3\2\2\2\u0187\u0180\3\2\2\2\u0187\u0181\3\2\2\2\u0187\u0182\3\2"+ - "\2\2\u0187\u0184\3\2\2\2\u0188%\3\2\2\2\u0189\u018a\6\24\33\3\u018a\u018e"+ - "\5(\25\2\u018b\u018c\6\24\34\3\u018c\u018e\5*\26\2\u018d\u0189\3\2\2\2"+ - "\u018d\u018b\3\2\2\2\u018e\'\3\2\2\2\u018f\u0190\7\13\2\2\u0190\u0191"+ - "\7R\2\2\u0191\u0195\5,\27\2\u0192\u0193\7\13\2\2\u0193\u0195\t\r\2\2\u0194"+ - "\u018f\3\2\2\2\u0194\u0192\3\2\2\2\u0195)\3\2\2\2\u0196\u0197\7\7\2\2"+ - "\u0197\u0198\5\36\20\2\u0198\u0199\7\b\2\2\u0199+\3\2\2\2\u019a\u01a3"+ - "\7\t\2\2\u019b\u01a0\5.\30\2\u019c\u019d\7\f\2\2\u019d\u019f\5.\30\2\u019e"+ - "\u019c\3\2\2\2\u019f\u01a2\3\2\2\2\u01a0\u019e\3\2\2\2\u01a0\u01a1\3\2"+ - "\2\2\u01a1\u01a4\3\2\2\2\u01a2\u01a0\3\2\2\2\u01a3\u019b\3\2\2\2\u01a3"+ - "\u01a4\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a6\7\n\2\2\u01a6-\3\2\2\2"+ - "\u01a7\u01ab\5\36\20\2\u01a8\u01ab\5\60\31\2\u01a9\u01ab\5\64\33\2\u01aa"+ - "\u01a7\3\2\2\2\u01aa\u01a8\3\2\2\2\u01aa\u01a9\3\2\2\2\u01ab/\3\2\2\2"+ - "\u01ac\u01ba\5\62\32\2\u01ad\u01b6\7\t\2\2\u01ae\u01b3\5\62\32\2\u01af"+ - "\u01b0\7\f\2\2\u01b0\u01b2\5\62\32\2\u01b1\u01af\3\2\2\2\u01b2\u01b5\3"+ - "\2\2\2\u01b3\u01b1\3\2\2\2\u01b3\u01b4\3\2\2\2\u01b4\u01b7\3\2\2\2\u01b5"+ - "\u01b3\3\2\2\2\u01b6\u01ae\3\2\2\2\u01b6\u01b7\3\2\2\2\u01b7\u01b8\3\2"+ - "\2\2\u01b8\u01ba\7\n\2\2\u01b9\u01ac\3\2\2\2\u01b9\u01ad\3\2\2\2\u01ba"+ - "\u01bb\3\2\2\2\u01bb\u01be\7\65\2\2\u01bc\u01bf\5\f\7\2\u01bd\u01bf\5"+ - "\36\20\2\u01be\u01bc\3\2\2\2\u01be\u01bd\3\2\2\2\u01bf\61\3\2\2\2\u01c0"+ - "\u01c2\5\26\f\2\u01c1\u01c0\3\2\2\2\u01c1\u01c2\3\2\2\2\u01c2\u01c3\3"+ - "\2\2\2\u01c3\u01c4\7P\2\2\u01c4\63\3\2\2\2\u01c5\u01ca\5\66\34\2\u01c6"+ - "\u01ca\58\35\2\u01c7\u01ca\5:\36\2\u01c8\u01ca\5<\37\2\u01c9\u01c5\3\2"+ - "\2\2\u01c9\u01c6\3\2\2\2\u01c9\u01c7\3\2\2\2\u01c9\u01c8\3\2\2\2\u01ca"+ - "\65\3\2\2\2\u01cb\u01cc\7O\2\2\u01cc\u01cd\7\64\2\2\u01cd\u01ce\7P\2\2"+ - "\u01ce\67\3\2\2\2\u01cf\u01d0\5\26\f\2\u01d0\u01d1\7\64\2\2\u01d1\u01d2"+ - "\7\26\2\2\u01d29\3\2\2\2\u01d3\u01d4\7P\2\2\u01d4\u01d5\7\64\2\2\u01d5"+ - "\u01d6\7P\2\2\u01d6;\3\2\2\2\u01d7\u01d8\7\32\2\2\u01d8\u01d9\7\64\2\2"+ - "\u01d9\u01da\7P\2\2\u01da=\3\2\2\2\u01db\u01dc\7\26\2\2\u01dc\u01e1\7"+ - "O\2\2\u01dd\u01de\7\7\2\2\u01de\u01df\5\36\20\2\u01df\u01e0\7\b\2\2\u01e0"+ - "\u01e2\3\2\2\2\u01e1\u01dd\3\2\2\2\u01e2\u01e3\3\2\2\2\u01e3\u01e1\3\2"+ - "\2\2\u01e3\u01e4\3\2\2\2\u01e4\u01ec\3\2\2\2\u01e5\u01e9\5(\25\2\u01e6"+ - "\u01e8\5&\24\2\u01e7\u01e6\3\2\2\2\u01e8\u01eb\3\2\2\2\u01e9\u01e7\3\2"+ - "\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01ed\3\2\2\2\u01eb\u01e9\3\2\2\2\u01ec"+ - "\u01e5\3\2\2\2\u01ec\u01ed\3\2\2\2\u01ed\u0202\3\2\2\2\u01ee\u01ef\7\26"+ - "\2\2\u01ef\u01f0\7O\2\2\u01f0\u01f1\7\7\2\2\u01f1\u01f2\7\b\2\2\u01f2"+ - "\u01fb\7\5\2\2\u01f3\u01f8\5\36\20\2\u01f4\u01f5\7\f\2\2\u01f5\u01f7\5"+ - "\36\20\2\u01f6\u01f4\3\2\2\2\u01f7\u01fa\3\2\2\2\u01f8\u01f6\3\2\2\2\u01f8"+ - "\u01f9\3\2\2\2\u01f9\u01fc\3\2\2\2\u01fa\u01f8\3\2\2\2\u01fb\u01f3\3\2"+ - "\2\2\u01fb\u01fc\3\2\2\2\u01fc\u01fe\3\2\2\2\u01fd\u01ff\7\r\2\2\u01fe"+ - "\u01fd\3\2\2\2\u01fe\u01ff\3\2\2\2\u01ff\u0200\3\2\2\2\u0200\u0202\7\6"+ - "\2\2\u0201\u01db\3\2\2\2\u0201\u01ee\3\2\2\2\u0202?\3\2\2\2\u0203\u0204"+ - "\7\7\2\2\u0204\u0209\5\36\20\2\u0205\u0206\7\f\2\2\u0206\u0208\5\36\20"+ - "\2\u0207\u0205\3\2\2\2\u0208\u020b\3\2\2\2\u0209\u0207\3\2\2\2\u0209\u020a"+ - "\3\2\2\2\u020a\u020c\3\2\2\2\u020b\u0209\3\2\2\2\u020c\u020d\7\b\2\2\u020d"+ - "\u0211\3\2\2\2\u020e\u020f\7\7\2\2\u020f\u0211\7\b\2\2\u0210\u0203\3\2"+ - "\2\2\u0210\u020e\3\2\2\2\u0211A\3\2\2\2\u0212\u0213\7\7\2\2\u0213\u0218"+ - "\5D#\2\u0214\u0215\7\f\2\2\u0215\u0217\5D#\2\u0216\u0214\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\7\b\2\2\u021c\u0221\3\2\2\2\u021d"+ - "\u021e\7\7\2\2\u021e\u021f\7\63\2\2\u021f\u0221\7\b\2\2\u0220\u0212\3"+ - "\2\2\2\u0220\u021d\3\2\2\2\u0221C\3\2\2\2\u0222\u0223\5\36\20\2\u0223"+ - "\u0224\7\63\2\2\u0224\u0225\5\36\20\2\u0225E\3\2\2\2\62IObeqy\u0086\u008a"+ - "\u008e\u0093\u00ae\u00b7\u00bb\u00c1\u00ca\u00d4\u00dc\u00e2\u00f6\u0136"+ - "\u0138\u0160\u0166\u016e\u0172\u0187\u018d\u0194\u01a0\u01a3\u01aa\u01b3"+ - "\u01b6\u01b9\u01be\u01c1\u01c9\u01e3\u01e9\u01ec\u01f8\u01fb\u01fe\u0201"+ - "\u0209\u0210\u0218\u0220"; + "\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\5\21\u0166\n\21\3\22\3\22\7\22"+ + "\u016a\n\22\f\22\16\22\u016d\13\22\3\22\3\22\3\22\7\22\u0172\n\22\f\22"+ + "\16\22\u0175\13\22\3\22\5\22\u0178\n\22\3\23\3\23\3\23\3\23\3\23\3\23"+ + "\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23"+ + "\u018d\n\23\3\24\3\24\3\24\3\24\5\24\u0193\n\24\3\25\3\25\3\25\3\25\3"+ + "\25\5\25\u019a\n\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\7\27\u01a4"+ + "\n\27\f\27\16\27\u01a7\13\27\5\27\u01a9\n\27\3\27\3\27\3\30\3\30\3\30"+ + "\5\30\u01b0\n\30\3\31\3\31\3\31\3\31\3\31\7\31\u01b7\n\31\f\31\16\31\u01ba"+ + "\13\31\5\31\u01bc\n\31\3\31\5\31\u01bf\n\31\3\31\3\31\3\31\5\31\u01c4"+ + "\n\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 \3 \3 \3 \3 \3 \6 \u01e7\n \r \16 \u01e8\3 \3 \7 \u01ed"+ + "\n \f \16 \u01f0\13 \5 \u01f2\n \3 \3 \3 \3 \3 \3 \3 \3 \7 \u01fc\n \f"+ + " \16 \u01ff\13 \5 \u0201\n \3 \5 \u0204\n \3 \5 \u0207\n \3!\3!\3!\3!"+ + "\7!\u020d\n!\f!\16!\u0210\13!\3!\3!\3!\3!\5!\u0216\n!\3\"\3\"\3\"\3\""+ + "\7\"\u021c\n\"\f\"\16\"\u021f\13\"\3\"\3\"\3\"\3\"\3\"\5\"\u0226\n\"\3"+ + "#\3#\3#\3#\3#\2\3\36$\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,."+ + "\60\62\64\668:<>@BD\2\16\3\3\r\r\3\2;F\3\2\36 \3\2!\"\3\2\678\3\2#%\3"+ + "\2&)\3\2*-\3\29:\3\2GJ\4\2\34\35!\"\3\2RS\u0260\2I\3\2\2\2\4T\3\2\2\2"+ + "\6Y\3\2\2\2\b\u00b7\3\2\2\2\n\u00bb\3\2\2\2\f\u00bd\3\2\2\2\16\u00c6\3"+ + "\2\2\2\20\u00ca\3\2\2\2\22\u00cc\3\2\2\2\24\u00ce\3\2\2\2\26\u00d7\3\2"+ + "\2\2\30\u00df\3\2\2\2\32\u00e4\3\2\2\2\34\u00eb\3\2\2\2\36\u00f6\3\2\2"+ + "\2 \u0165\3\2\2\2\"\u0177\3\2\2\2$\u018c\3\2\2\2&\u0192\3\2\2\2(\u0199"+ + "\3\2\2\2*\u019b\3\2\2\2,\u019f\3\2\2\2.\u01af\3\2\2\2\60\u01be\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>\u0206\3\2\2\2@\u0215\3\2\2\2B\u0225\3\2\2\2D"+ + "\u0227\3\2\2\2FH\5\4\3\2GF\3\2\2\2HK\3\2\2\2IG\3\2\2\2IJ\3\2\2\2JO\3\2"+ + "\2\2KI\3\2\2\2LN\5\b\5\2ML\3\2\2\2NQ\3\2\2\2OM\3\2\2\2OP\3\2\2\2PR\3\2"+ + "\2\2QO\3\2\2\2RS\7\2\2\3S\3\3\2\2\2TU\5\26\f\2UV\7Q\2\2VW\5\6\4\2WX\5"+ + "\f\7\2X\5\3\2\2\2Ye\7\t\2\2Z[\5\26\f\2[b\7Q\2\2\\]\7\f\2\2]^\5\26\f\2"+ + "^_\7Q\2\2_a\3\2\2\2`\\\3\2\2\2ad\3\2\2\2b`\3\2\2\2bc\3\2\2\2cf\3\2\2\2"+ + "db\3\2\2\2eZ\3\2\2\2ef\3\2\2\2fg\3\2\2\2gh\7\n\2\2h\7\3\2\2\2ij\7\16\2"+ + "\2jk\7\t\2\2kl\5\36\20\2lm\7\n\2\2mq\5\n\6\2no\7\17\2\2or\5\n\6\2pr\6"+ + "\5\2\2qn\3\2\2\2qp\3\2\2\2r\u00b8\3\2\2\2st\7\20\2\2tu\7\t\2\2uv\5\36"+ + "\20\2vy\7\n\2\2wz\5\n\6\2xz\5\16\b\2yw\3\2\2\2yx\3\2\2\2z\u00b8\3\2\2"+ + "\2{|\7\21\2\2|}\5\f\7\2}~\7\20\2\2~\177\7\t\2\2\177\u0080\5\36\20\2\u0080"+ + "\u0081\7\n\2\2\u0081\u0082\5\34\17\2\u0082\u00b8\3\2\2\2\u0083\u0084\7"+ + "\22\2\2\u0084\u0086\7\t\2\2\u0085\u0087\5\20\t\2\u0086\u0085\3\2\2\2\u0086"+ + "\u0087\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u008a\7\r\2\2\u0089\u008b\5\36"+ + "\20\2\u008a\u0089\3\2\2\2\u008a\u008b\3\2\2\2\u008b\u008c\3\2\2\2\u008c"+ + "\u008e\7\r\2\2\u008d\u008f\5\22\n\2\u008e\u008d\3\2\2\2\u008e\u008f\3"+ + "\2\2\2\u008f\u0090\3\2\2\2\u0090\u0093\7\n\2\2\u0091\u0094\5\n\6\2\u0092"+ + "\u0094\5\16\b\2\u0093\u0091\3\2\2\2\u0093\u0092\3\2\2\2\u0094\u00b8\3"+ + "\2\2\2\u0095\u0096\7\22\2\2\u0096\u0097\7\t\2\2\u0097\u0098\5\26\f\2\u0098"+ + "\u0099\7Q\2\2\u0099\u009a\7\64\2\2\u009a\u009b\5\36\20\2\u009b\u009c\7"+ + "\n\2\2\u009c\u009d\5\n\6\2\u009d\u00b8\3\2\2\2\u009e\u009f\5\24\13\2\u009f"+ + "\u00a0\5\34\17\2\u00a0\u00b8\3\2\2\2\u00a1\u00a2\7\23\2\2\u00a2\u00b8"+ + "\5\34\17\2\u00a3\u00a4\7\24\2\2\u00a4\u00b8\5\34\17\2\u00a5\u00a6\7\25"+ + "\2\2\u00a6\u00a7\5\36\20\2\u00a7\u00a8\5\34\17\2\u00a8\u00b8\3\2\2\2\u00a9"+ + "\u00aa\7\27\2\2\u00aa\u00ac\5\f\7\2\u00ab\u00ad\5\32\16\2\u00ac\u00ab"+ + "\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ae\u00ac\3\2\2\2\u00ae\u00af\3\2\2\2\u00af"+ + "\u00b8\3\2\2\2\u00b0\u00b1\7\31\2\2\u00b1\u00b2\5\36\20\2\u00b2\u00b3"+ + "\5\34\17\2\u00b3\u00b8\3\2\2\2\u00b4\u00b5\5\36\20\2\u00b5\u00b6\5\34"+ + "\17\2\u00b6\u00b8\3\2\2\2\u00b7i\3\2\2\2\u00b7s\3\2\2\2\u00b7{\3\2\2\2"+ + "\u00b7\u0083\3\2\2\2\u00b7\u0095\3\2\2\2\u00b7\u009e\3\2\2\2\u00b7\u00a1"+ + "\3\2\2\2\u00b7\u00a3\3\2\2\2\u00b7\u00a5\3\2\2\2\u00b7\u00a9\3\2\2\2\u00b7"+ + "\u00b0\3\2\2\2\u00b7\u00b4\3\2\2\2\u00b8\t\3\2\2\2\u00b9\u00bc\5\f\7\2"+ + "\u00ba\u00bc\5\b\5\2\u00bb\u00b9\3\2\2\2\u00bb\u00ba\3\2\2\2\u00bc\13"+ + "\3\2\2\2\u00bd\u00c1\7\5\2\2\u00be\u00c0\5\b\5\2\u00bf\u00be\3\2\2\2\u00c0"+ + "\u00c3\3\2\2\2\u00c1\u00bf\3\2\2\2\u00c1\u00c2\3\2\2\2\u00c2\u00c4\3\2"+ + "\2\2\u00c3\u00c1\3\2\2\2\u00c4\u00c5\7\6\2\2\u00c5\r\3\2\2\2\u00c6\u00c7"+ + "\7\r\2\2\u00c7\17\3\2\2\2\u00c8\u00cb\5\24\13\2\u00c9\u00cb\5\36\20\2"+ + "\u00ca\u00c8\3\2\2\2\u00ca\u00c9\3\2\2\2\u00cb\21\3\2\2\2\u00cc\u00cd"+ + "\5\36\20\2\u00cd\23\3\2\2\2\u00ce\u00cf\5\26\f\2\u00cf\u00d4\5\30\r\2"+ + "\u00d0\u00d1\7\f\2\2\u00d1\u00d3\5\30\r\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\25\3\2\2\2\u00d6"+ + "\u00d4\3\2\2\2\u00d7\u00dc\7P\2\2\u00d8\u00d9\7\7\2\2\u00d9\u00db\7\b"+ + "\2\2\u00da\u00d8\3\2\2\2\u00db\u00de\3\2\2\2\u00dc\u00da\3\2\2\2\u00dc"+ + "\u00dd\3\2\2\2\u00dd\27\3\2\2\2\u00de\u00dc\3\2\2\2\u00df\u00e2\7Q\2\2"+ + "\u00e0\u00e1\7;\2\2\u00e1\u00e3\5\36\20\2\u00e2\u00e0\3\2\2\2\u00e2\u00e3"+ + "\3\2\2\2\u00e3\31\3\2\2\2\u00e4\u00e5\7\30\2\2\u00e5\u00e6\7\t\2\2\u00e6"+ + "\u00e7\7P\2\2\u00e7\u00e8\7Q\2\2\u00e8\u00e9\7\n\2\2\u00e9\u00ea\5\f\7"+ + "\2\u00ea\33\3\2\2\2\u00eb\u00ec\t\2\2\2\u00ec\35\3\2\2\2\u00ed\u00ee\b"+ + "\20\1\2\u00ee\u00ef\5\"\22\2\u00ef\u00f0\t\3\2\2\u00f0\u00f1\5\36\20\3"+ + "\u00f1\u00f2\b\20\1\2\u00f2\u00f7\3\2\2\2\u00f3\u00f4\5 \21\2\u00f4\u00f5"+ + "\b\20\1\2\u00f5\u00f7\3\2\2\2\u00f6\u00ed\3\2\2\2\u00f6\u00f3\3\2\2\2"+ + "\u00f7\u013d\3\2\2\2\u00f8\u00f9\f\20\2\2\u00f9\u00fa\t\4\2\2\u00fa\u00fb"+ + "\5\36\20\21\u00fb\u00fc\b\20\1\2\u00fc\u013c\3\2\2\2\u00fd\u00fe\f\17"+ + "\2\2\u00fe\u00ff\t\5\2\2\u00ff\u0100\5\36\20\20\u0100\u0101\b\20\1\2\u0101"+ + "\u013c\3\2\2\2\u0102\u0103\f\16\2\2\u0103\u0104\t\6\2\2\u0104\u0105\5"+ + "\36\20\17\u0105\u0106\b\20\1\2\u0106\u013c\3\2\2\2\u0107\u0108\f\r\2\2"+ + "\u0108\u0109\t\7\2\2\u0109\u010a\5\36\20\16\u010a\u010b\b\20\1\2\u010b"+ + "\u013c\3\2\2\2\u010c\u010d\f\f\2\2\u010d\u010e\t\b\2\2\u010e\u010f\5\36"+ + "\20\r\u010f\u0110\b\20\1\2\u0110\u013c\3\2\2\2\u0111\u0112\f\n\2\2\u0112"+ + "\u0113\t\t\2\2\u0113\u0114\5\36\20\13\u0114\u0115\b\20\1\2\u0115\u013c"+ + "\3\2\2\2\u0116\u0117\f\t\2\2\u0117\u0118\7.\2\2\u0118\u0119\5\36\20\n"+ + "\u0119\u011a\b\20\1\2\u011a\u013c\3\2\2\2\u011b\u011c\f\b\2\2\u011c\u011d"+ + "\7/\2\2\u011d\u011e\5\36\20\t\u011e\u011f\b\20\1\2\u011f\u013c\3\2\2\2"+ + "\u0120\u0121\f\7\2\2\u0121\u0122\7\60\2\2\u0122\u0123\5\36\20\b\u0123"+ + "\u0124\b\20\1\2\u0124\u013c\3\2\2\2\u0125\u0126\f\6\2\2\u0126\u0127\7"+ + "\61\2\2\u0127\u0128\5\36\20\7\u0128\u0129\b\20\1\2\u0129\u013c\3\2\2\2"+ + "\u012a\u012b\f\5\2\2\u012b\u012c\7\62\2\2\u012c\u012d\5\36\20\6\u012d"+ + "\u012e\b\20\1\2\u012e\u013c\3\2\2\2\u012f\u0130\f\4\2\2\u0130\u0131\7"+ + "\63\2\2\u0131\u0132\5\36\20\2\u0132\u0133\7\64\2\2\u0133\u0134\5\36\20"+ + "\4\u0134\u0135\b\20\1\2\u0135\u013c\3\2\2\2\u0136\u0137\f\13\2\2\u0137"+ + "\u0138\7\33\2\2\u0138\u0139\5\26\f\2\u0139\u013a\b\20\1\2\u013a\u013c"+ + "\3\2\2\2\u013b\u00f8\3\2\2\2\u013b\u00fd\3\2\2\2\u013b\u0102\3\2\2\2\u013b"+ + "\u0107\3\2\2\2\u013b\u010c\3\2\2\2\u013b\u0111\3\2\2\2\u013b\u0116\3\2"+ + "\2\2\u013b\u011b\3\2\2\2\u013b\u0120\3\2\2\2\u013b\u0125\3\2\2\2\u013b"+ + "\u012a\3\2\2\2\u013b\u012f\3\2\2\2\u013b\u0136\3\2\2\2\u013c\u013f\3\2"+ + "\2\2\u013d\u013b\3\2\2\2\u013d\u013e\3\2\2\2\u013e\37\3\2\2\2\u013f\u013d"+ + "\3\2\2\2\u0140\u0141\6\21\20\3\u0141\u0142\t\n\2\2\u0142\u0166\5\"\22"+ + "\2\u0143\u0144\6\21\21\3\u0144\u0145\5\"\22\2\u0145\u0146\t\n\2\2\u0146"+ + "\u0166\3\2\2\2\u0147\u0148\6\21\22\3\u0148\u0166\5\"\22\2\u0149\u014a"+ + "\6\21\23\3\u014a\u014b\t\13\2\2\u014b\u0166\b\21\1\2\u014c\u014d\6\21"+ + "\24\3\u014d\u014e\7M\2\2\u014e\u0166\b\21\1\2\u014f\u0150\6\21\25\3\u0150"+ + "\u0151\7N\2\2\u0151\u0166\b\21\1\2\u0152\u0153\6\21\26\3\u0153\u0154\7"+ + "O\2\2\u0154\u0166\b\21\1\2\u0155\u0156\6\21\27\3\u0156\u0157\5@!\2\u0157"+ + "\u0158\b\21\1\2\u0158\u0166\3\2\2\2\u0159\u015a\6\21\30\3\u015a\u015b"+ + "\5B\"\2\u015b\u015c\b\21\1\2\u015c\u0166\3\2\2\2\u015d\u015e\6\21\31\3"+ + "\u015e\u015f\t\f\2\2\u015f\u0166\5 \21\2\u0160\u0161\7\t\2\2\u0161\u0162"+ + "\5\26\f\2\u0162\u0163\7\n\2\2\u0163\u0164\5 \21\2\u0164\u0166\3\2\2\2"+ + "\u0165\u0140\3\2\2\2\u0165\u0143\3\2\2\2\u0165\u0147\3\2\2\2\u0165\u0149"+ + "\3\2\2\2\u0165\u014c\3\2\2\2\u0165\u014f\3\2\2\2\u0165\u0152\3\2\2\2\u0165"+ + "\u0155\3\2\2\2\u0165\u0159\3\2\2\2\u0165\u015d\3\2\2\2\u0165\u0160\3\2"+ + "\2\2\u0166!\3\2\2\2\u0167\u016b\5$\23\2\u0168\u016a\5&\24\2\u0169\u0168"+ + "\3\2\2\2\u016a\u016d\3\2\2\2\u016b\u0169\3\2\2\2\u016b\u016c\3\2\2\2\u016c"+ + "\u0178\3\2\2\2\u016d\u016b\3\2\2\2\u016e\u016f\5\26\f\2\u016f\u0173\5"+ + "(\25\2\u0170\u0172\5&\24\2\u0171\u0170\3\2\2\2\u0172\u0175\3\2\2\2\u0173"+ + "\u0171\3\2\2\2\u0173\u0174\3\2\2\2\u0174\u0178\3\2\2\2\u0175\u0173\3\2"+ + "\2\2\u0176\u0178\5> \2\u0177\u0167\3\2\2\2\u0177\u016e\3\2\2\2\u0177\u0176"+ + "\3\2\2\2\u0178#\3\2\2\2\u0179\u017a\6\23\32\3\u017a\u017b\7\t\2\2\u017b"+ + "\u017c\5\36\20\2\u017c\u017d\7\n\2\2\u017d\u017e\b\23\1\2\u017e\u018d"+ + "\3\2\2\2\u017f\u0180\6\23\33\3\u0180\u0181\7\t\2\2\u0181\u0182\5 \21\2"+ + "\u0182\u0183\7\n\2\2\u0183\u018d\3\2\2\2\u0184\u018d\7K\2\2\u0185\u018d"+ + "\7L\2\2\u0186\u018d\7Q\2\2\u0187\u0188\7Q\2\2\u0188\u018d\5,\27\2\u0189"+ + "\u018a\7\26\2\2\u018a\u018b\7P\2\2\u018b\u018d\5,\27\2\u018c\u0179\3\2"+ + "\2\2\u018c\u017f\3\2\2\2\u018c\u0184\3\2\2\2\u018c\u0185\3\2\2\2\u018c"+ + "\u0186\3\2\2\2\u018c\u0187\3\2\2\2\u018c\u0189\3\2\2\2\u018d%\3\2\2\2"+ + "\u018e\u018f\6\24\34\3\u018f\u0193\5(\25\2\u0190\u0191\6\24\35\3\u0191"+ + "\u0193\5*\26\2\u0192\u018e\3\2\2\2\u0192\u0190\3\2\2\2\u0193\'\3\2\2\2"+ + "\u0194\u0195\7\13\2\2\u0195\u0196\7S\2\2\u0196\u019a\5,\27\2\u0197\u0198"+ + "\7\13\2\2\u0198\u019a\t\r\2\2\u0199\u0194\3\2\2\2\u0199\u0197\3\2\2\2"+ + "\u019a)\3\2\2\2\u019b\u019c\7\7\2\2\u019c\u019d\5\36\20\2\u019d\u019e"+ + "\7\b\2\2\u019e+\3\2\2\2\u019f\u01a8\7\t\2\2\u01a0\u01a5\5.\30\2\u01a1"+ + "\u01a2\7\f\2\2\u01a2\u01a4\5.\30\2\u01a3\u01a1\3\2\2\2\u01a4\u01a7\3\2"+ + "\2\2\u01a5\u01a3\3\2\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a9\3\2\2\2\u01a7"+ + "\u01a5\3\2\2\2\u01a8\u01a0\3\2\2\2\u01a8\u01a9\3\2\2\2\u01a9\u01aa\3\2"+ + "\2\2\u01aa\u01ab\7\n\2\2\u01ab-\3\2\2\2\u01ac\u01b0\5\36\20\2\u01ad\u01b0"+ + "\5\60\31\2\u01ae\u01b0\5\64\33\2\u01af\u01ac\3\2\2\2\u01af\u01ad\3\2\2"+ + "\2\u01af\u01ae\3\2\2\2\u01b0/\3\2\2\2\u01b1\u01bf\5\62\32\2\u01b2\u01bb"+ + "\7\t\2\2\u01b3\u01b8\5\62\32\2\u01b4\u01b5\7\f\2\2\u01b5\u01b7\5\62\32"+ + "\2\u01b6\u01b4\3\2\2\2\u01b7\u01ba\3\2\2\2\u01b8\u01b6\3\2\2\2\u01b8\u01b9"+ + "\3\2\2\2\u01b9\u01bc\3\2\2\2\u01ba\u01b8\3\2\2\2\u01bb\u01b3\3\2\2\2\u01bb"+ + "\u01bc\3\2\2\2\u01bc\u01bd\3\2\2\2\u01bd\u01bf\7\n\2\2\u01be\u01b1\3\2"+ + "\2\2\u01be\u01b2\3\2\2\2\u01bf\u01c0\3\2\2\2\u01c0\u01c3\7\66\2\2\u01c1"+ + "\u01c4\5\f\7\2\u01c2\u01c4\5\36\20\2\u01c3\u01c1\3\2\2\2\u01c3\u01c2\3"+ + "\2\2\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\7Q\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\7P\2\2\u01d1\u01d2\7\65\2"+ + "\2\u01d2\u01d3\7Q\2\2\u01d3\67\3\2\2\2\u01d4\u01d5\5\26\f\2\u01d5\u01d6"+ + "\7\65\2\2\u01d6\u01d7\7\26\2\2\u01d79\3\2\2\2\u01d8\u01d9\7Q\2\2\u01d9"+ + "\u01da\7\65\2\2\u01da\u01db\7Q\2\2\u01db;\3\2\2\2\u01dc\u01dd\7\32\2\2"+ + "\u01dd\u01de\7\65\2\2\u01de\u01df\7Q\2\2\u01df=\3\2\2\2\u01e0\u01e1\7"+ + "\26\2\2\u01e1\u01e6\7P\2\2\u01e2\u01e3\7\7\2\2\u01e3\u01e4\5\36\20\2\u01e4"+ + "\u01e5\7\b\2\2\u01e5\u01e7\3\2\2\2\u01e6\u01e2\3\2\2\2\u01e7\u01e8\3\2"+ + "\2\2\u01e8\u01e6\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01f1\3\2\2\2\u01ea"+ + "\u01ee\5(\25\2\u01eb\u01ed\5&\24\2\u01ec\u01eb\3\2\2\2\u01ed\u01f0\3\2"+ + "\2\2\u01ee\u01ec\3\2\2\2\u01ee\u01ef\3\2\2\2\u01ef\u01f2\3\2\2\2\u01f0"+ + "\u01ee\3\2\2\2\u01f1\u01ea\3\2\2\2\u01f1\u01f2\3\2\2\2\u01f2\u0207\3\2"+ + "\2\2\u01f3\u01f4\7\26\2\2\u01f4\u01f5\7P\2\2\u01f5\u01f6\7\7\2\2\u01f6"+ + "\u01f7\7\b\2\2\u01f7\u0200\7\5\2\2\u01f8\u01fd\5\36\20\2\u01f9\u01fa\7"+ + "\f\2\2\u01fa\u01fc\5\36\20\2\u01fb\u01f9\3\2\2\2\u01fc\u01ff\3\2\2\2\u01fd"+ + "\u01fb\3\2\2\2\u01fd\u01fe\3\2\2\2\u01fe\u0201\3\2\2\2\u01ff\u01fd\3\2"+ + "\2\2\u0200\u01f8\3\2\2\2\u0200\u0201\3\2\2\2\u0201\u0203\3\2\2\2\u0202"+ + "\u0204\7\r\2\2\u0203\u0202\3\2\2\2\u0203\u0204\3\2\2\2\u0204\u0205\3\2"+ + "\2\2\u0205\u0207\7\6\2\2\u0206\u01e0\3\2\2\2\u0206\u01f3\3\2\2\2\u0207"+ + "?\3\2\2\2\u0208\u0209\7\7\2\2\u0209\u020e\5\36\20\2\u020a\u020b\7\f\2"+ + "\2\u020b\u020d\5\36\20\2\u020c\u020a\3\2\2\2\u020d\u0210\3\2\2\2\u020e"+ + "\u020c\3\2\2\2\u020e\u020f\3\2\2\2\u020f\u0211\3\2\2\2\u0210\u020e\3\2"+ + "\2\2\u0211\u0212\7\b\2\2\u0212\u0216\3\2\2\2\u0213\u0214\7\7\2\2\u0214"+ + "\u0216\7\b\2\2\u0215\u0208\3\2\2\2\u0215\u0213\3\2\2\2\u0216A\3\2\2\2"+ + "\u0217\u0218\7\7\2\2\u0218\u021d\5D#\2\u0219\u021a\7\f\2\2\u021a\u021c"+ + "\5D#\2\u021b\u0219\3\2\2\2\u021c\u021f\3\2\2\2\u021d\u021b\3\2\2\2\u021d"+ + "\u021e\3\2\2\2\u021e\u0220\3\2\2\2\u021f\u021d\3\2\2\2\u0220\u0221\7\b"+ + "\2\2\u0221\u0226\3\2\2\2\u0222\u0223\7\7\2\2\u0223\u0224\7\64\2\2\u0224"+ + "\u0226\7\b\2\2\u0225\u0217\3\2\2\2\u0225\u0222\3\2\2\2\u0226C\3\2\2\2"+ + "\u0227\u0228\5\36\20\2\u0228\u0229\7\64\2\2\u0229\u022a\5\36\20\2\u022a"+ + "E\3\2\2\2\62IObeqy\u0086\u008a\u008e\u0093\u00ae\u00b7\u00bb\u00c1\u00ca"+ + "\u00d4\u00dc\u00e2\u00f6\u013b\u013d\u0165\u016b\u0173\u0177\u018c\u0192"+ + "\u0199\u01a5\u01a8\u01af\u01b8\u01bb\u01be\u01c3\u01c6\u01ce\u01e8\u01ee"+ + "\u01f1\u01fd\u0200\u0203\u0206\u020e\u0215\u021d\u0225"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserBaseVisitor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserBaseVisitor.java index 498324441e6..a11a856edd4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserBaseVisitor.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserBaseVisitor.java @@ -228,6 +228,13 @@ class PainlessParserBaseVisitor extends AbstractParseTreeVisitor implement * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitBinary(PainlessParser.BinaryContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstanceof(PainlessParser.InstanceofContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserVisitor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserVisitor.java index e57a274f8ef..bc9e8c4f994 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserVisitor.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParserVisitor.java @@ -214,6 +214,13 @@ interface PainlessParserVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitBinary(PainlessParser.BinaryContext ctx); + /** + * Visit a parse tree produced by the {@code instanceof} + * labeled alternative in {@link PainlessParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstanceof(PainlessParser.InstanceofContext ctx); /** * Visit a parse tree produced by the {@code pre} * labeled alternative in {@link PainlessParser#unary}. 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 20384b57145..88774bb9984 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 @@ -82,6 +82,7 @@ import org.elasticsearch.painless.antlr.PainlessParser.FuncrefContext; import org.elasticsearch.painless.antlr.PainlessParser.FunctionContext; import org.elasticsearch.painless.antlr.PainlessParser.IfContext; import org.elasticsearch.painless.antlr.PainlessParser.InitializerContext; +import org.elasticsearch.painless.antlr.PainlessParser.InstanceofContext; import org.elasticsearch.painless.antlr.PainlessParser.LambdaContext; import org.elasticsearch.painless.antlr.PainlessParser.LamtypeContext; import org.elasticsearch.painless.antlr.PainlessParser.LocalFuncrefContext; @@ -124,6 +125,7 @@ import org.elasticsearch.painless.node.EConditional; import org.elasticsearch.painless.node.EDecimal; import org.elasticsearch.painless.node.EExplicit; import org.elasticsearch.painless.node.EFunctionRef; +import org.elasticsearch.painless.node.EInstanceof; import org.elasticsearch.painless.node.ELambda; import org.elasticsearch.painless.node.ENull; import org.elasticsearch.painless.node.ENumeric; @@ -1107,6 +1109,13 @@ public final class Walker extends PainlessParserBaseVisitor { throw location(ctx).createError(new IllegalStateException("Illegal tree structure.")); } + @Override + public Object visitInstanceof(InstanceofContext ctx) { + AExpression expr = (AExpression)visitExpression(ctx.expression()); + String type = ctx.decltype().getText(); + return new EInstanceof(location(ctx), expr, type); + } + /** Returns name of next lambda */ private String nextLambda() { return "lambda$" + syntheticCounter++; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java new file mode 100644 index 00000000000..312bb10efec --- /dev/null +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java @@ -0,0 +1,89 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.painless.node; + +import org.elasticsearch.painless.Definition; +import org.elasticsearch.painless.Globals; +import org.elasticsearch.painless.Locals; +import org.elasticsearch.painless.Location; +import org.elasticsearch.painless.MethodWriter; + +import java.lang.invoke.MethodType; +import java.util.Objects; +import java.util.Set; + +/** + * Represents instanceof operator. + *

+ * Unlike java's, this works for primitive types too. + */ +public class EInstanceof extends AExpression { + AExpression expression; + final String type; + Class resolvedType; + Class expressionType; + boolean primitiveExpression; + + public EInstanceof(Location location, AExpression expression, String type) { + super(location); + this.expression = Objects.requireNonNull(expression); + this.type = Objects.requireNonNull(type); + } + + @Override + void extractVariables(Set variables) { + expression.extractVariables(variables); + } + + @Override + void analyze(Locals locals) { + Definition.Type raw = Definition.getType(type); + // map to wrapped type for primitive types + resolvedType = MethodType.methodType(raw.clazz).wrap().returnType(); + expression.analyze(locals); + actual = Definition.BOOLEAN_TYPE; + + Definition.Type expressionRaw = expression.actual; + if (expressionRaw == null) { + expressionRaw = Definition.DEF_TYPE; + } + // record if the expression returns a primitive + primitiveExpression = expressionRaw.clazz.isPrimitive(); + // map to wrapped type for primitive types + expressionType = MethodType.methodType(expressionRaw.clazz).wrap().returnType(); + } + + @Override + void write(MethodWriter writer, Globals globals) { + // primitive types + if (primitiveExpression) { + // run the expression anyway (who knows what it does) + expression.write(writer, globals); + // discard its result + writer.writePop(expression.actual.type.getSize()); + // push our result: its a primitive so it cannot be null. + writer.push(resolvedType == Object.class || resolvedType == expressionType); + } else { + // ordinary instanceof + expression.write(writer, globals); + writer.instanceOf(org.objectweb.asm.Type.getType(resolvedType)); + } + } +} diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java index 7111afa59f4..2e3d07ebf92 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java @@ -22,7 +22,7 @@ *

* The following are the types of nodes: * A* (abstract) - These are the abstract nodes that are the superclasses for the other types. - * I* (interface) -- Thse are marker interfaces to denote a property of the node. + * I* (interface) -- These are marker interfaces to denote a property of the node. * S* (statement) - These are nodes that represent a statement in Painless. These are the highest level nodes. * E* (expression) - These are nodes that represent an expression in Painless. These are the middle level nodes. * L* (link) - These are nodes that represent a piece of a variable/method chain. The are the lowest level nodes. @@ -44,8 +44,9 @@ * {@link org.elasticsearch.painless.node.EDecimal} - Represents a decimal constant. * {@link org.elasticsearch.painless.node.EExplicit} - Represents an explicit cast. * {@link org.elasticsearch.painless.node.EFunctionRef} - Represents a function reference (non-capturing). + * {@link org.elasticsearch.painless.node.EInstanceof} - Represents an instanceof check. * {@link org.elasticsearch.painless.node.EListInit} - Represents a list initialization shortcut. - * {@link org.elasticsearch.painless.node.EMapInit} - Represents a map initializiation shortcut. + * {@link org.elasticsearch.painless.node.EMapInit} - Represents a map initialization shortcut. * {@link org.elasticsearch.painless.node.ENull} - Represents a null constant. * {@link org.elasticsearch.painless.node.ENumeric} - Represents a non-decimal numeric constant. * {@link org.elasticsearch.painless.node.EUnary} - Represents a unary math expression. @@ -92,7 +93,7 @@ * All Painless trees must start with an SSource node at the root. Each node has a constructor that requires * all of its values and children be passed in at the time of instantiation. This means that Painless trees * are build bottom-up; however, this helps enforce tree structure to be correct and fits naturally with a - * standard recurvise-descent parser. + * standard recursive-descent parser. *

* Generally, statement nodes have member data that evaluate legal control-flow during the analysis phase. * The typical order for statement nodes is for each node to call analyze on it's children during the analysis phase diff --git a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/java.lang.txt b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/java.lang.txt index 035dc9ba0c8..17016f1d318 100644 --- a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/java.lang.txt +++ b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/java.lang.txt @@ -52,12 +52,15 @@ class Iterable -> java.lang.Iterable { Spliterator spliterator() # some adaptations of groovy methods boolean any*(Predicate) + Collection asCollection*() + List asList*() def each*(Consumer) def eachWithIndex*(ObjIntConsumer) boolean every*(Predicate) List findResults*(Function) Map groupBy*(Function) String join*(String) + double sum*() double sum*(ToDoubleFunction) } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/AugmentationTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/AugmentationTests.java index c0872dd1994..241de3c5db8 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/AugmentationTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/AugmentationTests.java @@ -58,6 +58,18 @@ public class AugmentationTests extends ScriptTestCase { exec("List l = new ArrayList(); l.add(1); l.any(x -> x == 1)")); } + public void testIterable_AsCollection() { + assertEquals(true, + exec("List l = new ArrayList(); return l.asCollection() === l")); + } + + public void testIterable_AsList() { + assertEquals(true, + exec("List l = new ArrayList(); return l.asList() === l")); + assertEquals(5, + exec("Set l = new HashSet(); l.add(5); return l.asList()[0]")); + } + public void testIterable_Each() { assertEquals(1, exec("List l = new ArrayList(); l.add(1); List l2 = new ArrayList(); l.each(l2::add); return l2.size()")); @@ -88,6 +100,7 @@ public class AugmentationTests extends ScriptTestCase { } public void testIterable_Sum() { + assertEquals(3.0D, exec("def l = [1,2]; return l.sum()")); assertEquals(5.0D, exec("List l = new ArrayList(); l.add(1); l.add(2); l.sum(x -> x + 1)")); } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ComparisonTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ComparisonTests.java index 355a1223273..73c0c6a3698 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ComparisonTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ComparisonTests.java @@ -439,4 +439,22 @@ public class ComparisonTests extends ScriptTestCase { assertEquals(true, exec("def x = (float)6; double y = (double)2; return x >= y")); assertEquals(true, exec("def x = (double)7; double y = (double)1; return x >= y")); } + + public void testInstanceOf() { + assertEquals(true, exec("int x = 5; return x instanceof int")); + assertEquals(true, exec("def x = 5; return x instanceof int")); + assertEquals(true, exec("def x = 5; return x instanceof def")); + assertEquals(true, exec("def x = 5; return x instanceof Object")); + assertEquals(true, exec("def x = 5; return x instanceof Integer")); + assertEquals(true, exec("def x = 5; return x instanceof Number")); + assertEquals(false, exec("def x = 5; return x instanceof float")); + assertEquals(false, exec("def x = 5; return x instanceof Map")); + assertEquals(true, exec("List l = new ArrayList(); return l instanceof List")); + assertEquals(false, exec("List l = null; return l instanceof List")); + assertEquals(true, exec("List l = new ArrayList(); return l instanceof Collection")); + assertEquals(false, exec("List l = new ArrayList(); return l instanceof Map")); + assertEquals(true, exec("int[] x = new int[] { 5 }; return x instanceof int[]")); + assertEquals(false, exec("int[] x = new int[] { 5 }; return x instanceof float[]")); + assertEquals(false, exec("int[] x = new int[] { 5 }; return x instanceof int[][]")); + } } From e6819648ccf09db6a47d794a6f09cea85b8df961 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Fri, 24 Jun 2016 12:44:57 -0400 Subject: [PATCH 2/2] fix the primitive case of instanceof --- .../java/org/elasticsearch/painless/node/EInstanceof.java | 2 +- .../test/java/org/elasticsearch/painless/ComparisonTests.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java index 312bb10efec..5f08ff521d8 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java @@ -79,7 +79,7 @@ public class EInstanceof extends AExpression { // discard its result writer.writePop(expression.actual.type.getSize()); // push our result: its a primitive so it cannot be null. - writer.push(resolvedType == Object.class || resolvedType == expressionType); + writer.push(resolvedType.isAssignableFrom(expressionType)); } else { // ordinary instanceof expression.write(writer, globals); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ComparisonTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ComparisonTests.java index 73c0c6a3698..d9259cf2008 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ComparisonTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ComparisonTests.java @@ -442,6 +442,10 @@ public class ComparisonTests extends ScriptTestCase { public void testInstanceOf() { assertEquals(true, exec("int x = 5; return x instanceof int")); + assertEquals(true, exec("int x = 5; return x instanceof Number")); + assertEquals(true, exec("int x = 5; return x instanceof Integer")); + assertEquals(true, exec("int x = 5; return x instanceof def")); + assertEquals(true, exec("int x = 5; return x instanceof Object")); assertEquals(true, exec("def x = 5; return x instanceof int")); assertEquals(true, exec("def x = 5; return x instanceof def")); assertEquals(true, exec("def x = 5; return x instanceof Object"));