Upgrade ANTLR to version 4.11.1 (#12016)

Drop 3.x compatibility (which was pickier at compile-time and prevented slow things from happening). Instead add paranoia to runtime tests, so that they fail if antlr would do something slow in the parsing. This is needed because antlrv4 is a big performance trap: https://github.com/antlr/antlr4/blob/master/doc/faq/general.md

"Q: What are the main design decisions in ANTLR4?
Ease-of-use over performance. I will worry about performance later."

It allows us to move forward with newer antlr but hopefully prevent the associated headaches.

Signed-off-by: Andriy Redko <andriy.redko@aiven.io>
Co-authored-by: Robert Muir <rmuir@apache.org>
This commit is contained in:
Andriy Redko 2022-12-15 22:40:35 -05:00 committed by GitHub
parent 3e8ef57e3f
commit 945d7fe027
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 663 additions and 370 deletions

View File

@ -170,6 +170,8 @@ Improvements
* GITHUB#12003: Minor cleanup/improvements to IndexSortSortedNumericDocValuesRangeQuery. (Greg Miller)
* GITHUB#12016: Upgrade lucene/expressions to use antlr 4.11.1 (Andriy Redko)
Bug Fixes
---------------------
* GITHUB#11726: Indexing term vectors on large documents could fail due to

View File

@ -1,7 +1,7 @@
{
"lucene/expressions/src/java/org/apache/lucene/expressions/js/Javascript.g4": "818e89aae0b6c7601051802013898c128fe7c1ba",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptBaseVisitor.java": "45e3c7093f3e485a07be507efbdefc5e3d112576",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptLexer.java": "354e2d7a982fec18a06e552438c2b2e2c13137cf",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptParser.java": "6182b6a2e3ade663e6f7a8643ace313e66cbf12a",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptBaseVisitor.java": "706c11702149d135fc7ebe13ec1fe01800338260",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptLexer.java": "b8d6b259ebbfce09a5379a1a2aa4c1ddd4e378eb",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptParser.java": "7a3a7b9de17f4a8d41ef342312eae5c55e483e08",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptVisitor.java": "ebf033dc72e63203e5d4d85fd57114dd973482dc"
}

View File

@ -19,7 +19,7 @@
module org.apache.lucene.expressions {
requires org.objectweb.asm;
requires org.objectweb.asm.commons;
requires antlr4.runtime;
requires org.antlr.antlr4.runtime;
requires org.apache.lucene.core;
requires org.apache.lucene.codecs;

View File

@ -10,6 +10,7 @@ import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
* @param <T> The return type of the visit operation. Use {@link Void} for operations with no return
* type.
*/
@SuppressWarnings("CheckReturnValue")
class JavascriptBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements JavascriptVisitor<T> {
/**
* {@inheritDoc}

View File

@ -34,7 +34,12 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.DiagnosticErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.atn.PredictionMode;
import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.lucene.expressions.Expression;
import org.apache.lucene.expressions.js.JavascriptParser.ExpressionContext;
@ -120,21 +125,22 @@ public final class JavascriptCompiler {
final String sourceText;
final Map<String, Method> functions;
final boolean picky;
/**
* Compiles the given expression.
* Compiles the given expression using default compiler settings.
*
* @param sourceText The expression to compile
* @return A new compiled expression
* @throws ParseException on failure to compile
*/
public static Expression compile(String sourceText) throws ParseException {
return new JavascriptCompiler(sourceText)
.compileExpression(JavascriptCompiler.class.getClassLoader());
return compile(sourceText, DEFAULT_FUNCTIONS, JavascriptCompiler.class.getClassLoader());
}
/**
* Compiles the given expression with the supplied custom functions.
* Compiles the given expression with the supplied custom functions using default compiler
* settings.
*
* <p>Functions must be {@code public static}, return {@code double} and can take from zero to 256
* {@code double} parameters.
@ -148,6 +154,27 @@ public final class JavascriptCompiler {
*/
public static Expression compile(
String sourceText, Map<String, Method> functions, ClassLoader parent) throws ParseException {
return compile(sourceText, functions, parent, false);
}
/**
* Compiles the given expression with the supplied custom functions.
*
* <p>Functions must be {@code public static}, return {@code double} and can take from zero to 256
* {@code double} parameters.
*
* @param sourceText The expression to compile
* @param functions map of String names to functions
* @param parent a {@code ClassLoader} that should be used as the parent of the loaded class. It
* must contain all classes referred to by the given {@code functions}.
* @param picky whether to throw exception on ambiguity or other internal parsing issues (this
* option makes things slower too, it is only for debugging).
* @return A new compiled expression
* @throws ParseException on failure to compile
*/
static Expression compile(
String sourceText, Map<String, Method> functions, ClassLoader parent, boolean picky)
throws ParseException {
if (parent == null) {
throw new NullPointerException("A parent ClassLoader must be given.");
}
@ -155,7 +182,7 @@ public final class JavascriptCompiler {
checkFunctionClassLoader(m, parent);
checkFunction(m);
}
return new JavascriptCompiler(sourceText, functions).compileExpression(parent);
return new JavascriptCompiler(sourceText, functions, picky).compileExpression(parent);
}
/**
@ -169,26 +196,18 @@ public final class JavascriptCompiler {
f.doubleValue();
}
/**
* Constructs a compiler for expressions.
*
* @param sourceText The expression to compile
*/
private JavascriptCompiler(String sourceText) {
this(sourceText, DEFAULT_FUNCTIONS);
}
/**
* Constructs a compiler for expressions with specific set of functions
*
* @param sourceText The expression to compile
*/
private JavascriptCompiler(String sourceText, Map<String, Method> functions) {
private JavascriptCompiler(String sourceText, Map<String, Method> functions, boolean picky) {
if (sourceText == null) {
throw new NullPointerException();
}
this.sourceText = sourceText;
this.functions = functions;
this.picky = picky;
}
/**
@ -238,10 +257,47 @@ public final class JavascriptCompiler {
final JavascriptParser javascriptParser =
new JavascriptParser(new CommonTokenStream(javascriptLexer));
javascriptParser.removeErrorListeners();
if (picky) {
setupPicky(javascriptParser);
}
javascriptParser.setErrorHandler(new JavascriptParserErrorStrategy());
return javascriptParser.compile();
}
private void setupPicky(JavascriptParser parser) {
// Diagnostic listener invokes syntaxError on other listeners for ambiguity issues
parser.addErrorListener(new DiagnosticErrorListener(true));
// a second listener to fail the test when the above happens.
parser.addErrorListener(
new BaseErrorListener() {
@Override
public void syntaxError(
final Recognizer<?, ?> recognizer,
final Object offendingSymbol,
final int line,
final int charPositionInLine,
final String msg,
final RecognitionException e) {
throw new RuntimeException(
new ParseException(
"line ("
+ line
+ "), offset ("
+ charPositionInLine
+ "), symbol ("
+ offendingSymbol
+ ") "
+ msg,
charPositionInLine));
}
});
// Enable exact ambiguity detection (costly). we enable exact since its the default for
// DiagnosticErrorListener, life is too short to think about what 'inexact ambiguity' might
// mean.
parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);
}
/** Sends the bytecode of class file to {@link ClassWriter}. */
private void generateClass(
final ParseTree parseTree,

View File

@ -8,10 +8,10 @@ import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"})
class JavascriptLexer extends Lexer {
static {
RuntimeMetaData.checkVersion("4.5.1", RuntimeMetaData.VERSION);
RuntimeMetaData.checkVersion("4.11.1", RuntimeMetaData.VERSION);
}
protected static final DFA[] _decisionToDFA;
@ -47,84 +47,99 @@ class JavascriptLexer extends Lexer {
OCTAL = 29,
HEX = 30,
DECIMAL = 31;
public static String[] channelNames = {"DEFAULT_TOKEN_CHANNEL", "HIDDEN"};
public static String[] modeNames = {"DEFAULT_MODE"};
public static final String[] ruleNames = {
"LP",
"RP",
"COMMA",
"BOOLNOT",
"BWNOT",
"MUL",
"DIV",
"REM",
"ADD",
"SUB",
"LSH",
"RSH",
"USH",
"LT",
"LTE",
"GT",
"GTE",
"EQ",
"NE",
"BWAND",
"BWXOR",
"BWOR",
"BOOLAND",
"BOOLOR",
"COND",
"COLON",
"WS",
"VARIABLE",
"ARRAY",
"ID",
"STRING",
"OCTAL",
"HEX",
"DECIMAL",
"INTEGER"
};
private static String[] makeRuleNames() {
return new String[] {
"LP",
"RP",
"COMMA",
"BOOLNOT",
"BWNOT",
"MUL",
"DIV",
"REM",
"ADD",
"SUB",
"LSH",
"RSH",
"USH",
"LT",
"LTE",
"GT",
"GTE",
"EQ",
"NE",
"BWAND",
"BWXOR",
"BWOR",
"BOOLAND",
"BOOLOR",
"COND",
"COLON",
"WS",
"VARIABLE",
"ARRAY",
"ID",
"STRING",
"OCTAL",
"HEX",
"DECIMAL",
"INTEGER"
};
}
private static final String[] _LITERAL_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, "'<<'", "'>>'", "'>>>'", null,
"'<='", null, "'>='", "'=='", "'!='", null, null, null, "'&&'", "'||'"
};
private static final String[] _SYMBOLIC_NAMES = {
null,
"LP",
"RP",
"COMMA",
"BOOLNOT",
"BWNOT",
"MUL",
"DIV",
"REM",
"ADD",
"SUB",
"LSH",
"RSH",
"USH",
"LT",
"LTE",
"GT",
"GTE",
"EQ",
"NE",
"BWAND",
"BWXOR",
"BWOR",
"BOOLAND",
"BOOLOR",
"COND",
"COLON",
"WS",
"VARIABLE",
"OCTAL",
"HEX",
"DECIMAL"
};
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, null, null, null, null, null, null, null, null, null, null, "'<<'", "'>>'", "'>>>'",
null, "'<='", null, "'>='", "'=='", "'!='", null, null, null, "'&&'", "'||'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null,
"LP",
"RP",
"COMMA",
"BOOLNOT",
"BWNOT",
"MUL",
"DIV",
"REM",
"ADD",
"SUB",
"LSH",
"RSH",
"USH",
"LT",
"LTE",
"GT",
"GTE",
"EQ",
"NE",
"BWAND",
"BWXOR",
"BWOR",
"BOOLAND",
"BOOLOR",
"COND",
"COLON",
"WS",
"VARIABLE",
"OCTAL",
"HEX",
"DECIMAL"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
@ -177,6 +192,11 @@ class JavascriptLexer extends Lexer {
return _serializedATN;
}
@Override
public String[] getChannelNames() {
return channelNames;
}
@Override
public String[] getModeNames() {
return modeNames;
@ -188,96 +208,180 @@ class JavascriptLexer extends Lexer {
}
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2!\u00fe\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\t\31"
+ "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"
+ "\t!\4\"\t\"\4#\t#\4$\t$\3\2\3\2\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\13\3\13\3\f\3\f\3\f\3\r\3\r\3\r\3\16\3\16"
+ "\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\22\3\22\3\22\3\23\3\23"
+ "\3\23\3\24\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\30\3\31"
+ "\3\31\3\31\3\32\3\32\3\33\3\33\3\34\6\34\u0089\n\34\r\34\16\34\u008a\3"
+ "\34\3\34\3\35\3\35\7\35\u0091\n\35\f\35\16\35\u0094\13\35\3\35\3\35\3"
+ "\35\7\35\u0099\n\35\f\35\16\35\u009c\13\35\7\35\u009e\n\35\f\35\16\35"
+ "\u00a1\13\35\3\36\3\36\3\36\5\36\u00a6\n\36\3\36\3\36\3\37\3\37\7\37\u00ac"
+ "\n\37\f\37\16\37\u00af\13\37\3 \3 \3 \3 \3 \3 \7 \u00b7\n \f \16 \u00ba"
+ "\13 \3 \3 \3 \3 \3 \3 \3 \7 \u00c3\n \f \16 \u00c6\13 \3 \5 \u00c9\n "
+ "\3!\3!\6!\u00cd\n!\r!\16!\u00ce\3\"\3\"\3\"\6\"\u00d4\n\"\r\"\16\"\u00d5"
+ "\3#\3#\3#\7#\u00db\n#\f#\16#\u00de\13#\5#\u00e0\n#\3#\3#\6#\u00e4\n#\r"
+ "#\16#\u00e5\5#\u00e8\n#\3#\3#\5#\u00ec\n#\3#\6#\u00ef\n#\r#\16#\u00f0"
+ "\5#\u00f3\n#\3$\3$\3$\7$\u00f8\n$\f$\16$\u00fb\13$\5$\u00fd\n$\4\u00b8"
+ "\u00c4\2%\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33"
+ "\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67"
+ "\359\36;\2=\2?\2A\37C E!G\2\3\2%\3\2**\3\2++\3\2..\3\2##\3\2\u0080\u0080"
+ "\3\2,,\3\2\61\61\3\2\'\'\3\2--\3\2//\3\2>>\3\2@@\3\2((\3\2``\3\2~~\3\2"
+ "AA\3\2<<\5\2\13\f\17\17\"\"\3\2\60\60\3\2]]\3\2^_\6\2&&C\\aac|\7\2&&\62"
+ ";C\\aac|\3\2))\4\2))^^\3\2$$\4\2$$^^\3\2\62\62\3\2\629\4\2ZZzz\5\2\62"
+ ";CHch\3\2\62;\4\2GGgg\4\2--//\3\2\63;\u0111\2\3\3\2\2\2\2\5\3\2\2\2\2"
+ "\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2"
+ "\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2"
+ "\2\35\3\2\2\2\2\37\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\61\3\2\2\2\2\63\3\2\2"
+ "\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2"
+ "\2\3I\3\2\2\2\5K\3\2\2\2\7M\3\2\2\2\tO\3\2\2\2\13Q\3\2\2\2\rS\3\2\2\2"
+ "\17U\3\2\2\2\21W\3\2\2\2\23Y\3\2\2\2\25[\3\2\2\2\27]\3\2\2\2\31`\3\2\2"
+ "\2\33c\3\2\2\2\35g\3\2\2\2\37i\3\2\2\2!l\3\2\2\2#n\3\2\2\2%q\3\2\2\2\'"
+ "t\3\2\2\2)w\3\2\2\2+y\3\2\2\2-{\3\2\2\2/}\3\2\2\2\61\u0080\3\2\2\2\63"
+ "\u0083\3\2\2\2\65\u0085\3\2\2\2\67\u0088\3\2\2\29\u008e\3\2\2\2;\u00a2"
+ "\3\2\2\2=\u00a9\3\2\2\2?\u00c8\3\2\2\2A\u00ca\3\2\2\2C\u00d0\3\2\2\2E"
+ "\u00e7\3\2\2\2G\u00fc\3\2\2\2IJ\t\2\2\2J\4\3\2\2\2KL\t\3\2\2L\6\3\2\2"
+ "\2MN\t\4\2\2N\b\3\2\2\2OP\t\5\2\2P\n\3\2\2\2QR\t\6\2\2R\f\3\2\2\2ST\t"
+ "\7\2\2T\16\3\2\2\2UV\t\b\2\2V\20\3\2\2\2WX\t\t\2\2X\22\3\2\2\2YZ\t\n\2"
+ "\2Z\24\3\2\2\2[\\\t\13\2\2\\\26\3\2\2\2]^\7>\2\2^_\7>\2\2_\30\3\2\2\2"
+ "`a\7@\2\2ab\7@\2\2b\32\3\2\2\2cd\7@\2\2de\7@\2\2ef\7@\2\2f\34\3\2\2\2"
+ "gh\t\f\2\2h\36\3\2\2\2ij\7>\2\2jk\7?\2\2k \3\2\2\2lm\t\r\2\2m\"\3\2\2"
+ "\2no\7@\2\2op\7?\2\2p$\3\2\2\2qr\7?\2\2rs\7?\2\2s&\3\2\2\2tu\7#\2\2uv"
+ "\7?\2\2v(\3\2\2\2wx\t\16\2\2x*\3\2\2\2yz\t\17\2\2z,\3\2\2\2{|\t\20\2\2"
+ "|.\3\2\2\2}~\7(\2\2~\177\7(\2\2\177\60\3\2\2\2\u0080\u0081\7~\2\2\u0081"
+ "\u0082\7~\2\2\u0082\62\3\2\2\2\u0083\u0084\t\21\2\2\u0084\64\3\2\2\2\u0085"
+ "\u0086\t\22\2\2\u0086\66\3\2\2\2\u0087\u0089\t\23\2\2\u0088\u0087\3\2"
+ "\2\2\u0089\u008a\3\2\2\2\u008a\u0088\3\2\2\2\u008a\u008b\3\2\2\2\u008b"
+ "\u008c\3\2\2\2\u008c\u008d\b\34\2\2\u008d8\3\2\2\2\u008e\u0092\5=\37\2"
+ "\u008f\u0091\5;\36\2\u0090\u008f\3\2\2\2\u0091\u0094\3\2\2\2\u0092\u0090"
+ "\3\2\2\2\u0092\u0093\3\2\2\2\u0093\u009f\3\2\2\2\u0094\u0092\3\2\2\2\u0095"
+ "\u0096\t\24\2\2\u0096\u009a\5=\37\2\u0097\u0099\5;\36\2\u0098\u0097\3"
+ "\2\2\2\u0099\u009c\3\2\2\2\u009a\u0098\3\2\2\2\u009a\u009b\3\2\2\2\u009b"
+ "\u009e\3\2\2\2\u009c\u009a\3\2\2\2\u009d\u0095\3\2\2\2\u009e\u00a1\3\2"
+ "\2\2\u009f\u009d\3\2\2\2\u009f\u00a0\3\2\2\2\u00a0:\3\2\2\2\u00a1\u009f"
+ "\3\2\2\2\u00a2\u00a5\t\25\2\2\u00a3\u00a6\5? \2\u00a4\u00a6\5G$\2\u00a5"
+ "\u00a3\3\2\2\2\u00a5\u00a4\3\2\2\2\u00a6\u00a7\3\2\2\2\u00a7\u00a8\t\26"
+ "\2\2\u00a8<\3\2\2\2\u00a9\u00ad\t\27\2\2\u00aa\u00ac\t\30\2\2\u00ab\u00aa"
+ "\3\2\2\2\u00ac\u00af\3\2\2\2\u00ad\u00ab\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ae"
+ ">\3\2\2\2\u00af\u00ad\3\2\2\2\u00b0\u00b8\t\31\2\2\u00b1\u00b2\7^\2\2"
+ "\u00b2\u00b7\7)\2\2\u00b3\u00b4\7^\2\2\u00b4\u00b7\7^\2\2\u00b5\u00b7"
+ "\n\32\2\2\u00b6\u00b1\3\2\2\2\u00b6\u00b3\3\2\2\2\u00b6\u00b5\3\2\2\2"
+ "\u00b7\u00ba\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b8\u00b6\3\2\2\2\u00b9\u00bb"
+ "\3\2\2\2\u00ba\u00b8\3\2\2\2\u00bb\u00c9\t\31\2\2\u00bc\u00c4\t\33\2\2"
+ "\u00bd\u00be\7^\2\2\u00be\u00c3\7$\2\2\u00bf\u00c0\7^\2\2\u00c0\u00c3"
+ "\7^\2\2\u00c1\u00c3\n\34\2\2\u00c2\u00bd\3\2\2\2\u00c2\u00bf\3\2\2\2\u00c2"
+ "\u00c1\3\2\2\2\u00c3\u00c6\3\2\2\2\u00c4\u00c5\3\2\2\2\u00c4\u00c2\3\2"
+ "\2\2\u00c5\u00c7\3\2\2\2\u00c6\u00c4\3\2\2\2\u00c7\u00c9\t\33\2\2\u00c8"
+ "\u00b0\3\2\2\2\u00c8\u00bc\3\2\2\2\u00c9@\3\2\2\2\u00ca\u00cc\t\35\2\2"
+ "\u00cb\u00cd\t\36\2\2\u00cc\u00cb\3\2\2\2\u00cd\u00ce\3\2\2\2\u00ce\u00cc"
+ "\3\2\2\2\u00ce\u00cf\3\2\2\2\u00cfB\3\2\2\2\u00d0\u00d1\t\35\2\2\u00d1"
+ "\u00d3\t\37\2\2\u00d2\u00d4\t \2\2\u00d3\u00d2\3\2\2\2\u00d4\u00d5\3\2"
+ "\2\2\u00d5\u00d3\3\2\2\2\u00d5\u00d6\3\2\2\2\u00d6D\3\2\2\2\u00d7\u00df"
+ "\5G$\2\u00d8\u00dc\t\24\2\2\u00d9\u00db\t!\2\2\u00da\u00d9\3\2\2\2\u00db"
+ "\u00de\3\2\2\2\u00dc\u00da\3\2\2\2\u00dc\u00dd\3\2\2\2\u00dd\u00e0\3\2"
+ "\2\2\u00de\u00dc\3\2\2\2\u00df\u00d8\3\2\2\2\u00df\u00e0\3\2\2\2\u00e0"
+ "\u00e8\3\2\2\2\u00e1\u00e3\t\24\2\2\u00e2\u00e4\t!\2\2\u00e3\u00e2\3\2"
+ "\2\2\u00e4\u00e5\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6"
+ "\u00e8\3\2\2\2\u00e7\u00d7\3\2\2\2\u00e7\u00e1\3\2\2\2\u00e8\u00f2\3\2"
+ "\2\2\u00e9\u00eb\t\"\2\2\u00ea\u00ec\t#\2\2\u00eb\u00ea\3\2\2\2\u00eb"
+ "\u00ec\3\2\2\2\u00ec\u00ee\3\2\2\2\u00ed\u00ef\t!\2\2\u00ee\u00ed\3\2"
+ "\2\2\u00ef\u00f0\3\2\2\2\u00f0\u00ee\3\2\2\2\u00f0\u00f1\3\2\2\2\u00f1"
+ "\u00f3\3\2\2\2\u00f2\u00e9\3\2\2\2\u00f2\u00f3\3\2\2\2\u00f3F\3\2\2\2"
+ "\u00f4\u00fd\t\35\2\2\u00f5\u00f9\t$\2\2\u00f6\u00f8\t!\2\2\u00f7\u00f6"
+ "\3\2\2\2\u00f8\u00fb\3\2\2\2\u00f9\u00f7\3\2\2\2\u00f9\u00fa\3\2\2\2\u00fa"
+ "\u00fd\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fc\u00f4\3\2\2\2\u00fc\u00f5\3\2"
+ "\2\2\u00fdH\3\2\2\2\31\2\u008a\u0092\u009a\u009f\u00a5\u00ad\u00b6\u00b8"
+ "\u00c2\u00c4\u00c8\u00ce\u00d5\u00dc\u00df\u00e5\u00e7\u00eb\u00f0\u00f2"
+ "\u00f9\u00fc\3\b\2\2";
"\u0004\u0000\u001f\u00fc\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"
+ "\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"
+ "\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"
+ "\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"
+ "\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"
+ "\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"
+ "\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"
+ "\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"
+ "\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"
+ "\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"
+ "\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!"
+ "\u0007!\u0002\"\u0007\"\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001"
+ "\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004"
+ "\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007"
+ "\u0001\b\u0001\b\u0001\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001"
+ "\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001"
+ "\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u0010\u0001"
+ "\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001"
+ "\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001"
+ "\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0001"
+ "\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001"
+ "\u001a\u0004\u001a\u0087\b\u001a\u000b\u001a\f\u001a\u0088\u0001\u001a"
+ "\u0001\u001a\u0001\u001b\u0001\u001b\u0005\u001b\u008f\b\u001b\n\u001b"
+ "\f\u001b\u0092\t\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0005\u001b"
+ "\u0097\b\u001b\n\u001b\f\u001b\u009a\t\u001b\u0005\u001b\u009c\b\u001b"
+ "\n\u001b\f\u001b\u009f\t\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0003"
+ "\u001c\u00a4\b\u001c\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0005"
+ "\u001d\u00aa\b\u001d\n\u001d\f\u001d\u00ad\t\u001d\u0001\u001e\u0001\u001e"
+ "\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0005\u001e\u00b5\b\u001e"
+ "\n\u001e\f\u001e\u00b8\t\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001"
+ "\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0005\u001e\u00c1\b\u001e\n"
+ "\u001e\f\u001e\u00c4\t\u001e\u0001\u001e\u0003\u001e\u00c7\b\u001e\u0001"
+ "\u001f\u0001\u001f\u0004\u001f\u00cb\b\u001f\u000b\u001f\f\u001f\u00cc"
+ "\u0001 \u0001 \u0001 \u0004 \u00d2\b \u000b \f \u00d3\u0001!\u0001!\u0001"
+ "!\u0005!\u00d9\b!\n!\f!\u00dc\t!\u0003!\u00de\b!\u0001!\u0001!\u0004!"
+ "\u00e2\b!\u000b!\f!\u00e3\u0003!\u00e6\b!\u0001!\u0001!\u0003!\u00ea\b"
+ "!\u0001!\u0004!\u00ed\b!\u000b!\f!\u00ee\u0003!\u00f1\b!\u0001\"\u0001"
+ "\"\u0001\"\u0005\"\u00f6\b\"\n\"\f\"\u00f9\t\"\u0003\"\u00fb\b\"\u0002"
+ "\u00b6\u00c2\u0000#\u0001\u0001\u0003\u0002\u0005\u0003\u0007\u0004\t"
+ "\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b\u0017\f"
+ "\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013\'\u0014"
+ ")\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u0000;\u0000"
+ "=\u0000?\u001dA\u001eC\u001fE\u0000\u0001\u0000#\u0001\u0000((\u0001\u0000"
+ "))\u0001\u0000,,\u0001\u0000!!\u0001\u0000~~\u0001\u0000**\u0001\u0000"
+ "//\u0001\u0000%%\u0001\u0000++\u0001\u0000--\u0001\u0000<<\u0001\u0000"
+ ">>\u0001\u0000&&\u0001\u0000^^\u0001\u0000||\u0001\u0000??\u0001\u0000"
+ "::\u0003\u0000\t\n\r\r \u0001\u0000..\u0001\u0000[[\u0001\u0000]]\u0004"
+ "\u0000$$AZ__az\u0005\u0000$$09AZ__az\u0001\u0000\'\'\u0002\u0000\'\'\\"
+ "\\\u0001\u0000\"\"\u0002\u0000\"\"\\\\\u0001\u000000\u0001\u000007\u0002"
+ "\u0000XXxx\u0003\u000009AFaf\u0001\u000009\u0002\u0000EEee\u0002\u0000"
+ "++--\u0001\u000019\u010f\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003"
+ "\u0001\u0000\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007"
+ "\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001"
+ "\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000"
+ "\u0000\u0000\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000"
+ "\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000"
+ "\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000"
+ "\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000"
+ "\u0000\u0000\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000"
+ "\u0000%\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000"
+ ")\u0001\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001"
+ "\u0000\u0000\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000"
+ "\u0000\u00003\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u0000"
+ "7\u0001\u0000\u0000\u0000\u0000?\u0001\u0000\u0000\u0000\u0000A\u0001"
+ "\u0000\u0000\u0000\u0000C\u0001\u0000\u0000\u0000\u0001G\u0001\u0000\u0000"
+ "\u0000\u0003I\u0001\u0000\u0000\u0000\u0005K\u0001\u0000\u0000\u0000\u0007"
+ "M\u0001\u0000\u0000\u0000\tO\u0001\u0000\u0000\u0000\u000bQ\u0001\u0000"
+ "\u0000\u0000\rS\u0001\u0000\u0000\u0000\u000fU\u0001\u0000\u0000\u0000"
+ "\u0011W\u0001\u0000\u0000\u0000\u0013Y\u0001\u0000\u0000\u0000\u0015["
+ "\u0001\u0000\u0000\u0000\u0017^\u0001\u0000\u0000\u0000\u0019a\u0001\u0000"
+ "\u0000\u0000\u001be\u0001\u0000\u0000\u0000\u001dg\u0001\u0000\u0000\u0000"
+ "\u001fj\u0001\u0000\u0000\u0000!l\u0001\u0000\u0000\u0000#o\u0001\u0000"
+ "\u0000\u0000%r\u0001\u0000\u0000\u0000\'u\u0001\u0000\u0000\u0000)w\u0001"
+ "\u0000\u0000\u0000+y\u0001\u0000\u0000\u0000-{\u0001\u0000\u0000\u0000"
+ "/~\u0001\u0000\u0000\u00001\u0081\u0001\u0000\u0000\u00003\u0083\u0001"
+ "\u0000\u0000\u00005\u0086\u0001\u0000\u0000\u00007\u008c\u0001\u0000\u0000"
+ "\u00009\u00a0\u0001\u0000\u0000\u0000;\u00a7\u0001\u0000\u0000\u0000="
+ "\u00c6\u0001\u0000\u0000\u0000?\u00c8\u0001\u0000\u0000\u0000A\u00ce\u0001"
+ "\u0000\u0000\u0000C\u00e5\u0001\u0000\u0000\u0000E\u00fa\u0001\u0000\u0000"
+ "\u0000GH\u0007\u0000\u0000\u0000H\u0002\u0001\u0000\u0000\u0000IJ\u0007"
+ "\u0001\u0000\u0000J\u0004\u0001\u0000\u0000\u0000KL\u0007\u0002\u0000"
+ "\u0000L\u0006\u0001\u0000\u0000\u0000MN\u0007\u0003\u0000\u0000N\b\u0001"
+ "\u0000\u0000\u0000OP\u0007\u0004\u0000\u0000P\n\u0001\u0000\u0000\u0000"
+ "QR\u0007\u0005\u0000\u0000R\f\u0001\u0000\u0000\u0000ST\u0007\u0006\u0000"
+ "\u0000T\u000e\u0001\u0000\u0000\u0000UV\u0007\u0007\u0000\u0000V\u0010"
+ "\u0001\u0000\u0000\u0000WX\u0007\b\u0000\u0000X\u0012\u0001\u0000\u0000"
+ "\u0000YZ\u0007\t\u0000\u0000Z\u0014\u0001\u0000\u0000\u0000[\\\u0005<"
+ "\u0000\u0000\\]\u0005<\u0000\u0000]\u0016\u0001\u0000\u0000\u0000^_\u0005"
+ ">\u0000\u0000_`\u0005>\u0000\u0000`\u0018\u0001\u0000\u0000\u0000ab\u0005"
+ ">\u0000\u0000bc\u0005>\u0000\u0000cd\u0005>\u0000\u0000d\u001a\u0001\u0000"
+ "\u0000\u0000ef\u0007\n\u0000\u0000f\u001c\u0001\u0000\u0000\u0000gh\u0005"
+ "<\u0000\u0000hi\u0005=\u0000\u0000i\u001e\u0001\u0000\u0000\u0000jk\u0007"
+ "\u000b\u0000\u0000k \u0001\u0000\u0000\u0000lm\u0005>\u0000\u0000mn\u0005"
+ "=\u0000\u0000n\"\u0001\u0000\u0000\u0000op\u0005=\u0000\u0000pq\u0005"
+ "=\u0000\u0000q$\u0001\u0000\u0000\u0000rs\u0005!\u0000\u0000st\u0005="
+ "\u0000\u0000t&\u0001\u0000\u0000\u0000uv\u0007\f\u0000\u0000v(\u0001\u0000"
+ "\u0000\u0000wx\u0007\r\u0000\u0000x*\u0001\u0000\u0000\u0000yz\u0007\u000e"
+ "\u0000\u0000z,\u0001\u0000\u0000\u0000{|\u0005&\u0000\u0000|}\u0005&\u0000"
+ "\u0000}.\u0001\u0000\u0000\u0000~\u007f\u0005|\u0000\u0000\u007f\u0080"
+ "\u0005|\u0000\u0000\u00800\u0001\u0000\u0000\u0000\u0081\u0082\u0007\u000f"
+ "\u0000\u0000\u00822\u0001\u0000\u0000\u0000\u0083\u0084\u0007\u0010\u0000"
+ "\u0000\u00844\u0001\u0000\u0000\u0000\u0085\u0087\u0007\u0011\u0000\u0000"
+ "\u0086\u0085\u0001\u0000\u0000\u0000\u0087\u0088\u0001\u0000\u0000\u0000"
+ "\u0088\u0086\u0001\u0000\u0000\u0000\u0088\u0089\u0001\u0000\u0000\u0000"
+ "\u0089\u008a\u0001\u0000\u0000\u0000\u008a\u008b\u0006\u001a\u0000\u0000"
+ "\u008b6\u0001\u0000\u0000\u0000\u008c\u0090\u0003;\u001d\u0000\u008d\u008f"
+ "\u00039\u001c\u0000\u008e\u008d\u0001\u0000\u0000\u0000\u008f\u0092\u0001"
+ "\u0000\u0000\u0000\u0090\u008e\u0001\u0000\u0000\u0000\u0090\u0091\u0001"
+ "\u0000\u0000\u0000\u0091\u009d\u0001\u0000\u0000\u0000\u0092\u0090\u0001"
+ "\u0000\u0000\u0000\u0093\u0094\u0007\u0012\u0000\u0000\u0094\u0098\u0003"
+ ";\u001d\u0000\u0095\u0097\u00039\u001c\u0000\u0096\u0095\u0001\u0000\u0000"
+ "\u0000\u0097\u009a\u0001\u0000\u0000\u0000\u0098\u0096\u0001\u0000\u0000"
+ "\u0000\u0098\u0099\u0001\u0000\u0000\u0000\u0099\u009c\u0001\u0000\u0000"
+ "\u0000\u009a\u0098\u0001\u0000\u0000\u0000\u009b\u0093\u0001\u0000\u0000"
+ "\u0000\u009c\u009f\u0001\u0000\u0000\u0000\u009d\u009b\u0001\u0000\u0000"
+ "\u0000\u009d\u009e\u0001\u0000\u0000\u0000\u009e8\u0001\u0000\u0000\u0000"
+ "\u009f\u009d\u0001\u0000\u0000\u0000\u00a0\u00a3\u0007\u0013\u0000\u0000"
+ "\u00a1\u00a4\u0003=\u001e\u0000\u00a2\u00a4\u0003E\"\u0000\u00a3\u00a1"
+ "\u0001\u0000\u0000\u0000\u00a3\u00a2\u0001\u0000\u0000\u0000\u00a4\u00a5"
+ "\u0001\u0000\u0000\u0000\u00a5\u00a6\u0007\u0014\u0000\u0000\u00a6:\u0001"
+ "\u0000\u0000\u0000\u00a7\u00ab\u0007\u0015\u0000\u0000\u00a8\u00aa\u0007"
+ "\u0016\u0000\u0000\u00a9\u00a8\u0001\u0000\u0000\u0000\u00aa\u00ad\u0001"
+ "\u0000\u0000\u0000\u00ab\u00a9\u0001\u0000\u0000\u0000\u00ab\u00ac\u0001"
+ "\u0000\u0000\u0000\u00ac<\u0001\u0000\u0000\u0000\u00ad\u00ab\u0001\u0000"
+ "\u0000\u0000\u00ae\u00b6\u0007\u0017\u0000\u0000\u00af\u00b0\u0005\\\u0000"
+ "\u0000\u00b0\u00b5\u0005\'\u0000\u0000\u00b1\u00b2\u0005\\\u0000\u0000"
+ "\u00b2\u00b5\u0005\\\u0000\u0000\u00b3\u00b5\b\u0018\u0000\u0000\u00b4"
+ "\u00af\u0001\u0000\u0000\u0000\u00b4\u00b1\u0001\u0000\u0000\u0000\u00b4"
+ "\u00b3\u0001\u0000\u0000\u0000\u00b5\u00b8\u0001\u0000\u0000\u0000\u00b6"
+ "\u00b7\u0001\u0000\u0000\u0000\u00b6\u00b4\u0001\u0000\u0000\u0000\u00b7"
+ "\u00b9\u0001\u0000\u0000\u0000\u00b8\u00b6\u0001\u0000\u0000\u0000\u00b9"
+ "\u00c7\u0007\u0017\u0000\u0000\u00ba\u00c2\u0007\u0019\u0000\u0000\u00bb"
+ "\u00bc\u0005\\\u0000\u0000\u00bc\u00c1\u0005\"\u0000\u0000\u00bd\u00be"
+ "\u0005\\\u0000\u0000\u00be\u00c1\u0005\\\u0000\u0000\u00bf\u00c1\b\u001a"
+ "\u0000\u0000\u00c0\u00bb\u0001\u0000\u0000\u0000\u00c0\u00bd\u0001\u0000"
+ "\u0000\u0000\u00c0\u00bf\u0001\u0000\u0000\u0000\u00c1\u00c4\u0001\u0000"
+ "\u0000\u0000\u00c2\u00c3\u0001\u0000\u0000\u0000\u00c2\u00c0\u0001\u0000"
+ "\u0000\u0000\u00c3\u00c5\u0001\u0000\u0000\u0000\u00c4\u00c2\u0001\u0000"
+ "\u0000\u0000\u00c5\u00c7\u0007\u0019\u0000\u0000\u00c6\u00ae\u0001\u0000"
+ "\u0000\u0000\u00c6\u00ba\u0001\u0000\u0000\u0000\u00c7>\u0001\u0000\u0000"
+ "\u0000\u00c8\u00ca\u0007\u001b\u0000\u0000\u00c9\u00cb\u0007\u001c\u0000"
+ "\u0000\u00ca\u00c9\u0001\u0000\u0000\u0000\u00cb\u00cc\u0001\u0000\u0000"
+ "\u0000\u00cc\u00ca\u0001\u0000\u0000\u0000\u00cc\u00cd\u0001\u0000\u0000"
+ "\u0000\u00cd@\u0001\u0000\u0000\u0000\u00ce\u00cf\u0007\u001b\u0000\u0000"
+ "\u00cf\u00d1\u0007\u001d\u0000\u0000\u00d0\u00d2\u0007\u001e\u0000\u0000"
+ "\u00d1\u00d0\u0001\u0000\u0000\u0000\u00d2\u00d3\u0001\u0000\u0000\u0000"
+ "\u00d3\u00d1\u0001\u0000\u0000\u0000\u00d3\u00d4\u0001\u0000\u0000\u0000"
+ "\u00d4B\u0001\u0000\u0000\u0000\u00d5\u00dd\u0003E\"\u0000\u00d6\u00da"
+ "\u0007\u0012\u0000\u0000\u00d7\u00d9\u0007\u001f\u0000\u0000\u00d8\u00d7"
+ "\u0001\u0000\u0000\u0000\u00d9\u00dc\u0001\u0000\u0000\u0000\u00da\u00d8"
+ "\u0001\u0000\u0000\u0000\u00da\u00db\u0001\u0000\u0000\u0000\u00db\u00de"
+ "\u0001\u0000\u0000\u0000\u00dc\u00da\u0001\u0000\u0000\u0000\u00dd\u00d6"
+ "\u0001\u0000\u0000\u0000\u00dd\u00de\u0001\u0000\u0000\u0000\u00de\u00e6"
+ "\u0001\u0000\u0000\u0000\u00df\u00e1\u0007\u0012\u0000\u0000\u00e0\u00e2"
+ "\u0007\u001f\u0000\u0000\u00e1\u00e0\u0001\u0000\u0000\u0000\u00e2\u00e3"
+ "\u0001\u0000\u0000\u0000\u00e3\u00e1\u0001\u0000\u0000\u0000\u00e3\u00e4"
+ "\u0001\u0000\u0000\u0000\u00e4\u00e6\u0001\u0000\u0000\u0000\u00e5\u00d5"
+ "\u0001\u0000\u0000\u0000\u00e5\u00df\u0001\u0000\u0000\u0000\u00e6\u00f0"
+ "\u0001\u0000\u0000\u0000\u00e7\u00e9\u0007 \u0000\u0000\u00e8\u00ea\u0007"
+ "!\u0000\u0000\u00e9\u00e8\u0001\u0000\u0000\u0000\u00e9\u00ea\u0001\u0000"
+ "\u0000\u0000\u00ea\u00ec\u0001\u0000\u0000\u0000\u00eb\u00ed\u0007\u001f"
+ "\u0000\u0000\u00ec\u00eb\u0001\u0000\u0000\u0000\u00ed\u00ee\u0001\u0000"
+ "\u0000\u0000\u00ee\u00ec\u0001\u0000\u0000\u0000\u00ee\u00ef\u0001\u0000"
+ "\u0000\u0000\u00ef\u00f1\u0001\u0000\u0000\u0000\u00f0\u00e7\u0001\u0000"
+ "\u0000\u0000\u00f0\u00f1\u0001\u0000\u0000\u0000\u00f1D\u0001\u0000\u0000"
+ "\u0000\u00f2\u00fb\u0007\u001b\u0000\u0000\u00f3\u00f7\u0007\"\u0000\u0000"
+ "\u00f4\u00f6\u0007\u001f\u0000\u0000\u00f5\u00f4\u0001\u0000\u0000\u0000"
+ "\u00f6\u00f9\u0001\u0000\u0000\u0000\u00f7\u00f5\u0001\u0000\u0000\u0000"
+ "\u00f7\u00f8\u0001\u0000\u0000\u0000\u00f8\u00fb\u0001\u0000\u0000\u0000"
+ "\u00f9\u00f7\u0001\u0000\u0000\u0000\u00fa\u00f2\u0001\u0000\u0000\u0000"
+ "\u00fa\u00f3\u0001\u0000\u0000\u0000\u00fbF\u0001\u0000\u0000\u0000\u0017"
+ "\u0000\u0088\u0090\u0098\u009d\u00a3\u00ab\u00b4\u00b6\u00c0\u00c2\u00c6"
+ "\u00cc\u00d3\u00da\u00dd\u00e3\u00e5\u00e9\u00ee\u00f0\u00f7\u00fa\u0001"
+ "\u0006\u0000\u0000";
public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -8,10 +8,10 @@ import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"})
class JavascriptParser extends Parser {
static {
RuntimeMetaData.checkVersion("4.5.1", RuntimeMetaData.VERSION);
RuntimeMetaData.checkVersion("4.11.1", RuntimeMetaData.VERSION);
}
protected static final DFA[] _decisionToDFA;
@ -48,46 +48,60 @@ class JavascriptParser extends Parser {
HEX = 30,
DECIMAL = 31;
public static final int RULE_compile = 0, RULE_expression = 1;
public static final String[] ruleNames = {"compile", "expression"};
private static final String[] _LITERAL_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, "'<<'", "'>>'", "'>>>'", null,
"'<='", null, "'>='", "'=='", "'!='", null, null, null, "'&&'", "'||'"
};
private static final String[] _SYMBOLIC_NAMES = {
null,
"LP",
"RP",
"COMMA",
"BOOLNOT",
"BWNOT",
"MUL",
"DIV",
"REM",
"ADD",
"SUB",
"LSH",
"RSH",
"USH",
"LT",
"LTE",
"GT",
"GTE",
"EQ",
"NE",
"BWAND",
"BWXOR",
"BWOR",
"BOOLAND",
"BOOLOR",
"COND",
"COLON",
"WS",
"VARIABLE",
"OCTAL",
"HEX",
"DECIMAL"
};
private static String[] makeRuleNames() {
return new String[] {"compile", "expression"};
}
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, null, null, null, null, null, null, null, null, null, null, "'<<'", "'>>'", "'>>>'",
null, "'<='", null, "'>='", "'=='", "'!='", null, null, null, "'&&'", "'||'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null,
"LP",
"RP",
"COMMA",
"BOOLNOT",
"BWNOT",
"MUL",
"DIV",
"REM",
"ADD",
"SUB",
"LSH",
"RSH",
"USH",
"LT",
"LTE",
"GT",
"GTE",
"EQ",
"NE",
"BWAND",
"BWXOR",
"BWOR",
"BOOLAND",
"BOOLOR",
"COND",
"COLON",
"WS",
"VARIABLE",
"OCTAL",
"HEX",
"DECIMAL"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
@ -122,7 +136,7 @@ class JavascriptParser extends Parser {
@Override
public String getGrammarFileName() {
return "Javascript.g4";
return "java-escape";
}
@Override
@ -145,6 +159,7 @@ class JavascriptParser extends Parser {
_interp = new ParserATNSimulator(this, _ATN, _decisionToDFA, _sharedContextCache);
}
@SuppressWarnings("CheckReturnValue")
public static class CompileContext extends ParserRuleContext {
public ExpressionContext expression() {
return getRuleContext(ExpressionContext.class, 0);
@ -192,6 +207,7 @@ class JavascriptParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class ExpressionContext extends ParserRuleContext {
public ExpressionContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
@ -209,6 +225,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class ConditionalContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -238,6 +255,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class BoolorContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -263,6 +281,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class BoolcompContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -300,6 +319,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class NumericContext extends ExpressionContext {
public TerminalNode OCTAL() {
return getToken(JavascriptParser.OCTAL, 0);
@ -325,6 +345,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class AddsubContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -354,6 +375,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class UnaryContext extends ExpressionContext {
public ExpressionContext expression() {
return getRuleContext(ExpressionContext.class, 0);
@ -387,6 +409,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class PrecedenceContext extends ExpressionContext {
public TerminalNode LP() {
return getToken(JavascriptParser.LP, 0);
@ -412,6 +435,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class MuldivContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -445,6 +469,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class ExternalContext extends ExpressionContext {
public TerminalNode VARIABLE() {
return getToken(JavascriptParser.VARIABLE, 0);
@ -486,6 +511,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class BwshiftContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -519,6 +545,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class BworContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -544,6 +571,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class BoolandContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -569,6 +597,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class BwxorContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -594,6 +623,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class BwandContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -619,6 +649,7 @@ class JavascriptParser extends Parser {
}
}
@SuppressWarnings("CheckReturnValue")
public static class BooleqneContext extends ExpressionContext {
public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
@ -665,39 +696,19 @@ class JavascriptParser extends Parser {
enterOuterAlt(_localctx, 1);
{
setState(30);
_errHandler.sync(this);
switch (_input.LA(1)) {
case BOOLNOT:
case BWNOT:
case ADD:
case SUB:
{
_localctx = new UnaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(8);
_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(9);
expression(12);
}
break;
case LP:
{
_localctx = new PrecedenceContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(10);
setState(8);
match(LP);
setState(11);
setState(9);
expression(0);
setState(12);
setState(10);
match(RP);
}
break;
@ -708,12 +719,13 @@ class JavascriptParser extends Parser {
_localctx = new NumericContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(14);
setState(12);
_la = _input.LA(1);
if (!((((_la) & ~0x3f) == 0
&& ((1L << _la) & ((1L << OCTAL) | (1L << HEX) | (1L << DECIMAL))) != 0))) {
if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 3758096384L) != 0)) {
_errHandler.recoverInline(this);
} else {
if (_input.LA(1) == Token.EOF) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
}
@ -723,57 +735,69 @@ class JavascriptParser extends Parser {
_localctx = new ExternalContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(15);
setState(13);
match(VARIABLE);
setState(28);
setState(26);
_errHandler.sync(this);
switch (getInterpreter().adaptivePredict(_input, 2, _ctx)) {
case 1:
{
setState(16);
setState(14);
match(LP);
setState(25);
setState(23);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0
&& ((1L << _la)
& ((1L << LP)
| (1L << BOOLNOT)
| (1L << BWNOT)
| (1L << ADD)
| (1L << SUB)
| (1L << VARIABLE)
| (1L << OCTAL)
| (1L << HEX)
| (1L << DECIMAL)))
!= 0)) {
if (((_la) & ~0x3f) == 0 && ((1L << _la) & 4026533426L) != 0) {
{
setState(17);
setState(15);
expression(0);
setState(22);
setState(20);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la == COMMA) {
{
{
setState(18);
setState(16);
match(COMMA);
setState(19);
setState(17);
expression(0);
}
}
setState(24);
setState(22);
_errHandler.sync(this);
_la = _input.LA(1);
}
}
}
setState(27);
setState(25);
match(RP);
}
break;
}
}
break;
case BOOLNOT:
case BWNOT:
case ADD:
case SUB:
{
_localctx = new UnaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(28);
_la = _input.LA(1);
if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 1584L) != 0)) {
_errHandler.recoverInline(this);
} else {
if (_input.LA(1) == Token.EOF) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
setState(29);
expression(12);
}
break;
default:
throw new NoViableAltException(this);
}
@ -787,6 +811,7 @@ class JavascriptParser extends Parser {
_prevctx = _localctx;
{
setState(68);
_errHandler.sync(this);
switch (getInterpreter().adaptivePredict(_input, 4, _ctx)) {
case 1:
{
@ -797,10 +822,11 @@ class JavascriptParser extends Parser {
throw new FailedPredicateException(this, "precpred(_ctx, 11)");
setState(33);
_la = _input.LA(1);
if (!((((_la) & ~0x3f) == 0
&& ((1L << _la) & ((1L << MUL) | (1L << DIV) | (1L << REM))) != 0))) {
if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 448L) != 0)) {
_errHandler.recoverInline(this);
} else {
if (_input.LA(1) == Token.EOF) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
setState(34);
@ -819,6 +845,8 @@ class JavascriptParser extends Parser {
if (!(_la == ADD || _la == SUB)) {
_errHandler.recoverInline(this);
} else {
if (_input.LA(1) == Token.EOF) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
setState(37);
@ -834,10 +862,11 @@ class JavascriptParser extends Parser {
throw new FailedPredicateException(this, "precpred(_ctx, 9)");
setState(39);
_la = _input.LA(1);
if (!((((_la) & ~0x3f) == 0
&& ((1L << _la) & ((1L << LSH) | (1L << RSH) | (1L << USH))) != 0))) {
if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 14336L) != 0)) {
_errHandler.recoverInline(this);
} else {
if (_input.LA(1) == Token.EOF) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
setState(40);
@ -854,11 +883,11 @@ class JavascriptParser extends Parser {
throw new FailedPredicateException(this, "precpred(_ctx, 8)");
setState(42);
_la = _input.LA(1);
if (!((((_la) & ~0x3f) == 0
&& ((1L << _la) & ((1L << LT) | (1L << LTE) | (1L << GT) | (1L << GTE)))
!= 0))) {
if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 245760L) != 0)) {
_errHandler.recoverInline(this);
} else {
if (_input.LA(1) == Token.EOF) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
setState(43);
@ -878,6 +907,8 @@ class JavascriptParser extends Parser {
if (!(_la == EQ || _la == NE)) {
_errHandler.recoverInline(this);
} else {
if (_input.LA(1) == Token.EOF) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
setState(46);
@ -1022,28 +1053,57 @@ class JavascriptParser extends Parser {
}
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3!L\4\2\t\2\4\3\t\3"
+ "\3\2\3\2\3\2\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\7\3\27"
+ "\n\3\f\3\16\3\32\13\3\5\3\34\n\3\3\3\5\3\37\n\3\5\3!\n\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\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\7\3G\n\3"
+ "\f\3\16\3J\13\3\3\3\2\3\4\4\2\4\2\t\4\2\6\7\13\f\3\2\37!\3\2\b\n\3\2\13"
+ "\f\3\2\r\17\3\2\20\23\3\2\24\25Z\2\6\3\2\2\2\4 \3\2\2\2\6\7\5\4\3\2\7"
+ "\b\7\2\2\3\b\3\3\2\2\2\t\n\b\3\1\2\n\13\t\2\2\2\13!\5\4\3\16\f\r\7\3\2"
+ "\2\r\16\5\4\3\2\16\17\7\4\2\2\17!\3\2\2\2\20!\t\3\2\2\21\36\7\36\2\2\22"
+ "\33\7\3\2\2\23\30\5\4\3\2\24\25\7\5\2\2\25\27\5\4\3\2\26\24\3\2\2\2\27"
+ "\32\3\2\2\2\30\26\3\2\2\2\30\31\3\2\2\2\31\34\3\2\2\2\32\30\3\2\2\2\33"
+ "\23\3\2\2\2\33\34\3\2\2\2\34\35\3\2\2\2\35\37\7\4\2\2\36\22\3\2\2\2\36"
+ "\37\3\2\2\2\37!\3\2\2\2 \t\3\2\2\2 \f\3\2\2\2 \20\3\2\2\2 \21\3\2\2\2"
+ "!H\3\2\2\2\"#\f\r\2\2#$\t\4\2\2$G\5\4\3\16%&\f\f\2\2&\'\t\5\2\2\'G\5\4"
+ "\3\r()\f\13\2\2)*\t\6\2\2*G\5\4\3\f+,\f\n\2\2,-\t\7\2\2-G\5\4\3\13./\f"
+ "\t\2\2/\60\t\b\2\2\60G\5\4\3\n\61\62\f\b\2\2\62\63\7\26\2\2\63G\5\4\3"
+ "\t\64\65\f\7\2\2\65\66\7\27\2\2\66G\5\4\3\b\678\f\6\2\289\7\30\2\29G\5"
+ "\4\3\7:;\f\5\2\2;<\7\31\2\2<G\5\4\3\6=>\f\4\2\2>?\7\32\2\2?G\5\4\3\5@"
+ "A\f\3\2\2AB\7\33\2\2BC\5\4\3\2CD\7\34\2\2DE\5\4\3\3EG\3\2\2\2F\"\3\2\2"
+ "\2F%\3\2\2\2F(\3\2\2\2F+\3\2\2\2F.\3\2\2\2F\61\3\2\2\2F\64\3\2\2\2F\67"
+ "\3\2\2\2F:\3\2\2\2F=\3\2\2\2F@\3\2\2\2GJ\3\2\2\2HF\3\2\2\2HI\3\2\2\2I"
+ "\5\3\2\2\2JH\3\2\2\2\b\30\33\36 FH";
"\u0004\u0001\u001fJ\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0001"
+ "\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001"
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"
+ "\u0001\u0001\u0001\u0005\u0001\u0013\b\u0001\n\u0001\f\u0001\u0016\t\u0001"
+ "\u0003\u0001\u0018\b\u0001\u0001\u0001\u0003\u0001\u001b\b\u0001\u0001"
+ "\u0001\u0001\u0001\u0003\u0001\u001f\b\u0001\u0001\u0001\u0001\u0001\u0001"
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0001E\b\u0001\n\u0001"
+ "\f\u0001H\t\u0001\u0001\u0001\u0000\u0001\u0002\u0002\u0000\u0002\u0000"
+ "\u0007\u0001\u0000\u001d\u001f\u0002\u0000\u0004\u0005\t\n\u0001\u0000"
+ "\u0006\b\u0001\u0000\t\n\u0001\u0000\u000b\r\u0001\u0000\u000e\u0011\u0001"
+ "\u0000\u0012\u0013X\u0000\u0004\u0001\u0000\u0000\u0000\u0002\u001e\u0001"
+ "\u0000\u0000\u0000\u0004\u0005\u0003\u0002\u0001\u0000\u0005\u0006\u0005"
+ "\u0000\u0000\u0001\u0006\u0001\u0001\u0000\u0000\u0000\u0007\b\u0006\u0001"
+ "\uffff\uffff\u0000\b\t\u0005\u0001\u0000\u0000\t\n\u0003\u0002\u0001\u0000"
+ "\n\u000b\u0005\u0002\u0000\u0000\u000b\u001f\u0001\u0000\u0000\u0000\f"
+ "\u001f\u0007\u0000\u0000\u0000\r\u001a\u0005\u001c\u0000\u0000\u000e\u0017"
+ "\u0005\u0001\u0000\u0000\u000f\u0014\u0003\u0002\u0001\u0000\u0010\u0011"
+ "\u0005\u0003\u0000\u0000\u0011\u0013\u0003\u0002\u0001\u0000\u0012\u0010"
+ "\u0001\u0000\u0000\u0000\u0013\u0016\u0001\u0000\u0000\u0000\u0014\u0012"
+ "\u0001\u0000\u0000\u0000\u0014\u0015\u0001\u0000\u0000\u0000\u0015\u0018"
+ "\u0001\u0000\u0000\u0000\u0016\u0014\u0001\u0000\u0000\u0000\u0017\u000f"
+ "\u0001\u0000\u0000\u0000\u0017\u0018\u0001\u0000\u0000\u0000\u0018\u0019"
+ "\u0001\u0000\u0000\u0000\u0019\u001b\u0005\u0002\u0000\u0000\u001a\u000e"
+ "\u0001\u0000\u0000\u0000\u001a\u001b\u0001\u0000\u0000\u0000\u001b\u001f"
+ "\u0001\u0000\u0000\u0000\u001c\u001d\u0007\u0001\u0000\u0000\u001d\u001f"
+ "\u0003\u0002\u0001\f\u001e\u0007\u0001\u0000\u0000\u0000\u001e\f\u0001"
+ "\u0000\u0000\u0000\u001e\r\u0001\u0000\u0000\u0000\u001e\u001c\u0001\u0000"
+ "\u0000\u0000\u001fF\u0001\u0000\u0000\u0000 !\n\u000b\u0000\u0000!\"\u0007"
+ "\u0002\u0000\u0000\"E\u0003\u0002\u0001\f#$\n\n\u0000\u0000$%\u0007\u0003"
+ "\u0000\u0000%E\u0003\u0002\u0001\u000b&\'\n\t\u0000\u0000\'(\u0007\u0004"
+ "\u0000\u0000(E\u0003\u0002\u0001\n)*\n\b\u0000\u0000*+\u0007\u0005\u0000"
+ "\u0000+E\u0003\u0002\u0001\t,-\n\u0007\u0000\u0000-.\u0007\u0006\u0000"
+ "\u0000.E\u0003\u0002\u0001\b/0\n\u0006\u0000\u000001\u0005\u0014\u0000"
+ "\u00001E\u0003\u0002\u0001\u000723\n\u0005\u0000\u000034\u0005\u0015\u0000"
+ "\u00004E\u0003\u0002\u0001\u000656\n\u0004\u0000\u000067\u0005\u0016\u0000"
+ "\u00007E\u0003\u0002\u0001\u000589\n\u0003\u0000\u00009:\u0005\u0017\u0000"
+ "\u0000:E\u0003\u0002\u0001\u0004;<\n\u0002\u0000\u0000<=\u0005\u0018\u0000"
+ "\u0000=E\u0003\u0002\u0001\u0003>?\n\u0001\u0000\u0000?@\u0005\u0019\u0000"
+ "\u0000@A\u0003\u0002\u0001\u0000AB\u0005\u001a\u0000\u0000BC\u0003\u0002"
+ "\u0001\u0001CE\u0001\u0000\u0000\u0000D \u0001\u0000\u0000\u0000D#\u0001"
+ "\u0000\u0000\u0000D&\u0001\u0000\u0000\u0000D)\u0001\u0000\u0000\u0000"
+ "D,\u0001\u0000\u0000\u0000D/\u0001\u0000\u0000\u0000D2\u0001\u0000\u0000"
+ "\u0000D5\u0001\u0000\u0000\u0000D8\u0001\u0000\u0000\u0000D;\u0001\u0000"
+ "\u0000\u0000D>\u0001\u0000\u0000\u0000EH\u0001\u0000\u0000\u0000FD\u0001"
+ "\u0000\u0000\u0000FG\u0001\u0000\u0000\u0000G\u0003\u0001\u0000\u0000"
+ "\u0000HF\u0001\u0000\u0000\u0000\u0006\u0014\u0017\u001a\u001eDF";
public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.lucene.expressions.js;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.Map;
import org.apache.lucene.expressions.Expression;
import org.apache.lucene.tests.util.LuceneTestCase;
/** Base class for testing JS compiler */
public abstract class CompilerTestCase extends LuceneTestCase {
/** compiles expression for sourceText with default functions list */
protected Expression compile(String sourceText) throws ParseException {
return compile(
sourceText,
JavascriptCompiler.DEFAULT_FUNCTIONS,
JavascriptCompiler.class.getClassLoader());
}
/** compiles expression for sourceText with custom functions list */
protected Expression compile(String sourceText, Map<String, Method> functions)
throws ParseException {
return compile(sourceText, functions, JavascriptCompiler.class.getClassLoader());
}
/** compiles expression for sourceText with custom functions list and parent classloader */
protected Expression compile(String sourceText, Map<String, Method> functions, ClassLoader parent)
throws ParseException {
return JavascriptCompiler.compile(sourceText, functions, parent, true);
}
}

View File

@ -24,14 +24,13 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.lucene.expressions.Expression;
import org.apache.lucene.tests.util.LuceneTestCase;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
/** Tests customing the function map */
public class TestCustomFunctions extends LuceneTestCase {
public class TestCustomFunctions extends CompilerTestCase {
private static double DELTA = 0.0000001;
/** empty list of methods */
@ -41,7 +40,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("sqrt(20)", functions, getClass().getClassLoader());
compile("sqrt(20)", functions);
});
assertEquals(
"Invalid expression 'sqrt(20)': Unrecognized function call (sqrt).", expected.getMessage());
@ -51,8 +50,7 @@ public class TestCustomFunctions extends LuceneTestCase {
/** using the default map explicitly */
public void testDefaultList() throws Exception {
Map<String, Method> functions = JavascriptCompiler.DEFAULT_FUNCTIONS;
Expression expr =
JavascriptCompiler.compile("sqrt(20)", functions, getClass().getClassLoader());
Expression expr = compile("sqrt(20)", functions);
assertEquals(Math.sqrt(20), expr.evaluate(null), DELTA);
}
@ -64,7 +62,7 @@ public class TestCustomFunctions extends LuceneTestCase {
public void testNoArgMethod() throws Exception {
Map<String, Method> functions = new HashMap<>();
functions.put("foo", getClass().getMethod("zeroArgMethod"));
Expression expr = JavascriptCompiler.compile("foo()", functions, getClass().getClassLoader());
Expression expr = compile("foo()", functions);
assertEquals(5, expr.evaluate(null), DELTA);
}
@ -76,7 +74,7 @@ public class TestCustomFunctions extends LuceneTestCase {
public void testOneArgMethod() throws Exception {
Map<String, Method> functions = new HashMap<>();
functions.put("foo", getClass().getMethod("oneArgMethod", double.class));
Expression expr = JavascriptCompiler.compile("foo(3)", functions, getClass().getClassLoader());
Expression expr = compile("foo(3)", functions);
assertEquals(6, expr.evaluate(null), DELTA);
}
@ -89,8 +87,7 @@ public class TestCustomFunctions extends LuceneTestCase {
Map<String, Method> functions = new HashMap<>();
functions.put(
"foo", getClass().getMethod("threeArgMethod", double.class, double.class, double.class));
Expression expr =
JavascriptCompiler.compile("foo(3, 4, 5)", functions, getClass().getClassLoader());
Expression expr = compile("foo(3, 4, 5)", functions);
assertEquals(12, expr.evaluate(null), DELTA);
}
@ -99,8 +96,7 @@ public class TestCustomFunctions extends LuceneTestCase {
Map<String, Method> functions = new HashMap<>();
functions.put("foo", getClass().getMethod("zeroArgMethod"));
functions.put("bar", getClass().getMethod("oneArgMethod", double.class));
Expression expr =
JavascriptCompiler.compile("foo() + bar(3)", functions, getClass().getClassLoader());
Expression expr = compile("foo() + bar(3)", functions);
assertEquals(11, expr.evaluate(null), DELTA);
}
@ -110,7 +106,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("method()");
compile("method()");
});
assertEquals(
"Invalid expression 'method()': Unrecognized function call (method).",
@ -121,7 +117,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("method.method(1)");
compile("method.method(1)");
});
assertEquals(
"Invalid expression 'method.method(1)': Unrecognized function call (method.method).",
@ -132,7 +128,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("1 + method()");
compile("1 + method()");
});
assertEquals(
"Invalid expression '1 + method()': Unrecognized function call (method).",
@ -152,7 +148,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
IllegalArgumentException.class,
() -> {
JavascriptCompiler.compile("foo()", functions, getClass().getClassLoader());
compile("foo()", functions);
});
assertTrue(expected.getMessage().contains("does not return a double"));
}
@ -169,7 +165,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
IllegalArgumentException.class,
() -> {
JavascriptCompiler.compile("foo(2)", functions, getClass().getClassLoader());
compile("foo(2)", functions);
});
assertTrue(expected.getMessage().contains("must take only double parameters"));
}
@ -186,7 +182,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
IllegalArgumentException.class,
() -> {
JavascriptCompiler.compile("foo()", functions, getClass().getClassLoader());
compile("foo()", functions);
});
assertTrue(expected.getMessage().contains("is not static"));
}
@ -203,7 +199,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
IllegalArgumentException.class,
() -> {
JavascriptCompiler.compile("foo()", functions, getClass().getClassLoader());
compile("foo()", functions);
});
assertTrue(expected.getMessage().contains("not public"));
}
@ -222,7 +218,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
IllegalArgumentException.class,
() -> {
JavascriptCompiler.compile("foo()", functions, getClass().getClassLoader());
compile("foo()", functions);
});
assertTrue(expected.getMessage().contains("not public"));
}
@ -289,7 +285,7 @@ public class TestCustomFunctions extends LuceneTestCase {
assertNotSame(thisLoader, barMethod.getDeclaringClass().getClassLoader());
// this should pass:
Expression expr = JavascriptCompiler.compile("bar()", functions, childLoader);
Expression expr = compile("bar()", functions, childLoader);
assertEquals(2.0, expr.evaluate(null), DELTA);
// use our classloader, not the foreign one, which should fail!
@ -297,7 +293,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
IllegalArgumentException.class,
() -> {
JavascriptCompiler.compile("bar()", functions, thisLoader);
compile("bar()", functions, thisLoader);
});
assertTrue(
expected
@ -308,9 +304,9 @@ public class TestCustomFunctions extends LuceneTestCase {
// mix foreign and default functions
Map<String, Method> mixedFunctions = new HashMap<>(JavascriptCompiler.DEFAULT_FUNCTIONS);
mixedFunctions.putAll(functions);
expr = JavascriptCompiler.compile("bar()", mixedFunctions, childLoader);
expr = compile("bar()", mixedFunctions, childLoader);
assertEquals(2.0, expr.evaluate(null), DELTA);
expr = JavascriptCompiler.compile("sqrt(20)", mixedFunctions, childLoader);
expr = compile("sqrt(20)", mixedFunctions, childLoader);
assertEquals(Math.sqrt(20), expr.evaluate(null), DELTA);
// use our classloader, not the foreign one, which should fail!
@ -318,7 +314,7 @@ public class TestCustomFunctions extends LuceneTestCase {
expectThrows(
IllegalArgumentException.class,
() -> {
JavascriptCompiler.compile("bar()", mixedFunctions, thisLoader);
compile("bar()", mixedFunctions, thisLoader);
});
assertTrue(
expected
@ -343,7 +339,7 @@ public class TestCustomFunctions extends LuceneTestCase {
Map<String, Method> functions = new HashMap<>();
functions.put("foo", StaticThrowingException.class.getMethod("method"));
String source = "3 * foo() / 5";
Expression expr = JavascriptCompiler.compile(source, functions, getClass().getClassLoader());
Expression expr = compile(source, functions);
ArithmeticException expected =
expectThrows(
ArithmeticException.class,
@ -364,7 +360,7 @@ public class TestCustomFunctions extends LuceneTestCase {
Map<String, Method> functions = new HashMap<>();
functions.put("foo.bar", getClass().getMethod("zeroArgMethod"));
String source = "foo.bar()";
Expression expr = JavascriptCompiler.compile(source, functions, getClass().getClassLoader());
Expression expr = compile(source, functions);
assertEquals(5, expr.evaluate(null), DELTA);
}
}

View File

@ -18,15 +18,43 @@ package org.apache.lucene.expressions.js;
import java.text.ParseException;
import org.apache.lucene.expressions.Expression;
import org.apache.lucene.tests.util.LuceneTestCase;
public class TestJavascriptCompiler extends LuceneTestCase {
public class TestJavascriptCompiler extends CompilerTestCase {
public void testNullExpression() throws Exception {
expectThrows(
NullPointerException.class,
() -> {
JavascriptCompiler.compile(null);
});
}
public void testNullFunctions() throws Exception {
expectThrows(
NullPointerException.class,
() -> {
JavascriptCompiler.compile("100", null, getClass().getClassLoader());
});
}
public void testNullLoader() throws Exception {
expectThrows(
NullPointerException.class,
() -> {
JavascriptCompiler.compile("100", JavascriptCompiler.DEFAULT_FUNCTIONS, null);
});
}
public void testEnormousExpressionSource() throws Exception {
String expr = " ".repeat(20000) + "100";
assertNotNull(compile(expr));
}
public void testValidCompiles() throws Exception {
assertNotNull(JavascriptCompiler.compile("100"));
assertNotNull(JavascriptCompiler.compile("valid0+100"));
assertNotNull(JavascriptCompiler.compile("valid0+\n100"));
assertNotNull(JavascriptCompiler.compile("logn(2, 20+10-5.0)"));
assertNotNull(compile("100"));
assertNotNull(compile("valid0+100"));
assertNotNull(compile("valid0+\n100"));
assertNotNull(compile("logn(2, 20+10-5.0)"));
}
public void testValidVariables() throws Exception {
@ -66,7 +94,7 @@ public class TestJavascriptCompiler extends LuceneTestCase {
}
void doTestValidVariable(String variable, String output) throws Exception {
Expression e = JavascriptCompiler.compile(variable);
Expression e = compile(variable);
assertNotNull(e);
assertEquals(1, e.variables.length);
assertEquals(output, e.variables[0]);
@ -93,7 +121,7 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile(variable);
compile(variable);
});
}
@ -102,7 +130,7 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("\n .");
compile("\n .");
});
assertTrue(expected.getMessage().contains("unexpected character '.' on line (2) position (1)"));
}
@ -111,31 +139,31 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("100 100");
compile("100 100");
});
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("7*/-8");
compile("7*/-8");
});
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("0y1234");
compile("0y1234");
});
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("500EE");
compile("500EE");
});
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("500.5EE");
compile("500.5EE");
});
}
@ -143,19 +171,19 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("");
compile("");
});
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("()");
compile("()");
});
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile(" \r\n \n \t");
compile(" \r\n \n \t");
});
}
@ -163,7 +191,7 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
NullPointerException.class,
() -> {
JavascriptCompiler.compile(null);
compile(null);
});
}
@ -172,7 +200,7 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("tan()");
compile("tan()");
fail();
});
assertEquals(
@ -184,7 +212,7 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("tan(1, 1)");
compile("tan(1, 1)");
});
assertTrue(expected.getMessage().contains("arguments for function call"));
@ -192,7 +220,7 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile(" tan()");
compile(" tan()");
});
assertEquals(
"Invalid expression ' tan()': Expected (1) arguments for function call (tan), but found (0).",
@ -203,7 +231,7 @@ public class TestJavascriptCompiler extends LuceneTestCase {
expectThrows(
ParseException.class,
() -> {
JavascriptCompiler.compile("1 + tan()");
compile("1 + tan()");
});
assertEquals(
"Invalid expression '1 + tan()': Expected (1) arguments for function call (tan), but found (0).",
@ -213,27 +241,27 @@ public class TestJavascriptCompiler extends LuceneTestCase {
public void testVariableNormalization() throws Exception {
// multiple double quotes
Expression x = JavascriptCompiler.compile("foo[\"a\"][\"b\"]");
Expression x = compile("foo[\"a\"][\"b\"]");
assertEquals("foo['a']['b']", x.variables[0]);
// single and double in the same var
x = JavascriptCompiler.compile("foo['a'][\"b\"]");
x = compile("foo['a'][\"b\"]");
assertEquals("foo['a']['b']", x.variables[0]);
// escapes remain the same in single quoted strings
x = JavascriptCompiler.compile("foo['\\\\\\'\"']");
x = compile("foo['\\\\\\'\"']");
assertEquals("foo['\\\\\\'\"']", x.variables[0]);
// single quotes are escaped
x = JavascriptCompiler.compile("foo[\"'\"]");
x = compile("foo[\"'\"]");
assertEquals("foo['\\'']", x.variables[0]);
// double quotes are unescaped
x = JavascriptCompiler.compile("foo[\"\\\"\"]");
x = compile("foo[\"\\\"\"]");
assertEquals("foo['\"']", x.variables[0]);
// backslash escapes are kept the same
x = JavascriptCompiler.compile("foo['\\\\'][\"\\\\\"]");
x = compile("foo['\\\\'][\"\\\\\"]");
assertEquals("foo['\\\\']['\\\\']", x.variables[0]);
}
}

View File

@ -17,13 +17,12 @@
package org.apache.lucene.expressions.js;
import org.apache.lucene.expressions.Expression;
import org.apache.lucene.tests.util.LuceneTestCase;
public class TestJavascriptFunction extends LuceneTestCase {
public class TestJavascriptFunction extends CompilerTestCase {
private static double DELTA = 0.0000001;
private void assertEvaluatesTo(String expression, double expected) throws Exception {
Expression evaluator = JavascriptCompiler.compile(expression);
Expression evaluator = compile(expression);
double actual = evaluator.evaluate(null);
assertEquals(expected, actual, DELTA);
}

View File

@ -17,11 +17,10 @@
package org.apache.lucene.expressions.js;
import org.apache.lucene.expressions.Expression;
import org.apache.lucene.tests.util.LuceneTestCase;
public class TestJavascriptOperations extends LuceneTestCase {
public class TestJavascriptOperations extends CompilerTestCase {
private void assertEvaluatesTo(String expression, long expected) throws Exception {
Expression evaluator = JavascriptCompiler.compile(expression);
Expression evaluator = compile(expression);
long actual = (long) evaluator.evaluate(null);
assertEquals(expected, actual);
}

View File

@ -0,0 +1 @@
069214c1de1960040729702eb58deac8827135e7

View File

@ -1 +0,0 @@
66144204f9d6d7d3f3f775622c2dd7e9bd511d97

View File

@ -8,7 +8,7 @@ io.sgr:s2-geometry-library-java:1.0.0 (1 constraints: 0305f035)
javax.servlet:javax.servlet-api:3.1.0 (2 constraints: 88129b22)
junit:junit:4.13.1 (1 constraints: 3b05453b)
net.sourceforge.nekohtml:nekohtml:1.9.17 (1 constraints: 4405503b)
org.antlr:antlr4-runtime:4.5.1-1 (1 constraints: 6a05b240)
org.antlr:antlr4-runtime:4.11.1 (1 constraints: 39053f3b)
org.apache.commons:commons-compress:1.19 (1 constraints: df04fa30)
org.apache.httpcomponents:httpclient:4.5.13 (1 constraints: 3f054e3b)
org.apache.httpcomponents:httpcore:4.4.13 (1 constraints: 591016a2)

View File

@ -8,7 +8,7 @@ io.sgr:s2-geometry-library-java=1.0.0
javax.servlet:javax.servlet-api=3.1.0
junit:junit=4.13.1
net.sourceforge.nekohtml:nekohtml=1.9.17
org.antlr:antlr4*=4.5.1-1
org.antlr:antlr4*=4.11.1
org.apache.commons:commons-compress=1.19
org.apache.httpcomponents:httpclient=4.5.13
org.apache.opennlp:opennlp-tools=1.9.1