Sorting out Parboiled issues. Initial parser draft complete.
* Created test script. * Created working parser.
This commit is contained in:
40
src/main/com/jdblabs/jlp/JLPMain.groovy
Normal file
40
src/main/com/jdblabs/jlp/JLPMain.groovy
Normal file
@ -0,0 +1,40 @@
|
||||
package com.jdblabs.jlp
|
||||
|
||||
public class JLPMain {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
JLPMain inst = new JLPMain()
|
||||
|
||||
// create command-line parser
|
||||
CliBuilder cli = new CliBuilder(
|
||||
usage: 'jlp [options] <src-file> <src-file> ...')
|
||||
|
||||
// define options
|
||||
cli.h('Print this help information.', longOpt: 'help', required: false)
|
||||
|
||||
// parse options
|
||||
def opts = cli.parse(args)
|
||||
|
||||
// display help if requested
|
||||
if (opts.h) {
|
||||
cli.usage()
|
||||
return }
|
||||
|
||||
Map documentContext = [ docs: [:] ]
|
||||
|
||||
// get files passed in
|
||||
def filenames = opts.getArgs()
|
||||
def files = filenames.collect { new File(it) }
|
||||
|
||||
// -------- parse input -------- //
|
||||
files.inject(documentContext) { docContext, file ->
|
||||
inst.parse(new File(file), docContext) }
|
||||
|
||||
// -------- generate output -------- //
|
||||
}
|
||||
|
||||
public void parse(File inputFile, Map docCtx) {
|
||||
}
|
||||
|
||||
}
|
62
src/main/com/jdblabs/jlp/JLPPegParser.groovy
Normal file
62
src/main/com/jdblabs/jlp/JLPPegParser.groovy
Normal file
@ -0,0 +1,62 @@
|
||||
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")
|
||||
|
||||
}
|
Reference in New Issue
Block a user