diff options
| author | Ben Culkin <scorpress@gmail.com> | 2022-08-16 23:03:27 -0400 |
|---|---|---|
| committer | Ben Culkin <scorpress@gmail.com> | 2022-08-16 23:03:27 -0400 |
| commit | cea3e47938322b97c318dea38dc0d649e196dc1b (patch) | |
| tree | 0ceef0bafbfed7aa5802e8fc526c0c98276f1fff /JPratt/src/examples/java/bjc/pratt | |
| parent | 4869146748ed51eb212935d2b971388fb9e73d37 (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/examples/java/bjc/pratt')
4 files changed, 55 insertions, 33 deletions
diff --git a/JPratt/src/examples/java/bjc/pratt/examples/lang/AssignCommand.java b/JPratt/src/examples/java/bjc/pratt/examples/lang/AssignCommand.java index 78fec0d..138e47e 100644 --- a/JPratt/src/examples/java/bjc/pratt/examples/lang/AssignCommand.java +++ b/JPratt/src/examples/java/bjc/pratt/examples/lang/AssignCommand.java @@ -1,6 +1,8 @@ package bjc.pratt.examples.lang; import bjc.pratt.ParserContext; +import bjc.pratt.commands.CommandResult; +import bjc.pratt.commands.CommandResult.Status; import bjc.pratt.commands.impls.NonBinaryCommand; import bjc.pratt.tokens.StringToken; import bjc.pratt.tokens.Token; @@ -14,7 +16,7 @@ class AssignCommand extends NonBinaryCommand<String, String, TestContext> { } @Override - public Tree<Token<String, String>> denote(final Tree<Token<String, String>> operand, + public CommandResult<String, String> denote(final Tree<Token<String, String>> operand, final Token<String, String> operator, final ParserContext<String, String, TestContext> ctx) throws ParserException { final Token<String, String> name = operand.getHead(); @@ -27,10 +29,12 @@ class AssignCommand extends NonBinaryCommand<String, String, TestContext> { throw new ParserException("Variable name must be simple"); } - final Tree<Token<String, String>> body = ctx.parse.parseExpression(0, ctx.tokens, ctx.state, false); - + final CommandResult<String,String> bodyRes = ctx.parse.parseExpression(0, ctx.tokens, ctx.state, false); + if (bodyRes.status != Status.SUCCESS) return bodyRes; + + Tree<Token<String, String>> body = bodyRes.success(); ctx.state.scopes.top().putKey(name.getValue(), body); - return new SimpleTree<>(new StringToken("assign", "assign"), operand, body); + return CommandResult.success(new SimpleTree<>(new StringToken("assign", "assign"), operand, body)); } } diff --git a/JPratt/src/examples/java/bjc/pratt/examples/lang/PrattParserTest.java b/JPratt/src/examples/java/bjc/pratt/examples/lang/PrattParserTest.java index ba957c9..9d05ca2 100644 --- a/JPratt/src/examples/java/bjc/pratt/examples/lang/PrattParserTest.java +++ b/JPratt/src/examples/java/bjc/pratt/examples/lang/PrattParserTest.java @@ -26,6 +26,8 @@ import java.util.Set; import java.util.function.UnaryOperator; import bjc.pratt.PrattParser; +import bjc.pratt.commands.CommandResult; +import bjc.pratt.commands.CommandResult.Status; import bjc.pratt.commands.InitialCommand; import bjc.pratt.commands.NonInitialCommand; import bjc.pratt.tokens.StringToken; @@ -49,7 +51,7 @@ import bjc.utils.parserutils.splitter.TokenSplitter; public class PrattParserTest { private final static Set<String> ops; private final static Set<String> reserved; - + static { /* * Setup operator hash. @@ -61,9 +63,9 @@ public class PrattParserTest { ops.add("!!!"); ops.add(":="); - + ops.addAll(Arrays.asList("|>", "[|]")); - + ops.addAll(Arrays.asList("->", "=>")); ops.addAll(Arrays.asList("||", "&&")); ops.addAll(Arrays.asList("<=", ">=")); @@ -76,7 +78,7 @@ public class PrattParserTest { ops.addAll(Arrays.asList("(", ")")); ops.addAll(Arrays.asList("[", "]")); ops.addAll(Arrays.asList("{", "}")); - + reserved = new LinkedHashSet<>(); reserved.addAll(Arrays.asList("if", "then", "else")); reserved.addAll(Arrays.asList("and", "or")); @@ -86,23 +88,23 @@ public class PrattParserTest { reserved.addAll(Arrays.asList("try", "throw", "catch", "finally")); reserved.add("var"); } + /** * Main method. * - * @param args - * Unused CLI arguments. + * @param args Unused CLI arguments. */ public static void main(final String[] args) { final ConfigurableTokenSplitter lo = new ConfigurableTokenSplitter(true); lo.addSimpleDelimiters(":="); - + lo.addSimpleDelimiters("|>", "[|]"); - + lo.addSimpleDelimiters("->, =>"); lo.addSimpleDelimiters("||", "&&"); lo.addSimpleDelimiters("<=", ">="); - + lo.addSimpleDelimiters("\u00B1"); // Unicode plus/minus lo.addSimpleDelimiters(".", ",", ";", ":"); lo.addSimpleDelimiters("=", "<", ">"); @@ -142,13 +144,17 @@ public class PrattParserTest { */ tokenStream.next(); - final Tree<Token<String, String>> rawTree = parser.parseExpression(0, tokenStream, ctx, true); + final CommandResult<String, String> rawTree = parser.parseExpression(0, tokenStream, ctx, true); - if (!tokenStream.headIs("(end)")) { - System.out.println("\nMultiple expressions on line"); - } + if (rawTree.status != Status.SUCCESS) { + System.out.println("Command parsing failed."); + } else { + if (!tokenStream.headIs("(end)")) { + System.out.println("\nMultiple expressions on line"); + } - System.out.printf("\nParsed expression:\n%s", rawTree); + System.out.printf("\nParsed expression:\n%s", rawTree.success()); + } } catch (ParserException pex) { pex.printStackTrace(); } @@ -183,8 +189,8 @@ public class PrattParserTest { } String strang = raw.replaceAll("\\.(\\.+)", "$1"); - - if (doSplit) { + + if (doSplit) { ListEx<String> splitStrangs = split.split(strang); splitStrangs.removeMatching(""); @@ -264,7 +270,7 @@ public class PrattParserTest { * Pipeline operator. */ parser.addNonInitialCommand("|>", infixLeft(12)); - + /* * Non-short circuiting conditionals. */ @@ -293,7 +299,7 @@ public class PrattParserTest { * Range operator. */ parser.addNonInitialCommand("[|]", infixNon(18)); - + /* * Add/subtracting operators. */ diff --git a/JPratt/src/examples/java/bjc/pratt/examples/lang/SwitchCommand.java b/JPratt/src/examples/java/bjc/pratt/examples/lang/SwitchCommand.java index fb2ae66..901790e 100644 --- a/JPratt/src/examples/java/bjc/pratt/examples/lang/SwitchCommand.java +++ b/JPratt/src/examples/java/bjc/pratt/examples/lang/SwitchCommand.java @@ -1,6 +1,8 @@ package bjc.pratt.examples.lang; import bjc.pratt.ParserContext; +import bjc.pratt.commands.CommandResult; +import bjc.pratt.commands.CommandResult.Status; import bjc.pratt.commands.InitialCommand; import bjc.pratt.tokens.StringToken; import bjc.pratt.tokens.Token; @@ -10,12 +12,16 @@ import bjc.utils.parserutils.ParserException; class SwitchCommand implements InitialCommand<String, String, TestContext> { @Override - public Tree<Token<String, String>> denote(final Token<String, String> operator, + public CommandResult<String, String> denote(final Token<String, String> operator, final ParserContext<String, String, TestContext> ctx) throws ParserException { - final Tree<Token<String, String>> object = ctx.parse.parseExpression(0, ctx.tokens, ctx.state, false); - - final Tree<Token<String, String>> body = ctx.parse.parseExpression(0, ctx.tokens, ctx.state, false); - - return new SimpleTree<>(new StringToken("switch", "switch"), object, body); + final CommandResult<String,String> objectRes = ctx.parse.parseExpression(0, ctx.tokens, ctx.state, false); + if (objectRes.status != Status.SUCCESS) return objectRes; + Tree<Token<String, String>> object = objectRes.success(); + + final CommandResult<String,String> bodyRes = ctx.parse.parseExpression(0, ctx.tokens, ctx.state, false); + if (bodyRes.status != Status.SUCCESS) return bodyRes; + Tree<Token<String, String>> body = bodyRes.success(); + + return CommandResult.success(new SimpleTree<>(new StringToken("switch", "switch"), object, body)); } } diff --git a/JPratt/src/examples/java/bjc/pratt/examples/lang/VarCommand.java b/JPratt/src/examples/java/bjc/pratt/examples/lang/VarCommand.java index 1f47218..328d6eb 100644 --- a/JPratt/src/examples/java/bjc/pratt/examples/lang/VarCommand.java +++ b/JPratt/src/examples/java/bjc/pratt/examples/lang/VarCommand.java @@ -2,6 +2,8 @@ package bjc.pratt.examples.lang; import bjc.pratt.ParserContext; import bjc.pratt.commands.AbstractInitialCommand; +import bjc.pratt.commands.CommandResult; +import bjc.pratt.commands.CommandResult.Status; import bjc.pratt.tokens.StringToken; import bjc.pratt.tokens.Token; import bjc.data.Tree; @@ -11,7 +13,7 @@ import bjc.utils.parserutils.ParserException; class VarCommand extends AbstractInitialCommand<String, String, TestContext> { @Override - protected Tree<Token<String, String>> intNullDenotation(final Token<String, String> operator, + protected CommandResult<String, String> intNullDenotation(final Token<String, String> operator, final ParserContext<String, String, TestContext> ctx) throws ParserException { final Token<String, String> name = ctx.tokens.current(); @@ -26,11 +28,15 @@ class VarCommand extends AbstractInitialCommand<String, String, TestContext> { ctx.tokens.expect(":="); - final Tree<Token<String, String>> body = ctx.parse.parseExpression(0, ctx.tokens, ctx.state, false); - + final CommandResult<String,String> bodyRes = ctx.parse.parseExpression(0, ctx.tokens, ctx.state, false); + if (bodyRes.status != Status.SUCCESS) return bodyRes; + Tree<Token<String, String>> body = bodyRes.success(); ctx.state.scopes.top().putKey(name.getValue(), body); - - return new SimpleTree<>(new StringToken("var-bind", "var-bind"), new SimpleTree<>(name), body); + + StringToken token = new StringToken("var-bind", "var-bind"); + Tree<Token<String,String>> tree = new SimpleTree<>(token, new SimpleTree<>(name), body); + + return CommandResult.success(tree); } } |
