started reorg to have codegen extensions for customizing and doing stuff like output=AST

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8766]
This commit is contained in:
parrt 2011-06-26 18:04:57 -08:00
parent 46f68c8d63
commit 506f8eec09
9 changed files with 160 additions and 2475 deletions

View File

@ -84,8 +84,8 @@ public class CodeGenerator {
factory = new LexerFactory(this);
}
OutputModelWalker walker = new OutputModelWalker(g.tool, templates);
OutputModelObject outputModel = factory.buildOutputModel();
OutputModelWalker walker = new OutputModelWalker(g.tool, templates);
ST st = walker.walk(outputModel);
if (CodeGenerator.LAUNCH_ST_INSPECTOR) {

View File

@ -1,22 +1,16 @@
package org.antlr.v4.codegen;
import org.antlr.v4.codegen.model.*;
import org.antlr.v4.tool.*;
import org.stringtemplate.v4.ST;
import java.util.*;
/** */
public class LexerFactory extends OutputModelFactory {
public LexerFactory(CodeGenerator gen) {
super(gen);
}
public LexerFactory(CodeGenerator gen) { super(gen); }
@Override
public OutputModelObject buildOutputModel() {
return new LexerFile(this, gen.getRecognizerFileName());
}
/*
public ST build() {
LexerGrammar lg = (LexerGrammar)gen.g;
ST fileST = gen.templates.getInstanceOf("LexerFile");
@ -26,16 +20,6 @@ public class LexerFactory extends OutputModelFactory {
fileST.add("fileName", gen.getRecognizerFileName());
fileST.add("lexer", lexerST);
SerializedATN atn = new SerializedATN(this, lg.atn);
for (String modeName : lg.modes.keySet()) { // for each mode
// injectDFAs(lg, lexerST, modeName);
// LexerCompiler comp = new LexerCompiler(lg);
// CompiledATN atn = comp.compileMode(modeName);
// injectPDAs(atn, lexerST, modeName);
}
LinkedHashMap<String,Integer> tokens = new LinkedHashMap<String,Integer>();
for (String t : gen.g.tokenNameToTypeMap.keySet()) {
Integer ttype = gen.g.tokenNameToTypeMap.get(t);
@ -46,66 +30,5 @@ public class LexerFactory extends OutputModelFactory {
return fileST;
}
// void injectDFAs(LexerGrammar lg, ST lexerST, String modeName) {
// System.out.println("inject dfa for "+modeName);
// DFA dfa = lg.modeToDFA.get(modeName);
// ST dfaST = gen.templates.getInstanceOf("DFA");
// dfaST.add("name", modeName);
// CompiledDFA obj = new CompiledDFA(dfa);
// dfaST.add("model", obj);
//// ST actionST = gen.templates.getInstanceOf("actionMethod");
//// actionST.add("name", modeName);
//// actionST.add("actions", obj.actions);
//// lexerST.add("actions", actionST);
// lexerST.add("dfas", dfaST);
// }
/*
void injectPDAs(CompiledATN atn, ST lexerST, String modeName) {
ST pdaST = gen.templates.getInstanceOf("ATN");
for (Rule r : atn.ruleActions.keySet()) {
Set<Token> actionTokens = atn.ruleActions.keySet(r);
ST actionST = gen.templates.getInstanceOf("actionMethod");
actionST.add("name", r.name);
for (Token t : actionTokens) {
actionST.add("actions", Misc.strip(t.getText(),1));
actionST.add("ruleIndex", r.index);
}
pdaST.add("actions", actionST);
lexerST.add("actions", actionST);
}
for (Rule r : atn.ruleSempreds.keySet()) {
Set<Token> sempredTokens = atn.ruleSempreds.keySet(r);
ST sempredST = gen.templates.getInstanceOf("sempredMethod");
sempredST.add("name", r.name);
sempredST.add("ruleIndex", r.index);
for (Token t : sempredTokens) {
sempredST.add("preds", t.getText());
}
pdaST.add("sempreds", sempredST);
lexerST.add("sempreds", sempredST);
}
pdaST.add("name", modeName);
pdaST.add("model", atn);
lexerST.add("atns", pdaST);
}
*/
// lexers don't do anything with rules etc...
@Override
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
return null;
}
@Override
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
return null;
}
@Override
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label) {
return null;
}
*/
}

View File

