Fixed parser weirdness. More readable parser finished.
For whatever reason, writing the parser in Groovy was causing weird errors to occur when the parser or parse runner was created. Using a plain Java source file fixed this.
This commit is contained in:
parent
e8ebcd4998
commit
13e0e72fed
@ -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<Object> {
|
|
||||||
|
|
||||||
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")
|
|
||||||
|
|
||||||
}
|
|
58
src/main/com/jdblabs/jlp/JLPPegParser.java
Normal file
58
src/main/com/jdblabs/jlp/JLPPegParser.java
Normal file
@ -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<Object> {
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
BIN
src/test/TestParser.class
Normal file
BIN
src/test/TestParser.class
Normal file
Binary file not shown.
27
src/test/TestParser.java
Normal file
27
src/test/TestParser.java
Normal file
@ -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<Object> {
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user