summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands
diff options
context:
space:
mode:
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryPostCommand.java29
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DelimitedCommand.java65
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/GroupingCommand.java41
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InitialCommands.java26
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeafCommand.java18
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeftBinaryCommand.java24
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonBinaryCommand.java24
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonInitialCommands.java10
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostCircumfixCommand.java54
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostfixCommand.java28
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PreTernaryCommand.java72
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/RightBinaryCommand.java22
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TernaryCommand.java54
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TransformingInitialCommand.java52
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/UnaryCommand.java28
15 files changed, 402 insertions, 145 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryPostCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryPostCommand.java
index 7aaf735..806f2f3 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryPostCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryPostCommand.java
@@ -2,14 +2,35 @@ package bjc.utils.parserutils.pratt.commands;
import bjc.utils.parserutils.pratt.NonInitialCommand;
-/*
- * A command with constant binding power.
+/**
+ * A operator with fixed precedence.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
*/
public abstract class BinaryPostCommand<K, V, C> extends NonInitialCommand<K, V, C> {
private final int leftPower;
- public BinaryPostCommand(int power) {
- leftPower = power;
+ /**
+ * Create a new operator with fixed precedence.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ */
+ public BinaryPostCommand(int precedence) {
+ if (precedence < 0) {
+ throw new IllegalArgumentException("Precedence must be non-negative");
+ }
+
+ leftPower = precedence;
}
@Override
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DelimitedCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DelimitedCommand.java
deleted file mode 100644
index 090b2f4..0000000
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DelimitedCommand.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package bjc.utils.parserutils.pratt.commands;
-
-import bjc.utils.data.ITree;
-import bjc.utils.data.Tree;
-import bjc.utils.funcdata.FunctionalList;
-import bjc.utils.funcdata.IList;
-import bjc.utils.parserutils.ParserException;
-import bjc.utils.parserutils.pratt.ParserContext;
-import bjc.utils.parserutils.pratt.Token;
-
-import java.util.function.UnaryOperator;
-
-public class DelimitedCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
- private int inner;
-
- private K delim;
- private K mark;
-
- private Token<K, V> term;
-
- private UnaryOperator<C> onEnter;
- private UnaryOperator<C> onDelim;
- private UnaryOperator<C> onExit;
-
- private boolean statement;
-
- public DelimitedCommand(int inner, K delim, K mark, Token<K, V> term, UnaryOperator<C> onEnter,
- UnaryOperator<C> onDelim, UnaryOperator<C> onExit, boolean statement) {
- this.inner = inner;
- this.delim = delim;
- this.mark = mark;
- this.term = term;
- this.onEnter = onEnter;
- this.onDelim = onDelim;
- this.onExit = onExit;
- this.statement = statement;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- protected ITree<Token<K, V>> intNullDenotation(Token<K, V> operator, ParserContext<K, V, C> ctx)
- throws ParserException {
- C newState = onEnter.apply(ctx.state);
-
- IList<ITree<Token<K, V>>> kids = new FunctionalList<>();
-
- while(true) {
- ITree<Token<K, V>> kid = ctx.parse.parseExpression(inner, ctx.tokens, newState,
- statement);
- kids.add(kid);
-
- Token<K, V> tok = ctx.tokens.current();
-
- ctx.tokens.expect(delim, mark);
-
- if(tok.getKey().equals(mark)) break;
-
- newState = onDelim.apply(newState);
- }
-
- ctx.state = onExit.apply(newState);
-
- return new Tree<>(term, kids);
- }
-} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/GroupingCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/GroupingCommand.java
index 407a39e..37cc6ee 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/GroupingCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/GroupingCommand.java
@@ -3,27 +3,48 @@ package bjc.utils.parserutils.pratt.commands;
import bjc.utils.data.ITree;
import bjc.utils.data.Tree;
import bjc.utils.parserutils.ParserException;
+import bjc.utils.parserutils.pratt.ParseBlock;
import bjc.utils.parserutils.pratt.ParserContext;
import bjc.utils.parserutils.pratt.Token;
+/**
+ * A grouping operator.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class GroupingCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
- private K term;
- private Token<K, V> mark;
- private int inner;
+ private ParseBlock<K, V, C> innerBlock;
+
+ private Token<K, V> mark;
+
+ /**
+ * Create a new grouping command.
+ *
+ * @param inner
+ * The inner block.
+ *
+ * @param marker
+ * The token to use as the node in the AST.
+ */
+ public GroupingCommand(ParseBlock<K, V, C> inner, Token<K, V> marker) {
+ innerBlock = inner;
- public GroupingCommand(int innerPrec, K terminator, Token<K, V> marker) {
- inner = innerPrec;
- term = terminator;
mark = marker;
}
- @SuppressWarnings("unchecked")
@Override
protected ITree<Token<K, V>> intNullDenotation(Token<K, V> operator, ParserContext<K, V, C> ctx)
throws ParserException {
- ITree<Token<K, V>> opr = ctx.parse.parseExpression(inner, ctx.tokens, ctx.state, false);
-
- ctx.tokens.expect(term);
+ ITree<Token<K, V>> opr = innerBlock.parse(ctx);
return new Tree<>(mark, opr);
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InitialCommands.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InitialCommands.java
index d9e7f90..bad5964 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InitialCommands.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InitialCommands.java
@@ -2,7 +2,11 @@ package bjc.utils.parserutils.pratt.commands;
import bjc.utils.data.ITree;
import bjc.utils.parserutils.pratt.InitialCommand;
+import bjc.utils.parserutils.pratt.ParseBlock;
import bjc.utils.parserutils.pratt.Token;
+import bjc.utils.parserutils.pratt.blocks.RepeatingParseBlock;
+import bjc.utils.parserutils.pratt.blocks.SimpleParseBlock;
+import bjc.utils.parserutils.pratt.blocks.TriggeredParseBlock;
import java.util.function.UnaryOperator;
@@ -41,7 +45,9 @@ public class InitialCommands {
* @return A command implementing the operator.
*/
public static <K, V, C> InitialCommand<K, V, C> grouping(int precedence, K term, Token<K, V> mark) {
- return new GroupingCommand<>(precedence, term, mark);
+ ParseBlock<K, V, C> innerBlock = new SimpleParseBlock<>(precedence, term, null);
+
+ return new GroupingCommand<>(innerBlock, mark);
}
/**
@@ -78,7 +84,11 @@ public class InitialCommands {
*/
public static <K, V, C> InitialCommand<K, V, C> preTernary(int cond1, int block1, int block2, K mark1, K mark2,
Token<K, V> term) {
- return new PreTernaryCommand<>(cond1, block1, block2, mark1, mark2, term);
+ ParseBlock<K, V, C> condBlock = new SimpleParseBlock<>(cond1, mark1, null);
+ ParseBlock<K, V, C> opblock1 = new SimpleParseBlock<>(block1, mark2, null);
+ ParseBlock<K, V, C> opblock2 = new SimpleParseBlock<>(block2, null, null);
+
+ return new PreTernaryCommand<>(condBlock, opblock1, opblock2, term);
}
/**
@@ -129,6 +139,16 @@ public class InitialCommands {
public static <K, V, C> InitialCommand<K, V, C> delimited(int inner, K delim, K mark, Token<K, V> term,
UnaryOperator<C> onEnter, UnaryOperator<C> onDelim, UnaryOperator<C> onExit,
boolean statement) {
- return new DelimitedCommand<>(inner, delim, mark, term, onEnter, onDelim, onExit, statement);
+ ParseBlock<K, V, C> innerBlock = new SimpleParseBlock<>(inner, null, null);
+ ParseBlock<K, V, C> delimsBlock = new RepeatingParseBlock<>(innerBlock, delim, mark, term, onDelim);
+ ParseBlock<K, V, C> scopedBlock = new TriggeredParseBlock<>(onEnter, onExit, delimsBlock);
+
+ GroupingCommand<K, V, C> command = new GroupingCommand<>(scopedBlock, term);
+
+ /*
+ * Remove the wrapper layer from grouping-command on top of
+ * RepeatingParseBlock.
+ */
+ return new TransformingInitialCommand<>(command, (tree) -> tree.getChild(0));
}
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeafCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeafCommand.java
index 87fe7c1..3937f5f 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeafCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeafCommand.java
@@ -7,11 +7,23 @@ import bjc.utils.parserutils.pratt.InitialCommand;
import bjc.utils.parserutils.pratt.ParserContext;
import bjc.utils.parserutils.pratt.Token;
+/**
+ * A operator that stands for itself.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class LeafCommand<K, V, C> implements InitialCommand<K, V, C> {
@Override
- public ITree<Token<K, V>> denote(Token<K, V> operator, ParserContext<K, V, C> ctx)
- throws ParserException {
-
+ public ITree<Token<K, V>> denote(Token<K, V> operator, ParserContext<K, V, C> ctx) throws ParserException {
return new Tree<>(operator);
}
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeftBinaryCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeftBinaryCommand.java
index 1306735..58d7261 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeftBinaryCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeftBinaryCommand.java
@@ -1,8 +1,28 @@
package bjc.utils.parserutils.pratt.commands;
+/**
+ * A left-associative operator.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class LeftBinaryCommand<K, V, C> extends BinaryCommand<K, V, C> {
- public LeftBinaryCommand(int leftPower) {
- super(leftPower);
+ /**
+ * Create a new left-associative operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ */
+ public LeftBinaryCommand(int precedence) {
+ super(precedence);
}
@Override
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonBinaryCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonBinaryCommand.java
index 36ea0e1..d32a1a7 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonBinaryCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonBinaryCommand.java
@@ -1,8 +1,28 @@
package bjc.utils.parserutils.pratt.commands;
+/**
+ * A non-associative operator.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class NonBinaryCommand<K, V, C> extends BinaryCommand<K, V, C> {
- public NonBinaryCommand(int leftPower) {
- super(leftPower);
+ /**
+ * Create a new non-associative operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ */
+ public NonBinaryCommand(int precedence) {
+ super(precedence);
}
@Override
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonInitialCommands.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonInitialCommands.java
index 086ecf8..45bdc51 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonInitialCommands.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonInitialCommands.java
@@ -1,7 +1,9 @@
package bjc.utils.parserutils.pratt.commands;
import bjc.utils.parserutils.pratt.NonInitialCommand;
+import bjc.utils.parserutils.pratt.ParseBlock;
import bjc.utils.parserutils.pratt.Token;
+import bjc.utils.parserutils.pratt.blocks.SimpleParseBlock;
import java.util.Set;
@@ -101,7 +103,9 @@ public class NonInitialCommands {
*/
public static <K, V, C> NonInitialCommand<K, V, C> postCircumfix(int precedence, int insidePrecedence, K closer,
Token<K, V> marker) {
- return new PostCircumfixCommand<>(precedence, insidePrecedence, closer, marker);
+ ParseBlock<K, V, C> innerBlock = new SimpleParseBlock<>(insidePrecedence, closer, null);
+
+ return new PostCircumfixCommand<>(precedence, innerBlock, marker);
}
/**
@@ -129,6 +133,8 @@ public class NonInitialCommands {
*/
public static <K, V, C> NonInitialCommand<K, V, C> ternary(int precedence, int insidePrecedence, K closer,
Token<K, V> marker, boolean nonassoc) {
- return new TernaryCommand<>(insidePrecedence, closer, marker, nonassoc);
+ ParseBlock<K, V, C> innerBlock = new SimpleParseBlock<>(insidePrecedence, closer, null);
+
+ return new TernaryCommand<>(precedence, innerBlock, marker, nonassoc);
}
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostCircumfixCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostCircumfixCommand.java
index ba5099e..90fca00 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostCircumfixCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostCircumfixCommand.java
@@ -3,29 +3,57 @@ package bjc.utils.parserutils.pratt.commands;
import bjc.utils.data.ITree;
import bjc.utils.data.Tree;
import bjc.utils.parserutils.ParserException;
+import bjc.utils.parserutils.pratt.ParseBlock;
import bjc.utils.parserutils.pratt.ParserContext;
import bjc.utils.parserutils.pratt.Token;
+/**
+ * A post-circumfix operator, like array indexing.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class PostCircumfixCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
- private int insidePrec;
- private K term;
- private Token<K, V> mark;
+ private ParseBlock<K, V, C> innerBlock;
- public PostCircumfixCommand(int leftPower, int insidePower, K terminator, Token<K, V> marker) {
- super(leftPower);
+ private Token<K, V> mark;
+
+ /**
+ * Create a new post-circumfix operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ *
+ * @param inner
+ * The block inside the expression.
+ *
+ * @param marker
+ * The token to use as the node for the AST.
+ */
+ public PostCircumfixCommand(int precedence, ParseBlock<K, V, C> inner, Token<K, V> marker) {
+ super(precedence);
+
+ if (inner == null) {
+ throw new NullPointerException("Inner block must not be null");
+ }
+
+ innerBlock = inner;
- insidePrec = insidePower;
- term = terminator;
mark = marker;
}
- @SuppressWarnings("unchecked")
@Override
- public ITree<Token<K, V>> denote(ITree<Token<K, V>> operand, Token<K, V> operator,
- ParserContext<K, V, C> ctx) throws ParserException {
- ITree<Token<K, V>> inside = ctx.parse.parseExpression(insidePrec, ctx.tokens, ctx.state, false);
-
- ctx.tokens.expect(term);
+ public ITree<Token<K, V>> denote(ITree<Token<K, V>> operand, Token<K, V> operator, ParserContext<K, V, C> ctx)
+ throws ParserException {
+ ITree<Token<K, V>> inside = innerBlock.parse(ctx);
return new Tree<>(mark, operand, inside);
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostfixCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostfixCommand.java
index 19c540a..bab3de4 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostfixCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostfixCommand.java
@@ -6,14 +6,34 @@ import bjc.utils.parserutils.ParserException;
import bjc.utils.parserutils.pratt.ParserContext;
import bjc.utils.parserutils.pratt.Token;
+/**
+ * A postfix operator.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class PostfixCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
- public PostfixCommand(int leftPower) {
- super(leftPower);
+ /**
+ * Create a new postfix operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ */
+ public PostfixCommand(int precedence) {
+ super(precedence);
}
@Override
- public ITree<Token<K, V>> denote(ITree<Token<K, V>> operand, Token<K, V> operator,
- ParserContext<K, V, C> ctx) throws ParserException {
+ public ITree<Token<K, V>> denote(ITree<Token<K, V>> operand, Token<K, V> operator, ParserContext<K, V, C> ctx)
+ throws ParserException {
return new Tree<>(operator, operand);
}
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PreTernaryCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PreTernaryCommand.java
index 04604be..42d1a6e 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PreTernaryCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PreTernaryCommand.java
@@ -3,43 +3,73 @@ package bjc.utils.parserutils.pratt.commands;
import bjc.utils.data.ITree;
import bjc.utils.data.Tree;
import bjc.utils.parserutils.ParserException;
+import bjc.utils.parserutils.pratt.ParseBlock;
import bjc.utils.parserutils.pratt.ParserContext;
import bjc.utils.parserutils.pratt.Token;
+/**
+ * A prefix ternary operator, like an if/then/else group.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class PreTernaryCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
- private int cond1;
- private int block1;
- private int block2;
+ private Token<K, V> term;
- private K mark1;
- private K mark2;
+ private ParseBlock<K, V, C> condBlock;
- private Token<K, V> term;
+ private ParseBlock<K, V, C> opblock1;
+ private ParseBlock<K, V, C> opblock2;
- public PreTernaryCommand(int cond1, int block1, int block2, K mark1, K mark2, Token<K, V> term) {
+ /**
+ * Create a new ternary statement.
+ *
+ * @param cond
+ * The block for handling the condition.
+ *
+ * @param op1
+ * The block for handling the first operator.
+ *
+ * @param op2
+ * The block for handling the second operator.
+ *
+ * @param term
+ * The token to use as the node for the AST.
+ */
+ public PreTernaryCommand(ParseBlock<K, V, C> cond, ParseBlock<K, V, C> op1, ParseBlock<K, V, C> op2,
+ Token<K, V> term) {
super();
- this.cond1 = cond1;
- this.block1 = block1;
- this.block2 = block2;
- this.mark1 = mark1;
- this.mark2 = mark2;
+
+ if (cond == null)
+ throw new NullPointerException("Cond block must not be null");
+ else if (op1 == null)
+ throw new NullPointerException("Op block #1 must not be null");
+ else if (op2 == null) throw new NullPointerException("Op block #2 must not be null");
+
+ this.condBlock = cond;
+ this.opblock1 = op1;
+ this.opblock2 = op2;
+
this.term = term;
}
- @SuppressWarnings("unchecked")
@Override
protected ITree<Token<K, V>> intNullDenotation(Token<K, V> operator, ParserContext<K, V, C> ctx)
throws ParserException {
- ITree<Token<K, V>> cond = ctx.parse.parseExpression(cond1, ctx.tokens, ctx.state, false);
-
- ctx.tokens.expect(mark1);
-
- ITree<Token<K, V>> fstBlock = ctx.parse.parseExpression(block1, ctx.tokens, ctx.state, false);
+ ITree<Token<K, V>> cond = condBlock.parse(ctx);
- ctx.tokens.expect(mark2);
+ ITree<Token<K, V>> op1 = opblock1.parse(ctx);
- ITree<Token<K, V>> sndBlock = ctx.parse.parseExpression(block2, ctx.tokens, ctx.state, false);
+ ITree<Token<K, V>> op2 = opblock2.parse(ctx);
- return new Tree<>(term, cond, fstBlock, sndBlock);
+ return new Tree<>(term, cond, op1, op2);
}
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/RightBinaryCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/RightBinaryCommand.java
index 729c33d..5f3d9f2 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/RightBinaryCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/RightBinaryCommand.java
@@ -1,8 +1,26 @@
package bjc.utils.parserutils.pratt.commands;
+/**
+ * A right-associative binary operator.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ * @param <V>
+ * The value type of the tokens.
+ * @param <C>
+ * The state type of the parser.
+ */
public class RightBinaryCommand<K, V, C> extends BinaryCommand<K, V, C> {
- public RightBinaryCommand(int leftPower) {
- super(leftPower);
+ /**
+ * Create a new right-associative operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ */
+ public RightBinaryCommand(int precedence) {
+ super(precedence);
}
@Override
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TernaryCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TernaryCommand.java
index c3204b9..8f04368 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TernaryCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TernaryCommand.java
@@ -3,33 +3,63 @@ package bjc.utils.parserutils.pratt.commands;
import bjc.utils.data.ITree;
import bjc.utils.data.Tree;
import bjc.utils.parserutils.ParserException;
+import bjc.utils.parserutils.pratt.ParseBlock;
import bjc.utils.parserutils.pratt.ParserContext;
import bjc.utils.parserutils.pratt.Token;
+/**
+ * A ternary command, like C's ?:
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class TernaryCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
- private K term;
-
- private int innerExp;
+ private ParseBlock<K, V, C> innerBlck;
private Token<K, V> mark;
private boolean nonassoc;
- public TernaryCommand(int leftPower, K terminator, Token<K, V> marker, boolean isNonassoc) {
- super(leftPower);
+ /**
+ * Create a new ternary command.
+ *
+ * @param precedence
+ * The precedence of this operator.
+ *
+ * @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 isNonassoc
+ * Whether or not the conditional is associative.
+ */
+ public TernaryCommand(int precedence, ParseBlock<K, V, C> innerBlock, Token<K, V> marker, boolean isNonassoc) {
+ super(precedence);
+
+ if (innerBlock == null)
+ throw new NullPointerException("Inner block must not be null");
+ else if (marker == null) throw new NullPointerException("Marker must not be null");
- term = terminator;
+ innerBlck = innerBlock;
mark = marker;
nonassoc = isNonassoc;
}
- @SuppressWarnings("unchecked")
@Override
- public ITree<Token<K, V>> denote(ITree<Token<K, V>> operand, Token<K, V> operator,
- ParserContext<K, V, C> ctx) throws ParserException {
- ITree<Token<K, V>> inner = ctx.parse.parseExpression(innerExp, ctx.tokens, ctx.state, false);
-
- ctx.tokens.expect(term);
+ public ITree<Token<K, V>> denote(ITree<Token<K, V>> operand, Token<K, V> operator, ParserContext<K, V, C> ctx)
+ throws ParserException {
+ ITree<Token<K, V>> inner = innerBlck.parse(ctx);
ITree<Token<K, V>> outer = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state, false);
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TransformingInitialCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TransformingInitialCommand.java
new file mode 100644
index 0000000..88803df
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TransformingInitialCommand.java
@@ -0,0 +1,52 @@
+package bjc.utils.parserutils.pratt.commands;
+
+import java.util.function.UnaryOperator;
+
+import bjc.utils.data.ITree;
+import bjc.utils.parserutils.ParserException;
+import bjc.utils.parserutils.pratt.InitialCommand;
+import bjc.utils.parserutils.pratt.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+/**
+ * An initial command that transforms the result of another command.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
+public class TransformingInitialCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
+ private InitialCommand<K, V, C> internal;
+
+ private UnaryOperator<ITree<Token<K, V>>> transform;
+
+ /**
+ * Create a new transforming initial command.
+ *
+ * @param internal
+ * The initial command to delegate to.
+ *
+ * @param transform
+ * The transform to apply to the returned tree.
+ */
+ public TransformingInitialCommand(InitialCommand<K, V, C> internal,
+ UnaryOperator<ITree<Token<K, V>>> transform) {
+ super();
+ this.internal = internal;
+ this.transform = transform;
+ }
+
+ @Override
+ protected ITree<Token<K, V>> intNullDenotation(Token<K, V> operator, ParserContext<K, V, C> ctx)
+ throws ParserException {
+ return transform.apply(internal.denote(operator, ctx));
+ }
+
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/UnaryCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/UnaryCommand.java
index 9a79d21..c608362 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/UnaryCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/UnaryCommand.java
@@ -6,11 +6,35 @@ import bjc.utils.parserutils.ParserException;
import bjc.utils.parserutils.pratt.ParserContext;
import bjc.utils.parserutils.pratt.Token;
+/**
+ * A unary operator.
+ *
+ * @author bjculkin
+ *
+ * @param <K>
+ * The key type of the tokens.
+ *
+ * @param <V>
+ * The value type of the tokens.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
public class UnaryCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
private final int nullPwer;
- public UnaryCommand(int nullPower) {
- nullPwer = nullPower;
+ /**
+ * Create a new unary command.
+ *
+ * @param precedence
+ * The precedence of this operator.
+ */
+ public UnaryCommand(int precedence) {
+ if(precedence < 0) {
+ throw new IllegalArgumentException("Precedence must be non-negative");
+ }
+
+ nullPwer = precedence;
}
@Override