@ -1,17 +1,17 @@
package org.antlr.v4.codegen;
import org.antlr.v4.analysis.AnalysisPipeline;
import org.antlr.v4.codegen.model.*;
import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.tool.*;
import java.util.*;
/** Create output objects wthin rule functions */
/** Create output objects for elements *within* rule functions except
* buildOutputModel() which builds outer/root model object and any
* objects such as RuleFunction that surround elements in rule
* functions.
*/
public abstract class OutputModelFactory {
//TODO: lexer doesn't gen code anymore; refactor
public Grammar g;
public CodeGenerator gen;
@ -25,102 +25,80 @@ public abstract class OutputModelFactory {
this.g = gen.g;
}
public abstract OutputModelObject buildOutputModel();
public OutputModelObject buildOutputModel() {
return null;
}
public CodeBlock epsilon() { return new CodeBlock(this); }
// ALTERNATIVES / ELEMENTS
public CodeBlock alternative(List<SrcOp> elems) { return new CodeBlock(this, elems); }
public CodeBlock alternative(List<SrcOp> elems) {
return null;
}
public SrcOp action(GrammarAST ast) { return new Action(this, ast); }
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
return null;
}
public SrcOp forcedAction(GrammarAST ast) { return new ForcedAction(this, ast); }
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
return null;
}
public SrcOp sempred(GrammarAST ast) { return new SemPred(this, ast); }
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label) {
return null;
}
public abstract List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args);
public CodeBlock epsilon() {
return null;
}
public abstract List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args);
// ACTIONS
public abstract List<SrcOp> stringRef(GrammarAST ID, GrammarAST label);
public SrcOp action(GrammarAST ast) {
return null;
}
public SrcOp forcedAction(GrammarAST ast) {
return null;
}
public SrcOp sempred(GrammarAST ast) {
return null;
}
// AST OPS
public List<SrcOp> rootToken(List<SrcOp> ops) { return ops; }
public List<SrcOp> rootRule(List<SrcOp> ops) { return ops; }
// BLOCKS
public Choice getChoiceBlock(BlockAST blkAST, List<CodeBlock> alts) {
int decision = ((DecisionState)blkAST.atnState).decision;
if ( AnalysisPipeline.disjoint(g.decisionLOOK.get(decision)) ) {
return getLL1ChoiceBlock(blkAST, alts);
}
else {
return getLLStarChoiceBlock(blkAST, alts);
}
return null;
}
public Choice getEBNFBlock(GrammarAST ebnfRoot, List<CodeBlock> alts) {
int decision;
if ( ebnfRoot.getType()==ANTLRParser.POSITIVE_CLOSURE ) {
decision = ((PlusBlockStartState)ebnfRoot.atnState).loopBackState.decision;
}
else if ( ebnfRoot.getType()==ANTLRParser.CLOSURE ) {
decision = ((BlockStartState)ebnfRoot.atnState).decision;
}
else {
decision = ((DecisionState)ebnfRoot.atnState).decision;
}
if ( AnalysisPipeline.disjoint(g.decisionLOOK.get(decision)) ) {
return getLL1EBNFBlock(ebnfRoot, alts);
}
else {
return getLLStarEBNFBlock(ebnfRoot, alts);
}
return null;
}
public Choice getLL1ChoiceBlock(BlockAST blkAST, List<CodeBlock> alts) {
return new LL1AltBlock(this, blkAST, alts);
return null;
}
public Choice getLLStarChoiceBlock(BlockAST blkAST, List<CodeBlock> alts) {
return new AltBlock(this, blkAST, alts);
return null;
}
public Choice getLL1EBNFBlock(GrammarAST ebnfRoot, List<CodeBlock> alts) {
int ebnf = 0;
if ( ebnfRoot!=null ) ebnf = ebnfRoot.getType();
Choice c = null;
switch ( ebnf ) {
case ANTLRParser.OPTIONAL :
if ( alts.size()==1 ) c = new LL1OptionalBlockSingleAlt(this, ebnfRoot, alts);
else c = new LL1OptionalBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.CLOSURE :
if ( alts.size()==1 ) c = new LL1StarBlockSingleAlt(this, ebnfRoot, alts);
else c = new LL1StarBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.POSITIVE_CLOSURE :
if ( alts.size()==1 ) c = new LL1PlusBlockSingleAlt(this, ebnfRoot, alts);
else c = new LL1PlusBlock(this, ebnfRoot, alts);
break;
}
return c;
return null;
}
public Choice getLLStarEBNFBlock(GrammarAST ebnfRoot, List<CodeBlock> alts) {
int ebnf = 0;
if ( ebnfRoot!=null ) ebnf = ebnfRoot.getType();
Choice c = null;
switch ( ebnf ) {
case ANTLRParser.OPTIONAL :
c = new OptionalBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.CLOSURE :
c = new StarBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.POSITIVE_CLOSURE :
c = new PlusBlock(this, ebnfRoot, alts);
break;
}
return c;
return null;
}
public SrcOp getLL1Test(IntervalSet look, GrammarAST blkAST) {
return new TestSetInline(this, blkAST, look);
return null;
}
}

