ParseExceptions pool
This commit is contained in:
parent
b482b83007
commit
88c1253609
@ -123,7 +123,7 @@ public class Expression extends Generic {
|
||||
|
||||
int index = position.intValue();
|
||||
if (index < expression.length()) {
|
||||
throw new ParseException(Messages.msg_1, index, expression, index + 1);
|
||||
throw new ParseException(index, expression, Messages.msg_1, index + 1);
|
||||
}
|
||||
|
||||
return new Expression().init(generic);
|
||||
|
@ -33,6 +33,7 @@ public class CompoundIdentifier implements Parser<String> {
|
||||
// NOTE: '.' must be appended after parsing
|
||||
result.append(".").append(dotAndId);
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ public class ConstantParser implements Parser<Constant> {
|
||||
try {
|
||||
l.add(Subscript.parser.parse(p, previousSumElement));
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -33,6 +34,7 @@ public class ConstantParser implements Parser<Constant> {
|
||||
try {
|
||||
prime = Prime.parser.parse(p, previousSumElement);
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
}
|
||||
|
||||
return new Constant(name, prime, ArrayUtils.toArray(l, new Generic[l.size()]));
|
||||
|
@ -10,6 +10,7 @@ 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> {
|
||||
@ -80,6 +81,7 @@ class FloatingPointLiteral implements Parser<Double> {
|
||||
result.append(digitsParser.parse(p, previousSumElement));
|
||||
digits = true;
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -90,6 +92,8 @@ class FloatingPointLiteral implements Parser<Double> {
|
||||
if (!digits) {
|
||||
p.position.setValue(pos0);
|
||||
throw e;
|
||||
} else {
|
||||
p.exceptionsPool.release(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +107,8 @@ class FloatingPointLiteral implements Parser<Double> {
|
||||
if (!digits) {
|
||||
p.position.setValue(pos0);
|
||||
throw e;
|
||||
} else {
|
||||
p.exceptionsPool.release(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,6 +119,8 @@ class FloatingPointLiteral implements Parser<Double> {
|
||||
if (!point) {
|
||||
p.position.setValue(pos0);
|
||||
throw e;
|
||||
} else {
|
||||
p.exceptionsPool.release(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,7 +132,7 @@ class FloatingPointLiteral implements Parser<Double> {
|
||||
try {
|
||||
return nb.toDouble(doubleString);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ParseException(Messages.msg_8, p.position.intValue(), p.expression, doubleString);
|
||||
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_8, Collections.singletonList(doubleString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
jscl/src/main/java/jscl/text/ExceptionsPool.java
Normal file
28
jscl/src/main/java/jscl/text/ExceptionsPool.java
Normal file
@ -0,0 +1,28 @@
|
||||
package jscl.text;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ExceptionsPool {
|
||||
|
||||
@Nonnull
|
||||
private final List<ParseException> list = new ArrayList<>();
|
||||
|
||||
@Nonnull
|
||||
public ParseException obtain(int position, @Nonnull String expression, @Nonnull String messageCode) {
|
||||
return obtain(position, expression, messageCode, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public ParseException obtain(int position, @Nonnull String expression, @Nonnull String messageCode, @Nonnull List<?> messagesArgs) {
|
||||
final ParseException exception = !list.isEmpty() ? list.remove(list.size() - 1) : new ParseException();
|
||||
exception.set(position, expression, messageCode, messagesArgs);
|
||||
return exception;
|
||||
}
|
||||
|
||||
public void release(@Nonnull ParseException e) {
|
||||
list.add(e);
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ public class ExpressionParser implements Parser<Generic> {
|
||||
try {
|
||||
result = result.add(PlusOrMinusTerm.parser.parse(p, result));
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import jscl.util.ArrayUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ImplicitFunctionParser implements Parser<Function> {
|
||||
@ -25,7 +26,7 @@ public class ImplicitFunctionParser implements Parser<Function> {
|
||||
final String name = ParserUtils.parseWithRollback(CompoundIdentifier.parser, pos0, previousSumElement, p);
|
||||
if (FunctionsRegistry.getInstance().getNames().contains(name) || OperatorsRegistry.getInstance().getNames().contains(name)) {
|
||||
p.position.setValue(pos0);
|
||||
throw new ParseException(Messages.msg_6, p.position.intValue(), p.expression, name);
|
||||
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_6, Collections.singletonList(name));
|
||||
}
|
||||
|
||||
final List<Generic> subscripts = new ArrayList<Generic>();
|
||||
@ -33,6 +34,7 @@ public class ImplicitFunctionParser implements Parser<Function> {
|
||||
try {
|
||||
subscripts.add(Subscript.parser.parse(p, previousSumElement));
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -41,6 +43,7 @@ public class ImplicitFunctionParser implements Parser<Function> {
|
||||
try {
|
||||
b = Derivation.parser.parse(p, previousSumElement);
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
b = new int[0];
|
||||
}
|
||||
try {
|
||||
@ -67,15 +70,12 @@ class Derivation implements Parser<int[]> {
|
||||
}
|
||||
|
||||
public int[] parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
|
||||
|
||||
int result[];
|
||||
try {
|
||||
result = new int[]{PrimeCharacters.parser.parse(p, previousSumElement)};
|
||||
return new int[]{PrimeCharacters.parser.parse(p, previousSumElement)};
|
||||
} catch (ParseException e) {
|
||||
result = SuperscriptList.parser.parse(p, previousSumElement);
|
||||
p.exceptionsPool.release(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
return SuperscriptList.parser.parse(p, previousSumElement);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +103,7 @@ class SuperscriptList implements Parser<int[]> {
|
||||
try {
|
||||
result.add(CommaAndInteger.parser.parse(p, previousSumElement));
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import jscl.text.msg.Messages;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
|
||||
public class IntegerParser implements Parser<Integer> {
|
||||
|
||||
@ -46,7 +47,7 @@ public class IntegerParser implements Parser<Integer> {
|
||||
result.append(c);
|
||||
} else {
|
||||
p.position.setValue(pos0);
|
||||
throw new ParseException(Messages.msg_7, p.position.intValue(), p.expression);
|
||||
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_7);
|
||||
}
|
||||
|
||||
while (p.position.intValue() < p.expression.length() && nb.getAcceptableCharacters().contains(p.expression.charAt(p.position.intValue()))) {
|
||||
@ -59,7 +60,7 @@ public class IntegerParser implements Parser<Integer> {
|
||||
try {
|
||||
return nb.toInteger(number);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ParseException(Messages.msg_8, p.position.intValue(), p.expression, number);
|
||||
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_8, Collections.singletonList(number));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import jscl.text.msg.Messages;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
|
||||
public class JsclIntegerParser implements Parser<JsclInteger> {
|
||||
|
||||
@ -33,7 +34,7 @@ public class JsclIntegerParser implements Parser<JsclInteger> {
|
||||
try {
|
||||
return nb.toJsclInteger(number);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ParseException(Messages.msg_8, p.position.intValue(), p.expression, number);
|
||||
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_8, Collections.singletonList(number));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ public class MatrixParser implements Parser<Matrix> {
|
||||
try {
|
||||
vectors.add(CommaAndVector.parser.parse(p, previousSumElement));
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package jscl.text;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.Matrix;
|
||||
import jscl.math.MatrixVariable;
|
||||
import jscl.math.Variable;
|
||||
|
||||
@ -14,12 +13,6 @@ class MatrixVariableParser implements Parser<Variable> {
|
||||
}
|
||||
|
||||
public Variable parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
|
||||
Matrix m;
|
||||
try {
|
||||
m = (Matrix) MatrixParser.parser.parse(p, previousSumElement);
|
||||
} catch (ParseException e) {
|
||||
throw e;
|
||||
}
|
||||
return new MatrixVariable(m);
|
||||
return new MatrixVariable(MatrixParser.parser.parse(p, previousSumElement));
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public class NumeralBaseParser implements Parser<NumeralBase> {
|
||||
result = numeralBase;
|
||||
break;
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,8 @@ public class ParameterListParser implements Parser<Generic[]> {
|
||||
if (minNumberOfParameters > 0) {
|
||||
p.position.setValue(pos0);
|
||||
throw e;
|
||||
} else {
|
||||
p.exceptionsPool.release(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +43,7 @@ public class ParameterListParser implements Parser<Generic[]> {
|
||||
try {
|
||||
result.add(CommaAndExpression.parser.parse(p, previousSumElement));
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +1,61 @@
|
||||
package jscl.text;
|
||||
|
||||
import jscl.text.msg.JsclMessage;
|
||||
import org.solovyev.common.collections.Collections;
|
||||
import org.solovyev.common.msg.Message;
|
||||
import org.solovyev.common.msg.MessageLevel;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class ParseException extends Exception implements Message {
|
||||
|
||||
private int position;
|
||||
@Nonnull
|
||||
private final Message message;
|
||||
|
||||
private final int position;
|
||||
|
||||
private String expression;
|
||||
@Nonnull
|
||||
private final String expression;
|
||||
private String messageCode;
|
||||
@Nonnull
|
||||
private List<?> parameters;
|
||||
|
||||
public ParseException(@Nonnull String messageCode, int position, @Nonnull String expression, Object... parameters) {
|
||||
this.message = new JsclMessage(messageCode, MessageType.error, parameters);
|
||||
this.position = position;
|
||||
this.expression = expression;
|
||||
ParseException() {
|
||||
}
|
||||
|
||||
public ParseException(@Nonnull Message message, int position, @Nonnull String expression) {
|
||||
this.message = message;
|
||||
public ParseException(int position, @Nonnull String expression, @Nonnull String messageCode, @Nullable Object... parameters) {
|
||||
set(position, expression, messageCode, Collections.asList(parameters));
|
||||
}
|
||||
|
||||
void set(int position, @Nonnull String expression, @Nonnull String messageCode, @Nonnull List<?> parameters) {
|
||||
this.position = position;
|
||||
this.expression = expression;
|
||||
this.messageCode = messageCode;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getMessageCode() {
|
||||
return this.message.getMessageCode();
|
||||
return messageCode;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<Object> getParameters() {
|
||||
return this.message.getParameters();
|
||||
return (List<Object>) parameters;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public MessageLevel getMessageLevel() {
|
||||
return this.message.getMessageLevel();
|
||||
return MessageType.error;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getLocalizedMessage(@Nonnull Locale locale) {
|
||||
return this.message.getLocalizedMessage(locale);
|
||||
final ResourceBundle rb = ResourceBundle.getBundle("jscl/text/msg/messages", locale);
|
||||
return rb.getString(getMessageCode());
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
@ -67,20 +72,21 @@ public class ParseException extends Exception implements Message {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ParseException that = (ParseException) o;
|
||||
ParseException exception = (ParseException) o;
|
||||
|
||||
if (position != that.position) return false;
|
||||
if (!expression.equals(that.expression)) return false;
|
||||
if (!message.equals(that.message)) return false;
|
||||
if (position != exception.position) return false;
|
||||
if (!expression.equals(exception.expression)) return false;
|
||||
if (!messageCode.equals(exception.messageCode)) return false;
|
||||
return parameters.equals(exception.parameters);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = message.hashCode();
|
||||
result = 31 * result + position;
|
||||
int result = position;
|
||||
result = 31 * result + expression.hashCode();
|
||||
result = 31 * result + messageCode.hashCode();
|
||||
result = 31 * result + parameters.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,9 @@ public interface Parser<T> {
|
||||
@Nonnull
|
||||
public final MathContext context;
|
||||
|
||||
@Nonnull
|
||||
public final ExceptionsPool exceptionsPool = new ExceptionsPool();
|
||||
|
||||
/**
|
||||
* @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)
|
||||
|
@ -2,6 +2,7 @@ package jscl.text;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import jscl.text.msg.Messages;
|
||||
import org.solovyev.common.collections.Collections;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@ -67,7 +68,7 @@ public class ParserUtils {
|
||||
@Nonnull String messageId,
|
||||
Object... parameters) throws ParseException {
|
||||
final MutableInt position = p.position;
|
||||
final ParseException parseException = new ParseException(messageId, position.intValue(), p.expression, parameters);
|
||||
final ParseException parseException = p.exceptionsPool.obtain(position.intValue(), p.expression, messageId, Collections.asList(parameters));
|
||||
position.setValue(pos0);
|
||||
throw parseException;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ 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;
|
||||
|
||||
/**
|
||||
@ -28,11 +29,11 @@ public class PostfixFunctionsParser implements Parser<Generic> {
|
||||
private static Generic parsePostfix(@Nonnull List<PostfixFunctionParser> parsers,
|
||||
Generic content,
|
||||
@Nullable final Generic previousSumElement,
|
||||
@Nonnull final Parameters parseParameters) throws ParseException {
|
||||
@Nonnull final Parameters p) throws ParseException {
|
||||
Generic result = content;
|
||||
|
||||
for (PostfixFunctionParser parser : parsers) {
|
||||
final PostfixFunctionParser.Result postfixResult = parser.parse(parseParameters, previousSumElement);
|
||||
final PostfixFunctionParser.Result postfixResult = parser.parse(p, previousSumElement);
|
||||
if (postfixResult.isPostfixFunction()) {
|
||||
final Operator postfixFunction;
|
||||
|
||||
@ -44,13 +45,13 @@ public class PostfixFunctionsParser implements Parser<Generic> {
|
||||
|
||||
if (postfixFunction == null) {
|
||||
if (TripleFactorial.NAME.equals(postfixResult.getPostfixFunctionName())) {
|
||||
throw new ParseException(Messages.msg_18, parseParameters.position.intValue(), parseParameters.expression);
|
||||
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_18);
|
||||
} else {
|
||||
throw new ParseException(Messages.msg_4, parseParameters.position.intValue(), parseParameters.expression, postfixResult.getPostfixFunctionName());
|
||||
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_4, Collections.singletonList(postfixResult.getPostfixFunctionName()));
|
||||
}
|
||||
}
|
||||
|
||||
result = parsePostfix(parsers, postfixFunction.expressionValue(), previousSumElement, parseParameters);
|
||||
result = parsePostfix(parsers, postfixFunction.expressionValue(), previousSumElement, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ class TermParser implements Parser<Generic> {
|
||||
result = result.multiply(s);
|
||||
s = b;
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
try {
|
||||
Generic b = DivideFactor.parser.parse(p, null);
|
||||
if (s.compareTo(JsclInteger.valueOf(1)) == 0)
|
||||
@ -38,6 +39,7 @@ class TermParser implements Parser<Generic> {
|
||||
else
|
||||
s = new Fraction(GenericVariable.content(s, true), GenericVariable.content(b, true)).expressionValue();
|
||||
} catch (ParseException e2) {
|
||||
p.exceptionsPool.release(e2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ class UnsignedFactor implements Parser {
|
||||
try {
|
||||
list.add(PowerExponentParser.parser.parse(p, null));
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ public class VectorParser implements Parser<JsclVector> {
|
||||
try {
|
||||
result.add(CommaAndExpression.parser.parse(p, previousSumElement));
|
||||
} catch (ParseException e) {
|
||||
p.exceptionsPool.release(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package jscl.text;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.JsclVector;
|
||||
import jscl.math.Variable;
|
||||
import jscl.math.VectorVariable;
|
||||
|
||||
@ -14,12 +13,6 @@ public class VectorVariableParser implements Parser<Variable> {
|
||||
}
|
||||
|
||||
public Variable parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
|
||||
JsclVector result;
|
||||
try {
|
||||
result = VectorParser.parser.parse(p, previousSumElement);
|
||||
} catch (ParseException e) {
|
||||
throw e;
|
||||
}
|
||||
return new VectorVariable(result);
|
||||
return new VectorVariable(VectorParser.parser.parse(p, previousSumElement));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user