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 characters fed to the lexer from a InputStream that can
34	 * be rewound via mark()/rewind() methods.
35	 * <p>
36	 * A dynamic array is used to buffer up all the input characters.  Normally,
37	 * "k" characters are stored in the buffer.  More characters may be stored during
38	 * guess mode (testing syntactic predicate), or when LT(i>k) is referenced.
39	 * Consumption of characters is deferred.  In other words, reading the next
40	 * character is not done by conume(), but deferred until needed by LA or LT.
41	 * <p>
42	 *
43	 * @see antlr.CharQueue
44	 */
45	
46	// SAS: Added this class to genericise the input buffers for scanners
47	//      This allows a scanner to use a binary (FileInputStream) or
48	//      text (FileReader) stream of data; the generated scanner
49	//      subclass will define the input stream
50	//      There are two subclasses to this: CharBuffer and ByteBuffer
51	import java.io.IOException;
52	
53	public abstract class InputBuffer {
54		// char source
55	//	transient Reader input;  // leave to subclasses
56	
57		// Number of active markers
58		int nMarkers = 0;
59	
60		// Additional offset used when markers are active
61		int markerOffset = 0;
62	
63		// Number of calls to consume() since last LA() or LT() call
64		int numToConsume = 0;
65	
66		// Circular queue
67		CharQueue queue;
68	
69		/** Create an input buffer */
70		public InputBuffer() {
71			queue = new CharQueue(1);
72		}
73		/** This method updates the state of the input buffer so that
74		 *  the text matched since the most recent mark() is no longer
75		 *  held by the buffer.  So, you either do a mark/rewind for
76		 *  failed predicate or mark/commit to keep on parsing without
77		 *  rewinding the input.
78		 */
79		public void commit() {
80			nMarkers--;
81		}
82		/** Mark another character for deferred consumption */
83		public void consume() {
84			numToConsume++;
85		}
86		/** Ensure that the input buffer is sufficiently full */
87		public abstract void fill(int amount) throws IOException;
88		public String getLAChars() {
89			StringBuffer la = new StringBuffer();
90			for(int i = markerOffset; i < queue.nbrEntries; i++)
91				la.append(queue.elementAt(i));
92			return la.toString();
93		}
94		public String getMarkedChars() {
95			StringBuffer marked = new StringBuffer();
96			for(int i = 0; i < markerOffset; i++)
97				marked.append(queue.elementAt(i));
98			return marked.toString();
99		}
100		public boolean isMarked() {
101			return (nMarkers != 0);
102		}
103		/** Get a lookahead character */
104		public char LA(int i) throws IOException {
105			fill(i);
106			return queue.elementAt(markerOffset + i - 1);
107		}
108		/**Return an integer marker that can be used to rewind the buffer to
109		 * its current state.
110		 */
111		public int mark() {
112			syncConsume();
113			nMarkers++;
114			return markerOffset;
115		}
116		/**Rewind the character buffer to a marker.
117		 * @param mark Marker returned previously from mark()
118		 */
119		public void rewind(int mark) {
120			syncConsume();
121			markerOffset = mark;
122			nMarkers--;
123		}
124		/** Sync up deferred consumption */
125		protected void syncConsume() {
126			while (numToConsume > 0) {
127				if (nMarkers > 0)
128				{
129					// guess mode -- leave leading characters and bump offset.
130					markerOffset++;
131				} else {
132					// normal mode -- remove first character
133					queue.removeFirst();
134				}
135				numToConsume--;
136			}
137		}
138	}
139