View File

@ -1,24 +1,33 @@
package org.antlr.v4.codegen;
import org.antlr.v4.analysis.AnalysisPipeline;
import org.antlr.v4.codegen.model.*;
import org.antlr.v4.codegen.model.ast.AddLeaf;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.misc.*;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.tool.*;
import java.util.List;
/** */
public class ParserFactory extends OutputModelFactory {
public ParserFactory(CodeGenerator gen) {
super(gen);
}
public ParserFactory(CodeGenerator gen) { super(gen); }
public OutputModelObject buildOutputModel() {
return new ParserFile(this, gen.getRecognizerFileName());
}
@Override
public CodeBlock epsilon() { return new CodeBlock(this); }
public CodeBlock alternative(List<SrcOp> elems) { return new CodeBlock(this, elems); }
public SrcOp action(GrammarAST ast) { return new Action(this, ast); }
public SrcOp forcedAction(GrammarAST ast) { return new ForcedAction(this, ast); }
public SrcOp sempred(GrammarAST ast) { return new SemPred(this, ast); }
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
InvokeRule r = new InvokeRule(this, ID, label);
AddToLabelList a = null;
@ -28,7 +37,6 @@ public class ParserFactory extends OutputModelFactory {
return Utils.list(r, a);
}
@Override
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
MatchToken matchOp = new MatchToken(this, (TerminalAST) ID, label);
AddToLabelList labelOp = null;
@ -43,9 +51,87 @@ public class ParserFactory extends OutputModelFactory {
return Utils.list(matchOp, labelOp, treeOp);
}
@Override
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label) {
return tokenRef(ID, label, null);
}
public Choice getChoiceBlock(BlockAST blkAST, List<CodeBlock> alts) {
int decision = ((DecisionState)blkAST.atnState).decision;
if ( AnalysisPipeline.disjoint(g.decisionLOOK.get(decision)) ) {
return getLL1ChoiceBlock(blkAST, alts);
}
else {
return getLLStarChoiceBlock(blkAST, alts);
}
}
public Choice getEBNFBlock(GrammarAST ebnfRoot, List<CodeBlock> alts) {
int decision;
if ( ebnfRoot.getType()==ANTLRParser.POSITIVE_CLOSURE ) {
decision = ((PlusBlockStartState)ebnfRoot.atnState).loopBackState.decision;
}
else if ( ebnfRoot.getType()==ANTLRParser.CLOSURE ) {
decision = ((BlockStartState)ebnfRoot.atnState).decision;
}
else {
decision = ((DecisionState)ebnfRoot.atnState).decision;
}
if ( AnalysisPipeline.disjoint(g.decisionLOOK.get(decision)) ) {
return getLL1EBNFBlock(ebnfRoot, alts);
}
else {
return getLLStarEBNFBlock(ebnfRoot, alts);
}
}
public Choice getLL1ChoiceBlock(BlockAST blkAST, List<CodeBlock> alts) {
return new LL1AltBlock(this, blkAST, alts);
}
public Choice getLLStarChoiceBlock(BlockAST blkAST, List<CodeBlock> alts) {
return new AltBlock(this, blkAST, alts);
}
public Choice getLL1EBNFBlock(GrammarAST ebnfRoot, List<CodeBlock> alts) {
int ebnf = 0;
if ( ebnfRoot!=null ) ebnf = ebnfRoot.getType();
Choice c = null;
switch ( ebnf ) {
case ANTLRParser.OPTIONAL :
if ( alts.size()==1 ) c = new LL1OptionalBlockSingleAlt(this, ebnfRoot, alts);
else c = new LL1OptionalBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.CLOSURE :
if ( alts.size()==1 ) c = new LL1StarBlockSingleAlt(this, ebnfRoot, alts);
else c = new LL1StarBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.POSITIVE_CLOSURE :
if ( alts.size()==1 ) c = new LL1PlusBlockSingleAlt(this, ebnfRoot, alts);
else c = new LL1PlusBlock(this, ebnfRoot, alts);
break;
}
return c;
}
public Choice getLLStarEBNFBlock(GrammarAST ebnfRoot, List<CodeBlock> alts) {
int ebnf = 0;
if ( ebnfRoot!=null ) ebnf = ebnfRoot.getType();
Choice c = null;
switch ( ebnf ) {
case ANTLRParser.OPTIONAL :
c = new OptionalBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.CLOSURE :
c = new StarBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.POSITIVE_CLOSURE :
c = new PlusBlock(this, ebnfRoot, alts);
break;
}
return c;
}
public SrcOp getLL1Test(IntervalSet look, GrammarAST blkAST) {
return new TestSetInline(this, blkAST, look);
}
}

