Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
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]);
Tree t = new CharParser(meta).parse(new FileInputStream(s[1])).expand1();
- System.out.println("tree:\n" + t.toPrettyString());
-
- Reducer red = (Reducer)t.head();
- MG.Grammar g = (MG.Grammar)red.reduce(t);
- System.out.println(g);
-
- Context cx = new Context(g,m);
- Element u = null;
- for(MG.NonTerminal nt : g.nonterminals) {
- 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;
- }
- System.err.println();
+ Union u = Demo.make(t, "s");
+
+ System.err.println();
System.err.println("== parsing with parsed grammar =================================================================================");
t = new CharParser((Union)u).parse(new FileInputStream(s[1])).expand1();
System.out.println(t.toPrettyString());
System.out.println(t.toPrettyString());
}
+ 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;
MG.Seq.class,
MG.NonTerminalReference.class,
MG.StringLiteral.class,
- MG.Tree.class,
+ MG.XTree.class,
MG.CharClass.class
});
}
return false;
}
public Object repeatTag() {
- return new Reducer() {
- public String toString() { return "[**]"; }
- public Object reduce(Tree t) {
- Object[] ret = new Object[t.numChildren()];
- for(int i=0; i<t.numChildren(); i++) {
- Tree tc = t.child(i);
- if (tc.head() != null && tc.head() instanceof Reducer)
- ret[i] = ((Reducer)tc.head()).reduce(tc);
- else if (tc.numChildren() == 0)
- ret[i] = tc.head();
- else {
- System.err.println("FIXME: don't know what to do about " + tc);
- ret[i] = null;
- }
- }
- return ret;
- }
- };
+ return new Tree.ArrayBuildingTreeFunctor<Object>();
}
public Sequence tryResolveTag(String tag, String nonTerminalName, Element[] els, Object[] labels, boolean[] drops) {
Production p = new Production(tag, nonTerminalName, els, labels, drops);
*/
@Retention(RetentionPolicy.RUNTIME) public static @interface nonterminal { String value() default ""; }
+ @Retention(RetentionPolicy.RUNTIME) public static @interface raw { }
+
/**
* Constructors, classes, and methods with this attribute will
* match every tree tagged with "value()" that is arg-compatible.
tag t = getTag();
if (t != null &&
(t.value().equals(p.tag) ||
- (t.value().equals("") && p.tag.equals(getName()))))
+ (t.value().equals("") && getName().equals(p.tag))))
return buildSequence(p)!=null;
nonterminal n = getNonTerminal();
if (n != null &&
(n.value().equals(p.nonTerminal) ||
- (n.value().equals("") && p.nonTerminal.equals(getName()))))
+ (n.value().equals("") && getName().equals(p.nonTerminal))))
return buildSequence(p)!=null;
return false;
}
}
public Sequence makeSequence(Production p) {
- return Sequence.rewritingSequence(new TargetReducer(p), p.elements, p.labels, p.drops);
+ return Sequence.rewritingSequence(new TargetReducer(p, buildSequence(p), "reducer-"+this), p.elements, p.labels, p.drops);
}
public abstract Object plant(Object[] fields, int[] map);
- public class TargetReducer implements Reducer {
+ public boolean isRaw() { return false; }
+ public Object invokeRaw(Iterable<Tree> t) { return null; }
+ public class TargetReducer implements Functor<Iterable<Tree>,Object> {
private Production p;
private int[] map;
- public TargetReducer(Production p) {
+ private String name;
+ public TargetReducer(Production p, int[] map, String name) {
this.p = p;
- this.map = buildSequence(p);
+ this.map = map;
+ this.name = name;
}
- public String toString() { return "reducer-"+Target.this; }
- public Object reduce(Tree t) {
- Object[] objects = new Object[t.numChildren()];
- for(int i=0; i<t.numChildren(); i++) {
- Tree tc = t.child(i);
- if (tc.head() != null && tc.head() instanceof Reducer)
- objects[i] = ((Reducer)tc.head()).reduce(tc);
+ public String toString() { return name; }
+ public Object invoke(Iterable<Tree> t) {
+ if (isRaw()) return invokeRaw(t);
+ ArrayList ret = new ArrayList();
+ for(Tree tc : t) {
+ if (tc.head() != null && tc.head() instanceof Functor)
+ ret.add(((Functor<Iterable<Tree>,Object>)tc.head()).invoke(tc.children()));
else if (tc.numChildren() == 0)
- objects[i] = tc.head();
+ ret.add(tc.head());
else {
System.err.println("FIXME: don't know what to do about " + tc);
- objects[i] = null;
+ ret.add(null);
}
}
System.err.println("input tree: " + t);
- return plant(objects, map);
+ return plant(ret.toArray(new Object[0]), map);
}
}
}
- public static interface Reducer {
- public Object reduce(Tree t);
- }
-
public static class TargetClass extends Target {
public final Class _class;
public TargetClass(Class _class) { this._class = _class; }
int[] ret = buildSequence(p, names, argtags);
return ret;
}
+ public boolean isRaw() { return _method.isAnnotationPresent(raw.class); }
+ public Object invokeRaw(Iterable<Tree> t) {
+ try {
+ return _method.invoke(null, new Object[] { t });
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
public Object plant(Object[] fields, int[] map) {
try {
Class[] argTypes = _method.getParameterTypes();
if (c == char.class) {
return o.toString().charAt(0);
}
+
+ if (o.getClass().isArray() &&
+ o.getClass().getComponentType().isArray() &&
+ o.getClass().getComponentType().getComponentType() == String.class &&
+ c.isArray() &&
+ c.getComponentType() == String.class) {
+ String[] ret = new String[((Object[])o).length];
+ for(int i=0; i<ret.length; i++) {
+ StringBuffer sb = new StringBuffer();
+ for(Object ob : (Object[])(((Object[])o)[i]))
+ sb.append(ob);
+ ret[i] = sb.toString();
+ }
+ return ret;
+ }
+
if (c.isArray() && (c.getComponentType().isInstance(o))) {
Object[] ret = (Object[])Array.newInstance(c.getComponentType(), 1);
ret[0] = o;
return ret;
}
+
if (o.getClass().isArray() && c.isArray()) {
boolean ok = true;
for(int i=0; i<((Object[])o).length; i++) {
return o;
}
+ public static Union cached = null;
+ public static Union make() {
+ if (cached != null) return cached;
+ try {
+ ReflectiveMeta m = new ReflectiveMeta();
+ Tree<String> 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);
+ Union meta = mgf.get("s").build(bc);
+ Tree t = new CharParser(meta).parse(new FileInputStream("tests/meta.g")).expand1();
+ return cached = make(t, "s");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public static Union make(Tree t, String s) { return make(t, s, new ReflectiveMeta()); }
+ public static Union make(Tree t, String s, ReflectiveMeta rm) {
+ Functor<Iterable<Tree>,Object> red = (Functor<Iterable<Tree>,Object>)t.head();
+ MG.Grammar g = (MG.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);
+ 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;
+ }
+
public static class MG {
public static @tag("grammar") class Grammar {
public NonTerminal get(String s) {
return cx.get(nonTerminal);
}
}
+
public static class StringLiteral extends Constant {
public @tag("literal") StringLiteral(String string) { super(CharRange.string(string)); }
public boolean drop() { return true; }
}
+
public static class CharClass extends El {
Range[] ranges;
public @tag("[") CharClass(Range[] ranges) { this.ranges = ranges; }
}
}
- public static @tag("{") class Tree extends El {
+ public static @tag("{") class XTree extends El {
public @arg Seq body;
public Element build(Context cx) {
throw new Error();
}
public Context(Tree t, ReflectiveMeta rm) {
this.rm = rm;
- Reducer red = (Reducer)t.head();
- this.grammar = (MG.Grammar)red.reduce(t);
+ Functor<Iterable<Tree>,Object> red = (Functor<Iterable<Tree>,Object>)t.head();
+ this.grammar = (MG.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); }