*.g cmdline works now to topologically sort by tokenVocab dependencies.

This commit is contained in:
Terence Parr 2012-09-08 12:26:32 -07:00
parent fcb67d8d93
commit 3638073efe
4 changed files with 75 additions and 19 deletions

View File

@ -14,7 +14,7 @@ member
stat: expr ';' stat: expr ';'
{System.out.println("found expr: "+$stat.text);} {System.out.println("found expr: "+$stat.text);}
| ID '=' expr ';' | ID '=' expr ';'
{System.out.println("found assign: "+$stat.text);} {System.out.println("found assign: "+$stat.text+$ID.text);}
; ;
expr: INT expr: INT

View File

@ -1,5 +1,2 @@
grammar T; lexer grammar T;
A : 'a';
tokens { A,B }
s : A ;

View File

@ -29,6 +29,7 @@
package org.antlr.v4; package org.antlr.v4;
import org.antlr.misc.Graph;
import org.antlr.runtime.ANTLRFileStream; import org.antlr.runtime.ANTLRFileStream;
import org.antlr.runtime.ANTLRStringStream; import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream; import org.antlr.runtime.CharStream;
@ -221,7 +222,7 @@ public class Tool {
continue; continue;
} }
if ( arg.charAt(0)!='-' ) { // file name if ( arg.charAt(0)!='-' ) { // file name
grammarFiles.add(arg); if ( !grammarFiles.contains(arg) ) grammarFiles.add(arg);
continue; continue;
} }
boolean found = false; boolean found = false;
@ -316,14 +317,11 @@ public class Tool {
} }
public void processGrammarsOnCommandLine() { public void processGrammarsOnCommandLine() {
for (String fileName : grammarFiles) { List<GrammarRootAST> sortedGrammars = sortGrammarByTokenVocab(grammarFiles);
GrammarAST t = loadGrammar(fileName);
if ( t==null || t instanceof GrammarASTErrorNode) return; // came back as error node
if ( ((GrammarRootAST)t).hasErrors ) return;
GrammarRootAST ast = (GrammarRootAST)t;
final Grammar g = createGrammar(ast); for (GrammarRootAST t : sortedGrammars) {
g.fileName = fileName; final Grammar g = createGrammar(t);
g.fileName = t.fileName;
process(g, true); process(g, true);
} }
} }
@ -337,7 +335,6 @@ public class Tool {
public void process(Grammar g, boolean gencode) { public void process(Grammar g, boolean gencode) {
g.loadImportedGrammars(); g.loadImportedGrammars();
GrammarTransformPipeline transform = new GrammarTransformPipeline(g, this); GrammarTransformPipeline transform = new GrammarTransformPipeline(g, this);
transform.process(); transform.process();
@ -367,13 +364,12 @@ public class Tool {
if ( g.ast!=null && internalOption_PrintGrammarTree ) System.out.println(g.ast.toStringTree()); if ( g.ast!=null && internalOption_PrintGrammarTree ) System.out.println(g.ast.toStringTree());
//g.ast.inspect(); //g.ast.inspect();
if ( errMgr.getNumErrors()>0 ) return; int prevErrors = errMgr.getNumErrors();
// MAKE SURE GRAMMAR IS SEMANTICALLY CORRECT (FILL IN GRAMMAR OBJECT) // MAKE SURE GRAMMAR IS SEMANTICALLY CORRECT (FILL IN GRAMMAR OBJECT)
SemanticPipeline sem = new SemanticPipeline(g); SemanticPipeline sem = new SemanticPipeline(g);
sem.process(); sem.process();
if ( errMgr.getNumErrors()>0 ) return; if ( errMgr.getNumErrors()>prevErrors ) return;
// BUILD ATN FROM AST // BUILD ATN FROM AST
ATNFactory factory; ATNFactory factory;
@ -389,7 +385,7 @@ public class Tool {
//if ( generate_DFA_dot ) generateDFAs(g); //if ( generate_DFA_dot ) generateDFAs(g);
if ( g.tool.getNumErrors()>0 ) return; if ( g.tool.getNumErrors()>prevErrors ) return;
// GENERATE CODE // GENERATE CODE
if ( gencode ) { if ( gencode ) {
@ -398,6 +394,63 @@ public class Tool {
} }
} }
public List<GrammarRootAST> sortGrammarByTokenVocab(List<String> fileNames) {
// System.out.println(fileNames);
Graph<String> g = new Graph<String>();
List<GrammarRootAST> roots = new ArrayList<GrammarRootAST>();
for (String fileName : fileNames) {
GrammarAST t = loadGrammar(fileName);
if ( t==null || t instanceof 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).getText();
GrammarAST tokenVocabNode = findOptionValueAST(root, "tokenVocab");
// Make grammars depend on any tokenVocab options
if ( tokenVocabNode!=null ) {
String vocabName = tokenVocabNode.getText();
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);
}
List<String> sortedGrammarNames = g.sort();
// System.out.println("sortedGrammarNames="+sortedGrammarNames);
List<GrammarRootAST> sortedRoots = new ArrayList<GrammarRootAST>();
for (String grammarName : sortedGrammarNames) {
for (GrammarRootAST root : roots) {
if ( root.getGrammarName().equals(grammarName) ) {
sortedRoots.add(root);
break;
}
}
}
return sortedRoots;
}
/** Manually get option node from tree; return null if no defined. */
public static GrammarAST findOptionValueAST(GrammarRootAST root, String option) {
GrammarAST options = (GrammarAST)root.getFirstChildWithType(ANTLRParser.OPTIONS);
if ( options!=null ) {
for (Object o : options.getChildren()) {
GrammarAST c = (GrammarAST)o;
if ( c.getType() == ANTLRParser.ASSIGN &&
c.getChild(0).getText().equals(option) )
{
return (GrammarAST)c.getChild(1);
}
}
}
return null;
}
/** Given the raw AST of a grammar, create a grammar object /** Given the raw AST of a grammar, create a grammar object
associated with the AST. Once we have the grammar object, ensure associated with the AST. Once we have the grammar object, ensure
that all nodes in tree referred to this grammar. Later, we will that all nodes in tree referred to this grammar. Later, we will

View File

@ -46,6 +46,7 @@ public class GrammarRootAST extends GrammarASTWithOptions {
/** Track stream used to create this tree */ /** Track stream used to create this tree */
public TokenStream tokens; public TokenStream tokens;
public Map<String, String> cmdLineOptions; // -DsuperClass=T on command line public Map<String, String> cmdLineOptions; // -DsuperClass=T on command line
public String fileName;
public GrammarRootAST(GrammarAST node) { public GrammarRootAST(GrammarAST node) {
super(node); super(node);
@ -60,6 +61,11 @@ public class GrammarRootAST extends GrammarASTWithOptions {
super(type,t,text); super(type,t,text);
} }
public String getGrammarName() {
Tree t = getChild(0);
if ( t!=null ) return t.getText();
return null;
}
@Override @Override
public String getOptionString(String key) { public String getOptionString(String key) {