[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6863]
This commit is contained in:
parrt 2010-05-12 16:50:23 -08:00
parent adc231ddae
commit d1b8c3229d
11 changed files with 387 additions and 372 deletions

View File

@ -74,7 +74,6 @@ LL1StarBlockSingleAlt(choice, expr, alts, preamble) ::= <<
<preamble> <preamble>
while ( <expr> ) { while ( <expr> ) {
<alts; separator="\n"> <alts; separator="\n">
<choice.loop
} }
>> >>
@ -100,7 +99,7 @@ LL1PlusBlockSingleAlt(choice, expr, alts, preamble) ::= <<
do { do {
<alts; separator="\n"> <alts; separator="\n">
// TODO: only if !set // TODO: only if !set
<choice.expr.nextToken.varName> = input.LA(1); choice.expr.nextToken.varName> = input.LA(1);
} while ( <expr> ); } while ( <expr> );
>> >>

View File

@ -10,13 +10,16 @@ import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarAST; import org.antlr.v4.tool.GrammarAST;
import java.util.List; import java.util.List;
import java.util.Stack;
/** */ /** Create output objects wthin rule functions */
public abstract class OutputModelFactory { public abstract class OutputModelFactory {
public Grammar g; public Grammar g;
public CodeGenerator gen; public CodeGenerator gen;
public OutputModelObject root; // Context ptrs
public OutputModelObject file; // root
public Stack<RuleFunction> currentRule = new Stack<RuleFunction>();
protected OutputModelFactory(CodeGenerator gen) { protected OutputModelFactory(CodeGenerator gen) {
this.gen = gen; this.gen = gen;
@ -25,17 +28,20 @@ public abstract class OutputModelFactory {
public abstract OutputModelObject buildOutputModel(); public abstract OutputModelObject buildOutputModel();
public abstract ParserFile outputFile(String fileName);
public abstract Parser parser(ParserFile pf);
public CodeBlock epsilon() { return new CodeBlock(this); } public CodeBlock epsilon() { return new CodeBlock(this); }
public CodeBlock alternative(List<SrcOp> elems) { return new CodeBlock(this, elems); } public CodeBlock alternative(List<SrcOp> elems) { return new CodeBlock(this, elems); }
public SrcOp action(GrammarAST ast) { return new Action(this, ast); } public SrcOp action(GrammarAST ast) { return new Action(this, ast); }
public SrcOp sempred(GrammarAST ast) { return new SemPred(this, ast); } public SrcOp sempred(GrammarAST ast) { return new SemPred(this, ast); }
public abstract List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args);
public abstract List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args);
public abstract List<SrcOp> stringRef(GrammarAST ID, GrammarAST label);
public Choice getChoiceBlock(BlockAST blkAST, GrammarAST ebnfRoot, List<CodeBlock> alts) { public Choice getChoiceBlock(BlockAST blkAST, GrammarAST ebnfRoot, List<CodeBlock> alts) {
// TODO: assumes LL1 // TODO: assumes LL1
int ebnf = 0; int ebnf = 0;

View File

@ -1,8 +1,11 @@
package org.antlr.v4.codegen; package org.antlr.v4.codegen;
import org.antlr.v4.codegen.src.*; import org.antlr.v4.codegen.src.*;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.tool.GrammarAST;
import org.antlr.v4.tool.TerminalAST;
import java.util.Stack; import java.util.List;
/** */ /** */
public class ParserFactory extends OutputModelFactory { public class ParserFactory extends OutputModelFactory {
@ -16,30 +19,29 @@ public class ParserFactory extends OutputModelFactory {
// put(MatchToken.class, "matchToken"); // put(MatchToken.class, "matchToken");
// }}; // }};
// Context ptrs
ParserFile file;
Parser parser;
Stack<RuleFunction> currentRule;
public ParserFactory(CodeGenerator gen) { public ParserFactory(CodeGenerator gen) {
super(gen); super(gen);
} }
public OutputModelObject buildOutputModel() { public OutputModelObject buildOutputModel() {
root = file = new ParserFile(this, gen.getRecognizerFileName()); return new ParserFile(this, gen.getRecognizerFileName());
file.parser = new Parser(this, file);
// side-effect: fills pf dfa and bitset defs
return file;
} }
public ParserFile outputFile(String fileName) { @Override
return new ParserFile(this, fileName); public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
InvokeRule r = new InvokeRule(this, ID, label);
return Utils.list(r);
} }
public Parser parser(ParserFile pf) { @Override
return new Parser(this, pf); public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
return Utils.list(new MatchToken(this, (TerminalAST)ID, label));
} }
public void defineBitSet(BitSetDef b) { file.defineBitSet(b); } @Override
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label) {
return tokenRef(ID, label, null);
}
public void defineBitSet(BitSetDef b) { ((ParserFile)file).defineBitSet(b); }
} }

View File

@ -7,6 +7,7 @@ options {
@header { @header {
package org.antlr.v4.codegen; package org.antlr.v4.codegen;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.codegen.src.*; import org.antlr.v4.codegen.src.*;
import org.antlr.v4.tool.*; import org.antlr.v4.tool.*;
import java.util.Collections; import java.util.Collections;
@ -38,24 +39,24 @@ alternative returns [CodeBlock omo]
@init {List<SrcOp> elems = new ArrayList<SrcOp>();} @init {List<SrcOp> elems = new ArrayList<SrcOp>();}
: ^(ALT_REWRITE a=alternative .) : ^(ALT_REWRITE a=alternative .)
| ^(ALT EPSILON) {$omo = factory.epsilon();} | ^(ALT EPSILON) {$omo = factory.epsilon();}
| ^( ALT ( element {elems.add($element.omo);} )+ ) {$omo = factory.alternative(elems);} | ^( ALT ( element {elems.addAll($element.omos);} )+ ) {$omo = factory.alternative(elems);}
; ;
element returns [SrcOp omo] element returns [List<SrcOp> omos]
: labeledElement {$omo = $labeledElement.omo;} : labeledElement {$omos = $labeledElement.omos;}
| atom[null] {$omo = $atom.omo;} | atom[null] {$omos = $atom.omos;}
| ebnf {$omo = $ebnf.omo;} | ebnf {$omos = Utils.list($ebnf.omo);}
| ACTION {$omo = factory.action($ACTION);} | ACTION {$omos = Utils.list(factory.action($ACTION));}
| SEMPRED {$omo = factory.sempred($SEMPRED);} | SEMPRED {$omos = Utils.list(factory.sempred($SEMPRED));}
| GATED_SEMPRED | GATED_SEMPRED
| treeSpec | treeSpec
; ;
labeledElement returns [SrcOp omo] labeledElement returns [List<SrcOp> omos]
: ^(ASSIGN ID atom[$ID] ) {$omo = $atom.omo;} : ^(ASSIGN ID atom[$ID] ) {$omos = $atom.omos;}
| ^(ASSIGN ID block[$ID,null]) {$omo = $block.omo;} | ^(ASSIGN ID block[$ID,null]) {$omos = Utils.list($block.omo);}
| ^(PLUS_ASSIGN ID atom[$ID]) {$omo = $atom.omo;} | ^(PLUS_ASSIGN ID atom[$ID]) {$omos = $atom.omos;}
| ^(PLUS_ASSIGN ID block[$ID,null]) {$omo = $block.omo;} | ^(PLUS_ASSIGN ID block[$ID,null]) {$omos = Utils.list($block.omo);}
; ;
treeSpec returns [SrcOp omo] treeSpec returns [SrcOp omo]
@ -79,42 +80,42 @@ astBlockSuffix
// TODO: combine ROOT/BANG into one then just make new op ref'ing return value of atom/terminal... // TODO: combine ROOT/BANG into one then just make new op ref'ing return value of atom/terminal...
// TODO: same for NOT // TODO: same for NOT
atom[GrammarAST label] returns [SrcOp omo] atom[GrammarAST label] returns [List<SrcOp> omos]
: ^(ROOT range[label]) : ^(ROOT range[label])
| ^(BANG range[label]) {$omo = $range.omo;} | ^(BANG range[label]) {$omos = $range.omos;}
| ^(ROOT notSet[label]) | ^(ROOT notSet[label])
| ^(BANG notSet[label]) {$omo = $notSet.omo;} | ^(BANG notSet[label]) {$omos = $notSet.omos;}
| notSet[label] | notSet[label]
| range[label] {$omo = $range.omo;} | range[label] {$omos = $range.omos;}
| ^(DOT ID terminal[label]) | ^(DOT ID terminal[label])
| ^(DOT ID ruleref[label]) | ^(DOT ID ruleref[label])
| ^(WILDCARD .) | ^(WILDCARD .)
| WILDCARD | WILDCARD
| terminal[label] {$omo = $terminal.omo;} | terminal[label] {$omos = $terminal.omos;}
| ruleref[label] {$omo = $ruleref.omo;} | ruleref[label] {$omos = $ruleref.omos;}
; ;
notSet[GrammarAST label] returns [SrcOp omo] notSet[GrammarAST label] returns [List<SrcOp> omos]
: ^(NOT terminal[label]) : ^(NOT terminal[label])
| ^(NOT block[label,null]) | ^(NOT block[label,null])
; ;
ruleref[GrammarAST label] returns [SrcOp omo] ruleref[GrammarAST label] returns [List<SrcOp> omos]
: ^(ROOT ^(RULE_REF ARG_ACTION?)) : ^(ROOT ^(RULE_REF ARG_ACTION?))
| ^(BANG ^(RULE_REF ARG_ACTION?)) {$omo = new InvokeRule(factory, $RULE_REF, $label);} | ^(BANG ^(RULE_REF ARG_ACTION?)) {$omos = factory.ruleRef($RULE_REF, $label, $ARG_ACTION);}
| ^(RULE_REF ARG_ACTION?) {$omo = new InvokeRule(factory, $RULE_REF, $label);} | ^(RULE_REF ARG_ACTION?) {$omos = factory.ruleRef($RULE_REF, $label, $ARG_ACTION);}
; ;
range[GrammarAST label] returns [SrcOp omo] range[GrammarAST label] returns [List<SrcOp> omos]
: ^(RANGE a=STRING_LITERAL b=STRING_LITERAL) : ^(RANGE a=STRING_LITERAL b=STRING_LITERAL)
; ;
terminal[GrammarAST label] returns [MatchToken omo] terminal[GrammarAST label] returns [List<SrcOp> omos]
: ^(STRING_LITERAL .) {$omo = new MatchToken(factory, (TerminalAST)$STRING_LITERAL, $label);} : ^(STRING_LITERAL .) {$omos = factory.stringRef($STRING_LITERAL, $label);}
| STRING_LITERAL {$omo = new MatchToken(factory, (TerminalAST)$STRING_LITERAL, $label);} | STRING_LITERAL {$omos = factory.stringRef($STRING_LITERAL, $label);}
| ^(TOKEN_REF ARG_ACTION .) {$omo = new MatchToken(factory, (TerminalAST)$TOKEN_REF, $label);} | ^(TOKEN_REF ARG_ACTION .) {$omos = factory.tokenRef($TOKEN_REF, $label, $ARG_ACTION);}
| ^(TOKEN_REF .) {$omo = new MatchToken(factory, (TerminalAST)$TOKEN_REF, $label);} | ^(TOKEN_REF .) {$omos = factory.tokenRef($TOKEN_REF, $label, null);}
| TOKEN_REF {$omo = new MatchToken(factory, (TerminalAST)$TOKEN_REF, $label);} | TOKEN_REF {$omos = factory.tokenRef($TOKEN_REF, $label, null);}
| ^(ROOT terminal[label]) | ^(ROOT terminal[label])
| ^(BANG terminal[label]) | ^(BANG terminal[label])
; ;

File diff suppressed because it is too large Load Diff

View File

@ -14,9 +14,9 @@ public class LL1PlusBlockSingleAlt extends LL1Choice {
public LL1PlusBlockSingleAlt(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) { public LL1PlusBlockSingleAlt(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
super(factory, blkAST, alts); super(factory, blkAST, alts);
IntervalSet loopBackLook = altLookSets[2]; // loop exit is alt 1 IntervalSet loopBackLook = altLookSets[2]; // loop exit is alt 1
expr = factory.getLL1Test(loopBackLook, blkAST); expr = factory.getLL1Test(loopBackLook, ast);
if ( expr instanceof TestSetInline ) { if ( expr instanceof TestSetInline ) {
CaptureNextToken nextToken = new CaptureNextToken("la"+blkAST.token.getTokenIndex()); CaptureNextToken nextToken = new CaptureNextToken("la"+ast.token.getTokenIndex());
addPreambleOp(nextToken); addPreambleOp(nextToken);
loopIteration.add(nextToken); loopIteration.add(nextToken);
} }

View File

@ -10,6 +10,15 @@ public abstract class OutputModelObject {
public OutputModelFactory factory; public OutputModelFactory factory;
public GrammarAST ast; public GrammarAST ast;
public OutputModelObject() {;}
public OutputModelObject(OutputModelFactory factory) { this.factory = factory; }
public OutputModelObject(OutputModelFactory factory, GrammarAST ast) {
this.factory = factory;
this.ast = ast;
}
/** If the output model object encloses some other model objects, /** If the output model object encloses some other model objects,
* we need to be able to walk them. Rather than make each class * we need to be able to walk them. Rather than make each class
* properly walk any nested objects, I'm going to use a generic * properly walk any nested objects, I'm going to use a generic
@ -21,13 +30,4 @@ public abstract class OutputModelObject {
public List<String> getChildren() { public List<String> getChildren() {
return null; return null;
} }
public OutputModelObject() {;}
public OutputModelObject(OutputModelFactory factory) { this.factory = factory; }
public OutputModelObject(OutputModelFactory factory, GrammarAST ast) {
this.factory = factory;
this.ast = ast;
}
} }

View File

@ -17,12 +17,6 @@ public class Parser extends OutputModelObject {
this.file = file; // who contains us? this.file = file; // who contains us?
name = factory.g.getRecognizerName(); name = factory.g.getRecognizerName();
for (Rule r : factory.g.rules.values()) funcs.add( new RuleFunction(factory, r) ); for (Rule r : factory.g.rules.values()) funcs.add( new RuleFunction(factory, r) );
// We create dfa and bitsets during rule function construction.
// They get stored in code gen for convenience as we walk rule block tree
// for (DFA dfa : gen.g.decisionDFAs.values()) {
// file.dfaDefs.add( new DFADef("DFA"+dfa.decision, dfa) );
// }
} }
@Override @Override

View File

@ -15,6 +15,8 @@ public class ParserFile extends OutputModelObject {
public ParserFile(OutputModelFactory factory, String fileName) { public ParserFile(OutputModelFactory factory, String fileName) {
super(factory); super(factory);
this.fileName = fileName; this.fileName = fileName;
factory.file = this;
parser = new Parser(factory, this);
} }
public void defineBitSet(BitSetDef b) { public void defineBitSet(BitSetDef b) {

View File

@ -47,6 +47,7 @@ public class RuleFunction extends OutputModelObject {
exceptions = Utils.nodesToStrings(r.exceptionActions); exceptions = Utils.nodesToStrings(r.exceptionActions);
if ( r.finallyAction!=null ) finallyAction = r.finallyAction.getText(); if ( r.finallyAction!=null ) finallyAction = r.finallyAction.getText();
factory.currentRule.push(this);
GrammarASTAdaptor adaptor = new GrammarASTAdaptor(r.ast.token.getInputStream()); GrammarASTAdaptor adaptor = new GrammarASTAdaptor(r.ast.token.getInputStream());
GrammarAST blk = (GrammarAST)r.ast.getFirstChildWithType(ANTLRParser.BLOCK); GrammarAST blk = (GrammarAST)r.ast.getFirstChildWithType(ANTLRParser.BLOCK);
CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk); CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk);
@ -57,6 +58,7 @@ public class RuleFunction extends OutputModelObject {
catch (Exception e){ catch (Exception e){
e.printStackTrace(System.err); e.printStackTrace(System.err);
} }
factory.currentRule.pop();
} }
@Override @Override

View File

@ -102,9 +102,17 @@ public class Utils {
return a; return a;
} }
public static <T> List<T> list(T... values) { // public static <T> List<T> list(T... values) {
List<T> x = new ArrayList<T>(values.length); // List<T> x = new ArrayList<T>(values.length);
for (T v : values) { // for (T v : values) {
// if ( v!=null ) x.add(v);
// }
// return x;
// }
public static List list(Object... values) {
List x = new ArrayList(values.length);
for (Object v : values) {
if ( v!=null ) x.add(v); if ( v!=null ) x.add(v);
} }
return x; return x;