summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/PrattParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/PrattParser.java')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/PrattParser.java83
1 files changed, 52 insertions, 31 deletions
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 a8c273d..e8543dc 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
@@ -3,6 +3,8 @@ package bjc.utils.parserutils.pratt;
import bjc.utils.data.ITree;
import bjc.utils.funcutils.NumberUtils;
import bjc.utils.parserutils.ParserException;
+import bjc.utils.parserutils.pratt.commands.DefaultNonInitialCommand;
+import bjc.utils.parserutils.pratt.commands.DefaultInitialCommand;
import java.util.HashMap;
import java.util.Map;
@@ -13,29 +15,29 @@ 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 NonInitialCommand<K, V, C> DEFAULT_LEFT_COMMAND = new DefaultNonInitialCommand<>();
+ private final InitialCommand<K, V, C> DEFAULT_NULL_COMMAND = new DefaultInitialCommand<>();
- private Map<K, LeftCommand<K, V, C>> leftCommands;
- private Map<K, NullCommand<K, V, C>> nullCommands;
- private Map<K, NullCommand<K, V, C>> statementCommands;
+ private Map<K, NonInitialCommand<K, V, C>> leftCommands;
+ private Map<K, InitialCommand<K, V, C>> nullCommands;
+ private Map<K, InitialCommand<K, V, C>> statementCommands;
/**
* Create a new Pratt parser.
*
* @param terminal
- * The terminal symbol.
+ * The terminal symbol.
*/
public PrattParser() {
leftCommands = new HashMap<>();
@@ -47,22 +49,25 @@ public class PrattParser<K, V, C> {
* 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.
+ *
+ * @param isStatement
+ * Whether or not to parse statements.
*
* @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, boolean isStatement)
- throws ParserException {
- if (precedence < 0) {
+ public ITree<Token<K, V>> parseExpression(int precedence, TokenStream<K, V> tokens, C state,
+ boolean isStatement) throws ParserException {
+ if(precedence < 0) {
throw new IllegalArgumentException("Precedence must be greater than zero");
}
@@ -71,28 +76,28 @@ public class PrattParser<K, V, C> {
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));
+ if(isStatement && statementCommands.containsKey(initToken.getKey())) {
+ ast = statementCommands.getOrDefault(initToken.getKey(), DEFAULT_NULL_COMMAND)
+ .denote(initToken, new ParserContext<>(tokens, this, state));
} else {
- ast = nullCommands.getOrDefault(initToken.getKey(), DEFAULT_NULL_COMMAND).nullDenotation(initToken,
- new ParserContext<>(tokens, this, state));
+ ast = nullCommands.getOrDefault(initToken.getKey(), DEFAULT_NULL_COMMAND)
+ .denote(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();
- LeftCommand<K, V, C> command = leftCommands.getOrDefault(key, DEFAULT_LEFT_COMMAND);
+ NonInitialCommand<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));
+ ast = command.denote(ast, tok, new ParserContext<>(tokens, this, state));
rightPrec = command.nextBinding();
} else {
break;
@@ -106,12 +111,12 @@ 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) {
+ public void addNonInitialCommand(K marker, NonInitialCommand<K, V, C> comm) {
leftCommands.put(marker, comm);
}
@@ -119,12 +124,28 @@ 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) {
+ public void addInitialCommand(K marker, InitialCommand<K, V, C> comm) {
nullCommands.put(marker, comm);
}
+
+ /**
+ * Add a statement command to this parser.
+ *
+ * The difference between statements and initial commands is that
+ * statements can only appear at the start of the expression.
+ *
+ * @param marker
+ * The key that marks the command.
+ *
+ * @param comm
+ * The command.
+ */
+ public void addStatementCommand(K marker, InitialCommand<K, V, C> comm) {
+ statementCommands.put(marker, comm);
+ }
}