public abstract static class UnionNode extends ElementNode {
public Seq[][] sequences;
- public void build(Context cx, Union u) {
+ public void build(Context cx, Union u, NonTerminalNode cnt) {
HashSet<Sequence> bad2 = new HashSet<Sequence>();
for(int i=0; i<sequences.length; i++) {
Seq[] group = sequences[i];
Union u2 = new Union();
if (sequences.length==1) u2 = u;
for(int j=0; j<group.length; j++) {
- group[j].build(cx, u2, false);
+ group[j].build(cx, u2, false, cnt);
}
if (sequences.length==1) break;
Sequence seq = Sequence.singleton(u2);
this.rep = rep;
this.sep = sep;
}
- public Element build(Context cx) { return cx.get(name); }
- public void build(Context cx, Union u) {
- if (!rep) { super.build(cx, u); return; }
+ 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<Sequence> bad2 = new HashSet<Sequence>();
Union urep = new Union();
if (sequences.length==1) u2 = u;
for(int j=0; j<group.length; j++) {
Union u3 = new Union();
- group[j].build(cx, u3, false);
+ group[j].build(cx, u3, false, this);
Sequence s = Sequence.unwrap(new Element[] { u3, urep },
cx.rm.repeatTag(),
new boolean[] { false, false });
public @bind.as("(") AnonUnionNode(Seq[][] sequences) {
this.sequences = sequences;
}
- public Element build(Context cx) {
+ public Element build(Context cx, NonTerminalNode cnt) {
Union ret = new Union();
- build(cx, ret);
+ build(cx, ret, cnt);
return ret;
}
}
public String getLabel() { return null; }
public String getOwnerTag() { return null; }
public boolean drop() { return false; }
- public abstract Element build(Context cx);
+ public abstract Element build(Context cx, NonTerminalNode cnt);
}
public static class Drop extends ElementNode {
public String getLabel() { return null; }
public boolean drop() { return true; }
public String getOwnerTag() { return e.getOwnerTag(); }
- public Element build(Context cx) { return e.build(cx); }
+ public Element build(Context cx, NonTerminalNode cnt) { return e.build(cx, cnt); }
}
public static class Label extends ElementNode {
public Label(String label, ElementNode e) { this.e = e; this.label = label; }
public String getLabel() { return label; }
public String getOwnerTag() { return e.getOwnerTag(); }
- public Element build(Context cx) { return e.build(cx); }
+ public Element build(Context cx, NonTerminalNode cnt) { return e.build(cx, cnt); }
}
public static /*abstract*/ class Seq {
this.elements = elements;
return this;
}
- public Sequence build(Context cx, Union u, boolean lame) {
- Sequence ret = build0(cx, lame || this.lame);
- for(Seq s : and) { Sequence dork = s.build(cx, u, true); ret = ret.and(dork); }
- for(Seq s : not) { Sequence dork = s.build(cx, u, true); ret = ret.not(dork); }
+ public Sequence build(Context cx, Union u, boolean lame, NonTerminalNode cnt) {
+ Sequence ret = build0(cx, lame || this.lame, cnt);
+ for(Seq s : and) { Sequence dork = s.build(cx, u, true, cnt); ret = ret.and(dork); }
+ for(Seq s : not) { Sequence dork = s.build(cx, u, true, cnt); ret = ret.not(dork); }
u.add(ret);
ret.lame = lame;
return ret;
}
- public Sequence build0(Context cx, boolean lame) {
+ public Sequence build0(Context cx, boolean lame, NonTerminalNode cnt) {
boolean dropAll = lame;
if (tag!=null && "()".equals(tag)) dropAll = true;
- Object[] labels = new Object[elements.length];
boolean[] drops = new boolean[elements.length];
Element[] els = new Element[elements.length];
for(int i=0; i<elements.length; i++) {
- labels[i] = elements[i].getLabel();
drops[i] = elements[i].drop();
- els[i] = elements[i].build(cx);
+ els[i] = elements[i].build(cx, cnt);
if (elements[i].getOwnerTag() != null)
tag = elements[i].getOwnerTag();
}
Sequence ret = null;
if (dropAll) ret = Sequence.drop(els, false);
else {
- ret = cx.rm.tryResolveTag(tag, cx.cnt, els, labels, drops);
+ ret = cx.rm.tryResolveTag(tag, cnt==null?null:cnt.name, els, drops);
if (ret == null) {
int idx = -1;
for(int i=0; i<els.length; i++)
}
}
if (this.follow != null)
- ret.follow = infer(this.follow.build(cx));
+ ret.follow = infer(this.follow.build(cx, null));
ret.lame = this.lame;
return ret;
}
public static @bind.as("NonTerminalReference") class NonTerminalReferenceNode extends ElementNode {
public @bind.arg String nonTerminal;
- public Element build(Context cx) { return cx.get(nonTerminal); }
+ public Element build(Context cx, NonTerminalNode cnt) {
+ Element ret = cx.get(nonTerminal);
+ if (ret == null) throw new RuntimeException("unkown nonterminal \""+nonTerminal+"\"");
+ return ret;
+ }
}
public static class Literal extends Constant {
public static class CharClass extends ElementNode {
Range[] ranges;
public @bind.as("[") CharClass(Range[] ranges) { this.ranges = ranges; }
- public Element build(Context cx) {
+ 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);
public static @bind.as("{") class XTree extends ElementNode {
public @bind.arg Seq body;
- public Element build(Context cx) {
+ public Element build(Context cx, NonTerminalNode cnt) {
Union u = new Union();
- Sequence s = body.build(cx, u, false);
+ Sequence s = body.build(cx, u, false, null);
Union u2 = new Union();
u2.add(Sequence.singleton(new Element[] {
CharRange.leftBrace,
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 Element build(Context cx) {
+ public Element build(Context cx, NonTerminalNode cnt) {
return (!max)
- ? Sequence.repeat(e.build(cx), zero, many, sep==null ? null : sep.build(cx), cx.rm.repeatTag())
+ ? Sequence.repeat(e.build(cx, null), zero, many, sep==null ? null : sep.build(cx, null), 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());
+ ? Sequence.repeatMaximal(infer(e.build(cx, null)), zero, many, cx.rm.repeatTag())
+ : Sequence.repeatMaximal(e.build(cx, null), zero, many, infer(sep.build(cx, null)), cx.rm.repeatTag());
}
}
public static class Constant extends ElementNode {
Element constant;
public Constant(Element constant) { this.constant = constant; }
- public Element build(Context cx) { return constant; }
+ public Element build(Context cx, NonTerminalNode cnt) { return constant; }
}
public abstract static class PostProcess extends ElementNode {
ElementNode e;
public PostProcess(ElementNode e) { this.e = e; }
- public Element build(Context cx) { return postProcess(e.build(cx)); }
+ public Element build(Context cx, NonTerminalNode cnt) { return postProcess(e.build(cx, cnt)); }
public abstract Element postProcess(Element e);
}
} else {
String old = cnt;
cnt = name;
- nt.build(this, ret);
+ nt.build(this, ret, nt);
cnt = old;
}
return ret;