X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fmeta%2FGrammarAST.java;h=297886b36f69cfe5427d71d5020aacf9a04b2dc5;hp=87f7789269cabbfdc1a2a102567439de866a140a;hb=d474c27d3c37b00d2b2ec2dc62d123d69c8edac9;hpb=67d5def8fede01f412905fb5ff968b79894166fb diff --git a/src/edu/berkeley/sbp/meta/GrammarAST.java b/src/edu/berkeley/sbp/meta/GrammarAST.java index 87f7789..297886b 100644 --- a/src/edu/berkeley/sbp/meta/GrammarAST.java +++ b/src/edu/berkeley/sbp/meta/GrammarAST.java @@ -17,6 +17,14 @@ import java.io.*; public class GrammarAST { /** + * Returns a Union representing the metagrammar (meta.g); the Tree produced by + * parsing with this Union should be provided to buildFromAST + */ + public static Union getMetaGrammar() { + return buildFromAST(MetaGrammar.meta, "s", new File[0]); + } + + /** * Create a grammar from a parse tree and binding resolver * * @param t a tree produced by parsing a grammar using the metagrammar @@ -27,10 +35,6 @@ public class GrammarAST { return new GrammarAST(includes, "").buildGrammar(grammarAST, startingNonterminal); } - public static Union getMetaGrammar() { - return MetaGrammar.newInstance(); - } - private static Object illegalTag = ""; // this is the tag that should never appear in the non-dropped output FIXME // Instance ////////////////////////////////////////////////////////////////////////////// @@ -88,7 +92,6 @@ public class GrammarAST { if (head.equals("Elements")) return new Seq((ElementNode[])Reflection.rebuild(walkChildren(t), ElementNode[].class)); if (head.equals("NonTerminalReference")) return new ReferenceNode(stringifyChildren(t.child(0))); if (head.equals(")")) return new ReferenceNode(stringifyChildren(t.child(0)), true); - if (head.equals("{")) return new BracedNode(walkSeq(t.child(0))); if (head.equals("::")) return walkSeq(t.child(1)).tag(walkString(t.child(0))); if (head.equals("...")) return new DropNode(new RepeatNode(new TildeNode(new AtomNode()), null, true, true, false)); @@ -104,15 +107,15 @@ public class GrammarAST { if (head.equals("!")) return new DropNode(walkElement(t.child(0))); if (head.equals("^")) return new LiteralNode(walkString(t.child(0)), true); - if (head.equals("`")) return walkElement(t.child(0)).lifted(); + if (head.equals("`")) return new BacktickNode(walkElement(t.child(0))); if (head.equals("Quoted")) return stringifyChildren(t); if (head.equals("Literal")) return new LiteralNode(walkString(t.child(0))); if (head.equals("->")) return walkSeq(t.child(0)).follow(walkElement(t.child(1))); if (head.equals("DropNT")) return new NonTerminalNode(walkString(t.child(0)), (Seq[][])walkChildren(t.child(1)), false, null, true); if (head.equals("=")) return new NonTerminalNode(walkString(t.child(0)), (Seq[][])walk(t.child(2)), true, t.size()==2 ? null : walkString(t.child(1)), false); - if (head.equals("&")) return and2(walkSeq(t.child(0)), walkSeq(t.child(1))); - if (head.equals("&~")) return andnot2(walkSeq(t.child(0)), walkSeq(t.child(1))); + if (head.equals("&")) return walkSeq(t.child(0)).and(walkSeq(t.child(1))); + if (head.equals("&~")) return walkSeq(t.child(0)).andnot(walkSeq(t.child(1))); if (head.equals("/")) return (walkSeq(t.child(0))).separate(walkElement(t.child(1))); if (head.equals("()")) return new LiteralNode(""); if (head.equals("[")) return new AtomNode((char[][])Reflection.rebuild(walkChildren(t), char[][].class)); @@ -151,7 +154,7 @@ public class GrammarAST { try { String newPrefix = t.size()<2 ? "" : (walkString(t.child(1))+"."); FileInputStream fis = new FileInputStream(file); - Tree tr = new CharParser(MetaGrammar.newInstance()).parse(fis).expand1(); + Tree tr = new CharParser(getMetaGrammar()).parse(fis).expand1(); return (GrammarNode)new GrammarAST(includes, newPrefix).walk(tr); } catch (Exception e) { throw new RuntimeException("while parsing " + file, e); @@ -204,6 +207,14 @@ public class GrammarAST { } } + /** a node in the AST which is resolved into an Element */ + private abstract class ElementNode { + public boolean isLifted() { return false; } + public boolean drop(Context cx) { return false; } + public Atom toAtom(Context cx) { throw new Error("can't convert a " + this.getClass().getName() + " to an atom: " + this); } + public abstract Element build(Context cx, NonTerminalNode cnt, boolean dropall); + } + private class UnionNode extends ElementNode { public Seq[][] sequences; public String sep = null; @@ -302,7 +313,6 @@ public class GrammarAST { for(int i=0; i)_e.toAtom(cx).complement()); } @@ -516,26 +518,6 @@ public class GrammarAST { public boolean drop(Context cx) { return true; } } - // FIXME: doesn't this require a tag? - private class BracedNode extends ElementNode { - public Seq body; - public BracedNode(Seq seq) { this.body = seq; } - public Element build(Context cx, NonTerminalNode cnt, boolean dropall) { - Union u = new Union(null, false); - Sequence s = body.build(cx, u, null, dropall); - Union u2 = new Union(null, false); - u2.add(Sequence.create(new Element[] { - CharAtom.leftBrace, - u, - CharAtom.rightBrace - }, 1)); - return u2; - } - } - - public Seq and2(Seq s, Seq a) { a.alwaysDrop = true; return s.and(a); } - public Seq andnot2(Seq s, Seq a) { a.alwaysDrop = true; return s.andnot(a); } - ////////////////////////////////////////////////////////////////////////////// public class Context {