* @param ruleName
* the name of the rule.
*/
public JSGFRuleName resolve(JSGFRuleName ruleName) throws JSGFGrammarException {
// System.out.println ("Resolving " + ruleName);
JSGFRuleName rn = new JSGFRuleName(ruleName.getRuleName());
String simpleName = rn.getSimpleRuleName();
String grammarName = rn.getSimpleGrammarName();
String packageName = rn.getPackageName();
String fullGrammarName = rn.getFullGrammarName();
// Check for badly formed RuleName
if (packageName != null && grammarName == null) {
throw new JSGFGrammarException("Error: badly formed rulename " + rn);
}
if (ruleName.getSimpleRuleName().equals("NULL")) {
return JSGFRuleName.NULL;
}
if (ruleName.getSimpleRuleName().equals("VOID")) {
return JSGFRuleName.VOID;
}
// Check simple case: a local rule reference
if (fullGrammarName == null && this.getRule(simpleName) != null) {
return new JSGFRuleName(name + '.' + simpleName);
}
// Check for fully-qualified reference
if (fullGrammarName != null) {
JSGFRuleGrammar g = manager.retrieveGrammar(fullGrammarName);
if (g != null) {
if (g.getRule(simpleName) != null) {
// we have a successful resolution
return new JSGFRuleName(fullGrammarName + '.' + simpleName);
}
}
}
// Collect all matching imports into a list. After trying to
// match rn to each import statement the vec will have
// size()=0 if rn is unresolvable
// size()=1 if rn is properly resolvable
// size()>1 if rn is an ambiguous reference
List<JSGFRuleName> matches = new ArrayList<JSGFRuleName>();
// Get list of imports
// Add local grammar to simply the case of checking for
// a qualified or fully-qualified local reference.
List<JSGFRuleName> imports = new ArrayList<JSGFRuleName>(this.imports);
imports.add(new JSGFRuleName(name + ".*"));
// Check each import statement for a possible match
for (JSGFRuleName importName : imports) {
// TO-DO: update for JSAPI 1.0
String importSimpleName = importName.getSimpleRuleName();
String importGrammarName = importName.getSimpleGrammarName();
String importFullGrammarName = importName.getFullGrammarName();
// Check for badly formed import name
if (importFullGrammarName == null) {
throw new JSGFGrammarException("Error: badly formed import " + ruleName);
}
// Get the imported grammar
JSGFRuleGrammar gref = manager.retrieveGrammar(importFullGrammarName);
if (gref == null) {
System.out.println("Warning: import of unknown grammar " + ruleName + " in " + name);
continue;
}
// If import includes simpleName, test that it really exists
if (!importSimpleName.equals("*") && gref.getRule(importSimpleName) == null) {
System.out.println("Warning: import of undefined rule " + ruleName + " in " + name);
continue;
}
// Check for fully-qualified or qualified reference
if (importFullGrammarName.equals(fullGrammarName) || importGrammarName.equals(fullGrammarName)) {
// Know that either
// import <ipkg.igram.???> matches <pkg.gram.???>
// OR
// import <ipkg.igram.???> matches <gram.???>
// (ipkg may be null)
if (importSimpleName.equals("*")) {
if (gref.getRule(simpleName) != null) {
// import <pkg.gram.*> matches <pkg.gram.rulename>
matches.add(new JSGFRuleName(importFullGrammarName + '.' + simpleName));
}
continue;
} else {
// Now testing
// import <ipkg.igram.iRuleName> against <??.gram.ruleName>
//
if (importSimpleName.equals(simpleName)) {
// import <pkg.gram.rulename> exact match for
// <???.gram.rulename>
matches.add(new JSGFRuleName(importFullGrammarName + '.' + simpleName));
}
continue;
}
}
// If we get here and rulename is qualified or fully-qualified
// then the match failed - try the next import statement
if (fullGrammarName != null) {
continue;
}
// Now test
// import <ipkg.igram.*> against <simpleName>
if (importSimpleName.equals("*")) {
if (gref.getRule(simpleName) != null) {
// import <pkg.gram.*> matches <simpleName>
matches.add(new JSGFRuleName(importFullGrammarName + '.' + simpleName));
}
continue;
}
// Finally test
// import <ipkg.igram.iSimpleName> against <simpleName>
if (importSimpleName.equals(simpleName)) {
matches.add(new JSGFRuleName(importFullGrammarName + '.' + simpleName));
continue;
}
}
// The return behavior depends upon number of matches