summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands
diff options
context:
space:
mode:
authorbjculkin <bjculkin@mix.wvu.edu>2017-03-24 16:21:07 -0400
committerbjculkin <bjculkin@mix.wvu.edu>2017-03-24 16:21:07 -0400
commit0f6565687e03968abd2e508fa8183f50f04f1cc7 (patch)
tree22da19d978f61a199fec5762c2dd70507be75b05 /BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands
parentb168fd38be0bb344d268bfd11d14df36bb9fd4f2 (diff)
Update Pratt Parser
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/AbstractInitialCommand.java19
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryCommand.java23
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryPostCommand.java19
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ChainCommand.java47
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ConstantCommand.java21
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultInitialCommand.java28
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultNonInitialCommand.java34
-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.java30
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InitialCommands.java134
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeafCommand.java17
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeftBinaryCommand.java12
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonBinaryCommand.java17
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonInitialCommands.java134
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostCircumfixCommand.java32
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostfixCommand.java19
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PreTernaryCommand.java45
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/RightBinaryCommand.java12
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TernaryCommand.java47
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/UnaryCommand.java23
20 files changed, 778 insertions, 0 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/AbstractInitialCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/AbstractInitialCommand.java
new file mode 100644
index 0000000..b263422
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/AbstractInitialCommand.java
@@ -0,0 +1,19 @@
+package bjc.utils.parserutils.pratt.commands;
+
+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;
+
+public abstract class AbstractInitialCommand<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 {
+ return intNullDenotation(operator, ctx);
+ }
+
+ protected abstract ITree<Token<K, V>> intNullDenotation(Token<K, V> operator,
+ ParserContext<K, V, C> ctx) throws ParserException;
+
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryCommand.java
new file mode 100644
index 0000000..bf6786b
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryCommand.java
@@ -0,0 +1,23 @@
+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.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+public abstract class BinaryCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
+ public BinaryCommand(int leftPower) {
+ super(leftPower);
+ }
+
+ protected abstract int rightBinding();
+
+ @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>> opr = ctx.parse.parseExpression(rightBinding(), ctx.tokens, ctx.state, false);
+
+ return new Tree<>(operator, operand, opr);
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000..7aaf735
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryPostCommand.java
@@ -0,0 +1,19 @@
+package bjc.utils.parserutils.pratt.commands;
+
+import bjc.utils.parserutils.pratt.NonInitialCommand;
+
+/*
+ * A command with constant binding power.
+ */
+public abstract class BinaryPostCommand<K, V, C> extends NonInitialCommand<K, V, C> {
+ private final int leftPower;
+
+ public BinaryPostCommand(int power) {
+ leftPower = power;
+ }
+
+ @Override
+ public int leftBinding() {
+ return leftPower;
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ChainCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ChainCommand.java
new file mode 100644
index 0000000..aa85f75
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ChainCommand.java
@@ -0,0 +1,47 @@
+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.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+import java.util.Set;
+
+public class ChainCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
+ private Set<K> chainWith;
+
+ private Token<K, V> chain;
+
+ public ChainCommand(int leftPower, Set<K> chainSet, Token<K, V> chainMarker) {
+ super(leftPower);
+
+ chainWith = chainSet;
+ chain = chainMarker;
+ }
+
+ @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>> tree = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state, false);
+
+ ITree<Token<K, V>> res = new Tree<>(operator, operand, tree);
+
+ if (chainWith.contains(ctx.tokens.current().getKey())) {
+ Token<K, V> tok = ctx.tokens.current();
+ ctx.tokens.next();
+
+ ITree<Token<K, V>> other = denote(tree, tok,
+ new ParserContext<>(ctx.tokens, ctx.parse, ctx.state));
+
+ return new Tree<>(chain, res, other);
+ } else {
+ return res;
+ }
+ }
+
+ @Override
+ public int nextBinding() {
+ return leftBinding() - 1;
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ConstantCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ConstantCommand.java
new file mode 100644
index 0000000..2308cc7
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ConstantCommand.java
@@ -0,0 +1,21 @@
+package bjc.utils.parserutils.pratt.commands;
+
+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;
+
+public class ConstantCommand<K, V, C> implements InitialCommand<K, V, C> {
+ private ITree<Token<K, V>> val;
+
+ public ConstantCommand(ITree<Token<K, V>> con) {
+ val = con;
+ }
+
+ @Override
+ public ITree<Token<K, V>> denote(Token<K, V> operator, ParserContext<K, V, C> ctx)
+ throws ParserException {
+ return val;
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultInitialCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultInitialCommand.java
new file mode 100644
index 0000000..7409755
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultInitialCommand.java
@@ -0,0 +1,28 @@
+package bjc.utils.parserutils.pratt.commands;
+
+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;
+
+/**
+ * Default implementation of an initial command.
+ *
+ * @author EVE
+ *
+ * @param <K>
+ * The key type of the token.
+ *
+ * @param <V>
+ * The value type of the token.
+ *
+ * @param <C>
+ * The state type of the parser.
+ */
+public class DefaultInitialCommand<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 {
+ throw new ParserException("Unexpected token " + operator);
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultNonInitialCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultNonInitialCommand.java
new file mode 100644
index 0000000..8c500a9
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultNonInitialCommand.java
@@ -0,0 +1,34 @@
+package bjc.utils.parserutils.pratt.commands;
+
+import bjc.utils.data.ITree;
+import bjc.utils.parserutils.pratt.NonInitialCommand;
+import bjc.utils.parserutils.pratt.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+/**
+ * Default implementation of a non-initial command.
+ *
+ * @author EVE
+ *
+ * @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 DefaultNonInitialCommand<K, V, C> extends NonInitialCommand<K, V, C> {
+
+ @Override
+ public ITree<Token<K, V>> denote(ITree<Token<K, V>> operand, Token<K, V> operator, ParserContext<K, V, C> ctx) {
+ throw new UnsupportedOperationException("Default command has no left denotation");
+ }
+
+ @Override
+ public int leftBinding() {
+ return -1;
+ }
+
+}
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
new file mode 100644
index 0000000..090b2f4
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DelimitedCommand.java
@@ -0,0 +1,65 @@
+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
new file mode 100644
index 0000000..407a39e
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/GroupingCommand.java
@@ -0,0 +1,30 @@
+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.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+public class GroupingCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
+ private K term;
+ private Token<K, V> mark;
+ private int 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);
+
+ return new Tree<>(mark, opr);
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000..d9e7f90
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InitialCommands.java
@@ -0,0 +1,134 @@
+package bjc.utils.parserutils.pratt.commands;
+
+import bjc.utils.data.ITree;
+import bjc.utils.parserutils.pratt.InitialCommand;
+import bjc.utils.parserutils.pratt.Token;
+
+import java.util.function.UnaryOperator;
+
+/**
+ * * Contains factory methods for producing common implementations of
+ * {@link InitialCommand}
+ *
+ * @author EVE
+ *
+ */
+public class InitialCommands {
+ /**
+ * Create a new unary operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ *
+ * @return A command implementing that operator.
+ */
+ public static <K, V, C> InitialCommand<K, V, C> unary(int precedence) {
+ return new UnaryCommand<>(precedence);
+ }
+
+ /**
+ * Create a new grouping operator.
+ *
+ * @param precedence
+ * The precedence of the expression in the operator.
+ *
+ * @param term
+ * The type that closes the group.
+ *
+ * @param mark
+ * The token for the AST node of the group.
+ *
+ * @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);
+ }
+
+ /**
+ * Create a new leaf operator.
+ *
+ * @return A command implementing the operator.
+ */
+ public static <K, V, C> InitialCommand<K, V, C> leaf() {
+ return new LeafCommand<>();
+ }
+
+ /**
+ * Create a new pre-ternary operator, like an if-then-else statement.
+ *
+ * @param cond1
+ * The priority of the first block.
+ *
+ * @param block1
+ * The priority of the second block.
+ *
+ * @param block2
+ * The priority of the third block.
+ *
+ * @param mark1
+ * The marker that ends the first block.
+ *
+ * @param mark2
+ * The marker that ends the second block.
+ *
+ * @param term
+ * The token for the AST node of the group.
+ *
+ * @return A command implementing the operator.
+ */
+ 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);
+ }
+
+ /**
+ * Create a new named constant.
+ *
+ * @param val
+ * The value of the constant.
+ *
+ * @return A command implementing the constant.
+ */
+ public static <K, V, C> InitialCommand<K, V, C> constant(ITree<Token<K, V>> val) {
+ return new ConstantCommand<>(val);
+ }
+
+ /**
+ * Create a new delimited command. This is for block-like constructs.
+ *
+ * @param inner
+ * The precedence of the inner blocks.
+ *
+ * @param delim
+ * The marker between sub-blocks.
+ *
+ * @param mark
+ * The block terminator.
+ *
+ * @param term
+ * The token for the AST node of the group.
+ *
+ * @param onEnter
+ * The function to apply to the state on entering the
+ * block.
+ *
+ * @param onDelim
+ * The function to apply to the state on finishing a
+ * sub-block.
+ *
+ * @param onExit
+ * The function to apply to the state on exiting the
+ * block.
+ *
+ * @param statement
+ * Whether or not the sub-blocks are statements or
+ * expressions.
+ *
+ * @return A command implementing the operator.
+ */
+ 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);
+ }
+}
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
new file mode 100644
index 0000000..87fe7c1
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeafCommand.java
@@ -0,0 +1,17 @@
+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.InitialCommand;
+import bjc.utils.parserutils.pratt.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+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 {
+
+ 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
new file mode 100644
index 0000000..1306735
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/LeftBinaryCommand.java
@@ -0,0 +1,12 @@
+package bjc.utils.parserutils.pratt.commands;
+
+public class LeftBinaryCommand<K, V, C> extends BinaryCommand<K, V, C> {
+ public LeftBinaryCommand(int leftPower) {
+ super(leftPower);
+ }
+
+ @Override
+ protected int rightBinding() {
+ return 1 + leftBinding();
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000..36ea0e1
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonBinaryCommand.java
@@ -0,0 +1,17 @@
+package bjc.utils.parserutils.pratt.commands;
+
+public class NonBinaryCommand<K, V, C> extends BinaryCommand<K, V, C> {
+ public NonBinaryCommand(int leftPower) {
+ super(leftPower);
+ }
+
+ @Override
+ protected int rightBinding() {
+ return 1 + leftBinding();
+ }
+
+ @Override
+ public int nextBinding() {
+ return leftBinding() - 1;
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000..086ecf8
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/NonInitialCommands.java
@@ -0,0 +1,134 @@
+package bjc.utils.parserutils.pratt.commands;
+
+import bjc.utils.parserutils.pratt.NonInitialCommand;
+import bjc.utils.parserutils.pratt.Token;
+
+import java.util.Set;
+
+/**
+ * Contains factory methods for producing common implementations of
+ * {@link NonInitialCommand}
+ *
+ * @author EVE
+ *
+ */
+public class NonInitialCommands {
+ /**
+ * Create a left-associative infix operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ *
+ * @return A command implementing that operator.
+ */
+ public static <K, V, C> NonInitialCommand<K, V, C> infixLeft(int precedence) {
+ return new LeftBinaryCommand<>(precedence);
+ }
+
+ /**
+ * Create a right-associative infix operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ *
+ * @return A command implementing that operator.
+ */
+ public static <K, V, C> NonInitialCommand<K, V, C> infixRight(int precedence) {
+ return new RightBinaryCommand<>(precedence);
+ }
+
+ /**
+ * Create a non-associative infix operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ *
+ * @return A command implementing that operator.
+ */
+ public static <K, V, C> NonInitialCommand<K, V, C> infixNon(int precedence) {
+ return new NonBinaryCommand<>(precedence);
+ }
+
+ /**
+ * Create a chained operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ *
+ * @param chainSet
+ * The operators it forms a chain with.
+ *
+ * @param marker
+ * The token to use as the AST node for the chained
+ * operators.
+ *
+ * @return A command implementing that operator.
+ */
+ public static <K, V, C> NonInitialCommand<K, V, C> chain(int precedence, Set<K> chainSet, Token<K, V> marker) {
+ return new ChainCommand<>(precedence, chainSet, marker);
+ }
+
+ /**
+ * Create a postfix operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ *
+ * @return A command implementing that operator.
+ */
+ public static <K, V, C> NonInitialCommand<K, V, C> postfix(int precedence) {
+ return new PostfixCommand<>(precedence);
+ }
+
+ /**
+ * Create a post-circumfix operator.
+ *
+ * This is an operator in form similar to array indexing.
+ *
+ * @param precedence
+ * The precedence of this operator
+ *
+ * @param insidePrecedence
+ * The precedence of the expression inside the operator
+ *
+ * @param closer
+ * The token that closes the circumfix.
+ *
+ * @param marker
+ * The token to use as the AST node for the operator.
+ *
+ * @return A command implementing that operator.
+ */
+ 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);
+ }
+
+ /**
+ * Create a ternary operator.
+ *
+ * This is like C's ?: operator.
+ *
+ * @param precedence
+ * The precedence of the operator.
+ *
+ * @param insidePrecedence
+ * The precedence of the inner section of the operator.
+ *
+ * @param closer
+ * The token that marks the end of the inner section.
+ *
+ * @param marker
+ * The token to use as the AST node for the operator.
+ *
+ * @param nonassoc
+ * True if the command is non-associative, false
+ * otherwise.
+ *
+ * @return A command implementing this operator.
+ */
+ 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);
+ }
+}
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
new file mode 100644
index 0000000..ba5099e
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostCircumfixCommand.java
@@ -0,0 +1,32 @@
+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.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+public class PostCircumfixCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
+ private int insidePrec;
+ private K term;
+ private Token<K, V> mark;
+
+ public PostCircumfixCommand(int leftPower, int insidePower, K terminator, Token<K, V> marker) {
+ super(leftPower);
+
+ 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);
+
+ return new Tree<>(mark, operand, inside);
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000..19c540a
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PostfixCommand.java
@@ -0,0 +1,19 @@
+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.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+public class PostfixCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
+ public PostfixCommand(int leftPower) {
+ super(leftPower);
+ }
+
+ @Override
+ 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
new file mode 100644
index 0000000..04604be
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/PreTernaryCommand.java
@@ -0,0 +1,45 @@
+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.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+public class PreTernaryCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
+ private int cond1;
+ private int block1;
+ private int block2;
+
+ private K mark1;
+ private K mark2;
+
+ private Token<K, V> term;
+
+ public PreTernaryCommand(int cond1, int block1, int block2, K mark1, K mark2, Token<K, V> term) {
+ super();
+ this.cond1 = cond1;
+ this.block1 = block1;
+ this.block2 = block2;
+ this.mark1 = mark1;
+ this.mark2 = mark2;
+ 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);
+
+ ctx.tokens.expect(mark2);
+
+ ITree<Token<K, V>> sndBlock = ctx.parse.parseExpression(block2, ctx.tokens, ctx.state, false);
+
+ return new Tree<>(term, cond, fstBlock, sndBlock);
+ }
+} \ 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
new file mode 100644
index 0000000..729c33d
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/RightBinaryCommand.java
@@ -0,0 +1,12 @@
+package bjc.utils.parserutils.pratt.commands;
+
+public class RightBinaryCommand<K, V, C> extends BinaryCommand<K, V, C> {
+ public RightBinaryCommand(int leftPower) {
+ super(leftPower);
+ }
+
+ @Override
+ protected int rightBinding() {
+ return leftBinding();
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000..c3204b9
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/TernaryCommand.java
@@ -0,0 +1,47 @@
+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.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+public class TernaryCommand<K, V, C> extends BinaryPostCommand<K, V, C> {
+ private K term;
+
+ private int innerExp;
+
+ private Token<K, V> mark;
+
+ private boolean nonassoc;
+
+ public TernaryCommand(int leftPower, K terminator, Token<K, V> marker, boolean isNonassoc) {
+ super(leftPower);
+
+ term = terminator;
+ 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);
+
+ ITree<Token<K, V>> outer = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state, false);
+
+ return new Tree<>(mark, inner, operand, outer);
+ }
+
+ @Override
+ public int nextBinding() {
+ if (nonassoc) {
+ return leftBinding() - 1;
+ } else {
+ return leftBinding();
+ }
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000..9a79d21
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/UnaryCommand.java
@@ -0,0 +1,23 @@
+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.ParserContext;
+import bjc.utils.parserutils.pratt.Token;
+
+public class UnaryCommand<K, V, C> extends AbstractInitialCommand<K, V, C> {
+ private final int nullPwer;
+
+ public UnaryCommand(int nullPower) {
+ nullPwer = nullPower;
+ }
+
+ @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(nullPwer, ctx.tokens, ctx.state, false);
+
+ return new Tree<>(operator, opr);
+ }
+} \ No newline at end of file