Worked on documentation, parser.

* Added planning documentation regrding the process.
* Updated grammer.
* Refactored the test code a bit.
* Added sample input file from vbs-suite
* Refactored the AST node structure created by the parser.
This commit is contained in:
Jonathan Bernard
2011-08-29 09:44:05 -05:00
parent c275fd0ce1
commit 557feaeb83
8 changed files with 398 additions and 53 deletions

View File

@ -10,7 +10,7 @@ import org.parboiled.Rule;
import org.parboiled.annotations.*;
import static com.jdblabs.jlp.ast.TextBlock.makeCodeBlock;
import static com.jdblabs.jlp.ast.TextBlock.makeMarkdownBlock;
import static com.jdblabs.jlp.ast.TextBlock.makeTextBlock;
@BuildParseTree
public class JLPPegParser extends BaseParser<Object> {
@ -20,7 +20,7 @@ public class JLPPegParser extends BaseParser<Object> {
public Rule SourceFile() {
return Sequence(
clearLineCount(),
push(new ArrayList<Object>()),
push(new ArrayList<ASTNode>()),
ZeroOrMore(Sequence(
FirstOf(
DocBlock(),
@ -29,22 +29,19 @@ public class JLPPegParser extends BaseParser<Object> {
/**
* Parses the rule:
* DocBlock = DirectiveBlock / MarkdownBlock
* DocBlock = (DirectiveBlock / DocTextBlock)+
*
* Pushes a DocBlock object onto the stack.
*/
Rule DocBlock() {
return Sequence(
push(new ArrayList<ASTNode>()),
OneOrMore(Sequence(
push(new DocBlock(curLineNum)),
OneOrMore(
FirstOf(
DirectiveBlock(),
MarkdownBlock()),
// stack is now: [List<ASTNode>, BlockValue *top*]
// pop the Block, then List, pass to helper to add the
// Block to the list, then push the List back on
push(addToList((ASTNode)pop(), (List<ASTNode>)pop()))))); }
Sequence(DirectiveBlock(),
push(addDirectiveBlock((Directive) pop(), (DocBlock) pop()))),
Sequence(DocTextBlock(),
push(addTextBlock((TextBlock) pop(), (DocBlock) pop())))))); }
/**
* Parses the rule:
@ -55,13 +52,15 @@ public class JLPPegParser extends BaseParser<Object> {
Rule CodeBlock() {
return Sequence(
push(curLineNum),
TestNot(DOC_START), RemainingLine(), push(match()),
ZeroOrMore(Sequence(
TestNot(DOC_START), RemainingLine(),
push(popAsString() + match()))),
push(""),
OneOrMore(FirstOf(
Sequence(
TestNot(DOC_START), RemainingLine(),
push(popAsString() + match())),
Sequence(EmptyLine(),
push(popAsString() + match())))),
push(makeCodeBlock(popAsString(),popAsInt()))); }
push(makeCodeBlock(popAsString(), popAsInt()))); }
/**
* Parses the rule:
* DirectiveBlock =
@ -77,7 +76,7 @@ public class JLPPegParser extends BaseParser<Object> {
/**
* Parses the rule:
* LongDirective =
* (AUTHOR_DIR / DOC_DIR / EXAMPLE_DIR) RemainingLine MarkdownBlock?
* (AUTHOR_DIR / DOC_DIR / EXAMPLE_DIR) RemainingLine DocTextBlock?
*
* Pushes a Directive object onto the value stack.
*/
@ -87,7 +86,7 @@ public class JLPPegParser extends BaseParser<Object> {
FirstOf(AUTHOR_DIR, DOC_DIR, EXAMPLE_DIR), push(match()),
RemainingLine(), push(match()),
Optional(Sequence(
MarkdownBlock(), // pushes block
DocTextBlock(), // pushes block
swap(),
push(popAsString() + ((TextBlock) pop()).value))),
@ -112,29 +111,29 @@ public class JLPPegParser extends BaseParser<Object> {
/**
* Parses the rule:
* MarkdownBlock = MarkdownLine+
* DocTextBlock = DocTextLine+
*
* Pushes a MarkdownBlock onto the stack as a string.
* Pushes a DocTextBlock onto the stack as a string.
*/
Rule MarkdownBlock() {
Rule DocTextBlock() {
return Sequence(
push(curLineNum),
MarkdownLine(), // pushes the value onto the stack
DocTextLine(), // pushes the value onto the stack
ZeroOrMore(Sequence(
MarkdownLine(),
DocTextLine(),
swap(),
push(popAsString() + popAsString()))),
push(makeMarkdownBlock(popAsString(), popAsInt()))); }
push(makeTextBlock(popAsString(), popAsInt()))); }
/**
* Parses the rule:
* MarkdownLine =
* DocTextLine =
* DOC_START !DIRECTIVE_START RemainingLine
*
* Pushes the line value (not including the DOC_START) onto the stack.
*/
Rule MarkdownLine() {
Rule DocTextLine() {
return Sequence(
DOC_START, TestNot(DIRECTIVE_START),
RemainingLine(), push(match())); }
@ -145,13 +144,17 @@ public class JLPPegParser extends BaseParser<Object> {
*/
@SuppressSubnodes
Rule RemainingLine() {
return Sequence(OneOrMore(NOT_EOL), EOL, incLineCount()); }
return Sequence(OneOrMore(NOT_EOL), FirstOf(EOL, EOI), incLineCount()); }
Rule EmptyLine() {
return Sequence(EOL, incLineCount()); }
Rule DOC_START = String("%% ");
Rule EOL = FirstOf(Ch('\n'), EOI);
Rule EOL = Ch('\n');
Rule NOT_EOL = Sequence(TestNot(EOL), ANY);
Rule DIRECTIVE_START= Ch('@');
Rule SLASH = Ch('/');
Rule SPACE = AnyOf(" \t");
// directive terminals
Rule AUTHOR_DIR = IgnoreCase("author");
@ -175,4 +178,12 @@ public class JLPPegParser extends BaseParser<Object> {
boolean clearLineCount() { curLineNum = 1; return true; }
boolean incLineCount() { curLineNum++; return true; }
boolean echo(String msg) { System.out.println(msg); return true; }
static DocBlock addDirectiveBlock(Directive dir, DocBlock docBlock) {
docBlock.directives.add(dir); return docBlock; }
static DocBlock addTextBlock(TextBlock tb, DocBlock docBlock) {
docBlock.textBlocks.add(tb); return docBlock; }
}