forked from jasder/antlr
Fix exponential complexity of recursive imports
This commit is contained in:
parent
9d6a6bd3a8
commit
e4c193005e
|
@ -608,6 +608,8 @@ public class Tool {
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Map<String, Grammar> importedGrammars = new HashMap<String, Grammar>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try current dir then dir of g then lib dir
|
* Try current dir then dir of g then lib dir
|
||||||
* @param g
|
* @param g
|
||||||
|
@ -615,27 +617,34 @@ public class Tool {
|
||||||
*/
|
*/
|
||||||
public Grammar loadImportedGrammar(Grammar g, GrammarAST nameNode) throws IOException {
|
public Grammar loadImportedGrammar(Grammar g, GrammarAST nameNode) throws IOException {
|
||||||
String name = nameNode.getText();
|
String name = nameNode.getText();
|
||||||
g.tool.log("grammar", "load " + name + " from " + g.fileName);
|
Grammar imported = importedGrammars.get(name);
|
||||||
File importedFile = null;
|
if (imported == null) {
|
||||||
for (String extension : ALL_GRAMMAR_EXTENSIONS) {
|
g.tool.log("grammar", "load " + name + " from " + g.fileName);
|
||||||
importedFile = getImportedGrammarFile(g, name + extension);
|
File importedFile = null;
|
||||||
if (importedFile != null) {
|
for (String extension : ALL_GRAMMAR_EXTENSIONS) {
|
||||||
break;
|
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;
|
return imported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -514,16 +514,24 @@ public class Grammar implements AttributeResolver {
|
||||||
* The grammars are in import tree preorder. Don't include ourselves
|
* The grammars are in import tree preorder. Don't include ourselves
|
||||||
* in list as we're not a delegate of ourselves.
|
* in list as we're not a delegate of ourselves.
|
||||||
*/
|
*/
|
||||||
public List<Grammar> getAllImportedGrammars() {
|
public List<Grammar> getAllImportedGrammars() {
|
||||||
if ( importedGrammars==null ) return null;
|
if (importedGrammars == null) {
|
||||||
List<Grammar> delegates = new ArrayList<Grammar>();
|
return null;
|
||||||
for (Grammar d : importedGrammars) {
|
|
||||||
delegates.add(d);
|
|
||||||
List<Grammar> ds = d.getAllImportedGrammars();
|
|
||||||
if (ds != null) delegates.addAll(ds);
|
|
||||||
}
|
}
|
||||||
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; }
|
public List<Grammar> getImportedGrammars() { return importedGrammars; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue