package com.fr.third.antlr; /* ANTLR Translator Generator * Project led by Terence Parr at http://www.cs.usfca.edu * Software rights: http://www.antlr.org/license.html * * $Id: //depot/code/org.antlr/release/antlr-2.7.7/antlr/Lookahead.java#2 $ */ import com.fr.third.antlr.collections.impl.BitSet; import com.fr.third.antlr.collections.impl.Vector; /**This object holds all information needed to represent * the lookahead for any particular lookahead computation * for a single lookahead depth. Final lookahead * information is a simple bit set, but intermediate * stages need computation cycle and FOLLOW information. * *
* Concerning the cycle variable. * If lookahead is computed for a RuleEnd node, then * computation is part of a FOLLOW cycle for this rule. * If lookahead is computed for a RuleBlock node, the * computation is part of a FIRST cycle to this rule. * *
* Concerning the epsilonDepth variable. * This is not the depth relative to the rule reference * that epsilon was encountered. That value is *
* initial_k - epsilonDepth + 1 ** Also, lookahead depths past rule ref for local follow are: *
* initial_k - (initial_k - epsilonDepth) ** Used for rule references. If we try * to compute look(k, ruleref) and there are fewer * than k lookahead terminals before the end of the * the rule, epsilon will be returned (don't want to * pass the end of the rule). We must track when the * the lookahead got stuck. For example, *
* a : b A B E F G; * b : C ; ** LOOK(5, ref-to(b)) is {
* a : b A B C ; * b : E F // epsilon depth of 1 relative to initial k=3 * | G // epsilon depth of 2 * ; ** Here, LOOK(3,ref-to(b)) returns epsilon, but the depths are * {1, 2}; i.e., 3-(3-1) and 3-(3-2). Those are the lookahead depths * past the rule ref needed for the local follow. * *
* This is null unless an epsilon is created.
*
* @see com.fr.third.antlr.Lookahead#combineWith(Lookahead)
*/
public class Lookahead implements Cloneable {
/** actual bitset of the lookahead */
BitSet fset;
/** is this computation part of a computation cycle? */
String cycle;
/** What k values were being computed when end of rule hit? */
BitSet epsilonDepth;
/** Does this lookahead depth include Epsilon token type? This
* is used to avoid having a bit in the set for Epsilon as it
* conflicts with parsing binary files.
*/
boolean hasEpsilon = false;
public Lookahead() {
fset = new BitSet();
}
/** create a new lookahead set with the LL(1) set to the parameter */
public Lookahead(BitSet p) {
fset = p;
}
/** create an empty lookahead set, but with cycle */
public Lookahead(String c) {
this();
cycle = c;
}
/** Make a deep copy of everything in this object */
public Object clone() {
Lookahead p = null;
try {
p = (Lookahead)super.clone();
p.fset = (BitSet)fset.clone();
p.cycle = cycle; // strings are immutable
if (epsilonDepth != null) {
p.epsilonDepth = (BitSet)epsilonDepth.clone();
}
}
catch (CloneNotSupportedException e) {
throw new InternalError();
}
return p;
}
public void combineWith(Lookahead q) {
if (cycle == null) { // track at least one cycle
cycle = q.cycle;
}
if (q.containsEpsilon()) {
hasEpsilon = true;
}
// combine epsilon depths
if (epsilonDepth != null) {
if (q.epsilonDepth != null) {
epsilonDepth.orInPlace(q.epsilonDepth);
}
}
else if (q.epsilonDepth != null) {
epsilonDepth = (BitSet)q.epsilonDepth.clone();
}
fset.orInPlace(q.fset);
}
public boolean containsEpsilon() {
return hasEpsilon;
}
/** What is the intersection of two lookahead depths?
* Only the Epsilon "bit" and bitset are considered.
*/
public Lookahead intersection(Lookahead q) {
Lookahead p = new Lookahead(fset.and(q.fset));
if (this.hasEpsilon && q.hasEpsilon) {
p.setEpsilon();
}
return p;
}
public boolean nil() {
return fset.nil() && !hasEpsilon;
}
public static Lookahead of(int el) {
Lookahead look = new Lookahead();
look.fset.add(el);
return look;
}
public void resetEpsilon() {
hasEpsilon = false;
}
public void setEpsilon() {
hasEpsilon = true;
}
public String toString() {
String e = "",b,f = "",d = "";
b = fset.toString(",");
if (containsEpsilon()) {
e = "+