rewrote resolver to return attr and scopes
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6695]
This commit is contained in:
parent
d23c9cb527
commit
846e25d9cb
|
@ -68,16 +68,15 @@ public class AttributeChecks implements ActionSplitterListener {
|
|||
new AttributeChecks(g, r, alt, node, rhs).examineAction();
|
||||
}
|
||||
|
||||
public void qualifiedAttr(String expr, Token x, Token y) {
|
||||
if ( !node.resolver.resolves(x.getText(), y.getText(), node) ) {
|
||||
if ( !node.resolver.resolves(x.getText(), node) &&
|
||||
(r==null || !r.name.equals(x.getText())) )
|
||||
{
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
return;
|
||||
}
|
||||
if ( node.resolver.resolveRefToRule(x.getText(), node)!=null ) {
|
||||
public void qualifiedAttr(String expr, Token x, Token y) {
|
||||
if ( node.resolver.resolveToScope(x.getText(), node)==null ) {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( node.resolver.resolveToAttribute(x.getText(), y.getText(), node)==null ) {
|
||||
if ( node.resolver.resolveToRule(x.getText(), node)!=null ) {
|
||||
Rule rref = g.getRule(x.getText());
|
||||
if ( rref!=null && rref.args!=null && rref.args.get(y.getText())!=null ) {
|
||||
ErrorManager.grammarError(ErrorType.INVALID_RULE_PARAMETER_REF,
|
||||
|
@ -95,7 +94,7 @@ public class AttributeChecks implements ActionSplitterListener {
|
|||
}
|
||||
|
||||
public void setAttr(String expr, Token x, Token rhs) {
|
||||
if ( !node.resolver.resolves(x.getText(), node) ) {
|
||||
if ( node.resolver.resolveToAttribute(x.getText(), node)==null ) {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
}
|
||||
|
@ -103,15 +102,15 @@ public class AttributeChecks implements ActionSplitterListener {
|
|||
}
|
||||
|
||||
public void attr(String expr, Token x) { // arg, retval, predefined, token ref, rule ref, current rule
|
||||
if ( node.resolver.resolveRefToRule(x.getText(), node)!=null ) { // or in rule and is rule ref
|
||||
ErrorManager.grammarError(ErrorType.ISOLATED_RULE_SCOPE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
return;
|
||||
}
|
||||
if ( !node.resolver.resolves(x.getText(), node) ) {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
}
|
||||
if ( node.resolver.resolveToAttribute(x.getText(), node)==null ) {
|
||||
if ( node.resolver.resolveToRule(x.getText(), node)!=null ) { // or in rule and is rule ref
|
||||
ErrorManager.grammarError(ErrorType.ISOLATED_RULE_SCOPE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
return;
|
||||
}
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDynamicScopeAttr(String expr, Token x, Token y, Token rhs) {
|
||||
|
@ -120,18 +119,18 @@ public class AttributeChecks implements ActionSplitterListener {
|
|||
|
||||
public void dynamicScopeAttr(String expr, Token x, Token y) {
|
||||
System.out.println(x+" :: "+y);
|
||||
if ( !node.resolver.resolves(x.getText(), y.getText(), node) ) {
|
||||
if ( !node.resolver.resolves(x.getText(), node) &&
|
||||
(r==null || !r.name.equals(x.getText())) )
|
||||
{
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
}
|
||||
else {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_DYNAMIC_SCOPE_ATTRIBUTE,
|
||||
g.fileName, y, x.getText(), y.getText(), expr);
|
||||
}
|
||||
}
|
||||
// if ( !node.resolver.resolves(x.getText(), y.getText(), node) ) {
|
||||
// if ( !node.resolver.resolves(x.getText(), node) &&
|
||||
// (r==null || !r.name.equals(x.getText())) )
|
||||
// {
|
||||
// ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
// g.fileName, x, x.getText(), expr);
|
||||
// }
|
||||
// else {
|
||||
// ErrorManager.grammarError(ErrorType.UNKNOWN_DYNAMIC_SCOPE_ATTRIBUTE,
|
||||
// g.fileName, y, x.getText(), y.getText(), expr);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void setDynamicNegativeIndexedScopeAttr(String expr, Token x, Token y,
|
||||
|
|
|
@ -35,39 +35,54 @@ public class Alternative implements AttributeResolver {
|
|||
|
||||
public AttributeResolver getParent() { return rule; }
|
||||
|
||||
/** Is isolated x a token/rule/label ref? */
|
||||
public boolean resolves(String x, ActionAST node) {
|
||||
boolean inAlt =
|
||||
tokenRefs.get(x)!=null||
|
||||
ruleRefs.get(x)!=null ||
|
||||
labelDefs.get(x)!=null;
|
||||
if ( inAlt ) return inAlt;
|
||||
return getParent().resolves(x, node);
|
||||
}
|
||||
|
||||
/** Find x as token/rule/label ref then find y in properties list. */
|
||||
public boolean resolves(String x, String y, ActionAST node) {
|
||||
if ( tokenRefs.get(x)!=null ) { // token ref in this alt?
|
||||
return rule.getPredefinedScope(LabelType.TOKEN_LABEL).get(y)!=null;
|
||||
}
|
||||
if ( ruleRefs.get(x)!=null ) { // rule ref in this alt?
|
||||
// look up rule, ask it to resolve y (must be retval or predefined)
|
||||
return rule.g.getRule(x).resolvesAsRetvalOrProperty(y);
|
||||
}
|
||||
Rule r = resolveRefToRule(x, node);
|
||||
if ( r!=null ) return r.resolvesAsRetvalOrProperty(y);
|
||||
return getParent().resolves(x, y, node);
|
||||
}
|
||||
|
||||
public boolean dynScopeResolves(String x, ActionAST node) {
|
||||
return getParent().dynScopeResolves(x,node);
|
||||
// only rules have attr, not alts
|
||||
public Attribute resolveToAttribute(String x, ActionAST node) {
|
||||
return getParent().resolveToAttribute(x, node);
|
||||
}
|
||||
|
||||
public boolean dynScopeResolves(String x, String y, ActionAST node) {
|
||||
return getParent().dynScopeResolves(x,y,node);
|
||||
public Attribute resolveToAttribute(String x, String y, ActionAST node) {
|
||||
AttributeScope s = resolveToScope(x, node);
|
||||
return s.get(y);
|
||||
// if ( s.get(y)!=null ) return s.get(y);
|
||||
// return getParent().resolveToAttribute(x, y, node);
|
||||
}
|
||||
|
||||
public Rule resolveRefToRule(String x, ActionAST node) {
|
||||
/** Is isolated x a token/rule/label ref? */
|
||||
public AttributeScope resolveToScope(String x, ActionAST node) {
|
||||
if ( tokenRefs.get(x)!=null ) return AttributeScope.predefinedTokenScope;
|
||||
if ( ruleRefs.get(x)!=null ) return AttributeScope.predefinedTokenScope;
|
||||
List<LabelElementPair> labels = labelDefs.get(x);
|
||||
if ( labels !=null ) {
|
||||
LabelElementPair anyLabelDef = labels.get(0);
|
||||
return rule.getPredefinedScope(anyLabelDef.type);
|
||||
}
|
||||
return getParent().resolveToScope(x, node);
|
||||
}
|
||||
|
||||
// public boolean resolves(String x, ActionAST node) {
|
||||
// boolean inAlt =
|
||||
// tokenRefs.get(x)!=null||
|
||||
// ruleRefs.get(x)!=null ||
|
||||
// labelDefs.get(x)!=null;
|
||||
// if ( inAlt ) return inAlt;
|
||||
// return getParent().resolves(x, node);
|
||||
// }
|
||||
//
|
||||
// /** Find x as token/rule/label ref then find y in properties list. */
|
||||
// public boolean resolves(String x, String y, ActionAST node) {
|
||||
// if ( tokenRefs.get(x)!=null ) { // token ref in this alt?
|
||||
// return rule.getPredefinedScope(LabelType.TOKEN_LABEL).get(y)!=null;
|
||||
// }
|
||||
// if ( ruleRefs.get(x)!=null ) { // rule ref in this alt?
|
||||
// // look up rule, ask it to resolve y (must be retval or predefined)
|
||||
// return rule.g.getRule(x).resolvesAsRetvalOrProperty(y);
|
||||
// }
|
||||
// Rule r = resolveRule(x, node);
|
||||
// if ( r!=null ) return r.resolvesAsRetvalOrProperty(y);
|
||||
// return getParent().resolves(x, y, node);
|
||||
// }
|
||||
|
||||
public Rule resolveToRule(String x, ActionAST node) {
|
||||
if ( ruleRefs.get(x)!=null ) return rule.g.getRule(x);
|
||||
List<LabelElementPair> labels = labelDefs.get(x);
|
||||
if ( labels!=null ) { // it's a label ref. is it a rule label?
|
||||
|
@ -76,6 +91,6 @@ public class Alternative implements AttributeResolver {
|
|||
return rule.g.getRule(anyLabelDef.element.getText());
|
||||
}
|
||||
}
|
||||
return getParent().resolveRefToRule(x, node);
|
||||
return getParent().resolveToRule(x, node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ package org.antlr.v4.tool;
|
|||
*/
|
||||
public interface AttributeResolver {
|
||||
public AttributeResolver getParent();
|
||||
public boolean resolves(String x, ActionAST node);
|
||||
public boolean resolves(String x, String y, ActionAST node);
|
||||
public boolean dynScopeResolves(String x, ActionAST node);
|
||||
public boolean dynScopeResolves(String x, String y, ActionAST node);
|
||||
public Rule resolveRefToRule(String x, ActionAST node);
|
||||
public Attribute resolveToAttribute(String x, ActionAST node);
|
||||
public Attribute resolveToAttribute(String x, String y, ActionAST node);
|
||||
public AttributeScope resolveToScope(String x, ActionAST node);
|
||||
/** Resolve to surrounding rule, rule ref/label if in alt, or other rule */
|
||||
public Rule resolveToRule(String x, ActionAST node);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,9 @@ import java.util.Set;
|
|||
*/
|
||||
public class AttributeScope {
|
||||
/** The scope name */
|
||||
protected String name;
|
||||
public String name;
|
||||
public GrammarAST ast;
|
||||
// public Type type;
|
||||
|
||||
/** All token scopes (token labels) share the same fixed scope of
|
||||
* of predefined attributes. I keep this out of the runtime.Token
|
||||
|
|
|
@ -214,33 +214,35 @@ public class Grammar implements AttributeResolver {
|
|||
|
||||
public AttributeResolver getParent() { return null; }
|
||||
|
||||
/** $x in grammar action can only be scope name */
|
||||
public boolean resolves(String x, ActionAST node) {
|
||||
return scopes.get(x)!=null;
|
||||
}
|
||||
|
||||
/** $x.y makes no sense in grammar action; Rule.resolves()
|
||||
* shouldn't call this.
|
||||
*/
|
||||
public boolean resolves(String x, String y, ActionAST node) { return false; }
|
||||
|
||||
public boolean dynScopeResolves(String x, ActionAST node) {
|
||||
if ( scopes.get(x)!=null ) return true;
|
||||
// resolve inside of a rule? x can be any rule ref
|
||||
if ( !(node.resolver instanceof Grammar) ) {
|
||||
Rule r = getRule(x);
|
||||
if ( r!=null && r.scope!=null ) return true;
|
||||
}
|
||||
return false;
|
||||
// no isolated attr at grammar action level
|
||||
public Attribute resolveToAttribute(String x, ActionAST node) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean dynScopeResolves(String x, String y, ActionAST node) {
|
||||
public Attribute resolveToAttribute(String x, String y, ActionAST node) {
|
||||
AttributeScope s = resolveToScope(x, node);
|
||||
return s.get(y);
|
||||
}
|
||||
|
||||
// $x can be scope (but not rule with scope)
|
||||
public AttributeScope resolveToScope(String x, ActionAST node) {
|
||||
AttributeScope s = scopes.get(x);
|
||||
return s.get(y)!=null;
|
||||
if ( s!=null ) return s;
|
||||
return null;
|
||||
}
|
||||
|
||||
// /** $x in grammar action can only be scope name */
|
||||
// public boolean resolves(String x, ActionAST node) {
|
||||
// return scopes.get(x)!=null;
|
||||
// }
|
||||
//
|
||||
// /** $x.y makes no sense in grammar action; Rule.resolves()
|
||||
// * shouldn't call this.
|
||||
// */
|
||||
// public boolean resolves(String x, String y, ActionAST node) { return false; }
|
||||
|
||||
/** Can't be a rule ref in grammar named action */
|
||||
public Rule resolveRefToRule(String x, ActionAST node) { return null; }
|
||||
public Rule resolveToRule(String x, ActionAST node) { return null; }
|
||||
|
||||
/** Given a grammar type, what should be the default action scope?
|
||||
* If I say @members in a COMBINED grammar, for example, the
|
||||
|
|
|
@ -79,49 +79,25 @@ public class Rule implements AttributeResolver {
|
|||
for (int i=1; i<=numberOfAlts; i++) alt[i] = new Alternative(this);
|
||||
}
|
||||
|
||||
public AttributeResolver getParent() { return g; }
|
||||
|
||||
/** Is isolated x an arg, retval, predefined prop? */
|
||||
public boolean resolves(String x, ActionAST node) {
|
||||
if ( resolvesAsRetvalOrProperty(x) ) return true;
|
||||
if ( args.get(x)!=null ) return true;
|
||||
// resolve outside of an alt?
|
||||
if ( node.resolver instanceof Alternative ) return getParent().resolves(x, node);
|
||||
if ( getLabelNames().contains(x) ) return true; // can see all labels if not in alt
|
||||
return getParent().resolves(x, node);
|
||||
}
|
||||
|
||||
/** For $x.y, is x an arg, retval, predefined prop, token/rule/label ref?
|
||||
* If so, make sure y resolves within that perspective.
|
||||
* For $x::y, is x this rule or another? If so, is y in that scope?
|
||||
*/
|
||||
public boolean resolves(String x, String y, ActionAST node) {
|
||||
Rule r = resolveRefToRule(x, node);
|
||||
if ( r!=null ) return r.resolvesAsRetvalOrProperty(y);
|
||||
return getParent().resolves(x,y,node);
|
||||
}
|
||||
|
||||
public boolean dynScopeResolves(String x, ActionAST node) {
|
||||
return x.equals(this.name);
|
||||
}
|
||||
|
||||
public boolean dynScopeResolves(String x, String y, ActionAST node) {
|
||||
return x.equals(this.name) && scope.get(y)!=null;
|
||||
}
|
||||
|
||||
public Rule resolveRefToRule(String x, ActionAST node) {
|
||||
if ( x.equals(this.name) ) return this;
|
||||
if ( node.resolver == this ) { // action not in alt (attr space is this rule)
|
||||
List<LabelElementPair> labels = getLabelDefs().get(x);
|
||||
if ( labels!=null ) { // it's a label ref. is it a rule label?
|
||||
LabelElementPair anyLabelDef = labels.get(0);
|
||||
if ( anyLabelDef.type==LabelType.RULE_LABEL ) {
|
||||
return g.getRule(anyLabelDef.element.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // don't look for general rule (not one ref'd in this rule)
|
||||
}
|
||||
// public boolean resolves(String x, ActionAST node) {
|
||||
// if ( resolvesAsRetvalOrProperty(x) ) return true;
|
||||
// if ( args.get(x)!=null ) return true;
|
||||
// // resolve outside of an alt?
|
||||
// if ( node.resolver instanceof Alternative ) return getParent().resolves(x, node);
|
||||
// if ( getLabelNames().contains(x) ) return true; // can see all labels if not in alt
|
||||
// return getParent().resolves(x, node);
|
||||
// }
|
||||
//
|
||||
// /** For $x.y, is x an arg, retval, predefined prop, token/rule/label ref?
|
||||
// * If so, make sure y resolves within that perspective.
|
||||
// * For $x::y, is x this rule or another? If so, is y in that scope?
|
||||
// */
|
||||
// public boolean resolves(String x, String y, ActionAST node) {
|
||||
// Rule r = resolveRule(x, node);
|
||||
// if ( r!=null ) return r.resolvesAsRetvalOrProperty(y);
|
||||
// return getParent().resolves(x,y,node);
|
||||
// }
|
||||
|
||||
public boolean resolvesAsRetvalOrProperty(String y) {
|
||||
if ( retvals.get(y)!=null ) return true;
|
||||
|
@ -156,7 +132,56 @@ public class Rule implements AttributeResolver {
|
|||
return defs;
|
||||
}
|
||||
|
||||
/** Look up name from context of this rule and an alternative.
|
||||
public AttributeResolver getParent() { return g; }
|
||||
|
||||
public Attribute resolveToAttribute(String x, ActionAST node) {
|
||||
Attribute a = args.get(name); if ( a!=null ) return a;
|
||||
a = retvals.get(name); if ( a!=null ) return a;
|
||||
AttributeScope properties = getPredefinedScope(LabelType.RULE_LABEL);
|
||||
a = properties.get(name);
|
||||
if ( a!=null ) return a;
|
||||
// not here? look in grammar for global scope
|
||||
return getParent().resolveToAttribute(x, node);
|
||||
}
|
||||
|
||||
public Attribute resolveToAttribute(String x, String y, ActionAST node) {
|
||||
AttributeScope s = resolveToScope(x, node);
|
||||
return s.get(y);
|
||||
}
|
||||
|
||||
/** $r ref in rule r? if not, look for x in grammar's perspective
|
||||
*/
|
||||
public AttributeScope resolveToScope(String x, ActionAST node) {
|
||||
if ( this.name.equals(x) ) {
|
||||
return getPredefinedScope(LabelType.RULE_LABEL);
|
||||
}
|
||||
if ( node.resolver == this ) { // action not in alt (attr space is this rule)
|
||||
List<LabelElementPair> labels = getLabelDefs().get(x);
|
||||
if ( labels!=null ) { // it's a label ref. is it a rule label?
|
||||
LabelElementPair anyLabelDef = labels.get(0);
|
||||
if ( anyLabelDef.type==LabelType.RULE_LABEL ) {
|
||||
return getPredefinedScope(LabelType.RULE_LABEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
return getParent().resolveToScope(x, node);
|
||||
}
|
||||
|
||||
public Rule resolveToRule(String x, ActionAST node) {
|
||||
if ( x.equals(this.name) ) return this;
|
||||
if ( node.resolver == this ) { // action not in alt (attr space is this rule)
|
||||
List<LabelElementPair> labels = getLabelDefs().get(x);
|
||||
if ( labels!=null ) { // it's a label ref. is it a rule label?
|
||||
LabelElementPair anyLabelDef = labels.get(0);
|
||||
if ( anyLabelDef.type==LabelType.RULE_LABEL ) {
|
||||
return g.getRule(anyLabelDef.element.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // don't look for general rule (not one ref'd in this rule)
|
||||
}
|
||||
|
||||
/** Look up name from context of this rule and an alternative.
|
||||
* Find an arg, retval, predefined property, or label/rule/token ref.
|
||||
*/
|
||||
// public Attribute resolve(String name) {
|
||||
|
|
Loading…
Reference in New Issue