- public abstract Forest<Result> shiftToken(Tok t, Token.Location loc);
-
- /** parse <tt>input</tt>, using the table <tt>pt</tt> to drive the parser */
- public Forest<Result> parse(Token.Stream<Tok> input) throws IOException, ParseFailed {
- GSS gss = new GSS();
- Token.Location loc = input.getLocation();
- GSS.Phase current = gss.new Phase<Tok>(null, this, null, input.next(1, 0, 0), loc, null);
- current.newNode(null, Forest.leaf(null, null), pt.start, true);
- int count = 1;
- for(;;) {
- loc = input.getLocation();
- current.reduce();
- Forest forest = current.token==null ? null : shiftToken((Tok)current.token, loc);
- GSS.Phase next = gss.new Phase<Tok>(current, this, current, input.next(count, gss.resets, gss.waits), loc, forest);
- count = next.size();
- if (current.isDone()) return (Forest<Result>)gss.finalResult;
- current = next;
+ public abstract Forest<NodeType> shiftToken(Token t, Input.Region region);
+
+ public abstract Topology<Token> emptyTopology();
+
+ public String toString() { return pt.toString(); }
+
+ /** parse <tt>input</tt>, and return the shared packed parse forest (or throw an exception) */
+ public Forest<NodeType> parse(Input<Token> input) throws IOException, ParseFailed {
+ verbose = System.getProperty("sbp.verbose", null) != null;
+ spinpos = 0;
+ GSS gss = new GSS(input, this);
+ try {
+ for(GSS.Phase current = gss.new Phase<Token>(pt.start); ;) {
+ if (verbose) debug(current.token, gss, input);
+ if (current.isDone()) return (Forest<NodeType>)current.finalResult;
+ Input.Region region = current.getLocation().createRegion(current.getNextLocation());
+ Forest forest = shiftToken((Token)current.token, region);
+ current = gss.new Phase<Token>(current, forest);
+ }
+ } finally {
+ if (verbose) {
+ System.err.print("\r"+ANSI.clreol());
+ debug(null, gss, input);
+ }
+ }
+ }
+
+ // Spinner //////////////////////////////////////////////////////////////////////////////
+
+ private boolean verbose = false;
+ private static final char[] spin = new char[] { '-', '\\', '|', '/' };
+ private int spinpos = 0;
+ private long last = 0;
+ void spin() {
+ if (!verbose) return;
+ long now = System.currentTimeMillis();
+ if (now-last < 70) return;
+ last = now;
+ System.err.print("\r " + spin[spinpos++ % (spin.length)]+"\r");
+ }
+
+ private int _last = -1;
+ private String buf = "";
+ private void debug(Object t, GSS gss, Input input) {
+ //FIXME
+ int c = t==null ? -1 : ((t+"").charAt(0));
+ int last = _last;
+ _last = c;
+ switch(c) {
+ case edu.berkeley.sbp.chr.CharAtom.left:
+ buf += "\033[31m>\033[0m";
+ break;
+ case edu.berkeley.sbp.chr.CharAtom.right:
+ buf += "\033[31m<\033[0m";
+ break;
+ case -1: // FIXME
+ case '\n':
+ if (verbose) {
+ if (last==' ') buf += ANSI.blue("\\n");
+ System.err.println("\r"+ANSI.clreol()+"\r"+buf);
+ buf = "";
+ }
+ break;
+ default:
+ buf += ANSI.cyan(""+((char)c));
+ break;