Skip to content

Commit d522956

Browse files
Improve Painless compilation performance for nested conditionals (elastic#52056)
This PR changes how conditional expression is handled in `PainlessParser` in a way that avoids the need for backtracking, which led to exponential compilation times in case of nested conditionals. The test was added ensures that we can compile deeply nested conditionals. Co-authored-by: Elastic Machine <[email protected]>
1 parent 282e919 commit d522956

File tree

7 files changed

+961
-890
lines changed

7 files changed

+961
-890
lines changed

modules/lang-painless/src/main/antlr/PainlessParser.g4

+22-18
Original file line numberDiff line numberDiff line change
@@ -98,25 +98,29 @@ trap
9898
: CATCH LP TYPE ID RP block
9999
;
100100

101+
noncondexpression
102+
: unary # single
103+
| noncondexpression ( MUL | DIV | REM ) noncondexpression # binary
104+
| noncondexpression ( ADD | SUB ) noncondexpression # binary
105+
| noncondexpression ( FIND | MATCH ) noncondexpression # binary
106+
| noncondexpression ( LSH | RSH | USH ) noncondexpression # binary
107+
| noncondexpression ( LT | LTE | GT | GTE ) noncondexpression # comp
108+
| noncondexpression INSTANCEOF decltype # instanceof
109+
| noncondexpression ( EQ | EQR | NE | NER ) noncondexpression # comp
110+
| noncondexpression BWAND noncondexpression # binary
111+
| noncondexpression XOR noncondexpression # binary
112+
| noncondexpression BWOR noncondexpression # binary
113+
| noncondexpression BOOLAND noncondexpression # bool
114+
| noncondexpression BOOLOR noncondexpression # bool
115+
| <assoc=right> noncondexpression ELVIS noncondexpression # elvis
116+
;
117+
101118
expression
102-
: unary # single
103-
| expression ( MUL | DIV | REM ) expression # binary
104-
| expression ( ADD | SUB ) expression # binary
105-
| expression ( FIND | MATCH ) expression # binary
106-
| expression ( LSH | RSH | USH ) expression # binary
107-
| expression ( LT | LTE | GT | GTE ) expression # comp
108-
| expression INSTANCEOF decltype # instanceof
109-
| expression ( EQ | EQR | NE | NER ) expression # comp
110-
| expression BWAND expression # binary
111-
| expression XOR expression # binary
112-
| expression BWOR expression # binary
113-
| expression BOOLAND expression # bool
114-
| expression BOOLOR expression # bool
115-
| <assoc=right> expression COND expression COLON expression # conditional
116-
| <assoc=right> expression ELVIS expression # elvis
117-
| <assoc=right> expression ( ASSIGN | AADD | ASUB | AMUL |
118-
ADIV | AREM | AAND | AXOR |
119-
AOR | ALSH | ARSH | AUSH ) expression # assignment
119+
: noncondexpression # nonconditional
120+
| <assoc=right> noncondexpression COND expression COLON expression # conditional
121+
| <assoc=right> noncondexpression ( ASSIGN | AADD | ASUB | AMUL |
122+
ADIV | AREM | AAND | AXOR |
123+
AOR | ALSH | ARSH | AUSH ) expression # assignment
120124
;
121125

122126
unary

modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
// ANTLR GENERATED CODE: DO NOT EDIT
22
package org.elasticsearch.painless.antlr;
3-
4-
import org.antlr.v4.runtime.CharStream;
53
import org.antlr.v4.runtime.Lexer;
6-
import org.antlr.v4.runtime.RuleContext;
7-
import org.antlr.v4.runtime.RuntimeMetaData;
8-
import org.antlr.v4.runtime.Vocabulary;
9-
import org.antlr.v4.runtime.VocabularyImpl;
10-
import org.antlr.v4.runtime.atn.ATN;
11-
import org.antlr.v4.runtime.atn.ATNDeserializer;
12-
import org.antlr.v4.runtime.atn.LexerATNSimulator;
13-
import org.antlr.v4.runtime.atn.PredictionContextCache;
4+
import org.antlr.v4.runtime.CharStream;
5+
import org.antlr.v4.runtime.Token;
6+
import org.antlr.v4.runtime.TokenStream;
7+
import org.antlr.v4.runtime.*;
8+
import org.antlr.v4.runtime.atn.*;
149
import org.antlr.v4.runtime.dfa.DFA;
10+
import org.antlr.v4.runtime.misc.*;
1511

1612
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
1713
abstract class PainlessLexer extends Lexer {

0 commit comments

Comments
 (0)