Skip to content

Commit 66a0a18

Browse files
authored
Merge pull request #37 from nmeier/develop
Add support for logical operators to Expression.format()/InlineTreeFormatter
2 parents ed7f35d + 1faec63 commit 66a0a18

2 files changed

Lines changed: 51 additions & 15 deletions

File tree

src/main/java/net/rptools/parser/InlineTreeFormatter.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,7 @@
1414
*/
1515
package net.rptools.parser;
1616

17-
import static net.rptools.parser.ExpressionParserTokenTypes.ASSIGNEE;
18-
import static net.rptools.parser.ExpressionParserTokenTypes.FUNCTION;
19-
import static net.rptools.parser.ExpressionParserTokenTypes.HEXNUMBER;
20-
import static net.rptools.parser.ExpressionParserTokenTypes.NUMBER;
21-
import static net.rptools.parser.ExpressionParserTokenTypes.OPERATOR;
22-
import static net.rptools.parser.ExpressionParserTokenTypes.STRING;
23-
import static net.rptools.parser.ExpressionParserTokenTypes.UNARY_OPERATOR;
24-
import static net.rptools.parser.ExpressionParserTokenTypes.VARIABLE;
17+
import static net.rptools.parser.ExpressionParserTokenTypes.*;
2518

2619
import antlr.collections.AST;
2720
import java.util.HashMap;
@@ -35,12 +28,23 @@ public class InlineTreeFormatter {
3528

3629
static {
3730
// P(1) E(2) MD(3) AS(4):
38-
ORDER_OF_OPERATIONS.put("=", 0);
31+
// provide order-of for all operators as per
32+
// https://en.wikipedia.org/wiki/Order_of_operations#Programming_languages
33+
// Note that parser historically places operator = first
34+
ORDER_OF_OPERATIONS.put("=", 1);
3935
ORDER_OF_OPERATIONS.put("^", 2);
4036
ORDER_OF_OPERATIONS.put("*", 3);
4137
ORDER_OF_OPERATIONS.put("/", 3);
4238
ORDER_OF_OPERATIONS.put("+", 4);
4339
ORDER_OF_OPERATIONS.put("-", 4);
40+
ORDER_OF_OPERATIONS.put("<", 6);
41+
ORDER_OF_OPERATIONS.put("<=", 6);
42+
ORDER_OF_OPERATIONS.put(">", 6);
43+
ORDER_OF_OPERATIONS.put(">=", 6);
44+
ORDER_OF_OPERATIONS.put("==", 7);
45+
ORDER_OF_OPERATIONS.put("!=", 7);
46+
ORDER_OF_OPERATIONS.put("&&", 11);
47+
ORDER_OF_OPERATIONS.put("||", 13);
4448
}
4549

4650
public String format(AST node) throws EvaluationException, ParameterException {
@@ -50,6 +54,12 @@ public String format(AST node) throws EvaluationException, ParameterException {
5054
return sb.toString();
5155
}
5256

57+
private int getOrderOfOperator(String op) {
58+
Integer result = ORDER_OF_OPERATIONS.get(op);
59+
// revert to a default high order of for any not mapped operator
60+
return result == null ? Integer.MAX_VALUE : result;
61+
}
62+
5363
private void format(AST node, StringBuilder sb) throws EvaluationException, ParameterException {
5464
if (node == null) return;
5565

@@ -59,6 +69,8 @@ private void format(AST node, StringBuilder sb) throws EvaluationException, Para
5969
case VARIABLE:
6070
case NUMBER:
6171
case HEXNUMBER:
72+
case TRUE:
73+
case FALSE:
6274
{
6375
sb.append(node.getText());
6476
return;
@@ -73,12 +85,12 @@ private void format(AST node, StringBuilder sb) throws EvaluationException, Para
7385
}
7486
case OPERATOR:
7587
{
76-
int currentLevel = ORDER_OF_OPERATIONS.get(node.getText());
88+
int currentLevel = getOrderOfOperator(node.getText());
7789

7890
AST child = node.getFirstChild();
7991
while (child != null) {
8092
if (child.getType() == OPERATOR) {
81-
int childLevel = ORDER_OF_OPERATIONS.get(child.getText());
93+
int childLevel = getOrderOfOperator(child.getText());
8294
if (currentLevel < childLevel) sb.append("(");
8395
format(child, sb);
8496
if (currentLevel < childLevel) sb.append(")");

src/test/java/net/rptools/parser/InlineTreeFormatterTest.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,37 @@ public void testFormatEval() throws ParserException, EvaluationException, Parame
5151
compare("eval('2*2')", "eval('2*2')");
5252
}
5353

54+
public void testLogicalOperators()
55+
throws ParserException, EvaluationException, ParameterException {
56+
/**
57+
* OR : "||" ; AND : "&&" ; NOT : '!' ; EQUALS : "==" ; NOTEQUALS : "!=" ; GE : ">=" ; GT : ">"
58+
* ; LT : "<" ; LE : "<=" ; TRUE : "true"; FALSE : "false";
59+
*/
60+
compare("1||1", "1 || 1");
61+
compare("1||1", "1 || 1");
62+
compare("1&&1", "1 && 1");
63+
64+
compare("x<2||x>3", "x < 2 || x > 3");
65+
compare("1&&1 || 0||1", "1 && 1 || 0 || 1");
66+
compare("1||1 && 0||1", "1 || 1 && 0 || 1");
67+
compare("(1||1)&&(0||1)", "(1 || 1) && (0 || 1)");
68+
69+
compare("!true", "!true");
70+
compare("1==1", "1 == 1");
71+
compare("a!=b", "a != b");
72+
compare("1>2", "1 > 2");
73+
compare("1+1>=2+2", "1 + 1 >= 2 + 2");
74+
compare("1<2", "1 < 2");
75+
compare("1+1<=2+2", "1 + 1 <= 2 + 2");
76+
compare("true == (true && false) && false", "true == (true && false) && false");
77+
compare("true", "true");
78+
compare("false", "false");
79+
}
80+
5481
private void compare(String expression, String expected)
5582
throws ParserException, EvaluationException, ParameterException {
5683
Parser p = new Parser();
5784
Expression xp = p.parseExpression(expression);
58-
59-
InlineTreeFormatter tf = new InlineTreeFormatter();
60-
61-
assertEquals(expected, tf.format(xp.getTree()));
85+
assertEquals(expected, xp.format());
6286
}
6387
}

0 commit comments

Comments
 (0)