]> gitweb.hamatoma.de Git - jpinet/commitdiff
expression full tested, StringUtils full tested
authorhama <hama@siduction.net>
Mon, 25 Jul 2016 22:11:06 +0000 (00:11 +0200)
committerhama <hama@siduction.net>
Mon, 25 Jul 2016 22:11:06 +0000 (00:11 +0200)
src/main/java/de/republib/expr/Expression.java
src/main/java/de/republib/expr/ParserException.java
src/main/java/de/republib/expr/Scanner.java
src/main/java/de/republib/util/StringUtils.java
src/test/java/de/republib/expr/ExpressionTest.java
src/test/java/de/republib/util/StringUtilsTest.java

index 395de537d287a50c4f9588fee743c660f48ab9b8..bd0219a215fa5d88fdc9caf9b264248940389f1a 100644 (file)
@@ -49,7 +49,6 @@ public class Expression {
         *
         * @return the value of the expression stored in a token
         * @throws ParserException
-        * @throws VariantException
         */
        public Variant expr() throws ParserException {
                final int entryStackLevel = this.operators.size();
@@ -80,6 +79,9 @@ public class Expression {
                        } else {
                                value2 = term();
                        }
+                       if (value2 == null) {
+                               throw new ParserException(I18N.tr("unexpected end of string"), this.scanner.getLastToken(), false);
+                       }
                        while (this.operators.size() > entryStackLevel
                                        && this.operators.lastElement().getOpCode().getPriority() >= op.getPriority()) {
                                reduceStack();
@@ -94,6 +96,22 @@ public class Expression {
                return value1;
        }
 
+       /**
+        * Calculates the value of the expression.
+        *
+        * @param text
+        *            formula text
+        * @return the value of the expression
+        * @throws ParserException
+        */
+       public Variant expr(String text) throws ParserException {
+               final Variant rc = reset(text).expr();
+               if (this.values.size() != 0) {
+                       assert (this.values.size() == 0);
+               }
+               return rc;
+       }
+
        /**
         * Returns the variable given by the name.
         *
@@ -137,6 +155,8 @@ public class Expression {
         */
        public Expression reset(String text) {
                this.scanner.reset(text);
+               this.values.clear();
+               this.operators.clear();
                return this;
        }
 
index d871be07a95f509fdb41b46ff44d8fede8c2be0b..4d3df7c335eb02084d19143df53ddd7a6eff7c5d 100644 (file)
@@ -28,9 +28,11 @@ public class ParserException extends Exception {
        private static String buildMessage(String message, Token token, boolean startPosition) {
                String rc;
                if (startPosition) {
-                       rc = String.format("%d-%d ==> [%s]: %s", token.getLineNo(), token.getPosition(), token.toString(), message);
+                       rc = String.format("%d-%d ==> [%s]: %s", token.getLineNo(), 1 + token.getPosition(), token.toString(),
+                                       message);
                } else {
-                       rc = String.format("%d-%d [%s] <==: %s", token.getLineNo(), token.getPosition(), token.toString(), message);
+                       rc = String.format("%d-%d [%s] <==: %s", token.getLineNo(), 1 + token.getPosition(), token.toString(),
+                                       message);
                }
                return rc;
        }
index 226c1ff35b9b22e20a65d3295727aa50a33f720e..6d3d947bca9af36931b24c6672842ac0478dd2e9 100644 (file)
@@ -139,6 +139,9 @@ public class Scanner {
                case ')':
                        op = OpCode.RIGHT_PARENT;
                        break;
+               case '=':
+                       op = OpCode.ASSIGN;
+                       break;
                default:
                        rc = false;
                        break;
index 84f2d10a59c0a6a1403334f6383b5e9de940d9b5..e9c0c6ed3d7632b46cbd1125ac00415568dc6f4c 100644 (file)
@@ -25,61 +25,40 @@ public class StringUtils {
                if (precision <= 0) {
                        precision = 1;
                }
-               if (value >= 1E6) {
-                       rc = String.format("%.g", precision - 1, value);
-               } else if (value > 1.0) {
-                       double limit;
-                       int prec = 0;
-                       switch (precision) {
-                       case 1:
-                               limit = 10.0;
-                               prec = 0;
-                               break;
-                       case 2:
-                               limit = 100.0;
-                               prec = 1;
-                               break;
-                       case 3:
-                               limit = 1000.0;
-                               prec = 2;
-                               break;
-                       default:
-                               limit = 1000.0;
-                               break;
-                       }
-                       if (value >= limit) {
-                               rc = String.format("%d", (int) Math.round(value));
-                       } else {
-                               rc = String.format("%.*g", prec, value);
-                       }
-               } else if (value >= 1E-5) {
-                       final double limit;
-                       int prec;
-                       switch (precision) {
-                       case 1:
-                               limit = 1E-4;
-                               prec = 5;
-                               break;
-                       case 2:
-                               limit = 1E-3;
-                               prec = 4;
-                               break;
-                       case 3:
-                               limit = 1E-2;
-                               prec = 3;
-                               break;
-                       default:
-                               limit = 1E-2;
-                               prec = 3;
-                               break;
-                       }
-                       if (value < limit) {
-
-                       } else {
-                               rc = String.format("%.*f", prec, value);
-                       }
+               double upperLimit = 1E6;
+               double lowerLimit = 100;
+               double lowerLimit2 = 1e-4;
+               int prec = 0;
+               final int prec2 = 5;
+               switch (precision) {
+               case 1:
+                       prec = 1;
+                       upperLimit = 1E4;
+                       lowerLimit = 10.0;
+                       lowerLimit2 = 1e-2;
+                       break;
+               case 2:
+                       prec = 2;
+                       upperLimit = 1E5;
+                       lowerLimit = 100.0;
+                       lowerLimit2 = 1e-3;
+                       break;
+               case 3:
+                       prec = 3;
+                       lowerLimit = 1000.0;
+                       break;
+               default:
+                       upperLimit = 1000.0;
+                       break;
+               }
+               if (value < 1.0) {
+                       final String format = String.format("%%.%dg", prec);
+                       rc = String.format(format, value).replace("e-0", "e-");
+               } else if (value < upperLimit && value >= lowerLimit) {
+                       rc = String.format("%d", (int) Math.round(value));
                } else {
-                       rc = String.format("%.*g", precision - 1, value);
+                       final String format = String.format("%%.%dg", prec);
+                       rc = String.format(format, value).replace("e+0", "e");
                }
                return rc;
        }
index d1f82859562c266b5ccd29db75822192c6cad781..00b7a9603304d56783eee831450ea743f27f46ba 100644 (file)
@@ -23,6 +23,35 @@ public class ExpressionTest {
                Assert.assertEquals(expr.findVariable(name).getValue().getLongValue(), 47L);
        }
 
+       @Test
+       public void shouldThrowOnErrors() {
+               final Expression expr = new Expression("1+");
+               try {
+                       expr.expr();
+                       Assert.fail("missing exception");
+               } catch (final ParserException e) {
+                       Assert.assertFalse(e.getMessage().isEmpty());
+               }
+               try {
+                       expr.expr("(");
+                       Assert.fail("missing exception");
+               } catch (final ParserException e) {
+                       Assert.assertFalse(e.getMessage().isEmpty());
+               }
+               try {
+                       expr.expr("3=4");
+                       Assert.fail("missing exception");
+               } catch (final ParserException e) {
+                       Assert.assertTrue(e.getMessage().indexOf("[=]") > 0);
+               }
+               try {
+                       expr.expr("1+*");
+                       Assert.fail("missing exception");
+               } catch (final ParserException e) {
+                       Assert.assertTrue(e.getMessage().indexOf("[*]") > 0);
+               }
+       }
+
        @Test
        public void shouldWorkExpr() throws ParserException {
                final Expression expr = new Expression("1 + 2*3");
index 799e4e5ca7f28ed2a9d989d320548c9f098e6153..88b0360a7c547d300a588f713b444f9a4fc58d4d 100644 (file)
@@ -7,22 +7,50 @@ public class StringUtilsTest {
 
        private void checkPrec1() {
                final double value = 1234567.77;
-               Assert.assertEquals(StringUtils.formatFloat(value, 3), "123E6");
-               Assert.assertEquals(StringUtils.formatFloat(123456.77, 3), "123456");
-               Assert.assertEquals(StringUtils.formatFloat(12345.77, 3), "123456");
-               Assert.assertEquals(StringUtils.formatFloat(1234.77, 3), "12345");
-               Assert.assertEquals(StringUtils.formatFloat(123.77, 3), "123");
-               Assert.assertEquals(StringUtils.formatFloat(12.77, 3), "12.7");
-               Assert.assertEquals(StringUtils.formatFloat(1.77, 3), "1.77");
-
+               Assert.assertEquals(StringUtils.formatFloat(value, 1), "1e6");
+               Assert.assertEquals(StringUtils.formatFloat(123456.77, 1), "1e5");
+               Assert.assertEquals(StringUtils.formatFloat(12345.77, 1), "1e4");
+               Assert.assertEquals(StringUtils.formatFloat(1234.77, 1), "1235");
+               Assert.assertEquals(StringUtils.formatFloat(123.77, 1), "124");
+               Assert.assertEquals(StringUtils.formatFloat(12.77, 1), "13");
+               Assert.assertEquals(StringUtils.formatFloat(1.77222, 1), "2");
+               Assert.assertEquals(StringUtils.formatFloat(0.177222, 1), "0,2");
+               Assert.assertEquals(StringUtils.formatFloat(0.0177222, 1), "0,02");
+               Assert.assertEquals(StringUtils.formatFloat(0.00177222, 1), "0,002");
+               Assert.assertEquals(StringUtils.formatFloat(0.000177222, 1), "0,0002");
+               Assert.assertEquals(StringUtils.formatFloat(0.0000177222, 1), "2e-5");
        }
 
        private void checkPrec2() {
-
+               final double value = 1234567.77;
+               Assert.assertEquals(StringUtils.formatFloat(value, 2), "1,2e6");
+               Assert.assertEquals(StringUtils.formatFloat(123456.77, 2), "1,2e5");
+               Assert.assertEquals(StringUtils.formatFloat(12345.77, 2), "12346");
+               Assert.assertEquals(StringUtils.formatFloat(1234.77, 2), "1235");
+               Assert.assertEquals(StringUtils.formatFloat(123.77, 2), "124");
+               Assert.assertEquals(StringUtils.formatFloat(12.77, 2), "13");
+               Assert.assertEquals(StringUtils.formatFloat(1.77, 2), "1,8");
+               Assert.assertEquals(StringUtils.formatFloat(0.177222, 2), "0,18");
+               Assert.assertEquals(StringUtils.formatFloat(0.0177222, 2), "0,018");
+               Assert.assertEquals(StringUtils.formatFloat(0.00177222, 2), "0,0018");
+               Assert.assertEquals(StringUtils.formatFloat(0.000177222, 2), "0,00018");
+               Assert.assertEquals(StringUtils.formatFloat(0.0000177222, 2), "1,8e-5");
        }
 
        private void checkPrec3() {
-
+               final double value = 1234567.77;
+               Assert.assertEquals(StringUtils.formatFloat(value, 3), "1,23e6");
+               Assert.assertEquals(StringUtils.formatFloat(123456.77, 3), "123457");
+               Assert.assertEquals(StringUtils.formatFloat(12345.77, 3), "12346");
+               Assert.assertEquals(StringUtils.formatFloat(1234.77, 3), "1235");
+               Assert.assertEquals(StringUtils.formatFloat(123.77, 3), "124");
+               Assert.assertEquals(StringUtils.formatFloat(12.77, 3), "12,8");
+               Assert.assertEquals(StringUtils.formatFloat(1.77222, 3), "1,77");
+               Assert.assertEquals(StringUtils.formatFloat(0.177222, 3), "0,177");
+               Assert.assertEquals(StringUtils.formatFloat(0.0177222, 3), "0,0177");
+               Assert.assertEquals(StringUtils.formatFloat(0.00177222, 3), "0,00177");
+               Assert.assertEquals(StringUtils.formatFloat(0.000177222, 3), "0,000177");
+               Assert.assertEquals(StringUtils.formatFloat(0.0000177222, 3), "1,77e-5");
        }
 
        @Test