IDEMPIERE-5367 Logic expression IN doesn't works with quoted text (#1423)

* IDEMPIERE-5367 Logic expression IN doesn't works with quoted text

* IDEMPIERE-5367 Logic expression IN doesn't works with quoted text

- Fixed equal not working for quoted text with comma (e.g 'A,R,S')
This commit is contained in:
hengsin 2022-08-05 19:21:50 +08:00 committed by GitHub
parent d78238b0f6
commit 5f8e7be3c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 319 additions and 101 deletions

View File

@ -0,0 +1 @@
Source generated with ANTLR 4 IDE for Eclipse, Antlr Tools 4.9.2 (antlr-4.9.2-complete.jar) and Generate parse tree visitor(-visitor) turn on.

View File

@ -13,7 +13,9 @@ expression
| left=expression op=binary right=expression #binaryExpression | left=expression op=binary right=expression #binaryExpression
| bool #boolExpression | bool #boolExpression
| VARIABLE #contextVariables | VARIABLE #contextVariables
| QCSVTEXT #quotedCSVText
| QTEXT #quotedText | QTEXT #quotedText
| DQCSVTEXT #doubleQuotedCSVText
| DQTEXT #doubleQuotedText | DQTEXT #doubleQuotedText
| TEXT #text | TEXT #text
| DECIMAL #decimalExpression | DECIMAL #decimalExpression
@ -47,7 +49,12 @@ LPAREN : '(' ;
RPAREN : ')' ; RPAREN : ')' ;
DECIMAL : '-'? [0-9]+ ( '.' [0-9]+ )? ; DECIMAL : '-'? [0-9]+ ( '.' [0-9]+ )? ;
VARIABLE : '@'(.*?)'@' ; VARIABLE : '@'(.*?)'@' ;
COMMA : ',' ;
QCOMMA : '\',' ;
QTEXT : ['](.*?)['] ; QTEXT : ['](.*?)['] ;
QCSVTEXT : [']~(['])*(QCOMMA)(QTEXT)(COMMA QTEXT)* ;
DQCOMMA : '",';
DQTEXT : ["](.*?)["] ; DQTEXT : ["](.*?)["] ;
DQCSVTEXT : ["]~(["])*(DQCOMMA)(DQTEXT)(COMMA DQTEXT)* ;
TEXT : [a-zA-Z_0-9,]+ ; TEXT : [a-zA-Z_0-9,]+ ;
WS : [ \r\t\u000C\n]+ -> skip; WS : [ \r\t\u000C\n]+ -> skip;

View File

