*.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 ';'
{System.out.println("found expr: "+$stat.text);}
| ID '=' expr ';'
{System.out.println("found assign: "+$stat.text);}
{System.out.println("found assign: "+$stat.text+$ID.text);}
;
expr: INT

View File

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

View File

@ -29,6 +29,7 @@
package org.antlr.v4;
import org.antlr.misc.Graph;
import org.antlr.runtime.ANTLRFileStream;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
@ -221,7 +222,7 @@ public class Tool {
continue;
}
if ( arg.charAt(0)!='-' ) { // file name
grammarFiles.add(arg);
if ( !grammarFiles.contains(arg) ) grammarFiles.add(arg);
continue;
}
boolean found = false;
@ -316,14 +317,11 @@ public class Tool {
}
public void processGrammarsOnCommandLine() {
for (String fileName : 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;
List<GrammarRootAST> sortedGrammars = sortGrammarByTokenVocab(grammarFiles);
final Grammar g = createGrammar(ast);
g.fileName = fileName;
for (GrammarRootAST t : sortedGrammars) {
final Grammar g = createGrammar(t);
g.fileName = t.fileName;
process(g, true);
}
}
@ -337,7 +335,6 @@ public class Tool {
public void process(Grammar g, boolean gencode) {
g.loadImportedGrammars();
GrammarTransformPipeline transform = new GrammarTransformPipeline(g, this);
transform.process();
@ -367,13 +364,12 @@ public class Tool {
if ( g.ast!=null && internalOption_PrintGrammarTree ) System.out.println(g.ast.toStringTree());
//g.ast.inspect();
if ( errMgr.getNumErrors()>0 ) return;
int prevErrors = errMgr.getNumErrors();
// MAKE SURE GRAMMAR IS SEMANTICALLY CORRECT (FILL IN GRAMMAR OBJECT)
SemanticPipeline sem = new SemanticPipeline(g);
sem.process();
if ( errMgr.getNumErrors()>0 ) return;
if ( errMgr.getNumErrors()>prevErrors ) return;
// BUILD ATN FROM AST
ATNFactory factory;
@ -389,7 +385,7 @@ public class Tool {
//if ( generate_DFA_dot ) generateDFAs(g);
if ( g.tool.getNumErrors()>0 ) return;
if ( g.tool.getNumErrors()>prevErrors ) return;
// GENERATE CODE
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
associated with the AST. Once we have the grammar object, ensure
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 */
public TokenStream tokens;
public Map<String, String> cmdLineOptions; // -DsuperClass=T on command line
public String fileName;
public GrammarRootAST(GrammarAST node) {
super(node);
@ -60,6 +61,11 @@ public class GrammarRootAST extends GrammarASTWithOptions {
super(type,t,text);
}
public String getGrammarName() {
Tree t = getChild(0);
if ( t!=null ) return t.getText();
return null;
}
@Override
public String getOptionString(String key) {