mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-29 01:44:36 -04:00
Painless: =~ and ==~ operators
Adds support for the find operator (=~) and the match operator (==~) to painless's regexes. Also whitelists most of the Matcher class and documents regex support in painless. The find operator (=~) returns a boolean that is the result of building a matcher on the lhs with the Pattern on the RHS and calling `find` on it. Use it like this: ``` if (ctx._source.last =~ /b/) ``` The match operator (==~) returns boolean like find but instead of calling `find` on the Matcher it calls `matches`. ``` if (ctx._source.last ==~ /[^aeiou].*[aeiou]/) ``` Finally, if you want the actual matcher you do: ``` Matcher m = /[aeiou]/.matcher(ctx._source.last) ```
This commit is contained in:
parent
3c9712794e
commit
8d3ef742db
17 changed files with 947 additions and 700 deletions
|
@ -33,6 +33,8 @@ to `painless`.
|
|||
|
||||
* Shortcuts for list, map access using the dot `.` operator
|
||||
|
||||
* Native support for regular expressions with `/pattern/`, `=~`, and `==~`
|
||||
|
||||
|
||||
[[painless-examples]]
|
||||
[float]
|
||||
|
@ -199,6 +201,79 @@ POST hockey/player/1/_update
|
|||
----------------------------------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
[float]
|
||||
=== Regular expressions
|
||||
|
||||
Painless's native support for regular expressions has syntax constructs:
|
||||
|
||||
* `/pattern/`: Pattern literals create patterns. This is the only way to create
|
||||
a pattern in painless.
|
||||
* `=~`: The find operator return a `boolean`, `true` if a subsequence of the
|
||||
text matches, `false` otherwise.
|
||||
* `==~`: The match operator returns a `boolean`, `true` if the text matches,
|
||||
`false` if it doesn't.
|
||||
|
||||
Using the find operator (`=~`) you can update all hockey players with "b" in
|
||||
their last name:
|
||||
|
||||
[source,js]
|
||||
----------------------------------------------------------------
|
||||
POST hockey/player/_update_by_query
|
||||
{
|
||||
"script": {
|
||||
"lang": "painless",
|
||||
"inline": "if (ctx._source.last =~ /b/) {ctx._source.last += \"matched\"} else {ctx.op = 'noop'}"
|
||||
}
|
||||
}
|
||||
----------------------------------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
Using the match operator (`==~`) you can update all the hockey players who's
|
||||
names start with a consonant and end with a vowel:
|
||||
|
||||
[source,js]
|
||||
----------------------------------------------------------------
|
||||
POST hockey/player/_update_by_query
|
||||
{
|
||||
"script": {
|
||||
"lang": "painless",
|
||||
"inline": "if (ctx._source.last ==~ /[^aeiou].*[aeiou]/) {ctx._source.last += \"matched\"} else {ctx.op = 'noop'}"
|
||||
}
|
||||
}
|
||||
----------------------------------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
Or you can use the `Pattern.matcher` directory to get a `Matcher` instance and
|
||||
remove all of the vowels in all of their names:
|
||||
|
||||
[source,js]
|
||||
----------------------------------------------------------------
|
||||
POST hockey/player/_update_by_query
|
||||
{
|
||||
"script": {
|
||||
"lang": "painless",
|
||||
"inline": "ctx._source.last = /[aeiou]/.matcher(ctx._source.last).replaceAll('')"
|
||||
}
|
||||
}
|
||||
----------------------------------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
|
||||
Note: all of the `_update_by_query` examples above could really do with a
|
||||
`query` to limit the data that they pull back. While you *could* use a
|
||||
<<query-dsl-script-query>> it wouldn't be as efficient as using any other query
|
||||
because script queries aren't able to use the inverted index to limit the
|
||||
documents that they have to check.
|
||||
|
||||
The pattern syntax is just
|
||||
http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html[Java regular expressions].
|
||||
We intentionally don't allow scripts to call `Pattern.compile` to get a new
|
||||
pattern on the fly because building a `Pattern` is (comparatively) slow.
|
||||
Pattern literals (`/apattern/`) have fancy constant extraction so no matter
|
||||
where they show up in the painless script they are built only when the script
|
||||
is first used. It is fairly similar to how `String` literals work in Java.
|
||||
|
||||
|
||||
[[painless-api]]
|
||||
[float]
|
||||
== Painless API
|
||||
|
|
|
@ -80,6 +80,8 @@ COND: '?';
|
|||
COLON: ':';
|
||||
REF: '::';
|
||||
ARROW: '->';
|
||||
FIND: '=~';
|
||||
MATCH: '==~';
|
||||
INCR: '++';
|
||||
DECR: '--';
|
||||
|
||||
|
|
|
@ -49,33 +49,35 @@ COND=48
|
|||
COLON=49
|
||||
REF=50
|
||||
ARROW=51
|
||||
INCR=52
|
||||
DECR=53
|
||||
ASSIGN=54
|
||||
AADD=55
|
||||
ASUB=56
|
||||
AMUL=57
|
||||
ADIV=58
|
||||
AREM=59
|
||||
AAND=60
|
||||
AXOR=61
|
||||
AOR=62
|
||||
ALSH=63
|
||||
ARSH=64
|
||||
AUSH=65
|
||||
OCTAL=66
|
||||
HEX=67
|
||||
INTEGER=68
|
||||
DECIMAL=69
|
||||
STRING=70
|
||||
REGEX=71
|
||||
TRUE=72
|
||||
FALSE=73
|
||||
NULL=74
|
||||
TYPE=75
|
||||
ID=76
|
||||
DOTINTEGER=77
|
||||
DOTID=78
|
||||
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
|
||||
'{'=3
|
||||
'}'=4
|
||||
'['=5
|
||||
|
@ -125,20 +127,22 @@ DOTID=78
|
|||
':'=49
|
||||
'::'=50
|
||||
'->'=51
|
||||
'++'=52
|
||||
'--'=53
|
||||
'='=54
|
||||
'+='=55
|
||||
'-='=56
|
||||
'*='=57
|
||||
'/='=58
|
||||
'%='=59
|
||||
'&='=60
|
||||
'^='=61
|
||||
'|='=62
|
||||
'<<='=63
|
||||
'>>='=64
|
||||
'>>>='=65
|
||||
'true'=72
|
||||
'false'=73
|
||||
'null'=74
|
||||
'=~'=52
|
||||
'==~'=53
|
||||
'++'=54
|
||||
'--'=55
|
||||
'='=56
|
||||
'+='=57
|
||||
'-='=58
|
||||
'*='=59
|
||||
'/='=60
|
||||
'%='=61
|
||||
'&='=62
|
||||
'^='=63
|
||||
'|='=64
|
||||
'<<='=65
|
||||
'>>='=66
|
||||
'>>>='=67
|
||||
'true'=74
|
||||
'false'=75
|
||||
'null'=76
|
||||
|
|
|
@ -113,6 +113,7 @@ expression returns [boolean s = true]
|
|||
: u = unary[false] { $s = $u.s; } # single
|
||||
| expression ( MUL | DIV | REM ) expression { $s = false; } # binary
|
||||
| expression ( ADD | SUB ) expression { $s = false; } # binary
|
||||
| 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 ( EQ | EQR | NE | NER ) expression { $s = false; } # comp
|
||||
|
|
|
@ -49,33 +49,35 @@ COND=48
|
|||
COLON=49
|
||||
REF=50
|
||||
ARROW=51
|
||||
INCR=52
|
||||
DECR=53
|
||||
ASSIGN=54
|
||||
AADD=55
|
||||
ASUB=56
|
||||
AMUL=57
|
||||
ADIV=58
|
||||
AREM=59
|
||||
AAND=60
|
||||
AXOR=61
|
||||
AOR=62
|
||||
ALSH=63
|
||||
ARSH=64
|
||||
AUSH=65
|
||||
OCTAL=66
|
||||
HEX=67
|
||||
INTEGER=68
|
||||
DECIMAL=69
|
||||
STRING=70
|
||||
REGEX=71
|
||||
TRUE=72
|
||||
FALSE=73
|
||||
NULL=74
|
||||
TYPE=75
|
||||
ID=76
|
||||
DOTINTEGER=77
|
||||
DOTID=78
|
||||
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
|
||||
'{'=3
|
||||
'}'=4
|
||||
'['=5
|
||||
|
@ -125,20 +127,22 @@ DOTID=78
|
|||
':'=49
|
||||
'::'=50
|
||||
'->'=51
|
||||
'++'=52
|
||||
'--'=53
|
||||
'='=54
|
||||
'+='=55
|
||||
'-='=56
|
||||
'*='=57
|
||||
'/='=58
|
||||
'%='=59
|
||||
'&='=60
|
||||
'^='=61
|
||||
'|='=62
|
||||
'<<='=63
|
||||
'>>='=64
|
||||
'>>>='=65
|
||||
'true'=72
|
||||
'false'=73
|
||||
'null'=74
|
||||
'=~'=52
|
||||
'==~'=53
|
||||
'++'=54
|
||||
'--'=55
|
||||
'='=56
|
||||
'+='=57
|
||||
'-='=58
|
||||
'*='=59
|
||||
'/='=60
|
||||
'%='=61
|
||||
'&='=62
|
||||
'^='=63
|
||||
'|='=64
|
||||
'<<='=65
|
||||
'>>='=66
|
||||
'>>>='=67
|
||||
'true'=74
|
||||
'false'=75
|
||||
'null'=76
|
||||
|
|
|
@ -87,6 +87,8 @@ public final class Definition {
|
|||
public static final Type DEF_TYPE = getType("def");
|
||||
public static final Type STRING_TYPE = getType("String");
|
||||
public static final Type EXCEPTION_TYPE = getType("Exception");
|
||||
public static final Type PATTERN_TYPE = getType("Pattern");
|
||||
public static final Type MATCHER_TYPE = getType("Matcher");
|
||||
|
||||
public enum Sort {
|
||||
VOID( void.class , 0 , true , false , false , false ),
|
||||
|
@ -772,7 +774,7 @@ public final class Definition {
|
|||
|
||||
if (owner.staticMethods.containsKey(methodKey) || owner.methods.containsKey(methodKey)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Duplicate method signature [" + methodKey + "] found within the struct [" + owner.name + "].");
|
||||
"Duplicate method signature [" + methodKey + "] found within the struct [" + owner.name + "].");
|
||||
}
|
||||
|
||||
final Class<?>[] classes = new Class<?>[args.length];
|
||||
|
|
|
@ -386,5 +386,4 @@ public final class MethodWriter extends GeneratorAdapter {
|
|||
public void visitEnd() {
|
||||
throw new AssertionError("Should never call this method on MethodWriter, use endMethod() instead");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ public enum Operation {
|
|||
REM ( "%" ),
|
||||
ADD ( "+" ),
|
||||
SUB ( "-" ),
|
||||
FIND ( "=~" ),
|
||||
MATCH ( "==~" ),
|
||||
LSH ( "<<" ),
|
||||
RSH ( ">>" ),
|
||||
USH ( ">>>" ),
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.BitSet;
|
|||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
|
@ -73,12 +74,15 @@ public final class WriterConstants {
|
|||
public final static Type METHOD_HANDLE_TYPE = Type.getType(MethodHandle.class);
|
||||
|
||||
/**
|
||||
* A Method instance for {@linkplain Pattern#compile}. This isn't looked up from Definition because we intentionally don't add it there
|
||||
* A Method instance for {@linkplain Pattern#compile}. This isn't available from Definition because we intentionally don't add it there
|
||||
* so that the script can't create regexes without this syntax. Essentially, our static regex syntax has a monopoly on building regexes
|
||||
* because it can do it statically. This is both faster and prevents the script from doing something super slow like building a regex
|
||||
* per time it is run.
|
||||
*/
|
||||
public final static Method PATTERN_COMPILE = getAsmMethod(Pattern.class, "compile", String.class);
|
||||
public final static Method PATTERN_MATCHER = getAsmMethod(Matcher.class, "matcher", CharSequence.class);
|
||||
public final static Method MATCHER_MATCHES = getAsmMethod(boolean.class, "matches");
|
||||
public final static Method MATCHER_FIND = getAsmMethod(boolean.class, "find");
|
||||
|
||||
/** dynamic callsite bootstrap signature */
|
||||
public final static MethodType DEF_BOOTSTRAP_TYPE =
|
||||
|
|
|
@ -26,10 +26,10 @@ class PainlessLexer extends Lexer {
|
|||
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,
|
||||
INCR=52, DECR=53, ASSIGN=54, AADD=55, ASUB=56, AMUL=57, ADIV=58, AREM=59,
|
||||
AAND=60, AXOR=61, AOR=62, ALSH=63, ARSH=64, AUSH=65, OCTAL=66, HEX=67,
|
||||
INTEGER=68, DECIMAL=69, STRING=70, REGEX=71, TRUE=72, FALSE=73, NULL=74,
|
||||
TYPE=75, ID=76, DOTINTEGER=77, DOTID=78;
|
||||
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;
|
||||
public static final int AFTER_DOT = 1;
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE", "AFTER_DOT"
|
||||
|
@ -41,10 +41,11 @@ class PainlessLexer extends Lexer {
|
|||
"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",
|
||||
"BOOLAND", "BOOLOR", "COND", "COLON", "REF", "ARROW", "INCR", "DECR",
|
||||
"ASSIGN", "AADD", "ASUB", "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR",
|
||||
"ALSH", "ARSH", "AUSH", "OCTAL", "HEX", "INTEGER", "DECIMAL", "STRING",
|
||||
"REGEX", "TRUE", "FALSE", "NULL", "TYPE", "ID", "DOTINTEGER", "DOTID"
|
||||
"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",
|
||||
"STRING", "REGEX", "TRUE", "FALSE", "NULL", "TYPE", "ID", "DOTINTEGER",
|
||||
"DOTID"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
|
@ -53,9 +54,10 @@ class PainlessLexer extends Lexer {
|
|||
"'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'", "'!'", "'~'",
|
||||
"'*'", "'/'", "'%'", "'+'", "'-'", "'<<'", "'>>'", "'>>>'", "'<'", "'<='",
|
||||
"'>'", "'>='", "'=='", "'==='", "'!='", "'!=='", "'&'", "'^'", "'|'",
|
||||
"'&&'", "'||'", "'?'", "':'", "'::'", "'->'", "'++'", "'--'", "'='", "'+='",
|
||||
"'-='", "'*='", "'/='", "'%='", "'&='", "'^='", "'|='", "'<<='", "'>>='",
|
||||
"'>>>='", null, null, null, null, null, null, "'true'", "'false'", "'null'"
|
||||
"'&&'", "'||'", "'?'", "':'", "'::'", "'->'", "'=~'", "'==~'", "'++'",
|
||||
"'--'", "'='", "'+='", "'-='", "'*='", "'/='", "'%='", "'&='", "'^='",
|
||||
"'|='", "'<<='", "'>>='", "'>>>='", null, null, null, null, null, null,
|
||||
"'true'", "'false'", "'null'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP",
|
||||
|
@ -63,10 +65,11 @@ class PainlessLexer extends Lexer {
|
|||
"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",
|
||||
"BOOLAND", "BOOLOR", "COND", "COLON", "REF", "ARROW", "INCR", "DECR",
|
||||
"ASSIGN", "AADD", "ASUB", "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR",
|
||||
"ALSH", "ARSH", "AUSH", "OCTAL", "HEX", "INTEGER", "DECIMAL", "STRING",
|
||||
"REGEX", "TRUE", "FALSE", "NULL", "TYPE", "ID", "DOTINTEGER", "DOTID"
|
||||
"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",
|
||||
"STRING", "REGEX", "TRUE", "FALSE", "NULL", "TYPE", "ID", "DOTINTEGER",
|
||||
"DOTID"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
|
@ -127,9 +130,9 @@ class PainlessLexer extends Lexer {
|
|||
switch (ruleIndex) {
|
||||
case 27:
|
||||
return DIV_sempred((RuleContext)_localctx, predIndex);
|
||||
case 70:
|
||||
case 72:
|
||||
return REGEX_sempred((RuleContext)_localctx, predIndex);
|
||||
case 74:
|
||||
case 76:
|
||||
return TYPE_sempred((RuleContext)_localctx, predIndex);
|
||||
}
|
||||
return true;
|
||||
|
@ -157,7 +160,7 @@ class PainlessLexer extends Lexer {
|
|||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2P\u0228\b\1\b\1\4"+
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2R\u0233\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"+
|
||||
|
@ -166,190 +169,193 @@ 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\3\2\6\2\u00a2\n\2\r\2\16\2\u00a3"+
|
||||
"\3\2\3\2\3\3\3\3\3\3\3\3\7\3\u00ac\n\3\f\3\16\3\u00af\13\3\3\3\3\3\3\3"+
|
||||
"\3\3\3\3\7\3\u00b6\n\3\f\3\16\3\u00b9\13\3\3\3\3\3\5\3\u00bd\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\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@\3@\3@\3A\3A\3A\3A\3B\3B\3B"+
|
||||
"\3B\3B\3C\3C\6C\u018f\nC\rC\16C\u0190\3C\5C\u0194\nC\3D\3D\3D\6D\u0199"+
|
||||
"\nD\rD\16D\u019a\3D\5D\u019e\nD\3E\3E\3E\7E\u01a3\nE\fE\16E\u01a6\13E"+
|
||||
"\5E\u01a8\nE\3E\5E\u01ab\nE\3F\3F\3F\7F\u01b0\nF\fF\16F\u01b3\13F\5F\u01b5"+
|
||||
"\nF\3F\3F\6F\u01b9\nF\rF\16F\u01ba\5F\u01bd\nF\3F\3F\5F\u01c1\nF\3F\6"+
|
||||
"F\u01c4\nF\rF\16F\u01c5\5F\u01c8\nF\3F\5F\u01cb\nF\3G\3G\3G\3G\3G\3G\7"+
|
||||
"G\u01d3\nG\fG\16G\u01d6\13G\3G\3G\3G\3G\3G\3G\3G\7G\u01df\nG\fG\16G\u01e2"+
|
||||
"\13G\3G\5G\u01e5\nG\3H\3H\3H\3H\6H\u01eb\nH\rH\16H\u01ec\3H\3H\3H\3I\3"+
|
||||
"I\3I\3I\3I\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L\7L\u0206\nL\f"+
|
||||
"L\16L\u0209\13L\3L\3L\3M\3M\7M\u020f\nM\fM\16M\u0212\13M\3N\3N\3N\7N\u0217"+
|
||||
"\nN\fN\16N\u021a\13N\5N\u021c\nN\3N\3N\3O\3O\7O\u0222\nO\fO\16O\u0225"+
|
||||
"\13O\3O\3O\6\u00ad\u00b7\u01d4\u01e0\2P\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<x=z>|?~@\u0080A\u0082B"+
|
||||
"\u0084C\u0086D\u0088E\u008aF\u008cG\u008eH\u0090I\u0092J\u0094K\u0096"+
|
||||
"L\u0098M\u009aN\u009cO\u009eP\4\2\3\23\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\5\2C\\aac|\6\2\62"+
|
||||
";C\\aac|\u0247\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\2"+
|
||||
"T\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\2"+
|
||||
"z\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\3\u009c\3\2\2\2\3\u009e\3\2\2"+
|
||||
"\2\4\u00a1\3\2\2\2\6\u00bc\3\2\2\2\b\u00c0\3\2\2\2\n\u00c2\3\2\2\2\f\u00c4"+
|
||||
"\3\2\2\2\16\u00c6\3\2\2\2\20\u00c8\3\2\2\2\22\u00ca\3\2\2\2\24\u00cc\3"+
|
||||
"\2\2\2\26\u00d0\3\2\2\2\30\u00d2\3\2\2\2\32\u00d4\3\2\2\2\34\u00d7\3\2"+
|
||||
"\2\2\36\u00dc\3\2\2\2 \u00e2\3\2\2\2\"\u00e5\3\2\2\2$\u00e9\3\2\2\2&\u00f2"+
|
||||
"\3\2\2\2(\u00f8\3\2\2\2*\u00ff\3\2\2\2,\u0103\3\2\2\2.\u0107\3\2\2\2\60"+
|
||||
"\u010d\3\2\2\2\62\u0113\3\2\2\2\64\u0118\3\2\2\2\66\u011a\3\2\2\28\u011c"+
|
||||
"\3\2\2\2:\u011e\3\2\2\2<\u0121\3\2\2\2>\u0123\3\2\2\2@\u0125\3\2\2\2B"+
|
||||
"\u0127\3\2\2\2D\u012a\3\2\2\2F\u012d\3\2\2\2H\u0131\3\2\2\2J\u0133\3\2"+
|
||||
"\2\2L\u0136\3\2\2\2N\u0138\3\2\2\2P\u013b\3\2\2\2R\u013e\3\2\2\2T\u0142"+
|
||||
"\3\2\2\2V\u0145\3\2\2\2X\u0149\3\2\2\2Z\u014b\3\2\2\2\\\u014d\3\2\2\2"+
|
||||
"^\u014f\3\2\2\2`\u0152\3\2\2\2b\u0155\3\2\2\2d\u0157\3\2\2\2f\u0159\3"+
|
||||
"\2\2\2h\u015c\3\2\2\2j\u015f\3\2\2\2l\u0162\3\2\2\2n\u0165\3\2\2\2p\u0167"+
|
||||
"\3\2\2\2r\u016a\3\2\2\2t\u016d\3\2\2\2v\u0170\3\2\2\2x\u0173\3\2\2\2z"+
|
||||
"\u0176\3\2\2\2|\u0179\3\2\2\2~\u017c\3\2\2\2\u0080\u017f\3\2\2\2\u0082"+
|
||||
"\u0183\3\2\2\2\u0084\u0187\3\2\2\2\u0086\u018c\3\2\2\2\u0088\u0195\3\2"+
|
||||
"\2\2\u008a\u01a7\3\2\2\2\u008c\u01b4\3\2\2\2\u008e\u01e4\3\2\2\2\u0090"+
|
||||
"\u01e6\3\2\2\2\u0092\u01f1\3\2\2\2\u0094\u01f6\3\2\2\2\u0096\u01fc\3\2"+
|
||||
"\2\2\u0098\u0201\3\2\2\2\u009a\u020c\3\2\2\2\u009c\u021b\3\2\2\2\u009e"+
|
||||
"\u021f\3\2\2\2\u00a0\u00a2\t\2\2\2\u00a1\u00a0\3\2\2\2\u00a2\u00a3\3\2"+
|
||||
"\2\2\u00a3\u00a1\3\2\2\2\u00a3\u00a4\3\2\2\2\u00a4\u00a5\3\2\2\2\u00a5"+
|
||||
"\u00a6\b\2\2\2\u00a6\5\3\2\2\2\u00a7\u00a8\7\61\2\2\u00a8\u00a9\7\61\2"+
|
||||
"\2\u00a9\u00ad\3\2\2\2\u00aa\u00ac\13\2\2\2\u00ab\u00aa\3\2\2\2\u00ac"+
|
||||
"\u00af\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ad\u00ab\3\2\2\2\u00ae\u00b0\3\2"+
|
||||
"\2\2\u00af\u00ad\3\2\2\2\u00b0\u00bd\t\3\2\2\u00b1\u00b2\7\61\2\2\u00b2"+
|
||||
"\u00b3\7,\2\2\u00b3\u00b7\3\2\2\2\u00b4\u00b6\13\2\2\2\u00b5\u00b4\3\2"+
|
||||
"\2\2\u00b6\u00b9\3\2\2\2\u00b7\u00b8\3\2\2\2\u00b7\u00b5\3\2\2\2\u00b8"+
|
||||
"\u00ba\3\2\2\2\u00b9\u00b7\3\2\2\2\u00ba\u00bb\7,\2\2\u00bb\u00bd\7\61"+
|
||||
"\2\2\u00bc\u00a7\3\2\2\2\u00bc\u00b1\3\2\2\2\u00bd\u00be\3\2\2\2\u00be"+
|
||||
"\u00bf\b\3\2\2\u00bf\7\3\2\2\2\u00c0\u00c1\7}\2\2\u00c1\t\3\2\2\2\u00c2"+
|
||||
"\u00c3\7\177\2\2\u00c3\13\3\2\2\2\u00c4\u00c5\7]\2\2\u00c5\r\3\2\2\2\u00c6"+
|
||||
"\u00c7\7_\2\2\u00c7\17\3\2\2\2\u00c8\u00c9\7*\2\2\u00c9\21\3\2\2\2\u00ca"+
|
||||
"\u00cb\7+\2\2\u00cb\23\3\2\2\2\u00cc\u00cd\7\60\2\2\u00cd\u00ce\3\2\2"+
|
||||
"\2\u00ce\u00cf\b\n\3\2\u00cf\25\3\2\2\2\u00d0\u00d1\7.\2\2\u00d1\27\3"+
|
||||
"\2\2\2\u00d2\u00d3\7=\2\2\u00d3\31\3\2\2\2\u00d4\u00d5\7k\2\2\u00d5\u00d6"+
|
||||
"\7h\2\2\u00d6\33\3\2\2\2\u00d7\u00d8\7g\2\2\u00d8\u00d9\7n\2\2\u00d9\u00da"+
|
||||
"\7u\2\2\u00da\u00db\7g\2\2\u00db\35\3\2\2\2\u00dc\u00dd\7y\2\2\u00dd\u00de"+
|
||||
"\7j\2\2\u00de\u00df\7k\2\2\u00df\u00e0\7n\2\2\u00e0\u00e1\7g\2\2\u00e1"+
|
||||
"\37\3\2\2\2\u00e2\u00e3\7f\2\2\u00e3\u00e4\7q\2\2\u00e4!\3\2\2\2\u00e5"+
|
||||
"\u00e6\7h\2\2\u00e6\u00e7\7q\2\2\u00e7\u00e8\7t\2\2\u00e8#\3\2\2\2\u00e9"+
|
||||
"\u00ea\7e\2\2\u00ea\u00eb\7q\2\2\u00eb\u00ec\7p\2\2\u00ec\u00ed\7v\2\2"+
|
||||
"\u00ed\u00ee\7k\2\2\u00ee\u00ef\7p\2\2\u00ef\u00f0\7w\2\2\u00f0\u00f1"+
|
||||
"\7g\2\2\u00f1%\3\2\2\2\u00f2\u00f3\7d\2\2\u00f3\u00f4\7t\2\2\u00f4\u00f5"+
|
||||
"\7g\2\2\u00f5\u00f6\7c\2\2\u00f6\u00f7\7m\2\2\u00f7\'\3\2\2\2\u00f8\u00f9"+
|
||||
"\7t\2\2\u00f9\u00fa\7g\2\2\u00fa\u00fb\7v\2\2\u00fb\u00fc\7w\2\2\u00fc"+
|
||||
"\u00fd\7t\2\2\u00fd\u00fe\7p\2\2\u00fe)\3\2\2\2\u00ff\u0100\7p\2\2\u0100"+
|
||||
"\u0101\7g\2\2\u0101\u0102\7y\2\2\u0102+\3\2\2\2\u0103\u0104\7v\2\2\u0104"+
|
||||
"\u0105\7t\2\2\u0105\u0106\7{\2\2\u0106-\3\2\2\2\u0107\u0108\7e\2\2\u0108"+
|
||||
"\u0109\7c\2\2\u0109\u010a\7v\2\2\u010a\u010b\7e\2\2\u010b\u010c\7j\2\2"+
|
||||
"\u010c/\3\2\2\2\u010d\u010e\7v\2\2\u010e\u010f\7j\2\2\u010f\u0110\7t\2"+
|
||||
"\2\u0110\u0111\7q\2\2\u0111\u0112\7y\2\2\u0112\61\3\2\2\2\u0113\u0114"+
|
||||
"\7v\2\2\u0114\u0115\7j\2\2\u0115\u0116\7k\2\2\u0116\u0117\7u\2\2\u0117"+
|
||||
"\63\3\2\2\2\u0118\u0119\7#\2\2\u0119\65\3\2\2\2\u011a\u011b\7\u0080\2"+
|
||||
"\2\u011b\67\3\2\2\2\u011c\u011d\7,\2\2\u011d9\3\2\2\2\u011e\u011f\7\61"+
|
||||
"\2\2\u011f\u0120\6\35\2\2\u0120;\3\2\2\2\u0121\u0122\7\'\2\2\u0122=\3"+
|
||||
"\2\2\2\u0123\u0124\7-\2\2\u0124?\3\2\2\2\u0125\u0126\7/\2\2\u0126A\3\2"+
|
||||
"\2\2\u0127\u0128\7>\2\2\u0128\u0129\7>\2\2\u0129C\3\2\2\2\u012a\u012b"+
|
||||
"\7@\2\2\u012b\u012c\7@\2\2\u012cE\3\2\2\2\u012d\u012e\7@\2\2\u012e\u012f"+
|
||||
"\7@\2\2\u012f\u0130\7@\2\2\u0130G\3\2\2\2\u0131\u0132\7>\2\2\u0132I\3"+
|
||||
"\2\2\2\u0133\u0134\7>\2\2\u0134\u0135\7?\2\2\u0135K\3\2\2\2\u0136\u0137"+
|
||||
"\7@\2\2\u0137M\3\2\2\2\u0138\u0139\7@\2\2\u0139\u013a\7?\2\2\u013aO\3"+
|
||||
"\2\2\2\u013b\u013c\7?\2\2\u013c\u013d\7?\2\2\u013dQ\3\2\2\2\u013e\u013f"+
|
||||
"\7?\2\2\u013f\u0140\7?\2\2\u0140\u0141\7?\2\2\u0141S\3\2\2\2\u0142\u0143"+
|
||||
"\7#\2\2\u0143\u0144\7?\2\2\u0144U\3\2\2\2\u0145\u0146\7#\2\2\u0146\u0147"+
|
||||
"\7?\2\2\u0147\u0148\7?\2\2\u0148W\3\2\2\2\u0149\u014a\7(\2\2\u014aY\3"+
|
||||
"\2\2\2\u014b\u014c\7`\2\2\u014c[\3\2\2\2\u014d\u014e\7~\2\2\u014e]\3\2"+
|
||||
"\2\2\u014f\u0150\7(\2\2\u0150\u0151\7(\2\2\u0151_\3\2\2\2\u0152\u0153"+
|
||||
"\7~\2\2\u0153\u0154\7~\2\2\u0154a\3\2\2\2\u0155\u0156\7A\2\2\u0156c\3"+
|
||||
"\2\2\2\u0157\u0158\7<\2\2\u0158e\3\2\2\2\u0159\u015a\7<\2\2\u015a\u015b"+
|
||||
"\7<\2\2\u015bg\3\2\2\2\u015c\u015d\7/\2\2\u015d\u015e\7@\2\2\u015ei\3"+
|
||||
"\2\2\2\u015f\u0160\7-\2\2\u0160\u0161\7-\2\2\u0161k\3\2\2\2\u0162\u0163"+
|
||||
"\7/\2\2\u0163\u0164\7/\2\2\u0164m\3\2\2\2\u0165\u0166\7?\2\2\u0166o\3"+
|
||||
"\2\2\2\u0167\u0168\7-\2\2\u0168\u0169\7?\2\2\u0169q\3\2\2\2\u016a\u016b"+
|
||||
"\7/\2\2\u016b\u016c\7?\2\2\u016cs\3\2\2\2\u016d\u016e\7,\2\2\u016e\u016f"+
|
||||
"\7?\2\2\u016fu\3\2\2\2\u0170\u0171\7\61\2\2\u0171\u0172\7?\2\2\u0172w"+
|
||||
"\3\2\2\2\u0173\u0174\7\'\2\2\u0174\u0175\7?\2\2\u0175y\3\2\2\2\u0176\u0177"+
|
||||
"\7(\2\2\u0177\u0178\7?\2\2\u0178{\3\2\2\2\u0179\u017a\7`\2\2\u017a\u017b"+
|
||||
"\7?\2\2\u017b}\3\2\2\2\u017c\u017d\7~\2\2\u017d\u017e\7?\2\2\u017e\177"+
|
||||
"\3\2\2\2\u017f\u0180\7>\2\2\u0180\u0181\7>\2\2\u0181\u0182\7?\2\2\u0182"+
|
||||
"\u0081\3\2\2\2\u0183\u0184\7@\2\2\u0184\u0185\7@\2\2\u0185\u0186\7?\2"+
|
||||
"\2\u0186\u0083\3\2\2\2\u0187\u0188\7@\2\2\u0188\u0189\7@\2\2\u0189\u018a"+
|
||||
"\7@\2\2\u018a\u018b\7?\2\2\u018b\u0085\3\2\2\2\u018c\u018e\7\62\2\2\u018d"+
|
||||
"\u018f\t\4\2\2\u018e\u018d\3\2\2\2\u018f\u0190\3\2\2\2\u0190\u018e\3\2"+
|
||||
"\2\2\u0190\u0191\3\2\2\2\u0191\u0193\3\2\2\2\u0192\u0194\t\5\2\2\u0193"+
|
||||
"\u0192\3\2\2\2\u0193\u0194\3\2\2\2\u0194\u0087\3\2\2\2\u0195\u0196\7\62"+
|
||||
"\2\2\u0196\u0198\t\6\2\2\u0197\u0199\t\7\2\2\u0198\u0197\3\2\2\2\u0199"+
|
||||
"\u019a\3\2\2\2\u019a\u0198\3\2\2\2\u019a\u019b\3\2\2\2\u019b\u019d\3\2"+
|
||||
"\2\2\u019c\u019e\t\5\2\2\u019d\u019c\3\2\2\2\u019d\u019e\3\2\2\2\u019e"+
|
||||
"\u0089\3\2\2\2\u019f\u01a8\7\62\2\2\u01a0\u01a4\t\b\2\2\u01a1\u01a3\t"+
|
||||
"\t\2\2\u01a2\u01a1\3\2\2\2\u01a3\u01a6\3\2\2\2\u01a4\u01a2\3\2\2\2\u01a4"+
|
||||
"\u01a5\3\2\2\2\u01a5\u01a8\3\2\2\2\u01a6\u01a4\3\2\2\2\u01a7\u019f\3\2"+
|
||||
"\2\2\u01a7\u01a0\3\2\2\2\u01a8\u01aa\3\2\2\2\u01a9\u01ab\t\n\2\2\u01aa"+
|
||||
"\u01a9\3\2\2\2\u01aa\u01ab\3\2\2\2\u01ab\u008b\3\2\2\2\u01ac\u01b5\7\62"+
|
||||
"\2\2\u01ad\u01b1\t\b\2\2\u01ae\u01b0\t\t\2\2\u01af\u01ae\3\2\2\2\u01b0"+
|
||||
"\u01b3\3\2\2\2\u01b1\u01af\3\2\2\2\u01b1\u01b2\3\2\2\2\u01b2\u01b5\3\2"+
|
||||
"\2\2\u01b3\u01b1\3\2\2\2\u01b4\u01ac\3\2\2\2\u01b4\u01ad\3\2\2\2\u01b5"+
|
||||
"\u01bc\3\2\2\2\u01b6\u01b8\5\24\n\2\u01b7\u01b9\t\t\2\2\u01b8\u01b7\3"+
|
||||
"\2\2\2\u01b9\u01ba\3\2\2\2\u01ba\u01b8\3\2\2\2\u01ba\u01bb\3\2\2\2\u01bb"+
|
||||
"\u01bd\3\2\2\2\u01bc\u01b6\3\2\2\2\u01bc\u01bd\3\2\2\2\u01bd\u01c7\3\2"+
|
||||
"\2\2\u01be\u01c0\t\13\2\2\u01bf\u01c1\t\f\2\2\u01c0\u01bf\3\2\2\2\u01c0"+
|
||||
"\u01c1\3\2\2\2\u01c1\u01c3\3\2\2\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\u01be\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01ca\3\2"+
|
||||
"\2\2\u01c9\u01cb\t\r\2\2\u01ca\u01c9\3\2\2\2\u01ca\u01cb\3\2\2\2\u01cb"+
|
||||
"\u008d\3\2\2\2\u01cc\u01d4\7$\2\2\u01cd\u01ce\7^\2\2\u01ce\u01d3\7$\2"+
|
||||
"\2\u01cf\u01d0\7^\2\2\u01d0\u01d3\7^\2\2\u01d1\u01d3\n\16\2\2\u01d2\u01cd"+
|
||||
"\3\2\2\2\u01d2\u01cf\3\2\2\2\u01d2\u01d1\3\2\2\2\u01d3\u01d6\3\2\2\2\u01d4"+
|
||||
"\u01d5\3\2\2\2\u01d4\u01d2\3\2\2\2\u01d5\u01d7\3\2\2\2\u01d6\u01d4\3\2"+
|
||||
"\2\2\u01d7\u01e5\7$\2\2\u01d8\u01e0\7)\2\2\u01d9\u01da\7^\2\2\u01da\u01df"+
|
||||
"\7)\2\2\u01db\u01dc\7^\2\2\u01dc\u01df\7^\2\2\u01dd\u01df\n\16\2\2\u01de"+
|
||||
"\u01d9\3\2\2\2\u01de\u01db\3\2\2\2\u01de\u01dd\3\2\2\2\u01df\u01e2\3\2"+
|
||||
"\2\2\u01e0\u01e1\3\2\2\2\u01e0\u01de\3\2\2\2\u01e1\u01e3\3\2\2\2\u01e2"+
|
||||
"\u01e0\3\2\2\2\u01e3\u01e5\7)\2\2\u01e4\u01cc\3\2\2\2\u01e4\u01d8\3\2"+
|
||||
"\2\2\u01e5\u008f\3\2\2\2\u01e6\u01ea\7\61\2\2\u01e7\u01eb\n\17\2\2\u01e8"+
|
||||
"\u01e9\7^\2\2\u01e9\u01eb\n\20\2\2\u01ea\u01e7\3\2\2\2\u01ea\u01e8\3\2"+
|
||||
"\2\2\u01eb\u01ec\3\2\2\2\u01ec\u01ea\3\2\2\2\u01ec\u01ed\3\2\2\2\u01ed"+
|
||||
"\u01ee\3\2\2\2\u01ee\u01ef\7\61\2\2\u01ef\u01f0\6H\3\2\u01f0\u0091\3\2"+
|
||||
"\2\2\u01f1\u01f2\7v\2\2\u01f2\u01f3\7t\2\2\u01f3\u01f4\7w\2\2\u01f4\u01f5"+
|
||||
"\7g\2\2\u01f5\u0093\3\2\2\2\u01f6\u01f7\7h\2\2\u01f7\u01f8\7c\2\2\u01f8"+
|
||||
"\u01f9\7n\2\2\u01f9\u01fa\7u\2\2\u01fa\u01fb\7g\2\2\u01fb\u0095\3\2\2"+
|
||||
"\2\u01fc\u01fd\7p\2\2\u01fd\u01fe\7w\2\2\u01fe\u01ff\7n\2\2\u01ff\u0200"+
|
||||
"\7n\2\2\u0200\u0097\3\2\2\2\u0201\u0207\5\u009aM\2\u0202\u0203\5\24\n"+
|
||||
"\2\u0203\u0204\5\u009aM\2\u0204\u0206\3\2\2\2\u0205\u0202\3\2\2\2\u0206"+
|
||||
"\u0209\3\2\2\2\u0207\u0205\3\2\2\2\u0207\u0208\3\2\2\2\u0208\u020a\3\2"+
|
||||
"\2\2\u0209\u0207\3\2\2\2\u020a\u020b\6L\4\2\u020b\u0099\3\2\2\2\u020c"+
|
||||
"\u0210\t\21\2\2\u020d\u020f\t\22\2\2\u020e\u020d\3\2\2\2\u020f\u0212\3"+
|
||||
"\2\2\2\u0210\u020e\3\2\2\2\u0210\u0211\3\2\2\2\u0211\u009b\3\2\2\2\u0212"+
|
||||
"\u0210\3\2\2\2\u0213\u021c\7\62\2\2\u0214\u0218\t\b\2\2\u0215\u0217\t"+
|
||||
"\t\2\2\u0216\u0215\3\2\2\2\u0217\u021a\3\2\2\2\u0218\u0216\3\2\2\2\u0218"+
|
||||
"\u0219\3\2\2\2\u0219\u021c\3\2\2\2\u021a\u0218\3\2\2\2\u021b\u0213\3\2"+
|
||||
"\2\2\u021b\u0214\3\2\2\2\u021c\u021d\3\2\2\2\u021d\u021e\bN\4\2\u021e"+
|
||||
"\u009d\3\2\2\2\u021f\u0223\t\21\2\2\u0220\u0222\t\22\2\2\u0221\u0220\3"+
|
||||
"\2\2\2\u0222\u0225\3\2\2\2\u0223\u0221\3\2\2\2\u0223\u0224\3\2\2\2\u0224"+
|
||||
"\u0226\3\2\2\2\u0225\u0223\3\2\2\2\u0226\u0227\bO\4\2\u0227\u009f\3\2"+
|
||||
"\2\2#\2\3\u00a3\u00ad\u00b7\u00bc\u0190\u0193\u019a\u019d\u01a4\u01a7"+
|
||||
"\u01aa\u01b1\u01b4\u01ba\u01bc\u01c0\u01c5\u01c7\u01ca\u01d2\u01d4\u01de"+
|
||||
"\u01e0\u01e4\u01ea\u01ec\u0207\u0210\u0218\u021b\u0223\5\b\2\2\4\3\2\4"+
|
||||
"\2\2";
|
||||
"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\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3"+
|
||||
"M\3M\3M\3M\3M\3N\3N\3N\3N\7N\u0211\nN\fN\16N\u0214\13N\3N\3N\3O\3O\7O"+
|
||||
"\u021a\nO\fO\16O\u021d\13O\3P\3P\3P\7P\u0222\nP\fP\16P\u0225\13P\5P\u0227"+
|
||||
"\nP\3P\3P\3Q\3Q\7Q\u022d\nQ\fQ\16Q\u0230\13Q\3Q\3Q\6\u00b1\u00bb\u01df"+
|
||||
"\u01eb\2R\4\3\6\4\b\5\n\6\f\7\16\b\20\t\22\n\24\13\26\f\30\r\32\16\34"+
|
||||
"\17\36\20 \21\"\22$\23&\24(\25*\26,\27.\30\60\31\62\32\64\33\66\348\35"+
|
||||
":\36<\37> @!B\"D#F$H%J&L\'N(P)R*T+V,X-Z.\\/^\60`\61b\62d\63f\64h\65j\66"+
|
||||
"l\67n8p9r:t;v<x=z>|?~@\u0080A\u0082B\u0084C\u0086D\u0088E\u008aF\u008c"+
|
||||
"G\u008eH\u0090I\u0092J\u0094K\u0096L\u0098M\u009aN\u009cO\u009eP\u00a0"+
|
||||
"Q\u00a2R\4\2\3\23\5\2\13\f\17\17\"\"\4\2\f\f\17\17\3\2\629\4\2NNnn\4\2"+
|
||||
"ZZzz\5\2\62;CHch\3\2\63;\3\2\62;\b\2FFHHNNffhhnn\4\2GGgg\4\2--//\4\2H"+
|
||||
"Hhh\4\2$$^^\4\2\f\f\61\61\3\2\f\f\5\2C\\aac|\6\2\62;C\\aac|\u0252\2\4"+
|
||||
"\3\2\2\2\2\6\3\2\2\2\2\b\3\2\2\2\2\n\3\2\2\2\2\f\3\2\2\2\2\16\3\2\2\2"+
|
||||
"\2\20\3\2\2\2\2\22\3\2\2\2\2\24\3\2\2\2\2\26\3\2\2\2\2\30\3\2\2\2\2\32"+
|
||||
"\3\2\2\2\2\34\3\2\2\2\2\36\3\2\2\2\2 \3\2\2\2\2\"\3\2\2\2\2$\3\2\2\2\2"+
|
||||
"&\3\2\2\2\2(\3\2\2\2\2*\3\2\2\2\2,\3\2\2\2\2.\3\2\2\2\2\60\3\2\2\2\2\62"+
|
||||
"\3\2\2\2\2\64\3\2\2\2\2\66\3\2\2\2\28\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2"+
|
||||
">\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2J\3"+
|
||||
"\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2\2\2\2V\3\2\2"+
|
||||
"\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2\2\2b\3\2\2\2"+
|
||||
"\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2n\3\2\2\2\2p"+
|
||||
"\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3\2\2\2\2|\3\2"+
|
||||
"\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3\2\2\2\2\u0086"+
|
||||
"\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2\2\u008e\3\2\2"+
|
||||
"\2\2\u0090\3\2\2\2\2\u0092\3\2\2\2\2\u0094\3\2\2\2\2\u0096\3\2\2\2\2\u0098"+
|
||||
"\3\2\2\2\2\u009a\3\2\2\2\2\u009c\3\2\2\2\2\u009e\3\2\2\2\3\u00a0\3\2\2"+
|
||||
"\2\3\u00a2\3\2\2\2\4\u00a5\3\2\2\2\6\u00c0\3\2\2\2\b\u00c4\3\2\2\2\n\u00c6"+
|
||||
"\3\2\2\2\f\u00c8\3\2\2\2\16\u00ca\3\2\2\2\20\u00cc\3\2\2\2\22\u00ce\3"+
|
||||
"\2\2\2\24\u00d0\3\2\2\2\26\u00d4\3\2\2\2\30\u00d6\3\2\2\2\32\u00d8\3\2"+
|
||||
"\2\2\34\u00db\3\2\2\2\36\u00e0\3\2\2\2 \u00e6\3\2\2\2\"\u00e9\3\2\2\2"+
|
||||
"$\u00ed\3\2\2\2&\u00f6\3\2\2\2(\u00fc\3\2\2\2*\u0103\3\2\2\2,\u0107\3"+
|
||||
"\2\2\2.\u010b\3\2\2\2\60\u0111\3\2\2\2\62\u0117\3\2\2\2\64\u011c\3\2\2"+
|
||||
"\2\66\u011e\3\2\2\28\u0120\3\2\2\2:\u0122\3\2\2\2<\u0125\3\2\2\2>\u0127"+
|
||||
"\3\2\2\2@\u0129\3\2\2\2B\u012b\3\2\2\2D\u012e\3\2\2\2F\u0131\3\2\2\2H"+
|
||||
"\u0135\3\2\2\2J\u0137\3\2\2\2L\u013a\3\2\2\2N\u013c\3\2\2\2P\u013f\3\2"+
|
||||
"\2\2R\u0142\3\2\2\2T\u0146\3\2\2\2V\u0149\3\2\2\2X\u014d\3\2\2\2Z\u014f"+
|
||||
"\3\2\2\2\\\u0151\3\2\2\2^\u0153\3\2\2\2`\u0156\3\2\2\2b\u0159\3\2\2\2"+
|
||||
"d\u015b\3\2\2\2f\u015d\3\2\2\2h\u0160\3\2\2\2j\u0163\3\2\2\2l\u0166\3"+
|
||||
"\2\2\2n\u016a\3\2\2\2p\u016d\3\2\2\2r\u0170\3\2\2\2t\u0172\3\2\2\2v\u0175"+
|
||||
"\3\2\2\2x\u0178\3\2\2\2z\u017b\3\2\2\2|\u017e\3\2\2\2~\u0181\3\2\2\2\u0080"+
|
||||
"\u0184\3\2\2\2\u0082\u0187\3\2\2\2\u0084\u018a\3\2\2\2\u0086\u018e\3\2"+
|
||||
"\2\2\u0088\u0192\3\2\2\2\u008a\u0197\3\2\2\2\u008c\u01a0\3\2\2\2\u008e"+
|
||||
"\u01b2\3\2\2\2\u0090\u01bf\3\2\2\2\u0092\u01ef\3\2\2\2\u0094\u01f1\3\2"+
|
||||
"\2\2\u0096\u01fc\3\2\2\2\u0098\u0201\3\2\2\2\u009a\u0207\3\2\2\2\u009c"+
|
||||
"\u020c\3\2\2\2\u009e\u0217\3\2\2\2\u00a0\u0226\3\2\2\2\u00a2\u022a\3\2"+
|
||||
"\2\2\u00a4\u00a6\t\2\2\2\u00a5\u00a4\3\2\2\2\u00a6\u00a7\3\2\2\2\u00a7"+
|
||||
"\u00a5\3\2\2\2\u00a7\u00a8\3\2\2\2\u00a8\u00a9\3\2\2\2\u00a9\u00aa\b\2"+
|
||||
"\2\2\u00aa\5\3\2\2\2\u00ab\u00ac\7\61\2\2\u00ac\u00ad\7\61\2\2\u00ad\u00b1"+
|
||||
"\3\2\2\2\u00ae\u00b0\13\2\2\2\u00af\u00ae\3\2\2\2\u00b0\u00b3\3\2\2\2"+
|
||||
"\u00b1\u00b2\3\2\2\2\u00b1\u00af\3\2\2\2\u00b2\u00b4\3\2\2\2\u00b3\u00b1"+
|
||||
"\3\2\2\2\u00b4\u00c1\t\3\2\2\u00b5\u00b6\7\61\2\2\u00b6\u00b7\7,\2\2\u00b7"+
|
||||
"\u00bb\3\2\2\2\u00b8\u00ba\13\2\2\2\u00b9\u00b8\3\2\2\2\u00ba\u00bd\3"+
|
||||
"\2\2\2\u00bb\u00bc\3\2\2\2\u00bb\u00b9\3\2\2\2\u00bc\u00be\3\2\2\2\u00bd"+
|
||||
"\u00bb\3\2\2\2\u00be\u00bf\7,\2\2\u00bf\u00c1\7\61\2\2\u00c0\u00ab\3\2"+
|
||||
"\2\2\u00c0\u00b5\3\2\2\2\u00c1\u00c2\3\2\2\2\u00c2\u00c3\b\3\2\2\u00c3"+
|
||||
"\7\3\2\2\2\u00c4\u00c5\7}\2\2\u00c5\t\3\2\2\2\u00c6\u00c7\7\177\2\2\u00c7"+
|
||||
"\13\3\2\2\2\u00c8\u00c9\7]\2\2\u00c9\r\3\2\2\2\u00ca\u00cb\7_\2\2\u00cb"+
|
||||
"\17\3\2\2\2\u00cc\u00cd\7*\2\2\u00cd\21\3\2\2\2\u00ce\u00cf\7+\2\2\u00cf"+
|
||||
"\23\3\2\2\2\u00d0\u00d1\7\60\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00d3\b\n\3"+
|
||||
"\2\u00d3\25\3\2\2\2\u00d4\u00d5\7.\2\2\u00d5\27\3\2\2\2\u00d6\u00d7\7"+
|
||||
"=\2\2\u00d7\31\3\2\2\2\u00d8\u00d9\7k\2\2\u00d9\u00da\7h\2\2\u00da\33"+
|
||||
"\3\2\2\2\u00db\u00dc\7g\2\2\u00dc\u00dd\7n\2\2\u00dd\u00de\7u\2\2\u00de"+
|
||||
"\u00df\7g\2\2\u00df\35\3\2\2\2\u00e0\u00e1\7y\2\2\u00e1\u00e2\7j\2\2\u00e2"+
|
||||
"\u00e3\7k\2\2\u00e3\u00e4\7n\2\2\u00e4\u00e5\7g\2\2\u00e5\37\3\2\2\2\u00e6"+
|
||||
"\u00e7\7f\2\2\u00e7\u00e8\7q\2\2\u00e8!\3\2\2\2\u00e9\u00ea\7h\2\2\u00ea"+
|
||||
"\u00eb\7q\2\2\u00eb\u00ec\7t\2\2\u00ec#\3\2\2\2\u00ed\u00ee\7e\2\2\u00ee"+
|
||||
"\u00ef\7q\2\2\u00ef\u00f0\7p\2\2\u00f0\u00f1\7v\2\2\u00f1\u00f2\7k\2\2"+
|
||||
"\u00f2\u00f3\7p\2\2\u00f3\u00f4\7w\2\2\u00f4\u00f5\7g\2\2\u00f5%\3\2\2"+
|
||||
"\2\u00f6\u00f7\7d\2\2\u00f7\u00f8\7t\2\2\u00f8\u00f9\7g\2\2\u00f9\u00fa"+
|
||||
"\7c\2\2\u00fa\u00fb\7m\2\2\u00fb\'\3\2\2\2\u00fc\u00fd\7t\2\2\u00fd\u00fe"+
|
||||
"\7g\2\2\u00fe\u00ff\7v\2\2\u00ff\u0100\7w\2\2\u0100\u0101\7t\2\2\u0101"+
|
||||
"\u0102\7p\2\2\u0102)\3\2\2\2\u0103\u0104\7p\2\2\u0104\u0105\7g\2\2\u0105"+
|
||||
"\u0106\7y\2\2\u0106+\3\2\2\2\u0107\u0108\7v\2\2\u0108\u0109\7t\2\2\u0109"+
|
||||
"\u010a\7{\2\2\u010a-\3\2\2\2\u010b\u010c\7e\2\2\u010c\u010d\7c\2\2\u010d"+
|
||||
"\u010e\7v\2\2\u010e\u010f\7e\2\2\u010f\u0110\7j\2\2\u0110/\3\2\2\2\u0111"+
|
||||
"\u0112\7v\2\2\u0112\u0113\7j\2\2\u0113\u0114\7t\2\2\u0114\u0115\7q\2\2"+
|
||||
"\u0115\u0116\7y\2\2\u0116\61\3\2\2\2\u0117\u0118\7v\2\2\u0118\u0119\7"+
|
||||
"j\2\2\u0119\u011a\7k\2\2\u011a\u011b\7u\2\2\u011b\63\3\2\2\2\u011c\u011d"+
|
||||
"\7#\2\2\u011d\65\3\2\2\2\u011e\u011f\7\u0080\2\2\u011f\67\3\2\2\2\u0120"+
|
||||
"\u0121\7,\2\2\u01219\3\2\2\2\u0122\u0123\7\61\2\2\u0123\u0124\6\35\2\2"+
|
||||
"\u0124;\3\2\2\2\u0125\u0126\7\'\2\2\u0126=\3\2\2\2\u0127\u0128\7-\2\2"+
|
||||
"\u0128?\3\2\2\2\u0129\u012a\7/\2\2\u012aA\3\2\2\2\u012b\u012c\7>\2\2\u012c"+
|
||||
"\u012d\7>\2\2\u012dC\3\2\2\2\u012e\u012f\7@\2\2\u012f\u0130\7@\2\2\u0130"+
|
||||
"E\3\2\2\2\u0131\u0132\7@\2\2\u0132\u0133\7@\2\2\u0133\u0134\7@\2\2\u0134"+
|
||||
"G\3\2\2\2\u0135\u0136\7>\2\2\u0136I\3\2\2\2\u0137\u0138\7>\2\2\u0138\u0139"+
|
||||
"\7?\2\2\u0139K\3\2\2\2\u013a\u013b\7@\2\2\u013bM\3\2\2\2\u013c\u013d\7"+
|
||||
"@\2\2\u013d\u013e\7?\2\2\u013eO\3\2\2\2\u013f\u0140\7?\2\2\u0140\u0141"+
|
||||
"\7?\2\2\u0141Q\3\2\2\2\u0142\u0143\7?\2\2\u0143\u0144\7?\2\2\u0144\u0145"+
|
||||
"\7?\2\2\u0145S\3\2\2\2\u0146\u0147\7#\2\2\u0147\u0148\7?\2\2\u0148U\3"+
|
||||
"\2\2\2\u0149\u014a\7#\2\2\u014a\u014b\7?\2\2\u014b\u014c\7?\2\2\u014c"+
|
||||
"W\3\2\2\2\u014d\u014e\7(\2\2\u014eY\3\2\2\2\u014f\u0150\7`\2\2\u0150["+
|
||||
"\3\2\2\2\u0151\u0152\7~\2\2\u0152]\3\2\2\2\u0153\u0154\7(\2\2\u0154\u0155"+
|
||||
"\7(\2\2\u0155_\3\2\2\2\u0156\u0157\7~\2\2\u0157\u0158\7~\2\2\u0158a\3"+
|
||||
"\2\2\2\u0159\u015a\7A\2\2\u015ac\3\2\2\2\u015b\u015c\7<\2\2\u015ce\3\2"+
|
||||
"\2\2\u015d\u015e\7<\2\2\u015e\u015f\7<\2\2\u015fg\3\2\2\2\u0160\u0161"+
|
||||
"\7/\2\2\u0161\u0162\7@\2\2\u0162i\3\2\2\2\u0163\u0164\7?\2\2\u0164\u0165"+
|
||||
"\7\u0080\2\2\u0165k\3\2\2\2\u0166\u0167\7?\2\2\u0167\u0168\7?\2\2\u0168"+
|
||||
"\u0169\7\u0080\2\2\u0169m\3\2\2\2\u016a\u016b\7-\2\2\u016b\u016c\7-\2"+
|
||||
"\2\u016co\3\2\2\2\u016d\u016e\7/\2\2\u016e\u016f\7/\2\2\u016fq\3\2\2\2"+
|
||||
"\u0170\u0171\7?\2\2\u0171s\3\2\2\2\u0172\u0173\7-\2\2\u0173\u0174\7?\2"+
|
||||
"\2\u0174u\3\2\2\2\u0175\u0176\7/\2\2\u0176\u0177\7?\2\2\u0177w\3\2\2\2"+
|
||||
"\u0178\u0179\7,\2\2\u0179\u017a\7?\2\2\u017ay\3\2\2\2\u017b\u017c\7\61"+
|
||||
"\2\2\u017c\u017d\7?\2\2\u017d{\3\2\2\2\u017e\u017f\7\'\2\2\u017f\u0180"+
|
||||
"\7?\2\2\u0180}\3\2\2\2\u0181\u0182\7(\2\2\u0182\u0183\7?\2\2\u0183\177"+
|
||||
"\3\2\2\2\u0184\u0185\7`\2\2\u0185\u0186\7?\2\2\u0186\u0081\3\2\2\2\u0187"+
|
||||
"\u0188\7~\2\2\u0188\u0189\7?\2\2\u0189\u0083\3\2\2\2\u018a\u018b\7>\2"+
|
||||
"\2\u018b\u018c\7>\2\2\u018c\u018d\7?\2\2\u018d\u0085\3\2\2\2\u018e\u018f"+
|
||||
"\7@\2\2\u018f\u0190\7@\2\2\u0190\u0191\7?\2\2\u0191\u0087\3\2\2\2\u0192"+
|
||||
"\u0193\7@\2\2\u0193\u0194\7@\2\2\u0194\u0195\7@\2\2\u0195\u0196\7?\2\2"+
|
||||
"\u0196\u0089\3\2\2\2\u0197\u0199\7\62\2\2\u0198\u019a\t\4\2\2\u0199\u0198"+
|
||||
"\3\2\2\2\u019a\u019b\3\2\2\2\u019b\u0199\3\2\2\2\u019b\u019c\3\2\2\2\u019c"+
|
||||
"\u019e\3\2\2\2\u019d\u019f\t\5\2\2\u019e\u019d\3\2\2\2\u019e\u019f\3\2"+
|
||||
"\2\2\u019f\u008b\3\2\2\2\u01a0\u01a1\7\62\2\2\u01a1\u01a3\t\6\2\2\u01a2"+
|
||||
"\u01a4\t\7\2\2\u01a3\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a3\3\2"+
|
||||
"\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a8\3\2\2\2\u01a7\u01a9\t\5\2\2\u01a8"+
|
||||
"\u01a7\3\2\2\2\u01a8\u01a9\3\2\2\2\u01a9\u008d\3\2\2\2\u01aa\u01b3\7\62"+
|
||||
"\2\2\u01ab\u01af\t\b\2\2\u01ac\u01ae\t\t\2\2\u01ad\u01ac\3\2\2\2\u01ae"+
|
||||
"\u01b1\3\2\2\2\u01af\u01ad\3\2\2\2\u01af\u01b0\3\2\2\2\u01b0\u01b3\3\2"+
|
||||
"\2\2\u01b1\u01af\3\2\2\2\u01b2\u01aa\3\2\2\2\u01b2\u01ab\3\2\2\2\u01b3"+
|
||||
"\u01b5\3\2\2\2\u01b4\u01b6\t\n\2\2\u01b5\u01b4\3\2\2\2\u01b5\u01b6\3\2"+
|
||||
"\2\2\u01b6\u008f\3\2\2\2\u01b7\u01c0\7\62\2\2\u01b8\u01bc\t\b\2\2\u01b9"+
|
||||
"\u01bb\t\t\2\2\u01ba\u01b9\3\2\2\2\u01bb\u01be\3\2\2\2\u01bc\u01ba\3\2"+
|
||||
"\2\2\u01bc\u01bd\3\2\2\2\u01bd\u01c0\3\2\2\2\u01be\u01bc\3\2\2\2\u01bf"+
|
||||
"\u01b7\3\2\2\2\u01bf\u01b8\3\2\2\2\u01c0\u01c7\3\2\2\2\u01c1\u01c3\5\24"+
|
||||
"\n\2\u01c2\u01c4\t\t\2\2\u01c3\u01c2\3\2\2\2\u01c4\u01c5\3\2\2\2\u01c5"+
|
||||
"\u01c3\3\2\2\2\u01c5\u01c6\3\2\2\2\u01c6\u01c8\3\2\2\2\u01c7\u01c1\3\2"+
|
||||
"\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01d2\3\2\2\2\u01c9\u01cb\t\13\2\2\u01ca"+
|
||||
"\u01cc\t\f\2\2\u01cb\u01ca\3\2\2\2\u01cb\u01cc\3\2\2\2\u01cc\u01ce\3\2"+
|
||||
"\2\2\u01cd\u01cf\t\t\2\2\u01ce\u01cd\3\2\2\2\u01cf\u01d0\3\2\2\2\u01d0"+
|
||||
"\u01ce\3\2\2\2\u01d0\u01d1\3\2\2\2\u01d1\u01d3\3\2\2\2\u01d2\u01c9\3\2"+
|
||||
"\2\2\u01d2\u01d3\3\2\2\2\u01d3\u01d5\3\2\2\2\u01d4\u01d6\t\r\2\2\u01d5"+
|
||||
"\u01d4\3\2\2\2\u01d5\u01d6\3\2\2\2\u01d6\u0091\3\2\2\2\u01d7\u01df\7$"+
|
||||
"\2\2\u01d8\u01d9\7^\2\2\u01d9\u01de\7$\2\2\u01da\u01db\7^\2\2\u01db\u01de"+
|
||||
"\7^\2\2\u01dc\u01de\n\16\2\2\u01dd\u01d8\3\2\2\2\u01dd\u01da\3\2\2\2\u01dd"+
|
||||
"\u01dc\3\2\2\2\u01de\u01e1\3\2\2\2\u01df\u01e0\3\2\2\2\u01df\u01dd\3\2"+
|
||||
"\2\2\u01e0\u01e2\3\2\2\2\u01e1\u01df\3\2\2\2\u01e2\u01f0\7$\2\2\u01e3"+
|
||||
"\u01eb\7)\2\2\u01e4\u01e5\7^\2\2\u01e5\u01ea\7)\2\2\u01e6\u01e7\7^\2\2"+
|
||||
"\u01e7\u01ea\7^\2\2\u01e8\u01ea\n\16\2\2\u01e9\u01e4\3\2\2\2\u01e9\u01e6"+
|
||||
"\3\2\2\2\u01e9\u01e8\3\2\2\2\u01ea\u01ed\3\2\2\2\u01eb\u01ec\3\2\2\2\u01eb"+
|
||||
"\u01e9\3\2\2\2\u01ec\u01ee\3\2\2\2\u01ed\u01eb\3\2\2\2\u01ee\u01f0\7)"+
|
||||
"\2\2\u01ef\u01d7\3\2\2\2\u01ef\u01e3\3\2\2\2\u01f0\u0093\3\2\2\2\u01f1"+
|
||||
"\u01f5\7\61\2\2\u01f2\u01f6\n\17\2\2\u01f3\u01f4\7^\2\2\u01f4\u01f6\n"+
|
||||
"\20\2\2\u01f5\u01f2\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f6\u01f7\3\2\2\2\u01f7"+
|
||||
"\u01f5\3\2\2\2\u01f7\u01f8\3\2\2\2\u01f8\u01f9\3\2\2\2\u01f9\u01fa\7\61"+
|
||||
"\2\2\u01fa\u01fb\6J\3\2\u01fb\u0095\3\2\2\2\u01fc\u01fd\7v\2\2\u01fd\u01fe"+
|
||||
"\7t\2\2\u01fe\u01ff\7w\2\2\u01ff\u0200\7g\2\2\u0200\u0097\3\2\2\2\u0201"+
|
||||
"\u0202\7h\2\2\u0202\u0203\7c\2\2\u0203\u0204\7n\2\2\u0204\u0205\7u\2\2"+
|
||||
"\u0205\u0206\7g\2\2\u0206\u0099\3\2\2\2\u0207\u0208\7p\2\2\u0208\u0209"+
|
||||
"\7w\2\2\u0209\u020a\7n\2\2\u020a\u020b\7n\2\2\u020b\u009b\3\2\2\2\u020c"+
|
||||
"\u0212\5\u009eO\2\u020d\u020e\5\24\n\2\u020e\u020f\5\u009eO\2\u020f\u0211"+
|
||||
"\3\2\2\2\u0210\u020d\3\2\2\2\u0211\u0214\3\2\2\2\u0212\u0210\3\2\2\2\u0212"+
|
||||
"\u0213\3\2\2\2\u0213\u0215\3\2\2\2\u0214\u0212\3\2\2\2\u0215\u0216\6N"+
|
||||
"\4\2\u0216\u009d\3\2\2\2\u0217\u021b\t\21\2\2\u0218\u021a\t\22\2\2\u0219"+
|
||||
"\u0218\3\2\2\2\u021a\u021d\3\2\2\2\u021b\u0219\3\2\2\2\u021b\u021c\3\2"+
|
||||
"\2\2\u021c\u009f\3\2\2\2\u021d\u021b\3\2\2\2\u021e\u0227\7\62\2\2\u021f"+
|
||||
"\u0223\t\b\2\2\u0220\u0222\t\t\2\2\u0221\u0220\3\2\2\2\u0222\u0225\3\2"+
|
||||
"\2\2\u0223\u0221\3\2\2\2\u0223\u0224\3\2\2\2\u0224\u0227\3\2\2\2\u0225"+
|
||||
"\u0223\3\2\2\2\u0226\u021e\3\2\2\2\u0226\u021f\3\2\2\2\u0227\u0228\3\2"+
|
||||
"\2\2\u0228\u0229\bP\4\2\u0229\u00a1\3\2\2\2\u022a\u022e\t\21\2\2\u022b"+
|
||||
"\u022d\t\22\2\2\u022c\u022b\3\2\2\2\u022d\u0230\3\2\2\2\u022e\u022c\3"+
|
||||
"\2\2\2\u022e\u022f\3\2\2\2\u022f\u0231\3\2\2\2\u0230\u022e\3\2\2\2\u0231"+
|
||||
"\u0232\bQ\4\2\u0232\u00a3\3\2\2\2#\2\3\u00a7\u00b1\u00bb\u00c0\u019b\u019e"+
|
||||
"\u01a5\u01a8\u01af\u01b2\u01b5\u01bc\u01bf\u01c5\u01c7\u01cb\u01d0\u01d2"+
|
||||
"\u01d5\u01dd\u01df\u01e9\u01eb\u01ef\u01f5\u01f7\u0212\u021b\u0223\u0226"+
|
||||
"\u022e\5\b\2\2\4\3\2\4\2\2";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -512,6 +512,10 @@ public final class Walker extends PainlessParserBaseVisitor<Object> {
|
|||
operation = Operation.ADD;
|
||||
} else if (ctx.SUB() != null) {
|
||||
operation = Operation.SUB;
|
||||
} else if (ctx.FIND() != null) {
|
||||
operation = Operation.FIND;
|
||||
} else if (ctx.MATCH() != null) {
|
||||
operation = Operation.MATCH;
|
||||
} else if (ctx.LSH() != null) {
|
||||
operation = Operation.LSH;
|
||||
} else if (ctx.RSH() != null) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.painless.Definition.Type;
|
|||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.Operation;
|
||||
import org.elasticsearch.painless.WriterConstants;
|
||||
import org.elasticsearch.painless.Locals;
|
||||
|
||||
/**
|
||||
|
@ -61,6 +62,10 @@ public final class EBinary extends AExpression {
|
|||
analyzeAdd(locals);
|
||||
} else if (operation == Operation.SUB) {
|
||||
analyzeSub(locals);
|
||||
} else if (operation == Operation.FIND) {
|
||||
analyzeRegexOp(locals);
|
||||
} else if (operation == Operation.MATCH) {
|
||||
analyzeRegexOp(locals);
|
||||
} else if (operation == Operation.LSH) {
|
||||
analyzeLSH(locals);
|
||||
} else if (operation == Operation.RSH) {
|
||||
|
@ -320,6 +325,21 @@ public final class EBinary extends AExpression {
|
|||
}
|
||||
}
|
||||
|
||||
private void analyzeRegexOp(Locals variables) {
|
||||
left.analyze(variables);
|
||||
right.analyze(variables);
|
||||
|
||||
left.expected = Definition.STRING_TYPE;
|
||||
right.expected = Definition.PATTERN_TYPE;
|
||||
|
||||
left = left.cast(variables);
|
||||
right = right.cast(variables);
|
||||
|
||||
// It'd be nice to be able to do constant folding here but we can't because constants aren't flowing through EChain
|
||||
promote = Definition.BOOLEAN_TYPE;
|
||||
actual = Definition.BOOLEAN_TYPE;
|
||||
}
|
||||
|
||||
private void analyzeLSH(Locals variables) {
|
||||
left.analyze(variables);
|
||||
right.analyze(variables);
|
||||
|
@ -607,6 +627,12 @@ public final class EBinary extends AExpression {
|
|||
if (!cat) {
|
||||
writer.writeToStrings();
|
||||
}
|
||||
} else if (operation == Operation.FIND) {
|
||||
writeBuildMatcher(writer);
|
||||
writer.invokeVirtual(Definition.MATCHER_TYPE.type, WriterConstants.MATCHER_FIND);
|
||||
} else if (operation == Operation.MATCH) {
|
||||
writeBuildMatcher(writer);
|
||||
writer.invokeVirtual(Definition.MATCHER_TYPE.type, WriterConstants.MATCHER_MATCHES);
|
||||
} else {
|
||||
left.write(writer);
|
||||
right.write(writer);
|
||||
|
@ -620,4 +646,10 @@ public final class EBinary extends AExpression {
|
|||
|
||||
writer.writeBranch(tru, fals);
|
||||
}
|
||||
|
||||
private void writeBuildMatcher(MethodWriter writer) {
|
||||
right.write(writer);
|
||||
left.write(writer);
|
||||
writer.invokeVirtual(Definition.PATTERN_TYPE.type, WriterConstants.PATTERN_MATCHER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,6 @@ import org.elasticsearch.painless.WriterConstants;
|
|||
* Represents a regex constant. All regexes are constants.
|
||||
*/
|
||||
public final class LRegex extends ALink {
|
||||
private static final Definition.Type PATTERN_TYPE = Definition.getType("Pattern");
|
||||
|
||||
private final String pattern;
|
||||
private Constant constant;
|
||||
|
||||
|
@ -60,8 +58,8 @@ public final class LRegex extends ALink {
|
|||
throw createError(new IllegalArgumentException("Regex constant may only be read [" + pattern + "]."));
|
||||
}
|
||||
|
||||
constant = locals.addConstant(location, PATTERN_TYPE, "regexAt$" + location.getOffset(), this::initializeConstant);
|
||||
after = PATTERN_TYPE;
|
||||
constant = locals.addConstant(location, Definition.PATTERN_TYPE, "regexAt$" + location.getOffset(), this::initializeConstant);
|
||||
after = Definition.PATTERN_TYPE;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -74,7 +72,7 @@ public final class LRegex extends ALink {
|
|||
@Override
|
||||
void load(MethodWriter writer) {
|
||||
writer.writeDebugInfo(location);
|
||||
writer.getStatic(WriterConstants.CLASS_TYPE, constant.name, PATTERN_TYPE.type);
|
||||
writer.getStatic(WriterConstants.CLASS_TYPE, constant.name, Definition.PATTERN_TYPE.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,6 +82,6 @@ public final class LRegex extends ALink {
|
|||
|
||||
private void initializeConstant(MethodWriter writer) {
|
||||
writer.push(pattern);
|
||||
writer.invokeStatic(PATTERN_TYPE.type, WriterConstants.PATTERN_COMPILE);
|
||||
writer.invokeStatic(Definition.PATTERN_TYPE.type, WriterConstants.PATTERN_COMPILE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,5 +29,31 @@ class Pattern -> java.util.regex.Pattern extends Object {
|
|||
}
|
||||
|
||||
class Matcher -> java.util.regex.Matcher extends Object {
|
||||
int end()
|
||||
int end(int)
|
||||
boolean find()
|
||||
boolean find(int)
|
||||
String group()
|
||||
String group(int)
|
||||
String namedGroup/group(String)
|
||||
int groupCount()
|
||||
boolean hasAnchoringBounds()
|
||||
boolean hasTransparentBounds()
|
||||
boolean hitEnd()
|
||||
boolean lookingAt()
|
||||
boolean matches()
|
||||
Pattern pattern()
|
||||
String quoteReplacement(String)
|
||||
Matcher region(int,int)
|
||||
int regionEnd()
|
||||
int regionStart()
|
||||
String replaceAll(String)
|
||||
String replaceFirst(String)
|
||||
boolean requireEnd()
|
||||
Matcher reset()
|
||||
int start()
|
||||
int start(int)
|
||||
Matcher useAnchoringBounds(boolean)
|
||||
Matcher usePattern(Pattern)
|
||||
Matcher useTransparentBounds(boolean)
|
||||
}
|
||||
|
|
|
@ -19,53 +19,131 @@
|
|||
|
||||
package org.elasticsearch.painless;
|
||||
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
public class RegexTests extends ScriptTestCase {
|
||||
public void testPatternAfterReturn() {
|
||||
assertEquals(true, exec("return /foo/.matcher(\"foo\").matches()"));
|
||||
assertEquals(false, exec("return /foo/.matcher(\"bar\").matches()"));
|
||||
assertEquals(true, exec("return 'foo' ==~ /foo/"));
|
||||
assertEquals(false, exec("return 'bar' ==~ /foo/"));
|
||||
}
|
||||
|
||||
public void testSlashesEscapePattern() {
|
||||
assertEquals(true, exec("return /\\/\\//.matcher(\"//\").matches()"));
|
||||
assertEquals(true, exec("return '//' ==~ /\\/\\//"));
|
||||
}
|
||||
|
||||
public void testPatternAfterAssignment() {
|
||||
assertEquals(true, exec("def a = /foo/; return a.matcher(\"foo\").matches()"));
|
||||
assertEquals(true, exec("def a = /foo/; return 'foo' ==~ a"));
|
||||
}
|
||||
|
||||
public void testPatternInIfStement() {
|
||||
assertEquals(true, exec("if (/foo/.matcher(\"foo\").matches()) { return true } else { return false }"));
|
||||
assertEquals(true, exec("if (/foo/.matcher('foo').matches()) { return true } else { return false }"));
|
||||
assertEquals(true, exec("if ('foo' ==~ /foo/) { return true } else { return false }"));
|
||||
}
|
||||
|
||||
public void testPatternAfterInfixBoolean() {
|
||||
assertEquals(true, exec("return false || /foo/.matcher(\"foo\").matches()"));
|
||||
assertEquals(true, exec("return true && /foo/.matcher(\"foo\").matches()"));
|
||||
assertEquals(true, exec("return false || /foo/.matcher('foo').matches()"));
|
||||
assertEquals(true, exec("return true && /foo/.matcher('foo').matches()"));
|
||||
assertEquals(true, exec("return false || 'foo' ==~ /foo/"));
|
||||
assertEquals(true, exec("return true && 'foo' ==~ /foo/"));
|
||||
}
|
||||
|
||||
public void testPatternAfterUnaryNotBoolean() {
|
||||
assertEquals(false, exec("return !/foo/.matcher(\"foo\").matches()"));
|
||||
assertEquals(true, exec("return !/foo/.matcher(\"bar\").matches()"));
|
||||
assertEquals(false, exec("return !/foo/.matcher('foo').matches()"));
|
||||
assertEquals(true, exec("return !/foo/.matcher('bar').matches()"));
|
||||
}
|
||||
|
||||
public void testInTernaryCondition() {
|
||||
assertEquals(true, exec("return /foo/.matcher(\"foo\").matches() ? true : false"));
|
||||
assertEquals(1, exec("def i = 0; i += /foo/.matcher(\"foo\").matches() ? 1 : 1; return i"));
|
||||
assertEquals(true, exec("return /foo/.matcher('foo').matches() ? true : false"));
|
||||
assertEquals(1, exec("def i = 0; i += /foo/.matcher('foo').matches() ? 1 : 1; return i"));
|
||||
assertEquals(true, exec("return 'foo' ==~ /foo/ ? true : false"));
|
||||
assertEquals(1, exec("def i = 0; i += 'foo' ==~ /foo/ ? 1 : 1; return i"));
|
||||
}
|
||||
|
||||
public void testInTernaryTrueArm() {
|
||||
assertEquals(true, exec("def i = true; return i ? /foo/.matcher(\"foo\").matches() : false"));
|
||||
assertEquals(true, exec("def i = true; return i ? /foo/.matcher('foo').matches() : false"));
|
||||
assertEquals(true, exec("def i = true; return i ? 'foo' ==~ /foo/ : false"));
|
||||
}
|
||||
|
||||
public void testInTernaryFalseArm() {
|
||||
assertEquals(true, exec("def i = false; return i ? false : /foo/.matcher(\"foo\").matches()"));
|
||||
assertEquals(true, exec("def i = false; return i ? false : 'foo' ==~ /foo/"));
|
||||
}
|
||||
|
||||
public void testRegexInFunction() {
|
||||
assertEquals(true, exec("boolean m(String s) {/foo/.matcher(s).matches()} m(\"foo\")"));
|
||||
assertEquals(true, exec("boolean m(String s) {/foo/.matcher(s).matches()} m('foo')"));
|
||||
assertEquals(true, exec("boolean m(String s) {s ==~ /foo/} m('foo')"));
|
||||
}
|
||||
|
||||
public void testReturnRegexFromFunction() {
|
||||
assertEquals(true, exec("Pattern m(boolean a) {a ? /foo/ : /bar/} m(true).matcher(\"foo\").matches()"));
|
||||
assertEquals(true, exec("Pattern m(boolean a) {a ? /foo/ : /bar/} m(true).matcher('foo').matches()"));
|
||||
assertEquals(true, exec("Pattern m(boolean a) {a ? /foo/ : /bar/} 'foo' ==~ m(true)"));
|
||||
assertEquals(false, exec("Pattern m(boolean a) {a ? /foo/ : /bar/} m(false).matcher('foo').matches()"));
|
||||
assertEquals(false, exec("Pattern m(boolean a) {a ? /foo/ : /bar/} 'foo' ==~ m(false)"));
|
||||
}
|
||||
|
||||
public void testCallMatcherDirectly() {
|
||||
assertEquals(true, exec("return /foo/.matcher('foo').matches()"));
|
||||
assertEquals(false, exec("return /foo/.matcher('bar').matches()"));
|
||||
}
|
||||
|
||||
public void testFindInIf() {
|
||||
assertEquals(true, exec("if ('fooasdfbasdf' =~ /foo/) {return true} else {return false}"));
|
||||
assertEquals(true, exec("if ('1fooasdfbasdf' =~ /foo/) {return true} else {return false}"));
|
||||
assertEquals(false, exec("if ('1f11ooasdfbasdf' =~ /foo/) {return true} else {return false}"));
|
||||
}
|
||||
|
||||
public void testFindCastToBoolean() {
|
||||
assertEquals(true, exec("return (boolean)('fooasdfbasdf' =~ /foo/)"));
|
||||
assertEquals(true, exec("return (boolean)('111fooasdfbasdf' =~ /foo/)"));
|
||||
assertEquals(false, exec("return (boolean)('fo11oasdfbasdf' =~ /foo/)"));
|
||||
}
|
||||
|
||||
public void testFindOrStringConcat() {
|
||||
assertEquals(true, exec("return 'f' + 'o' + 'o' =~ /foo/"));
|
||||
}
|
||||
|
||||
public void testFindOfDef() {
|
||||
assertEquals(true, exec("def s = 'foo'; return s =~ /foo/"));
|
||||
}
|
||||
|
||||
public void testFindOnInput() {
|
||||
assertEquals(true, exec("return params.s =~ /foo/", singletonMap("s", "fooasdfdf")));
|
||||
assertEquals(false, exec("return params.s =~ /foo/", singletonMap("s", "11f2ooasdfdf")));
|
||||
}
|
||||
|
||||
public void testGroup() {
|
||||
assertEquals("foo", exec("Matcher m = /foo/.matcher('foo'); m.find(); return m.group()"));
|
||||
}
|
||||
|
||||
public void testNumberedGroup() {
|
||||
assertEquals("o", exec("Matcher m = /(f)(o)o/.matcher('foo'); m.find(); return m.group(2)"));
|
||||
}
|
||||
|
||||
public void testNamedGroup() {
|
||||
assertEquals("o", exec("Matcher m = /(?<first>f)(?<second>o)o/.matcher('foo'); m.find(); return m.namedGroup('second')"));
|
||||
}
|
||||
|
||||
public void testCantUsePatternCompile() {
|
||||
IllegalArgumentException e = expectScriptThrows(IllegalArgumentException.class, () -> {
|
||||
exec("Pattern.compile('aa')");
|
||||
});
|
||||
assertEquals("Unknown call [compile] with [1] arguments on type [Pattern].", e.getMessage());
|
||||
}
|
||||
|
||||
public void testBadRegexPattern() {
|
||||
PatternSyntaxException e = expectScriptThrows(PatternSyntaxException.class, () -> {
|
||||
exec("/\\ujjjj/"); // Invalid unicode
|
||||
});
|
||||
assertThat(e.getMessage(), containsString("Illegal Unicode escape sequence near index 2"));
|
||||
assertThat(e.getMessage(), containsString("\\ujjjj"));
|
||||
}
|
||||
|
||||
public void testRegexAgainstNumber() {
|
||||
ClassCastException e = expectScriptThrows(ClassCastException.class, () -> {
|
||||
exec("12 ==~ /cat/");
|
||||
});
|
||||
assertEquals("Cannot cast from [int] to [String].", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.painless;
|
|||
import java.lang.invoke.WrongMethodTypeException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
@ -214,21 +213,6 @@ public class WhenThingsGoWrongTests extends ScriptTestCase {
|
|||
assertEquals("invalid sequence of tokens near ['}'].", e.getMessage());
|
||||
}
|
||||
|
||||
public void testCantUsePatternCompile() {
|
||||
IllegalArgumentException e = expectScriptThrows(IllegalArgumentException.class, () -> {
|
||||
exec("Pattern.compile(\"aa\")");
|
||||
});
|
||||
assertEquals("Unknown call [compile] with [1] arguments on type [Pattern].", e.getMessage());
|
||||
}
|
||||
|
||||
public void testBadRegexPattern() {
|
||||
PatternSyntaxException e = expectScriptThrows(PatternSyntaxException.class, () -> {
|
||||
exec("/\\ujjjj/"); // Invalid unicode
|
||||
});
|
||||
assertThat(e.getMessage(), containsString("Illegal Unicode escape sequence near index 2"));
|
||||
assertThat(e.getMessage(), containsString("\\ujjjj"));
|
||||
}
|
||||
|
||||
public void testBadBoxingCast() {
|
||||
expectScriptThrows(ClassCastException.class, () -> {
|
||||
exec("BitSet bs = new BitSet(); bs.and(2);");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue