Lookahead.java
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:6k
源码类别:

编译器/解释器

开发平台:

Others

  1. package antlr;
  2. /* ANTLR Translator Generator
  3.  * Project led by Terence Parr at http://www.jGuru.com
  4.  * Software rights: http://www.antlr.org/RIGHTS.html
  5.  *
  6.  * $Id: //depot/code/org.antlr/release/antlr-2.7.0/antlr/Lookahead.java#1 $
  7.  */
  8. import antlr.collections.impl.BitSet;
  9. import antlr.collections.impl.Vector;
  10. /**This object holds all information needed to represent
  11.  * the lookahead for any particular lookahead computation
  12.  * for a <b>single</b> lookahead depth.  Final lookahead
  13.  * information is a simple bit set, but intermediate
  14.  * stages need computation cycle and FOLLOW information.
  15.  *
  16.  * <p>
  17.  * Concerning the <tt>cycle</tt> variable.
  18.  * If lookahead is computed for a RuleEnd node, then
  19.  * computation is part of a FOLLOW cycle for this rule.
  20.  * If lookahead is computed for a RuleBlock node, the
  21.  * computation is part of a FIRST cycle to this rule.
  22.  *
  23.  * <p>
  24.  * Concerning the <tt>epsilonDepth</tt> variable.
  25.  * This is not the depth relative to the rule reference
  26.  * that epsilon was encountered.  That value is
  27.  * <pre>
  28.  *  initial_k - epsilonDepth + 1
  29.  * </pre>
  30.  * Also, lookahead depths past rule ref for local follow are:
  31.  * <pre>
  32.  *  initial_k - (initial_k - epsilonDepth)
  33.  * </pre>
  34.  * Used for rule references.  If we try
  35.  * to compute look(k, ruleref) and there are fewer
  36.  * than k lookahead terminals before the end of the
  37.  * the rule, epsilon will be returned (don't want to
  38.  * pass the end of the rule).  We must track when the
  39.  * the lookahead got stuck.  For example,
  40.  * <pre>
  41.  *  a : b A B E F G;
  42.  *  b : C ;
  43.  * </pre>
  44.  * LOOK(5, ref-to(b)) is {<EPSILON>} with depth = 4, which
  45.  * indicates that at 2 (5-4+1) tokens ahead, end of rule was reached.
  46.  * Therefore, the token at 4=5-(5-4) past rule ref b must be
  47.  * included in the set == F.
  48.  * The situation is complicated by the fact that a computation
  49.  * may hit the end of a rule at many different depths.  For example,
  50.  * <pre>
  51.  *  a : b A B C ;
  52.  *  b : E F // epsilon depth of 1 relative to initial k=3
  53.  *    | G // epsilon depth of 2
  54.  *    ;
  55.  * </pre>
  56.  * Here, LOOK(3,ref-to(b)) returns epsilon, but the depths are
  57.  * {1, 2}; i.e., 3-(3-1) and 3-(3-2).  Those are the lookahead depths
  58.  * past the rule ref needed for the local follow.
  59.  * 
  60.  * <p>
  61.  * This is null unless an epsilon is created.
  62.  *
  63.  * @see antlr.Lookahead#combineWith(Lookahead)
  64.  */
  65. public class Lookahead implements Cloneable {
  66. /** actual bitset of the lookahead */
  67. BitSet fset;
  68. /** is this computation part of a computation cycle? */
  69. String cycle;
  70. /** What k values were being computed when end of rule hit? */
  71. BitSet epsilonDepth;
  72. /** Does this lookahead depth include Epsilon token type? This
  73.  *  is used to avoid having a bit in the set for Epsilon as it
  74.  *  conflicts with parsing binary files.
  75.  */
  76. boolean hasEpsilon = false;
  77. public Lookahead() {
  78. fset = new BitSet();
  79. }
  80. /** create a new lookahead set with the LL(1) set to the parameter */
  81. public Lookahead(BitSet p) {
  82. fset = p;
  83. }
  84. /** create an empty lookahead set, but with cycle */
  85. public Lookahead(String c) {
  86. this();
  87. cycle = c;
  88. }
  89. /** Make a deep copy of everything in this object */
  90. public Object clone() {
  91. Lookahead p=null;
  92. try {
  93. p = (Lookahead)super.clone();
  94. p.fset = (BitSet)fset.clone();
  95. p.cycle = cycle; // strings are immutable
  96. if ( epsilonDepth!=null ) {
  97. p.epsilonDepth = (BitSet)epsilonDepth.clone();
  98. }
  99. }
  100. catch (CloneNotSupportedException e) {
  101. throw new InternalError();
  102. }
  103. return p;
  104. }
  105. public void combineWith(Lookahead q) {
  106. if ( cycle==null ) { // track at least one cycle
  107. cycle = q.cycle;
  108. }
  109. if ( q.containsEpsilon() ) {
  110. hasEpsilon = true;
  111. }
  112. // combine epsilon depths
  113. if ( epsilonDepth!=null ) {
  114. if ( q.epsilonDepth!=null ) {
  115. epsilonDepth.orInPlace(q.epsilonDepth);
  116. }
  117. }
  118. else if ( q.epsilonDepth!=null ) {
  119. epsilonDepth = (BitSet)q.epsilonDepth.clone();
  120. }
  121. fset.orInPlace(q.fset);
  122. }
  123. public boolean containsEpsilon() { return hasEpsilon; }
  124. /** What is the intersection of two lookahead depths?
  125.  *  Only the Epsilon "bit" and bitset are considered.
  126.  */
  127. public Lookahead intersection(Lookahead q) {
  128. Lookahead p = new Lookahead(fset.and(q.fset));
  129. if ( this.hasEpsilon && q.hasEpsilon ) {
  130. p.setEpsilon();
  131. }
  132. return p;
  133. }
  134. public boolean nil() {
  135. return fset.nil() && !hasEpsilon;
  136. }
  137. public static Lookahead of(int el) {
  138. Lookahead look = new Lookahead();
  139. look.fset.add(el);
  140. return look;
  141. }
  142. public void resetEpsilon() { hasEpsilon=false; }
  143. public void setEpsilon() { hasEpsilon = true; }
  144. public String toString() {
  145. String e="",b,f="",d="";
  146. b = fset.toString(",");
  147. if ( containsEpsilon() ) {
  148. e="+<epsilon>";
  149. }
  150. if ( cycle!=null ) {
  151. f="; FOLLOW("+cycle+")";
  152. }
  153. if ( epsilonDepth != null ) {
  154. d = "; depths="+epsilonDepth.toString(",");
  155. }
  156. return b+e+f+d;
  157. }
  158. public String toString(String separator, CharFormatter formatter) {
  159. String e="",b,f="",d="";
  160. b = fset.toString(separator, formatter);
  161. if ( containsEpsilon() ) {
  162. e="+<epsilon>";
  163. }
  164. if ( cycle!=null ) {
  165. f="; FOLLOW("+cycle+")";
  166. }
  167. if ( epsilonDepth != null ) {
  168. d = "; depths="+epsilonDepth.toString(",");
  169. }
  170. return b+e+f+d;
  171. }
  172. public String toString(String separator, CharFormatter formatter, Grammar g) {
  173. if (g instanceof LexerGrammar) {
  174. return toString(separator, formatter);
  175. }
  176. else {
  177. return toString(separator, g.tokenManager.getVocabulary());
  178. }
  179. }
  180. public String toString(String separator, Vector vocab) {
  181. String b,f="",d="";
  182. b = fset.toString(separator, vocab);
  183. if ( cycle!=null ) {
  184. f="; FOLLOW("+cycle+")";
  185. }
  186. if ( epsilonDepth != null ) {
  187. d = "; depths="+epsilonDepth.toString(",");
  188. }
  189. return b+f+d;
  190. }
  191. }