diff --git a/src/main/com/jdblabs/jlp/JLPPegParser.groovy b/src/main/com/jdblabs/jlp/JLPPegParser.groovy deleted file mode 100644 index 0cec44b..0000000 --- a/src/main/com/jdblabs/jlp/JLPPegParser.groovy +++ /dev/null @@ -1,62 +0,0 @@ -package com.jdblabs.jlp - -import org.parboiled.BaseParser -import org.parboiled.Rule -import org.parboiled.annotations.* - -public class JLPPegParser extends BaseParser { - - public Rule CodePage() { - println "Parsing CodePage" - ZeroOrMore(FirstOf( - DocBlock(), - CodeBlock())) } - - Rule DocBlock() { - OneOrMore(FirstOf( - DirectiveBlock(), - MarkdownBlock())) } - - Rule CodeBlock() { - OneOrMore(Sequence( - TestNot(DOC_START), RemainingLine())) } - - Rule DirectiveBlock() { - FirstOf( - - // there is a bug in parboiled that prevents sequences of greater - // than 2, so this ia workaround - Sequence( - Sequence( - Sequence(DOC_START, DIRECTIVE_START), - Sequence(LongDirective(), RemainingLine())), - Sequence(Optional(MarkdownBlock()))), - - Sequence( - Sequence(DOC_START, DIRECTIVE_START), - Sequence(LineDirective(), RemainingLine()))) } - - Rule LongDirective() { FirstOf(AUTHOR_DIR, DOC_DIR, EXAMPLE_DIR) } - - Rule LineDirective() { ORG_DIR } - - Rule MarkdownBlock() { OneOrMore(MarkdownLine()) } - - Rule MarkdownLine() { - Sequence(DOC_START, Sequence(TestNot(DIRECTIVE_START), RemainingLine())) } - - Rule RemainingLine() { Sequence(OneOrMore(NOT_EOL), EOL) } - - Rule DOC_START = String("%% ") - Rule EOL = Ch('\n' as char) - Rule NOT_EOL = Sequence(TestNot(EOL), ANY) - Rule DIRECTIVE_START= Ch('@' as char) - Rule SLASH = Ch('/' as char) - - // directive terminals - Rule AUTHOR_DIR = IgnoreCase("author") - Rule DOC_DIR = IgnoreCase("doc") - Rule EXAMPLE_DIR = IgnoreCase("example") - Rule ORG_DIR = IgnoreCase("org") - -} diff --git a/src/main/com/jdblabs/jlp/JLPPegParser.java b/src/main/com/jdblabs/jlp/JLPPegParser.java new file mode 100644 index 0000000..bf4a7fa --- /dev/null +++ b/src/main/com/jdblabs/jlp/JLPPegParser.java @@ -0,0 +1,58 @@ +package com.jdblabs.jlp; + +import org.parboiled.Action; +import org.parboiled.BaseParser; +import org.parboiled.Context; +import org.parboiled.Rule; +import org.parboiled.annotations.*; + +public class JLPPegParser extends BaseParser { + + public Rule CodePage() { + return ZeroOrMore(FirstOf( + DocBlock(), + CodeBlock())); } + + Rule DocBlock() { + return OneOrMore(FirstOf( + DirectiveBlock(), + MarkdownBlock())); } + + Rule CodeBlock() { + return OneOrMore(Sequence( + TestNot(DOC_START), RemainingLine())); } + + Rule DirectiveBlock() { + return FirstOf( + + // there is a bug in parboiled that prevents sequences of greater + // than 2, so this ia workaround + Sequence(DOC_START, DIRECTIVE_START, LongDirective(), + RemainingLine(), Optional(MarkdownBlock())), + + Sequence(DOC_START, DIRECTIVE_START, LineDirective(), + RemainingLine())); } + + Rule LongDirective() { return FirstOf(AUTHOR_DIR, DOC_DIR, EXAMPLE_DIR); } + + Rule LineDirective() { return ORG_DIR; } + + Rule MarkdownBlock() { return OneOrMore(MarkdownLine()); } + + Rule MarkdownLine() { + return Sequence(DOC_START, TestNot(DIRECTIVE_START), RemainingLine()); } + + Rule RemainingLine() { return Sequence(OneOrMore(NOT_EOL), EOL); } + + Rule DOC_START = String("%% "); + Rule EOL = Ch('\n'); + Rule NOT_EOL = Sequence(TestNot(EOL), ANY); + Rule DIRECTIVE_START= Ch('@'); + Rule SLASH = Ch('/'); + + // directive terminals + Rule AUTHOR_DIR = IgnoreCase("author"); + Rule DOC_DIR = IgnoreCase("doc"); + Rule EXAMPLE_DIR = IgnoreCase("example"); + Rule ORG_DIR = IgnoreCase("org"); +} diff --git a/src/test/TestParser.class b/src/test/TestParser.class new file mode 100644 index 0000000..24b1c47 Binary files /dev/null and b/src/test/TestParser.class differ diff --git a/src/test/TestParser.java b/src/test/TestParser.java new file mode 100644 index 0000000..9bc72d9 --- /dev/null +++ b/src/test/TestParser.java @@ -0,0 +1,27 @@ +import org.parboiled.BaseParser; +import org.parboiled.Parboiled; +import org.parboiled.Rule; +import org.parboiled.annotations.BuildParseTree; +import org.parboiled.parserunners.ReportingParseRunner; +import org.parboiled.support.ParsingResult; +import static org.parboiled.support.ParseTreeUtils.printNodeTree; + +@BuildParseTree +public class TestParser extends BaseParser { + + public Rule S() { + return OneOrMore( + Sequence(A(), OneOrMore(B()), C())); } + + Rule A() { return Ch('a'); } + Rule B() { return Ch('b'); } + Rule C() { return Ch('c'); } + + public static void main(String[] args) { + TestParser parser = Parboiled.createParser(TestParser.class); + ReportingParseRunner parseRunner = new ReportingParseRunner(parser.S()); + + ParsingResult result = parseRunner.run("abbbbcabc"); + System.out.println(result.matched ? printNodeTree(result) + "\n" : "No Match"); + } +}