public class MetaGrammar extends StringWalker {
+ boolean forceDrop = false;
+
public static class Hack<T extends Input> extends Atom<T> {
private final Atom<T> a;
static final Topology leftright = CharRange.rightBrace.union(CharRange.leftBrace);
public Union getNonTerminal(String str) { return nonTerminal(str, null, false, false); }
private Union nonTerminal(String str) { return nonTerminal(str, null, false, false); }
- public Union anonymousNonTerminal(PreSequence[][] s) {
+ public Union anonymousNonTerminal(Sequence[][] s) {
return nonTerminal("anon"+(anon++), s, false, false);
}
- private Union nonTerminal(String str, PreSequence[][] s, boolean synthetic, boolean dropAll) {
+ private Union nonTerminal(String str, Sequence[][] s, boolean synthetic, boolean dropAll) {
Union n = str.equals(startSymbol) ? g : nt.get(str);
if (n == null) nt.put(str, n = new Union(str, synthetic));
if (dropAll) this.dropAll.add(n);
for(int i=0; i<s.length; i++) {
if (s[i]==null) continue;
HashSet<Sequence> temp = new HashSet<Sequence>();
- for(PreSequence pre : s[i]) {
- pre.not.addAll(seqs);
- Sequence seq = pre.buildSequence(n, false, dropAll);
- temp.add(seq);
- n.add(seq);
+ for(Sequence pre : s[i]) {
+ for(Sequence sn : seqs) pre = pre.not(sn);
+ temp.add(pre);
+ n.add(pre);
}
seqs.addAll(temp);
}
+ //StringBuffer sb = new StringBuffer();
+ //n.toString(sb);
+ //System.out.println(sb);
return n;
}
else if ("epsilon".equals(head)) return Union.epsilon;
else if ("()".equals(head)) return Union.epsilon;
else if (")".equals(head)) return SELF;
- else if ("psx".equals(head)) return walk(tree, 0);
+ else if ("psx".equals(head)) return ((PreSequence)walk(tree, 0)).buildSequence();
else if ("nonTerminal".equals(head)) return getNonTerminal(string(tree.child(0)));
- else if ("::=".equals(head)) return nonTerminal(string(tree.child(0)), (PreSequence[][])walk(tree, 1), false, false);
- else if ("!::=".equals(head)) return nonTerminal(string(tree.child(0)), (PreSequence[][])walk(tree, 1), false, true);
- else if ("(".equals(head)) return buildUnion((PreSequence[][])walk(tree, 0));
+ else if ("::=".equals(head)) {
+ forceDrop = false;
+ return nonTerminal(string(tree.child(0)), (Sequence[][])walk(tree, 1), false, false);
+ }
+ else if ("!::=".equals(head)) {
+ forceDrop = true;
+ Object ret = nonTerminal(string(tree.child(0)), (Sequence[][])walk(tree, 1), false, true);
+ forceDrop = false;
+ return ret;
+ }
+ else if ("(".equals(head)) return buildUnion((Sequence[][])walk(tree, 0));
else if ("literal".equals(head)) { Element ret = string(string(tree.child(0))); dropAll.add(ret); return ret; }
else if ("-".equals(head)) return new Range(walk(tree, 0).toString().charAt(0), walk(tree,1).toString().charAt(0));
else if ("range".equals(head)) return new Range(walk(tree, 0).toString().charAt(0), walk(tree,0).toString().charAt(0));
return super.walk(tag, argo);
}
- public Union buildUnion(PreSequence[][] p) {
+ public Union buildUnion(Sequence[][] p) {
return anonymousNonTerminal(p);
}
}
public Union buildUnion() { return buildUnion("???"); }
public boolean unwrap = false;
+ public Sequence buildSequence() { return buildSequence(null, false, forceDrop); }
public Sequence buildSequence(Union u) { return buildSequence(u, false, false); }
public Sequence buildSequence(Union u, boolean lame, boolean dropAll) {
- for(Sequence s : and) u.add(s);
- for(Sequence s : not) u.add(s);
+ if (u!=null) {
+ for(Sequence s : and) u.add(s);
+ for(Sequence s : not) u.add(s);
+ }
HashSet<Sequence> set = new HashSet<Sequence>();
Element[] o2 = o==null ? new Element[0] : new Element[o.length];
int nonDrop = 0;