Got a rule labels added to the tree and also altered code generation so that it pays attention to the labels. fairly major surgery but it's a nice refactoring.
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9062]
This commit is contained in:
parent
f13fd1973e
commit
bf19465437
|
@ -57,7 +57,7 @@ public class ParserRuleContext extends RuleContext {
|
|||
public int ruleIndex;
|
||||
|
||||
/** Set during parsing to identify which alt of rule parser is in. */
|
||||
public int alt;
|
||||
public int altNum;
|
||||
|
||||
public ParserRuleContext() { super(); }
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
grammar T;
|
||||
s : i=ifstat {System.out.println(_input.toString(0,_input.index()-1));} ;
|
||||
ifstat : 'if' '(' INT ')' ID '=' ID ';' ;
|
||||
|
||||
ifstat : 'if' '(' INT ')' ID '=' ID ';' # DoIf;
|
||||
|
||||
r[int x] returns [int y]
|
||||
locals [int z]
|
||||
: name=ID
|
||||
: name=ID # foo
|
||||
| ID (ID|';'{;}) # bar
|
||||
;
|
||||
|
||||
EQ : '=' ;
|
||||
|
|
|
@ -41,9 +41,9 @@ import org.antlr.v4.runtime.tree.ParseTreeListener;
|
|||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused"})
|
||||
public interface <listener.grammarName>Listener extends ParseTreeListener {
|
||||
<listener.rules:{r |
|
||||
void enterRule(<listener.parserName>.<r.name>Context ctx);
|
||||
void exitRule(<listener.parserName>.<r.name>Context ctx);}; separator="\n">
|
||||
<listener.listenerNames,listener.ruleNames:{lname,rname |
|
||||
void enter<lname>(<listener.parserName>.<rname>Context ctx);
|
||||
void exit<lname>(<listener.parserName>.<rname>Context ctx);}; separator="\n">
|
||||
}
|
||||
>>
|
||||
|
||||
|
@ -55,9 +55,9 @@ import org.antlr.v4.runtime.Token;
|
|||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused"})
|
||||
public class Blank<listener.grammarName>Listener implements <listener.grammarName>Listener {
|
||||
<listener.rules:{r |
|
||||
public void enterRule(<listener.parserName>.<r.name>Context ctx) { \}
|
||||
public void exitRule(<listener.parserName>.<r.name>Context ctx) { \}}; separator="\n">
|
||||
<listener.listenerNames,listener.ruleNames:{lname,rname |
|
||||
public void enter<lname>(<listener.parserName>.<rname>Context ctx) { \}
|
||||
public void exit<lname>(<listener.parserName>.<rname>Context ctx) { \}}; separator="\n">
|
||||
|
||||
public void enterEveryRule(ParserRuleContext ctx) { }
|
||||
public void exitEveryRule(ParserRuleContext ctx) { }
|
||||
|
@ -188,6 +188,11 @@ public QStack\<<currentRule.ctxType>\> <currentRule.name>_stk = new QStack\<<cur
|
|||
}
|
||||
>>
|
||||
|
||||
CodeBlockForOuterMostAlt(c, locals, preamble, ops) ::= <<
|
||||
_ctx.altNum = <c.altNum>;
|
||||
<CodeBlockForAlt(...)>
|
||||
>>
|
||||
|
||||
CodeBlockForAlt(c, locals, preamble, ops) ::= <<
|
||||
{
|
||||
<locals; separator="\n">
|
||||
|
@ -442,7 +447,7 @@ ListLabelName(label) ::= "<label>_list"
|
|||
CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
|
||||
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"
|
||||
|
||||
StructDecl(s,attrs) ::= <<
|
||||
StructDecl(s,attrs,visitorDispatchMethods) ::= <<
|
||||
public static class <s.name> extends ParserRuleContext {
|
||||
<attrs:{a | public <a>;}; separator="\n">
|
||||
<if(s.ctorAttrs)>public <s.name>(RuleContext parent, int state) { super(parent, state); }<endif>
|
||||
|
@ -450,8 +455,22 @@ public static class <s.name> extends ParserRuleContext {
|
|||
super(parent, state);
|
||||
<s.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
|
||||
}
|
||||
public void enterRule(ParseTreeListener listener) { ((<parser.grammarName>Listener)listener).enterRule(this); }
|
||||
public void exitRule(ParseTreeListener listener) { ((<parser.grammarName>Listener)listener).exitRule(this); }
|
||||
<visitorDispatchMethods; separator="\n">
|
||||
}
|
||||
>>
|
||||
|
||||
VisitorDispatchMethod(method) ::= <<
|
||||
public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener listener) {
|
||||
((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif><method.listenerName>(this);
|
||||
}
|
||||
>>
|
||||
|
||||
SwitchedVisitorDispatchMethod(method) ::= <<
|
||||
public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener listener) {
|
||||
switch ( altNum ) {
|
||||
<method.listenerNames:{m |
|
||||
case <i> : ((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif><m>(this); break;}; separator="\n">
|
||||
}
|
||||
}
|
||||
>>
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public abstract class BlankOutputModelFactory implements OutputModelFactory {
|
|||
|
||||
// ALTERNATIVES / ELEMENTS
|
||||
|
||||
public CodeBlockForAlt alternative(Alternative alt) { return null; }
|
||||
public CodeBlockForAlt alternative(Alternative alt, boolean outerMost) { return null; }
|
||||
|
||||
public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, List<SrcOp> ops) { return blk; }
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ public class OutputModelController {
|
|||
public CodeGenerator getGenerator() { return delegate.getGenerator(); }
|
||||
|
||||
public CodeBlockForAlt alternative(Alternative alt, boolean outerMost) {
|
||||
CodeBlockForAlt blk = delegate.alternative(alt);
|
||||
CodeBlockForAlt blk = delegate.alternative(alt, outerMost);
|
||||
if ( outerMost ) currentOuterMostAlternativeBlock = blk;
|
||||
for (CodeGeneratorExtension ext : extensions) blk = ext.alternative(blk, outerMost);
|
||||
return blk;
|
||||
|
|
|
@ -58,7 +58,7 @@ public interface OutputModelFactory {
|
|||
|
||||
// ELEMENT TRIGGERS
|
||||
|
||||
CodeBlockForAlt alternative(Alternative alt);
|
||||
CodeBlockForAlt alternative(Alternative alt, boolean outerMost);
|
||||
|
||||
CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, List<SrcOp> ops);
|
||||
|
||||
|
|
|
@ -34,7 +34,9 @@ import org.antlr.v4.codegen.model.*;
|
|||
import org.antlr.v4.codegen.model.ast.*;
|
||||
import org.antlr.v4.codegen.model.decl.*;
|
||||
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.semantics.UseDefAnalyzer;
|
||||
import org.antlr.v4.tool.*;
|
||||
|
@ -59,7 +61,10 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
|||
|
||||
public CodeBlockForAlt epsilon() { return new CodeBlockForAlt(this); }
|
||||
|
||||
public CodeBlockForAlt alternative(Alternative alt) { return new CodeBlockForAlt(this); }
|
||||
public CodeBlockForAlt alternative(Alternative alt, boolean outerMost) {
|
||||
if ( outerMost ) return new CodeBlockForOuterMostAlt(this, alt.altNum);
|
||||
return new CodeBlockForAlt(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, List<SrcOp> ops) {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
||||
/** The code associated with an outermost alternative overrule.
|
||||
* Sometimes we might want to treat them differently in the
|
||||
* code generation.
|
||||
*/
|
||||
public class CodeBlockForOuterMostAlt extends CodeBlockForAlt {
|
||||
public int altNum;
|
||||
|
||||
public CodeBlockForOuterMostAlt(OutputModelFactory factory, int altNum) {
|
||||
super(factory);
|
||||
this.altNum = altNum;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.misc.CharSupport;
|
||||
import org.antlr.v4.tool.ActionAST;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** A model object representing a parse tree listener file.
|
||||
* These are the rules specific events triggered by a parse tree visitor.
|
||||
|
@ -14,7 +16,8 @@ public class ListenerFile extends OutputModelObject {
|
|||
public String fileName;
|
||||
public String grammarName;
|
||||
public String parserName;
|
||||
public Collection<Rule> rules;
|
||||
public List<String> listenerNames = new ArrayList<String>();
|
||||
public List<String> ruleNames = new ArrayList<String>();
|
||||
|
||||
@ModelElement public Action header;
|
||||
|
||||
|
@ -24,7 +27,18 @@ public class ListenerFile extends OutputModelObject {
|
|||
Grammar g = factory.getGrammar();
|
||||
parserName = g.getRecognizerName();
|
||||
grammarName = g.name;
|
||||
rules = g.rules.values();
|
||||
for (Rule r : g.rules.values()) {
|
||||
List<String> labels = r.getAltLabels();
|
||||
if ( labels==null ) {
|
||||
listenerNames.add("Rule"); ruleNames.add(r.name);
|
||||
}
|
||||
else { // alt(s) with label(s)
|
||||
for (String label : labels) {
|
||||
String labelCapitalized = CharSupport.capitalize(label);
|
||||
listenerNames.add(labelCapitalized); ruleNames.add(r.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
ActionAST ast = g.namedActions.get("header");
|
||||
if ( ast!=null ) header = new Action(factory, ast);
|
||||
}
|
||||
|
|
|
@ -30,11 +30,14 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.decl.*;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.codegen.model.decl.StructDecl;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.Attribute;
|
||||
import org.antlr.v4.tool.GrammarAST;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -72,7 +75,7 @@ public class RuleFunction extends OutputModelObject {
|
|||
index = r.index;
|
||||
|
||||
// might need struct; build but drop later if no elements
|
||||
ruleCtx = new StructDecl(factory);
|
||||
ruleCtx = new StructDecl(factory, r);
|
||||
|
||||
if ( r.args!=null ) {
|
||||
ruleCtx.addDecls(r.args.attributes.values());
|
||||
|
@ -86,7 +89,7 @@ public class RuleFunction extends OutputModelObject {
|
|||
ruleCtx.addDecls(r.scope.attributes.values());
|
||||
}
|
||||
|
||||
ruleLabels = r.getLabelNames();
|
||||
ruleLabels = r.getElementLabelNames();
|
||||
tokenLabels = r.getTokenRefs();
|
||||
exceptions = Utils.nodesToStrings(r.exceptionActions);
|
||||
if ( r.finallyAction!=null ) finallyAction = new Action(factory, r.finallyAction);
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.misc.CharSupport;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SwitchedVisitorDispatchMethod extends VisitorDispatchMethod {
|
||||
public List<String> listenerNames = new ArrayList<String>();
|
||||
|
||||
public SwitchedVisitorDispatchMethod(OutputModelFactory factory, Rule r, boolean isEnter) {
|
||||
super(factory, r, isEnter);
|
||||
RuleFunction rf = factory.getCurrentRuleFunction();
|
||||
this.isEnter = isEnter;
|
||||
List<String> labels = r.getAltLabels();
|
||||
for (String label : labels) {
|
||||
String labelCapitalized = CharSupport.capitalize(label);
|
||||
listenerNames.add(labelCapitalized);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VisitorDispatchMethod extends OutputModelObject {
|
||||
public String listenerName = "Rule";
|
||||
public boolean isEnter;
|
||||
|
||||
public VisitorDispatchMethod(OutputModelFactory factory, Rule r, boolean isEnter) {
|
||||
super(factory);
|
||||
this.isEnter = isEnter;
|
||||
List<String> label = r.getAltLabels();
|
||||
if ( label!=null ) listenerName = label.get(0);
|
||||
}
|
||||
}
|
|
@ -31,22 +31,35 @@ package org.antlr.v4.codegen.model.decl;
|
|||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.ModelElement;
|
||||
import org.antlr.v4.codegen.model.SwitchedVisitorDispatchMethod;
|
||||
import org.antlr.v4.codegen.model.VisitorDispatchMethod;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
import org.antlr.v4.tool.Attribute;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/** */
|
||||
public class StructDecl extends Decl {
|
||||
@ModelElement public OrderedHashSet<Decl> attrs = new OrderedHashSet<Decl>();
|
||||
@ModelElement public Collection<Attribute> ctorAttrs;
|
||||
@ModelElement public List<VisitorDispatchMethod> visitorDispatchMethods;
|
||||
|
||||
public StructDecl(OutputModelFactory factory) {
|
||||
public StructDecl(OutputModelFactory factory, Rule r) {
|
||||
super(factory, null);
|
||||
}
|
||||
|
||||
public StructDecl(OutputModelFactory factory, String name) {
|
||||
super(factory, name);
|
||||
List<String> labels = r.getAltLabels();
|
||||
boolean multiAlts = labels!=null && labels.size()>1;
|
||||
visitorDispatchMethods = new ArrayList<VisitorDispatchMethod>();
|
||||
VisitorDispatchMethod enter = multiAlts ?
|
||||
new SwitchedVisitorDispatchMethod(factory, r, true) :
|
||||
new VisitorDispatchMethod(factory, r, true);
|
||||
visitorDispatchMethods.add(enter);
|
||||
VisitorDispatchMethod exit = multiAlts ?
|
||||
new SwitchedVisitorDispatchMethod(factory, r, false) :
|
||||
new VisitorDispatchMethod(factory, r, false);
|
||||
visitorDispatchMethods.add(exit);
|
||||
}
|
||||
|
||||
public void addDecl(Decl d) { attrs.add(d); }
|
||||
|
|
|
@ -157,4 +157,7 @@ public class CharSupport {
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
public static final String capitalize(String s) {
|
||||
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -448,6 +448,7 @@ ETC : '...' ;
|
|||
RARROW : '->' ;
|
||||
TREE_BEGIN : '^(' ;
|
||||
AT : '@' ;
|
||||
POUND : '#' ;
|
||||
NOT : '~' ;
|
||||
RBRACE : '}' ;
|
||||
|
||||
|
|
|
@ -530,10 +530,6 @@ ruleModifier
|
|||
| FRAGMENT
|
||||
;
|
||||
|
||||
altList
|
||||
: alternative (OR alternative)* -> alternative+
|
||||
;
|
||||
|
||||
// A set of alts, rewritten as a BLOCK for generic processing
|
||||
// in tree walkers. Used by the rule 'rule' so that the list of
|
||||
// alts for a rule appears as a BLOCK containing the alts and
|
||||
|
@ -542,13 +538,26 @@ altList
|
|||
// boundaries set correctly by rule post processing of rewrites.
|
||||
ruleBlock
|
||||
@init {Token colon = input.LT(-1);}
|
||||
: altList -> ^(BLOCK<BlockAST>[colon,"BLOCK"] altList)
|
||||
: ruleAltList -> ^(BLOCK<BlockAST>[colon,"BLOCK"] ruleAltList)
|
||||
;
|
||||
catch [ResyncToEndOfRuleBlock e] {
|
||||
// just resyncing; ignore error
|
||||
retval.tree = (GrammarAST)adaptor.errorNode(input, retval.start, input.LT(-1), null);
|
||||
}
|
||||
|
||||
ruleAltList
|
||||
: labeledAlt (OR labeledAlt)* -> labeledAlt+
|
||||
;
|
||||
|
||||
labeledAlt
|
||||
: alternative (POUND id {((AltAST)$alternative.tree).altLabel=$id.tree;})?
|
||||
-> alternative
|
||||
;
|
||||
|
||||
altList
|
||||
: alternative (OR alternative)* -> alternative+
|
||||
;
|
||||
|
||||
// An individual alt with an optional rewrite clause for the
|
||||
// elements of the alt.
|
||||
alternative
|
||||
|
|
|
@ -29,8 +29,10 @@
|
|||
|
||||
package org.antlr.v4.semantics;
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.v4.parse.*;
|
||||
import org.antlr.runtime.ANTLRStringStream;
|
||||
import org.antlr.runtime.Token;
|
||||
import org.antlr.v4.parse.ActionSplitter;
|
||||
import org.antlr.v4.parse.ActionSplitterListener;
|
||||
import org.antlr.v4.tool.*;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -204,7 +206,7 @@ public class AttributeChecks implements ActionSplitterListener {
|
|||
if ( x.equals(r.name) ) return r;
|
||||
List<LabelElementPair> labels = null;
|
||||
if ( node.resolver instanceof Rule ) {
|
||||
labels = r.getLabelDefs().get(x);
|
||||
labels = r.getElementLabelDefs().get(x);
|
||||
}
|
||||
else if ( node.resolver instanceof Alternative ) {
|
||||
labels = ((Alternative)node.resolver).labelDefs.get(x);
|
||||
|
|
|
@ -31,7 +31,8 @@ package org.antlr.v4.semantics;
|
|||
|
||||
import org.antlr.runtime.Token;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.parse.*;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.parse.GrammarTreeVisitor;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.stringtemplate.v4.misc.MultiMap;
|
||||
|
||||
|
@ -205,6 +206,7 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
|
|||
GrammarAST thrws, GrammarAST options,
|
||||
List<GrammarAST> actions, GrammarAST block)
|
||||
{
|
||||
// TODO: chk that all or no alts have "# label"
|
||||
checkInvalidRuleDef(ID.token);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,10 +33,15 @@ import org.antlr.runtime.Token;
|
|||
import org.antlr.runtime.tree.Tree;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
|
||||
/** An ALT (which can be child of ALT_REWRITE node) */
|
||||
/** Any ALT (which can be child of ALT_REWRITE node) */
|
||||
public class AltAST extends GrammarAST {
|
||||
public Alternative alt;
|
||||
|
||||
/** If someone specified an outermost alternative label with #foo.
|
||||
* Token type will be ID.
|
||||
*/
|
||||
public GrammarAST altLabel;
|
||||
|
||||
public AltAST(GrammarAST node) {
|
||||
super(node);
|
||||
this.alt = ((AltAST)node).alt;
|
||||
|
|
|
@ -33,16 +33,18 @@ package org.antlr.v4.tool;
|
|||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.stringtemplate.v4.misc.MultiMap;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Record use/def information about an outermost alternative in a subrule
|
||||
* or rule of a grammar.
|
||||
*/
|
||||
/** An outermost alternative for a rule. We don't track inner alternatives. */
|
||||
public class Alternative implements AttributeResolver {
|
||||
public Rule rule;
|
||||
|
||||
public AltAST ast;
|
||||
|
||||
/** What alternative number is this outermost alt? 1..n */
|
||||
public int altNum;
|
||||
|
||||
// token IDs, string literals in this alt
|
||||
public MultiMap<String, TerminalAST> tokenRefs = new MultiMap<String, TerminalAST>();
|
||||
|
||||
|
@ -70,7 +72,7 @@ public class Alternative implements AttributeResolver {
|
|||
*/
|
||||
public List<ActionAST> actions = new ArrayList<ActionAST>();
|
||||
|
||||
public Alternative(Rule r) { this.rule = r; }
|
||||
public Alternative(Rule r, int altNum) { this.rule = r; this.altNum = altNum; }
|
||||
|
||||
/** (ALT_REWRITE (ALT ...) (-> (ALT ...))); rewrite might nested in subrule */
|
||||
public boolean hasRewrite() {
|
||||
|
|
|
@ -124,7 +124,7 @@ public class Rule implements AttributeResolver {
|
|||
this.ast = ast;
|
||||
this.numberOfAlts = numberOfAlts;
|
||||
alt = new Alternative[numberOfAlts+1]; // 1..n
|
||||
for (int i=1; i<=numberOfAlts; i++) alt[i] = new Alternative(this);
|
||||
for (int i=1; i<=numberOfAlts; i++) alt[i] = new Alternative(this, i);
|
||||
}
|
||||
|
||||
public void defineActionInAlt(int currentAlt, ActionAST actionAST) {
|
||||
|
@ -163,7 +163,7 @@ public class Rule implements AttributeResolver {
|
|||
return refs;
|
||||
}
|
||||
|
||||
public Set<String> getLabelNames() {
|
||||
public Set<String> getElementLabelNames() {
|
||||
Set<String> refs = new HashSet<String>();
|
||||
for (int i=1; i<=numberOfAlts; i++) {
|
||||
refs.addAll(alt[i].labelDefs.keySet());
|
||||
|
@ -172,7 +172,7 @@ public class Rule implements AttributeResolver {
|
|||
return refs;
|
||||
}
|
||||
|
||||
public MultiMap<String, LabelElementPair> getLabelDefs() {
|
||||
public MultiMap<String, LabelElementPair> getElementLabelDefs() {
|
||||
MultiMap<String, LabelElementPair> defs =
|
||||
new MultiMap<String, LabelElementPair>();
|
||||
for (int i=1; i<=numberOfAlts; i++) {
|
||||
|
@ -185,7 +185,18 @@ public class Rule implements AttributeResolver {
|
|||
return defs;
|
||||
}
|
||||
|
||||
/** $x Attribute: rule arguments, return values, predefined rule prop.
|
||||
public List<String> getAltLabels() {
|
||||
List<String> labels = new ArrayList<String>();
|
||||
for (int i=1; i<=numberOfAlts; i++) {
|
||||
GrammarAST altLabel = alt[i].ast.altLabel;
|
||||
if ( altLabel==null ) break; // all or none
|
||||
labels.add(altLabel.getText());
|
||||
}
|
||||
if ( labels.size()==0 ) return null;
|
||||
return labels;
|
||||
}
|
||||
|
||||
/** $x Attribute: rule arguments, return values, predefined rule prop.
|
||||
*/
|
||||
public Attribute resolveToAttribute(String x, ActionAST node) {
|
||||
if ( args!=null ) {
|
||||
|
@ -253,7 +264,7 @@ public class Rule implements AttributeResolver {
|
|||
}
|
||||
|
||||
public LabelElementPair getAnyLabelDef(String x) {
|
||||
List<LabelElementPair> labels = getLabelDefs().get(x);
|
||||
List<LabelElementPair> labels = getElementLabelDefs().get(x);
|
||||
if ( labels!=null ) return labels.get(0);
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue