Memory performance improvements

This commit is contained in:
serso 2016-01-25 10:34:12 +01:00
parent 9d4365cc79
commit f05d050b6c
14 changed files with 170 additions and 131 deletions

View File

@ -38,7 +38,6 @@ import jscl.NumeralBase;
import jscl.math.numeric.Real; import jscl.math.numeric.Real;
import jscl.text.DoubleParser; import jscl.text.DoubleParser;
import jscl.text.JsclIntegerParser; import jscl.text.JsclIntegerParser;
import jscl.text.MutableInt;
import jscl.text.ParseException; import jscl.text.ParseException;
import jscl.text.Parser; import jscl.text.Parser;
@ -114,12 +113,16 @@ public class NumberBuilder extends BaseNumberBuilder {
try { try {
mc.setNumeralBase(nb); mc.setNumeralBase(nb);
final Parser.Parameters p = Parser.Parameters.get(s);
try { try {
return JsclIntegerParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), mc), null).content().doubleValue(); return JsclIntegerParser.parser.parse(p, null).content().doubleValue();
} catch (ParseException e) { } catch (ParseException e) {
p.exceptionsPool.release(e);
try { try {
return ((Real) DoubleParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), mc), null).content()).doubleValue(); p.reset();
return ((Real) DoubleParser.parser.parse(p, null).content()).doubleValue();
} catch (ParseException e1) { } catch (ParseException e1) {
p.exceptionsPool.release(e1);
throw new NumberFormatException(); throw new NumberFormatException();
} }
} }

View File

@ -24,14 +24,11 @@ package org.solovyev.android.calculator.math.edit;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import jscl.text.Identifier;
import jscl.text.MutableInt;
import jscl.text.ParseException;
import jscl.text.Parser;
import org.solovyev.android.calculator.VarsRegistry;
import org.solovyev.android.calculator.EntitiesRegistry; import org.solovyev.android.calculator.EntitiesRegistry;
import org.solovyev.android.calculator.Locator; import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.VarsRegistry;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.MathEntityBuilder; import org.solovyev.android.calculator.model.MathEntityBuilder;
import org.solovyev.common.math.MathEntity; import org.solovyev.common.math.MathEntity;
@ -41,6 +38,10 @@ import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import jscl.text.Identifier;
import jscl.text.ParseException;
import jscl.text.Parser;
public class VarEditorSaver<T extends MathEntity> implements View.OnClickListener { public class VarEditorSaver<T extends MathEntity> implements View.OnClickListener {
@Nonnull @Nonnull
@ -71,19 +72,16 @@ public class VarEditorSaver<T extends MathEntity> implements View.OnClickListene
} }
public static boolean isValidName(@Nullable String name) { public static boolean isValidName(@Nullable String name) {
boolean result = false;
if (!Strings.isEmpty(name)) { if (!Strings.isEmpty(name)) {
try { try {
if (name == null) throw new AssertionError(); Identifier.parser.parse(Parser.Parameters.get(name), null);
Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), Locator.getInstance().getEngine().getMathEngine()), null); return true;
result = true;
} catch (ParseException e) { } catch (ParseException e) {
// not valid name; // not valid name;
} }
} }
return result; return false;
} }
@Override @Override

View File

