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