summaryrefslogtreecommitdiff
path: root/JPratt/src/main/java/bjc/pratt/commands
diff options
context:
space:
mode:
authorBen Culkin <scorpress@gmail.com>2022-08-16 23:03:27 -0400
committerBen Culkin <scorpress@gmail.com>2022-08-16 23:03:27 -0400
commitcea3e47938322b97c318dea38dc0d649e196dc1b (patch)
tree0ceef0bafbfed7aa5802e8fc526c0c98276f1fff /JPratt/src/main/java/bjc/pratt/commands
parent4869146748ed51eb212935d2b971388fb9e73d37 (diff)
Refactor to add backtracking support
This probably doesn't help w/ error messages, but it enables some cool ideas where syntax can be reused in cases where it would otherwise be invalid
Diffstat (limited to 'JPratt/src/main/java/bjc/pratt/commands')
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/AbstractInitialCommand.java4
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/BinaryCommand.java9
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/CommandResult.java97
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/InitialCommand.java4
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/NonInitialCommand.java4
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/BlockInitialCommand.java3
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/ChainCommand.java17
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/ConstantCommand.java5
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/DefaultInitialCommand.java3
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/DefaultNonInitialCommand.java3
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/DenestingCommand.java8
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/GroupingCommand.java9
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/InitialCommands.java13
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/LeafCommand.java5
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/PanfixCommand.java39
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/PostCircumfixCommand.java11
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/PostfixCommand.java5
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/PreTernaryCommand.java21
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/TernaryCommand.java47
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/TransformingInitialCommand.java9
-rw-r--r--JPratt/src/main/java/bjc/pratt/commands/impls/UnaryCommand.java10
21 files changed, 246 insertions, 80 deletions
diff --git a/JPratt/src/main/java/bjc/pratt/commands/AbstractInitialCommand.java b/JPratt/src/main/java/bjc/pratt/commands/AbstractInitialCommand.java
index 50e884b..48f9ba7 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/AbstractInitialCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/AbstractInitialCommand.java
@@ -21,7 +21,7 @@ import bjc.utils.parserutils.ParserException;
*/
public abstract class AbstractInitialCommand<K, V, C> implements InitialCommand<K, V, C> {
@Override
- public Tree<Token<K, V>> denote(final Token<K, V> operator,
+ public CommandResult<K, V> denote(final Token<K, V> operator,
final ParserContext<K, V, C> ctx) throws ParserException {
return intNullDenotation(operator, ctx);
}
@@ -39,7 +39,7 @@ public abstract class AbstractInitialCommand<K, V, C> implements InitialCommand<
* @throws ParserException
* If something went wrong while parsing.
*/
- protected abstract Tree<Token<K, V>> intNullDenotation(Token<K, V> operator,
+ protected abstract CommandResult<K, V> intNullDenotation(Token<K, V> operator,
ParserContext<K, V, C> ctx) throws ParserException;
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/BinaryCommand.java b/JPratt/src/main/java/bjc/pratt/commands/BinaryCommand.java
index 069de78..7a65052 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/BinaryCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/BinaryCommand.java
@@ -1,6 +1,7 @@
package bjc.pratt.commands;
import bjc.pratt.ParserContext;
+import bjc.pratt.commands.CommandResult.Status;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.data.SimpleTree;
@@ -39,12 +40,14 @@ public abstract class BinaryCommand<K, V, C> extends BinaryPostCommand<K, V, C>
protected abstract int rightBinding();
@Override
- public Tree<Token<K, V>> denote(final Tree<Token<K, V>> operand,
+ public CommandResult<K, V> denote(final Tree<Token<K, V>> operand,
final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
- final Tree<Token<K, V>> opr
+ final CommandResult<K,V> opr
= ctx.parse.parseExpression(rightBinding(), ctx.tokens, ctx.state, false);
+
+ if (opr.status != Status.SUCCESS) return opr;
- return new SimpleTree<>(operator, operand, opr);
+ return CommandResult.success(new SimpleTree<>(operator, operand, opr.success()));
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/CommandResult.java b/JPratt/src/main/java/bjc/pratt/commands/CommandResult.java
new file mode 100644
index 0000000..d27400f
--- /dev/null
+++ b/JPratt/src/main/java/bjc/pratt/commands/CommandResult.java
@@ -0,0 +1,97 @@
+package bjc.pratt.commands;
+
+import bjc.data.Tree;
+import bjc.pratt.tokens.Token;
+
+/**
+ * Represents the result of executing a command.
+ *
+ * @author bjcul
+ *
+ * @param <K> The key type of the tokens
+ * @param <V> The value type of the tokens
+ */
+public class CommandResult<K, V> {
+ /**
+ * Represents the status of a command execution
+ *
+ * @author bjcul
+ *
+ */
+ public static enum Status {
+ /**
+ * The command successfully parsed.
+ */
+ SUCCESS,
+ /**
+ * The command failed, in a non-recoverable way
+ */
+ FAIL,
+ /**
+ * The command failed. Attempt recovery via backtracking
+ */
+ BACKTRACK
+ }
+
+ /**
+ * The status of this command.
+ */
+ public final Status status;
+
+ private Tree<Token<K, V>> success;
+
+ private CommandResult(Status status) {
+ this.status = status;
+ }
+
+ /**
+ * Get the success value of this command, or null if it failed.
+ *
+ * @return The success value of the command
+ */
+ public Tree<Token<K, V>> success() {
+ return success;
+ }
+
+ /**
+ * Create a success result
+ *
+ * @param <K2> The key type of the token
+ * @param <V2> The value type of the token
+ *
+ * @param succ The tree produced by the command
+ *
+ * @return A command result representing a success
+ */
+ public static <K2, V2> CommandResult<K2, V2> success(Tree<Token<K2, V2>> succ) {
+ CommandResult<K2, V2> result = new CommandResult<>(Status.SUCCESS);
+ result.success = succ;
+ return result;
+ }
+
+ /**
+ * Create a non-backtracking failure result.
+ *
+ * @param <K2> The key type of the token
+ * @param <V2> The value type of the token
+ *
+ * @return A command result representing a non-backtracking fail
+ */
+ public static <K2, V2> CommandResult<K2, V2> fail() {
+ CommandResult<K2, V2> result = new CommandResult<>(Status.FAIL);
+ return result;
+ }
+
+ /**
+ * Create a backtracking failure result.
+ *
+ * @param <K2> The key type of the token
+ * @param <V2> The value type of the token
+ *
+ * @return A command result representing a backtracking fail
+ */
+ public static <K2, V2> CommandResult<K2, V2> backtrack() {
+ CommandResult<K2, V2> result = new CommandResult<>(Status.BACKTRACK);
+ return result;
+ }
+}
diff --git a/JPratt/src/main/java/bjc/pratt/commands/InitialCommand.java b/JPratt/src/main/java/bjc/pratt/commands/InitialCommand.java
index 3a2a8ff..ba544b4 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/InitialCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/InitialCommand.java
@@ -31,10 +31,10 @@ public interface InitialCommand<K, V, C> {
* @param ctx
* The context for the command.
*
- * @return The tree for this command.
+ * @return The result of executing the command.
*
* @throws ParserException
* If something goes wrong during parsing.
*/
- Tree<Token<K, V>> denote(Token<K, V> operator, ParserContext<K, V, C> ctx) throws ParserException;
+ CommandResult<K, V> denote(Token<K, V> operator, ParserContext<K, V, C> ctx) throws ParserException;
}
diff --git a/JPratt/src/main/java/bjc/pratt/commands/NonInitialCommand.java b/JPratt/src/main/java/bjc/pratt/commands/NonInitialCommand.java
index 12eecb6..02826a9 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/NonInitialCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/NonInitialCommand.java
@@ -32,12 +32,12 @@ public abstract class NonInitialCommand<K, V, C> {
* @param ctx
* The state needed for commands.
*
- * @return The tree this command forms.
+ * @return The result of executing the command.
*
* @throws ParserException
* If something went wrong during parsing.
*/
- public abstract Tree<Token<K, V>> denote(Tree<Token<K, V>> operand, Token<K, V> operator,
+ public abstract CommandResult<K, V> denote(Tree<Token<K, V>> operand, Token<K, V> operator,
ParserContext<K, V, C> ctx) throws ParserException;
/**
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/BlockInitialCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/BlockInitialCommand.java
index db11484..1d54996 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/BlockInitialCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/BlockInitialCommand.java
@@ -3,6 +3,7 @@ package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
import bjc.pratt.blocks.ParseBlock;
import bjc.pratt.commands.AbstractInitialCommand;
+import bjc.pratt.commands.CommandResult;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.utils.parserutils.ParserException;
@@ -35,7 +36,7 @@ public class BlockInitialCommand<K, V, C> extends AbstractInitialCommand<K, V, C
}
@Override
- protected Tree<Token<K, V>> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ protected CommandResult<K, V> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
return blck.parse(ctx);
}
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/ChainCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/ChainCommand.java
index ed7a088..7311eb9 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/ChainCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/ChainCommand.java
@@ -4,6 +4,8 @@ import java.util.Set;
import bjc.pratt.ParserContext;
import bjc.pratt.commands.BinaryPostCommand;
+import bjc.pratt.commands.CommandResult;
+import bjc.pratt.commands.CommandResult.Status;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.data.SimpleTree;
@@ -48,10 +50,12 @@ public class ChainCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
}
@Override
- public Tree<Token<K, V>> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
+ public CommandResult<K, V> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
final ParserContext<K, V, C> ctx) throws ParserException {
- final Tree<Token<K, V>> tree = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state,
+ CommandResult<K, V> resOuter = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state,
false);
+ if (resOuter.status != Status.SUCCESS) return resOuter;
+ final Tree<Token<K, V>> tree = resOuter.success();
final Tree<Token<K, V>> res = new SimpleTree<>(operator, operand, tree);
@@ -59,13 +63,16 @@ public class ChainCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
final Token<K, V> tok = ctx.tokens.current();
ctx.tokens.next();
- final Tree<Token<K, V>> other = denote(tree, tok,
+ CommandResult<K, V> resOther = denote(tree, tok,
new ParserContext<>(ctx.tokens, ctx.parse, ctx.state));
+ if (resOther.status != Status.SUCCESS) return resOther;
+
+ final Tree<Token<K, V>> other = resOther.success();
- return new SimpleTree<>(chain, res, other);
+ return CommandResult.success(new SimpleTree<>(chain, res, other));
}
- return res;
+ return CommandResult.success(res);
}
@Override
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/ConstantCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/ConstantCommand.java
index 409adbb..657743c 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/ConstantCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/ConstantCommand.java
@@ -1,6 +1,7 @@
package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
+import bjc.pratt.commands.CommandResult;
import bjc.pratt.commands.InitialCommand;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
@@ -34,8 +35,8 @@ public class ConstantCommand<K, V, C> implements InitialCommand<K, V, C> {
}
@Override
- public Tree<Token<K, V>> denote(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ public CommandResult<K, V> denote(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
- return val;
+ return CommandResult.success(val);
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/DefaultInitialCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/DefaultInitialCommand.java
index 296cb1c..2dfc576 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/DefaultInitialCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/DefaultInitialCommand.java
@@ -1,6 +1,7 @@
package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
+import bjc.pratt.commands.CommandResult;
import bjc.pratt.commands.InitialCommand;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
@@ -22,7 +23,7 @@ import bjc.utils.parserutils.ParserException;
*/
public class DefaultInitialCommand<K, V, C> implements InitialCommand<K, V, C> {
@Override
- public Tree<Token<K, V>> denote(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ public CommandResult<K, V> denote(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
throw new ParserException("Unexpected token " + operator);
}
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/DefaultNonInitialCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/DefaultNonInitialCommand.java
index 797473a..2ae9fb7 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/DefaultNonInitialCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/DefaultNonInitialCommand.java
@@ -1,6 +1,7 @@
package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
+import bjc.pratt.commands.CommandResult;
import bjc.pratt.commands.NonInitialCommand;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
@@ -21,7 +22,7 @@ import bjc.data.Tree;
*/
public class DefaultNonInitialCommand<K, V, C> extends NonInitialCommand<K, V, C> {
@Override
- public Tree<Token<K, V>> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
+ public CommandResult<K, V> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
final ParserContext<K, V, C> ctx) {
throw new UnsupportedOperationException("Default command has no left denotation");
}
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/DenestingCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/DenestingCommand.java
index fbcd35c..4935c81 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/DenestingCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/DenestingCommand.java
@@ -2,6 +2,8 @@ package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
import bjc.pratt.commands.AbstractInitialCommand;
+import bjc.pratt.commands.CommandResult;
+import bjc.pratt.commands.CommandResult.Status;
import bjc.pratt.commands.InitialCommand;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
@@ -39,8 +41,10 @@ public class DenestingCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
}
@Override
- protected Tree<Token<K, V>> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ protected CommandResult<K, V> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
- return wrapped.denote(operator, ctx).getChild(0);
+ CommandResult<K, V> res = wrapped.denote(operator, ctx);
+ if (res.status != Status.SUCCESS) return res;
+ return CommandResult.success(res.success().getChild(0));
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/GroupingCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/GroupingCommand.java
index 1515359..44aa2c1 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/GroupingCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/GroupingCommand.java
@@ -3,6 +3,7 @@ package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
import bjc.pratt.blocks.ParseBlock;
import bjc.pratt.commands.AbstractInitialCommand;
+import bjc.pratt.commands.CommandResult;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.data.SimpleTree;
@@ -43,10 +44,10 @@ public class GroupingCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
}
@Override
- protected Tree<Token<K, V>> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ protected CommandResult<K, V> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
- final Tree<Token<K, V>> opr = innerBlock.parse(ctx);
-
- return new SimpleTree<>(mark, opr);
+ final CommandResult<K,V> resOpr = innerBlock.parse(ctx);
+ Tree<Token<K, V>> opr = resOpr.success();
+ return CommandResult.success(new SimpleTree<>(mark, opr));
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/InitialCommands.java b/JPratt/src/main/java/bjc/pratt/commands/impls/InitialCommands.java
index 0cfec29..9801788 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/InitialCommands.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/InitialCommands.java
@@ -9,6 +9,7 @@ import java.util.function.UnaryOperator;
import bjc.pratt.blocks.ParseBlock;
import bjc.pratt.commands.InitialCommand;
import bjc.pratt.tokens.Token;
+import bjc.utils.parserutils.ParserException;
import bjc.data.SimpleTree;
import bjc.data.Tree;
@@ -210,16 +211,6 @@ public class InitialCommands {
* @return A command that implements a panfix operator
*/
public static <K, V, C> InitialCommand<K, V, C> panfix(final int precedence, final K term, final Token<K, V> marker) {
- return (operator, ctx) -> {
- Tree<Token<K,V>> leftSide = ctx.parse.parseExpression(precedence + 1, ctx.tokens, ctx.state, false);
- ctx.tokens.expect(term);
- ctx.tokens.next();
-
- Tree<Token<K,V>> rightSide = ctx.parse.parseExpression(precedence + 1, ctx.tokens, ctx.state, false);
- ctx.tokens.expect(term);
- ctx.tokens.next();
-
- return new SimpleTree<>(marker, leftSide, rightSide);
- };
+ return new PanfixCommand<K, V, C>(marker, term, precedence);
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/LeafCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/LeafCommand.java
index 1223641..c702323 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/LeafCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/LeafCommand.java
@@ -1,6 +1,7 @@
package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
+import bjc.pratt.commands.CommandResult;
import bjc.pratt.commands.InitialCommand;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
@@ -23,8 +24,8 @@ import bjc.utils.parserutils.ParserException;
*/
public class LeafCommand<K, V, C> implements InitialCommand<K, V, C> {
@Override
- public Tree<Token<K, V>> denote(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ public CommandResult<K, V> denote(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
- return new SimpleTree<>(operator);
+ return CommandResult.success(new SimpleTree<>(operator));
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/PanfixCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/PanfixCommand.java
new file mode 100644
index 0000000..06e69c1
--- /dev/null
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/PanfixCommand.java
@@ -0,0 +1,39 @@
+package bjc.pratt.commands.impls;
+
+import bjc.data.SimpleTree;
+import bjc.data.Tree;
+import bjc.pratt.ParserContext;
+import bjc.pratt.commands.CommandResult;
+import bjc.pratt.commands.InitialCommand;
+import bjc.pratt.commands.CommandResult.Status;
+import bjc.pratt.tokens.Token;
+import bjc.utils.parserutils.ParserException;
+
+public final class PanfixCommand<K, V, C> implements InitialCommand<K, V, C> {
+ private final Token<K, V> marker;
+ private final K term;
+ private final int precedence;
+
+ public PanfixCommand(Token<K, V> marker, K term, int precedence) {
+ this.marker = marker;
+ this.term = term;
+ this.precedence = precedence;
+ }
+
+ @Override
+ public CommandResult<K, V> denote(Token<K, V> operator, ParserContext<K, V, C> ctx) throws ParserException {
+ CommandResult<K,V> resLeftSide = ctx.parse.parseExpression(precedence + 1, ctx.tokens, ctx.state, false);
+ if (resLeftSide.status != Status.SUCCESS) return resLeftSide;
+ Tree<Token<K, V>> leftSide = resLeftSide.success();
+ ctx.tokens.expect(term);
+ ctx.tokens.next();
+
+ CommandResult<K, V> resRightSide = ctx.parse.parseExpression(precedence + 1, ctx.tokens, ctx.state, false);
+ if (resLeftSide.status != Status.SUCCESS) return resRightSide;
+ Tree<Token<K,V>> rightSide = resRightSide.success();
+ ctx.tokens.expect(term);
+ ctx.tokens.next();
+
+ return CommandResult.success(new SimpleTree<>(marker, leftSide, rightSide));
+ }
+} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/PostCircumfixCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/PostCircumfixCommand.java
index 78ac1ef..ec2c8fb 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/PostCircumfixCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/PostCircumfixCommand.java
@@ -3,6 +3,8 @@ package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
import bjc.pratt.blocks.ParseBlock;
import bjc.pratt.commands.BinaryPostCommand;
+import bjc.pratt.commands.CommandResult;
+import bjc.pratt.commands.CommandResult.Status;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.data.SimpleTree;
@@ -50,10 +52,11 @@ public class PostCircumfixCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
}
@Override
- public Tree<Token<K, V>> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
+ public CommandResult<K, V> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
final ParserContext<K, V, C> ctx) throws ParserException {
- final Tree<Token<K, V>> inside = innerBlock.parse(ctx);
-
- return new SimpleTree<>(mark, operand, inside);
+ final CommandResult<K,V> insideRes = innerBlock.parse(ctx);
+ if (insideRes.status != Status.SUCCESS) return insideRes;
+ Tree<Token<K, V>> inside = insideRes.success();
+ return CommandResult.success(new SimpleTree<>(mark, operand, inside));
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/PostfixCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/PostfixCommand.java
index da587c1..ff370d0 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/PostfixCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/PostfixCommand.java
@@ -2,6 +2,7 @@ package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
import bjc.pratt.commands.BinaryPostCommand;
+import bjc.pratt.commands.CommandResult;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.data.SimpleTree;
@@ -33,8 +34,8 @@ public class PostfixCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
}
@Override
- public Tree<Token<K, V>> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
+ public CommandResult<K, V> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
final ParserContext<K, V, C> ctx) throws ParserException {
- return new SimpleTree<>(operator, operand);
+ return CommandResult.success(new SimpleTree<>(operator, operand));
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/PreTernaryCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/PreTernaryCommand.java
index e315804..5d5cbe1 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/PreTernaryCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/PreTernaryCommand.java
@@ -3,6 +3,8 @@ package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
import bjc.pratt.blocks.ParseBlock;
import bjc.pratt.commands.AbstractInitialCommand;
+import bjc.pratt.commands.CommandResult;
+import bjc.pratt.commands.CommandResult.Status;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.data.SimpleTree;
@@ -63,14 +65,19 @@ public class PreTernaryCommand<K, V, C> extends AbstractInitialCommand<K, V, C>
}
@Override
- protected Tree<Token<K, V>> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ protected CommandResult<K, V> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
- final Tree<Token<K, V>> cond = condBlock.parse(ctx);
+ final CommandResult<K,V> condRes = condBlock.parse(ctx);
+ if (condRes.status != Status.SUCCESS) return condRes;
+ Tree<Token<K, V>> cond = condRes.success();
+
+ final CommandResult<K,V> op1Res = opblock1.parse(ctx);
+ if (op1Res.status != Status.SUCCESS) return op1Res;
+ Tree<Token<K, V>> op1 = op1Res.success();
- final Tree<Token<K, V>> op1 = opblock1.parse(ctx);
-
- final Tree<Token<K, V>> op2 = opblock2.parse(ctx);
-
- return new SimpleTree<>(trm, cond, op1, op2);
+ final CommandResult<K,V> op2Res = opblock2.parse(ctx);
+ if (op2Res.status != Status.SUCCESS) return op2Res;
+ Tree<Token<K, V>> op2 = op2Res.success();
+ return CommandResult.success(new SimpleTree<>(trm, cond, op1, op2));
}
} \ No newline at end of file
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/TernaryCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/TernaryCommand.java
index 174f6fb..786dfec 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/TernaryCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/TernaryCommand.java
@@ -3,6 +3,8 @@ package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
import bjc.pratt.blocks.ParseBlock;
import bjc.pratt.commands.BinaryPostCommand;
+import bjc.pratt.commands.CommandResult;
+import bjc.pratt.commands.CommandResult.Status;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.data.SimpleTree;
@@ -13,14 +15,11 @@ import bjc.utils.parserutils.ParserException;
*
* @author bjculkin
*
- * @param <K>
- * The key type of the tokens.
+ * @param <K> The key type of the tokens.
*
- * @param <V>
- * The value type of the tokens.
+ * @param <V> The value type of the tokens.
*
- * @param <C>
- * The state type of the parser.
+ * @param <C> The state type of the parser.
*/
public class TernaryCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
private final ParseBlock<K, V, C> innerBlck;
@@ -32,25 +31,22 @@ public class TernaryCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
/**
* Create a new ternary command.
*
- * @param precedence
- * The precedence of this operator.
+ * @param precedence The precedence of this operator.
*
- * @param innerBlock
- * The representation of the inner block of the expression.
+ * @param innerBlock The representation of the inner block of the expression.
*
- * @param marker
- * The token to use as the root of the AST node.
+ * @param marker The token to use as the root of the AST node.
*
- * @param isNonassoc
- * Whether or not the conditional is associative.
+ * @param isNonassoc Whether or not the conditional is associative.
*/
public TernaryCommand(final int precedence, final ParseBlock<K, V, C> innerBlock, final Token<K, V> marker,
final boolean isNonassoc) {
super(precedence);
- if(innerBlock == null)
+ if (innerBlock == null)
throw new NullPointerException("Inner block must not be null");
- else if(marker == null) throw new NullPointerException("Marker must not be null");
+ else if (marker == null)
+ throw new NullPointerException("Marker must not be null");
innerBlck = innerBlock;
mark = marker;
@@ -58,19 +54,22 @@ public class TernaryCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
}
@Override
- public Tree<Token<K, V>> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
+ public CommandResult<K, V> denote(final Tree<Token<K, V>> operand, final Token<K, V> operator,
final ParserContext<K, V, C> ctx) throws ParserException {
- final Tree<Token<K, V>> inner = innerBlck.parse(ctx);
-
- final Tree<Token<K, V>> outer = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state,
- false);
-
- return new SimpleTree<>(mark, inner, operand, outer);
+ final CommandResult<K, V> innerRes = innerBlck.parse(ctx);
+ if (innerRes.status != Status.SUCCESS) return innerRes;
+ Tree<Token<K, V>> inner = innerRes.success();
+
+ final CommandResult<K,V> outerRes = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state, false);
+ if (outerRes.status != Status.SUCCESS) return outerRes;
+ Tree<Token<K, V>> outer = outerRes.success();
+ return CommandResult.success(new SimpleTree<>(mark, inner, operand, outer));
}
@Override
public int nextBinding() {
- if(nonassoc) return leftBinding() - 1;
+ if (nonassoc)
+ return leftBinding() - 1;
return leftBinding();
}
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/TransformingInitialCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/TransformingInitialCommand.java
index d39ec90..36f881d 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/TransformingInitialCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/TransformingInitialCommand.java
@@ -4,6 +4,8 @@ import java.util.function.UnaryOperator;
import bjc.pratt.ParserContext;
import bjc.pratt.commands.AbstractInitialCommand;
+import bjc.pratt.commands.CommandResult;
+import bjc.pratt.commands.CommandResult.Status;
import bjc.pratt.commands.InitialCommand;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
@@ -45,9 +47,12 @@ public class TransformingInitialCommand<K, V, C> extends AbstractInitialCommand<
}
@Override
- protected Tree<Token<K, V>> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ protected CommandResult<K, V> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
- return transfrm.apply(internl.denote(operator, ctx));
+ CommandResult<K,V> result = internl.denote(operator, ctx);
+ if (result.status != Status.SUCCESS) return result;
+
+ return CommandResult.success(transfrm.apply(result.success()));
}
}
diff --git a/JPratt/src/main/java/bjc/pratt/commands/impls/UnaryCommand.java b/JPratt/src/main/java/bjc/pratt/commands/impls/UnaryCommand.java
index 2e7365b..657c004 100644
--- a/JPratt/src/main/java/bjc/pratt/commands/impls/UnaryCommand.java
+++ b/JPratt/src/main/java/bjc/pratt/commands/impls/UnaryCommand.java
@@ -2,6 +2,8 @@ package bjc.pratt.commands.impls;
import bjc.pratt.ParserContext;
import bjc.pratt.commands.AbstractInitialCommand;
+import bjc.pratt.commands.CommandResult;
+import bjc.pratt.commands.CommandResult.Status;
import bjc.pratt.tokens.Token;
import bjc.data.Tree;
import bjc.data.SimpleTree;
@@ -37,10 +39,12 @@ public class UnaryCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
}
@Override
- protected Tree<Token<K, V>> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
+ protected CommandResult<K, V> intNullDenotation(final Token<K, V> operator, final ParserContext<K, V, C> ctx)
throws ParserException {
- final Tree<Token<K, V>> opr = ctx.parse.parseExpression(nullPwer, ctx.tokens, ctx.state, false);
+ CommandResult<K,V> result = ctx.parse.parseExpression(nullPwer, ctx.tokens, ctx.state, false);
+ if (result.status != Status.SUCCESS) return result;
+ final Tree<Token<K, V>> opr = result.success();
- return new SimpleTree<>(operator, opr);
+ return CommandResult.success(new SimpleTree<>(operator, opr));
}
} \ No newline at end of file