001: /**
002: * An implementation of interface CharStream, where the stream is assumed to
003: * contain only ASCII characters (without unicode processing).
004: */package pnuts.lang;
005:
006: class SimpleCharStream {
007: public static final boolean staticFlag = false;
008:
009: private final static java.io.IOException eof = new java.io.IOException();
010:
011: int bufsize;
012:
013: int available;
014:
015: int tokenBegin;
016:
017: public int bufpos = -1;
018:
019: protected int bufline[];
020:
021: protected int bufcolumn[];
022:
023: protected int column = 0;
024:
025: protected int line = 1;
026:
027: protected boolean prevCharIsCR = false;
028:
029: protected boolean prevCharIsLF = false;
030:
031: protected java.io.Reader inputStream;
032:
033: protected char[] buffer;
034:
035: protected int maxNextCharInd = 0;
036:
037: protected int inBuf = 0;
038:
039: protected void ExpandBuff(boolean wrapAround) {
040: int newbufferSize = (bufsize + 1) * 2;
041: char[] newbuffer = new char[newbufferSize];
042: int newbufline[] = new int[newbufferSize];
043: int newbufcolumn[] = new int[newbufferSize];
044:
045: try {
046: if (wrapAround) {
047: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
048: bufsize - tokenBegin);
049: System.arraycopy(buffer, 0, newbuffer, bufsize
050: - tokenBegin, bufpos);
051: buffer = newbuffer;
052:
053: System.arraycopy(bufline, tokenBegin, newbufline, 0,
054: bufsize - tokenBegin);
055: System.arraycopy(bufline, 0, newbufline, bufsize
056: - tokenBegin, bufpos);
057: bufline = newbufline;
058:
059: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
060: 0, bufsize - tokenBegin);
061: System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize
062: - tokenBegin, bufpos);
063: bufcolumn = newbufcolumn;
064:
065: maxNextCharInd = (bufpos += (bufsize - tokenBegin));
066: } else {
067: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
068: bufsize - tokenBegin);
069: buffer = newbuffer;
070:
071: System.arraycopy(bufline, tokenBegin, newbufline, 0,
072: bufsize - tokenBegin);
073: bufline = newbufline;
074:
075: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
076: 0, bufsize - tokenBegin);
077: bufcolumn = newbufcolumn;
078:
079: maxNextCharInd = (bufpos -= tokenBegin);
080: }
081: } catch (Throwable t) {
082: throw new Error(t.getMessage());
083: }
084:
085: bufsize = newbufferSize;
086: available = bufsize;
087: tokenBegin = 0;
088: }
089:
090: protected void FillBuff() throws java.io.IOException {
091: if (maxNextCharInd == available) {
092: if (available == bufsize) {
093: if (tokenBegin > 128) {
094: bufpos = maxNextCharInd = 0;
095: available = tokenBegin;
096: } else if (tokenBegin < 0)
097: bufpos = maxNextCharInd = 0;
098: else
099: ExpandBuff(false);
100: } else if (available > tokenBegin)
101: available = bufsize;
102: else if ((tokenBegin - available) < 128)
103: ExpandBuff(true);
104: else
105: available = tokenBegin;
106: }
107:
108: int i;
109: try {
110: if ((i = inputStream.read(buffer, maxNextCharInd, available
111: - maxNextCharInd)) == -1) {
112: throw eof;
113: } else
114: maxNextCharInd += i;
115: return;
116: } catch (java.io.IOException e) {
117: --bufpos;
118: backup(0);
119: if (tokenBegin == -1)
120: tokenBegin = bufpos;
121: throw e;
122: }
123: }
124:
125: public char BeginToken() throws java.io.IOException {
126: tokenBegin = -1;
127: char c = readChar();
128: tokenBegin = bufpos;
129:
130: return c;
131: }
132:
133: protected void UpdateLineColumn(char c) {
134: column++;
135:
136: if (prevCharIsLF) {
137: prevCharIsLF = false;
138: line += (column = 1);
139: } else if (prevCharIsCR) {
140: prevCharIsCR = false;
141: if (c == '\n') {
142: prevCharIsLF = true;
143: } else
144: line += (column = 1);
145: }
146:
147: switch (c) {
148: case '\r':
149: prevCharIsCR = true;
150: break;
151: case '\n':
152: prevCharIsLF = true;
153: break;
154: // case '\t':
155: // column--;
156: // column += (8 - (column & 07));
157: // break;
158: default:
159: break;
160: }
161:
162: bufline[bufpos] = line;
163: bufcolumn[bufpos] = column;
164: }
165:
166: public char readChar() throws java.io.IOException {
167: if (inBuf > 0) {
168: --inBuf;
169:
170: if (++bufpos == bufsize)
171: bufpos = 0;
172:
173: return buffer[bufpos];
174: }
175:
176: if (++bufpos >= maxNextCharInd)
177: FillBuff();
178:
179: char c = buffer[bufpos];
180:
181: UpdateLineColumn(c);
182: return (c);
183: }
184:
185: /**
186: * @deprecated
187: * @see #getEndColumn
188: */
189:
190: public int getColumn() {
191: return bufcolumn[bufpos];
192: }
193:
194: /**
195: * @deprecated
196: * @see #getEndLine
197: */
198:
199: public int getLine() {
200: return bufline[bufpos];
201: }
202:
203: public int getEndColumn() {
204: return bufcolumn[bufpos];
205: }
206:
207: public int getEndLine() {
208: return bufline[bufpos];
209: }
210:
211: public int getBeginColumn() {
212: return bufcolumn[tokenBegin];
213: }
214:
215: public int getBeginLine() {
216: return bufline[tokenBegin];
217: }
218:
219: public void backup(int amount) {
220:
221: inBuf += amount;
222: if ((bufpos -= amount) < 0)
223: bufpos += bufsize;
224: }
225:
226: public SimpleCharStream(java.io.Reader dstream, int startline,
227: int startcolumn, int buffersize) {
228: inputStream = dstream;
229: line = startline;
230: column = startcolumn - 1;
231:
232: available = bufsize = buffersize;
233: buffer = new char[buffersize];
234: bufline = new int[buffersize];
235: bufcolumn = new int[buffersize];
236: }
237:
238: public SimpleCharStream(java.io.Reader dstream, int startline,
239: int startcolumn) {
240: this (dstream, startline, startcolumn, 512);
241: }
242:
243: public SimpleCharStream(java.io.Reader dstream) {
244: this (dstream, 1, 1, 512);
245: }
246:
247: public void ReInit(java.io.Reader dstream, int startline,
248: int startcolumn, int buffersize) {
249: inputStream = dstream;
250: line = startline;
251: column = startcolumn - 1;
252:
253: if (buffer == null || buffersize != buffer.length) {
254: available = bufsize = buffersize;
255: buffer = new char[buffersize];
256: bufline = new int[buffersize];
257: bufcolumn = new int[buffersize];
258: }
259: prevCharIsLF = prevCharIsCR = false;
260: tokenBegin = inBuf = maxNextCharInd = 0;
261: bufpos = -1;
262: }
263:
264: public void ReInit(java.io.Reader dstream, int startline,
265: int startcolumn) {
266: ReInit(dstream, startline, startcolumn, 512);
267: }
268:
269: public void ReInit(java.io.Reader dstream) {
270: ReInit(dstream, 1, 1, 512);
271: }
272:
273: public SimpleCharStream(java.io.InputStream dstream, int startline,
274: int startcolumn, int buffersize) {
275: this (new java.io.InputStreamReader(dstream), startline,
276: startcolumn, 512);
277: }
278:
279: public SimpleCharStream(java.io.InputStream in, String encoding,
280: int startline, int startcolumn)
281: throws java.io.UnsupportedEncodingException {
282: this (new java.io.InputStreamReader(in, encoding), startline,
283: startcolumn, 512);
284: }
285:
286: public SimpleCharStream(java.io.InputStream dstream, int startline,
287: int startcolumn) {
288: this (dstream, startline, startcolumn, 512);
289: }
290:
291: public SimpleCharStream(java.io.InputStream dstream) {
292: this (dstream, 1, 1, 512);
293: }
294:
295: public void ReInit(java.io.InputStream dstream, int startline,
296: int startcolumn, int buffersize) {
297: ReInit(new java.io.InputStreamReader(dstream), startline,
298: startcolumn, 512);
299: }
300:
301: public void ReInit(java.io.InputStream dstream) {
302: ReInit(dstream, 1, 1, 512);
303: }
304:
305: public void ReInit(java.io.InputStream dstream, int startline,
306: int startcolumn) {
307: ReInit(dstream, startline, startcolumn, 512);
308: }
309:
310: public void ReInit(java.io.InputStream in, String encoding,
311: int startline, int startcolumn)
312: throws java.io.UnsupportedEncodingException {
313: ReInit(new java.io.InputStreamReader(in, encoding), startline,
314: startcolumn);
315: }
316:
317: public String GetImage() {
318: if (bufpos >= tokenBegin)
319: return new String(buffer, tokenBegin, bufpos - tokenBegin
320: + 1);
321: else
322: return new String(buffer, tokenBegin, bufsize - tokenBegin)
323: + new String(buffer, 0, bufpos + 1);
324: }
325:
326: public char[] GetSuffix(int len) {
327: char[] ret = new char[len];
328:
329: if ((bufpos + 1) >= len)
330: System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
331: else {
332: System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret,
333: 0, len - bufpos - 1);
334: System.arraycopy(buffer, 0, ret, len - bufpos - 1,
335: bufpos + 1);
336: }
337:
338: return ret;
339: }
340:
341: public void Done() {
342: buffer = null;
343: bufline = null;
344: bufcolumn = null;
345: }
346:
347: /**
348: * Method to adjust line and column numbers for the start of a token. <BR>
349: */
350: public void adjustBeginLineColumn(int newLine, int newCol) {
351: int start = tokenBegin;
352: int len;
353:
354: if (bufpos >= tokenBegin) {
355: len = bufpos - tokenBegin + inBuf + 1;
356: } else {
357: len = bufsize - tokenBegin + bufpos + 1 + inBuf;
358: }
359:
360: int i = 0, j = 0, k = 0;
361: int nextColDiff = 0, columnDiff = 0;
362:
363: while (i < len
364: && bufline[j = start % bufsize] == bufline[k = ++start
365: % bufsize]) {
366: bufline[j] = newLine;
367: nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
368: bufcolumn[j] = newCol + columnDiff;
369: columnDiff = nextColDiff;
370: i++;
371: }
372:
373: if (i < len) {
374: bufline[j] = newLine++;
375: bufcolumn[j] = newCol + columnDiff;
376:
377: while (i++ < len) {
378: if (bufline[j = start % bufsize] != bufline[++start
379: % bufsize])
380: bufline[j] = newLine++;
381: else
382: bufline[j] = newLine;
383: }
384: }
385:
386: line = bufline[j];
387: column = bufcolumn[j];
388: }
389:
390: }
|