-
- Node n = new Node(Phase.this, parent, pending, state); // ALLOC
- if (reducing) {
- n.performEmptyReductions();
- if (!fromEmptyReduction) n.performReductions(parent);
- }
- return true;
- }
-
- public LinkedList<Node> reductionQueue = new LinkedList<Node>();
-
- /** perform all reduction operations */
- public void reduce() throws ParseFailed {
- try {
- reducing = true;
- if (reducing_list==null || reducing_list.length < hash.size())
- reducing_list = new Node[hash.size() * 4];
- hash.toArray(reducing_list);
- int num = hash.size();
- for(int i=0; i<num; i++) {
- Node n = reducing_list[i];
- n.performEmptyReductions();
- // INVARIANT: we never "see" a node until its parent-set is complete, modulo merges
- }
- for(int i=0; i<num; i++) {
- reductionQueue.add(reducing_list[i]);
- reducing_list[i] = null;
- }
- while(!reductionQueue.isEmpty()) {
- reductionQueue.remove().performReductions();
- }
- if (reset) {
- reset = false;
- resets++;
- throw new Reset();
- }
- for(int i : expected)
- for(Sequence s : expected.getAll(i))
- if (!performed.contains(i, s)) {
- //System.out.println("resetting due to pos="+i+": " + s + " " + System.identityHashCode(s));
- resets++;
- throw new Reset();
- }
- } catch (Reset r) {
- reset();
- reduce();
- }
- count = 0;
- }
-
- private boolean reset = false;
- class Reset extends RuntimeException { }
-
- /** 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 && parser.helpgc) {
- //prev.hash = null;
- //System.out.println("\r" + /*shifts + " " + */ single_newnode /*+ "/"+multi_newnode + " " + waiting_newnode*/);
- //System.out.println("\r" + shifts + " " + note);
- //System.out.println("\r" + shifts);
- //System.out.println("\r" + toplevel_reductions);
- //System.out.println("\r" + multi_newnode);
- single_newnode = 0;
- note = "";
- multi_newnode = 0;
- toplevel_reductions = 0;
- waiting_newnode = 0;
- shifts = 0;
- }
- this.next = next;
- closed = true;
- Forest res = null;
- boolean ok = false;
- int count = 0;
- for(Node n : hash.values()) {
- if (token == null && n.state().isAccepting()) {
- if (finalResult==null) finalResult = new Forest.Many();
- for(Object f : n.results())
- finalResult.merge((Forest)f);
- }
- if (token == null) continue;
- n.state().invokeShifts(token, this, result, n);
- }
- //System.out.println(next.hash.size());
- if (!good && token!=null)
- ParseFailed.error("unexpected character",
- getLocation(),
- token,
- hash.values(),
- getRegion(),
- input,
- GSS.this);
-
- if (token==null && finalResult==null)
- ParseFailed.error("unexpected end of file",
- getLocation(),
- token,
- hash.values(),
- getLocation().createRegion(getLocation()),
- input,
- GSS.this);
+ StateNode n = new StateNode(Phase.this, f, reduction, pred, state, fromEmptyReduction); // ALLOC
+ /** FIXME: this null-result can be used to notice bogus/dead states */
+ for(Object s : state.conjunctStates)
+ newNode(null, null, n, (State)s, fromEmptyReduction);
+ return !n.state().doomed();