From 98ae7592861f7e7d3bf5744b5db84ffdefc6011d Mon Sep 17 00:00:00 2001 From: adam Date: Wed, 28 Jun 2006 18:06:21 -0400 Subject: [PATCH] checkpoint darcs-hash:20060628220621-5007d-27e1a175e71388d653724107e519e96753fe3b6c.gz --- Makefile | 4 +- src/edu/berkeley/sbp/misc/Demo.java | 321 +++++++++++++++++++++++++++- src/edu/berkeley/sbp/misc/MetaGrammar.java | 94 ++++---- 3 files changed, 366 insertions(+), 53 deletions(-) diff --git a/Makefile b/Makefile index 8cf95ac..c9da038 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,8 @@ tibdoc: edu.berkeley.sbp.jar demo: edu.berkeley.sbp.jar $(java) -cp $< edu.berkeley.sbp.misc.Demo \ - tests/demo.g \ - tests/demo.in + tests/meta.g \ + tests/meta.g regress: make boot diff --git a/src/edu/berkeley/sbp/misc/Demo.java b/src/edu/berkeley/sbp/misc/Demo.java index 4e0dc1b..02482fa 100644 --- a/src/edu/berkeley/sbp/misc/Demo.java +++ b/src/edu/berkeley/sbp/misc/Demo.java @@ -3,19 +3,320 @@ import edu.berkeley.sbp.util.*; import edu.berkeley.sbp.*; import edu.berkeley.sbp.chr.*; import java.util.*; +import java.lang.annotation.*; +import java.lang.reflect.*; import java.io.*; public class Demo { public static void main(String[] s) throws Exception { - /* - Tree gram = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1(); - MetaGrammar g = (MetaGrammar)new MetaGrammar().walk(gram); - Union meta = g.done(); - //Tree out = new CharParser(meta).parse(new FileInputStream(s[1])).expand1(); - Forest out = new CharParser(meta).parse(new FileInputStream(s[1])); - GraphViz gv = new GraphViz(); - out.toGraphViz(gv); - gv.dump(new PrintWriter(new OutputStreamWriter(System.out))); - */ + Tree res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1(); + + MetaGrammar.Meta m = + new ReflectiveMeta(MG.class, + new Class[] { + MG.Grammar.class, + MG.NonTerminal.class, + MG.Range.class, + MG.El.class, + MG.Seq.class, + MG.NonTerminalReference.class, + MG.StringLiteral.class, + MG.Epsilon.class, + MG.Tree.class, + MG.CharClass.class + }); + MetaGrammar.Meta.MetaGrammarFile mgf = m.new MetaGrammarFile(res); + MetaGrammar.BuildContext bc = new MetaGrammar.BuildContext(mgf); + Union meta = mgf.get("s").build(bc); + + System.err.println("parsing " + s[1]); + res = new CharParser(meta).parse(new FileInputStream(s[1])).expand1(); + + System.out.println(res); + } + + public static class ReflectiveMeta extends MetaGrammar.Meta { + private final Class _cl; + private final Class[] _inner; + public ReflectiveMeta(Class c, Class[] inner) { + this._cl = c; + this._inner = inner; + } + private boolean match(Method m, String s) { return match(m.getAnnotation(tag.class), null, s); } + private boolean match(tag t, Class c, String s) { + if (t==null) return false; + if (t.value().equals(s)) return true; + if (c != null && t.equals("") && c.getSimpleName().equals(s)) return true; + return false; + } + private boolean match(nonterminal t, Class c, String s) { + if (t==null) return false; + if (t.value().equals(s)) return true; + if (c != null && t.equals("") && c.getSimpleName().equals(s)) return true; + return false; + } + private boolean match(Class c, String s, String nonTerminalName) { + if (match((tag)c.getAnnotation(tag.class), c, s)) return true; + if (match((nonterminal)c.getAnnotation(nonterminal.class), c, nonTerminalName)) return true; + return false; + } + public boolean match(Constructor con, String s, String nonTerminalName) { + Class c = con.getDeclaringClass(); + if (match((tag)con.getAnnotation(tag.class), null, s)) return true; + if (match((nonterminal)con.getAnnotation(nonterminal.class), c, s)) return true; + return false; + } + public Sequence resolveTag(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 TargetMethod(m).isCompatible(p)) + return Sequence.rewritingSequence(m, els, labels, drops); + for(Class c : _inner) + for(Constructor con : c.getConstructors()) + if (new TargetConstructor(con).isCompatible(p)) + return Sequence.rewritingSequence(con, els, labels, drops); + for(Class c : _inner) + if (new TargetClass(c).isCompatible(p)) + return Sequence.rewritingSequence(c, els, labels, drops); + throw new RuntimeException("could not find a Java method/class/ctor matching tag \""+tag+"\", nonterminal \""+nonTerminalName+"\""); + } } + /* + public static Object makeFlattener(final Method m, final Element[] els, final Object[] labels, final boolean[] drops) { + return new Reducer() { + public Object reduce(Tree t) { + Object[] o = new Object[m.getParameterTypes()]; + int j = 0; + for(int i=0; i name.lastIndexOf('.')) { + len--; + ofs++; + } + String[] names = new String[len]; + arg[] argtags = new arg[len]; + for(int i=0; i") Seq arrow(Seq s, Element e) { return null; } + + public @tag("nonTerminal") class NonTerminalReference { public @arg String nonTerminal; } + public @tag("literal") class StringLiteral { public @arg String string; } + public @tag("()") class Epsilon { } + public @tag("{") class Tree { @arg Seq body; } + public @tag("[") class CharClass { public CharClass(Range[] ranges) { } } + + public @tag("++") void plusmax(El e) { } + public @tag("+") void plus(El e) { } + public @tag("++/") void plusmaxfollow(El e, El sep) { } + public @tag("+/") void plusfollow(El e, El sep) { } + public @tag("**") void starmax(El e) { } + public @tag("*") void star(El e) { } + public @tag("**/") void starmaxfollow(El e, El sep) { } + public @tag("*/") void starfollow(El e, El sep) { } + public @tag("!") void bang(El e) { } + public @tag("?") void question(El e) { } + public @tag("^") void caret(String s) { } + public @tag("~") void tilde(El e) { } + public @tag("^^") void doublecaret(El e) { } + public @tag("(") void subexpression(Seq[][] rhs) { } + + public @nonterminal("Word") String word(String s) { return null; } + public @nonterminal("Quoted") String quoted(String s) { return null; } + public @nonterminal("escaped") String c(char c) { return null; } + public @tag("\"\"") String emptystring() { return null; } + public @tag("\r") String lf() { return null; } + public @tag("\n") String cr() { return null; } + } + } diff --git a/src/edu/berkeley/sbp/misc/MetaGrammar.java b/src/edu/berkeley/sbp/misc/MetaGrammar.java index f5fff5d..3420ad5 100644 --- a/src/edu/berkeley/sbp/misc/MetaGrammar.java +++ b/src/edu/berkeley/sbp/misc/MetaGrammar.java @@ -39,42 +39,54 @@ public class MetaGrammar extends StringWalker { public static class BuildContext extends HashMap { private final Meta.MetaGrammarFile mgf; + public Meta.NonTerminal currentNonTerminal; public BuildContext(Meta.MetaGrammarFile mgf) { this.mgf = mgf; } public Union build(String s) { Union ret = get(s); if (ret != null) return ret; - Meta.MetaNonterminal mnt = mgf.get(s); + Meta.NonTerminal mnt = mgf.get(s); if (mnt==null) throw new Error("undeclared nonterminal \""+s+"\""); return mnt.build(this); } } public static class Meta { - public class MetaGrammarFile extends HashMap { + public Sequence resolveTag(String s, String nonTerminalName, Element[] els, Object[] labels, boolean [] drops) { + return Sequence.rewritingSequence(s, els, labels, drops); + } + public class MetaGrammarFile extends HashMap { public MetaGrammarFile(Tree tree) { if (!tree.head().equals("grammar")) throw new Error(); for(Tree nt : tree.child(0)) - add(new MetaNonterminal(nt)); + add(new NonTerminal(nt)); } - private void add(MetaNonterminal mnt) { + private void add(NonTerminal mnt) { if (this.get(mnt.name)!=null) throw new Error("duplicate definition of nonterminal \""+mnt.name+"\""); this.put(mnt.name, mnt); } public String toString() { String ret = ""; - for(MetaNonterminal mnt : this.values()) ret += mnt + "\n"; + for(NonTerminal mnt : this.values()) ret += mnt + "\n"; return ret; } } - public class MetaNonterminal { + public class NonTerminal { public String name; public MetaUnion rhs; - public MetaNonterminal(Tree tree) { + public NonTerminal(Tree tree) { name = string(tree.child(0)); rhs = rhs(tree.child(1)); } public String toString() { return name + " = " + rhs; } - public Union build(BuildContext bc) { return rhs.build(bc, name); } + public Union build(BuildContext bc) { + NonTerminal ont = bc.currentNonTerminal; + bc.currentNonTerminal = this; + try { + return rhs.build(bc, name); + } finally { + bc.currentNonTerminal = ont; + } + } } public MetaUnion rhs(Tree t) { return t.numChildren()==1 @@ -137,9 +149,9 @@ public class MetaGrammar extends StringWalker { } public MetaSequence makeMetaSequence(Tree t) { - if ("psx".equals(t.head())) return makeMetaConjunct(t.child(0)); - if (t.head().equals("&")) return new MetaAnd(makeMetaSequence(t.child(0)), makeMetaConjunct(t.child(1)), false); - if (t.head().equals("&~")) return new MetaAnd(makeMetaSequence(t.child(0)), makeMetaConjunct(t.child(1)), true); + if ("psx".equals(t.head())) return makeConjunct(t.child(0)); + if (t.head().equals("&")) return new MetaAnd(makeMetaSequence(t.child(0)), makeConjunct(t.child(1)), false); + if (t.head().equals("&~")) return new MetaAnd(makeMetaSequence(t.child(0)), makeConjunct(t.child(1)), true); return null; } @@ -166,7 +178,7 @@ public class MetaGrammar extends StringWalker { public String toString() { return left + " &"+(not?"~":"")+" "+right; } } - public class MetaConjunct implements MetaSequence { + public class Conjunct implements MetaSequence { public boolean negated = false; public MetaClause[] elements; public HashMap labelMap = new HashMap(); @@ -198,7 +210,7 @@ public class MetaGrammar extends StringWalker { if (dropAll) ret = Sequence.drop(els, false); else if (unwrap) ret = Sequence.unwrap(els, /*repeatTag FIXME*/null, drops); else if (tag!=null) { - ret = Sequence.rewritingSequence(tag, els, labels, drops); + ret = resolveTag(tag, bc.currentNonTerminal==null ? null : bc.currentNonTerminal.name, els, labels, drops); } else { int idx = -1; for(int i=0; i t) { + private Conjunct(Tree t) { elements = new MetaClause[t.numChildren()]; int i = 0; for(Tree tt : t) elements[i++] = makeMetaClause(tt, this); @@ -227,33 +239,33 @@ public class MetaGrammar extends StringWalker { return ret; } } - public MetaConjunct makeMetaConjunct(Tree t) { - //System.err.println("makeMetaConjunct("+t+")"); + public Conjunct makeConjunct(Tree t) { + //System.err.println("makeConjunct("+t+")"); if ("/".equals(t.head())) { - MetaConjunct ret = makeMetaConjunct(t.child(0)); + Conjunct ret = makeConjunct(t.child(0)); ret.separator = makeMetaClause(t.child(1), ret); return ret; } if ("->".equals(t.head())) { - MetaConjunct ret = makeMetaConjunct(t.child(0)); + Conjunct ret = makeConjunct(t.child(0)); ret.followedBy = makeMetaClause(t.child(1), ret); return ret; } if ("::".equals(t.head())) { - MetaConjunct ret = makeMetaConjunct(t.child(1)); + Conjunct ret = makeConjunct(t.child(1)); ret.tag = string(t.child(0)); return ret; } if ("ps".equals(t.head())) { - return new MetaConjunct(t.child(0)); + return new Conjunct(t.child(0)); } - return new MetaConjunct(t); + return new Conjunct(t); } - public MetaClause makeMetaClause(Tree t, MetaConjunct c) { + public MetaClause makeMetaClause(Tree t, Conjunct c) { //System.err.println("MetaClause.makeMetaClause("+t+")"); - if (t==null) return new MetaEpsilon(); - if (t.head()==null) return new MetaEpsilon(); + if (t==null) return new Epsilon(); + if (t.head()==null) return new Epsilon(); if (t.head().equals("{")) throw new Error("metatree: " + t); if (t.head().equals("*")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, true, true); if (t.head().equals("+")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, false, true); @@ -264,15 +276,15 @@ public class MetaGrammar extends StringWalker { if (t.head().equals("+/")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, makeMetaClause(t.child(1), c), false, true); if (t.head().equals("**/")) return new MetaRepeat(makeMetaClause(t.child(0), c), true, makeMetaClause(t.child(1), c), true, true); if (t.head().equals("++/")) return new MetaRepeat(makeMetaClause(t.child(0), c), true, makeMetaClause(t.child(1), c), false, true); - if (t.head().equals("()")) return new MetaEpsilon(); + if (t.head().equals("()")) return new Epsilon(); if (t.head().equals("[")) return new MetaRange(t.child(0)); - if (t.head().equals("literal")) return new MetaStringLiteral(t.child(0)); - if (t.head().equals("nonTerminal")) return new MetaNonterminalReference(t.child(0)); - if (t.head().equals(")")) return new MetaSelfReference(); - if (t.head().equals("(")) return new MetaParens(t.child(0)); + if (t.head().equals("literal")) return new StringLiteral(t.child(0)); + if (t.head().equals("nonTerminal")) return new NonTerminalReference(t.child(0)); + if (t.head().equals(")")) return new SelfReference(); + if (t.head().equals("(")) return new Parens(t.child(0)); if (t.head().equals("~")) return new MetaInvert(t.child(0), c); if (t.head().equals("!")) { MetaClause mc = makeMetaClause(t.child(0), c); mc.drop = true; return mc; } - if (t.head().equals("^")) { c.tag = string(t.child(0)); return new MetaStringLiteral(t.child(0)); } + if (t.head().equals("^")) { c.tag = string(t.child(0)); return new StringLiteral(t.child(0)); } if (t.head().equals("^^")) throw new Error("carets: " + t); if (t.head().equals(":")) { String name = string(t.child(0)); @@ -315,20 +327,20 @@ public class MetaGrammar extends StringWalker { (separator==null?"":(" /"+separator)); } } - public class MetaEpsilon extends MetaClause { + public class Epsilon extends MetaClause { public String toString() { return "()"; } public Element build(BuildContext bc) { return Union.epsilon; } } - public class MetaParens extends MetaClause { + public class Parens extends MetaClause { public MetaUnion body; - public MetaParens(Tree t) { this.body = rhs(t); } + public Parens(Tree t) { this.body = rhs(t); } public String toString() { return "( " + body + " )"; } public Element build(BuildContext bc) { return body.buildAnon(bc); } } /* public static class MetaTree extends MetaClause { - public MetaConjunct body; - public MetaTree(Tree t) { this.body = makeMetaConjunct(t); } + public Conjunct body; + public MetaTree(Tree t) { this.body = makeConjunct(t); } public String toString() { return "{ " + body + " }"; } public Element build(BuildContext bc) { return new Union("{}");// body.buildSequence(); @@ -350,25 +362,25 @@ public class MetaGrammar extends StringWalker { } } } - public class MetaStringLiteral extends MetaClause { + public class StringLiteral extends MetaClause { public String literal; public Element build(BuildContext bc) { return string(literal); } - public MetaStringLiteral(Tree literal) { this.literal = string(literal); this.drop = true; } + public StringLiteral(Tree literal) { this.literal = string(literal); this.drop = true; } public String toString() { return "\""+StringUtil.escapify(literal, "\"\r\n\\")+"\""; } } - public class MetaNonterminalReference extends MetaClause { + public class NonTerminalReference extends MetaClause { public String name; - public MetaNonterminalReference(Tree name) { this.name = string(name); } + public NonTerminalReference(Tree name) { this.name = string(name); } public Element build(BuildContext bc) { return bc.build(name); } public String toString() { return name; } } - public class MetaSelfReference extends MetaClause { + public class SelfReference extends MetaClause { public String toString() { return "(*)"; } public Element build(BuildContext bc) { return new Union("(*)"); /* FIXME */ } } public class MetaInvert extends MetaClause { public MetaClause element; - public MetaInvert(Tree t, MetaConjunct c) { this.element = makeMetaClause(t, c); } + public MetaInvert(Tree t, Conjunct c) { this.element = makeMetaClause(t, c); } public String toString() { return "~"+element; } public Element build(BuildContext bc) { return infer((Topology)Atom.toAtom(element.build(bc)).complement()); } } -- 1.7.10.4