X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2FParser.java;h=18bec5a0aebfa2c5179116f1c92617f1162dd04b;hp=95c3985aa49bb2a65adaf5b4a243de8b6b711d1c;hb=21da21b94e794fa4d7c7207327764895d92ea528;hpb=3eb9fa560dee4f8c3b3af0460ff850d755676d81;ds=sidebyside diff --git a/src/edu/berkeley/sbp/Parser.java b/src/edu/berkeley/sbp/Parser.java index 95c3985..18bec5a 100644 --- a/src/edu/berkeley/sbp/Parser.java +++ b/src/edu/berkeley/sbp/Parser.java @@ -1,39 +1,27 @@ package edu.berkeley.sbp; import edu.berkeley.sbp.*; import edu.berkeley.sbp.util.*; -import edu.berkeley.sbp.*; import edu.berkeley.sbp.Sequence.Position; -import edu.berkeley.sbp.*; import java.io.*; import java.util.*; -import java.lang.reflect.*; /** a parser which translates streams of Tokens of type T into a Forest */ public abstract class Parser { - public final Table pt; + private final Table pt; /** create a parser to parse the grammar with start symbol u */ protected Parser(Union u) { this.pt = new Table(u, top()); } protected Parser(Table pt) { this.pt = pt; } + /** implement this method to create the output forest corresponding to a lone shifted input token */ public abstract Forest shiftedToken(T t, Token.Location loc); - public abstract Topology top(); - - /** parse input for a exactly one unique result, throwing Ambiguous if not unique or Failed if none */ - public Tree parse1(Token.Stream input) throws IOException, Failed, Ambiguous { - Forest ret = parse(input); - try { return ret.expand1(); } - catch (Ambiguous a) { - System.out.println("while expanding:"); - System.out.println(ret); - throw a; - } - } + /** this method must return an empty topology of the input token type */ + public abstract Topology top(); /** parse input, using the table pt to drive the parser */ - public Forest parse(Token.Stream input) throws IOException, Failed { + public Forest parse(Token.Stream input) throws IOException, ParseFailed { GSS gss = new GSS(); Token.Location loc = input.getLocation(); GSS.Phase current = gss.new Phase(null, this, null, input.next(1, 0, 0), loc, null); @@ -41,7 +29,6 @@ public abstract class Parser { int count = 1; for(;;) { loc = input.getLocation(); - //current.checkFailure(); current.reduce(); Forest forest = current.token==null ? null : shiftedToken((T)current.token, loc); GSS.Phase next = gss.new Phase(current, this, current, input.next(count, gss.resets, gss.waits), loc, forest); @@ -50,31 +37,6 @@ public abstract class Parser { current = next; } } - - - // Exceptions ////////////////////////////////////////////////////////////////////////////// - - 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 static class Ambiguous extends RuntimeException { - public final Forest ambiguity; - public Ambiguous(Forest ambiguity) { this.ambiguity = ambiguity; } - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("unresolved ambiguity "/*"at " + ambiguity.getLocation() + ":"*/); - for(Object result : ambiguity.expand(false)) - sb.append("\n " + result); - return sb.toString(); - } - } - // Table ////////////////////////////////////////////////////////////////////////////// @@ -83,8 +45,6 @@ public abstract class Parser { public final Walk.Cache cache = this; - public HashMapBag byPosition = new HashMapBag(); - private void walk(Element e, HashSet hs) { if (e==null) return; if (hs.contains(e)) return; @@ -118,7 +78,7 @@ public abstract class Parser { HashSet all_elements = new HashSet(); walk(start0, all_elements); for(Element e : all_elements) - cache.ys.put(e, new Walk.YieldSet(e, cache).walk()); + cache.ys.addAll(e, new Walk.YieldSet(e, cache).walk()); HashSet hp = new HashSet(); reachable(start0, hp); this.start = new State(hp, all_states, all_elements); @@ -131,7 +91,7 @@ public abstract class Parser { if (start0.contains(p.owner()) && p.next()==null) state.accept = true; - if (p.isRightNullable(cache)) { + if (isRightNullable(p)) { Walk.Follow wf = new Walk.Follow(top.empty(), p.owner(), all_elements, cache); Reduction red = new Reduction(p); @@ -161,11 +121,25 @@ public abstract class Parser { } } + private boolean isRightNullable(Position p) { + if (p.isLast()) return true; + if (!p.element().possiblyEpsilon(this)) return false; + return isRightNullable(p.next()); + } + /** a single state in the LR table and the transitions possible from it */ - public class State implements Comparable, Iterable, IntegerMappable { + + public class State implements Comparable, IntegerMappable, Iterable { public int toInt() { return idx; } + public boolean lame() { + for(Position p : this) + for(Position p2 = p; p2!=null; p2=p2.next()) + if (p2.isLast() && !p2.owner().lame) + return false; + return true; + } /* public boolean isResolvable(Token t) { boolean found = false; @@ -250,7 +224,6 @@ 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 @@ -283,27 +256,14 @@ public abstract class Parser { // "yields" [in one or more step] is used instead of "produces" [in exactly one step] // to avoid having to iteratively construct our set of States as shown in most // expositions of the algorithm (ie "keep doing XYZ until things stop changing"). - /* - for(Element e : all_elements) { - if (e instanceof Atom) continue; - HashSet h = new Walk.Closure(null, g.cache).closure(e, hs); - State s = all_states.get(h) == null ? new State(h, all_states, all_elements) : all_states.get(h); - if (gotoSetNonTerminals.get(e) != null) - throw new Error("this should not happen"); - gotoSetNonTerminals.put(e, s); - } - */ HashMapBag move = new HashMapBag(); for(Position p : hs) { Element e = p.element(); if (e==null) continue; - HashSet ys = cache.ys.get(e); - if (ys != null) { - for(Element y : ys) { - HashSet hp = new HashSet(); - reachable(p.next(), hp); - move.addAll(y, hp); - } + for(Element y : cache.ys.getAll(e)) { + HashSet hp = new HashSet(); + reachable(p.next(), hp); + move.addAll(y, hp); } } for(Element y : move) { @@ -313,7 +273,13 @@ public abstract class Parser { } } - public String toString() { return "state["+idx+"]"; } + public String toString() { + //return "state["+idx+"]"; + StringBuffer ret = new StringBuffer(); + ret.append("state["+idx+"]: "); + for(Position p : this) ret.append("{"+p+"} "); + return ret.toString(); + } public int compareTo(Table.State s) { return idx==s.idx ? 0 : idx < s.idx ? -1 : 1; } }