1	package antlr;
2	
3	/**
4	 * <b>SOFTWARE RIGHTS</b>
5	 * <p>
6	 * ANTLR 2.5.0 MageLang Institute, 1998
7	 * <p>
8	 * We reserve no legal rights to the ANTLR--it is fully in the
9	 * public domain. An individual or company may do whatever
10	 * they wish with source code distributed with ANTLR or the
11	 * code generated by ANTLR, including the incorporation of
12	 * ANTLR, or its output, into commerical software.
13	 * <p>
14	 * We encourage users to develop software with ANTLR. However,
15	 * we do ask that credit is given to us for developing
16	 * ANTLR. By "credit", we mean that if you use ANTLR or
17	 * incorporate any source code into one of your programs
18	 * (commercial product, research project, or otherwise) that
19	 * you acknowledge this fact somewhere in the documentation,
20	 * research report, etc... If you like ANTLR and have
21	 * developed a nice tool with the output, please mention that
22	 * you developed it using ANTLR. In addition, we ask that the
23	 * headers remain intact in our source code. As long as these
24	 * guidelines are kept, we expect to continue enhancing this
25	 * system and expect to make other tools available as they are
26	 * completed.
27	 * <p>
28	 * The ANTLR gang:
29	 * @version ANTLR 2.5.0 MageLang Institute, 1998
30	 * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
31	 * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
32	 */
33	/**A Stream of Token objects fed to the parser from a Tokenizer that can
34	 * be rewound via mark()/rewind() methods.
35	 * <p>
36	 * A dynamic array is used to buffer up all the input tokens.  Normally,
37	 * "k" tokens are stored in the buffer.  More tokens may be stored during
38	 * guess mode (testing syntactic predicate), or when LT(i>k) is referenced.
39	 * Consumption of tokens is deferred.  In other words, reading the next
40	 * token is not done by conume(), but deferred until needed by LA or LT.
41	 * <p>
42	 *
43	 * @see antlr.Token
44	 * @see antlr.Tokenizer
45	 * @see antlr.TokenQueue
46	 */
47	 
48	import java.io.IOException;
49	
50	public class TokenBuffer {
51	
52		// Token source
53		protected Tokenizer input;
54	
55		// Number of active markers
56		int nMarkers = 0;
57	
58		// Additional offset used when markers are active
59		int markerOffset = 0;
60	
61		// Number of calls to consume() since last LA() or LT() call
62		int numToConsume = 0;
63	
64		// Circular queue
65		TokenQueue queue;
66	
67	
68		/** Create a token buffer */
69		public TokenBuffer(Tokenizer input_) {
70			input = input_;
71			queue = new TokenQueue(1);
72		}
73		/** Mark another token for deferred consumption */
74		public final void consume() {
75			numToConsume++;
76		}
77		/** Ensure that the token buffer is sufficiently full */
78		private final void fill(int amount) throws IOException 
79		{
80			syncConsume();
81			// Fill the buffer sufficiently to hold needed tokens
82			while (queue.nbrEntries < amount + markerOffset) {
83				// Append the next token
84				queue.append(input.nextToken());
85			}
86		}
87		/** Get a lookahead token value */
88		public final int LA(int i) throws IOException {
89			fill(i);
90			return queue.elementAt(markerOffset + i - 1).type;
91		}
92		/** Get a lookahead token */
93		public final Token LT(int i) throws IOException {
94			fill(i);
95			return queue.elementAt(markerOffset + i - 1);
96		}
97		/**Return an integer marker that can be used to rewind the buffer to
98		 * its current state.
99		 */
100		public final int mark() {
101			syncConsume();
102	//System.out.println("Marking at " + markerOffset);
103	//try { for (int i = 1; i <= 2; i++) { System.out.println("LA("+i+")=="+LT(i).getText()); } } catch (ScannerException e) {}
104			nMarkers++;
105			return markerOffset;
106		}
107		/**Rewind the token buffer to a marker.
108		 * @param mark Marker returned previously from mark()
109		 */
110		public final void rewind(int mark) {
111			syncConsume();
112			markerOffset = mark;
113			nMarkers--;
114	//System.out.println("Rewinding to " + mark);
115	//try { for (int i = 1; i <= 2; i++) { System.out.println("LA("+i+")=="+LT(i).getText()); } } catch (ScannerException e) {}
116		}
117		/** Sync up deferred consumption */
118		private final void syncConsume() {
119			while (numToConsume > 0) {
120				if (nMarkers > 0)
121				{
122					// guess mode -- leave leading tokens and bump offset.
123					markerOffset++;
124				} else {
125					// normal mode -- remove first token
126					queue.removeFirst();
127				}
128				numToConsume--;
129			}
130		}
131	}
132