X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=core%2Fsrc%2Fnet%2Fsf%2Fopenrocket%2Futil%2FExpressionParser.java;fp=core%2Fsrc%2Fnet%2Fsf%2Fopenrocket%2Futil%2FExpressionParser.java;h=d3a3fa62bcaf83a5b05c35f6f67eccd8e400a558;hb=9349577cdfdff682b2aabd6daa24fdc3a7449b58;hp=0000000000000000000000000000000000000000;hpb=30ba0a882f0c061176ba14dbf86d3d6fad096c02;p=debian%2Fopenrocket diff --git a/core/src/net/sf/openrocket/util/ExpressionParser.java b/core/src/net/sf/openrocket/util/ExpressionParser.java new file mode 100644 index 00000000..d3a3fa62 --- /dev/null +++ b/core/src/net/sf/openrocket/util/ExpressionParser.java @@ -0,0 +1,67 @@ +package net.sf.openrocket.util; + +import java.text.DecimalFormatSymbols; + +import net.sf.openrocket.logging.LogHelper; +import net.sf.openrocket.startup.Application; +import de.congrace.exp4j.Calculable; +import de.congrace.exp4j.ExpressionBuilder; + +public class ExpressionParser { + private static final LogHelper log = Application.getLogger(); + + private static final char DECIMAL_SEPARATOR; + private static final char MINUS_SIGN; + static { + DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(); + DECIMAL_SEPARATOR = symbols.getDecimalSeparator(); + MINUS_SIGN = symbols.getMinusSign(); + } + + public double parse(String expression) throws InvalidExpressionException { + + String modified = null; + try { + modified = modify(expression); + ExpressionBuilder builder = new ExpressionBuilder(modified); + Calculable calc = builder.build(); + double n = calc.calculate().getDoubleValue(); + log.debug("Evaluated expression '" + expression + "' (modified='" + modified + "') to " + n); + return n; + } catch (Exception e) { + log.warn("Unable to parse expression '" + expression + "' (modified='" + modified + "')", e); + throw new InvalidExpressionException("Invalid expression: " + expression, e); + } + } + + private String modify(String exp) throws InvalidExpressionException { + + // Normalize digit equivalents, fraction sign, decimal separators and minus sign + char[] chars = exp.toCharArray(); + for (int i = 0; i < chars.length; i++) { + int value = Character.getNumericValue(chars[i]); + if (value >= 0 && value < 10) { + chars[i] = Character.toChars(48 + value)[0]; + } + if (chars[i] == Chars.FRACTION) { + chars[i] = '/'; + } + if (chars[i] == DECIMAL_SEPARATOR || chars[i] == ',') { + chars[i] = '.'; + } + if (chars[i] == MINUS_SIGN) { + chars[i] = '-'; + } + } + exp = String.copyValueOf(chars); + + // Replace fraction equivalents "1 3/4" with "(1+3/4)" + exp = exp.replaceAll("(?