@ -26,6 +26,8 @@ package org.idempiere.expression.logic;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -36,7 +38,9 @@ import org.idempiere.expression.logic.SimpleBooleanParser.BoolContext;
import org.idempiere.expression.logic.SimpleBooleanParser.ComparatorContext; import org.idempiere.expression.logic.SimpleBooleanParser.ComparatorContext;
import org.idempiere.expression.logic.SimpleBooleanParser.ComparatorExpressionContext; import org.idempiere.expression.logic.SimpleBooleanParser.ComparatorExpressionContext;
import org.idempiere.expression.logic.SimpleBooleanParser.ContextVariablesContext; import org.idempiere.expression.logic.SimpleBooleanParser.ContextVariablesContext;
import org.idempiere.expression.logic.SimpleBooleanParser.DoubleQuotedCSVTextContext;
import org.idempiere.expression.logic.SimpleBooleanParser.DoubleQuotedTextContext; import org.idempiere.expression.logic.SimpleBooleanParser.DoubleQuotedTextContext;
import org.idempiere.expression.logic.SimpleBooleanParser.QuotedCSVTextContext;
import org.idempiere.expression.logic.SimpleBooleanParser.QuotedTextContext; import org.idempiere.expression.logic.SimpleBooleanParser.QuotedTextContext;
import org.idempiere.expression.logic.SimpleBooleanParser.TextContext; import org.idempiere.expression.logic.SimpleBooleanParser.TextContext;
@ -63,13 +67,21 @@ public class EvaluationVisitor extends SimpleBooleanBaseVisitor<Object> {
return new BigDecimal(ctx.DECIMAL().getText()); return new BigDecimal(ctx.DECIMAL().getText());
} }
@Override
public Object visitQuotedCSVText(QuotedCSVTextContext ctx) {
return ctx.QCSVTEXT().getText();
}
@Override @Override
public Object visitQuotedText(QuotedTextContext ctx) { public Object visitQuotedText(QuotedTextContext ctx) {
return ctx.QTEXT().getText().replaceAll("[']", ""); return ctx.QTEXT().getText().replaceAll("[']", "");
} }
@Override
public Object visitDoubleQuotedCSVText(DoubleQuotedCSVTextContext ctx) {
return ctx.DQCSVTEXT().getText();
}
@Override @Override
public Object visitDoubleQuotedText(DoubleQuotedTextContext ctx) { public Object visitDoubleQuotedText(DoubleQuotedTextContext ctx) {
return ctx.DQTEXT().getText().replaceAll("[\"]", ""); return ctx.DQTEXT().getText().replaceAll("[\"]", "");
@ -142,9 +154,11 @@ public class EvaluationVisitor extends SimpleBooleanBaseVisitor<Object> {
return Boolean.TRUE; return Boolean.TRUE;
if (left == null || right == null) if (left == null || right == null)
return Boolean.FALSE; return Boolean.FALSE;
if (left instanceof String && right instanceof String && !(ctx.right.getText().startsWith("'") && !(ctx.right.getText().startsWith("\"")))) { if (left instanceof String && right instanceof String) {
String rightText = (String) right; String rightText = (String) right;
if (rightText.indexOf(",") > 0) { if (ctx.right.start.getType() == SimpleBooleanLexer.QCSVTEXT || ctx.right.start.getType() == SimpleBooleanLexer.DQCSVTEXT) {
return isIn((String)left, rightText);
} else if (ctx.right.start.getType() == SimpleBooleanLexer.TEXT && rightText.indexOf(",") > 0) {
return isIn((String)left, rightText); return isIn((String)left, rightText);
} }
} }
@ -173,11 +187,39 @@ public class EvaluationVisitor extends SimpleBooleanBaseVisitor<Object> {
} }
private Boolean isIn(String left, String rightText) { private Boolean isIn(String left, String rightText) {
String[] values = rightText.split("[,]"); List<String> values = new ArrayList<>();
char[] chars = rightText.toCharArray();
Character quote = null;
StringBuilder value = new StringBuilder();
for (char ec : chars) {
if (quote != null && quote.charValue() == ec) {
quote = null;
} if (ec == '"') {
if (quote == null) {
quote = Character.valueOf(ec);
} else {
value.append(ec);
}
} else if (ec == '\'') {
if (quote == null) {
quote = Character.valueOf(ec);
} else {
value.append(ec);
}
} else if (Character.isWhitespace(ec)) {
if (quote != null)
value.append(ec);
} else if (ec == ',') {
if (value.length() > 0)
values.add(value.toString());
value = new StringBuilder();
} else {
value.append(ec);
}
}
if (value.length() > 0)
values.add(value.toString());
for(String s : values) { for(String s : values) {
s = s.trim();
if ((s.startsWith("'") && s.endsWith("'")) || (s.startsWith("\"") && s.endsWith("\"")))
s = s.substring(1, s.length()-1);
if (left.equals(s)) if (left.equals(s))
return Boolean.TRUE; return Boolean.TRUE;
} }

View File

@ -16,6 +16,11 @@ null
')' ')'
null null
null null
','
'\','
null
null
'",'
null null
null null
null null
@ -39,8 +44,13 @@ LPAREN
RPAREN RPAREN
DECIMAL DECIMAL
VARIABLE VARIABLE
COMMA
QCOMMA
QTEXT QTEXT
QCSVTEXT
DQCOMMA
DQTEXT DQTEXT
DQCSVTEXT
TEXT TEXT
WS WS
@ -53,4 +63,4 @@ bool
atn: atn:
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 22, 50, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 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, 5, 3, 29, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 39, 10, 3, 12, 3, 14, 3, 42, 11, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 2, 3, 4, 7, 2, 4, 6, 8, 10, 2, 5, 3, 2, 8, 14, 3, 2, 3, 4, 3, 2, 6, 7, 2, 53, 2, 12, 3, 2, 2, 2, 4, 28, 3, 2, 2, 2, 6, 43, 3, 2, 2, 2, 8, 45, 3, 2, 2, 2, 10, 47, 3, 2, 2, 2, 12, 13, 5, 4, 3, 2, 13, 14, 7, 2, 2, 3, 14, 3, 3, 2, 2, 2, 15, 16, 8, 3, 1, 2, 16, 17, 7, 15, 2, 2, 17, 18, 5, 4, 3, 2, 18, 19, 7, 16, 2, 2, 19, 29, 3, 2, 2, 2, 20, 21, 7, 5, 2, 2, 21, 29, 5, 4, 3, 11, 22, 29, 5, 10, 6, 2, 23, 29, 7, 18, 2, 2, 24, 29, 7, 19, 2, 2, 25, 29, 7, 20, 2, 2, 26, 29, 7, 21, 2, 2, 27, 29, 7, 17, 2, 2, 28, 15, 3, 2, 2, 2, 28, 20, 3, 2, 2, 2, 28, 22, 3, 2, 2, 2, 28, 23, 3, 2, 2, 2, 28, 24, 3, 2, 2, 2, 28, 25, 3, 2, 2, 2, 28, 26, 3, 2, 2, 2, 28, 27, 3, 2, 2, 2, 29, 40, 3, 2, 2, 2, 30, 31, 12, 10, 2, 2, 31, 32, 5, 6, 4, 2, 32, 33, 5, 4, 3, 11, 33, 39, 3, 2, 2, 2, 34, 35, 12, 9, 2, 2, 35, 36, 5, 8, 5, 2, 36, 37, 5, 4, 3, 10, 37, 39, 3, 2, 2, 2, 38, 30, 3, 2, 2, 2, 38, 34, 3, 2, 2, 2, 39, 42, 3, 2, 2, 2, 40, 38, 3, 2, 2, 2, 40, 41, 3, 2, 2, 2, 41, 5, 3, 2, 2, 2, 42, 40, 3, 2, 2, 2, 43, 44, 9, 2, 2, 2, 44, 7, 3, 2, 2, 2, 45, 46, 9, 3, 2, 2, 46, 9, 3, 2, 2, 2, 47, 48, 9, 4, 2, 2, 48, 11, 3, 2, 2, 2, 5, 28, 38, 40] [3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 27, 52, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 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, 3, 3, 3, 3, 5, 3, 31, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 41, 10, 3, 12, 3, 14, 3, 44, 11, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 2, 3, 4, 7, 2, 4, 6, 8, 10, 2, 5, 3, 2, 8, 14, 3, 2, 3, 4, 3, 2, 6, 7, 2, 57, 2, 12, 3, 2, 2, 2, 4, 30, 3, 2, 2, 2, 6, 45, 3, 2, 2, 2, 8, 47, 3, 2, 2, 2, 10, 49, 3, 2, 2, 2, 12, 13, 5, 4, 3, 2, 13, 14, 7, 2, 2, 3, 14, 3, 3, 2, 2, 2, 15, 16, 8, 3, 1, 2, 16, 17, 7, 15, 2, 2, 17, 18, 5, 4, 3, 2, 18, 19, 7, 16, 2, 2, 19, 31, 3, 2, 2, 2, 20, 21, 7, 5, 2, 2, 21, 31, 5, 4, 3, 13, 22, 31, 5, 10, 6, 2, 23, 31, 7, 18, 2, 2, 24, 31, 7, 22, 2, 2, 25, 31, 7, 21, 2, 2, 26, 31, 7, 25, 2, 2, 27, 31, 7, 24, 2, 2, 28, 31, 7, 26, 2, 2, 29, 31, 7, 17, 2, 2, 30, 15, 3, 2, 2, 2, 30, 20, 3, 2, 2, 2, 30, 22, 3, 2, 2, 2, 30, 23, 3, 2, 2, 2, 30, 24, 3, 2, 2, 2, 30, 25, 3, 2, 2, 2, 30, 26, 3, 2, 2, 2, 30, 27, 3, 2, 2, 2, 30, 28, 3, 2, 2, 2, 30, 29, 3, 2, 2, 2, 31, 42, 3, 2, 2, 2, 32, 33, 12, 12, 2, 2, 33, 34, 5, 6, 4, 2, 34, 35, 5, 4, 3, 13, 35, 41, 3, 2, 2, 2, 36, 37, 12, 11, 2, 2, 37, 38, 5, 8, 5, 2, 38, 39, 5, 4, 3, 12, 39, 41, 3, 2, 2, 2, 40, 32, 3, 2, 2, 2, 40, 36, 3, 2, 2, 2, 41, 44, 3, 2, 2, 2, 42, 40, 3, 2, 2, 2, 42, 43, 3, 2, 2, 2, 43, 5, 3, 2, 2, 2, 44, 42, 3, 2, 2, 2, 45, 46, 9, 2, 2, 2, 46, 7, 3, 2, 2, 2, 47, 48, 9, 3, 2, 2, 48, 9, 3, 2, 2, 2, 49, 50, 9, 4, 2, 2, 50, 11, 3, 2, 2, 2, 5, 30, 40, 42]

View File

@ -14,10 +14,15 @@ LPAREN=13
RPAREN=14 RPAREN=14
DECIMAL=15 DECIMAL=15
VARIABLE=16 VARIABLE=16
QTEXT=17 COMMA=17
DQTEXT=18 QCOMMA=18
TEXT=19 QTEXT=19
WS=20 QCSVTEXT=20
DQCOMMA=21
DQTEXT=22
DQCSVTEXT=23
TEXT=24
WS=25
'&'=1 '&'=1
'|'=2 '|'=2
'$!'=3 '$!'=3
@ -31,3 +36,6 @@ WS=20
'~'=12 '~'=12
'('=13 '('=13
')'=14 ')'=14
','=17
'\','=18
'",'=21

View File

@ -41,6 +41,13 @@ public class SimpleBooleanBaseVisitor<T> extends AbstractParseTreeVisitor<T> imp
* {@link #visitChildren} on {@code ctx}.</p> * {@link #visitChildren} on {@code ctx}.</p>
*/ */
@Override public T visitBoolExpression(SimpleBooleanParser.BoolExpressionContext ctx) { return visitChildren(ctx); } @Override public T visitBoolExpression(SimpleBooleanParser.BoolExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDoubleQuotedCSVText(SimpleBooleanParser.DoubleQuotedCSVTextContext ctx) { return visitChildren(ctx); }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *
@ -48,6 +55,13 @@ public class SimpleBooleanBaseVisitor<T> extends AbstractParseTreeVisitor<T> imp
* {@link #visitChildren} on {@code ctx}.</p> * {@link #visitChildren} on {@code ctx}.</p>
*/ */
@Override public T visitContextVariables(SimpleBooleanParser.ContextVariablesContext ctx) { return visitChildren(ctx); } @Override public T visitContextVariables(SimpleBooleanParser.ContextVariablesContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitQuotedCSVText(SimpleBooleanParser.QuotedCSVTextContext ctx) { return visitChildren(ctx); }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *

File diff suppressed because one or more lines are too long

View File

@ -20,8 +20,8 @@ public class SimpleBooleanLexer extends Lexer {
new PredictionContextCache(); new PredictionContextCache();
public static final int public static final int
AND=1, OR=2, NOT=3, TRUE=4, FALSE=5, GT=6, GE=7, LT=8, LE=9, EQ=10, NE=11, AND=1, OR=2, NOT=3, TRUE=4, FALSE=5, GT=6, GE=7, LT=8, LE=9, EQ=10, NE=11,
RE=12, LPAREN=13, RPAREN=14, DECIMAL=15, VARIABLE=16, QTEXT=17, DQTEXT=18, RE=12, LPAREN=13, RPAREN=14, DECIMAL=15, VARIABLE=16, COMMA=17, QCOMMA=18,
TEXT=19, WS=20; QTEXT=19, QCSVTEXT=20, DQCOMMA=21, DQTEXT=22, DQCSVTEXT=23, TEXT=24, WS=25;
public static String[] channelNames = { public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN" "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
}; };
@ -33,8 +33,8 @@ public class SimpleBooleanLexer extends Lexer {
private static String[] makeRuleNames() { private static String[] makeRuleNames() {
return new String[] { return new String[] {
"AND", "OR", "NOT", "TRUE", "FALSE", "GT", "GE", "LT", "LE", "EQ", "NE", "AND", "OR", "NOT", "TRUE", "FALSE", "GT", "GE", "LT", "LE", "EQ", "NE",
"RE", "LPAREN", "RPAREN", "DECIMAL", "VARIABLE", "QTEXT", "DQTEXT", "TEXT", "RE", "LPAREN", "RPAREN", "DECIMAL", "VARIABLE", "COMMA", "QCOMMA", "QTEXT",
"WS" "QCSVTEXT", "DQCOMMA", "DQTEXT", "DQCSVTEXT", "TEXT", "WS"
}; };
} }
public static final String[] ruleNames = makeRuleNames(); public static final String[] ruleNames = makeRuleNames();
@ -42,15 +42,16 @@ public class SimpleBooleanLexer extends Lexer {
private static String[] makeLiteralNames() { private static String[] makeLiteralNames() {
return new String[] { return new String[] {
null, "'&'", "'|'", "'$!'", "'true'", "'false'", "'>'", "'>='", "'<'", null, "'&'", "'|'", "'$!'", "'true'", "'false'", "'>'", "'>='", "'<'",
"'<='", "'='", null, "'~'", "'('", "')'" "'<='", "'='", null, "'~'", "'('", "')'", null, null, "','", "'','",
null, null, "'\",'"
}; };
} }
private static final String[] _LITERAL_NAMES = makeLiteralNames(); private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() { private static String[] makeSymbolicNames() {
return new String[] { return new String[] {
null, "AND", "OR", "NOT", "TRUE", "FALSE", "GT", "GE", "LT", "LE", "EQ", null, "AND", "OR", "NOT", "TRUE", "FALSE", "GT", "GE", "LT", "LE", "EQ",
"NE", "RE", "LPAREN", "RPAREN", "DECIMAL", "VARIABLE", "QTEXT", "DQTEXT", "NE", "RE", "LPAREN", "RPAREN", "DECIMAL", "VARIABLE", "COMMA", "QCOMMA",
"TEXT", "WS" "QTEXT", "QCSVTEXT", "DQCOMMA", "DQTEXT", "DQCSVTEXT", "TEXT", "WS"
}; };
} }
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@ -112,43 +113,65 @@ public class SimpleBooleanLexer extends Lexer {
public ATN getATN() { return _ATN; } public ATN getATN() { return _ATN; }
public static final String _serializedATN = public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\26\u0088\b\1\4\2"+ "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\33\u00bc\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"+ "\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"+ "\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\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\5\3"+ "\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"+
"\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\b\3\b\3\b\3\t\3\t\3\n"+ "\t\31\4\32\t\32\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\6\3"+
"\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\5\20S\n\20"+ "\6\3\6\3\6\3\6\3\6\3\7\3\7\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3"+
"\3\20\6\20V\n\20\r\20\16\20W\3\20\3\20\6\20\\\n\20\r\20\16\20]\5\20`\n"+ "\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\5\20]\n\20\3\20\6\20`\n\20\r\20"+
"\20\3\21\3\21\7\21d\n\21\f\21\16\21g\13\21\3\21\3\21\3\22\3\22\7\22m\n"+ "\16\20a\3\20\3\20\6\20f\n\20\r\20\16\20g\5\20j\n\20\3\21\3\21\7\21n\n"+
"\22\f\22\16\22p\13\22\3\22\3\22\3\23\3\23\7\23v\n\23\f\23\16\23y\13\23"+ "\21\f\21\16\21q\13\21\3\21\3\21\3\22\3\22\3\23\3\23\3\23\3\24\3\24\7\24"+
"\3\23\3\23\3\24\6\24~\n\24\r\24\16\24\177\3\25\6\25\u0083\n\25\r\25\16"+ "|\n\24\f\24\16\24\177\13\24\3\24\3\24\3\25\3\25\7\25\u0085\n\25\f\25\16"+
"\25\u0084\3\25\3\25\5enw\2\26\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13"+ "\25\u0088\13\25\3\25\3\25\3\25\3\25\3\25\7\25\u008f\n\25\f\25\16\25\u0092"+
"\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26\3\2\b\4\2##``"+ "\13\25\3\26\3\26\3\26\3\27\3\27\7\27\u0099\n\27\f\27\16\27\u009c\13\27"+
"\3\2\62;\3\2))\3\2$$\7\2..\62;C\\aac|\5\2\13\f\16\17\"\"\2\u0090\2\3\3"+ "\3\27\3\27\3\30\3\30\7\30\u00a2\n\30\f\30\16\30\u00a5\13\30\3\30\3\30"+
"\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"+ "\3\30\3\30\3\30\7\30\u00ac\n\30\f\30\16\30\u00af\13\30\3\31\6\31\u00b2"+
"\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"+ "\n\31\r\31\16\31\u00b3\3\32\6\32\u00b7\n\32\r\32\16\32\u00b8\3\32\3\32"+
"\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"+ "\5o}\u009a\2\33\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31"+
"%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\3+\3\2\2\2\5-\3\2\2\2\7/\3\2\2\2\t\62"+ "\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\3\2"+
"\3\2\2\2\13\67\3\2\2\2\r=\3\2\2\2\17?\3\2\2\2\21B\3\2\2\2\23D\3\2\2\2"+ "\b\4\2##``\3\2\62;\3\2))\3\2$$\7\2..\62;C\\aac|\5\2\13\f\16\17\"\"\2\u00c8"+
"\25G\3\2\2\2\27I\3\2\2\2\31K\3\2\2\2\33M\3\2\2\2\35O\3\2\2\2\37R\3\2\2"+ "\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!a\3\2\2\2#j\3\2\2\2%s\3\2\2\2\'}\3\2\2\2)\u0082\3\2\2\2+,\7(\2\2,\4"+ "\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"+
"\3\2\2\2-.\7~\2\2.\6\3\2\2\2/\60\7&\2\2\60\61\7#\2\2\61\b\3\2\2\2\62\63"+ "\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"+
"\7v\2\2\63\64\7t\2\2\64\65\7w\2\2\65\66\7g\2\2\66\n\3\2\2\2\678\7h\2\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"+
"89\7c\2\29:\7n\2\2:;\7u\2\2;<\7g\2\2<\f\3\2\2\2=>\7@\2\2>\16\3\2\2\2?"+ "\2\2\61\3\2\2\2\2\63\3\2\2\2\3\65\3\2\2\2\5\67\3\2\2\2\79\3\2\2\2\t<\3"+
"@\7@\2\2@A\7?\2\2A\20\3\2\2\2BC\7>\2\2C\22\3\2\2\2DE\7>\2\2EF\7?\2\2F"+ "\2\2\2\13A\3\2\2\2\rG\3\2\2\2\17I\3\2\2\2\21L\3\2\2\2\23N\3\2\2\2\25Q"+
"\24\3\2\2\2GH\7?\2\2H\26\3\2\2\2IJ\t\2\2\2J\30\3\2\2\2KL\7\u0080\2\2L"+ "\3\2\2\2\27S\3\2\2\2\31U\3\2\2\2\33W\3\2\2\2\35Y\3\2\2\2\37\\\3\2\2\2"+
"\32\3\2\2\2MN\7*\2\2N\34\3\2\2\2OP\7+\2\2P\36\3\2\2\2QS\7/\2\2RQ\3\2\2"+ "!k\3\2\2\2#t\3\2\2\2%v\3\2\2\2\'y\3\2\2\2)\u0082\3\2\2\2+\u0093\3\2\2"+
"\2RS\3\2\2\2SU\3\2\2\2TV\t\3\2\2UT\3\2\2\2VW\3\2\2\2WU\3\2\2\2WX\3\2\2"+ "\2-\u0096\3\2\2\2/\u009f\3\2\2\2\61\u00b1\3\2\2\2\63\u00b6\3\2\2\2\65"+
"\2X_\3\2\2\2Y[\7\60\2\2Z\\\t\3\2\2[Z\3\2\2\2\\]\3\2\2\2][\3\2\2\2]^\3"+ "\66\7(\2\2\66\4\3\2\2\2\678\7~\2\28\6\3\2\2\29:\7&\2\2:;\7#\2\2;\b\3\2"+
"\2\2\2^`\3\2\2\2_Y\3\2\2\2_`\3\2\2\2` \3\2\2\2ae\7B\2\2bd\13\2\2\2cb\3"+ "\2\2<=\7v\2\2=>\7t\2\2>?\7w\2\2?@\7g\2\2@\n\3\2\2\2AB\7h\2\2BC\7c\2\2"+
"\2\2\2dg\3\2\2\2ef\3\2\2\2ec\3\2\2\2fh\3\2\2\2ge\3\2\2\2hi\7B\2\2i\"\3"+ "CD\7n\2\2DE\7u\2\2EF\7g\2\2F\f\3\2\2\2GH\7@\2\2H\16\3\2\2\2IJ\7@\2\2J"+
"\2\2\2jn\t\4\2\2km\13\2\2\2lk\3\2\2\2mp\3\2\2\2no\3\2\2\2nl\3\2\2\2oq"+ "K\7?\2\2K\20\3\2\2\2LM\7>\2\2M\22\3\2\2\2NO\7>\2\2OP\7?\2\2P\24\3\2\2"+
"\3\2\2\2pn\3\2\2\2qr\t\4\2\2r$\3\2\2\2sw\t\5\2\2tv\13\2\2\2ut\3\2\2\2"+ "\2QR\7?\2\2R\26\3\2\2\2ST\t\2\2\2T\30\3\2\2\2UV\7\u0080\2\2V\32\3\2\2"+
"vy\3\2\2\2wx\3\2\2\2wu\3\2\2\2xz\3\2\2\2yw\3\2\2\2z{\t\5\2\2{&\3\2\2\2"+ "\2WX\7*\2\2X\34\3\2\2\2YZ\7+\2\2Z\36\3\2\2\2[]\7/\2\2\\[\3\2\2\2\\]\3"+
"|~\t\6\2\2}|\3\2\2\2~\177\3\2\2\2\177}\3\2\2\2\177\u0080\3\2\2\2\u0080"+ "\2\2\2]_\3\2\2\2^`\t\3\2\2_^\3\2\2\2`a\3\2\2\2a_\3\2\2\2ab\3\2\2\2bi\3"+
"(\3\2\2\2\u0081\u0083\t\7\2\2\u0082\u0081\3\2\2\2\u0083\u0084\3\2\2\2"+ "\2\2\2ce\7\60\2\2df\t\3\2\2ed\3\2\2\2fg\3\2\2\2ge\3\2\2\2gh\3\2\2\2hj"+
"\u0084\u0082\3\2\2\2\u0084\u0085\3\2\2\2\u0085\u0086\3\2\2\2\u0086\u0087"+ "\3\2\2\2ic\3\2\2\2ij\3\2\2\2j \3\2\2\2ko\7B\2\2ln\13\2\2\2ml\3\2\2\2n"+
"\b\25\2\2\u0087*\3\2\2\2\f\2RW]_enw\177\u0084\3\b\2\2"; "q\3\2\2\2op\3\2\2\2om\3\2\2\2pr\3\2\2\2qo\3\2\2\2rs\7B\2\2s\"\3\2\2\2"+
"tu\7.\2\2u$\3\2\2\2vw\7)\2\2wx\7.\2\2x&\3\2\2\2y}\t\4\2\2z|\13\2\2\2{"+
"z\3\2\2\2|\177\3\2\2\2}~\3\2\2\2}{\3\2\2\2~\u0080\3\2\2\2\177}\3\2\2\2"+
"\u0080\u0081\t\4\2\2\u0081(\3\2\2\2\u0082\u0086\t\4\2\2\u0083\u0085\n"+
"\4\2\2\u0084\u0083\3\2\2\2\u0085\u0088\3\2\2\2\u0086\u0084\3\2\2\2\u0086"+
"\u0087\3\2\2\2\u0087\u0089\3\2\2\2\u0088\u0086\3\2\2\2\u0089\u008a\5%"+
"\23\2\u008a\u0090\5\'\24\2\u008b\u008c\5#\22\2\u008c\u008d\5\'\24\2\u008d"+
"\u008f\3\2\2\2\u008e\u008b\3\2\2\2\u008f\u0092\3\2\2\2\u0090\u008e\3\2"+
"\2\2\u0090\u0091\3\2\2\2\u0091*\3\2\2\2\u0092\u0090\3\2\2\2\u0093\u0094"+
"\7$\2\2\u0094\u0095\7.\2\2\u0095,\3\2\2\2\u0096\u009a\t\5\2\2\u0097\u0099"+
"\13\2\2\2\u0098\u0097\3\2\2\2\u0099\u009c\3\2\2\2\u009a\u009b\3\2\2\2"+
"\u009a\u0098\3\2\2\2\u009b\u009d\3\2\2\2\u009c\u009a\3\2\2\2\u009d\u009e"+
"\t\5\2\2\u009e.\3\2\2\2\u009f\u00a3\t\5\2\2\u00a0\u00a2\n\5\2\2\u00a1"+
"\u00a0\3\2\2\2\u00a2\u00a5\3\2\2\2\u00a3\u00a1\3\2\2\2\u00a3\u00a4\3\2"+
"\2\2\u00a4\u00a6\3\2\2\2\u00a5\u00a3\3\2\2\2\u00a6\u00a7\5+\26\2\u00a7"+
"\u00ad\5-\27\2\u00a8\u00a9\5#\22\2\u00a9\u00aa\5-\27\2\u00aa\u00ac\3\2"+
"\2\2\u00ab\u00a8\3\2\2\2\u00ac\u00af\3\2\2\2\u00ad\u00ab\3\2\2\2\u00ad"+
"\u00ae\3\2\2\2\u00ae\60\3\2\2\2\u00af\u00ad\3\2\2\2\u00b0\u00b2\t\6\2"+
"\2\u00b1\u00b0\3\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\u00b1\3\2\2\2\u00b3\u00b4"+
"\3\2\2\2\u00b4\62\3\2\2\2\u00b5\u00b7\t\7\2\2\u00b6\u00b5\3\2\2\2\u00b7"+
"\u00b8\3\2\2\2\u00b8\u00b6\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9\u00ba\3\2"+
"\2\2\u00ba\u00bb\b\32\2\2\u00bb\64\3\2\2\2\20\2\\agio}\u0086\u0090\u009a"+
"\u00a3\u00ad\u00b3\u00b8\3\b\2\2";
public static final ATN _ATN = public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray()); new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static { static {

View File

@ -14,10 +14,15 @@ LPAREN=13
RPAREN=14 RPAREN=14
DECIMAL=15 DECIMAL=15
VARIABLE=16 VARIABLE=16
QTEXT=17 COMMA=17
DQTEXT=18 QCOMMA=18
TEXT=19 QTEXT=19
WS=20 QCSVTEXT=20
DQCOMMA=21
DQTEXT=22
DQCSVTEXT=23
TEXT=24
WS=25
'&'=1 '&'=1
'|'=2 '|'=2
'$!'=3 '$!'=3
@ -31,3 +36,6 @@ WS=20
'~'=12 '~'=12
'('=13 '('=13
')'=14 ')'=14
','=17
'\','=18
'",'=21

View File

@ -20,8 +20,8 @@ public class SimpleBooleanParser extends Parser {
new PredictionContextCache(); new PredictionContextCache();
public static final int public static final int
AND=1, OR=2, NOT=3, TRUE=4, FALSE=5, GT=6, GE=7, LT=8, LE=9, EQ=10, NE=11, AND=1, OR=2, NOT=3, TRUE=4, FALSE=5, GT=6, GE=7, LT=8, LE=9, EQ=10, NE=11,
RE=12, LPAREN=13, RPAREN=14, DECIMAL=15, VARIABLE=16, QTEXT=17, DQTEXT=18, RE=12, LPAREN=13, RPAREN=14, DECIMAL=15, VARIABLE=16, COMMA=17, QCOMMA=18,
TEXT=19, WS=20; QTEXT=19, QCSVTEXT=20, DQCOMMA=21, DQTEXT=22, DQCSVTEXT=23, TEXT=24, WS=25;
public static final int public static final int
RULE_parse = 0, RULE_expression = 1, RULE_comparator = 2, RULE_binary = 3, RULE_parse = 0, RULE_expression = 1, RULE_comparator = 2, RULE_binary = 3,
RULE_bool = 4; RULE_bool = 4;
@ -35,15 +35,16 @@ public class SimpleBooleanParser extends Parser {
private static String[] makeLiteralNames() { private static String[] makeLiteralNames() {
return new String[] { return new String[] {
null, "'&'", "'|'", "'$!'", "'true'", "'false'", "'>'", "'>='", "'<'", null, "'&'", "'|'", "'$!'", "'true'", "'false'", "'>'", "'>='", "'<'",
"'<='", "'='", null, "'~'", "'('", "')'" "'<='", "'='", null, "'~'", "'('", "')'", null, null, "','", "'','",
null, null, "'\",'"
}; };
} }
private static final String[] _LITERAL_NAMES = makeLiteralNames(); private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() { private static String[] makeSymbolicNames() {
return new String[] { return new String[] {
null, "AND", "OR", "NOT", "TRUE", "FALSE", "GT", "GE", "LT", "LE", "EQ", null, "AND", "OR", "NOT", "TRUE", "FALSE", "GT", "GE", "LT", "LE", "EQ",
"NE", "RE", "LPAREN", "RPAREN", "DECIMAL", "VARIABLE", "QTEXT", "DQTEXT", "NE", "RE", "LPAREN", "RPAREN", "DECIMAL", "VARIABLE", "COMMA", "QCOMMA",
"TEXT", "WS" "QTEXT", "QCSVTEXT", "DQCOMMA", "DQTEXT", "DQCSVTEXT", "TEXT", "WS"
}; };
} }
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@ -187,6 +188,15 @@ public class SimpleBooleanParser extends Parser {
else return visitor.visitChildren(this); else return visitor.visitChildren(this);
} }
} }
public static class DoubleQuotedCSVTextContext extends ExpressionContext {
public TerminalNode DQCSVTEXT() { return getToken(SimpleBooleanParser.DQCSVTEXT, 0); }
public DoubleQuotedCSVTextContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitDoubleQuotedCSVText(this);
else return visitor.visitChildren(this);
}
}
public static class ContextVariablesContext extends ExpressionContext { public static class ContextVariablesContext extends ExpressionContext {
public TerminalNode VARIABLE() { return getToken(SimpleBooleanParser.VARIABLE, 0); } public TerminalNode VARIABLE() { return getToken(SimpleBooleanParser.VARIABLE, 0); }
public ContextVariablesContext(ExpressionContext ctx) { copyFrom(ctx); } public ContextVariablesContext(ExpressionContext ctx) { copyFrom(ctx); }
@ -196,6 +206,15 @@ public class SimpleBooleanParser extends Parser {
else return visitor.visitChildren(this); else return visitor.visitChildren(this);
} }
} }
public static class QuotedCSVTextContext extends ExpressionContext {
public TerminalNode QCSVTEXT() { return getToken(SimpleBooleanParser.QCSVTEXT, 0); }
public QuotedCSVTextContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitQuotedCSVText(this);
else return visitor.visitChildren(this);
}
}
public static class NotExpressionContext extends ExpressionContext { public static class NotExpressionContext extends ExpressionContext {
public TerminalNode NOT() { return getToken(SimpleBooleanParser.NOT, 0); } public TerminalNode NOT() { return getToken(SimpleBooleanParser.NOT, 0); }
public ExpressionContext expression() { public ExpressionContext expression() {
@ -284,7 +303,7 @@ public class SimpleBooleanParser extends Parser {
int _alt; int _alt;
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(26); setState(28);
_errHandler.sync(this); _errHandler.sync(this);
switch (_input.LA(1)) { switch (_input.LA(1)) {
case LPAREN: case LPAREN:
@ -309,7 +328,7 @@ public class SimpleBooleanParser extends Parser {
setState(18); setState(18);
match(NOT); match(NOT);
setState(19); setState(19);
expression(9); expression(11);
} }
break; break;
case TRUE: case TRUE:
@ -331,21 +350,39 @@ public class SimpleBooleanParser extends Parser {
match(VARIABLE); match(VARIABLE);
} }
break; break;
case QCSVTEXT:
{
_localctx = new QuotedCSVTextContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(22);
match(QCSVTEXT);
}
break;
case QTEXT: case QTEXT:
{ {
_localctx = new QuotedTextContext(_localctx); _localctx = new QuotedTextContext(_localctx);
_ctx = _localctx; _ctx = _localctx;
_prevctx = _localctx; _prevctx = _localctx;
setState(22); setState(23);
match(QTEXT); match(QTEXT);
} }
break; break;
case DQCSVTEXT:
{
_localctx = new DoubleQuotedCSVTextContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(24);
match(DQCSVTEXT);
}
break;
case DQTEXT: case DQTEXT:
{ {
_localctx = new DoubleQuotedTextContext(_localctx); _localctx = new DoubleQuotedTextContext(_localctx);
_ctx = _localctx; _ctx = _localctx;
_prevctx = _localctx; _prevctx = _localctx;
setState(23); setState(25);
match(DQTEXT); match(DQTEXT);
} }
break; break;
@ -354,7 +391,7 @@ public class SimpleBooleanParser extends Parser {
_localctx = new TextContext(_localctx); _localctx = new TextContext(_localctx);
_ctx = _localctx; _ctx = _localctx;
_prevctx = _localctx; _prevctx = _localctx;
setState(24); setState(26);
match(TEXT); match(TEXT);
} }
break; break;
@ -363,7 +400,7 @@ public class SimpleBooleanParser extends Parser {
_localctx = new DecimalExpressionContext(_localctx); _localctx = new DecimalExpressionContext(_localctx);
_ctx = _localctx; _ctx = _localctx;
_prevctx = _localctx; _prevctx = _localctx;
setState(25); setState(27);
match(DECIMAL); match(DECIMAL);
} }
break; break;
@ -371,7 +408,7 @@ public class SimpleBooleanParser extends Parser {
throw new NoViableAltException(this); throw new NoViableAltException(this);
} }
_ctx.stop = _input.LT(-1); _ctx.stop = _input.LT(-1);
setState(38); setState(40);
_errHandler.sync(this); _errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,2,_ctx); _alt = getInterpreter().adaptivePredict(_input,2,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@ -379,7 +416,7 @@ public class SimpleBooleanParser extends Parser {
if ( _parseListeners!=null ) triggerExitRuleEvent(); if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx; _prevctx = _localctx;
{ {
setState(36); setState(38);
_errHandler.sync(this); _errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) { switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) {
case 1: case 1:
@ -387,12 +424,12 @@ public class SimpleBooleanParser extends Parser {
_localctx = new ComparatorExpressionContext(new ExpressionContext(_parentctx, _parentState)); _localctx = new ComparatorExpressionContext(new ExpressionContext(_parentctx, _parentState));
((ComparatorExpressionContext)_localctx).left = _prevctx; ((ComparatorExpressionContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression); pushNewRecursionContext(_localctx, _startState, RULE_expression);
setState(28);
if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
setState(29);
((ComparatorExpressionContext)_localctx).op = comparator();
setState(30); setState(30);
((ComparatorExpressionContext)_localctx).right = expression(9); if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)");
setState(31);
((ComparatorExpressionContext)_localctx).op = comparator();
setState(32);
((ComparatorExpressionContext)_localctx).right = expression(11);
} }
break; break;
case 2: case 2:
@ -400,18 +437,18 @@ public class SimpleBooleanParser extends Parser {
_localctx = new BinaryExpressionContext(new ExpressionContext(_parentctx, _parentState)); _localctx = new BinaryExpressionContext(new ExpressionContext(_parentctx, _parentState));
((BinaryExpressionContext)_localctx).left = _prevctx; ((BinaryExpressionContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression); pushNewRecursionContext(_localctx, _startState, RULE_expression);
setState(32);
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
setState(33);
((BinaryExpressionContext)_localctx).op = binary();
setState(34); setState(34);
((BinaryExpressionContext)_localctx).right = expression(8); if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)");
setState(35);
((BinaryExpressionContext)_localctx).op = binary();
setState(36);
((BinaryExpressionContext)_localctx).right = expression(10);
} }
break; break;
} }
} }
} }
setState(40); setState(42);
_errHandler.sync(this); _errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,2,_ctx); _alt = getInterpreter().adaptivePredict(_input,2,_ctx);
} }
@ -454,7 +491,7 @@ public class SimpleBooleanParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(41); setState(43);
_la = _input.LA(1); _la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << GT) | (1L << GE) | (1L << LT) | (1L << LE) | (1L << EQ) | (1L << NE) | (1L << RE))) != 0)) ) { if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << GT) | (1L << GE) | (1L << LT) | (1L << LE) | (1L << EQ) | (1L << NE) | (1L << RE))) != 0)) ) {
_errHandler.recoverInline(this); _errHandler.recoverInline(this);
@ -498,7 +535,7 @@ public class SimpleBooleanParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(43); setState(45);
_la = _input.LA(1); _la = _input.LA(1);
if ( !(_la==AND || _la==OR) ) { if ( !(_la==AND || _la==OR) ) {
_errHandler.recoverInline(this); _errHandler.recoverInline(this);
@ -542,7 +579,7 @@ public class SimpleBooleanParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(45); setState(47);
_la = _input.LA(1); _la = _input.LA(1);
if ( !(_la==TRUE || _la==FALSE) ) { if ( !(_la==TRUE || _la==FALSE) ) {
_errHandler.recoverInline(this); _errHandler.recoverInline(this);
@ -575,28 +612,29 @@ public class SimpleBooleanParser extends Parser {
private boolean expression_sempred(ExpressionContext _localctx, int predIndex) { private boolean expression_sempred(ExpressionContext _localctx, int predIndex) {
switch (predIndex) { switch (predIndex) {
case 0: case 0:
return precpred(_ctx, 8); return precpred(_ctx, 10);
case 1: case 1:
return precpred(_ctx, 7); return precpred(_ctx, 9);
} }
return true; return true;
} }
public static final String _serializedATN = public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\26\62\4\2\t\2\4\3"+ "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\33\64\4\2\t\2\4\3"+
"\t\3\4\4\t\4\4\5\t\5\4\6\t\6\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"+ "\t\3\4\4\t\4\4\5\t\5\4\6\t\6\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\5\3\35\n\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\7\3"+ "\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\5\3\37\n\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"+
"\'\n\3\f\3\16\3*\13\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6\2\3\4\7\2\4\6\b\n\2"+ "\3\3\7\3)\n\3\f\3\16\3,\13\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6\2\3\4\7\2\4\6"+
"\5\3\2\b\16\3\2\3\4\3\2\6\7\2\65\2\f\3\2\2\2\4\34\3\2\2\2\6+\3\2\2\2\b"+ "\b\n\2\5\3\2\b\16\3\2\3\4\3\2\6\7\29\2\f\3\2\2\2\4\36\3\2\2\2\6-\3\2\2"+
"-\3\2\2\2\n/\3\2\2\2\f\r\5\4\3\2\r\16\7\2\2\3\16\3\3\2\2\2\17\20\b\3\1"+ "\2\b/\3\2\2\2\n\61\3\2\2\2\f\r\5\4\3\2\r\16\7\2\2\3\16\3\3\2\2\2\17\20"+
"\2\20\21\7\17\2\2\21\22\5\4\3\2\22\23\7\20\2\2\23\35\3\2\2\2\24\25\7\5"+ "\b\3\1\2\20\21\7\17\2\2\21\22\5\4\3\2\22\23\7\20\2\2\23\37\3\2\2\2\24"+
"\2\2\25\35\5\4\3\13\26\35\5\n\6\2\27\35\7\22\2\2\30\35\7\23\2\2\31\35"+ "\25\7\5\2\2\25\37\5\4\3\r\26\37\5\n\6\2\27\37\7\22\2\2\30\37\7\26\2\2"+
"\7\24\2\2\32\35\7\25\2\2\33\35\7\21\2\2\34\17\3\2\2\2\34\24\3\2\2\2\34"+ "\31\37\7\25\2\2\32\37\7\31\2\2\33\37\7\30\2\2\34\37\7\32\2\2\35\37\7\21"+
"\26\3\2\2\2\34\27\3\2\2\2\34\30\3\2\2\2\34\31\3\2\2\2\34\32\3\2\2\2\34"+ "\2\2\36\17\3\2\2\2\36\24\3\2\2\2\36\26\3\2\2\2\36\27\3\2\2\2\36\30\3\2"+
"\33\3\2\2\2\35(\3\2\2\2\36\37\f\n\2\2\37 \5\6\4\2 !\5\4\3\13!\'\3\2\2"+ "\2\2\36\31\3\2\2\2\36\32\3\2\2\2\36\33\3\2\2\2\36\34\3\2\2\2\36\35\3\2"+
"\2\"#\f\t\2\2#$\5\b\5\2$%\5\4\3\n%\'\3\2\2\2&\36\3\2\2\2&\"\3\2\2\2\'"+ "\2\2\37*\3\2\2\2 !\f\f\2\2!\"\5\6\4\2\"#\5\4\3\r#)\3\2\2\2$%\f\13\2\2"+
"*\3\2\2\2(&\3\2\2\2()\3\2\2\2)\5\3\2\2\2*(\3\2\2\2+,\t\2\2\2,\7\3\2\2"+ "%&\5\b\5\2&\'\5\4\3\f\')\3\2\2\2( \3\2\2\2($\3\2\2\2),\3\2\2\2*(\3\2\2"+
"\2-.\t\3\2\2.\t\3\2\2\2/\60\t\4\2\2\60\13\3\2\2\2\5\34&("; "\2*+\3\2\2\2+\5\3\2\2\2,*\3\2\2\2-.\t\2\2\2.\7\3\2\2\2/\60\t\3\2\2\60"+
"\t\3\2\2\2\61\62\t\4\2\2\62\13\3\2\2\2\5\36(*";
public static final ATN _ATN = public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray()); new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static { static {

View File

@ -39,6 +39,13 @@ public interface SimpleBooleanVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result * @return the visitor result
*/ */
T visitBoolExpression(SimpleBooleanParser.BoolExpressionContext ctx); T visitBoolExpression(SimpleBooleanParser.BoolExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code doubleQuotedCSVText}
* labeled alternative in {@link SimpleBooleanParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDoubleQuotedCSVText(SimpleBooleanParser.DoubleQuotedCSVTextContext ctx);
/** /**
* Visit a parse tree produced by the {@code contextVariables} * Visit a parse tree produced by the {@code contextVariables}
* labeled alternative in {@link SimpleBooleanParser#expression}. * labeled alternative in {@link SimpleBooleanParser#expression}.
@ -46,6 +53,13 @@ public interface SimpleBooleanVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result * @return the visitor result
*/ */
T visitContextVariables(SimpleBooleanParser.ContextVariablesContext ctx); T visitContextVariables(SimpleBooleanParser.ContextVariablesContext ctx);
/**
* Visit a parse tree produced by the {@code quotedCSVText}
* labeled alternative in {@link SimpleBooleanParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitQuotedCSVText(SimpleBooleanParser.QuotedCSVTextContext ctx);
/** /**
* Visit a parse tree produced by the {@code notExpression} * Visit a parse tree produced by the {@code notExpression}
* labeled alternative in {@link SimpleBooleanParser#expression}. * labeled alternative in {@link SimpleBooleanParser#expression}.

View File

@ -96,6 +96,15 @@ public class LogicExpressionTest extends AbstractTestCase {
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr)); assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
Env.setContext(Env.getCtx(), "$Element_AY", "N"); Env.setContext(Env.getCtx(), "$Element_AY", "N");
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr)); assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
expr = "@LineType@=\"C\"&@CalculationType@='A,R,S'";
Env.setContext(Env.getCtx(), "LineType", "C");
Env.setContext(Env.getCtx(), "CalculationType", "B");
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
Env.setContext(Env.getCtx(), "CalculationType", "A");
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
Env.setContext(Env.getCtx(), "CalculationType", "A,R,S");
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
} }
@Test @Test
@ -129,6 +138,35 @@ public class LogicExpressionTest extends AbstractTestCase {
@Test @Test
public void testIn() { public void testIn() {
String expr = "@LineType@=C&@CalculationType@=A,R,S"; String expr = "@LineType@=C&@CalculationType@=A,R,S";
testInARS(expr);
expr = "@LineType@='C'&@CalculationType@='A','R','S'";
testInARS(expr);
expr = "@LineType@=\"C\"&@CalculationType@=\"A\",\"R\",\"S\"";
testInARS(expr);
expr = "@Name@='Name 1','Name 2','Name 3'";
testInName123(expr);
expr = "@Name@=\"Name 1\",\"Name 2\",\"Name 3\"";
testInName123(expr);
}
private void testInName123(String expr) {
Env.setContext(Env.getCtx(), "Name", (String)null);
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
Env.setContext(Env.getCtx(), "Name", "Name 2");
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
Env.setContext(Env.getCtx(), "Name", "Name 4");
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
Env.setContext(Env.getCtx(), "Name", (String)null);
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
Env.setContext(Env.getCtx(), "Name", "Name 2");
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
Env.setContext(Env.getCtx(), "Name", "Name 4");
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
}
private void testInARS(String expr) {
Env.setContext(Env.getCtx(), "LineType", (String)null); Env.setContext(Env.getCtx(), "LineType", (String)null);
Env.setContext(Env.getCtx(), "CalculationType", (String)null); Env.setContext(Env.getCtx(), "CalculationType", (String)null);
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr)); assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));