From: adam Date: Wed, 5 Jul 2006 05:18:43 +0000 (-0400) Subject: checkpoint X-Git-Tag: tag_for_25-Mar~201 X-Git-Url: http://git.megacz.com/?p=sbp.git;a=commitdiff_plain;h=f7d5c2384df4e9e586f3c3465a6e6e0f4212115c checkpoint darcs-hash:20060705051843-5007d-3e3a0ab2c41819d6ff4c645aa024369ecb483699.gz --- diff --git a/src/edu/berkeley/sbp/meta/AnnotationGrammarBindingResolver.java b/src/edu/berkeley/sbp/meta/AnnotationGrammarBindingResolver.java new file mode 100644 index 0000000..1955f7f --- /dev/null +++ b/src/edu/berkeley/sbp/meta/AnnotationGrammarBindingResolver.java @@ -0,0 +1,62 @@ +package edu.berkeley.sbp.meta; +import edu.berkeley.sbp.util.*; +import edu.berkeley.sbp.*; +import edu.berkeley.sbp.chr.*; +import edu.berkeley.sbp.misc.*; +import edu.berkeley.sbp.bind.*; +import java.util.*; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.io.*; + +public class AnnotationGrammarBindingResolver extends GrammarBindingResolver { + + private static boolean harsh = true; + + private final Class _cl; + private final Class[] _inner; + + public AnnotationGrammarBindingResolver() { + this(MetaGrammarBindings.class); + } + + public AnnotationGrammarBindingResolver(Class c) { + this._cl = c; + this._inner = c.getDeclaredClasses(); + } + + public AnnotationGrammarBindingResolver(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) { + for(Method m : _cl.getMethods()) + if (new MetaGrammar.Target(m).isCompatible(tag, nonTerminalName, els, labels, drops)) + return new MetaGrammar.Target(m).makeSequence(tag, nonTerminalName, els, labels, drops); + for(Class c : _inner) + for(Constructor con : c.getConstructors()) + if (new MetaGrammar.Target(con).isCompatible(tag, nonTerminalName, els, labels, drops)) + return new MetaGrammar.Target(con).makeSequence(tag, nonTerminalName, els, labels, drops); + for(Class c : _inner) + if (new MetaGrammar.Target(c).isCompatible(tag, nonTerminalName, els, labels, drops)) + return new MetaGrammar.Target(c).makeSequence(tag, nonTerminalName, els, labels, drops); + 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); + } + } +} diff --git a/src/edu/berkeley/sbp/meta/GrammarBindingResolver.java b/src/edu/berkeley/sbp/meta/GrammarBindingResolver.java new file mode 100644 index 0000000..a71122e --- /dev/null +++ b/src/edu/berkeley/sbp/meta/GrammarBindingResolver.java @@ -0,0 +1,19 @@ +package edu.berkeley.sbp.meta; +import edu.berkeley.sbp.util.*; +import edu.berkeley.sbp.*; +import edu.berkeley.sbp.chr.*; +import edu.berkeley.sbp.misc.*; +import edu.berkeley.sbp.bind.*; +import java.util.*; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.io.*; + +public class GrammarBindingResolver { + 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); + } +} diff --git a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java new file mode 100644 index 0000000..3ba3d2a --- /dev/null +++ b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java @@ -0,0 +1,280 @@ +package edu.berkeley.sbp.meta; +import edu.berkeley.sbp.util.*; +import edu.berkeley.sbp.*; +import edu.berkeley.sbp.chr.*; +import edu.berkeley.sbp.misc.*; +import edu.berkeley.sbp.bind.*; +import java.util.*; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.io.*; + +public class MetaGrammarBindings { + 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(MetaGrammar.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(MetaGrammar.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(MetaGrammar.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(MetaGrammar.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(MetaGrammar.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(MetaGrammar.Context cx) { return constant; } + } + public abstract static class PostProcess extends El { + El e; + public PostProcess(El e) { this.e = e; } + public Element build(MetaGrammar.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"; } + + static Atom infer(Element e) { return infer((Topology)Atom.toAtom(e)); } + static Atom infer(Topology t) { return new CharRange(new CharTopology(t)); } +}