staying human-readable

This commit is contained in:
rusefi 2017-03-08 23:38:09 -05:00
parent bad931e9b4
commit 011fd6f5ba
4 changed files with 32 additions and 35 deletions

View File

@ -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();

View File

@ -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);
@ -220,7 +220,7 @@ public class DoubleEvaluator extends AbstractEvaluator<Double> {
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();

View File

@ -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 +

View File

@ -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)");
} }