staying human-readable
This commit is contained in:
parent
bad931e9b4
commit
011fd6f5ba
|
@ -135,7 +135,7 @@ public abstract class AbstractEvaluator<T> {
|
||||||
values.push(value!=null ? value : toValue(literal, evaluationContext));
|
values.push(value!=null ? value : toValue(literal, evaluationContext));
|
||||||
} else if (token.isOperator()) {
|
} else if (token.isOperator()) {
|
||||||
Operator operator = token.getOperator();
|
Operator operator = token.getOperator();
|
||||||
rpnPush("deq", operator.getRpnSymbol());
|
rpnPush("deq", operator.getSymbol());
|
||||||
values.push(evaluate(operator, getArguments(values, operator.getOperandCount()), evaluationContext));
|
values.push(evaluate(operator, getArguments(values, operator.getOperandCount()), evaluationContext));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
|
|
@ -118,7 +118,7 @@ public class DoubleEvaluator extends AbstractEvaluator<Double> {
|
||||||
public static final Function RANDOM = new Function("random", 0);
|
public static final Function RANDOM = new Function("random", 0);
|
||||||
|
|
||||||
/** The negate unary operator in the standard operator precedence.*/
|
/** The negate unary operator in the standard operator precedence.*/
|
||||||
public static final Operator NEGATE = new Operator("-", 1, Operator.Associativity.RIGHT, 3, "negate");
|
public static final Operator NEGATE = new Operator("negate", 1, Operator.Associativity.RIGHT, 3, "negate");
|
||||||
/** The negate unary operator in the Excel like operator precedence.*/
|
/** The negate unary operator in the Excel like operator precedence.*/
|
||||||
public static final Operator NEGATE_HIGH = new Operator("-", 1, Operator.Associativity.RIGHT, 5);
|
public static final Operator NEGATE_HIGH = new Operator("-", 1, Operator.Associativity.RIGHT, 5);
|
||||||
|
|
||||||
|
@ -219,9 +219,9 @@ public class DoubleEvaluator extends AbstractEvaluator<Double> {
|
||||||
protected Double toValue(String literal, Object evaluationContext) {
|
protected Double toValue(String literal, Object evaluationContext) {
|
||||||
ParsePosition p = new ParsePosition(0);
|
ParsePosition p = new ParsePosition(0);
|
||||||
Number result = FORMATTER.get().parse(literal, p);
|
Number result = FORMATTER.get().parse(literal, p);
|
||||||
if (p.getIndex()==0 || p.getIndex()!=literal.length()) {
|
if (p.getIndex() == 0 || p.getIndex() != literal.length()) {
|
||||||
return 666.0;
|
return 6666666.0; // let's return this magic in case of any function call
|
||||||
// throw new IllegalArgumentException(literal+" is not a number");
|
// throw new IllegalArgumentException(literal + " is not a number");
|
||||||
}
|
}
|
||||||
return result.doubleValue();
|
return result.doubleValue();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@ import java.util.List;
|
||||||
* @author Jean-Marc Astesana
|
* @author Jean-Marc Astesana
|
||||||
* @see <a href="../../../license.html">License information</a>
|
* @see <a href="../../../license.html">License information</a>
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
public class Operator {
|
public class Operator {
|
||||||
public final String rpnSymbol;
|
private final String rpnSymbol;
|
||||||
public static final List<String> _2_OPERATORS = new ArrayList<>();
|
public static final List<String> _2_OPERATORS = new ArrayList<>();
|
||||||
|
|
||||||
/** An Operator's <a href="http://en.wikipedia.org/wiki/Operator_associativity">associativity</a>.
|
/** An Operator's <a href="http://en.wikipedia.org/wiki/Operator_associativity">associativity</a>.
|
||||||
|
@ -36,11 +37,11 @@ public class Operator {
|
||||||
* @throws IllegalArgumentException if operandCount if not 1 or 2 or if associativity is none
|
* @throws IllegalArgumentException if operandCount if not 1 or 2 or if associativity is none
|
||||||
* @throws NullPointerException if symbol or associativity are null
|
* @throws NullPointerException if symbol or associativity are null
|
||||||
*/
|
*/
|
||||||
public Operator(String symbol, int operandCount, Associativity associativity, int precedence) {
|
Operator(String symbol, int operandCount, Associativity associativity, int precedence) {
|
||||||
this(symbol, operandCount, associativity, precedence, null);
|
this(symbol, operandCount, associativity, precedence, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Operator(String symbol, int operandCount, Associativity associativity, int precedence, String rpnSymbol) {
|
Operator(String symbol, int operandCount, Associativity associativity, int precedence, String rpnSymbol) {
|
||||||
this.rpnSymbol = rpnSymbol;
|
this.rpnSymbol = rpnSymbol;
|
||||||
if (symbol==null || associativity==null) {
|
if (symbol==null || associativity==null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
@ -59,7 +60,7 @@ public class Operator {
|
||||||
this.associativity = associativity;
|
this.associativity = associativity;
|
||||||
this.precedence = precedence;
|
this.precedence = precedence;
|
||||||
if (operandCount == 2) {
|
if (operandCount == 2) {
|
||||||
_2_OPERATORS.add(getRpnSymbol());
|
_2_OPERATORS.add(symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,14 +71,6 @@ public class Operator {
|
||||||
return this.symbol;
|
return this.symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getRpnSymbol() {
|
|
||||||
if (rpnSymbol != null)
|
|
||||||
return rpnSymbol;
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Gets the operator's operand count.
|
/** Gets the operator's operand count.
|
||||||
* @return an integer
|
* @return an integer
|
||||||
*/
|
*/
|
||||||
|
@ -146,7 +139,6 @@ public class Operator {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Operator{" +
|
return "Operator{" +
|
||||||
"rpnSymbol='" + rpnSymbol + '\'' +
|
|
||||||
", symbol='" + symbol + '\'' +
|
", symbol='" + symbol + '\'' +
|
||||||
", precedence=" + precedence +
|
", precedence=" + precedence +
|
||||||
", operandCount=" + operandCount +
|
", operandCount=" + operandCount +
|
||||||
|
|
|
@ -20,9 +20,9 @@ public class ParserTest {
|
||||||
assertParseB("2 1 >", "2 > 1");
|
assertParseB("2 1 >", "2 > 1");
|
||||||
assertParse("rpm 0 >", "rpm > false");
|
assertParse("rpm 0 >", "rpm > false");
|
||||||
assertParse("rpm 0 >", "(rpm > false)");
|
assertParse("rpm 0 >", "(rpm > false)");
|
||||||
assertParse("rpm user0 > clt user2 > |", "(rpm > user0) or (clt > user2)");
|
assertParse("rpm user0 > clt user2 > or", "(rpm > user0) or (clt > user2)");
|
||||||
assertParse("1 2 | 3 |", "1 | 2 | 3");
|
assertParse("1 2 | 3 |", "1 | 2 | 3");
|
||||||
assertParse("rpm user0 > clt user2 > | vbatt user1 > |", "(rpm > user0) or (clt > user2) or (vbatt > user1)");
|
assertParse("rpm user0 > clt user2 > or vbatt user1 > or", "(rpm > user0) or (clt > user2) or (vbatt > user1)");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertParseB(String rpn, String expression) {
|
private void assertParseB(String rpn, String expression) {
|
||||||
|
@ -71,16 +71,22 @@ public class ParserTest {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void testUnaryMinus() {
|
||||||
assertValue("2 3 6 ^ negate +", "2+-3^6", -727.0);
|
/**
|
||||||
|
* do we even need to and/or should to support unary minus?
|
||||||
|
*
|
||||||
|
* http://stackoverflow.com/questions/20246787/handling-unary-minus-for-shunting-yard-algorithm
|
||||||
|
*/
|
||||||
|
assertValue("3 negate", "negate3", -3);
|
||||||
|
assertValue("2 3 6 ^ negate +", "2+negate 3^6", -727.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBooleanNot2() throws Exception {
|
public void testBooleanNot2() throws Exception {
|
||||||
assertValue("0 !", "! 0", 1);
|
assertValue("0 !", "! 0", 1);
|
||||||
assertValue("0 !", "not 0", 1);
|
assertValue("0 not", "not 0", 1);
|
||||||
assertValue("1 !", "not(1)", 0);
|
assertValue("1 not", "not(1)", 0);
|
||||||
assertValue("0 !", "not(0)", 1);
|
assertValue("0 not", "not(0)", 1);
|
||||||
// assertValue("1 0 | not 0 & 1 0 | |", "(((true | false) & not(false)) | (true | false))", 1);
|
// assertValue("1 0 | not 0 & 1 0 | |", "(((true | false) & not(false)) | (true | false))", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,31 +98,30 @@ public class ParserTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRusEfi() {
|
public void testRusEfi() {
|
||||||
assertParse("1 4 |", "1 or 4");
|
assertParse("1 4 or", "1 or 4");
|
||||||
assertParse("1 4 |", "1 OR 4");
|
assertParse("1 4 or", "1 OR 4");
|
||||||
|
|
||||||
assertParseB("time_since_boot 4 <", "(time_since_boot < 4)");
|
assertParseB("time_since_boot 4 <", "(time_since_boot < 4)");
|
||||||
assertParseB("1 4 |", "1 | 4");
|
assertParseB("1 4 |", "1 | 4");
|
||||||
assertParse("time_since_boot 4 < rpm 0 > |", "(time_since_boot < 4) | (rpm > 0)");
|
assertParse("time_since_boot 4 < rpm 0 > |", "(time_since_boot < 4) | (rpm > 0)");
|
||||||
|
|
||||||
assertParse("1 4 &", "1 and 4");
|
assertParse("1 4 and", "1 and 4");
|
||||||
assertParse("1 4 &", "1 AND 4");
|
assertParse("1 4 and", "1 AND 4");
|
||||||
|
|
||||||
assertParseB("1 4 &", "1 & 4");
|
assertParseB("1 4 &", "1 & 4");
|
||||||
|
|
||||||
assertParse("coolant fan_off_setting >", "(coolant > fan_off_setting)");
|
assertParse("coolant fan_off_setting >", "(coolant > fan_off_setting)");
|
||||||
assertParse("1 3 |", "1 OR 3");
|
|
||||||
assertParse("1 3 &", "1 and 3");
|
assertParse("1 coolant fan_on_setting > or", "1 OR (coolant > fan_on_setting)");
|
||||||
assertParse("1 coolant fan_on_setting > |", "1 OR (coolant > fan_on_setting)");
|
assertParse("fan coolant fan_off_setting > and coolant fan_on_setting > or", "(fan and (coolant > fan_off_setting)) OR (coolant > fan_on_setting)");
|
||||||
assertParse("fan coolant fan_off_setting > & coolant fan_on_setting > |", "(fan and (coolant > fan_off_setting)) OR (coolant > fan_on_setting)");
|
|
||||||
|
|
||||||
assertParse("time_since_boot 4 <= rpm 0 > |", "(time_since_boot <= 4) | (rpm > 0)");
|
assertParse("time_since_boot 4 <= rpm 0 > |", "(time_since_boot <= 4) | (rpm > 0)");
|
||||||
|
|
||||||
assertParse("time_since_boot 4 <= rpm 0 > |", "(time_since_boot <= 4) | (rpm > 0)");
|
assertParse("time_since_boot 4 <= rpm 0 > |", "(time_since_boot <= 4) | (rpm > 0)");
|
||||||
|
|
||||||
assertParse("time_since_boot 4 <= rpm 0 > |", "(time_since_boot <= 4) OR (rpm > 0)");
|
assertParse("time_since_boot 4 <= rpm 0 > or", "(time_since_boot <= 4) OR (rpm > 0)");
|
||||||
|
|
||||||
assertParse("self rpm 4800 >= & rpm 5000 > |", "(self and (rpm >= 4800)) OR (rpm > 5000)");
|
assertParse("self rpm 4800 >= and rpm 5000 > or", "(self and (rpm >= 4800)) OR (rpm > 5000)");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue