From 54ade61bad5f44255e9869bfcccac239237bffde Mon Sep 17 00:00:00 2001 From: rusEfi Date: Fri, 10 Oct 2014 10:03:27 -0500 Subject: [PATCH] auto-sync --- .../src/com/autsia/bracer/BracerParser.java | 61 +++++++------------ .../autsia/bracer/test/BracerParserTest.java | 19 +++--- 2 files changed, 33 insertions(+), 47 deletions(-) diff --git a/java_console/models/src/com/autsia/bracer/BracerParser.java b/java_console/models/src/com/autsia/bracer/BracerParser.java index 5fd6d608e9..1407a9d05a 100644 --- a/java_console/models/src/com/autsia/bracer/BracerParser.java +++ b/java_console/models/src/com/autsia/bracer/BracerParser.java @@ -19,11 +19,9 @@ package com.autsia.bracer; -import java.text.NumberFormat; import java.text.ParseException; import java.util.Collection; import java.util.Collections; -import java.util.Locale; import java.util.Stack; import java.util.StringTokenizer; @@ -35,16 +33,10 @@ import java.util.StringTokenizer; * @since 1.0 */ public class BracerParser { - /* list of available functions */ - private final String[] FUNCTIONS = {"abs", "acos", "arg", "asin", "atan", - "conj", "cos", "cosh", "exp", "imag", "log", "neg", "pow", "real", - "sin", "time_since_boot", "sqrt", "tan", "rpm", "not"}; /* list of available operators */ private final String OPERATORS = "<>=+-*/&|!"; /* separator of arguments */ private final String SEPARATOR = ","; - /* variable token */ - private final String VARIABLE = "var"; /* temporary stack that holds operators, functions and brackets */ private Stack stackOperations = new Stack<>(); /* stack for holding expression converted to reversed polish notation */ @@ -88,9 +80,21 @@ public class BracerParser { StringTokenizer stringTokenizer = new StringTokenizer(expression, OPERATORS + SEPARATOR + "()", true); + String pendingToken = null; + /* loop for handling each token - shunting-yard algorithm */ - while (stringTokenizer.hasMoreTokens()) { - String token = stringTokenizer.nextToken(); + while (pendingToken != null || stringTokenizer.hasMoreTokens()) { + String token; + if (pendingToken != null) { + token = pendingToken; + pendingToken = null; + } else { + token = stringTokenizer.nextToken(); + } + if (stringTokenizer.hasMoreTokens()) { + pendingToken = stringTokenizer.nextToken(); + } + if (isSeparator(token)) { while (!stackOperations.empty() && !isOpenBracket(stackOperations.lastElement())) { @@ -111,6 +115,12 @@ public class BracerParser { } else if (isNumber(token)) { stackRPN.push(token); } else if (isOperator(token)) { + + if ((token.equals("<") || token.equals(">")) && "=".equals(pendingToken)) { + token = token + pendingToken; + pendingToken = null; + } + while (!stackOperations.empty() && isOperator(stackOperations.lastElement()) && getPrecedence(token) <= getPrecedence(stackOperations @@ -141,22 +151,6 @@ public class BracerParser { * @since 1.0 */ public String evaluate() throws ParseException { - if (!stackRPN.contains("var")) { - return evaluate(0); - } - throw new ParseException("Unrecognized token: var", 0); - } - - /** - * Evaluates once parsed math expression with "var" variable included - * - * @param variableValue User-specified Double value - * @return String representation of the result - * @throws ParseException if the input expression is not - * correct - * @since 3.0 - */ - public String evaluate(double variableValue) throws ParseException { /* check if is there something to evaluate */ if (stackRPN.empty()) { return ""; @@ -169,10 +163,6 @@ public class BracerParser { @SuppressWarnings("unchecked") Stack stackRPN = (Stack) this.stackRPN.clone(); - /* enroll the variable value into expression */ - Collections.replaceAll(stackRPN, VARIABLE, - Double.toString(variableValue)); - /* evaluating the RPN expression */ while (!stackRPN.empty()) { String token = stackRPN.pop(); @@ -293,8 +283,8 @@ public class BracerParser { private boolean isNumber(String token) { try { Double.parseDouble(token); - } catch (Exception e) { - return token.equals(VARIABLE); + } catch (NumberFormatException e) { + return false; } return true; } @@ -307,12 +297,7 @@ public class BracerParser { * @since 1.0 */ private boolean isFunction(String token) { - for (String item : FUNCTIONS) { - if (item.equals(token)) { - return true; - } - } - return false; + return Character.isAlphabetic(token.charAt(0)); } /** diff --git a/java_console/models/src/com/autsia/bracer/test/BracerParserTest.java b/java_console/models/src/com/autsia/bracer/test/BracerParserTest.java index daafd0a5fa..c043dba092 100644 --- a/java_console/models/src/com/autsia/bracer/test/BracerParserTest.java +++ b/java_console/models/src/com/autsia/bracer/test/BracerParserTest.java @@ -33,7 +33,6 @@ import com.autsia.bracer.BracerParser; */ public class BracerParserTest { private final String INPUT_NOVAR = "-sin(3+4+cos(6)/exp(10/pow(22,-1)))"; - private final String INPUT_VAR = "-sin(3+var+cos(10)/exp(10/pow(22,-1)))"; private BracerParser bracerParser; @Before @@ -47,12 +46,6 @@ public class BracerParserTest { Assert.assertEquals("-0.6570194619480038", bracerParser.evaluate()); } - @Test - public void testEvaluateVar() throws Exception { - bracerParser.parse(INPUT_VAR); - Assert.assertEquals("-0.6569578792490918", bracerParser.evaluate(4)); - } - @Test public void testSimpleBoolean() throws Exception { bracerParser.parse("true or false"); @@ -78,10 +71,18 @@ public class BracerParserTest { @Test public void testRusEfi() throws ParseException { bracerParser.parse("(time_since_boot < 4) | (rpm > 0)"); - Collection stackRPN = bracerParser.getStackRPN(); - Assert.assertEquals("[|, rpm, >, 0, time_since_boot, <, 4]", stackRPN.toString()); + Assert.assertEquals("[|, rpm, >, 0, time_since_boot, <, 4]", bracerParser.getStackRPN().toString()); + + bracerParser.parse("(time_since_boot <= 4) | (rpm > 0)"); + Assert.assertEquals("[|, rpm, >, 0, time_since_boot, <=, 4]", bracerParser.getStackRPN().toString()); + + bracerParser.parse("(time_since_boot <= 4) | (rpm > 0)"); + Assert.assertEquals("[|, rpm, >, 0, time_since_boot, <=, 4]", bracerParser.getStackRPN().toString()); + + bracerParser.parse("(time_since_boot <= 4) OR (rpm > 0)"); + Assert.assertEquals("[OR, rpm, >, 0, time_since_boot, <=, 4]", bracerParser.getStackRPN().toString()); } @Test