rewrote resolver to return attr and scopes

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6695]
This commit is contained in:
parrt 2010-02-15 14:25:02 -08:00
parent d23c9cb527
commit 846e25d9cb
6 changed files with 174 additions and 132 deletions

View File

@ -69,15 +69,14 @@ public class AttributeChecks implements ActionSplitterListener {
}
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())) )
{
if ( node.resolver.resolveToScope(x.getText(), node)==null ) {
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
g.fileName, x, x.getText(), expr);
return;
}
if ( node.resolver.resolveRefToRule(x.getText(), node)!=null ) {
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,12 +102,12 @@ 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
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;
}
if ( !node.resolver.resolves(x.getText(), node) ) {
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
g.fileName, x, x.getText(), expr);
}
@ -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,

View File

@ -35,39 +35,54 @@ public class Alternative implements AttributeResolver {
public AttributeResolver getParent() { return rule; }
// only rules have attr, not alts
public Attribute resolveToAttribute(String x, ActionAST node) {
return getParent().resolveToAttribute(x, 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);
}
/** 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);
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);
}
/** 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 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 boolean dynScopeResolves(String x, ActionAST node) {
return getParent().dynScopeResolves(x,node);
}
public boolean dynScopeResolves(String x, String y, ActionAST node) {
return getParent().dynScopeResolves(x,y,node);
}
public Rule resolveRefToRule(String x, ActionAST 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);
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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;
// no isolated attr at grammar action level
public Attribute resolveToAttribute(String x, ActionAST node) {
return 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;
public Attribute resolveToAttribute(String x, String y, ActionAST node) {
AttributeScope s = resolveToScope(x, node);
return s.get(y);
}
public boolean dynScopeResolves(String x, String y, ActionAST node) {
// $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

View File

@ -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,6 +132,55 @@ public class Rule implements AttributeResolver {
return defs;
}
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.
*/