X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fmeta%2FGrammarBuilder.java;h=3651be36cbefc55bbafdf517920da51471aee8d5;hp=5e1d3d97ac538b38ec367c1d107784e838ab995e;hb=dc9bb3a45ed306e2e35549076842b3e74efecb48;hpb=b910ad546f02d07664d32a70ce9acf6f049a64b1 diff --git a/src/edu/berkeley/sbp/meta/GrammarBuilder.java b/src/edu/berkeley/sbp/meta/GrammarBuilder.java index 5e1d3d9..3651be3 100644 --- a/src/edu/berkeley/sbp/meta/GrammarBuilder.java +++ b/src/edu/berkeley/sbp/meta/GrammarBuilder.java @@ -31,15 +31,26 @@ import java.io.*; /** The java classes typically used to represent a parsed grammar AST; each inner class is a type of AST node. */ public class GrammarBuilder { + /** + * Create a grammar from a parse tree and binding resolver + * + * @param t a tree produced by parsing a grammar using the metagrammar + * @param s the name of the "start symbol" + * @param gbr a GrammarBindingResolver that resolves grammatical reductions into tree-node-heads + */ + public static Union buildFromAST(Tree grammarAST, String startingNonterminal, File[] includes) { + return new GrammarBuilder(includes, "").buildGrammar(grammarAST, startingNonterminal); + } + public static Object illegalTag = ""; // this is the tag that should never appear in the non-dropped output FIXME private final String prefix; - private final String path; + private final File[] includes; //public GrammarBuilder(String path) { this(path, ""); } - public GrammarBuilder(String path, String prefix) { + public GrammarBuilder(File[] includes, String prefix) { this.prefix = prefix; - this.path = path; + this.includes = includes; } public Union buildGrammar(Tree t, String rootNonTerminal) { @@ -117,7 +128,7 @@ public class GrammarBuilder { if (head.equals("\n")) return "\n"; if (head.equals("\r")) return "\r"; if (head.equals("grammar.Grammar")) return walkChildren(t); - if (head.equals("SubGrammar")) return Grammar.create(t.child(0), "s"); + if (head.equals("SubGrammar")) return GrammarBuilder.buildFromAST(t.child(0), "s", includes); if (head.equals("NonTerminal")) return new NonTerminalNode((String)walk(t.child(0)), (Seq[][])walkChildren(t.child(1)), false, null, false); @@ -137,16 +148,21 @@ public class GrammarBuilder { false, false); if (head.equals("#import")) { - String fileName = path+(String)stringifyChildren(t.child(0)); - try { - String newPrefix = (String)walk(t.child(1)); - if (newPrefix.length() > 0) newPrefix += "."; - FileInputStream fis = new FileInputStream(fileName); - Tree tr = new CharParser(MetaGrammar.newInstance()).parse(fis).expand1(); - return (GrammarNode)new GrammarBuilder(path, newPrefix).walk(tr); - } catch (Exception e) { - throw new RuntimeException("while parsing " + fileName, e); + String fileName = (String)stringifyChildren(t.child(0)); + for(File f : includes) { + File file = new File(f.getAbsolutePath()+File.separatorChar+fileName); + if (!file.exists()) continue; + try { + String newPrefix = (String)walk(t.child(1)); + if (newPrefix.length() > 0) newPrefix += "."; + FileInputStream fis = new FileInputStream(file); + Tree tr = new CharParser(MetaGrammar.newInstance()).parse(fis).expand1(); + return (GrammarNode)new GrammarBuilder(includes, newPrefix).walk(tr); + } catch (Exception e) { + throw new RuntimeException("while parsing " + file, e); + } } + throw new RuntimeException("unable to find #include file \""+fileName+"\""); } throw new RuntimeException("unknown head: " + head + "\n"+t); } @@ -327,8 +343,6 @@ public class GrammarBuilder { if (!drops[i]) if (idx==-1) idx = i; else multiNonDrop = true; - if (tag==null && multiNonDrop) - throw new Error("multiple non-dropped elements in sequence: " + Sequence.create(els, "")); for(int i=0; i