X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fmeta%2FMetaGrammarBindings.java;h=bddccf57b30a0ea594f04cac3aadae979dd1aefc;hp=401536f2aca726718d96982cb84f6fd463d4bac2;hb=bc2858abab718e5c3d0cf07c4f18f353f57832e6;hpb=a7ba8d8a5f0cb7fbb5bf67f1a95f1cad5226c507 diff --git a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java index 401536f..bddccf5 100644 --- a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java +++ b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java @@ -13,9 +13,34 @@ import java.io.*; public class MetaGrammarBindings { /** A grammar (a set of nonterminals) */ - public static class GrammarNode extends HashMap { - public @bind.as("Grammar") GrammarNode(NonTerminalNode[] nonterminals) { - for(NonTerminalNode nt : nonterminals) this.put(nt.name, nt); } + public static class GrammarNode extends HashMap implements NonTerminalSource { + public NonTerminalNode[] getNonTerminals() { + return (NonTerminalNode[])values().toArray(new NonTerminalNode[0]); + } + public 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 @bind.as("Grammar") GrammarNode(Object[] nt) { + add(nt); + } + private void add(Object[] obs) { + for(Object o : obs) { + if (o==null) continue; + else if (o instanceof Object[]) add((Object[])o); + else if (o instanceof NonTerminalNode) { + NonTerminalNode nt = (NonTerminalNode)o; + if (this.get(nt.name)!=null) + throw new RuntimeException("duplicate definition of nonterminal \""+nt.name+"\""); + this.put(nt.name, nt); + } + else if (o instanceof NonTerminalSource) add(((NonTerminalSource)o).getNonTerminals()); + } + } public String toString() { String ret = "[ "; for(NonTerminalNode nt : values()) ret += nt + ", "; @@ -57,10 +82,27 @@ public class MetaGrammarBindings { } } - public static class NonTerminalNode extends UnionNode { + public static @bind.as("#import") GrammarNode poundimport(String fileName) { + System.err.println("#import " + fileName); + try { + Tree t = new CharParser(MetaGrammar.make()).parse(new FileInputStream(fileName)).expand1(); + Tree.TreeFunctor red = (Tree.TreeFunctor)t.head(); + return (MetaGrammarBindings.GrammarNode)red.invoke(t); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public static interface NonTerminalSource { + public NonTerminalNode[] getNonTerminals(); + } + + public static class NonTerminalNode extends UnionNode implements NonTerminalSource { public boolean rep; public String name = null; public String sep = null; + public NonTerminalNode[] getNonTerminals() { return new NonTerminalNode[] { this }; } public @bind.as("NonTerminal") NonTerminalNode(@bind.arg String name, @bind.arg Seq[][] sequences) { this(name, sequences, false); } public NonTerminalNode(String name, Seq[][] sequences, boolean rep) { this(name, sequences, rep, null); } public NonTerminalNode(String name, Seq[][] sequences, boolean rep, String sep) { @@ -327,7 +369,7 @@ public class MetaGrammarBindings { public static @bind.as("~") ElementNode tilde(final ElementNode e) { return new PostProcess(e) { public Element postProcess(Element e) { - return infer((Topology)Atom.toAtom(e).complement()); + return infer((Topology)Atom.toAtom(e).complement().minus(CharRange.braces)); } }; } public static @bind.as("Word") String word(String s) { return s; } @@ -361,7 +403,7 @@ public class MetaGrammarBindings { public Context(Tree t, GrammarBindingResolver rm) { this.rm = rm; Tree.TreeFunctor red = (Tree.TreeFunctor)t.head(); - this.grammar = (GrammarNode)red.invoke(t.children()); + 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); }