Throw exception if expression contains a triple factorial

This commit is contained in:
serso 2016-04-27 20:58:55 +02:00
parent 96ead21537
commit 5315679add
2 changed files with 44 additions and 79 deletions

View File

@ -3,59 +3,29 @@ package jscl.text;
import jscl.math.Generic; import jscl.math.Generic;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** public class PostfixFunctionParser implements Parser<String> {
* User: serso
* Date: 10/27/11
* Time: 2:45 PM
*/
public class PostfixFunctionParser implements Parser<PostfixFunctionParser.Result> {
@Nonnull @Nonnull
private final String postfixFunctionName; private final String name;
protected PostfixFunctionParser(@Nonnull String postfixFunctionName) { protected PostfixFunctionParser(@Nonnull String name) {
this.postfixFunctionName = postfixFunctionName; this.name = name;
} }
@Nonnull @Nullable
public Result parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException { public String parse(@Nonnull Parameters p, Generic previousSumElement) throws ParseException {
int pos0 = p.position.intValue(); final int pos0 = p.position.intValue();
final boolean postfixFunction;
ParserUtils.skipWhitespaces(p); ParserUtils.skipWhitespaces(p);
if (p.position.intValue() < p.expression.length() && p.expression.startsWith(postfixFunctionName, p.position.intValue())) { if (p.position.intValue() < p.expression.length() && p.expression.startsWith(name, p.position.intValue())) {
p.position.add(postfixFunctionName.length()); p.position.add(name.length());
postfixFunction = true; return name;
} else { } else {
p.position.setValue(pos0); p.position.setValue(pos0);
postfixFunction = false; return null;
}
return new Result(postfixFunctionName, postfixFunction);
}
public static class Result {
@Nonnull
private final String postfixFunctionName;
private final boolean postfixFunction;
public Result(@Nonnull String postfixFunctionName, boolean postfixFunction) {
this.postfixFunctionName = postfixFunctionName;
this.postfixFunction = postfixFunction;
}
public boolean isPostfixFunction() {
return postfixFunction;
}
@Nonnull
public String getPostfixFunctionName() {
return postfixFunctionName;
} }
} }
} }

View File

@ -1,24 +1,22 @@
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;
* User: serso import javax.annotation.Nullable;
* Date: 10/31/11 import java.util.List;
* Time: 11:20 PM
*/ import static java.util.Collections.singletonList;
public class PostfixFunctionsParser implements Parser<Generic> { public class PostfixFunctionsParser implements Parser<Generic> {
private static final PostfixFunctionsRegistry registry = PostfixFunctionsRegistry.getInstance();
private static final PostfixFunctionParser tripleFactorialParser = new PostfixFunctionParser(TripleFactorial.NAME);
@Nonnull @Nonnull
private final Generic content; private final Generic content;
@ -27,39 +25,36 @@ public class PostfixFunctionsParser implements Parser<Generic> {
} }
private static Generic parsePostfix(@Nonnull List<String> names, private static Generic parsePostfix(@Nonnull List<String> names,
Generic content, final 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; checkTripleFactorial(previousSumElement, p);
for (String name : names) { for (int i = 0; i < names.size(); i++) {
final PostfixFunctionParser parser = new PostfixFunctionParser(name); final PostfixFunctionParser parser = new PostfixFunctionParser(names.get(i));
final PostfixFunctionParser.Result postfixResult = parser.parse(p, previousSumElement); final String functionName = parser.parse(p, previousSumElement);
if (postfixResult.isPostfixFunction()) { if (functionName == null) {
final Operator postfixFunction; continue;
}
final Generic[] parameters = previousSumElement == null ? new Generic[]{content} : new Generic[]{content, previousSumElement};
final Operator function = registry.get(functionName, parameters);
if (previousSumElement == null) { if (function != null) {
postfixFunction = PostfixFunctionsRegistry.getInstance().get(postfixResult.getPostfixFunctionName(), new Generic[]{content}); return parsePostfix(names, function.expressionValue(), previousSumElement, p);
} else {
postfixFunction = PostfixFunctionsRegistry.getInstance().get(postfixResult.getPostfixFunctionName(), new Generic[]{content, previousSumElement});
} }
if (postfixFunction == null) { throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_4, singletonList(functionName));
if (TripleFactorial.NAME.equals(postfixResult.getPostfixFunctionName())) { }
return content;
}
private static void checkTripleFactorial(@Nullable Generic previousSumElement, @Nonnull Parameters p) throws ParseException {
if (tripleFactorialParser.parse(p, previousSumElement) != null) {
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_18); throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_18);
} else {
throw p.exceptionsPool.obtain(p.position.intValue(), p.expression, Messages.msg_4, Collections.singletonList(postfixResult.getPostfixFunctionName()));
} }
} }
result = parsePostfix(names, postfixFunction.expressionValue(), previousSumElement, p);
}
}
return result;
}
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); return parsePostfix(registry.getNames(), content, previousSumElement, p);
} }
} }