public Forest.Ref finalResult;
/** all nodes, keyed by the value returned by code() */
- /*private*/ HashMap<Long,Phase.Node> hash; /* ALLOC */
+ /*private*/ IntPairMap<Phase.Node> hash; /* ALLOC */
/** the number of nodes in this phase */
private int numNodes;
tail.clear();
waiting.clear();
performed.clear();
- hash = new HashMap<Long,Phase.Node>();
+ hash = new IntPairMap<Phase.Node>();
good = false;
closed = false;
numNodes = 0;
ret.append("\n ");
ret.append(message);
HashMap<String,HashSet<String>> errors = new HashMap<String,HashSet<String>>();
- for(Node n : hash.values()) complain(n, errors, false);
+ for(Node n : hash.values()) {
+ //System.out.println(n.state);
+ complain(n, errors, false);
+ }
for(String s : errors.keySet()) {
ret.append(" while parsing " + yellow(s));
HashSet<String> hs = errors.get(s);
return ret.toString();
}
- public boolean isDone() throws Parser.Failed {
+ public boolean isDone() throws ParseFailed {
if (token != null) return false;
if (token==null && finalResult==null)
- throw new Parser.Failed(error(red("unexpected end of file\n")),
+ throw new ParseFailed(error(red("unexpected end of file\n")),
getLocation());
return true;
}
* @param start the earliest part of the input contributing to this node (used to make merging decisions)
*/
public boolean newNode(Node parent, Forest pending, State state, boolean fromEmptyReduction) {
- Node p = hash.get(code(state, parent==null?null:parent.phase()));
+ Node p = hash.get(state, parent==null?null:parent.phase());
if (p != null) return newNode2(p, parent, pending, state, fromEmptyReduction);
else return newNode3(parent, pending, state, fromEmptyReduction);
}
reducing = true;
if (reducing_list==null || reducing_list.length < hash.size())
reducing_list = new Phase.Node[hash.size() * 4];
- Collection<Node> hv = hash.values();
- hv.toArray(reducing_list);
- int num = hv.size();
+ hash.toArray(reducing_list);
+ int num = hash.size();
for(int i=0; i<num; i++) {
Node n = reducing_list[i];
n.queueEmptyReductions();
}
/** perform all shift operations, adding promoted nodes to <tt>next</tt> */
- public void shift(Phase next, Forest result) throws Parser.Failed {
+ public void shift(Phase next, Forest result) throws ParseFailed {
if (prev!=null) prev.hash = null;
this.next = next;
closed = true;
}
if (!good && token!=null)
- throw new Parser.Failed(error(red("unexpected character")+" "+purple(token)+" encountered at "+green(getLocation())+"\n"),
+ throw new ParseFailed(error(red("unexpected character")+" "+purple(token)+" encountered at "+green(getLocation())+"\n"),
getLocation());
if (token==null && finalResult==null)
- throw new Parser.Failed(error(red("unexpected end of file\n")),
+ throw new ParseFailed(error(red("unexpected end of file\n")),
getLocation());
// this massively improves GC performance
this.holder().merge(pending);
Phase start = parent==null ? null : parent.phase();
if (parent != null) parents().add(parent, true);
- if (Phase.this.hash.get(code(state, start)) != null) throw new Error("severe problem!");
- Phase.this.hash.put(code(state, start), this);
+ if (Phase.this.hash.get(state, start) != null) throw new Error("severe problem!");
+ Phase.this.hash.put(state, start, this);
Phase.this.numNodes++;
}
}
if (a==null || b==null) return false;
return a.equals(b);
}
-
- /** this is something of a hack right now */
- private static long code(State state, Phase start) {
- return (((long)state.idx) << 32) | (start==null ? 0 : (start.pos+1));
- }
}