@ -1,6 +1,16 @@
package jscl.math; package jscl.math;
import jscl.JsclMathEngine; import org.solovyev.common.Converter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.math.function.Constant; import jscl.math.function.Constant;
import jscl.math.function.Fraction; import jscl.math.function.Fraction;
import jscl.math.function.Inverse; import jscl.math.function.Inverse;
@ -8,14 +18,12 @@ import jscl.math.numeric.Real;
import jscl.math.polynomial.Polynomial; import jscl.math.polynomial.Polynomial;
import jscl.math.polynomial.UnivariatePolynomial; import jscl.math.polynomial.UnivariatePolynomial;
import jscl.mathml.MathML; import jscl.mathml.MathML;
import jscl.text.*; import jscl.text.ExpressionParser;
import jscl.text.ParseException;
import jscl.text.Parser;
import jscl.text.ParserUtils;
import jscl.text.msg.Messages; import jscl.text.msg.Messages;
import jscl.util.ArrayUtils; import jscl.util.ArrayUtils;
import org.solovyev.common.Converter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
public class Expression extends Generic { public class Expression extends Generic {
@ -113,15 +121,13 @@ public class Expression extends Generic {
} }
public static Expression valueOf(@Nonnull String expression) throws ParseException { public static Expression valueOf(@Nonnull String expression) throws ParseException {
final MutableInt position = new MutableInt(0); final Parser.Parameters p = Parser.Parameters.get(expression);
final Parser.Parameters p = Parser.Parameters.newInstance(expression, position, JsclMathEngine.getInstance());
final Generic generic = ExpressionParser.parser.parse(p, null); final Generic generic = ExpressionParser.parser.parse(p, null);
ParserUtils.skipWhitespaces(p); ParserUtils.skipWhitespaces(p);
int index = position.intValue(); int index = p.position.intValue();
if (index < expression.length()) { if (index < expression.length()) {
throw new ParseException(index, expression, Messages.msg_1, index + 1); throw new ParseException(index, expression, Messages.msg_1, index + 1);
} }

View File

@ -1,10 +1,10 @@
package jscl.text; package jscl.text;
import jscl.math.Generic;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import jscl.math.Generic;
public class CompoundIdentifier implements Parser<String> { public class CompoundIdentifier implements Parser<String> {
public static final Parser<String> parser = new CompoundIdentifier(); public static final Parser<String> parser = new CompoundIdentifier();
@ -16,12 +16,13 @@ public class CompoundIdentifier implements Parser<String> {
public String parse(@Nonnull Parameters p, @Nullable Generic previousSumElement) throws ParseException { public String parse(@Nonnull Parameters p, @Nullable Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue(); int pos0 = p.position.intValue();
StringBuilder result = new StringBuilder(); final StringBuilder result;
ParserUtils.skipWhitespaces(p); ParserUtils.skipWhitespaces(p);
try { try {
String s = Identifier.parser.parse(p, previousSumElement); final String identifier = Identifier.parser.parse(p, previousSumElement);
result.append(s); result = new StringBuilder();
result.append(identifier);
} catch (ParseException e) { } catch (ParseException e) {
p.position.setValue(pos0); p.position.setValue(pos0);
throw e; throw e;

View File

@ -1,11 +1,14 @@
package jscl.text; package jscl.text;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.text.msg.Messages; import jscl.text.msg.Messages;
import javax.annotation.Nonnull; import static jscl.text.ParserUtils.makeParseException;
import javax.annotation.Nullable; import static jscl.text.ParserUtils.skipWhitespaces;
public class Digits implements Parser<String> { public class Digits implements Parser<String> {
@ -20,15 +23,15 @@ public class Digits implements Parser<String> {
public String parse(@Nonnull Parameters p, @Nullable Generic previousSumElement) throws ParseException { public String parse(@Nonnull Parameters p, @Nullable Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue(); int pos0 = p.position.intValue();
final StringBuilder result = new StringBuilder(); skipWhitespaces(p);
ParserUtils.skipWhitespaces(p);
final StringBuilder result;
if (p.position.intValue() < p.expression.length() && nb.getAcceptableCharacters().contains(p.expression.charAt(p.position.intValue()))) { if (p.position.intValue() < p.expression.length() && nb.getAcceptableCharacters().contains(p.expression.charAt(p.position.intValue()))) {
result = new StringBuilder(2);
result.append(p.expression.charAt(p.position.intValue())); result.append(p.expression.charAt(p.position.intValue()));
p.position.increment(); p.position.increment();
} else { } else {
ParserUtils.throwParseException(p, pos0, Messages.msg_9); throw makeParseException(p, pos0, Messages.msg_9);
} }
while (p.position.intValue() < p.expression.length() && nb.getAcceptableCharacters().contains(p.expression.charAt(p.position.intValue()))) { while (p.position.intValue() < p.expression.length() && nb.getAcceptableCharacters().contains(p.expression.charAt(p.position.intValue()))) {

View File

@ -1,18 +1,19 @@
package jscl.text; package jscl.text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.math.NumericWrapper; import jscl.math.NumericWrapper;
import jscl.math.numeric.Real; import jscl.math.numeric.Real;
import jscl.text.msg.Messages; import jscl.text.msg.Messages;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class DoubleParser implements Parser<NumericWrapper> { public class DoubleParser implements Parser<NumericWrapper> {
public static final Parser<NumericWrapper> parser = new DoubleParser(); public static final Parser<NumericWrapper> parser = new DoubleParser();
@ -69,7 +70,6 @@ class FloatingPointLiteral implements Parser<Double> {
final NumeralBase nb = NumeralBaseParser.parser.parse(p, previousSumElement); final NumeralBase nb = NumeralBaseParser.parser.parse(p, previousSumElement);
final StringBuilder result = new StringBuilder();
boolean digits = false; boolean digits = false;
boolean point = false; boolean point = false;
@ -77,6 +77,7 @@ class FloatingPointLiteral implements Parser<Double> {
final Digits digitsParser = new Digits(nb); final Digits digitsParser = new Digits(nb);
final StringBuilder result = new StringBuilder();
try { try {
result.append(digitsParser.parse(p, previousSumElement)); result.append(digitsParser.parse(p, previousSumElement));
digits = true; digits = true;
@ -167,16 +168,15 @@ class ExponentPart implements Parser<String> {
public String parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException { public String parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue(); int pos0 = p.position.intValue();
final StringBuilder result = new StringBuilder();
ParserUtils.skipWhitespaces(p); ParserUtils.skipWhitespaces(p);
final StringBuilder result;
if (p.position.intValue() < p.expression.length() && (p.expression.charAt(p.position.intValue()) == 'e' || p.expression.charAt(p.position.intValue()) == 'E')) { if (p.position.intValue() < p.expression.length() && (p.expression.charAt(p.position.intValue()) == 'e' || p.expression.charAt(p.position.intValue()) == 'E')) {
char c = p.expression.charAt(p.position.intValue()); result = new StringBuilder();
result.append(p.expression.charAt(p.position.intValue()));
p.position.increment(); p.position.increment();
result.append(c);
} else { } else {
ParserUtils.throwParseException(p, pos0, Messages.msg_10, 'e', 'E'); throw ParserUtils.makeParseException(p, pos0, Messages.msg_10, 'e', 'E');
} }
try { try {
@ -201,10 +201,10 @@ class SignedInteger implements Parser<String> {
public String parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException { public String parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
final int pos0 = p.position.intValue(); final int pos0 = p.position.intValue();
final StringBuilder result = new StringBuilder();
ParserUtils.skipWhitespaces(p); ParserUtils.skipWhitespaces(p);
final StringBuilder result = new StringBuilder();
final int pos1 = p.position.intValue(); final int pos1 = p.position.intValue();
if (pos1 < p.expression.length() && (p.expression.charAt(pos1) == '+' || MinusParser.isMinus(p.expression.charAt(pos1)))) { if (pos1 < p.expression.length() && (p.expression.charAt(pos1) == '+' || MinusParser.isMinus(p.expression.charAt(pos1)))) {
final char c = p.expression.charAt(pos1); final char c = p.expression.charAt(pos1);

View File

@ -1,14 +1,17 @@
package jscl.text; package jscl.text;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ExceptionsPool { public class ExceptionsPool {
private static final int MAX_COUNT = 20;
@Nonnull @Nonnull
private final List<ParseException> list = new ArrayList<>(); private final List<ParseException> list = new ArrayList<>();
@ -30,6 +33,9 @@ public class ExceptionsPool {
} }
public void release(@Nonnull ParseException e) { public void release(@Nonnull ParseException e) {
if (list.size() >= MAX_COUNT) {
return;
}
list.add(e); list.add(e);
} }
} }

View File

@ -1,12 +1,13 @@
package jscl.text; package jscl.text;
import jscl.math.Generic; import java.util.Arrays;
import jscl.text.msg.Messages; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List; import jscl.math.Generic;
import jscl.text.msg.Messages;
public class Identifier implements Parser<String> { public class Identifier implements Parser<String> {
@ -30,15 +31,16 @@ public class Identifier implements Parser<String> {
public String parse(@Nonnull Parameters p, @Nullable Generic previousSumElement) throws ParseException { public String parse(@Nonnull Parameters p, @Nullable Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue(); int pos0 = p.position.intValue();
final StringBuilder result = new StringBuilder();
ParserUtils.skipWhitespaces(p); ParserUtils.skipWhitespaces(p);
final StringBuilder result;
if (p.position.intValue() < p.expression.length() && isValidFirstCharacter(p.expression.charAt(p.position.intValue()))) { if (p.position.intValue() < p.expression.length() && isValidFirstCharacter(p.expression.charAt(p.position.intValue()))) {
result = new StringBuilder();
result.append(p.expression.charAt(p.position.intValue())); result.append(p.expression.charAt(p.position.intValue()));
p.position.increment(); p.position.increment();
} else { } else {
ParserUtils.throwParseException(p, pos0, Messages.msg_5); throw ParserUtils.makeParseException(p, pos0, Messages.msg_5);
} }
while (p.position.intValue() < p.expression.length() && isValidNotFirstCharacter(p.expression, p.position)) { while (p.position.intValue() < p.expression.length() && isValidNotFirstCharacter(p.expression, p.position)) {

View File

@ -1,13 +1,14 @@
package jscl.text; package jscl.text;
import java.util.Collections;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.text.msg.Messages; import jscl.text.msg.Messages;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
public class IntegerParser implements Parser<Integer> { public class IntegerParser implements Parser<Integer> {
public static final Parser<Integer> parser = new IntegerParser(); public static final Parser<Integer> parser = new IntegerParser();
@ -18,32 +19,14 @@ public class IntegerParser implements Parser<Integer> {
public Integer parse(@Nonnull Parameters p, @Nullable Generic previousSumElement) throws ParseException { public Integer parse(@Nonnull Parameters p, @Nullable Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue(); int pos0 = p.position.intValue();
/*int n;
ParserUtils.skipWhitespaces(expression, position);
if (position.intValue() < expression.length() && Character.isDigit(expression.charAt(position.intValue()))) {
char c = expression.charAt(position.intValue());
position.increment();
n = c - '0';
} else {
position.setValue(pos0);
throw new ParseException();
}
while (position.intValue() < expression.length() && Character.isDigit(expression.charAt(position.intValue()))) {
char c = expression.charAt(position.intValue());
position.increment();
n = 10 * n + (c - '0');
}*/
final NumeralBase nb = NumeralBaseParser.parser.parse(p, previousSumElement); final NumeralBase nb = NumeralBaseParser.parser.parse(p, previousSumElement);
final StringBuilder result = new StringBuilder();
ParserUtils.skipWhitespaces(p); ParserUtils.skipWhitespaces(p);
final StringBuilder result;
if (p.position.intValue() < p.expression.length() && nb.getAcceptableCharacters().contains(p.expression.charAt(p.position.intValue()))) { if (p.position.intValue() < p.expression.length() && nb.getAcceptableCharacters().contains(p.expression.charAt(p.position.intValue()))) {
char c = p.expression.charAt(p.position.intValue()); char c = p.expression.charAt(p.position.intValue());
p.position.increment(); p.position.increment();
result = new StringBuilder();
result.append(c); result.append(c);
} else { } else {
p.position.setValue(pos0); p.position.setValue(pos0);

View File

@ -1,14 +1,15 @@
package jscl.text; package jscl.text;
import java.util.Collections;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.math.JsclInteger; import jscl.math.JsclInteger;
import jscl.text.msg.Messages; import jscl.text.msg.Messages;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
public class JsclIntegerParser implements Parser<JsclInteger> { public class JsclIntegerParser implements Parser<JsclInteger> {
public static final Parser<JsclInteger> parser = new JsclIntegerParser(); public static final Parser<JsclInteger> parser = new JsclIntegerParser();
@ -21,16 +22,14 @@ public class JsclIntegerParser implements Parser<JsclInteger> {
final NumeralBase nb = NumeralBaseParser.parser.parse(p, previousSumElement); final NumeralBase nb = NumeralBaseParser.parser.parse(p, previousSumElement);
final StringBuilder result = new StringBuilder(); final String number;
try { try {
result.append(new Digits(nb).parse(p, previousSumElement)); number = new Digits(nb).parse(p, previousSumElement);
} catch (ParseException e) { } catch (ParseException e) {
p.position.setValue(pos0); p.position.setValue(pos0);
throw e; throw e;
} }
final String number = result.toString();
try { try {
return nb.toJsclInteger(number); return nb.toJsclInteger(number);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {

View File

@ -1,12 +1,14 @@
package jscl.text; package jscl.text;
import jscl.MathContext; import java.util.ArrayList;
import jscl.math.Generic; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List; import jscl.JsclMathEngine;
import jscl.MathContext;
import jscl.math.Generic;
/** /**
* Main parser interface. * Main parser interface.
@ -28,10 +30,18 @@ public interface Parser<T> {
class Parameters { class Parameters {
@Nonnull @Nonnull
public final String expression; private static final ThreadLocal<Parameters> instance = new ThreadLocal<Parameters>() {
@Override
protected Parameters initialValue() {
return new Parameters("", JsclMathEngine.getInstance());
}
};
@Nonnull @Nonnull
public final MutableInt position; public String expression;
@Nonnull
public final MutableInt position = new MutableInt(0);
@Nonnull @Nonnull
public final List<ParseException> exceptions = new ArrayList<ParseException>(); public final List<ParseException> exceptions = new ArrayList<ParseException>();
@ -44,18 +54,24 @@ public interface Parser<T> {
/** /**
* @param expression expression to be parsed * @param expression expression to be parsed
* @param position current position of expression. Side effect: if parsing is successful this parameter should be increased on the number of parsed letters (incl whitespaces etc)
* @param context math engine to be used in parsing * @param context math engine to be used in parsing
*/ */
Parameters(@Nonnull String expression, @Nonnull MutableInt position, @Nonnull MathContext context) { Parameters(@Nonnull String expression, @Nonnull MathContext context) {
this.expression = expression; this.expression = expression;
this.position = position;
this.context = context; this.context = context;
} }
@Nonnull @Nonnull
public static Parameters newInstance(@Nonnull String expression, @Nonnull MutableInt position, @Nonnull final MathContext mathEngine) { public static Parameters get(@Nonnull String expression) {
return new Parameters(expression, position, mathEngine); final Parameters parameters = instance.get();
parameters.expression = expression;
parameters.reset();
return parameters;
}
public void reset() {
position.setValue(0);
exceptions.clear();
} }
public void addException(@Nonnull ParseException e) { public void addException(@Nonnull ParseException e) {

View File

@ -1,11 +1,13 @@
package jscl.text; package jscl.text;
import jscl.math.Generic; import java.lang.reflect.Array;
import jscl.text.msg.Messages; import java.util.Collections;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.reflect.Array;
import jscl.math.Generic;
import jscl.text.msg.Messages;
/** /**
* User: serso * User: serso
@ -62,14 +64,43 @@ public class ParserUtils {
} }
} }
public static void throwParseException(@Nonnull Parser.Parameters p,
int pos0,
@Nonnull String messageId) throws ParseException {
throw makeParseException(p, pos0, messageId);
}
@Nonnull
public static ParseException makeParseException(@Nonnull Parser.Parameters p, int pos0, @Nonnull String messageId) {
final MutableInt position = p.position;
final ParseException parseException = p.exceptionsPool.obtain(position.intValue(), p.expression, messageId, Collections.emptyList());
position.setValue(pos0);
return parseException;
}
public static void throwParseException(@Nonnull Parser.Parameters p,
int pos0,
@Nonnull String messageId,
@Nonnull Object parameter) throws ParseException {
final MutableInt position = p.position;
final ParseException parseException = p.exceptionsPool.obtain(position.intValue(), p.expression, messageId, Collections.singletonList(parameter));
position.setValue(pos0);
throw parseException;
}
public static void throwParseException(@Nonnull Parser.Parameters p, public static void throwParseException(@Nonnull Parser.Parameters p,
int pos0, int pos0,
@Nonnull String messageId, @Nonnull String messageId,
Object... parameters) throws ParseException { Object... parameters) throws ParseException {
throw makeParseException(p, pos0, messageId, parameters);
}
@Nonnull
public static ParseException makeParseException(@Nonnull Parser.Parameters p, int pos0, @Nonnull String messageId, Object... parameters) {
final MutableInt position = p.position; final MutableInt position = p.position;
final ParseException parseException = p.exceptionsPool.obtain(position.intValue(), p.expression, messageId, parameters); final ParseException parseException = p.exceptionsPool.obtain(position.intValue(), p.expression, messageId, parameters);
position.setValue(pos0); position.setValue(pos0);
throw parseException; return parseException;
} }

View File

@ -1,17 +1,17 @@
package jscl.text; package jscl.text;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.math.function.PostfixFunctionsRegistry; import jscl.math.function.PostfixFunctionsRegistry;
import jscl.math.operator.Operator; import jscl.math.operator.Operator;
import jscl.math.operator.TripleFactorial; import jscl.math.operator.TripleFactorial;
import jscl.text.msg.Messages; import jscl.text.msg.Messages;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/** /**
* User: serso * User: serso
* Date: 10/31/11 * Date: 10/31/11
@ -26,13 +26,14 @@ public class PostfixFunctionsParser implements Parser<Generic> {
this.content = content; this.content = content;
} }
private static Generic parsePostfix(@Nonnull List<PostfixFunctionParser> parsers, private static Generic parsePostfix(@Nonnull List<String> names,
Generic content, Generic content,
@Nullable final Generic previousSumElement, @Nullable final Generic previousSumElement,
@Nonnull final Parameters p) throws ParseException { @Nonnull final Parameters p) throws ParseException {
Generic result = content; Generic result = content;
for (PostfixFunctionParser parser : parsers) { for (String name : names) {
final PostfixFunctionParser parser = new PostfixFunctionParser(name);
final PostfixFunctionParser.Result postfixResult = parser.parse(p, previousSumElement); final PostfixFunctionParser.Result postfixResult = parser.parse(p, previousSumElement);
if (postfixResult.isPostfixFunction()) { if (postfixResult.isPostfixFunction()) {
final Operator postfixFunction; final Operator postfixFunction;
@ -51,7 +52,7 @@ public class PostfixFunctionsParser implements Parser<Generic> {
} }
} }
result = parsePostfix(parsers, postfixFunction.expressionValue(), previousSumElement, p); result = parsePostfix(names, postfixFunction.expressionValue(), previousSumElement, p);
} }
} }
@ -59,15 +60,6 @@ public class PostfixFunctionsParser implements Parser<Generic> {
} }
public Generic parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException { public Generic parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
return parsePostfix(PostfixFunctionsRegistry.getInstance().getNames(), content, previousSumElement, p);
final List<String> postfixFunctionNames = PostfixFunctionsRegistry.getInstance().getNames();
final List<PostfixFunctionParser> parsers = new ArrayList<PostfixFunctionParser>(postfixFunctionNames.size());
parsers.add(new PostfixFunctionParser(TripleFactorial.NAME));
for (String postfixFunctionName : postfixFunctionNames) {
parsers.add(new PostfixFunctionParser(postfixFunctionName));
}
return parsePostfix(parsers, content, previousSumElement, p);
} }
} }

View File

@ -1,6 +1,5 @@
package jscl.text; package jscl.text;
import jscl.JsclMathEngine;
import org.junit.Assert; import org.junit.Assert;
/** /**
@ -12,13 +11,13 @@ public class PowerParserTest {
@org.junit.Test @org.junit.Test
public void testParse() throws Exception { public void testParse() throws Exception {
PowerParser.parser.parse(Parser.Parameters.newInstance(" ^", new MutableInt(0), JsclMathEngine.getInstance()), null); PowerParser.parser.parse(Parser.Parameters.get(" ^"), null);
PowerParser.parser.parse(Parser.Parameters.newInstance(" **", new MutableInt(0), JsclMathEngine.getInstance()), null); PowerParser.parser.parse(Parser.Parameters.get(" **"), null);
PowerParser.parser.parse(Parser.Parameters.newInstance(" **7", new MutableInt(0), JsclMathEngine.getInstance()), null); PowerParser.parser.parse(Parser.Parameters.get(" **7"), null);
PowerParser.parser.parse(Parser.Parameters.newInstance("^", new MutableInt(0), JsclMathEngine.getInstance()), null); PowerParser.parser.parse(Parser.Parameters.get("^"), null);
PowerParser.parser.parse(Parser.Parameters.newInstance("**", new MutableInt(0), JsclMathEngine.getInstance()), null); PowerParser.parser.parse(Parser.Parameters.get("**"), null);
try { try {
PowerParser.parser.parse(Parser.Parameters.newInstance("*", new MutableInt(0), JsclMathEngine.getInstance()), null); PowerParser.parser.parse(Parser.Parameters.get("*"), null);
Assert.fail(); Assert.fail();
} catch (ParseException e) { } catch (ParseException e) {