_____________________________________________________________________________
Immediately
- - Sequence shouldn't be an Element
+ - Sequence shouldn't be an Element -> make Union.add(Element)
- Should Tree<T> really be type-parameterized?
- More topology untangling
/** if ambiguity checking is enabled, this exception is thrown to signal that the parse was ambiguous */
public class Ambiguous extends Exception {
- public final Forest<?> ambiguity;
+ final Forest<?> ambiguity;
private final HashSet<Tree<?>> ht;
- public Ambiguous(Forest<?> ambiguity, HashSet<Tree<?>> ht) {
+ Ambiguous(Forest<?> ambiguity, HashSet<Tree<?>> ht) {
this.ambiguity = ambiguity;
this.ht = ht;
}
+
+ public Forest<?> getAmbiguity() { return ambiguity; }
+
public String toString() {
// FIXME: print the input region that was ambiguously matched
StringBuffer sb = new StringBuffer();
private final Input.Location location;
private final String message;
- public ParseFailed() { this("", null); }
- public ParseFailed(String message, Input.Location loc) { this.location = loc; this.message = message; }
+ ParseFailed() { this("", null); }
+ ParseFailed(String message, Input.Location loc) { this.location = loc; this.message = message; }
public Input.Location getLocation() { return location; }
public String toString() { return message/* + (location==null ? "" : (" at " + location))*/; }
// FIXME
private static HashSet<GSS.Phase.Node> touched = new HashSet<GSS.Phase.Node>();
- public static <Tok> void complain(GSS.Phase<Tok>.Node n, HashMap<String,HashSet<String>> errors, boolean force) {
+ static <Tok> void complain(GSS.Phase<Tok>.Node n, HashMap<String,HashSet<String>> errors, boolean force) {
if (touched.contains(n)) return;
touched.add(n);
for(Position p : n.state) {
}
}
- public static String el(Object e) {
+ static String el(Object e) {
String s = e.toString();
if (s.length()==0 || s.charAt(0)!='\"' || s.charAt(s.length()-1)!='\"') return /*ANSI.yellow(s)*/s;
s = s.substring(1);
}
return /*ANSI.purple(ret.toString())*/ret.toString();
}
- public static String error(String message, Object token, Iterable<Node> nodes) {
+ static String error(String message, Object token, Iterable<Node> nodes) {
String lookAhead = token==null ? "<EOF>" : token.toString();
StringBuffer ret = new StringBuffer();
ret.append("\n ");
public String toString() { return pt.toString(); }
- /** parse <tt>input</tt>, using the table <tt>pt</tt> to drive the parser */
+ /** parse <tt>input</tt>, and return the shared packed parse forest (or throw an exception) */
public Forest<Result> parse(Input<Tok> input) throws IOException, ParseFailed {
GSS gss = new GSS();
Input.Location loc = input.getLocation();
final Position firstp;
- public Atom follow = null;
- public final Atom follow() { return follow; }
+ Atom follow = null;
// Static Constructors //////////////////////////////////////////////////////////////////////////////
public Sequence and(Sequence s) { Sequence ret = dup(); ret.needs.add(s); return ret; }
public Sequence not(Sequence s) { Sequence ret = dup(); ret.hates.add(s); s.hated.add(ret); return ret; }
+ public Sequence followedBy(Atom a) { Sequence ret = dup(); ret.follow = a; return ret; }
public Iterable<Sequence> needs() { return needs; }
public Iterable<Sequence> hates() { return hates; }
// Position //////////////////////////////////////////////////////////////////////////////
/** the imaginary position before or after an element of a sequence; corresponds to an "LR item" */
- public class Position implements IntegerMappable {
+ class Position implements IntegerMappable {
private Forest zero = null;
public Forest zero() {
import java.lang.reflect.*;
import java.lang.ref.*;
-/** <font color=green>an element which can produce one of several alternatives</font> */
+/**
+ * <font color=green>an element which can produce one of several alternatives</font>.
+ * <p>
+ *
+ * Unlike the other Elements, Union is not immutable once
+ * constructed. To simulate this desirable feature, it is immutable
+ * <i>once examined</i> by taking its iterator or calling contains().
+ */
public class Union extends Element implements Iterable<Sequence> {
private final String name;
private final boolean synthetic;
+ private boolean viewed = false;
private final List<Sequence> alternatives = new ArrayList<Sequence>();
this.synthetic = synthetic;
}
- public boolean contains(Sequence s) { return alternatives.contains(s); }
- public Iterator<Sequence> iterator() { return alternatives.iterator(); }
+ public boolean contains(Sequence s) {
+ viewed = true;
+ return alternatives.contains(s);
+ }
+
+ public Iterator<Sequence> iterator() {
+ viewed = true;
+ return alternatives.iterator();
+ }
/** adds an alternative */
public void add(Sequence s) {
+ if (viewed)
+ throw new RuntimeException("attempt to add a Sequence to a Union that has already been examined");
if (alternatives.contains(s)) return;
alternatives.add(s);
}
return "(anon_union)";
}
public String toString() {
+ viewed = true;
if (name != null) return name;
StringBuffer sb = new StringBuffer();
sb.append("(");
sb.append(")");
return sb.toString();
}
+
+ /** display this union in long/expanded form */
public StringBuffer toString(StringBuffer sb) {
+ viewed = true;
if (synthetic) return sb;
boolean first = true;
String before = StringUtil.pad(15, getName()) + " = ";
}
private void bodyToString(StringBuffer sb, String before, String between) {
+ viewed = true;
boolean first = true;
for(Sequence s : this) {
// FIXME: what to do here about printing out negated sequences?
if (e instanceof Sequence) {
Sequence s = (Sequence)e;
- if (s.follow() != null) cs = cs.intersect(s.follow().getTokenTopology());
+ if (s.follow != null) cs = cs.intersect(s.follow.getTokenTopology());
}
if (c != null && e==me) {
}
}
if (this.follow != null)
- ret.follow = this.follow.toAtom(cx);
+ ret = ret.followedBy(this.follow.toAtom(cx));
return ret;
}
}
FileOutputStream fos = new FileOutputStream("/Users/megacz/Desktop/out.dot");
PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
GraphViz gv = new GraphViz();
- a.ambiguity.toGraphViz(gv);
+ a.getAmbiguity().toGraphViz(gv);
gv.dump(p);
p.flush();
p.close();
sb.append("})");
}
+ // this is here to keep it out of the javadoc for Tree<T>
+
public GraphViz.Node toGraphViz(GraphViz gv) {
if (gv.hasNode(this)) return gv.createNode(this);
GraphViz.Node n = gv.createNode(this);