public virtual IList<GrammarRootAST> SortGrammarByTokenVocab(IList<string> fileNames)
{
//System.Console.WriteLine(fileNames);
Graph<string> g = new Graph<string>();
IList<GrammarRootAST> roots = new List<GrammarRootAST>();
foreach (string fileName in fileNames)
{
GrammarAST t = ParseGrammar(fileName);
if (t == null || t is GrammarASTErrorNode)
continue; // came back as error node
if (((GrammarRootAST)t).hasErrors)
continue;
GrammarRootAST root = (GrammarRootAST)t;
roots.Add(root);
root.fileName = fileName;
string grammarName = root.GetChild(0).Text;
GrammarAST tokenVocabNode = FindOptionValueAST(root, "tokenVocab");
// Make grammars depend on any tokenVocab options
if (tokenVocabNode != null)
{
string vocabName = tokenVocabNode.Text;
// Strip quote characters if any
int len = vocabName.Length;
int firstChar = vocabName[0];
int lastChar = vocabName[len - 1];
if (len >= 2 && firstChar == '\'' && lastChar == '\'')
{
vocabName = vocabName.Substring(1, len - 2);
}
// If the name contains a path delimited by forward slashes,
// use only the part after the last slash as the name
int lastSlash = vocabName.LastIndexOf('/');
if (lastSlash >= 0)
{
vocabName = vocabName.Substring(lastSlash + 1);
}
g.AddEdge(grammarName, vocabName);
}
// add cycle to graph so we always process a grammar if no error
// even if no dependency
g.AddEdge(grammarName, grammarName);
}
IList<string> sortedGrammarNames = g.Sort();
//System.Console.WriteLine("sortedGrammarNames=" + sortedGrammarNames);
IList<GrammarRootAST> sortedRoots = new List<GrammarRootAST>();
foreach (string grammarName in sortedGrammarNames)
{
foreach (GrammarRootAST root in roots)
{
if (root.GetGrammarName().Equals(grammarName))
{
sortedRoots.Add(root);
break;
}
}
}
return sortedRoots;
}