X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Fedu%2Fberkeley%2Fsbp%2FParser.java;h=c270a90b3d434bf88ecb49ad39814ba1f7547503;hb=526da96dd06e152d194ec92c9ef9df6085a1251b;hp=4244d21717cf8ac37cd029b502c0c05844f938d4;hpb=f33c05adc5aa3dd324c5352cdbd6f4b55359acad;p=sbp.git diff --git a/src/edu/berkeley/sbp/Parser.java b/src/edu/berkeley/sbp/Parser.java index 4244d21..c270a90 100644 --- a/src/edu/berkeley/sbp/Parser.java +++ b/src/edu/berkeley/sbp/Parser.java @@ -11,7 +11,7 @@ import java.lang.reflect.*; /** a parser which translates streams of Tokens of type T into a Forest */ public abstract class Parser { - private final Table pt; + public final Table pt; /** create a parser to parse the grammar with start symbol u */ protected Parser(Union u) { this.pt = new Table(u, top()); } @@ -36,16 +36,17 @@ public abstract class Parser { public Forest parse(Token.Stream input) throws IOException, Failed { GSS gss = new GSS(); Token.Location loc = input.getLocation(); - GSS.Phase current = gss.new Phase(null, input.next(), loc); - current.newNode(null, null, pt.start, true); + GSS.Phase current = gss.new Phase(null, this, null, input.next(1, 0, 0), loc, null); + current.newNode(null, Forest.leaf(null, null, null), pt.start, true); + int count = 1; for(;;) { loc = input.getLocation(); - GSS.Phase next = gss.new Phase(current, input.next(), loc); + //current.checkFailure(); current.reduce(); Forest forest = current.token==null ? null : shiftedToken((T)current.token, loc); - current.shift(next, forest); + GSS.Phase next = gss.new Phase(current, this, current, input.next(count, gss.resets, gss.waits), loc, forest); + count = next.hash.size(); if (current.isDone()) return (Forest)current.finalResult; - current.checkFailure(); current = next; } } @@ -53,13 +54,13 @@ public abstract class Parser { // Exceptions ////////////////////////////////////////////////////////////////////////////// - public static class Failed extends Exception { + public static class Failed extends RuntimeException { private final Token.Location location; private final String message; public Failed() { this("", null); } public Failed(String message, Token.Location loc) { this.location = loc; this.message = message; } public Token.Location getLocation() { return location; } - public String toString() { return message + (location==null ? "" : (" at " + location)); } + public String toString() { return message/* + (location==null ? "" : (" at " + location))*/; } } public static class Ambiguous extends RuntimeException { @@ -81,6 +82,8 @@ public abstract class Parser { static class Table extends Walk.Cache { public final Walk.Cache cache = this; + + public HashMapBag byPosition = new HashMapBag(); private void walk(Element e, HashSet hs) { if (e==null) return; @@ -128,12 +131,22 @@ public abstract class Parser { if (start0.contains(p.owner()) && p.next()==null) state.accept = true; - // FIXME: how does right-nullability interact with follow restrictions? - // all right-nullable rules get a reduction [Johnstone 2000] if (p.isRightNullable(cache)) { Walk.Follow wf = new Walk.Follow(top.empty(), p.owner(), all_elements, cache); Reduction red = new Reduction(p); - state.reductions.put(wf.walk(p.owner()), red); + + Topology follow = wf.walk(p.owner()); + if (p.owner() instanceof Sequence.RewritingSequence && + (((Sequence.RewritingSequence)p.owner()).tag+"").equals("emailaddr")) { + System.out.println("follow before: " + new edu.berkeley.sbp.misc.CharToken.CharRange(follow)); + } + for(Position p2 = p; p2 != null && p2.element() != null; p2 = p2.next()) + follow = follow.intersect(new Walk.Follow(top.empty(), p2.element(), all_elements, cache).walk(p2.element())); + if (p.owner() instanceof Sequence.RewritingSequence && + (((Sequence.RewritingSequence)p.owner()).tag+"").equals("emailaddr")) { + System.out.println("follow after: " + new edu.berkeley.sbp.misc.CharToken.CharRange(follow)); + } + state.reductions.put(follow, red); if (wf.includesEof()) state.eofReductions.add(red); } @@ -235,6 +248,7 @@ public abstract class Parser { // register ourselves in the all_states hash so that no // two states are ever created with an identical position set all_states.put(hs, this); + for(Position p : hs) byPosition.add(p,this); // Step 1a: examine all Position's in this state and compute the mappings from // sets of follow tokens (tokens which could follow this position) to sets @@ -368,8 +382,9 @@ public abstract class Parser { } private void finish(GSS.Phase.Node parent, Forest result, GSS.Phase target) { State state = parent.state.gotoSetNonTerminals.get(position.owner()); + if (result==null) throw new Error(); if (state!=null) - target.newNode(parent, result, state, numPop<=0); + target.newNode(parent, result, state, numPop<=0, this); } } }