1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver [The "BSD licence"]
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Copyright (c) 2005-2006 Terence Parr
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver All rights reserved.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Redistribution and use in source and binary forms, with or without
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver modification, are permitted provided that the following conditions
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver are met:
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1. Redistributions of source code must retain the above copyright
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    notice, this list of conditions and the following disclaimer.
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2. Redistributions in binary form must reproduce the above copyright
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    notice, this list of conditions and the following disclaimer in the
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    documentation and/or other materials provided with the distribution.
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 3. The name of the author may not be used to endorse or promote products
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    derived from this software without specific prior written permission.
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver*/
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.antlr.runtime {
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public class ANTLRStringStream implements CharStream {
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** The data being scanned */
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var data:String;
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** How many characters are actually in the buffer */
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var n:int;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** 0..n-1 index into string of next char */
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var p:int = 0;
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** line number 1..n within the input */
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var _line:int = 1;
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** The index of the character relative to the beginning of the line 0..n-1 */
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var _charPositionInLine:int = 0;
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** tracks how deep mark() calls are nested */
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var markDepth:int = 0;
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** A list of CharStreamState objects that tracks the stream state
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  values line, charPositionInLine, and p that can change as you
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  move through the input stream.  Indexed from 1..markDepth.
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	     *  A null is kept @ index 0.  Create upon first call to mark().
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var markers:Array;
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Track the last mark() call result value for use in rewind(). */
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var lastMarker:int;
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var _sourceName:String;
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    protected var _lineDelimiter:String;
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Copy data in string to a local char array */
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function ANTLRStringStream(input:String = null, lineDelimiter:String = "\n") {
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this._lineDelimiter = lineDelimiter;
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if (input != null) {
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				this.data = input;
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				this.n = input.length;
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Reset the stream so that it's in the same state it was
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  when the object was created *except* the data array is not
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  touched.
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function reset():void {
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			p = 0;
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			_line = 1;
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			_charPositionInLine = 0;
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			markDepth = 0;
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function consume():void {
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        if ( p < n ) {
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				_charPositionInLine++;
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( data.charAt(p)==_lineDelimiter ) {
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					_line++;
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					_charPositionInLine=0;
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            p++;
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        }
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function LA(i:int):int {
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( i==0 ) {
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return 0; // undefined
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( i<0 ) {
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				i++; // e.g., translate LA(-1) to use offset i=0; then data[p+0-1]
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( (p+i-1) < 0 ) {
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					return CharStreamConstants.EOF; // invalid; no char before first char
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( (p+i-1) >= n ) {
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            return CharStreamConstants.EOF;
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        }
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return data.charCodeAt(p+i-1);
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function LT(i:int):int {
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return LA(i);
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Return the current input symbol index 0..n where n indicates the
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	     *  last symbol has been read.  The index is the index of char to
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  be returned from LA(1).
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	     */
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function get index():int {
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        return p;
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get size():int {
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return n;
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function mark():int {
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        if ( markers==null ) {
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            markers = new Array();
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            markers.push(null); // depth 0 means no backtracking, leave blank
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        }
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        markDepth++;
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var state:CharStreamState = null;
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( markDepth>=markers.length ) {
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state = new CharStreamState();
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				markers.push(state);
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state = CharStreamState(markers[markDepth]);
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			state.p = p;
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			state.line = _line;
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			state.charPositionInLine = _charPositionInLine;
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lastMarker = markDepth;
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return markDepth;
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function rewindTo(m:int):void {
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var state:CharStreamState = CharStreamState(markers[m]);
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// restore stream state
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			seek(state.p);
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			_line = state.line;
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			_charPositionInLine = state.charPositionInLine;
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			release(m);
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function rewind():void {
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			rewindTo(lastMarker);
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function release(marker:int):void {
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// unwind any other markers made after m and release m
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			markDepth = marker;
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// release this marker
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			markDepth--;
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** consume() ahead until p==index; can't just set p=index as we must
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  update line and charPositionInLine.
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function seek(index:int):void {
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( index<=p ) {
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				p = index; // just jump; don't update stream state (line, ...)
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return;
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// seek forward, consume until p hits index
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			while ( p<index ) {
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				consume();
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function substring(start:int, stop:int):String {
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return data.substring(start, stop + 1);
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get line():int {
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return _line;
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get charPositionInLine():int {
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return _charPositionInLine;
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function set line(line:int):void {
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this._line = line;
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function set charPositionInLine(pos:int):void {
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this._charPositionInLine = pos;
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get sourceName():String {
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return _sourceName;
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function set sourceName(sourceName:String):void {
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			_sourceName = sourceName;
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}