View File

@ -26,8 +26,8 @@ import java.util.HashMap;
dummy : block[null, null] ;
block[GrammarAST label, GrammarAST ebnfRoot] returns [SrcOp omo]
: ^( blk=BLOCK (^(OPTIONS .+))?
{List<CodeBlock> alts = new ArrayList<CodeBlock>();}
: ^( blk=BLOCK (^(OPTIONS .+))?
{List<CodeBlock> alts = new ArrayList<CodeBlock>();}
( alternative {alts.add($alternative.omo);} )+
)
{
@ -49,7 +49,8 @@ alternative returns [CodeBlock omo]
}
: ^(ALT_REWRITE a=alternative .)
| ^(ALT EPSILON) {$omo = factory.epsilon();}
| ^( ALT ( element {elems.addAll($element.omos);} )+ ) {$omo = factory.alternative(elems);}
| ^( ALT ( element {if ($element.omos!=null) elems.addAll($element.omos);} )+ )
{$omo = factory.alternative(elems);}
;
element returns [List<SrcOp> omos]
@ -92,9 +93,7 @@ astBlockSuffix
// TODO: combine ROOT/BANG into one then just make new op ref'ing return value of atom/terminal...
// TODO: same for NOT
atom[GrammarAST label] returns [List<SrcOp> omos]
: ^(ROOT range[label])
| ^(BANG range[label]) {$omos = $range.omos;}
| ^(ROOT notSet[label])
: ^(ROOT notSet[label])
| ^(BANG notSet[label]) {$omos = $notSet.omos;}
| notSet[label]
| range[label] {$omos = $range.omos;}
@ -102,7 +101,11 @@ atom[GrammarAST label] returns [List<SrcOp> omos]
| ^(DOT ID ruleref[label])
| ^(WILDCARD .)
| WILDCARD
| ^(ROOT terminal[label]) {$omos = factory.rootToken($terminal.omos);}
| ^(BANG terminal[label]) {$omos = $terminal.omos;}
| terminal[label] {$omos = $terminal.omos;}
| ^(ROOT ruleref[label]) {$omos = factory.rootRule($ruleref.omos);}
| ^(BANG ruleref[label]) {$omos = $ruleref.omos;}
| ruleref[label] {$omos = $ruleref.omos;}
;
@ -112,9 +115,7 @@ notSet[GrammarAST label] returns [List<SrcOp> omos]
;
ruleref[GrammarAST label] returns [List<SrcOp> omos]
: ^(ROOT ^(RULE_REF ARG_ACTION?))
| ^(BANG ^(RULE_REF ARG_ACTION?)) {$omos = factory.ruleRef($RULE_REF, $label, $ARG_ACTION);}
| ^(RULE_REF ARG_ACTION?) {$omos = factory.ruleRef($RULE_REF, $label, $ARG_ACTION);}
: ^(RULE_REF ARG_ACTION?) {$omos = factory.ruleRef($RULE_REF, $label, $ARG_ACTION);}
;
range[GrammarAST label] returns [List<SrcOp> omos]
@ -127,6 +128,4 @@ terminal[GrammarAST label] returns [List<SrcOp> omos]
| ^(TOKEN_REF ARG_ACTION .) {$omos = factory.tokenRef($TOKEN_REF, $label, $ARG_ACTION);}
| ^(TOKEN_REF .) {$omos = factory.tokenRef($TOKEN_REF, $label, null);}
| TOKEN_REF {$omos = factory.tokenRef($TOKEN_REF, $label, null);}
| ^(ROOT terminal[label])
| ^(BANG terminal[label])
;

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,4 @@ public class ParserFile extends OutputModelObject {
}
parser = new Parser(factory, this);
}
// public void defineBitSet(BitSetDecl b) {
// bitSetDecls.add(b);
// }
}

View File

@ -81,6 +81,7 @@ public class RuleFunction extends OutputModelObject {
startState = factory.g.atn.ruleToStartState.get(r);
// TRIGGER factory functions for rule elements
factory.currentRule.push(this);
GrammarASTAdaptor adaptor = new GrammarASTAdaptor(r.ast.token.getInputStream());
GrammarAST blk = (GrammarAST)r.ast.getFirstChildWithType(ANTLRParser.BLOCK);

View File

@ -292,9 +292,7 @@ ebnfSuffix
| POSITIVE_CLOSURE
;
atom: ^(ROOT range)
| ^(BANG range)
| ^(ROOT notSet)
atom: ^(ROOT notSet)
| ^(BANG notSet)
| notSet
| ^(ROOT terminal)