X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2FParser.java;h=f2bb701710bc40901be1ed9275586dd194ae51c2;hp=9db0bf95b61e642415f48595e0ca8f39807433ba;hb=a2008a0c57702f49ed7f8be682e4e29484fded38;hpb=3ee451bce342d4bb61ad6235ba57bdf817bfdd1a diff --git a/src/edu/berkeley/sbp/Parser.java b/src/edu/berkeley/sbp/Parser.java index 9db0bf9..f2bb701 100644 --- a/src/edu/berkeley/sbp/Parser.java +++ b/src/edu/berkeley/sbp/Parser.java @@ -25,11 +25,11 @@ public abstract class Parser { /** parse input, and return the shared packed parse forest (or throw an exception) */ public Forest parse(Input input) throws IOException, ParseFailed { - GSS gss = new GSS(); + GSS gss = new GSS(input); Input.Location loc = input.getLocation(); Token tok = input.next(); - GSS.Phase current = gss.new Phase(null, this, null, tok, loc, input.getLocation(), null); - current.newNode(null, Forest.create(loc.createRegion(loc), null, null, false), pt.start, true); + GSS.Phase current = gss.new Phase(null, null, tok, loc, input.getLocation(), null); + current.newNode(new Result(Forest.create(loc.createRegion(loc), null, null, false), null, null), pt.start, true); int count = 1; for(int idx=0;;idx++) { Input.Location oldloc = loc; @@ -37,13 +37,13 @@ public abstract class Parser { Forest forest = current.token==null ? null : shiftToken((Token)current.token, loc); loc = input.getLocation(); Token nextToken = input.next(); - GSS.Phase next = gss.new Phase(current, this, current, nextToken, loc, input.getLocation(), forest); + GSS.Phase next = gss.new Phase(current, current, nextToken, loc, input.getLocation(), forest); if (!helpgc) { FileOutputStream fos = new FileOutputStream("out-"+idx+".dot"); PrintWriter p = new PrintWriter(new OutputStreamWriter(fos)); GraphViz gv = new GraphViz(); for(Object n : next) - ((GSS.Phase.Node)n).toGraphViz(gv); + ((Node)n).toGraphViz(gv); gv.dump(p); p.flush(); p.close(); @@ -106,6 +106,7 @@ public abstract class Parser { /** used to generate unique values for State.idx */ private int master_state_idx = 0; HashMap,State> all_states = new HashMap,State>(); + HashSet all_elements = new HashSet(); /** construct a parse table for the given grammar */ public Table(Topology top) { this("s", top); } @@ -118,15 +119,16 @@ public abstract class Parser { cache.eof.put(start0, true); // construct the set of states - HashSet all_elements = new HashSet(); walk(start0, all_elements); for(SequenceOrElement e : all_elements) cache.ys.addAll(e, new Walk.YieldSet(e, cache).walk()); + for(SequenceOrElement e : all_elements) + cache.ys2.addAll(e, new Walk.YieldSet2(e, cache).walk()); HashSet hp = new HashSet(); reachable(start0, hp); - this.dead_state = new State(new HashSet(), all_states, all_elements); - this.start = new State(hp, all_states, all_elements); + this.dead_state = new State(new HashSet()); + this.start = new State(hp); // for each state, fill in the corresponding "row" of the parse table for(State state : all_states.values()) @@ -139,8 +141,13 @@ public abstract class Parser { if (isRightNullable(p)) { Walk.Follow wf = new Walk.Follow(top.empty(), p.owner(), all_elements, cache); Topology follow = wf.walk(p.owner()); - for(Position p2 = p; p2 != null && p2.element() != null; p2 = p2.next()) + for(Position p2 = p; p2 != null && p2.element() != null; p2 = p2.next()) { + Atom set = new Walk.EpsilonFollowSet(new edu.berkeley.sbp.chr.CharAtom(top.empty().complement()), + new edu.berkeley.sbp.chr.CharAtom(top.empty()), + cache).walk(p2.element()); follow = follow.intersect(new Walk.Follow(top.empty(), p2.element(), all_elements, cache).walk(p2.element())); + if (set != null) follow = follow.intersect(set.getTokenTopology()); + } state.reductions.put(follow, p); if (wf.includesEof()) state.eofReductions.add(p); } @@ -165,10 +172,11 @@ public abstract class Parser { /** a single state in the LR table and the transitions possible from it */ - class State implements Comparable>, IntegerMappable, Iterable { + class State implements IntegerMappable, Iterable { public final int idx = master_state_idx++; private final HashSet hs; + public HashSet> also = new HashSet>(); public transient HashMap> gotoSetNonTerminals = new HashMap>(); private transient TopologicalBag> gotoSetTerminals = new TopologicalBag>(); @@ -202,7 +210,6 @@ public abstract class Parser { /** * create a new state consisting of all the Positions in hs * @param hs the set of Positions comprising this State - * @param all_states the set of states already constructed (to avoid recreating states) * @param all_elements the set of all elements (Atom instances need not be included) * * In principle these two steps could be merged, but they @@ -221,14 +228,31 @@ public abstract class Parser { * for non-Atom Elements. * */ - public State(HashSet hs, - HashMap,State> all_states, - HashSet all_elements) { + public State(HashSet hs) { this(hs, false); } + public boolean special; + public State(HashSet hs, boolean special) { this.hs = hs; + this.special = special; // 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); + ((HashMap)all_states).put(hs, this); + + for(Position p : hs) { + if (!p.isFirst()) continue; + for(Sequence s : p.owner().needs()) { + if (hs.contains(s.firstp())) continue; + HashSet h2 = new HashSet(); + reachable(s.firstp(), h2); + also.add((State)(all_states.get(h2) == null ? (State)new State(h2,true) : (State)all_states.get(h2))); + } + for(Sequence s : p.owner().hates()) { + if (hs.contains(s.firstp())) continue; + HashSet h2 = new HashSet(); + reachable(s, h2); + also.add((State)(all_states.get(h2) == null ? (State)new State(h2,true) : (State)all_states.get(h2))); + } + } // 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 @@ -251,7 +275,8 @@ public abstract class Parser { for(Topology r : bag0) { HashSet h = new HashSet(); for(Position p : bag0.getAll(r)) h.add(p); - gotoSetTerminals.put(r, all_states.get(h) == null ? new State(h, all_states, all_elements) : all_states.get(h)); + ((TopologicalBag)gotoSetTerminals).put(r, all_states.get(h) == null + ? new State(h) : all_states.get(h)); } // Step 2: for every non-Atom element (ie every Element which has a corresponding reduction), @@ -266,7 +291,8 @@ public abstract class Parser { for(Position p : hs) { Element e = p.element(); if (e==null) continue; - for(SequenceOrElement y : cache.ys.getAll(e)) { + for(SequenceOrElement y : cache.ys2.getAll(e)) { + //System.out.println(e + " yields " + y); HashSet hp = new HashSet(); reachable(p.next(), hp); move.addAll(y, hp); @@ -274,7 +300,7 @@ public abstract class Parser { } OUTER: for(SequenceOrElement y : move) { HashSet h = move.getAll(y); - State s = all_states.get(h) == null ? new State(h, all_states, all_elements) : all_states.get(h); + State s = all_states.get(h) == null ? (State)new State(h) : (State)all_states.get(h); // if a reduction is "lame", it should wind up in the dead_state after reducing if (y instanceof Sequence) { for(Position p : hs) { @@ -308,7 +334,7 @@ public abstract class Parser { return ret.toString(); } - public int compareTo(State s) { return idx==s.idx ? 0 : idx < s.idx ? -1 : 1; } + public Walk.Cache cache() { return cache; } public int toInt() { return idx; } } } @@ -317,8 +343,8 @@ public abstract class Parser { private static void reachable(Sequence s, HashSet h) { reachable(s.firstp(), h); - for(Sequence ss : s.needs()) reachable(ss, h); - for(Sequence ss : s.hates()) reachable(ss, h); + //for(Sequence ss : s.needs()) reachable(ss, h); + //for(Sequence ss : s.hates()) reachable(ss, h); } private static void reachable(Element e, HashSet h) { if (e instanceof Atom) return;