001: package antlr;
002:
003: /* ANTLR Translator Generator
004: * Project led by Terence Parr at http://www.cs.usfca.edu
005: * Software rights: http://www.antlr.org/license.html
006: */
007:
008: // SAS: Added this class to genericise the input buffers for scanners
009: // This allows a scanner to use a binary (FileInputStream) or
010: // text (FileReader) stream of data; the generated scanner
011: // subclass will define the input stream
012: // There are two subclasses to this: CharBuffer and ByteBuffer
013: import java.io.*;
014:
015: /**A Stream of characters fed to the lexer from a InputStream that can
016: * be rewound via mark()/rewind() methods.
017: * <p>
018: * A dynamic array is used to buffer up all the input characters. Normally,
019: * "k" characters are stored in the buffer. More characters may be stored during
020: * guess mode (testing syntactic predicate), or when LT(i>k) is referenced.
021: * Consumption of characters is deferred. In other words, reading the next
022: * character is not done by conume(), but deferred until needed by LA or LT.
023: * <p>
024: *
025: * @see antlr.CharQueue
026: */
027: public class InputBuffer {
028: // Number of active markers
029: private int nMarkers = 0;
030:
031: // Additional offset used when markers are active
032: private int markerOffset = 0;
033:
034: private int size = 0;
035:
036: // current position in the buffer
037: private int p = 0;
038:
039: // buffer data
040: public static final int INITIAL_BUFFER_SIZE = 2048;
041: public static final int READ_BUFFER_SIZE = INITIAL_BUFFER_SIZE;
042: private char[] data = new char[INITIAL_BUFFER_SIZE];
043:
044: public InputBuffer(Reader input) { // SAS: for proper text i/o
045: try {
046: int numRead = 0;
047: int p = 0;
048: do {
049: if (p + READ_BUFFER_SIZE > data.length) { // overflow?
050: char[] newdata = new char[data.length * 2]; // resize
051: System.arraycopy(data, 0, newdata, 0, data.length);
052: data = newdata;
053: }
054: numRead = input.read(data, p, READ_BUFFER_SIZE);
055: p += numRead;
056: } while (numRead != -1);
057: size = p + 1;
058: } catch (IOException io) {
059: System.err.println("tmp error: can't load input: " + io);
060: }
061: }
062:
063: public InputBuffer(InputStream input) {
064: this (new InputStreamReader(input));
065: }
066:
067: /** This method updates the state of the input buffer so that
068: * the text matched since the most recent mark() is no longer
069: * held by the buffer. So, you either do a mark/rewind for
070: * failed predicate or mark/commit to keep on parsing without
071: * rewinding the input.
072: */
073: /*public final void commit() {
074: nMarkers--;
075: }*/
076:
077: /** Mark another character for deferred consumption */
078: public final void consume() {
079: p++;
080: }
081:
082: /** Ensure that the input buffer is sufficiently full */
083: //public abstract void fill(int amount) throws CharStreamException;
084: //public abstract void fill() throws CharStreamException;
085: // Not used
086: /*public String getLAChars() {
087: StringBuffer la = new StringBuffer();
088: for (int i = markerOffset; i < queue.nbrEntries; i++)
089: la.append(queue.elementAt(i));
090: return la.toString();
091: }
092:
093: public String getMarkedChars() {
094: StringBuffer marked = new StringBuffer();
095: for (int i = 0; i < markerOffset; i++)
096: marked.append(queue.elementAt(i));
097: return marked.toString();
098: }*/
099:
100: /*public final boolean isMarked() {
101: return (nMarkers != 0);
102: }*/
103:
104: /** Get a lookahead character */
105: public final char LA(int i) {
106: if ((p + i - 1) >= size) {
107: return CharScanner.EOF_CHAR;
108: }
109:
110: return data[p + i - 1];
111: }
112:
113: /**Return an integer marker that can be used to rewind the buffer to
114: * its current state.
115: */
116: public final int mark() {
117: nMarkers++;
118: return p;
119: }
120:
121: /**Rewind the character buffer to a marker.
122: * @param mark Marker returned previously from mark()
123: */
124: public final void rewind(int mark) {
125: p = mark;
126: nMarkers--;
127: }
128:
129: /** Reset the input buffer
130: */
131: /*public final void reset() {
132: nMarkers = 0;
133: markerOffset = 0;
134: p=0;
135: //data = null;
136: }*/
137: }
|