cleaned up resolving. resolver interface is only 3 methods now

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6699]
This commit is contained in:
parrt 2010-02-16 14:25:02 -08:00
parent 6ec90d61d9
commit 340af98839
8 changed files with 78 additions and 165 deletions

View File

@ -122,7 +122,7 @@ UNKNOWN_RULE_ATTRIBUTE(arg,arg2,arg3) ::=
"unknown attribute <arg> for rule <arg2> in <arg3>"
UNKNOWN_SIMPLE_ATTRIBUTE(arg,arg2) ::=
"unknown attribute reference <arg> in <arg2>"
ISOLATED_RULE_SCOPE(arg,arg2) ::=
ISOLATED_RULE_REF(arg,arg2) ::=
"missing attribute access on rule reference <arg> in <arg2>"
INVALID_RULE_PARAMETER_REF(arg,arg2) ::=
"cannot access rule <arg>'s parameter: <arg2>"

View File

@ -71,19 +71,18 @@ public class AttributeChecks implements ActionSplitterListener {
// $x.y
public void qualifiedAttr(String expr, Token x, Token y) {
if ( node.resolver.resolveToAttribute(x.getText(), y.getText(), node)==null ) {
Rule r = node.resolver.resolveToRule(x.getText(), node);
if ( r!=null ) {
Rule rref = g.getRule(x.getText());
Rule rref = isolatedRuleRef(x.getText());
if ( rref!=null ) {
if ( rref!=null && rref.args!=null && rref.args.get(y.getText())!=null ) {
ErrorManager.grammarError(ErrorType.INVALID_RULE_PARAMETER_REF,
g.fileName, y, y.getText(), expr);
}
else {
ErrorManager.grammarError(ErrorType.UNKNOWN_RULE_ATTRIBUTE,
g.fileName, y, y.getText(), r.name, expr);
g.fileName, y, y.getText(), rref.name, expr);
}
}
else if ( !node.resolver.resolvesToAttributeDict(x.getText(), node) ) {
else if ( !resolvesToAttributeDict(x.getText()) ) {
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
g.fileName, x, x.getText(), expr);
}
@ -107,8 +106,8 @@ public class AttributeChecks implements ActionSplitterListener {
if ( node.resolver.resolveToDynamicScope(x.getText(), node)!=null ) {
return; // $S for scope S is ok
}
if ( node.resolver.resolveToRule(x.getText(), node)!=null ) {
ErrorManager.grammarError(ErrorType.ISOLATED_RULE_SCOPE,
if ( isolatedRuleRef(x.getText())!=null ) {
ErrorManager.grammarError(ErrorType.ISOLATED_RULE_REF,
g.fileName, x, x.getText(), expr);
return;
}
@ -174,4 +173,53 @@ public class AttributeChecks implements ActionSplitterListener {
public void setExprAttribute(String expr) { }
public void setAttribute(String expr) { }
public void templateExpr(String expr) { }
// SUPPORT
public Rule isolatedRuleRef(String x) {
if ( node.resolver instanceof Grammar ) return null;
if ( x.equals(r.name) ) return r;
List<LabelElementPair> labels = null;
if ( node.resolver instanceof Rule ) {
labels = r.getLabelDefs().get(x);
}
else if ( node.resolver instanceof Alternative ) {
labels = ((Alternative)node.resolver).labelDefs.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());
}
}
if ( node.resolver instanceof Alternative ) {
if ( ((Alternative)node.resolver).ruleRefs.get(x)!=null ) {
return g.getRule(x);
}
}
return null;
}
public boolean resolvesToAttributeDict(String x) {
if ( node.resolver instanceof Grammar ) return g.scopes.get(x)!=null;
List<LabelElementPair> labels = null;
if ( node.resolver instanceof Rule ) {
labels = r.getLabelDefs().get(x);
}
else if ( node.resolver instanceof Alternative ) {
labels = ((Alternative)node.resolver).labelDefs.get(x);
}
if ( labels!=null ) { // it's a label ref. is it a token label?
LabelElementPair anyLabelDef = labels.get(0);
if ( anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
}
if ( x.equals(r.name) ) return true; // $r for action in rule r, $r is a dict
Rule r = g.getRule(x);
if ( r!=null && r.scope!=null ) return true;
if ( g.scopes.get(x)!=null ) return true;
return false;
}
}

View File

@ -33,8 +33,6 @@ public class Alternative implements AttributeResolver {
public Alternative(Rule r) { this.rule = r; }
private AttributeResolver getParent() { return rule; }
/** $x Attribute: rule arguments, return values, predefined rule prop.
*/
public Attribute resolveToAttribute(String x, ActionAST node) {
@ -70,56 +68,13 @@ public class Alternative implements AttributeResolver {
return null;
}
/** $x AttributeDict: references to tokens and token labels in the
* current alt (including any elements within subrules contained
* in that outermost alt). x can be rule with scope or a global scope.
*
* x can also be surrounding rule since we use for error checking.
*/
public boolean resolvesToAttributeDict(String x, ActionAST node) {
if ( tokenRefs.get(x)!=null ) return true;
List<LabelElementPair> labels = labelDefs.get(x);
if ( labels!=null ) { // it's a label ref. is it a token label?
LabelElementPair anyLabelDef = labels.get(0);
if ( anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
}
if ( x.equals(rule.name) ) return true; // $r for action in rule r, $r is a dict
Rule r = rule.g.getRule(x);
if ( r!=null && r.scope!=null ) return true;
if ( rule.g.scopes.get(x)!=null ) return true;
return false;
}
// 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 AttributeDict resolveToDynamicScope(String x, ActionAST node) {
Rule r = resolveToRule(x, node);
if ( r!=null && r.scope !=null ) return r.scope;
return getParent().resolveToDynamicScope(x, node);
return rule.resolveToDynamicScope(x, node);
}
/** x can be ruleref or rule label. */
public Rule resolveToRule(String x, ActionAST node) {
if ( ruleRefs.get(x)!=null ) return rule.g.getRule(x);
List<LabelElementPair> labels = labelDefs.get(x);
@ -129,6 +84,7 @@ public class Alternative implements AttributeResolver {
return rule.g.getRule(anyLabelDef.element.getText());
}
}
return getParent().resolveToRule(x, node);
if ( x.equals(rule.name) ) return rule;
return null;
}
}

View File

@ -30,10 +30,5 @@ package org.antlr.v4.tool;
public interface AttributeResolver {
public Attribute resolveToAttribute(String x, ActionAST node);
public Attribute resolveToAttribute(String x, String y, ActionAST node);
/** Error checking when $x.y is not attribute. We ask if $x is a dict. */
public boolean resolvesToAttributeDict(String x, ActionAST node);
public AttributeDict resolveToDynamicScope(String x, ActionAST node);
//public Attribute resolveToDynamicScopeAttribute(String x, String y, ActionAST node);
/** Resolve to surrounding rule, rule ref/label if in alt, or other rule */
public Rule resolveToRule(String x, ActionAST node);
}

View File

@ -80,7 +80,7 @@ public enum ErrorType {
INVALID_RULE_PARAMETER_REF(ErrorSeverity.ERROR, true, true),
UNKNOWN_RULE_ATTRIBUTE(ErrorSeverity.ERROR, true, true),
UNKNOWN_ATTRIBUTE_IN_SCOPE(ErrorSeverity.ERROR, true, true),
ISOLATED_RULE_SCOPE(ErrorSeverity.ERROR, true, true),
ISOLATED_RULE_REF(ErrorSeverity.ERROR, true, true),
SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE(ErrorSeverity.ERROR, true, true),
LABEL_CONFLICTS_WITH_RULE(ErrorSeverity.ERROR, true, true),
LABEL_CONFLICTS_WITH_TOKEN(ErrorSeverity.ERROR, true, true),

View File

@ -222,19 +222,8 @@ public class Grammar implements AttributeResolver {
return null;
}
/** $s AttributeDict: s is a global scope */
public boolean resolvesToAttributeDict(String x, ActionAST node) {
return scopes.get(x)!=null;
}
public AttributeDict resolveToDynamicScope(String x, ActionAST node) {
AttributeDict s = scopes.get(x);
if ( s !=null ) return s;
if ( node.resolver != this ) { // if not member action, can ref rule
Rule r = rules.get(x);
if ( r!=null ) return r.scope;
}
return null;
return scopes.get(x);
}
// /** $x in grammar action can only be scope name */
@ -247,9 +236,6 @@ public class Grammar implements AttributeResolver {
// */
// public boolean resolves(String x, String y, ActionAST node) { return false; }
/** Can't be a rule ref in grammar named action */
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
* default scope should be "parser".

View File

@ -135,8 +135,6 @@ public class Rule implements AttributeResolver {
return defs;
}
private AttributeResolver getParent() { return g; }
/** $x Attribute: rule arguments, return values, predefined rule prop. */
public Attribute resolveToAttribute(String x, ActionAST node) {
Attribute a = args.get(x); if ( a!=null ) return a;
@ -163,31 +161,14 @@ public class Rule implements AttributeResolver {
}
/** $x AttributeDict: references to token labels in *any* alt. x can
* be any rule with scope or global scope or surrounding rule x.
*/
public boolean resolvesToAttributeDict(String x, ActionAST node) {
List<LabelElementPair> labels = getLabelDefs().get(x);
if ( labels!=null ) { // it's a label ref. is it a token label?
LabelElementPair anyLabelDef = labels.get(0);
if ( anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
}
if ( x.equals(this.name) ) return true; // $r for action in rule r, $r is a dict
Rule r = g.getRule(x);
if ( r!=null && r.scope!=null ) return true;
if ( g.scopes.get(x)!=null ) return true;
return false;
}
public AttributeDict resolveToDynamicScope(String x, ActionAST node) {
Rule r = resolveToRule(x, node);
Rule r = resolveToRule(x);
if ( r!=null && r.scope!=null ) return r.scope;
return getParent().resolveToDynamicScope(x, node);
return g.scopes.get(x);
}
public Rule resolveToRule(String x, ActionAST node) {
public Rule resolveToRule(String x) {
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);
@ -195,61 +176,8 @@ public class Rule implements AttributeResolver {
return g.getRule(anyLabelDef.element.getText());
}
}
return g.getRule(x);
}
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) {
// 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;
//
// //alt[currentAlt].tokenRefs
// // not here? look in grammar for global scope
// return null;
// }
/** Resolve x in $x.y to
*/
// public AttributeScope resolveScope(String name, Alternative alt) {
// AttributeScope s = null;
// if ( this.name.equals(name) ) { // $r ref in rule r
// s = resolveLocalAttributeScope(name);
// if ( s!=null ) return s;
// }
//
// if ( alt.tokenRefs.get(name)!=null ) { // token ref in this alt?
// return getPredefinedScope(LabelType.TOKEN_LABEL);
// }
// if ( alt.ruleRefs.get(name)!=null ) { // rule ref in this alt?
// s = getLocalAttributeScope(name);
// if ( s!=null ) return s;
// }
// List<GrammarAST> labels = alt.labelDefs.get(name); // label
// if ( labels!=null ) {
// // it's a label ref, compute scope from label type and grammar type
// LabelElementPair anyLabelDef = labels.get(0);
// return getPredefinedScope(anyLabelDef.type);
// }
// return null;
// }
//
// /** Look for name in the arg, return value, predefined property,
// * or dynamic scope attribute list for this rule.
// */
// public AttributeScope resolveLocalAttributeScope(String name) {
// if ( args.get(name)!=null ) return args;
// if ( retvals.get(name)!=null ) return retvals;
// AttributeScope s = getPredefinedScope(LabelType.RULE_LABEL);
// if ( s.get(name)!=null ) return s;
// if ( scope!=null && scope.get(name)!=null ) return scope;
// return null;
// }
public AttributeDict getPredefinedScope(LabelType ltype) {
String grammarLabelKey = g.getTypeString() + ":" + ltype;

View File

@ -73,7 +73,7 @@ public class TestAttributeChecks extends BaseTest {
"$a.ick = 3;", "error(31): A.g:6:6: unknown attribute ick for rule a in $a.ick = 3;",
"$b.d", "error(30): A.g:6:6: cannot access rule d's parameter: $b.d", // can't see rule ref's arg
"$d.text", "error(29): A.g:6:4: unknown attribute reference d in $d.text", // valid rule, but no ref
"$lab.d", "error(31): A.g:6:8: unknown attribute d for rule b in $lab.d",
"$lab.d", "error(30): A.g:6:8: cannot access rule d's parameter: $lab.d",
};
String[] finallyChecks = {
@ -91,7 +91,7 @@ public class TestAttributeChecks extends BaseTest {
"$b", "error(29): A.g:9:14: unknown attribute reference b in $b",
"$b.d", "error(29): A.g:9:14: unknown attribute reference b in $b.d",
"$c.text", "error(29): A.g:9:14: unknown attribute reference c in $c.text",
"$lab.d", "error(31): A.g:9:18: unknown attribute d for rule b in $lab.d",
"$lab.d", "error(30): A.g:9:18: cannot access rule d's parameter: $lab.d",
};
String[] dynMembersChecks = {