Fix exponential complexity of recursive imports

This commit is contained in:
Sam Harwell 2014-09-25 21:02:13 -05:00
parent 9d6a6bd3a8
commit e4c193005e
2 changed files with 44 additions and 27 deletions

View File

@ -608,6 +608,8 @@ public class Tool {
return g;
}
private final Map<String, Grammar> importedGrammars = new HashMap<String, Grammar>();
/**
* Try current dir then dir of g then lib dir
* @param g
@ -615,27 +617,34 @@ public class Tool {
*/
public Grammar loadImportedGrammar(Grammar g, GrammarAST nameNode) throws IOException {
String name = nameNode.getText();
g.tool.log("grammar", "load " + name + " from " + g.fileName);
File importedFile = null;
for (String extension : ALL_GRAMMAR_EXTENSIONS) {
importedFile = getImportedGrammarFile(g, name + extension);
if (importedFile != null) {
break;
Grammar imported = importedGrammars.get(name);
if (imported == null) {
g.tool.log("grammar", "load " + name + " from " + g.fileName);
File importedFile = null;
for (String extension : ALL_GRAMMAR_EXTENSIONS) {
importedFile = getImportedGrammarFile(g, name + extension);
if (importedFile != null) {
break;
}
}
if ( importedFile==null ) {
errMgr.grammarError(ErrorType.CANNOT_FIND_IMPORTED_GRAMMAR, g.fileName, nameNode.getToken(), name);
return null;
}
String absolutePath = importedFile.getAbsolutePath();
ANTLRFileStream in = new ANTLRFileStream(absolutePath, grammarEncoding);
GrammarRootAST root = parse(g.fileName, in);
if (root == null) {
return null;
}
imported = createGrammar(root);
imported.fileName = absolutePath;
importedGrammars.put(root.getGrammarName(), imported);
}
if ( importedFile==null ) {
errMgr.grammarError(ErrorType.CANNOT_FIND_IMPORTED_GRAMMAR, g.fileName, nameNode.getToken(), name);
return null;
}
ANTLRFileStream in = new ANTLRFileStream(importedFile.getAbsolutePath(), grammarEncoding);
GrammarRootAST root = parse(g.fileName, in);
if ( root==null ) {
return null;
}
Grammar imported = createGrammar(root);
imported.fileName = importedFile.getAbsolutePath();
return imported;
}

View File

@ -514,16 +514,24 @@ public class Grammar implements AttributeResolver {
* The grammars are in import tree preorder. Don't include ourselves
* in list as we're not a delegate of ourselves.
*/
public List<Grammar> getAllImportedGrammars() {
if ( importedGrammars==null ) return null;
List<Grammar> delegates = new ArrayList<Grammar>();
for (Grammar d : importedGrammars) {
delegates.add(d);
List<Grammar> ds = d.getAllImportedGrammars();
if (ds != null) delegates.addAll(ds);
public List<Grammar> getAllImportedGrammars() {
if (importedGrammars == null) {
return null;
}
return delegates;
}
LinkedHashMap<String, Grammar> delegates = new LinkedHashMap<String, Grammar>();
for (Grammar d : importedGrammars) {
delegates.put(d.fileName, d);
List<Grammar> ds = d.getAllImportedGrammars();
if (ds != null) {
for (Grammar imported : ds) {
delegates.put(imported.fileName, imported);
}
}
}
return new ArrayList<Grammar>(delegates.values());
}
public List<Grammar> getImportedGrammars() { return importedGrammars; }