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:
		| @@ -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"); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user