public int resets = 0;
public int waits = 0;
- HashMapBag<Integer,Sequence> inhibited = new HashMapBag<Integer,Sequence>();
- HashMapBag<Sequence,Phase.Waiting> waiting = new HashMapBag<Sequence,Phase.Waiting>();
- HashMapBag<Integer,Sequence> performed = new HashMapBag<Integer,Sequence>();
+ HashMapBag<Integer,Sequence> inhibited = new HashMapBag<Integer,Sequence>();
+ HashMapBag<Integer,Sequence> expectedInhibit = new HashMapBag<Integer,Sequence>();
+ HashMapBag<Sequence,Phase.Waiting> waiting = new HashMapBag<Sequence,Phase.Waiting>();
+ HashMapBag<Integer,Sequence> performed = new HashMapBag<Integer,Sequence>();
/** FIXME */
public Forest.Ref finalResult;
boolean reducing;
private IntPairMap<Phase.Node> hash; /* ALLOC */
+ private IntPairMap<Forest> singularReductions; /* ALLOC */
private boolean closed;
private boolean good;
private Phase next = null;
private Phase prev;
- private Token.Location location;
+ private Input.Location location;
public final Parser parser;
private Forest forest;
- public Phase(Phase prev, Parser parser, Phase previous, Tok token, Token.Location location, Forest forest) {
+ public Phase(Phase prev, Parser parser, Phase previous, Tok token, Input.Location location, Forest forest) {
this.prev = prev;
this.forest = forest;
this.parser = parser;
waiting.clear();
performed.clear();
hash = new IntPairMap<Phase.Node>();
+ singularReductions = new IntPairMap<Forest>();
+ expectedInhibit.clear();
+ expectedInhibit.addAll(inhibited);
good = false;
closed = false;
reducing = false;
return true;
}
- public Token.Location getLocation() { return location; }
+ public Input.Location getLocation() { return location; }
/** add a new node (merging with existing nodes if possible)
* @param parent the parent of the new node
throw new Reset();
}
inhibited.add(p, seq);
+ expectedInhibit.remove(p, seq);
}
}
reducing_list[i] = null;
n.performReductions();
}
+ if (expectedInhibit.size() > 0) {
+ inhibited.removeAll(expectedInhibit);
+ System.out.println("\n!!!!\n");
+ throw new Reset();
+ }
} catch (Reset r) {
reset();
reduce();
/** perform all shift operations, adding promoted nodes to <tt>next</tt> */
public void shift(Phase next, Forest result) throws ParseFailed {
// this massively improves GC performance
- if (prev!=null) prev.hash = null;
+ if (prev!=null) {
+ prev.hash = null;
+ prev.singularReductions = null;
+ }
this.next = next;
closed = true;
Forest res = null;
// Node /////////////////////////////////////////////////////////////////////////////////
/** a node in the GSS */
- public final class Node extends FastSet<Node> implements Invokable<Position, Node, Node> {
+ public final class Node extends FastSet<Node> implements Invokable<Position, Node, Node>, IntegerMappable {
private Forest.Ref holder = null;
private boolean allqueued = false;
holder[pos] = n.pending();
if (pos==0) {
System.arraycopy(holder, 0, r.holder, 0, holder.length);
- Forest rex = r.rewrite(n.phase().getLocation());
+ Forest rex = null;
+ if (r.pos==1) rex = singularReductions.get(this, r);
+ if (rex==null) {
+ rex = r.rewrite(n.phase().getLocation());
+ if (r.pos==1) singularReductions.put(this, r, rex);
+ }
n2.finish(r, rex, n.phase(), holder);
} else {
n2.reduce(r, pos-1, n.phase(), holder);
if (pos==0) {
System.arraycopy(holder, 0, r.holder, 0, holder.length);
for(int i=0; i<r.pos; i++) if (r.holder[i]==null) throw new Error("realbad");
- Forest rex = r.rewrite(target.getLocation());
+ Forest rex = null;
+ if (r.pos==1) rex = singularReductions.get(this, r);
+ if (rex==null) {
+ rex = r.rewrite(phase().getLocation());
+ if (r.pos==1) singularReductions.put(this, r, rex);
+ }
for(Node child : this.parents()) child.finish(r, rex, target, holder);
} else {
for(Node child : this.parents()) child.reduce(r, pos-1, target, holder);
if (Phase.this.hash.get(state, start) != null) throw new Error("severe problem!");
Phase.this.hash.put(state, start, this);
}
+ public int toInt() { return idx; }
+ private final int idx = node_idx++;
}
+ private int node_idx = 0;
public int toInt() { return pos+1; }
public int size() { return hash==null ? 0 : hash.size(); }