summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt
diff options
context:
space:
mode:
authorstudent <student@192.168.1.186>2017-03-24 11:51:10 -0400
committerstudent <student@192.168.1.186>2017-03-24 11:51:10 -0400
commitb168fd38be0bb344d268bfd11d14df36bb9fd4f2 (patch)
treeeed830c512ffa54b7afc4972cba67c2c818b8740 /BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt
parent33918524d7faab0146a0a92c13eaaef46cdbea8a (diff)
Update Pratt parser
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/LeftCommands.java10
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/NullCommands.java112
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/PrattParser.java53
3 files changed, 138 insertions, 37 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/LeftCommands.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/LeftCommands.java
index 5844c49..82ec843 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/LeftCommands.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/LeftCommands.java
@@ -40,7 +40,7 @@ public class LeftCommands {
@Override
public ITree<Token<K, V>> leftDenote(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);
+ ITree<Token<K, V>> opr = ctx.parse.parseExpression(rightBinding(), ctx.tokens, ctx.state, false);
return new Tree<>(operator, operand, opr);
}
@@ -101,7 +101,7 @@ public class LeftCommands {
@Override
public ITree<Token<K, V>> leftDenote(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);
+ ITree<Token<K, V>> inside = ctx.parse.parseExpression(insidePrec, ctx.tokens, ctx.state, false);
ctx.tokens.expect(term);
@@ -142,11 +142,11 @@ public class LeftCommands {
@Override
public ITree<Token<K, V>> leftDenote(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);
+ 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);
+ ITree<Token<K, V>> outer = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state, false);
return new Tree<>(mark, inner, operand, outer);
}
@@ -176,7 +176,7 @@ public class LeftCommands {
@Override
public ITree<Token<K, V>> leftDenote(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);
+ 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);
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/NullCommands.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/NullCommands.java
index cf57241..f0c2a80 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/NullCommands.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/NullCommands.java
@@ -16,7 +16,7 @@ public class NullCommands {
@Override
public ITree<Token<K, V>> nullDenotation(Token<K, V> operator, ParserContext<K, V, C> ctx)
throws ParserException {
- //tokens.next();
+ // tokens.next();
return intNullDenotation(operator, ctx);
}
@@ -36,16 +36,16 @@ public class NullCommands {
@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);
+ ITree<Token<K, V>> opr = ctx.parse.parseExpression(nullPwer, ctx.tokens, ctx.state, false);
return new Tree<>(operator, opr);
}
}
private static class GroupingCommand<K, V, C> extends AbstractNullCommand<K, V, C> {
- private K term;
- private Token<K, V> mark;
- private int inner;
+ private K term;
+ private Token<K, V> mark;
+ private int inner;
public GroupingCommand(int innerPrec, K terminator, Token<K, V> marker) {
inner = innerPrec;
@@ -57,7 +57,7 @@ public class NullCommands {
@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);
+ ITree<Token<K, V>> opr = ctx.parse.parseExpression(inner, ctx.tokens, ctx.state, false);
ctx.tokens.expect(term);
@@ -74,11 +74,63 @@ public class NullCommands {
}
}
+ private static class ConstantCommand<K, V, C> extends NullCommand<K, V, C> {
+ private ITree<Token<K, V>> val;
+
+ public ConstantCommand(ITree<Token<K, V>> con) {
+ val = con;
+ }
+
+ @Override
+ public ITree<Token<K, V>> nullDenotation(Token<K, V> operator, ParserContext<K, V, C> ctx)
+ throws ParserException {
+ return val;
+ }
+ }
+
+ private static class PreTernaryCommand<K, V, C> extends AbstractNullCommand<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);
+ }
+ }
+
/**
* Create a new unary operator.
*
* @param precedence
- * The precedence of the operator.
+ * The precedence of the operator.
*
* @return A command implementing that operator.
*/
@@ -90,13 +142,13 @@ public class NullCommands {
* Create a new grouping operator.
*
* @param precedence
- * The precedence of the expression in the operator.
+ * The precedence of the expression in the operator.
*
* @param term
- * The type that closes the group.
+ * The type that closes the group.
*
* @param mark
- * The token for the AST node of the group.
+ * The token for the AST node of the group.
*
* @return A command implementing the operator.
*/
@@ -112,4 +164,44 @@ public class NullCommands {
public static <K, V, C> NullCommand<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> NullCommand<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> NullCommand<K, V, C> constant(ITree<Token<K, V>> val) {
+ return new ConstantCommand<>(val);
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/PrattParser.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/PrattParser.java
index a2cefda..a8c273d 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/PrattParser.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/PrattParser.java
@@ -13,66 +13,75 @@ import java.util.Map;
* @author EVE
*
* @param <K>
- * The key type for the tokens.
+ * The key type for the tokens.
*
* @param <V>
- * The value type for the tokens.
+ * The value type for the tokens.
*
* @param <C>
- * The state type of the parser.
+ * The state type of the parser.
*
*
*/
public class PrattParser<K, V, C> {
- private final LeftCommand<K, V, C> DEFAULT_LEFT_COMMAND = new DefaultLeftCommand<>();
- private final NullCommand<K, V, C> DEFAULT_NULL_COMMAND = new DefaultNullCommand<>();
+ private final LeftCommand<K, V, C> DEFAULT_LEFT_COMMAND = new DefaultLeftCommand<>();
+ private final NullCommand<K, V, C> DEFAULT_NULL_COMMAND = new DefaultNullCommand<>();
- private Map<K, LeftCommand<K, V, C>> leftCommands;
- private Map<K, NullCommand<K, V, C>> nullCommands;
+ private Map<K, LeftCommand<K, V, C>> leftCommands;
+ private Map<K, NullCommand<K, V, C>> nullCommands;
+ private Map<K, NullCommand<K, V, C>> statementCommands;
/**
* Create a new Pratt parser.
*
* @param terminal
- * The terminal symbol.
+ * The terminal symbol.
*/
public PrattParser() {
leftCommands = new HashMap<>();
nullCommands = new HashMap<>();
+ statementCommands = new HashMap<>();
}
/**
* Parse an expression.
*
* @param precedence
- * The initial precedence for the expression.
+ * The initial precedence for the expression.
*
* @param tokens
- * The tokens for the expression.
+ * The tokens for the expression.
*
* @param state
- * The state of the parser.
+ * The state of the parser.
*
* @return The expression as an AST.
*
* @throws ParserException
- * If something goes wrong during parsing.
+ * If something goes wrong during parsing.
*/
- public ITree<Token<K, V>> parseExpression(int precedence, TokenStream<K, V> tokens, C state)
+ public ITree<Token<K, V>> parseExpression(int precedence, TokenStream<K, V> tokens, C state, boolean isStatement)
throws ParserException {
- if(precedence < 0) {
+ if (precedence < 0) {
throw new IllegalArgumentException("Precedence must be greater than zero");
}
Token<K, V> initToken = tokens.current();
tokens.next();
- ITree<Token<K, V>> ast = nullCommands.getOrDefault(initToken.getKey(), DEFAULT_NULL_COMMAND)
- .nullDenotation(initToken, new ParserContext<>(tokens, this, state));
+ ITree<Token<K, V>> ast;
+
+ if (isStatement && statementCommands.containsKey(initToken.getKey())) {
+ ast = statementCommands.getOrDefault(initToken.getKey(), DEFAULT_NULL_COMMAND).nullDenotation(initToken,
+ new ParserContext<>(tokens, this, state));
+ } else {
+ ast = nullCommands.getOrDefault(initToken.getKey(), DEFAULT_NULL_COMMAND).nullDenotation(initToken,
+ new ParserContext<>(tokens, this, state));
+ }
int rightPrec = Integer.MAX_VALUE;
- while(true) {
+ while (true) {
Token<K, V> tok = tokens.current();
K key = tok.getKey();
@@ -80,7 +89,7 @@ public class PrattParser<K, V, C> {
LeftCommand<K, V, C> command = leftCommands.getOrDefault(key, DEFAULT_LEFT_COMMAND);
int leftBind = command.leftBinding();
- if(NumberUtils.between(precedence, rightPrec, leftBind)) {
+ if (NumberUtils.between(precedence, rightPrec, leftBind)) {
tokens.next();
ast = command.leftDenote(ast, tok, new ParserContext<>(tokens, this, state));
@@ -97,10 +106,10 @@ public class PrattParser<K, V, C> {
* Add a non-initial command to this parser.
*
* @param marker
- * The key that marks the command.
+ * The key that marks the command.
*
* @param comm
- * The command.
+ * The command.
*/
public void addNonInitialCommand(K marker, LeftCommand<K, V, C> comm) {
leftCommands.put(marker, comm);
@@ -110,10 +119,10 @@ public class PrattParser<K, V, C> {
* Add a initial command to this parser.
*
* @param marker
- * The key that marks the command.
+ * The key that marks the command.
*
* @param comm
- * The command.
+ * The command.
*/
public void addInitialCommand(K marker, NullCommand<K, V, C> comm) {
nullCommands.put(marker, comm);