From 7a0f427727db7fcafd389e1e2c4b3ab207acd5c2 Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Tue, 26 Nov 2019 17:58:52 -0500 Subject: Multiplication between a value and a unit now has precedence. Example, 3 m / 2 s = (3 m) / (2 s) This change also makes "3m" a valid expression. --- src/org/unitConverter/unit/UnitDatabase.java | 36 +++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/org/unitConverter/unit/UnitDatabase.java b/src/org/unitConverter/unit/UnitDatabase.java index 5985c80..6a89b67 100644 --- a/src/org/unitConverter/unit/UnitDatabase.java +++ b/src/org/unitConverter/unit/UnitDatabase.java @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Set; @@ -968,6 +969,21 @@ public final class UnitDatabase { } } + /** + * Replacements done to *all* expression types + */ + private static final Map EXPRESSION_REPLACEMENTS = new HashMap<>(); + + static { + // place brackets around any expression of the form "number unit", with or without the space + EXPRESSION_REPLACEMENTS.put(Pattern.compile("((?:-?[1-9]\\d*|0)" // integer + + "(?:\\.\\d+)?)" // optional decimal point with numbers after it + + "\\s*" // optional space(s) + + "([a-zA-Z]+)" // unit name + + "(?!-?\\d)" // no number directly afterwards (avoids matching "1e3") + ), "\\($1 $2\\)"); + } + /** * A regular expression that separates names and expressions in unit files. */ @@ -1208,6 +1224,7 @@ public final class UnitDatabase { "Error at line %d: Lines of a unit file must consist of a unit name, then spaces or tabs, then a unit expression.", lineCounter)); final String name = lineMatcher.group(1); + final String expression = lineMatcher.group(2); if (name.endsWith(" ")) { @@ -1360,6 +1377,11 @@ public final class UnitDatabase { // fix broken spaces modifiedExpression = modifiedExpression.replaceAll(" +", " "); + // format expression + for (final Entry replacement : EXPRESSION_REPLACEMENTS.entrySet()) { + modifiedExpression = replacement.getKey().matcher(modifiedExpression).replaceAll(replacement.getValue()); + } + return this.unitDimensionParser.parseExpression(modifiedExpression); } @@ -1445,6 +1467,13 @@ public final class UnitDatabase { // fix broken spaces modifiedExpression = modifiedExpression.replaceAll(" +", " "); + // format expression + for (final Entry replacement : EXPRESSION_REPLACEMENTS.entrySet()) { + modifiedExpression = replacement.getKey().matcher(modifiedExpression).replaceAll(replacement.getValue()); + } + + System.out.println(modifiedExpression); + return this.prefixExpressionParser.parseExpression(modifiedExpression); } @@ -1507,11 +1536,16 @@ public final class UnitDatabase { // fix broken spaces modifiedExpression = modifiedExpression.replaceAll(" +", " "); + // format expression + for (final Entry replacement : EXPRESSION_REPLACEMENTS.entrySet()) { + modifiedExpression = replacement.getKey().matcher(modifiedExpression).replaceAll(replacement.getValue()); + } + // the previous operation breaks negative numbers, fix them! // (i.e. -2 becomes - 2) for (int i = 2; i < modifiedExpression.length(); i++) { if (modifiedExpression.charAt(i) == '-' - && Arrays.asList('+', '-', '*', '/', '^').contains(modifiedExpression.charAt(i - 2))) { + && (i < 2 || Arrays.asList('+', '-', '*', '/', '^').contains(modifiedExpression.charAt(i - 2)))) { // found a broken negative number modifiedExpression = modifiedExpression.substring(0, i + 1) + modifiedExpression.substring(i + 2); } -- cgit v1.2.3