X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fmeta%2FMetaGrammarBindings.java;fp=src%2Fedu%2Fberkeley%2Fsbp%2Fmeta%2FMetaGrammarBindings.java;h=0000000000000000000000000000000000000000;hp=927cd6248b6aba71085ae5a27ccb9a0a57ed9ebf;hb=7dd51387ce4308d3784a1291604203aaf677ba16;hpb=9d727bd14c659cdc6c34153b988e8d3fdb8067f5 diff --git a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java deleted file mode 100644 index 927cd62..0000000 --- a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java +++ /dev/null @@ -1,514 +0,0 @@ -// Copyright 2006 all rights reserved; see LICENSE file for BSD-style license - -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.*; - -/** The java classes typically used to represent a parsed grammar AST; each inner class is a type of AST node. */ -public class MetaGrammarBindings extends AnnotationGrammarBindings { - - public MetaGrammarBindings() { super(MetaGrammarBindings.class); } - - // FIXME ugly ugly ugly scary dangerous - public static String prefix = ""; - - /** A grammar (a set of nonterminals) */ - public static class GrammarNode extends HashMap { - 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 GrammarNode) add(((GrammarNode)o).getNonTerminals()); - } - } - public String toString() { - String ret = "[ "; - for(NonTerminalNode nt : values()) ret += nt + ", "; - return ret + " ]"; - } - public Union build(String s, Grammar.Bindings 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 Atom toAtom(Context cx) { - Atom ret = null; - for(Seq[] ss : sequences) - for(Seq s : ss) - ret = ret==null ? s.toAtom(cx) : (Atom)ret.union(s.toAtom(cx)); - return ret; - } - public void build(Context cx, Union u, NonTerminalNode cnt) { - HashSet bad2 = new HashSet(); - for(int i=0; i red = (TreeFunctor)t.head(); - String oldprefix = prefix; - prefix = as; - GrammarNode gn = (GrammarNode)red.invoke(t); - prefix = oldprefix; - return gn; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static class NonTerminalNode extends UnionNode { - 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) { - this.name = prefix + name; - this.sequences = sequences; - this.rep = rep; - this.sep = sep==null?null:(prefix + sep); - } - public Element build(Context cx, NonTerminalNode cnt) { return cx.get(name); } - public void build(Context cx, Union u, NonTerminalNode cnt) { - if (!rep) { super.build(cx, u, this); return; } - HashSet bad2 = new HashSet(); - - Union urep = new Union(null, false); - urep.add(Sequence.create()); - if (sep != null) - urep.add(Sequence.create(new Element[] { cx.get(sep), u }, 1)); - else - urep.add(Sequence.create(new Element[] { u }, 0)); - - for(int i=0; i and = new HashSet(); - HashSet not = new HashSet(); - ElementNode[] elements; - ElementNode follow; - String tag = null; - public void append(ElementNode e) { - ElementNode[] elements = new ElementNode[this.elements.length+1]; - System.arraycopy(this.elements, 0, elements, 0, this.elements.length); - this.elements = elements; - elements[elements.length-1] = e; - } - public Seq(ElementNode e) { this(new ElementNode[] { e }); } - public Seq(ElementNode[] elements) { this.elements = elements; } - public Atom toAtom(Context cx) { - if (elements.length != 1) throw new Error("you attempted to use ->, **, ++, or a similar character-class operator on a [potentially] multicharacter production"); - return elements[0].toAtom(cx); - } - public Seq tag(String tag) { this.tag = prefix+tag; return this; } - public Seq follow(ElementNode 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 = prefix+tag; - return ret; - } - public Seq and(Seq s) { and.add(s); return this; } - public Seq andnot(Seq s) { not.add(s); return this; } - public Seq separate(ElementNode sep) { - ElementNode[] elements = new ElementNode[this.elements.length * 2 - 1]; - for(int i=0; i") Seq arrow(Seq s, ElementNode 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, ElementNode e) { return s.separate(e); } - - public static Seq seq(ElementNode[] elements) { return new Seq(elements); } - public static @bind.as("Elements") Seq seq2(ElementNode[] elements) { return new Seq(elements); } - public static @bind.as Seq psx(Seq s) { return s; } - public static @bind.as(":") ElementNode colon(String s, ElementNode e) { return new Label(s, e); } - public static @bind.as(")") void close(String foo) { throw new Error("not supported"); } - public static @bind.as("()") ElementNode epsilon() { return new Constant(epsilon); } - - private static Union epsilon = new Union("()"); - static { epsilon.add(Sequence.create()); } - - public static class NonTerminalReferenceNode extends ElementNode { - public String nonTerminal; - public NonTerminalReferenceNode() { } - public @bind.as("NonTerminalReference") NonTerminalReferenceNode(String nonTerminal) { - this.nonTerminal = prefix + nonTerminal; - } - public Atom toAtom(Context cx) { - return cx.grammar.get(nonTerminal).toAtom(cx); - } - public Element build(Context cx, NonTerminalNode cnt) { - if (!this.nonTerminal.startsWith(prefix)) nonTerminal = prefix + nonTerminal; - Element ret = cx.get(nonTerminal); - if (ret == null) throw new RuntimeException("unknown nonterminal \""+nonTerminal+"\""); - return ret; - } - } - - public static class Literal extends Constant { - private String string; - public @bind Literal(@bind.arg String string) { - super(CharAtom.string(string)); - this.string = string; - } - public boolean drop() { return true; } - public Atom toAtom(Context cx) { - if (string.length()!=1) return super.toAtom(cx); - edu.berkeley.sbp.util.Range.Set set = new edu.berkeley.sbp.util.Range.Set(); - set.add(string.charAt(0), string.charAt(0)); - return CharAtom.set(set); - } - } - - public static class CharClass extends ElementNode { - Range[] ranges; - public @bind.as("[") CharClass(Range[] ranges) { this.ranges = ranges; } - public Atom toAtom(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 CharAtom.set(set); - } - public Element build(Context cx, NonTerminalNode cnt) { - 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 CharAtom.set(set); - } - } - - public static @bind.as("\\{") ElementNode leftBrace() { - return new Drop(new CharClass(new Range[] { new Range(CharAtom.left, CharAtom.left) })); } - public static @bind.as("\\}") ElementNode rightBrace() { - return new Drop(new CharClass(new Range[] { new Range(CharAtom.right, CharAtom.right) })); } - - public static @bind.as("{") class XTree extends ElementNode { - public @bind.arg Seq body; - public Element build(Context cx, NonTerminalNode cnt) { - Union u = new Union(null, false); - Sequence s = body.build(cx, u, null); - Union u2 = new Union(null, false); - u2.add(Sequence.create(new Element[] { - CharAtom.leftBrace, - cx.get("ws"), - u, - cx.get("ws"), - CharAtom.rightBrace - }, 2)); - return u2; - } - } - - public static class Rep extends ElementNode { - public ElementNode e, sep; - public boolean zero, many, max; - public Rep(ElementNode e, ElementNode sep, boolean zero, boolean many, boolean max) { - this.e = e; this.sep = sep; this.zero = zero; this.many = many; this.max = max;} - public Atom toAtom(Context cx) { - if (sep != null) return super.toAtom(cx); - return e.toAtom(cx); - } - public Element build(Context cx, NonTerminalNode cnt) { - return (!max) - ? Repeat.repeat(e.build(cx, null), zero, many, sep==null ? null : sep.build(cx, null), cx.rm.repeatTag()) - : sep==null - ? Repeat.repeatMaximal(e.toAtom(cx), zero, many, cx.rm.repeatTag()) - : Repeat.repeatMaximal(e.build(cx, null), zero, many, sep.toAtom(cx), cx.rm.repeatTag()); - } - } - - // FIXME: it would be nice if we could hoist this into "Rep" - public static @bind.as("++") ElementNode plusmax(final ElementNode e) - { return new Rep(e, null, false, true, true); } - public static @bind.as("+") ElementNode plus(final ElementNode e) - { return new Rep(e, null, false, true, false); } - public static @bind.as("++/") ElementNode plusmaxfollow(final ElementNode e, final ElementNode sep) - { return new Rep(e, sep, false, true, true); } - public static @bind.as("+/") ElementNode plusfollow(final ElementNode e, final ElementNode sep) - { return new Rep(e, sep, false, true, false); } - public static @bind.as("**") ElementNode starmax(final ElementNode e) - { return new Rep(e, null, true, true, true); } - public static @bind.as("*") ElementNode star(final ElementNode e) - { return new Rep(e, null, true, true, false); } - public static @bind.as("**/") ElementNode starmaxfollow(final ElementNode e, final ElementNode sep) - { return new Rep(e, sep, true, true, true); } - public static @bind.as("*/") ElementNode starfollow(final ElementNode e, final ElementNode sep) - { return new Rep(e, sep, true, true, false); } - public static @bind.as("?") ElementNode question(final ElementNode e) - { return new Rep(e, null, true, true, false); } - public static @bind.as("!") ElementNode bang(final ElementNode e) - { return new Drop(e); } - - public static @bind.as("^") ElementNode caret(final String s) { - final String thePrefix = prefix; - return new Constant(CharAtom.string(s)) { - public String getOwnerTag() { return thePrefix+s; } - public boolean drop() { return true; } - }; - } - - public static @bind.as("~") ElementNode tilde(final ElementNode e) { - return new ElementNodeWrapper(e) { - public Atom toAtom(Context cx) { - return infer((Topology)e.toAtom(cx).complement()/*.minus(CharAtom.braces)*/); - } - public Element build(Context cx, NonTerminalNode cnt) { - return infer((Topology)e.toAtom(cx).complement()/*.minus(CharAtom.braces)*/); - } }; } - - 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) { - if (c=='{') return CharAtom.left+""; - if (c=='}') return CharAtom.right+""; - return c+""; - } - public static @bind.as("EmptyString") 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(Object t) { return (Atom)t; } - - public static class Context { - public HashMap map = new HashMap(); - public GrammarNode grammar; - public String cnt = null; - public Grammar.Bindings rm; - public Context(GrammarNode g, Grammar.Bindings 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, Grammar.Bindings rm) { - this.rm = rm; - TreeFunctor red = (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) { - throw new Error("warning could not find " + name); - } else { - String old = cnt; - cnt = name; - nt.build(this, ret, nt); - cnt = old; - } - return ret; - } - - } - - public static abstract class ElementNode { - public String getLabel() { return null; } - public String getOwnerTag() { return null; } - public boolean drop() { return false; } - public Atom toAtom(Context cx) { throw new Error("can't convert a " + this.getClass().getName() + " to an atom"); } - public abstract Element build(Context cx, NonTerminalNode cnt); - } - - public static abstract class ElementNodeWrapper extends ElementNode { - protected ElementNode _e; - public ElementNodeWrapper(ElementNode e) { this._e = e; } - public String getLabel() { return _e.getLabel(); } - public String getOwnerTag() { return _e.getOwnerTag(); } - public boolean drop() { return _e.drop(); } - public Atom toAtom(Context cx) { return _e.toAtom(cx); } - public Element build(Context cx, NonTerminalNode cnt) { return _e.build(cx, cnt); } - } - - public static class Constant extends ElementNode { - Element constant; - public Constant(Element constant) { this.constant = constant; } - public Element build(Context cx, NonTerminalNode cnt) { return constant; } - public Atom toAtom(Context cx) { - if (constant instanceof Atom) return ((Atom)constant); - return super.toAtom(cx); - } - } - - public abstract static class PostProcess extends ElementNodeWrapper { - public PostProcess(ElementNode e) { super(e); } - public Element build(Context cx, NonTerminalNode cnt) { return postProcess(_e.build(cx, cnt)); } - public abstract Element postProcess(Element e); - } - - public static class Drop extends ElementNodeWrapper { - public Drop(ElementNode e) { super(e); } - public boolean drop() { return true; } - } - - public static class Label extends ElementNodeWrapper { - public String label; - public Label(String label, ElementNode e) { super(e); this.label = label; } - public String getLabel() { return label; } - } - - /* - static class Invert extends Atom { - private final Atom a; - public Invert(Atom a) { this.a = a; } - public Topology top() { return a.complement(); } - public String toString() { return "~"+a; } - } - */ -}