X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fmeta%2FMetaGrammar.java;h=2077bbd3be734ab61c8634c280d9df0e94f8f076;hb=80128a38a1c907f1860a5cb13769d691be059a5f;hp=2e5fd95dc6a50bcceb5cdad317920eb53b04fab4;hpb=54a6a6e983c3883720b22fe0bef998d309f92097;p=sbp.git diff --git a/src/edu/berkeley/sbp/meta/MetaGrammar.java b/src/edu/berkeley/sbp/meta/MetaGrammar.java index 2e5fd95..2077bbd 100644 --- a/src/edu/berkeley/sbp/meta/MetaGrammar.java +++ b/src/edu/berkeley/sbp/meta/MetaGrammar.java @@ -11,8 +11,6 @@ import java.io.*; public class MetaGrammar { - public static boolean harsh = true; - public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println("usage: java " + MetaGrammar.class.getName() + " grammarfile.g com.yourdomain.package.ClassName"); @@ -38,7 +36,7 @@ public class MetaGrammar { out.append("\n // DO NOT EDIT STUFF BELOW: IT IS AUTOMATICALLY GENERATED\n"); /* - ReflectiveMeta m = new ReflectiveMeta(); + GrammarCompiler m = new GrammarCompiler(); Tree res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(args[0])).expand1(); MetaGrammar.Meta.MetaGrammarFile mgf = m.new MetaGrammarFile(res); MetaGrammar.BuildContext bc = new MetaGrammar.BuildContext(mgf); @@ -75,59 +73,6 @@ public class MetaGrammar { os.close(); } - public static class ReflectiveMetaPlain extends ReflectiveMeta { - public Object repeatTag() { return null; } - public Sequence tryResolveTag(String tag, String nonTerminalName, Element[] els, Object[] labels, boolean[] drops) { - return null; } - public Sequence resolveTag(String tag, String nonTerminalName, Element[] els, Object[] labels, boolean[] drops) { - return Sequence.rewritingSequence(tag, els, labels, drops); - } - } - - public static class ReflectiveMeta /*extends MetaGrammar.Meta*/ { - private final Class _cl; - private final Class[] _inner; - public ReflectiveMeta() { - this(MG.class); - } - public ReflectiveMeta(Class c) { - this._cl = c; - this._inner = c.getDeclaredClasses(); - } - public ReflectiveMeta(Class c, Class[] inner) { - this._cl = c; - this._inner = inner; - } - public Object repeatTag() { - return new Tree.ArrayBuildingTreeFunctor(); - } - public Sequence tryResolveTag(String tag, String nonTerminalName, Element[] els, Object[] labels, boolean[] drops) { - Production p = new Production(tag, nonTerminalName, els, labels, drops); - for(Method m : _cl.getMethods()) - if (new Target(m).isCompatible(p)) - return new Target(m).makeSequence(p); - for(Class c : _inner) - for(Constructor con : c.getConstructors()) - if (new Target(con).isCompatible(p)) - return new Target(con).makeSequence(p); - for(Class c : _inner) - if (new Target(c).isCompatible(p)) - return new Target(c).makeSequence(p); - return null; - } - public Sequence resolveTag(String tag, String nonTerminalName, Element[] els, Object[] labels, boolean[] drops) { - Sequence ret = tryResolveTag(tag, nonTerminalName, els, labels, drops); - if (ret != null) return ret; - String message = "could not find a Java method/class/ctor matching tag \""+tag+ - "\", nonterminal \""+nonTerminalName+"\" with " + els.length + " arguments"; - if (harsh) { - throw new RuntimeException(message); - } else { - System.err.println(message); - return Sequence.rewritingSequence(tag, els, labels, drops); - } - } - } public static class Production { @@ -182,7 +127,7 @@ public class MetaGrammar { return buildSequence(p)!=null; bind b = getBind(); - System.out.println(_bindable.getClass().getSimpleName() + ": " + _bindable.getSimpleName()); + //System.out.println(_bindable.getClass().getSimpleName() + ": " + _bindable.getSimpleName()); if (b != null && getName().equals(p.tag)) return buildSequence(p)!=null; @@ -205,15 +150,27 @@ public class MetaGrammar { argTagged++; // FIXME: can be smarter here - if (names.length==p.count) { - int[] ret = new int[p.count]; - for(int i=0; i res = new CharParser(MetaGrammar.make()).parse(new FileInputStream("tests/meta.g")).expand1(); MetaGrammar.Meta.MetaGrammarFile mgf = m.new MetaGrammarFile(res); MetaGrammar.BuildContext bc = new MetaGrammar.BuildContext(mgf); @@ -290,19 +247,16 @@ public class MetaGrammar { */ return make(MetaGrammarTree.meta, "s"); } - public static Union make(Tree t, String s) { return make(t, s, new ReflectiveMeta()); } - public static Union make(Tree t, String s, ReflectiveMeta rm) { - System.out.println("Head: " + t.head()); + public static Union make(Tree t, String s) { return make(t, s, new AnnotationGrammarBindingResolver()); } + public static Union make(Tree t, String s, GrammarBindingResolver rm) { Tree.TreeFunctor red = (Tree.TreeFunctor)t.head(); - MG.Grammar g = (MG.Grammar)red.invoke(t.children()); + MetaGrammarBindings.Grammar g = (MetaGrammarBindings.Grammar)red.invoke(t.children()); Context cx = new Context(g,rm); Union u = null; - for(MG.NonTerminal nt : g.nonterminals) { - System.out.println(nt.name); + for(MetaGrammarBindings.NonTerminal nt : g.values()) { Union el = (Union)cx.get(nt.name); StringBuffer st = new StringBuffer(); el.toString(st); - System.err.println(st); if (nt.name.equals(s)) u = el; } return u; @@ -310,295 +264,28 @@ public class MetaGrammar { - public static class MG { - public static @bind class Grammar { - public NonTerminal get(String s) { - for(NonTerminal nt : nonterminals) - if (nt.name.equals(s)) return nt; - return null; - } - public @bind.arg NonTerminal[] nonterminals; - public String toString() { - String ret = "[ "; - for(NonTerminal nt : nonterminals) ret += nt + ", "; - return ret + " ]"; - } - } - public abstract static class Un extends El { - public Seq[][] sequences; - public void build(Context cx, Union u) { - HashSet bad2 = new HashSet(); - for(int i=0; i and = new HashSet(); - HashSet not = new HashSet(); - El[] elements; - El follow; - String tag = null; - boolean lame; - public Seq(El e) { this(new El[] { e }); } - public Seq(El[] elements) { this.elements = elements; } - public Seq tag(String tag) { this.tag = tag; return this; } - public Seq follow(El follow) { this.follow = follow; return this; } - public Seq dup() { - Seq ret = new Seq(elements); - ret.and.addAll(and); - ret.not.addAll(not); - ret.follow = follow; - ret.tag = tag; - return ret; - } - public Seq and(Seq s) { and.add(s); s.lame = true; return this; } - public Seq andnot(Seq s) { not.add(s); s.lame = true; return this; } - public Seq separate(El sep) { - El[] elements = new El[this.elements.length * 2 - 1]; - for(int i=0; i") Seq arrow(Seq s, El e) { return s.follow(e); } - public static @bind.as("::") Seq tag(String tagname, Seq s) { return s.tag(tagname); } - public static @bind.as("/") Seq slash(Seq s, El e) { return s.separate(e); } - - public static @bind.as("ps") Seq seq(El[] elements) { return new Seq(elements); } - public static @bind.as Seq psx(Seq s) { return s; } - public static @bind.as(":") El colon(String s, El e) { return new Label(s, e); } - public static @bind.as(")") void close(String foo) { throw new Error("not supported"); } - public static @bind.as("()") El epsilon() { return new Constant(Union.epsilon); } - - public static @bind.as("nonTerminal") class NonTerminalReference extends El { - public @bind.arg String nonTerminal; - public Element build(Context cx) { - return cx.get(nonTerminal); - } - } - - public static class StringLiteral extends Constant { - public @bind.as("literal") StringLiteral(String string) { super(CharRange.string(string)); } - public boolean drop() { return true; } - } - - public static class CharClass extends El { - Range[] ranges; - public @bind.as("[") CharClass(Range[] ranges) { this.ranges = ranges; } - public Element build(Context cx) { - edu.berkeley.sbp.util.Range.Set set = new edu.berkeley.sbp.util.Range.Set(); - for(Range r : ranges) - set.add(r.first, r.last); - return CharRange.set(set); - } - } - - public static @bind.as("{") class XTree extends El { - public @bind.arg Seq body; - public Element build(Context cx) { - throw new Error(); - } - } - - public static class Rep extends El { - public El e, sep; - public boolean zero, many, max; - public Rep(El e, El sep, boolean zero, boolean many, boolean max) { - this.e = e; this.sep = sep; this.zero = zero; this.many = many; this.max = max;} - public Element build(Context cx) { - return (!max) - ? Sequence.repeat(e.build(cx), zero, many, sep==null ? null : sep.build(cx), cx.rm.repeatTag()) - : sep==null - ? Sequence.repeatMaximal(infer(e.build(cx)), zero, many, cx.rm.repeatTag()) - : Sequence.repeatMaximal(e.build(cx), zero, many, infer(sep.build(cx)), cx.rm.repeatTag()); - } - } - public static class Constant extends El { - Element constant; - public Constant(Element constant) { this.constant = constant; } - public Element build(Context cx) { return constant; } - } - public abstract static class PostProcess extends El { - El e; - public PostProcess(El e) { this.e = e; } - public Element build(Context cx) { return postProcess(e.build(cx)); } - public abstract Element postProcess(Element e); - } - - // FIXME: it would be nice if we could hoist this into "Rep" - public static @bind.as("++") El plusmax(final El e) { return new Rep(e, null, false, true, true); } - public static @bind.as("+") El plus(final El e) { return new Rep(e, null, false, true, false); } - public static @bind.as("++/") El plusmaxfollow(final El e, final El sep) { return new Rep(e, sep, false, true, true); } - public static @bind.as("+/") El plusfollow(final El e, final El sep) { return new Rep(e, sep, false, true, false); } - public static @bind.as("**") El starmax(final El e) { return new Rep(e, null, true, true, true); } - public static @bind.as("*") El star(final El e) { return new Rep(e, null, true, true, false); } - public static @bind.as("**/") El starmaxfollow(final El e, final El sep) { return new Rep(e, sep, true, true, true); } - public static @bind.as("*/") El starfollow(final El e, final El sep) { return new Rep(e, sep, true, true, false); } - public static @bind.as("?") El question(final El e) { return new Rep(e, null, true, true, false); } - - public static @bind.as("!") El bang(final El e) { return new Drop(e); } - - public static @bind.as("^") El caret(final String s) { - return new Drop(new Constant(CharRange.string(s)) { - public String getOwnerTag() { return s; } - }); - } - - public static @bind.as("~") El tilde(final El e) { - return new PostProcess(e) { - public Element postProcess(Element e) { - return infer((Topology)Atom.toAtom(e).complement()); - } }; } - - public static @bind.as("^^") void doublecaret(final El e) { throw new Error("not implemented"); } - - //public static @bind.as("(") El 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+""; } - public static @bind.as("\"\"") String emptystring() { return ""; } - public static @bind.as("\n") String retur() { return "\n"; } - public static @bind.as("\r") String lf() { return "\r"; } - - } public static class Context { - HashMap map = new HashMap(); - private MG.Grammar grammar; + public HashMap map = new HashMap(); + public MetaGrammarBindings.Grammar grammar; public String cnt = null; - private ReflectiveMeta rm; - public Context(MG.Grammar g, ReflectiveMeta rm) { + public GrammarBindingResolver rm; + public Context(MetaGrammarBindings.Grammar g, GrammarBindingResolver rm) { this.grammar = g; this.rm = rm; } public Union build() { Union ret = null; - for(MG.NonTerminal nt : grammar.nonterminals) { + for(MetaGrammarBindings.NonTerminal nt : grammar.values()) { Union u = get(nt.name); if ("s".equals(nt.name)) ret = u; } return ret; } - public Context(Tree t, ReflectiveMeta rm) { + public Context(Tree t, GrammarBindingResolver rm) { this.rm = rm; Tree.TreeFunctor red = (Tree.TreeFunctor)t.head(); - this.grammar = (MG.Grammar)red.invoke(t.children()); + this.grammar = (MetaGrammarBindings.Grammar)red.invoke(t.children()); } public Union peek(String name) { return map.get(name); } public void put(String name, Union u) { map.put(name, u); } @@ -607,7 +294,7 @@ public class MetaGrammar { if (ret != null) return ret; ret = new Union(name); map.put(name, ret); - MG.NonTerminal nt = grammar.get(name); + MetaGrammarBindings.NonTerminal nt = grammar.get(name); if (nt==null) { System.err.println("*** warning could not find " + name); } else {