From 301eaaf98dc5234c4a6fc2325c8ae9ffb8c1894d Mon Sep 17 00:00:00 2001 From: Alberto Venturini Date: Sat, 3 Jul 2021 15:42:28 +0200 Subject: [PATCH] Refactoring: make Grammar an abstract class --- parsley-examples/pom.xml | 11 +- .../graphml/GrammarGraphMLParser.java | 66 +------- .../examples/graphml/GraphMLGrammar.java | 76 +++++++++ .../examples/markdown/MarkdownGrammar.java | 35 ++++ .../markdown/MarkdownParseResult.java | 4 + .../examples/markdown/MarkdownParser.java | 5 + .../examples/graphml/GraphMLGrammarTest.java | 5 +- .../examples/graphml/MarkdownGrammarTest.java | 13 ++ .../src/test/resources/markdown/markdown1.md | 155 ++++++++++++++++++ .../parsley/grammar/Grammar.java | 81 +-------- .../parsley/grammar/GrammarFactory.java | 27 +++ .../parsley/grammar/ParseContext.java | 2 +- .../parsley/grammar/ParseTree.java | 2 +- .../parsley/grammar/rules/MatchCharacter.java | 1 - .../parsley/grammar/rules/Rule.java | 3 +- .../parsley/grammar/rules/Rules.java | 54 ++++++ .../parsley/grammar/rules/Sequence.java | 2 +- .../parsley/grammar/GrammarTest.java | 16 +- 18 files changed, 395 insertions(+), 163 deletions(-) create mode 100644 parsley-examples/src/main/java/com/albertoventurini/parsley/examples/graphml/GraphMLGrammar.java create mode 100644 parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownGrammar.java create mode 100644 parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownParseResult.java create mode 100644 parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownParser.java create mode 100644 parsley-examples/src/test/java/com/albertoventurini/parsley/examples/graphml/MarkdownGrammarTest.java create mode 100644 parsley-examples/src/test/resources/markdown/markdown1.md create mode 100644 parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/GrammarFactory.java create mode 100644 parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Rules.java diff --git a/parsley-examples/pom.xml b/parsley-examples/pom.xml index 3044a47..8ab0925 100644 --- a/parsley-examples/pom.xml +++ b/parsley-examples/pom.xml @@ -26,6 +26,12 @@ + + com.albertoventurini.parsley + parsley-grammar + 0.1.0-SNAPSHOT + + org.junit.jupiter junit-jupiter @@ -37,10 +43,7 @@ junit-jupiter-engine test - - com.albertoventurini.parsley - parsley-grammar - + diff --git a/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/graphml/GrammarGraphMLParser.java b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/graphml/GrammarGraphMLParser.java index df2e369..9452fc1 100644 --- a/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/graphml/GrammarGraphMLParser.java +++ b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/graphml/GrammarGraphMLParser.java @@ -2,81 +2,17 @@ package com.albertoventurini.parsley.examples.graphml; import com.albertoventurini.parsley.grammar.Grammar; import com.albertoventurini.parsley.grammar.ParseTree; -import com.albertoventurini.parsley.grammar.rules.Rule; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Function; import java.util.stream.Collectors; -import static com.albertoventurini.parsley.grammar.Grammar.*; - public class GrammarGraphMLParser implements GraphMLParser { - private final Grammar grammar; - - public GrammarGraphMLParser() { - - final Rule comment = sequence(string("")).as("comment"); - final Rule comments = zeroOrMore(comment).as("comments"); - - final Rule xmlHeader = string("").as("header"); - - final Rule attribute = sequence( - takeWhile(c -> c != '=' && c != '>'), - character('='), - character('\''), - takeWhile(c -> c != '\''), - character('\'')).as("attribute"); - - final Function tagFunc = (s) -> sequence( - character('<'), - string(s).as("tagName"), - zeroOrMore(attribute).as("attributes"), - character('>')).as("tag:" + s); - - final Function closingTagFunc = (s) -> sequence( - string("')).as("closingTag:" + s); - - final BiFunction elementFunc = (tagName, content) -> sequence( - tagFunc.apply(tagName).as("tag:" + tagName), - content.as("content"), - closingTagFunc.apply(tagName).as("closingTag:" + tagName)); - - final Rule data = elementFunc.apply("data", takeWhile(c -> c != '<')).as("dataElem"); - - final Rule node = elementFunc.apply("node", zeroOrMore(data)).as("nodeElem"); - - final Rule edge = elementFunc.apply("edge", zeroOrMore(data)).as("edgeElem"); - - final Rule graph = sequence( - tagFunc.apply("graph"), - oneOrMore(node).as("nodes"), - oneOrMore(edge).as("edges"), - closingTagFunc.apply("graph")).as("graphElem"); - - final Rule key = sequence(tagFunc.apply("key"), closingTagFunc.apply("key")) - .as("keyElem"); - - final Rule graphml = sequence( - tagFunc.apply("graphml"), - oneOrMore(key).as("keys"), - graph, - closingTagFunc.apply("graphml")).as("graphmlElem"); - - final Rule graphmlFile = sequence( - xmlHeader, - comments.discard(), - graphml).as("graphmlFile"); - - grammar = new Grammar(graphmlFile, null); - } + private final Grammar grammar = new GraphMLGrammar(); @Override public GraphMLParseResult parse(final String filePath) { diff --git a/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/graphml/GraphMLGrammar.java b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/graphml/GraphMLGrammar.java new file mode 100644 index 0000000..d4d1a43 --- /dev/null +++ b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/graphml/GraphMLGrammar.java @@ -0,0 +1,76 @@ +package com.albertoventurini.parsley.examples.graphml; + +import com.albertoventurini.parsley.grammar.Grammar; +import com.albertoventurini.parsley.grammar.rules.Rule; + +import java.util.function.BiFunction; +import java.util.function.Function; + +import static com.albertoventurini.parsley.grammar.rules.Rules.*; + +public class GraphMLGrammar extends Grammar { + + private final Rule comment = sequence(string("")).as("comment"); + private final Rule comments = zeroOrMore(comment).setComment(true).as("comments"); + + private final Rule xmlHeader = string("").as("header"); + + private final Rule attribute = sequence( + takeWhile(c -> c != '=' && c != '>'), + character('='), + character('\''), + takeWhile(c -> c != '\''), + character('\'')).as("attribute"); + + private final Function tagFunc = (s) -> sequence( + character('<'), + string(s).as("tagName"), + zeroOrMore(attribute).as("attributes"), + character('>')).as("tag:" + s); + + private final Function closingTagFunc = (s) -> sequence( + string("')).as("closingTag:" + s); + + private final BiFunction elementFunc = (tagName, content) -> sequence( + tagFunc.apply(tagName).as("tag:" + tagName), + content.as("content"), + closingTagFunc.apply(tagName).as("closingTag:" + tagName)); + + private final Rule data = elementFunc.apply("data", takeWhile(c -> c != '<')).as("dataElem"); + + private final Rule node = elementFunc.apply("node", zeroOrMore(data)).as("nodeElem"); + + private final Rule edge = elementFunc.apply("edge", zeroOrMore(data)).as("edgeElem"); + + private final Rule graph = sequence( + tagFunc.apply("graph"), + oneOrMore(node).as("nodes"), + oneOrMore(edge).as("edges"), + closingTagFunc.apply("graph")).as("graphElem"); + + private final Rule key = sequence(tagFunc.apply("key"), closingTagFunc.apply("key")) + .as("keyElem"); + + private final Rule graphml = sequence( + tagFunc.apply("graphml"), + oneOrMore(key).as("keys"), + graph, + closingTagFunc.apply("graphml")).as("graphmlElem"); + + private final Rule graphmlFile = sequence( + xmlHeader, + comments.discard(), + graphml).as("graphmlFile"); + + @Override + protected Rule startRule() { + return graphmlFile; + } + + @Override + protected Rule commentRule() { + return comments; + } +} diff --git a/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownGrammar.java b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownGrammar.java new file mode 100644 index 0000000..61b7512 --- /dev/null +++ b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownGrammar.java @@ -0,0 +1,35 @@ +package com.albertoventurini.parsley.examples.markdown; + +import com.albertoventurini.parsley.grammar.Grammar; +import com.albertoventurini.parsley.grammar.rules.Rule; + +import static com.albertoventurini.parsley.grammar.rules.Rules.*; + +public class MarkdownGrammar extends Grammar { + + private final Rule h1 = sequence( + character('#'), + takeWhile(c -> c != '\n') + ); + + private final Rule paragraph = sequence( + character('\n'), + takeWhile(c -> c != '\n') + ); + + private final Rule element = oneOf(h1, paragraph); + + private final Rule elements = sequence(element); + + private final Rule document = zeroOrMore(elements); + + @Override + public Rule startRule() { + return document; + } + + @Override + protected Rule commentRule() { + return null; + } +} diff --git a/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownParseResult.java b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownParseResult.java new file mode 100644 index 0000000..b934f64 --- /dev/null +++ b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownParseResult.java @@ -0,0 +1,4 @@ +package com.albertoventurini.parsley.examples.markdown; + +public class MarkdownParseResult { +} diff --git a/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownParser.java b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownParser.java new file mode 100644 index 0000000..215b6a8 --- /dev/null +++ b/parsley-examples/src/main/java/com/albertoventurini/parsley/examples/markdown/MarkdownParser.java @@ -0,0 +1,5 @@ +package com.albertoventurini.parsley.examples.markdown; + +public interface MarkdownParser { + MarkdownParseResult parse(String filePath); +} diff --git a/parsley-examples/src/test/java/com/albertoventurini/parsley/examples/graphml/GraphMLGrammarTest.java b/parsley-examples/src/test/java/com/albertoventurini/parsley/examples/graphml/GraphMLGrammarTest.java index 9f69020..d08fad1 100644 --- a/parsley-examples/src/test/java/com/albertoventurini/parsley/examples/graphml/GraphMLGrammarTest.java +++ b/parsley-examples/src/test/java/com/albertoventurini/parsley/examples/graphml/GraphMLGrammarTest.java @@ -1,6 +1,7 @@ package com.albertoventurini.parsley.examples.graphml; import com.albertoventurini.parsley.grammar.Grammar; +import com.albertoventurini.parsley.grammar.GrammarFactory; import com.albertoventurini.parsley.grammar.rules.Rule; import org.junit.jupiter.api.Test; @@ -9,7 +10,7 @@ import java.nio.file.Path; import java.util.function.BiFunction; import java.util.function.Function; -import static com.albertoventurini.parsley.grammar.Grammar.*; +import static com.albertoventurini.parsley.grammar.rules.Rules.*; import static org.junit.jupiter.api.Assertions.assertTrue; public class GraphMLGrammarTest { @@ -69,7 +70,7 @@ public class GraphMLGrammarTest { final Rule graphmlFile = sequence(xmlHeader, graphml).as("graphmlFile"); - grammar = new Grammar(graphmlFile, comments); + grammar = GrammarFactory.newGrammar(graphmlFile, comments); } @Test diff --git a/parsley-examples/src/test/java/com/albertoventurini/parsley/examples/graphml/MarkdownGrammarTest.java b/parsley-examples/src/test/java/com/albertoventurini/parsley/examples/graphml/MarkdownGrammarTest.java new file mode 100644 index 0000000..4d7d4bd --- /dev/null +++ b/parsley-examples/src/test/java/com/albertoventurini/parsley/examples/graphml/MarkdownGrammarTest.java @@ -0,0 +1,13 @@ +package com.albertoventurini.parsley.examples.graphml; + +import com.albertoventurini.parsley.examples.markdown.MarkdownGrammar; +import org.junit.jupiter.api.Test; + +public class MarkdownGrammarTest { + + @Test + public void markdownGrammar_withH1AndParagraph_shouldParse() { + final MarkdownGrammar grammar = new MarkdownGrammar(); + } + +} diff --git a/parsley-examples/src/test/resources/markdown/markdown1.md b/parsley-examples/src/test/resources/markdown/markdown1.md new file mode 100644 index 0000000..f93ee39 --- /dev/null +++ b/parsley-examples/src/test/resources/markdown/markdown1.md @@ -0,0 +1,155 @@ +# An h1 header + +Paragraphs are separated by a blank line. + +2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists +look like: + +* this one +* that one +* the other one + +Note that --- not considering the asterisk --- the actual text +content starts at 4-columns in. + +> Block quotes are +> written like so. +> +> They can span multiple paragraphs, +> if you like. + +Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all +in chapters 12--14"). Three dots ... will be converted to an ellipsis. +Unicode is supported. ☺ + + + +# An h2 header + +Here's a numbered list: + +1. first item +2. second item +3. third item + +Note again how the actual text starts at 4 columns in (4 characters +from the left side). Here's a code sample: + + # Let me re-iterate ... + for i in 1 .. 10 { do-something(i) } + +As you probably guessed, indented 4 spaces. By the way, instead of +indenting the block, you can use delimited blocks, if you like: + +~~~ +define foobar() { + print "Welcome to flavor country!"; +} +~~~ + +(which makes copying & pasting easier). You can optionally mark the +delimited block for Pandoc to syntax highlight it: + +~~~python +import time +# Quick, count to ten! +for i in range(10): + # (but not *too* quick) + time.sleep(0.5) + print i +~~~ + + + +### An h3 header + +Now a nested list: + +1. First, get these ingredients: + + * carrots + * celery + * lentils + +2. Boil some water. + +3. Dump everything in the pot and follow + this algorithm: + + find wooden spoon + uncover pot + stir + cover pot + balance wooden spoon precariously on pot handle + wait 10 minutes + goto first step (or shut off burner when done) + + Do not bump wooden spoon or it will fall. + +Notice again how text always lines up on 4-space indents (including +that last line which continues item 3 above). + +Here's a link to [a website](http://foo.bar), to a [local +doc](local-doc.html), and to a [section heading in the current +doc](#an-h2-header). Here's a footnote [^1]. + +[^1]: Footnote text goes here. + +Tables can look like this: + +size material color +---- ------------ ------------ +9 leather brown +10 hemp canvas natural +11 glass transparent + +Table: Shoes, their sizes, and what they're made of + +(The above is the caption for the table.) Pandoc also supports +multi-line tables: + +-------- ----------------------- +keyword text +-------- ----------------------- +red Sunsets, apples, and +other red or reddish +things. + +green Leaves, grass, frogs +and other things it's +not easy being. +-------- ----------------------- + +A horizontal rule follows. + +*** + +Here's a definition list: + +apples +: Good for making applesauce. +oranges +: Citrus! +tomatoes +: There's no "e" in tomatoe. + +Again, text is indented 4 spaces. (Put a blank line between each +term/definition pair to spread things out more.) + +Here's a "line block": + +| Line one +| Line too +| Line tree + +and images can be specified like so: + +![example image](example-image.jpg "An exemplary image") + +Inline math equations go in like so: $\omega = d\phi / dt$. Display +math should get its own line and be put in in double-dollarsigns: + +$$I = \int \rho R^{2} dV$$ + +And note that you can backslash-escape any punctuation characters +which you wish to be displayed literally, ex.: \`foo\`, \*bar\*, etc. \ No newline at end of file diff --git a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/Grammar.java b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/Grammar.java index 8664662..4bf2b67 100644 --- a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/Grammar.java +++ b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/Grammar.java @@ -1,89 +1,18 @@ package com.albertoventurini.parsley.grammar; -import com.albertoventurini.parsley.grammar.rules.AnyCharacter; -import com.albertoventurini.parsley.grammar.rules.MatchCharacter; -import com.albertoventurini.parsley.grammar.rules.MatchString; -import com.albertoventurini.parsley.grammar.rules.OneOf; -import com.albertoventurini.parsley.grammar.rules.OneOrMore; import com.albertoventurini.parsley.grammar.rules.Rule; -import com.albertoventurini.parsley.grammar.rules.Sequence; -import com.albertoventurini.parsley.grammar.rules.TakeWhileCharacter; -import com.albertoventurini.parsley.grammar.rules.UntilString; -import com.albertoventurini.parsley.grammar.rules.Wrapper; -import com.albertoventurini.parsley.grammar.rules.ZeroOrMore; -import com.albertoventurini.parsley.grammar.rules.ZeroOrOne; import java.util.Optional; -import java.util.function.Predicate; -public class Grammar { +public abstract class Grammar { - private final Rule startRule; + protected abstract Rule startRule(); - private final Rule commentRule; - - public Grammar( - final Rule startRule, - final Rule commentRule) { - this.startRule = startRule; - this.commentRule = commentRule; - - // TODO: better than this - if (commentRule != null) { - commentRule.setComment(true); - } - } + protected abstract Rule commentRule(); public Optional parse(final String text) { - final var ctx = new GrammarContext(text, commentRule); - return startRule.apply(ctx); + final var ctx = new GrammarContext(text, commentRule()); + return startRule().apply(ctx); } - public static MatchCharacter character(final char c) { - return new MatchCharacter(c); - } - - public static AnyCharacter anyChar() { - return new AnyCharacter(); - } - - public static MatchString string(final String s) { - return new MatchString(s); - } - - public static TakeWhileCharacter token() { - return new TakeWhileCharacter(); - } - - public static TakeWhileCharacter takeWhile(final Predicate characterPredicate) { - return new TakeWhileCharacter(characterPredicate); - } - - public static UntilString until(final String s) { - return new UntilString(s); - } - - public static Sequence sequence(final Rule... rules) { - return new Sequence(rules); - } - - public static OneOf oneOf(final Rule... rules) { - return new OneOf(rules); - } - - public static ZeroOrMore zeroOrMore(final Rule childRule) { - return new ZeroOrMore(childRule); - } - - public static ZeroOrOne zeroOrOne(final Rule childRule) { - return new ZeroOrOne(childRule); - } - - public static OneOrMore oneOrMore(final Rule childRule) { - return new OneOrMore(childRule); - } - - public static Wrapper wrapper() { - return new Wrapper(); - } } diff --git a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/GrammarFactory.java b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/GrammarFactory.java new file mode 100644 index 0000000..c572eb1 --- /dev/null +++ b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/GrammarFactory.java @@ -0,0 +1,27 @@ +package com.albertoventurini.parsley.grammar; + +import com.albertoventurini.parsley.grammar.rules.Rule; + +public class GrammarFactory { + + public static Grammar newGrammar(final Rule startRule, final Rule commentRule) { + // TODO: better than this + + if (commentRule != null) { + commentRule.setComment(true); + } + + return new Grammar() { + + @Override + protected Rule startRule() { + return startRule; + } + + @Override + protected Rule commentRule() { + return commentRule; + } + }; + } +} diff --git a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/ParseContext.java b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/ParseContext.java index 491c411..82fdbd0 100644 --- a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/ParseContext.java +++ b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/ParseContext.java @@ -2,7 +2,7 @@ package com.albertoventurini.parsley.grammar; import java.util.Arrays; -public class ParseContext { +class ParseContext { private final char[] charArr; private int cursor; diff --git a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/ParseTree.java b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/ParseTree.java index af496ee..02d643e 100644 --- a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/ParseTree.java +++ b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/ParseTree.java @@ -4,7 +4,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -public class ParseTree { +public abstract class ParseTree { private final String text; diff --git a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/MatchCharacter.java b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/MatchCharacter.java index c25df8a..43a7ff3 100644 --- a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/MatchCharacter.java +++ b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/MatchCharacter.java @@ -10,7 +10,6 @@ public final class MatchCharacter extends Rule { public MatchCharacter(final char c) { this.c = c; - discard = true; } diff --git a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Rule.java b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Rule.java index 7b34f58..ea6740d 100644 --- a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Rule.java +++ b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Rule.java @@ -42,7 +42,8 @@ public abstract class Rule { public abstract Optional tryApply(final GrammarContext ctx); - public void setComment(final boolean comment) { + public Rule setComment(final boolean comment) { isComment = comment; + return this; } } diff --git a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Rules.java b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Rules.java new file mode 100644 index 0000000..2331c5f --- /dev/null +++ b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Rules.java @@ -0,0 +1,54 @@ +package com.albertoventurini.parsley.grammar.rules; + +import java.util.function.Predicate; + +public class Rules { + + public static MatchCharacter character(final char c) { + return new MatchCharacter(c); + } + + public static AnyCharacter anyChar() { + return new AnyCharacter(); + } + + public static MatchString string(final String s) { + return new MatchString(s); + } + + public static TakeWhileCharacter token() { + return new TakeWhileCharacter(); + } + + public static TakeWhileCharacter takeWhile(final Predicate characterPredicate) { + return new TakeWhileCharacter(characterPredicate); + } + + public static UntilString until(final String s) { + return new UntilString(s); + } + + public static Sequence sequence(final Rule... rules) { + return new Sequence(rules); + } + + public static OneOf oneOf(final Rule... rules) { + return new OneOf(rules); + } + + public static ZeroOrMore zeroOrMore(final Rule childRule) { + return new ZeroOrMore(childRule); + } + + public static ZeroOrOne zeroOrOne(final Rule childRule) { + return new ZeroOrOne(childRule); + } + + public static OneOrMore oneOrMore(final Rule childRule) { + return new OneOrMore(childRule); + } + + public static Wrapper wrapper() { + return new Wrapper(); + } +} diff --git a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Sequence.java b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Sequence.java index b5e2f96..9f018e3 100644 --- a/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Sequence.java +++ b/parsley-grammar/src/main/java/com/albertoventurini/parsley/grammar/rules/Sequence.java @@ -20,7 +20,7 @@ public final class Sequence extends Rule { final int start = ctx.getCursor(); final List children = new ArrayList<>(rules.length); - for (final com.albertoventurini.parsley.grammar.rules.Rule rule : rules) { + for (final Rule rule : rules) { if (!ctx.hasNext()) { ctx.setCursor(start); return Optional.empty(); diff --git a/parsley-grammar/src/test/java/com/albertoventurini/parsley/grammar/GrammarTest.java b/parsley-grammar/src/test/java/com/albertoventurini/parsley/grammar/GrammarTest.java index fa50b79..31f25ea 100644 --- a/parsley-grammar/src/test/java/com/albertoventurini/parsley/grammar/GrammarTest.java +++ b/parsley-grammar/src/test/java/com/albertoventurini/parsley/grammar/GrammarTest.java @@ -5,13 +5,7 @@ import org.junit.jupiter.api.Test; import java.util.function.Function; -import static com.albertoventurini.parsley.grammar.Grammar.character; -import static com.albertoventurini.parsley.grammar.Grammar.oneOf; -import static com.albertoventurini.parsley.grammar.Grammar.sequence; -import static com.albertoventurini.parsley.grammar.Grammar.string; -import static com.albertoventurini.parsley.grammar.Grammar.takeWhile; -import static com.albertoventurini.parsley.grammar.Grammar.token; -import static com.albertoventurini.parsley.grammar.Grammar.zeroOrMore; +import static com.albertoventurini.parsley.grammar.rules.Rules.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -24,7 +18,7 @@ public class GrammarTest { takeWhile(Character::isLetterOrDigit), oneOf(string("/>"), character('>'))); - final Grammar grammar = new Grammar(tag, null); + final Grammar grammar = GrammarFactory.newGrammar(tag, null); final var parseTree1 = grammar.parse(""); @@ -49,7 +43,7 @@ public class GrammarTest { zeroOrMore(attribute), oneOf(string("/>"), character('>'))); - final Grammar grammar = new Grammar(tag, null); + final Grammar grammar = GrammarFactory.newGrammar(tag, null); assertTrue(grammar.parse("").isPresent()); @@ -111,7 +105,7 @@ public class GrammarTest { zeroOrMore(attribute), oneOf(string("/>"), character('>'))); - final Grammar grammar = new Grammar(tag, null); + final Grammar grammar = GrammarFactory.newGrammar(tag, null); assertTrue(grammar.parse("").isPresent()); } @@ -140,7 +134,7 @@ public class GrammarTest { tagFunc.apply("key"), closingTagFunc.apply("key")); - final Grammar grammar = new Grammar(key, null); + final Grammar grammar = GrammarFactory.newGrammar(key, null); assertTrue(grammar.parse("").isPresent()); }