public class MetaGrammar extends StringWalker {
- public static Object repeatTag = null;
-
public static Union make() throws Exception { return make(MetaGrammarTree.meta, "s"); }
public static Union make(Tree<String> tree, String nt) throws Exception {
Meta.MetaGrammarFile mgf = new Meta().new MetaGrammarFile(tree);
private static Element set(Range.Set r) { return CharRange.set(r); }
private static Element string(String s) { return CharRange.string(s); }
- private static Atom infer(Element e) { return infer((Topology<Character>)Atom.toAtom(e)); }
- private static Atom infer(Topology<Character> t) { return new CharRange(new CharTopology(t)); }
+ /*private*/ static Atom infer(Element e) { return infer((Topology<Character>)Atom.toAtom(e)); }
+ /*private*/ static Atom infer(Topology<Character> t) { return new CharRange(new CharTopology(t)); }
private MetaGrammar() { }
}
public static class Meta {
+ public Object repeatTag() { return null; }
+ public Sequence tryResolveTag(String s, String nonTerminalName, Element[] els, Object[] labels, boolean [] drops) {
+ //return resolveTag(s, nonTerminalName, els, labels, drops);
+ return null;
+ }
public Sequence resolveTag(String s, String nonTerminalName, Element[] els, Object[] labels, boolean [] drops) {
return Sequence.rewritingSequence(s, els, labels, drops);
}
boolean dropAll = false;
if (tag!=null && tag.equals("[]")) unwrap = true;
if (tag!=null && "()".equals(tag)) dropAll=true;
+
+ NonTerminal old = bc.currentNonTerminal;
+ bc.currentNonTerminal = null;
for(int i=0; i<elements.length; i++) {
int j = separator==null ? i : i*2;
els[j] = elements[i].build(bc);
drops[j+1] = true;
}
}
+ bc.currentNonTerminal = old;
+
Sequence ret = null;
if (dropAll) ret = Sequence.drop(els, false);
- else if (unwrap) ret = Sequence.unwrap(els, /*repeatTag FIXME*/null, drops);
+ else if (unwrap) ret = Sequence.unwrap(els, repeatTag(), drops);
else if (tag!=null) {
ret = resolveTag(tag, bc.currentNonTerminal==null ? null : bc.currentNonTerminal.name, els, labels, drops);
+ System.err.println("resolvetag " + tag + " => " + ret);
} else {
- int idx = -1;
- for(int i=0; i<els.length; i++)
- if (!drops[i])
- if (idx==-1) idx = i;
- else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(els,false));
- if (idx != -1) ret = Sequence.singleton(els, idx);
- else ret = Sequence.drop(els, false);
+ ret = tryResolveTag(tag, bc.currentNonTerminal==null ? null : bc.currentNonTerminal.name, els, labels, drops);
+ if (ret==null) {
+ int idx = -1;
+ for(int i=0; i<els.length; i++)
+ if (!drops[i])
+ if (idx==-1) idx = i;
+ else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(els,false));
+ if (idx != -1) ret = Sequence.singleton(els, idx);
+ else ret = Sequence.drop(els, false);
+ }
}
if (this.followedBy != null)
ret.follow = infer(this.followedBy.build(bc));
//System.err.println("MetaClause.makeMetaClause("+t+")");
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 MetaTree(makeConjunct(t.child(0)));
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);
if (t.head().equals("?")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, true, false);
public Element build(BuildContext bc) {
return !maximal
? (separator==null
- ? Sequence.repeat(element.build(bc), zero, many, null, null)
- : Sequence.repeat(element.build(bc), zero, many, separator.build(bc), null))
+ ? Sequence.repeat(element.build(bc), zero, many, null, repeatTag())
+ : Sequence.repeat(element.build(bc), zero, many, separator.build(bc), repeatTag()))
: (separator==null
- ? Sequence.repeatMaximal(infer(element.build(bc)), zero, many, null)
- : Sequence.repeatMaximal(element.build(bc), zero, many, infer(separator.build(bc)), null));
+ ? Sequence.repeatMaximal(infer(element.build(bc)), zero, many, repeatTag())
+ : Sequence.repeatMaximal(element.build(bc), zero, many, infer(separator.build(bc)), repeatTag()));
}
public MetaRepeat(MetaClause element, boolean maximal, MetaClause separator, boolean zero, boolean many) {
this.separator = separator;
public String toString() { return "( " + body + " )"; }
public Element build(BuildContext bc) { return body.buildAnon(bc); }
}
- /*
- public static class MetaTree extends MetaClause {
+
+ public class MetaTree extends MetaClause {
public Conjunct body;
- public MetaTree(Tree<String> t) { this.body = makeConjunct(t); }
+ public MetaTree(Conjunct c) { this.body = c; }
public String toString() { return "{ " + body + " }"; }
public Element build(BuildContext bc) {
- return new Union("{}");// body.buildSequence();
+ Union u = new Union();
+ Union u2 = new Union();
+ Sequence seq = body.buildSequence(bc);
+ u2.add(seq);
+ u.add(Sequence.singleton(new Element[] { CharRange.leftBrace,
+ new NonTerminalReference("ws").build(bc),
+ u2,
+ new NonTerminalReference("ws").build(bc),
+ CharRange.rightBrace }
+ , 2));
+ //u.add(seq);
+ return u;
}
}
- */
+
public class MetaRange extends MetaClause {
Range.Set range = new Range.Set();
public String toString() { return range.toString(); }
public class NonTerminalReference extends MetaClause {
public String name;
public NonTerminalReference(Tree<String> name) { this.name = string(name); }
+ public NonTerminalReference(String name) { this.name = name; }
public Element build(BuildContext bc) { return bc.build(name); }
public String toString() { return name; }
}
public MetaClause element;
public MetaInvert(Tree<String> t, Conjunct c) { this.element = makeMetaClause(t, c); }
public String toString() { return "~"+element; }
- public Element build(BuildContext bc) { return infer((Topology<Character>)Atom.toAtom(element.build(bc)).complement()); }
+ public Element build(BuildContext bc) {
+ return infer((Topology<Character>)Atom.toAtom(element.build(bc)).complement().minus(CharRange.braces));
+ }
}
}