1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD license"]
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Copyright (c) 2010 Terence Parr
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  All rights reserved.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Redistribution and use in source and binary forms, with or without
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  modification, are permitted provided that the following conditions
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  are met:
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  1. Redistributions of source code must retain the above copyright
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      notice, this list of conditions and the following disclaimer.
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2. Redistributions in binary form must reproduce the above copyright
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      notice, this list of conditions and the following disclaimer in the
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      documentation and/or other materials provided with the distribution.
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  3. The name of the author may not be used to endorse or promote products
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      derived from this software without specific prior written permission.
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.antlr.tool;
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.analysis.Label;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.Token;
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.Iterator;
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.List;
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.Set;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class NameSpaceChecker {
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Grammar grammar;
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public NameSpaceChecker(Grammar grammar) {
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		this.grammar = grammar;
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void checkConflicts() {
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = CompositeGrammar.MIN_RULE_INDEX; i < grammar.composite.ruleIndexToRuleList.size(); i++) {
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Rule r = grammar.composite.ruleIndexToRuleList.elementAt(i);
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( r==null ) {
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				continue;
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// walk all labels for Rule r
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( r.labelNameSpace!=null ) {
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				Iterator it = r.labelNameSpace.values().iterator();
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				while ( it.hasNext() ) {
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					Grammar.LabelElementPair pair = (Grammar.LabelElementPair) it.next();
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					checkForLabelConflict(r, pair.label);
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// walk rule scope attributes for Rule r
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( r.ruleScope!=null ) {
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				List attributes = r.ruleScope.getAttributes();
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				for (int j = 0; j < attributes.size(); j++) {
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					Attribute attribute = (Attribute) attributes.get(j);
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					checkForRuleScopeAttributeConflict(r, attribute);
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			checkForRuleDefinitionProblems(r);
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			checkForRuleArgumentAndReturnValueConflicts(r);
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check all global scopes against tokens
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Iterator it = grammar.getGlobalScopes().values().iterator();
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		while (it.hasNext()) {
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			AttributeScope scope = (AttributeScope) it.next();
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			checkForGlobalScopeTokenConflict(scope);
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check for missing rule, tokens
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		lookForReferencesToUndefinedSymbols();
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void checkForRuleArgumentAndReturnValueConflicts(Rule r) {
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r.returnScope!=null ) {
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Set conflictingKeys = r.returnScope.intersection(r.parameterScope);
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if (conflictingKeys!=null) {
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				for (Iterator it = conflictingKeys.iterator(); it.hasNext();) {
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					String key = (String) it.next();
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.grammarError(
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						ErrorManager.MSG_ARG_RETVAL_CONFLICT,
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						grammar,
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						r.tree.getToken(),
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						key,
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						r.name);
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void checkForRuleDefinitionProblems(Rule r) {
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String ruleName = r.name;
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Token ruleToken = r.tree.getToken();
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int msgID = 0;
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( (grammar.type==Grammar.PARSER||grammar.type==Grammar.TREE_PARSER) &&
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 Character.isUpperCase(ruleName.charAt(0)) )
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_LEXER_RULES_NOT_ALLOWED;
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else if ( grammar.type==Grammar.LEXER &&
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			      Character.isLowerCase(ruleName.charAt(0)) &&
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			      !r.isSynPred )
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_PARSER_RULES_NOT_ALLOWED;
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else if ( grammar.getGlobalScope(ruleName)!=null ) {
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( msgID!=0 ) {
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarError(msgID, grammar, ruleToken, ruleName);
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If ref to undefined rule, give error at first occurrence.
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Give error if you cannot find the scope override on a rule reference.
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  If you ref ID in a combined grammar and don't define ID as a lexer rule
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  it is an error.
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void lookForReferencesToUndefinedSymbols() {
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// for each rule ref, ask if there is a rule definition
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator iter = grammar.ruleRefs.iterator(); iter.hasNext();) {
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarAST refAST = (GrammarAST)iter.next();
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Token tok = refAST.token;
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String ruleName = tok.getText();
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Rule localRule = grammar.getLocallyDefinedRule(ruleName);
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Rule rule = grammar.getRule(ruleName);
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( localRule==null && rule!=null ) { // imported rule?
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				grammar.delegatedRuleReferences.add(rule);
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				rule.imported = true;
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( rule==null && grammar.getTokenType(ruleName)!=Label.EOF ) {
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.grammarError(ErrorManager.MSG_UNDEFINED_RULE_REF,
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  grammar,
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  tok,
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  ruleName);
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( grammar.type==Grammar.COMBINED ) {
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// if we're a combined grammar, we know which token IDs have no
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// associated lexer rule.
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (Iterator iter = grammar.tokenIDRefs.iterator(); iter.hasNext();) {
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				Token tok = (Token) iter.next();
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				String tokenID = tok.getText();
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( !grammar.composite.lexerRules.contains(tokenID) &&
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					 grammar.getTokenType(tokenID)!=Label.EOF )
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.grammarWarning(ErrorManager.MSG_NO_TOKEN_DEFINITION,
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver												grammar,
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver												tok,
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver												tokenID);
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check scopes and scoped rule refs
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator it = grammar.scopedRuleRefs.iterator(); it.hasNext();) {
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarAST scopeAST = (GrammarAST)it.next(); // ^(DOT ID atom)
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Grammar scopeG = grammar.composite.getGrammar(scopeAST.getText());
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarAST refAST = (GrammarAST)scopeAST.getChild(1);
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String ruleName = refAST.getText();
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( scopeG==null ) {
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.grammarError(ErrorManager.MSG_NO_SUCH_GRAMMAR_SCOPE,
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  grammar,
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  scopeAST.getToken(),
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  scopeAST.getText(),
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  ruleName);
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				Rule rule = grammar.getRule(scopeG.name, ruleName);
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( rule==null ) {
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.grammarError(ErrorManager.MSG_NO_SUCH_RULE_IN_SCOPE,
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver											  grammar,
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver											  scopeAST.getToken(),
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver											  scopeAST.getText(),
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver											  ruleName);
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void checkForGlobalScopeTokenConflict(AttributeScope scope) {
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( grammar.getTokenType(scope.getName())!=Label.INVALID ) {
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarError(ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE,
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									  grammar, null, scope.getName());
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Check for collision of a rule-scope dynamic attribute with:
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  arg, return value, rule name itself.  Labels are checked elsewhere.
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void checkForRuleScopeAttributeConflict(Rule r, Attribute attribute) {
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int msgID = 0;
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Object arg2 = null;
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String attrName = attribute.name;
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r.name.equals(attrName) ) {
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE;
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			arg2 = r.name;
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else if ( (r.returnScope!=null&&r.returnScope.getAttribute(attrName)!=null) ||
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				  (r.parameterScope!=null&&r.parameterScope.getAttribute(attrName)!=null) )
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE_ARG_RETVAL;
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			arg2 = r.name;
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( msgID!=0 ) {
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarError(msgID,grammar,r.tree.getToken(),attrName,arg2);
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Make sure a label doesn't conflict with another symbol.
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Labels must not conflict with: rules, tokens, scope names,
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  return values, parameters, and rule-scope dynamic attributes
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  defined in surrounding rule.
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void checkForLabelConflict(Rule r, Token label) {
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int msgID = 0;
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Object arg2 = null;
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( grammar.getGlobalScope(label.getText())!=null ) {
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else if ( grammar.getRule(label.getText())!=null ) {
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE;
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else if ( grammar.getTokenType(label.getText())!=Label.INVALID ) {
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_TOKEN;
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else if ( r.ruleScope!=null && r.ruleScope.getAttribute(label.getText())!=null ) {
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_SCOPE_ATTRIBUTE;
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			arg2 = r.name;
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else if ( (r.returnScope!=null&&r.returnScope.getAttribute(label.getText())!=null) ||
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				  (r.parameterScope!=null&&r.parameterScope.getAttribute(label.getText())!=null) )
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_ARG_RETVAL;
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			arg2 = r.name;
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( msgID!=0 ) {
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarError(msgID,grammar,label,label.getText(),arg2);
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If type of previous label differs from new label's type, that's an error.
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean checkForLabelTypeMismatch(Rule r, Token label, int type) {
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar.LabelElementPair prevLabelPair =
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			(Grammar.LabelElementPair)r.labelNameSpace.get(label.getText());
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( prevLabelPair!=null ) {
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// label already defined; if same type, no problem
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( prevLabelPair.type != type ) {
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				String typeMismatchExpr =
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					Grammar.LabelTypeToString[type]+"!="+
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					Grammar.LabelTypeToString[prevLabelPair.type];
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.grammarError(
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.MSG_LABEL_TYPE_CONFLICT,
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					grammar,
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					label,
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					label.getText(),
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					typeMismatchExpr);
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return true;
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return false;
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
271