Memory performance improvements
This commit is contained in:
parent
9d4365cc79
commit
f05d050b6c
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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()))) {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user