77import org .antlr .v4 .runtime .CommonToken ;
88import org .antlr .v4 .runtime .Token ;
99import org .antlr .v4 .runtime .tree .ParseTree ;
10+ import org .antlr .v4 .runtime .tree .TerminalNodeImpl ;
1011import org .apache .commons .lang3 .StringUtils ;
1112import com .github .sidhant92 .boolparser .constant .FunctionType ;
1213import com .github .sidhant92 .boolparser .constant .DataType ;
@@ -50,80 +51,28 @@ public Node getNode() {
5051
5152 @ Override
5253 public void exitComparatorExpression (BooleanExpressionParser .ComparatorExpressionContext ctx ) {
53- final String variableName = getField (ctx .left .getText ());
54- final Operator operator = Operator .getOperatorFromSymbol (ctx .op .getText ()).orElse (Operator .EQUALS );
55- /*if ((ctx.right instanceof BooleanExpressionParser.ParentExpressionContext || ctx.right instanceof BooleanExpressionParser.ArithmeticFunctionExpressionContext) && !currentNodes.isEmpty()) {
56- final Node value = currentNodes.pop();
57- currentNodes.add(new ComparisonNode(variableName, value, operator, DataType.INTEGER));
58- } else {
59- final DataType dataType = getDataType(ctx.right.getStart());
60- currentNodes.add(new ComparisonNode(variableName, ValueUtils.convertValue(ctx.right.getText(), dataType), operator, dataType));
61- }*/
62- if (!(ctx .right instanceof BooleanExpressionParser .TypesExpressionContext ) && !currentNodes .isEmpty ()) {
63- final Node value = currentNodes .pop ();
64- currentNodes .add (new ComparisonNode (variableName , value , operator , DataType .INTEGER ));
65- } else {
66- final DataType dataType = getDataType (ctx .right .getStart ());
67- currentNodes .add (new ComparisonNode (variableName , ValueUtils .convertValue (ctx .right .getText (), dataType ), operator , dataType ));
68- }
54+ currentNodes .add (mapComparatorExpressionContext (ctx ));
6955 super .enterComparatorExpression (ctx );
7056 }
7157
72- private UnaryNode getUnaryNode (final BooleanExpressionParser .TypesExpressionContext ctx ) {
73- final DataType dataType = getDataType (ctx .getStart ());
74- final Object operand = ValueUtils .convertValue (ctx .getText (), dataType );
75- return UnaryNode .builder ().value (operand ).dataType (dataType ).build ();
76- }
77-
7858 @ Override
7959 public void exitArithmeticExpression (BooleanExpressionParser .ArithmeticExpressionContext ctx ) {
80- final Operator operator = Operator .getOperatorFromSymbol (ctx .op .getText ()).orElse (Operator .EQUALS );
81- if (ctx .left instanceof BooleanExpressionParser .TypesExpressionContext && ctx .right instanceof BooleanExpressionParser .TypesExpressionContext ) {
82- final UnaryNode left = getUnaryNode ((BooleanExpressionParser .TypesExpressionContext ) ctx .left );
83- final UnaryNode right = getUnaryNode ((BooleanExpressionParser .TypesExpressionContext ) ctx .right );
84- final ArithmeticNode node = ArithmeticNode .builder ().left (left ).right (right ).operator (operator ).build ();
85- currentNodes .add (node );
86- } else if (ctx .left instanceof BooleanExpressionParser .TypesExpressionContext ) {
87- final UnaryNode left = getUnaryNode ((BooleanExpressionParser .TypesExpressionContext ) ctx .left );
88- final Node right = currentNodes .pop ();
89- final ArithmeticNode node = ArithmeticNode .builder ().left (left ).right (right ).operator (operator ).build ();
90- currentNodes .add (node );
91- } else if (ctx .right instanceof BooleanExpressionParser .TypesExpressionContext ) {
92- final UnaryNode right = getUnaryNode ((BooleanExpressionParser .TypesExpressionContext ) ctx .right );
93- final Node left = currentNodes .pop ();
94- final ArithmeticNode node = ArithmeticNode .builder ().left (left ).right (right ).operator (operator ).build ();
95- currentNodes .add (node );
96- } else {
97- if (currentNodes .size () < 2 ) {
98- log .error ("Error parsing expression for the string {}" , ctx .getText ());
99- throw new InvalidExpressionException ();
100- }
101- final Node right = currentNodes .pop ();
102- final Node left = currentNodes .pop ();
103- final ArithmeticNode node = ArithmeticNode .builder ().left (left ).right (right ).operator (operator ).build ();
104- currentNodes .add (node );
105- }
60+ currentNodes .add (mapArithmeticExpressionContext (ctx ));
10661 super .exitArithmeticExpression (ctx );
10762 }
10863
10964 @ Override
11065 public void exitUnaryArithmeticExpression (BooleanExpressionParser .UnaryArithmeticExpressionContext ctx ) {
11166 final DataType dataType = getDataType (ctx .exp .getStart ());
11267 final Object operand = ValueUtils .convertValue (ctx .exp .getText (), dataType );
113- final UnaryNode leafNode = UnaryNode .builder ().value (operand ).dataType (dataType ).build ();
68+ final Node leafNode = ! currentNodes . isEmpty () ? currentNodes . pop () : UnaryNode .builder ().value (operand ).dataType (dataType ).build ();
11469 currentNodes .add (ArithmeticNode .builder ().left (leafNode ).operator (Operator .UNARY ).build ());
11570 super .enterUnaryArithmeticExpression (ctx );
11671 }
11772
11873 @ Override
11974 public void exitToExpression (BooleanExpressionParser .ToExpressionContext ctx ) {
120- validateField (ctx .field , ctx .getText ());
121- final String field = getField (ctx .field .getText ());
122- final DataType lowerDataType = getDataType (ctx .lower .start );
123- final Object lowerValue = ValueUtils .convertValue (ctx .lower .start .getText (), lowerDataType );
124- final DataType upperDataType = getDataType (ctx .upper .start );
125- final Object upperValue = ValueUtils .convertValue (ctx .upper .getText (), upperDataType );
126- currentNodes .add (new NumericRangeNode (field , lowerValue , upperValue , lowerDataType , upperDataType ));
75+ currentNodes .add (mapToExpressionContext (ctx ));
12776 super .exitToExpression (ctx );
12877 }
12978
@@ -139,6 +88,51 @@ public void exitArrayExpression(BooleanExpressionParser.ArrayExpressionContext c
13988
14089 @ Override
14190 public void exitArithmeticFunctionExpression (BooleanExpressionParser .ArithmeticFunctionExpressionContext ctx ) {
91+ final Node node = mapArithmeticFunctionExpressionContext (ctx );
92+ currentNodes .add (node );
93+ super .exitArithmeticFunctionExpression (ctx );
94+ }
95+
96+ @ Override
97+ public void exitInExpression (BooleanExpressionParser .InExpressionContext ctx ) {
98+ currentNodes .add (mapInExpressionContext (ctx ));
99+ super .exitInExpression (ctx );
100+ }
101+
102+ private List <Node > getArrayElements (final List <ParseTree > trees ) {
103+ return trees
104+ .stream ()
105+ .filter (child -> !(child instanceof TerminalNodeImpl ))
106+ .map (this ::mapContextToNode )
107+ .collect (Collectors .toList ());
108+ }
109+
110+ private Node mapContextToNode (final ParseTree ctx ) {
111+ if (ctx instanceof BooleanExpressionParser .ArithmeticExpressionContext ) {
112+ return mapArithmeticExpressionContext ((BooleanExpressionParser .ArithmeticExpressionContext ) ctx );
113+ } else if (ctx instanceof BooleanExpressionParser .InExpressionContext ) {
114+ return mapInExpressionContext ((BooleanExpressionParser .InExpressionContext ) ctx );
115+ } else if (ctx instanceof BooleanExpressionParser .ArithmeticFunctionExpressionContext ) {
116+ return mapArithmeticFunctionExpressionContext ((BooleanExpressionParser .ArithmeticFunctionExpressionContext ) ctx );
117+ } else if (ctx instanceof BooleanExpressionParser .ComparatorExpressionContext ) {
118+ return mapComparatorExpressionContext ((BooleanExpressionParser .ComparatorExpressionContext ) ctx );
119+ } else if (ctx instanceof BooleanExpressionParser .ToExpressionContext ) {
120+ return mapToExpressionContext ((BooleanExpressionParser .ToExpressionContext ) ctx );
121+ } else if (ctx instanceof BooleanExpressionParser .TypesExpressionContext ) {
122+ return mapTypesExpressionContext ((BooleanExpressionParser .TypesExpressionContext ) ctx );
123+ } else {
124+ log .error ("Array does not support this expression {}" , ctx .getText ());
125+ throw new InvalidExpressionException ();
126+ }
127+ }
128+
129+ private UnaryNode mapTypesExpressionContext (BooleanExpressionParser .TypesExpressionContext ctx ) {
130+ final DataType dataType = getDataType (ctx .start );
131+ final Object value = ValueUtils .convertValue (ctx .getText (), dataType );
132+ return new UnaryNode (dataType , value );
133+ }
134+
135+ private ArithmeticFunctionNode mapArithmeticFunctionExpressionContext (BooleanExpressionParser .ArithmeticFunctionExpressionContext ctx ) {
142136 if (ctx .data .exception != null ) {
143137 log .error ("Error parsing expression for the string {}" , ctx .getText ());
144138 throw new InvalidExpressionException ();
@@ -148,35 +142,66 @@ public void exitArithmeticFunctionExpression(BooleanExpressionParser.ArithmeticF
148142 return new InvalidExpressionException ();
149143 });
150144 final List <Node > items = getArrayElements (ctx .data .children );
151- currentNodes .add (new ArithmeticFunctionNode (functionType , items ));
152- super .exitArithmeticFunctionExpression (ctx );
145+ return new ArithmeticFunctionNode (functionType , items );
153146 }
154147
155- @ Override
156- public void exitInExpression (BooleanExpressionParser .InExpressionContext ctx ) {
148+ private ComparisonNode mapComparatorExpressionContext (BooleanExpressionParser .ComparatorExpressionContext ctx ) {
149+ final String variableName = getField (ctx .left .getText ());
150+ final Operator operator = Operator .getOperatorFromSymbol (ctx .op .getText ()).orElse (Operator .EQUALS );
151+ if (!(ctx .right instanceof BooleanExpressionParser .TypesExpressionContext ) && !currentNodes .isEmpty ()) {
152+ final Node value = currentNodes .pop ();
153+ return new ComparisonNode (variableName , value , operator , DataType .INTEGER );
154+ } else {
155+ final DataType dataType = getDataType (ctx .right .getStart ());
156+ return new ComparisonNode (variableName , ValueUtils .convertValue (ctx .right .getText (), dataType ), operator , dataType );
157+ }
158+ }
159+
160+ private ArithmeticNode mapArithmeticExpressionContext (BooleanExpressionParser .ArithmeticExpressionContext ctx ) {
161+ final Operator operator = Operator .getOperatorFromSymbol (ctx .op .getText ()).orElse (Operator .EQUALS );
162+ if (ctx .left instanceof BooleanExpressionParser .TypesExpressionContext && ctx .right instanceof BooleanExpressionParser .TypesExpressionContext ) {
163+ final UnaryNode left = mapTypesExpressionContext ((BooleanExpressionParser .TypesExpressionContext ) ctx .left );
164+ final UnaryNode right = mapTypesExpressionContext ((BooleanExpressionParser .TypesExpressionContext ) ctx .right );
165+ return ArithmeticNode .builder ().left (left ).right (right ).operator (operator ).build ();
166+ } else if (ctx .left instanceof BooleanExpressionParser .TypesExpressionContext ) {
167+ final UnaryNode left = mapTypesExpressionContext ((BooleanExpressionParser .TypesExpressionContext ) ctx .left );
168+ final Node right = currentNodes .pop ();
169+ return ArithmeticNode .builder ().left (left ).right (right ).operator (operator ).build ();
170+ } else if (ctx .right instanceof BooleanExpressionParser .TypesExpressionContext ) {
171+ final UnaryNode right = mapTypesExpressionContext ((BooleanExpressionParser .TypesExpressionContext ) ctx .right );
172+ final Node left = currentNodes .pop ();
173+ return ArithmeticNode .builder ().left (left ).right (right ).operator (operator ).build ();
174+ } else {
175+ if (currentNodes .size () < 2 ) {
176+ log .error ("Error parsing expression for the string {}" , ctx .getText ());
177+ throw new InvalidExpressionException ();
178+ }
179+ final Node right = currentNodes .pop ();
180+ final Node left = currentNodes .pop ();
181+ return ArithmeticNode .builder ().left (left ).right (right ).operator (operator ).build ();
182+ }
183+ }
184+
185+ private Node mapInExpressionContext (BooleanExpressionParser .InExpressionContext ctx ) {
157186 validateField (ctx .field , ctx .getText ());
158187 final String field = getField (ctx .field .getText ());
159188 final List <Node > items = getArrayElements (ctx .data .children );
160189 final InNode inNode = new InNode (field , items );
161190 if (Objects .isNull (ctx .not )) {
162- currentNodes . add ( inNode ) ;
191+ return inNode ;
163192 } else {
164- final BooleanNode booleanNode = new BooleanNode (inNode , null , LogicalOperationType .NOT );
165- currentNodes .add (booleanNode );
193+ return new BooleanNode (inNode , null , LogicalOperationType .NOT );
166194 }
167- super .exitInExpression (ctx );
168195 }
169196
170- private List <Node > getArrayElements (final List <ParseTree > trees ) {
171- return trees
172- .stream ()
173- .filter (child -> child instanceof BooleanExpressionParser .TypesExpressionContext )
174- .map (child -> {
175- final DataType dataType = getDataType (((BooleanExpressionParser .TypesExpressionContext ) child ).start );
176- final Object value = ValueUtils .convertValue (child .getText (), dataType );
177- return new UnaryNode (dataType , value );
178- })
179- .collect (Collectors .toList ());
197+ private NumericRangeNode mapToExpressionContext (BooleanExpressionParser .ToExpressionContext ctx ) {
198+ validateField (ctx .field , ctx .getText ());
199+ final String field = getField (ctx .field .getText ());
200+ final DataType lowerDataType = getDataType (ctx .lower .start );
201+ final Object lowerValue = ValueUtils .convertValue (ctx .lower .start .getText (), lowerDataType );
202+ final DataType upperDataType = getDataType (ctx .upper .start );
203+ final Object upperValue = ValueUtils .convertValue (ctx .upper .getText (), upperDataType );
204+ return new NumericRangeNode (field , lowerValue , upperValue , lowerDataType , upperDataType );
180205 }
181206
182207 private void validateField (final Token token , final String text ) {
@@ -219,17 +244,8 @@ private LogicalOperationType getLogicalOperator(final org.antlr.v4.runtime.Token
219244
220245 @ Override
221246 public void exitParse (BooleanExpressionParser .ParseContext ctx ) {
222- if (this .node == null && this .currentNodes .size () == 1 ) {
247+ if (this .node == null && ! this .currentNodes .isEmpty () ) {
223248 this .node = currentNodes .pop ();
224- } else if (this .node == null && this .currentNodes .size () == 2 ) {
225- final Node firstNode = currentNodes .pop ();
226- final Node secondNode = currentNodes .pop ();
227- if (firstNode instanceof ArithmeticNode && secondNode instanceof ArithmeticNode && ((ArithmeticNode ) secondNode ).getRight () == null ) {
228- this .node = ArithmeticNode .builder ().operator (Operator .UNARY ).left (firstNode ).build ();
229- }
230- if (secondNode instanceof ArithmeticNode && firstNode instanceof ArithmeticNode && ((ArithmeticNode ) firstNode ).getRight () == null ) {
231- this .node = ArithmeticNode .builder ().operator (Operator .UNARY ).left (secondNode ).build ();
232- }
233249 }
234250 if (this .node == null && tokenCount == 1 && lastToken instanceof CommonToken ) {
235251 this .node = UnaryNode .builder ().dataType (DataType .STRING ).value (ValueUtils .convertValue (lastToken .getText (), DataType .STRING ).toString ())
0 commit comments