forked from jasder/antlr
got it generating getters, labels correctly. now to impl getters
This commit is contained in:
parent
6c2beb530d
commit
a6786743d4
|
@ -485,15 +485,20 @@ NonLocalAttrRef(s) ::= "((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>
|
||||||
SetNonLocalAttr(s, rhsChunks) ::=
|
SetNonLocalAttr(s, rhsChunks) ::=
|
||||||
"((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>)).<s.name> = <rhsChunks>;"
|
"((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>)).<s.name> = <rhsChunks>;"
|
||||||
|
|
||||||
AddToLabelList(a) ::= "_localctx.<a.listName>.add(<labelref(a.label)>);"
|
AddToLabelList(a) ::= "<ctx(a.label)>.<a.listName>.add(<labelref(a.label)>);"
|
||||||
|
|
||||||
TokenDecl(t) ::= "Token <t.name>"
|
TokenDecl(t) ::= "public Token <t.name>;"
|
||||||
TokenTypeDecl(t) ::= "int <t.name>;"
|
TokenTypeDecl(t) ::= "int <t.name>;"
|
||||||
TokenListDecl(t) ::= "List\<Token> <t.name> = new ArrayList\<Token>()"
|
TokenListDecl(t) ::= "public List\<Token> <t.name> = new ArrayList\<Token>();"
|
||||||
RuleContextDecl(r) ::= "<r.ctxName> <r.name>"
|
RuleContextDecl(r) ::= "public <r.ctxName> <r.name>;"
|
||||||
RuleContextListDecl(rdecl) ::= "List\<<rdecl.ctxName>> <rdecl.name> = new ArrayList\<<rdecl.ctxName>>()"
|
RuleContextListDecl(rdecl) ::= "public List\<<rdecl.ctxName>> <rdecl.name> = new ArrayList\<<rdecl.ctxName>>();"
|
||||||
|
|
||||||
ContextGetterDecl(g) ::= "public <g.decl> get<t.name>() { }"
|
ContextTokenGetterDecl(t) ::= "public Token <t.name>() { return null; }"
|
||||||
|
ContextTokenListGetterDecl(t) ::= "public List\<Token> <t.name>() { return null; }"
|
||||||
|
ContextTokenListIndexedGetterDecl(t) ::= "public Token <t.name>(int i) { return null; }"
|
||||||
|
ContextRuleGetterDecl(r) ::= "public <r.ctxName> <r.name>() { return null; }"
|
||||||
|
ContextRuleListGetterDecl(r) ::= "public List\<<r.ctxName>> <r.name>() { return null; }"
|
||||||
|
ContextRuleListIndexedGetterDecl(r) ::= "public <r.ctxName> <r.name>(int i) { return null; }"
|
||||||
|
|
||||||
LexerRuleContext() ::= "RuleContext"
|
LexerRuleContext() ::= "RuleContext"
|
||||||
|
|
||||||
|
@ -502,18 +507,19 @@ LexerRuleContext() ::= "RuleContext"
|
||||||
*/
|
*/
|
||||||
RuleContextNameSuffix() ::= "Context"
|
RuleContextNameSuffix() ::= "Context"
|
||||||
|
|
||||||
ImplicitTokenLabel(tokenName) ::= "_<tokenName>"
|
ImplicitTokenLabel(tokenName) ::= "<tokenName>"
|
||||||
ImplicitRuleLabel(ruleName) ::= "_<ruleName>"
|
ImplicitRuleLabel(ruleName) ::= "<ruleName>"
|
||||||
ImplicitSetLabel(id) ::= "_tset<id>"
|
ImplicitSetLabel(id) ::= "_tset<id>"
|
||||||
ListLabelName(label) ::= "<label>"
|
ListLabelName(label) ::= "<label>"
|
||||||
|
|
||||||
CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
|
CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
|
||||||
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"
|
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"
|
||||||
|
|
||||||
StructDecl(s,attrs,visitorDispatchMethods,interfaces,extensionMembers,
|
StructDecl(s,attrs,getters,visitorDispatchMethods,interfaces,extensionMembers,
|
||||||
superClass={ParserRuleContext\<<InputSymbolType()>>}) ::= <<
|
superClass={ParserRuleContext\<<InputSymbolType()>>}) ::= <<
|
||||||
public static class <s.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
|
public static class <s.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
|
||||||
<attrs:{a | public <a>;}; separator="\n">
|
<attrs:{a | <a>}; separator="\n">
|
||||||
|
<getters:{g | <g>}; separator="\n">
|
||||||
<if(s.ctorAttrs)>public <s.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state) { super(parent, state); }<endif>
|
<if(s.ctorAttrs)>public <s.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state) { super(parent, state); }<endif>
|
||||||
public <s.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state<s.ctorAttrs:{a | , <a>}>) {
|
public <s.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state<s.ctorAttrs:{a | , <a>}>) {
|
||||||
super(parent, state);
|
super(parent, state);
|
||||||
|
@ -531,9 +537,10 @@ public static class <s.name> extends <superClass><if(interfaces)> implements <in
|
||||||
}
|
}
|
||||||
>>
|
>>
|
||||||
|
|
||||||
AltLabelStructDecl(s,attrs,visitorDispatchMethods) ::= <<
|
AltLabelStructDecl(s,attrs,getters,visitorDispatchMethods) ::= <<
|
||||||
public static class <s.name> extends <currentRule.name>Context {
|
public static class <s.name> extends <currentRule.name>Context {
|
||||||
<attrs:{a | public <a.decl> get<a.name>() {\}}; separator="\n">
|
<attrs:{a | <a>}; separator="\n">
|
||||||
|
<getters:{g | <g>}; separator="\n">
|
||||||
public <s.name>(<currentRule.name>Context ctx) { copyFrom(ctx); }
|
public <s.name>(<currentRule.name>Context ctx) { copyFrom(ctx); }
|
||||||
<visitorDispatchMethods; separator="\n">
|
<visitorDispatchMethods; separator="\n">
|
||||||
}
|
}
|
||||||
|
@ -546,7 +553,7 @@ public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener\<<I
|
||||||
}
|
}
|
||||||
>>
|
>>
|
||||||
|
|
||||||
AttributeDecl(d) ::= "<d.decl>"
|
AttributeDecl(d) ::= "public <d.decl>;"
|
||||||
|
|
||||||
/** If we don't know location of label def x, use this template */
|
/** If we don't know location of label def x, use this template */
|
||||||
labelref(x) ::= "<if(!x.isLocal)>((<x.ctx.name>)_localctx).<endif><x.name>"
|
labelref(x) ::= "<if(!x.isLocal)>((<x.ctx.name>)_localctx).<endif><x.name>"
|
||||||
|
|
|
@ -203,13 +203,13 @@ public class LeftRecursiveRuleTransformer {
|
||||||
LeftRecursiveRuleAltInfo altInfo = r.recPrimaryAlts.get(i);
|
LeftRecursiveRuleAltInfo altInfo = r.recPrimaryAlts.get(i);
|
||||||
altInfo.altAST = (AltAST)primaryBlk.getChild(i);
|
altInfo.altAST = (AltAST)primaryBlk.getChild(i);
|
||||||
altInfo.altAST.leftRecursiveAltInfo = altInfo;
|
altInfo.altAST.leftRecursiveAltInfo = altInfo;
|
||||||
System.out.println(altInfo.altAST.toStringTree());
|
// System.out.println(altInfo.altAST.toStringTree());
|
||||||
}
|
}
|
||||||
for (int i = 0; i < r.recOpAlts.size(); i++) {
|
for (int i = 0; i < r.recOpAlts.size(); i++) {
|
||||||
LeftRecursiveRuleAltInfo altInfo = r.recOpAlts.getElement(i);
|
LeftRecursiveRuleAltInfo altInfo = r.recOpAlts.getElement(i);
|
||||||
altInfo.altAST = (AltAST)opsBlk.getChild(i);
|
altInfo.altAST = (AltAST)opsBlk.getChild(i);
|
||||||
altInfo.altAST.leftRecursiveAltInfo = altInfo;
|
altInfo.altAST.leftRecursiveAltInfo = altInfo;
|
||||||
System.out.println(altInfo.altAST.toStringTree());
|
// System.out.println(altInfo.altAST.toStringTree());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,21 @@ package org.antlr.v4.codegen;
|
||||||
|
|
||||||
import org.antlr.v4.analysis.AnalysisPipeline;
|
import org.antlr.v4.analysis.AnalysisPipeline;
|
||||||
import org.antlr.v4.codegen.model.*;
|
import org.antlr.v4.codegen.model.*;
|
||||||
import org.antlr.v4.codegen.model.decl.*;
|
import org.antlr.v4.codegen.model.decl.Decl;
|
||||||
|
import org.antlr.v4.codegen.model.decl.RuleContextDecl;
|
||||||
|
import org.antlr.v4.codegen.model.decl.TokenDecl;
|
||||||
|
import org.antlr.v4.codegen.model.decl.TokenListDecl;
|
||||||
import org.antlr.v4.parse.ANTLRParser;
|
import org.antlr.v4.parse.ANTLRParser;
|
||||||
import org.antlr.v4.runtime.atn.*;
|
import org.antlr.v4.runtime.atn.DecisionState;
|
||||||
|
import org.antlr.v4.runtime.atn.PlusBlockStartState;
|
||||||
|
import org.antlr.v4.runtime.atn.StarLoopEntryState;
|
||||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||||
import org.antlr.v4.tool.*;
|
import org.antlr.v4.tool.Alternative;
|
||||||
import org.antlr.v4.tool.ast.*;
|
import org.antlr.v4.tool.LeftRecursiveRule;
|
||||||
|
import org.antlr.v4.tool.Rule;
|
||||||
|
import org.antlr.v4.tool.ast.BlockAST;
|
||||||
|
import org.antlr.v4.tool.ast.GrammarAST;
|
||||||
|
import org.antlr.v4.tool.ast.TerminalAST;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -83,7 +92,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
||||||
InvokeRule invokeOp = new InvokeRule(this, ID, label);
|
InvokeRule invokeOp = new InvokeRule(this, ID, label);
|
||||||
// If no manual label and action refs as token/rule not label, we need to define implicit label
|
// If no manual label and action refs as token/rule not label, we need to define implicit label
|
||||||
if ( controller.needsImplicitLabel(ID, invokeOp) ) defineImplicitLabel(ID, invokeOp);
|
if ( controller.needsImplicitLabel(ID, invokeOp) ) defineImplicitLabel(ID, invokeOp);
|
||||||
AddToLabelList listLabelOp = getListLabelIfPresent(invokeOp, label);
|
AddToLabelList listLabelOp = getAddToListOpIfListLabelPresent(invokeOp, label);
|
||||||
return list(invokeOp, listLabelOp);
|
return list(invokeOp, listLabelOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,22 +100,29 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
||||||
LabeledOp matchOp = new MatchToken(this, (TerminalAST) ID);
|
LabeledOp matchOp = new MatchToken(this, (TerminalAST) ID);
|
||||||
if ( labelAST!=null ) {
|
if ( labelAST!=null ) {
|
||||||
String label = labelAST.getText();
|
String label = labelAST.getText();
|
||||||
|
RuleFunction rf = getCurrentRuleFunction();
|
||||||
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
|
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
|
||||||
|
// add Token _X and List<Token> X decls
|
||||||
|
defineImplicitLabel(ID, matchOp); // adds _X
|
||||||
TokenListDecl l = getTokenListLabelDecl(label);
|
TokenListDecl l = getTokenListLabelDecl(label);
|
||||||
getCurrentRuleFunction().addContextDecl(ID.getAltLabel(), l);
|
rf.addContextDecl(ID.getAltLabel(), l);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Decl d = getTokenLabelDecl(label);
|
||||||
|
((MatchToken) matchOp).labels.add(d);
|
||||||
|
rf.addContextDecl(ID.getAltLabel(), d);
|
||||||
}
|
}
|
||||||
|
|
||||||
// String label = labelAST.getText();
|
// Decl d = getTokenLabelDecl(label);
|
||||||
Decl d = getTokenLabelDecl(label);
|
// ((MatchToken)matchOp).labels.add(d);
|
||||||
((MatchToken)matchOp).labels.add(d);
|
// getCurrentRuleFunction().addContextDecl(ID.getAltLabel(), d);
|
||||||
getCurrentRuleFunction().addContextDecl(ID.getAltLabel(), d);
|
// if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
|
||||||
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
|
// TokenListDecl l = getTokenListLabelDecl(label);
|
||||||
TokenListDecl l = getTokenListLabelDecl(label);
|
// getCurrentRuleFunction().addContextDecl(ID.getAltLabel(), l);
|
||||||
getCurrentRuleFunction().addContextDecl(ID.getAltLabel(), l);
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ( controller.needsImplicitLabel(ID, matchOp) ) defineImplicitLabel(ID, matchOp);
|
if ( controller.needsImplicitLabel(ID, matchOp) ) defineImplicitLabel(ID, matchOp);
|
||||||
AddToLabelList listLabelOp = getListLabelIfPresent(matchOp, labelAST);
|
AddToLabelList listLabelOp = getAddToListOpIfListLabelPresent(matchOp, labelAST);
|
||||||
return list(matchOp, listLabelOp);
|
return list(matchOp, listLabelOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +150,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( controller.needsImplicitLabel(setAST, matchOp) ) defineImplicitLabel(setAST, matchOp);
|
if ( controller.needsImplicitLabel(setAST, matchOp) ) defineImplicitLabel(setAST, matchOp);
|
||||||
AddToLabelList listLabelOp = getListLabelIfPresent(matchOp, labelAST);
|
AddToLabelList listLabelOp = getAddToListOpIfListLabelPresent(matchOp, labelAST);
|
||||||
return list(matchOp, listLabelOp);
|
return list(matchOp, listLabelOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +169,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( controller.needsImplicitLabel(ast, wild) ) defineImplicitLabel(ast, wild);
|
if ( controller.needsImplicitLabel(ast, wild) ) defineImplicitLabel(ast, wild);
|
||||||
AddToLabelList listLabelOp = getListLabelIfPresent(wild, labelAST);
|
AddToLabelList listLabelOp = getAddToListOpIfListLabelPresent(wild, labelAST);
|
||||||
return list(wild, listLabelOp);
|
return list(wild, listLabelOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +305,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
||||||
getCurrentRuleFunction().addContextDecl(ast.getAltLabel(), d);
|
getCurrentRuleFunction().addContextDecl(ast.getAltLabel(), d);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddToLabelList getListLabelIfPresent(LabeledOp op, GrammarAST label) {
|
public AddToLabelList getAddToListOpIfListLabelPresent(LabeledOp op, GrammarAST label) {
|
||||||
AddToLabelList labelOp = null;
|
AddToLabelList labelOp = null;
|
||||||
if ( label!=null && label.parent.getType()==ANTLRParser.PLUS_ASSIGN ) {
|
if ( label!=null && label.parent.getType()==ANTLRParser.PLUS_ASSIGN ) {
|
||||||
String listLabel = gen.target.getListLabel(label.getText());
|
String listLabel = gen.target.getListLabel(label.getText());
|
||||||
|
|
|
@ -88,11 +88,9 @@ public class RuleFunction extends OutputModelObject {
|
||||||
if ( !factory.getGrammar().tool.no_auto_element_labels ) {
|
if ( !factory.getGrammar().tool.no_auto_element_labels ) {
|
||||||
List<Alternative> altsNoLabels = r.getUnlabeledAlts();
|
List<Alternative> altsNoLabels = r.getUnlabeledAlts();
|
||||||
if ( altsNoLabels!=null ) {
|
if ( altsNoLabels!=null ) {
|
||||||
for (Alternative alt : altsNoLabels) {
|
Set<Decl> decls = getDeclsForAllElements(altsNoLabels);
|
||||||
List<Decl> decls = getLabelsForAltElements(alt.ast);
|
|
||||||
// we know to put in rule ctx, so do it directly
|
// we know to put in rule ctx, so do it directly
|
||||||
for (Decl d : decls) ruleCtx.addDecl(d);
|
for (Decl d : decls) ruleCtx.addDecl(d);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +105,7 @@ public class RuleFunction extends OutputModelObject {
|
||||||
altToContext[altNum] = new AltLabelStructDecl(factory, r, altNum, label);
|
altToContext[altNum] = new AltLabelStructDecl(factory, r, altNum, label);
|
||||||
altLabelCtxs.put(label, altToContext[altNum]);
|
altLabelCtxs.put(label, altToContext[altNum]);
|
||||||
if ( !factory.getGrammar().tool.no_auto_element_labels ) {
|
if ( !factory.getGrammar().tool.no_auto_element_labels ) {
|
||||||
List<Decl> decls = getLabelsForAltElements(altAST);
|
Set<Decl> decls = getDeclsForAltElements(altAST);
|
||||||
// we know which ctx to put in, so do it directly
|
// we know which ctx to put in, so do it directly
|
||||||
for (Decl d : decls) altToContext[altNum].addDecl(d);
|
for (Decl d : decls) altToContext[altNum].addDecl(d);
|
||||||
}
|
}
|
||||||
|
@ -142,45 +140,86 @@ public class RuleFunction extends OutputModelObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** for all alts, find which ref X or r in way which needs List
|
||||||
|
Must see across alts. If any alt needs X or r as list, then
|
||||||
|
define as list.
|
||||||
|
*/
|
||||||
|
public Set<Decl> getDeclsForAllElements(List<Alternative> alts) {
|
||||||
|
Set<String> needsList = new HashSet<String>();
|
||||||
|
List<GrammarAST> allRefs = new ArrayList<GrammarAST>();
|
||||||
|
for (Alternative a :alts) {
|
||||||
|
IntervalSet reftypes = new IntervalSet(RULE_REF, TOKEN_REF);
|
||||||
|
List<GrammarAST> refs = a.ast.getNodesWithType(reftypes);
|
||||||
|
FrequencySet<String> altFreq = new FrequencySet<String>();
|
||||||
|
for (GrammarAST t : refs) {
|
||||||
|
String refLabelName = t.getText();
|
||||||
|
altFreq.add(refLabelName);
|
||||||
|
allRefs.add(t);
|
||||||
|
}
|
||||||
|
for (GrammarAST t : refs) {
|
||||||
|
String refLabelName = t.getText();
|
||||||
|
if ( altFreq.count(t.getText())>1 ) needsList.add(refLabelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<Decl> decls = new HashSet<Decl>();
|
||||||
|
for (GrammarAST t : allRefs) {
|
||||||
|
String refLabelName = t.getText();
|
||||||
|
List<Decl> d = getDeclForAltElement(t,
|
||||||
|
refLabelName,
|
||||||
|
needsList.contains(refLabelName));
|
||||||
|
decls.addAll(d);
|
||||||
|
}
|
||||||
|
return decls;
|
||||||
|
}
|
||||||
|
|
||||||
/** Get list of decls for token/rule refs.
|
/** Get list of decls for token/rule refs.
|
||||||
* Single ref X becomes label X
|
* Single ref X becomes X() getter
|
||||||
* Multiple refs to X become X1, X2, ...
|
* Multiple refs to X becomes List X() method, X(int i) method.
|
||||||
* Ref X in a loop then is part of List
|
* Ref X in a loop then we get List X(), X(int i)
|
||||||
*
|
*
|
||||||
* Does not gen labels for literals like '+', 'begin', ';', ...
|
* Does not gen labels for literals like '+', 'begin', ';', ...
|
||||||
*/
|
*/
|
||||||
public List<Decl> getLabelsForAltElements(AltAST altAST) {
|
public Set<Decl> getDeclsForAltElements(AltAST altAST) {
|
||||||
List<Decl> decls = new ArrayList<Decl>();
|
|
||||||
IntervalSet reftypes = new IntervalSet(RULE_REF,
|
IntervalSet reftypes = new IntervalSet(RULE_REF,
|
||||||
TOKEN_REF);
|
TOKEN_REF);
|
||||||
List<GrammarAST> refs = altAST.getNodesWithType(reftypes);
|
List<GrammarAST> refs = altAST.getNodesWithType(reftypes);
|
||||||
|
Set<Decl> decls = new HashSet<Decl>();
|
||||||
FrequencySet<String> freq = new FrequencySet<String>();
|
FrequencySet<String> freq = new FrequencySet<String>();
|
||||||
|
for (GrammarAST t : refs) freq.add(t.getText());
|
||||||
for (GrammarAST t : refs) {
|
for (GrammarAST t : refs) {
|
||||||
freq.add(t.getText());
|
|
||||||
}
|
|
||||||
// track which ref for X we are at so we can gen X1 if necessary
|
|
||||||
FrequencySet<String> counter = new FrequencySet<String>();
|
|
||||||
for (GrammarAST t : refs) {
|
|
||||||
boolean inLoop = t.hasAncestor(CLOSURE) || t.hasAncestor(POSITIVE_CLOSURE);
|
|
||||||
// System.out.println(altAST.toStringTree()+" "+t+" inLoop? "+inLoop);
|
|
||||||
Decl d;
|
|
||||||
String refLabelName = t.getText();
|
String refLabelName = t.getText();
|
||||||
if ( !inLoop && freq.count(refLabelName)>1 ) {
|
boolean inLoop = t.hasAncestor(CLOSURE) || t.hasAncestor(POSITIVE_CLOSURE);
|
||||||
counter.add(refLabelName);
|
boolean multipleRefs = freq.count(refLabelName)>1;
|
||||||
refLabelName = refLabelName+counter.count(refLabelName);
|
boolean needList = inLoop || multipleRefs;
|
||||||
}
|
// System.out.println(altAST.toStringTree()+" "+t+" inLoop? "+inLoop);
|
||||||
if ( t.getType()==RULE_REF ) {
|
List<Decl> d = getDeclForAltElement(t, refLabelName, needList);
|
||||||
Rule rref = factory.getGrammar().getRule(t.getText());
|
decls.addAll(d);
|
||||||
String ctxName = factory.getGenerator().target
|
}
|
||||||
.getRuleFunctionContextStructName(rref);
|
return decls;
|
||||||
if ( inLoop ) d = new RuleContextListDecl(factory, refLabelName, ctxName);
|
}
|
||||||
else d = new RuleContextDecl(factory, refLabelName, ctxName);
|
|
||||||
|
public List<Decl> getDeclForAltElement(GrammarAST t, String refLabelName, boolean needList) {
|
||||||
|
List<Decl> decls = new ArrayList<Decl>();
|
||||||
|
if ( t.getType()==RULE_REF ) {
|
||||||
|
Rule rref = factory.getGrammar().getRule(t.getText());
|
||||||
|
String ctxName = factory.getGenerator().target
|
||||||
|
.getRuleFunctionContextStructName(rref);
|
||||||
|
if ( needList ) {
|
||||||
|
decls.add( new ContextRuleListGetterDecl(factory, refLabelName, ctxName) );
|
||||||
|
decls.add( new ContextRuleListIndexedGetterDecl(factory, refLabelName, ctxName) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( inLoop ) d = new TokenListDecl(factory, refLabelName);
|
decls.add( new ContextRuleGetterDecl(factory, refLabelName, ctxName) );
|
||||||
else d = new TokenDecl(factory, refLabelName);
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( needList ) {
|
||||||
|
decls.add( new ContextTokenListGetterDecl(factory, refLabelName) );
|
||||||
|
decls.add( new ContextTokenListIndexedGetterDecl(factory, refLabelName) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
decls.add( new ContextTokenGetterDecl(factory, refLabelName) );
|
||||||
}
|
}
|
||||||
decls.add(d);
|
|
||||||
}
|
}
|
||||||
return decls;
|
return decls;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,34 @@ package org.antlr.v4.codegen.model.decl;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.OutputModelFactory;
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
|
|
||||||
/** public Token getID() { } */
|
public abstract class ContextGetterDecl extends Decl {
|
||||||
public class ContextGetterDecl extends Decl {
|
public ContextGetterDecl(OutputModelFactory factory, String name) {
|
||||||
public ContextGetterDecl(OutputModelFactory factory, String name, String decl) {
|
super(factory, name);
|
||||||
super(factory, name, decl);
|
}
|
||||||
|
|
||||||
|
/** Not used for output; just used to distinguish between decl types
|
||||||
|
* to avoid dups.
|
||||||
|
*/
|
||||||
|
public String getArgType() { return ""; }; // assume no args
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return name.hashCode() + getArgType().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Make sure that a getter does not equal a label. X() and X are ok.
|
||||||
|
* OTOH, treat X() with two diff return values as the same. Treat
|
||||||
|
* two X() with diff args as different.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if ( obj==null ) return false;
|
||||||
|
// A() and label A are different
|
||||||
|
if ( !(obj instanceof ContextGetterDecl) ) return false;
|
||||||
|
if ( this==obj ) return true;
|
||||||
|
if ( this.hashCode() != obj.hashCode() ) return false;
|
||||||
|
return
|
||||||
|
name.equals(((Decl) obj).name) &&
|
||||||
|
getArgType().equals(((ContextGetterDecl) obj).getArgType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.antlr.v4.codegen.model.decl;
|
||||||
|
|
||||||
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
|
|
||||||
|
/** public XContext X() { } */
|
||||||
|
public class ContextRuleGetterDecl extends ContextGetterDecl {
|
||||||
|
public String ctxName;
|
||||||
|
public ContextRuleGetterDecl(OutputModelFactory factory, String name, String ctxName) {
|
||||||
|
super(factory, name);
|
||||||
|
this.ctxName = ctxName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.antlr.v4.codegen.model.decl;
|
||||||
|
|
||||||
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
|
|
||||||
|
/** public List<XContext> X() { }
|
||||||
|
* public XContext X(int i) { }
|
||||||
|
*/
|
||||||
|
public class ContextRuleListGetterDecl extends ContextGetterDecl {
|
||||||
|
public String ctxName;
|
||||||
|
public ContextRuleListGetterDecl(OutputModelFactory factory, String name, String ctxName) {
|
||||||
|
super(factory, name);
|
||||||
|
this.ctxName = ctxName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.antlr.v4.codegen.model.decl;
|
||||||
|
|
||||||
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
|
|
||||||
|
public class ContextRuleListIndexedGetterDecl extends ContextRuleListGetterDecl {
|
||||||
|
public ContextRuleListIndexedGetterDecl(OutputModelFactory factory, String name, String ctxName) {
|
||||||
|
super(factory, name, ctxName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getArgType() {
|
||||||
|
return "int";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package org.antlr.v4.codegen.model.decl;
|
||||||
|
|
||||||
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
|
|
||||||
|
/** public Token X() { } */
|
||||||
|
public class ContextTokenGetterDecl extends ContextGetterDecl {
|
||||||
|
public ContextTokenGetterDecl(OutputModelFactory factory, String name) {
|
||||||
|
super(factory, name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.antlr.v4.codegen.model.decl;
|
||||||
|
|
||||||
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
|
|
||||||
|
/** public List<Token> X() { }
|
||||||
|
* public Token X(int i) { }
|
||||||
|
*/
|
||||||
|
public class ContextTokenListGetterDecl extends ContextGetterDecl {
|
||||||
|
public ContextTokenListGetterDecl(OutputModelFactory factory, String name) {
|
||||||
|
super(factory, name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.antlr.v4.codegen.model.decl;
|
||||||
|
|
||||||
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
|
|
||||||
|
public class ContextTokenListIndexedGetterDecl extends ContextTokenListGetterDecl {
|
||||||
|
public ContextTokenListIndexedGetterDecl(OutputModelFactory factory, String name) {
|
||||||
|
super(factory, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getArgType() {
|
||||||
|
return "int";
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,8 +54,14 @@ public class Decl extends SrcOp {
|
||||||
return name.hashCode();
|
return name.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** If same name, can't redefine, unless it's a getter */
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return name.equals(((Decl)obj).name);
|
if ( obj==null ) return false;
|
||||||
|
// A() and label A are different
|
||||||
|
if ( obj instanceof ContextGetterDecl ) return false;
|
||||||
|
if ( this==obj ) return true;
|
||||||
|
if ( this.hashCode() != obj.hashCode() ) return false;
|
||||||
|
return name.equals(((Decl) obj).name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,16 @@
|
||||||
package org.antlr.v4.codegen.model.decl;
|
package org.antlr.v4.codegen.model.decl;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.OutputModelFactory;
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
import org.antlr.v4.codegen.model.*;
|
import org.antlr.v4.codegen.model.ModelElement;
|
||||||
|
import org.antlr.v4.codegen.model.OutputModelObject;
|
||||||
|
import org.antlr.v4.codegen.model.VisitorDispatchMethod;
|
||||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||||
import org.antlr.v4.tool.*;
|
import org.antlr.v4.tool.Attribute;
|
||||||
|
import org.antlr.v4.tool.Rule;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/** This object models the structure holding all of the parameters,
|
/** This object models the structure holding all of the parameters,
|
||||||
* return values, local variables, and labels associated with a rule.
|
* return values, local variables, and labels associated with a rule.
|
||||||
|
@ -43,6 +48,7 @@ public class StructDecl extends Decl {
|
||||||
public String superClass;
|
public String superClass;
|
||||||
public boolean provideCopyFrom;
|
public boolean provideCopyFrom;
|
||||||
@ModelElement public OrderedHashSet<Decl> attrs = new OrderedHashSet<Decl>();
|
@ModelElement public OrderedHashSet<Decl> attrs = new OrderedHashSet<Decl>();
|
||||||
|
@ModelElement public OrderedHashSet<Decl> getters = new OrderedHashSet<Decl>();
|
||||||
@ModelElement public Collection<Attribute> ctorAttrs;
|
@ModelElement public Collection<Attribute> ctorAttrs;
|
||||||
@ModelElement public List<VisitorDispatchMethod> visitorDispatchMethods;
|
@ModelElement public List<VisitorDispatchMethod> visitorDispatchMethods;
|
||||||
@ModelElement public List<OutputModelObject> interfaces;
|
@ModelElement public List<OutputModelObject> interfaces;
|
||||||
|
@ -60,7 +66,11 @@ public class StructDecl extends Decl {
|
||||||
visitorDispatchMethods.add(new VisitorDispatchMethod(factory, r, false));
|
visitorDispatchMethods.add(new VisitorDispatchMethod(factory, r, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDecl(Decl d) { attrs.add(d); d.ctx = this; }
|
public void addDecl(Decl d) {
|
||||||
|
d.ctx = this;
|
||||||
|
if ( d instanceof ContextGetterDecl ) getters.add(d);
|
||||||
|
else attrs.add(d);
|
||||||
|
}
|
||||||
|
|
||||||
public void addDecl(Attribute a) {
|
public void addDecl(Attribute a) {
|
||||||
addDecl(new AttributeDecl(factory, a.name, a.decl));
|
addDecl(new AttributeDecl(factory, a.name, a.decl));
|
||||||
|
|
|
@ -29,14 +29,22 @@
|
||||||
|
|
||||||
package org.antlr.v4.tool.ast;
|
package org.antlr.v4.tool.ast;
|
||||||
|
|
||||||
import org.antlr.runtime.*;
|
import org.antlr.runtime.CharStream;
|
||||||
import org.antlr.runtime.tree.*;
|
import org.antlr.runtime.CommonToken;
|
||||||
import org.antlr.v4.parse.*;
|
import org.antlr.runtime.Token;
|
||||||
|
import org.antlr.runtime.tree.CommonTree;
|
||||||
|
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||||
|
import org.antlr.runtime.tree.Tree;
|
||||||
|
import org.antlr.v4.parse.ANTLRParser;
|
||||||
|
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||||
import org.antlr.v4.runtime.atn.ATNState;
|
import org.antlr.v4.runtime.atn.ATNState;
|
||||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||||
import org.antlr.v4.tool.Grammar;
|
import org.antlr.v4.tool.Grammar;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class GrammarAST extends CommonTree {
|
public class GrammarAST extends CommonTree {
|
||||||
/** For error msgs, nice to know which grammar this AST lives in */
|
/** For error msgs, nice to know which grammar this AST lives in */
|
||||||
|
@ -115,8 +123,8 @@ public class GrammarAST extends CommonTree {
|
||||||
public String getAltLabel() {
|
public String getAltLabel() {
|
||||||
List ancestors = this.getAncestors();
|
List ancestors = this.getAncestors();
|
||||||
if ( ancestors==null ) return null;
|
if ( ancestors==null ) return null;
|
||||||
for (Object o : ancestors) {
|
for (int i=ancestors.size()-1; i>=0; i--) {
|
||||||
GrammarAST p = (GrammarAST)o;
|
GrammarAST p = (GrammarAST)ancestors.get(i);
|
||||||
if ( p.getType()== ANTLRParser.ALT ) {
|
if ( p.getType()== ANTLRParser.ALT ) {
|
||||||
AltAST a = (AltAST)p;
|
AltAST a = (AltAST)p;
|
||||||
if ( a.altLabel!=null ) return a.altLabel.getText();
|
if ( a.altLabel!=null ) return a.altLabel.getText();
|
||||||
|
|
Loading…
Reference in New Issue