X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fmeta%2FMetaGrammarBindings.java;h=d33758c87374e7bb3818ff0e8fff7b2384fb869c;hp=cae7f13b6f62afb3f74872f2d831a176e183dd3d;hb=f3b4ef0d81d572694905f4fe284cac6311a29ea4;hpb=184c7d30b66e1e2ae9ce2c0251cb3b65fd80e893 diff --git a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java index cae7f13..d33758c 100644 --- a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java +++ b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java @@ -13,26 +13,43 @@ import java.io.*; public class MetaGrammarBindings { /** A grammar (a set of nonterminals) */ - public static class Grammar extends HashMap { - public @bind Grammar(NonTerminal[] nonterminals) { - for(NonTerminal nt : nonterminals) this.put(nt.name, nt); } + public static class GrammarNode extends HashMap { + public @bind.as("Grammar") GrammarNode(NonTerminalNode[] nonterminals) { + for(NonTerminalNode nt : nonterminals) { + if (nt==null) continue; + if (this.get(nt.name)!=null) + throw new RuntimeException("duplicate definition of nonterminal \""+nt.name+"\""); + this.put(nt.name, nt); + } + } public String toString() { String ret = "[ "; - for(NonTerminal nt : values()) ret += nt + ", "; + for(NonTerminalNode nt : values()) ret += nt + ", "; return ret + " ]"; } + public Union build(String s, GrammarBindingResolver rm) { + Context cx = new Context(this,rm); + Union u = null; + for(MetaGrammarBindings.NonTerminalNode nt : values()) { + Union el = (Union)cx.get(nt.name); + StringBuffer st = new StringBuffer(); + el.toString(st); + if (nt.name.equals(s)) u = el; + } + return u; + } } public abstract static class UnionNode extends ElementNode { public Seq[][] sequences; - public void build(MetaGrammar.Context cx, Union u) { + public void build(Context cx, Union u, NonTerminalNode cnt) { HashSet bad2 = new HashSet(); for(int i=0; i bad2 = new HashSet(); Union urep = new Union(); @@ -73,7 +95,7 @@ public class MetaGrammarBindings { if (sequences.length==1) u2 = u; for(int j=0; j and = new HashSet(); HashSet not = new HashSet(); @@ -171,31 +197,29 @@ public class MetaGrammarBindings { this.elements = elements; return this; } - public Sequence build(MetaGrammar.Context cx, Union u, boolean lame) { - Sequence ret = build0(cx, lame || this.lame); - for(Seq s : and) { Sequence dork = s.build(cx, u, true); ret = ret.and(dork); } - for(Seq s : not) { Sequence dork = s.build(cx, u, true); ret = ret.not(dork); } + public Sequence build(Context cx, Union u, boolean lame, NonTerminalNode cnt) { + Sequence ret = build0(cx, lame || this.lame, cnt); + for(Seq s : and) { Sequence dork = s.build(cx, u, true, cnt); ret = ret.and(dork); } + for(Seq s : not) { Sequence dork = s.build(cx, u, true, cnt); ret = ret.not(dork); } u.add(ret); ret.lame = lame; return ret; } - public Sequence build0(MetaGrammar.Context cx, boolean lame) { + public Sequence build0(Context cx, boolean lame, NonTerminalNode cnt) { boolean dropAll = lame; if (tag!=null && "()".equals(tag)) dropAll = true; - Object[] labels = new Object[elements.length]; boolean[] drops = new boolean[elements.length]; Element[] els = new Element[elements.length]; for(int i=0; i)Atom.toAtom(e).complement()); + return infer((Topology)Atom.toAtom(e).complement().minus(CharRange.braces)); } }; } - public static @bind.as("^^") void doublecaret(final ElementNode e) { throw new Error("not implemented"); } - - //public static @bind.as("(") ElementNode subexpression(Seq[][] rhs) { return new NonTerminal(rhs); } - public static @bind.as("Word") String word(String s) { return s; } public static @bind.as("Quoted") String quoted(String s) { return s; } public static @bind.as("escaped") String c(char c) { return c+""; } @@ -326,4 +350,49 @@ public class MetaGrammarBindings { static Atom infer(Element e) { return infer((Topology)Atom.toAtom(e)); } static Atom infer(Topology t) { return new CharRange(new CharTopology(t)); } + + public static class Context { + public HashMap map = new HashMap(); + public GrammarNode grammar; + public String cnt = null; + public GrammarBindingResolver rm; + public Context(GrammarNode g, GrammarBindingResolver rm) { + this.grammar = g; + this.rm = rm; + } + public Union build() { + Union ret = null; + for(NonTerminalNode nt : grammar.values()) { + Union u = get(nt.name); + if ("s".equals(nt.name)) + ret = u; + } + return ret; + } + public Context(Tree t, GrammarBindingResolver rm) { + this.rm = rm; + Tree.TreeFunctor red = (Tree.TreeFunctor)t.head(); + this.grammar = (GrammarNode)red.invoke(t); + } + public Union peek(String name) { return map.get(name); } + public void put(String name, Union u) { map.put(name, u); } + public Union get(String name) { + Union ret = map.get(name); + if (ret != null) return ret; + ret = new Union(name); + map.put(name, ret); + NonTerminalNode nt = grammar.get(name); + if (nt==null) { + System.err.println("*** warning could not find " + name); + } else { + String old = cnt; + cnt = name; + nt.build(this, ret, nt); + cnt = old; + } + return ret; + } + + } + }