/** the root superclass for all components of the grammar (terminals, nonterminals, literals, etc) */
public abstract class Element {
+ /** sorry, you can't make up new, custom elements */
+ Element() { }
+
abstract StringBuffer toString(StringBuffer sb);
/** returns the Forest resulting from matching this element against the empty string */
for(Node child : ((Forest.Many<?>)result).parents) {
if (only != null && child!=only) continue;
holder[pos] = result;
- if (pos==0) child.finish(r, r.rewrite(new Input.Region(child.phase().getLocation(), phase().getLocation())), target);
+ if (pos==0) child.finish(r, r.rewrite(child.phase().getLocation().createRegion(phase().getLocation())), target);
else child.reduce(r, pos-1, target, null);
}
/** a location <i>between tokens<i> in the input stream */
public static interface Location<Tok> extends Comparable<Location> {
public String toString();
+ public Region<Tok> createRegion(Location<Tok> loc);
}
- public static class Region<Loc extends Location> /* implements Topology<Location<Tok>> */ {
- public final Loc start;
- public final Loc end;
- public String toString() { return start+"-"+end; }
- public Region(Loc a, Loc b) {
- switch(a.compareTo(b)) {
- case -1:
- case 0: start=a; end=b; return;
- case 1: start=b; end=a; return;
- default: throw new Error("impossible");
- }
- }
- }
+ public static interface Region<Tok> /* implements Topology<Location<Tok>> */ { }
}
protected Parser(Table<Tok> pt) { this.pt = pt; }
/** implement this method to create the output forest corresponding to a lone shifted input token */
- protected abstract Forest<Result> shiftToken(Input.Location oldloc, Tok t, Input.Location newloc);
+ protected abstract Forest<Result> shiftToken(Tok t, Input.Location newloc);
boolean helpgc = true;
Input.Location oldloc = loc;
loc = input.getLocation();
current.reduce();
- Forest forest = current.token==null ? null : shiftToken(oldloc, (Tok)current.token, loc);
+ Forest forest = current.token==null ? null : shiftToken((Tok)current.token, loc);
GSS.Phase next = gss.new Phase<Tok>(current, this, current, input.next(), loc, forest);
if (!helpgc) {
FileOutputStream fos = new FileOutputStream("out-"+idx+".dot");
public CharParser(Union u) { super(u, new CharTopology()); }
- public Forest<String> shiftToken(Location oldloc, Character ct, Location newloc) {
- return Forest.create(new Input.Region(oldloc, newloc), ct.toString(), null, false);
+ private Location oldloc;
+
+ public Forest<String> shiftToken(Character ct, Location newloc) {
+ if (oldloc==null) oldloc = newloc;
+ Forest<String> ret = Forest.create(oldloc.createRegion(newloc), ct.toString(), null, false);
+ oldloc = newloc;
+ return ret;
}
}
if (col > c.col) return 1;
return 0;
}
+ public Input.Region<Tok> createRegion(Input.Location<Tok> loc) {
+ return new Region<Tok>(this, (Cartesian.Location<Tok>)loc); }
+ }
+
+ public static class Region<Tok> implements Input.Region<Tok> {
+ public final Location<Tok> start;
+ public final Location<Tok> end;
+ public String toString() {
+ if (start.row==end.row) return start.row+":"+(start.col+"-"+end.col);
+ return start+"-"+end;
+ }
+ public Region(Location<Tok> a, Location<Tok> b) {
+ switch(a.compareTo(b)) {
+ case -1:
+ case 0: start=a; end=b; return;
+ case 1: start=b; end=a; return;
+ default: throw new Error("impossible");
+ }
+ }
}
}