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	/** A lexer is recognizer that draws input symbols from a character stream.
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  lexer grammars result in a subclass of this object. A Lexer object
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  uses simplified match() and error recovery mechanisms in the interest
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  of speed.
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public class Lexer extends BaseRecognizer implements TokenSource {
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Where is the lexer drawing characters from? */
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    protected var input:CharStream;
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function Lexer(input:CharStream = null, state:RecognizerSharedState = null) {
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		    super(state);
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.input = input;
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public override function reset():void {
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			super.reset(); // reset all recognizer state variables
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		// wack Lexer state variables
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		if ( input!=null ) {
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			input.seek(0); // rewind the input
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		}
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		if ( state==null ) {
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			return; // no shared state work to do
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		}
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		state.token = null;
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		state.type = TokenConstants.INVALID_TOKEN_TYPE;
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		state.channel = TokenConstants.DEFAULT_CHANNEL;
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		state.tokenStartCharIndex = -1;
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		state.tokenStartCharPositionInLine = -1;
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		state.tokenStartLine = -1;
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		state.text = null;
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Return a token from this source; i.e., match a token on the char
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  stream.
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function nextToken():Token {
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			while (true) {
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state.token = null;
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state.channel = TokenConstants.DEFAULT_CHANNEL;
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state.tokenStartCharIndex = input.index;
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state.tokenStartCharPositionInLine = input.charPositionInLine;
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state.tokenStartLine = input.line;
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state.text = null;
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( input.LA(1)==CharStreamConstants.EOF ) {
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	                return TokenConstants.EOF_TOKEN;
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            }
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            try {
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	                mTokens();
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if ( state.token==null ) {
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						emit();
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					else if ( state.token==TokenConstants.SKIP_TOKEN ) {
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						continue;
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					return state.token;
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            catch (nva:NoViableAltException) {
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    				reportError(nva);
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    				recover(nva); // throw out current char and try again
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			}
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			catch (re:RecognitionException) {
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    				reportError(re);
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    				// match() routine has already called recover()
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			}
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        }
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        // Can't happen, but will quiet complier error
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        return null;
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Instruct the lexer to skip creating a token for current lexer rule
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  and look for another token.  nextToken() knows to keep looking when
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  a lexer rule finishes with token set to SKIP_TOKEN.  Recall that
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  if token==null at end of any token rule, it creates one for you
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  and emits it.
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function skip():void {
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			state.token = TokenConstants.SKIP_TOKEN;
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** This is the lexer entry point that sets instance var 'token' */
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function mTokens():void {
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// abstract function
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			throw new Error("Not implemented");
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Set the char stream and reset the lexer */
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function set charStream(input:CharStream):void {
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.input = null;
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			reset();
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.input = input;
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get charStream():CharStream {
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return input;
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public override function get sourceName():String {
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return input.sourceName;
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Currently does not support multiple emits per nextToken invocation
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  for efficiency reasons.  Subclass and override this method and
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  nextToken (to push tokens into a list and pull from that list rather
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  than a single variable as this implementation does).
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function emitToken(token:Token):void {
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			state.token = token;
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** The standard method called to automatically emit a token at the
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  outermost lexical rule.  The token object should point into the
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  char buffer start..stop.  If there is a text override in 'text',
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  use that to set the token's text.  Override this method to emit
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  custom Token objects.
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function emit():Token {
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var t:Token = CommonToken.createFromStream(input, state.type, state.channel, state.tokenStartCharIndex, charIndex - 1);
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			t.line = state.tokenStartLine;
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			t.text = state.text;
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			t.charPositionInLine = state.tokenStartCharPositionInLine;
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			emitToken(t);
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return t;
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function matchString(s:String):void {
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        var i:int = 0;
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        while ( i<s.length ) {
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            if ( input.LA(1) != s.charCodeAt(i) ) {
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if ( state.backtracking>0 ) {
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						state.failed = true;
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						return;
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					var mte:MismatchedTokenException =
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						new MismatchedTokenException(s.charCodeAt(i), input);
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					recover(mte);
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					throw mte;
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            }
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            i++;
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            input.consume();
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				state.failed = false;
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        }
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function matchAny():void {
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        input.consume();
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function match(c:int):void {
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        if ( input.LA(1)!=c ) {
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( state.backtracking>0 ) {
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					state.failed = true;
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					return;
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var mte:MismatchedTokenException =
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					new MismatchedTokenException(c, input);
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				recover(mte);  // don't really recover; just consume in lexer
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				throw mte;
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        }
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        input.consume();
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			state.failed = false;
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function matchRange(a:int, b:int):void
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        if ( input.LA(1)<a || input.LA(1)>b ) {
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( state.backtracking>0 ) {
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					state.failed = true;
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					return;
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            var mre:MismatchedRangeException =
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					new MismatchedRangeException(a,b,input);
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				recover(mre);
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				throw mre;
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        }
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        input.consume();
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			state.failed = false;
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function get line():int {
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        return input.line;
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    public function get charPositionInLine():int {
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        return input.charPositionInLine;
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** What is the index of the current character of lookahead? */
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get charIndex():int {
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return input.index;
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Return the text matched so far for the current token or any
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  text override.
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get text():String {
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( state.text!=null ) {
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return state.text;
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return input.substring(state.tokenStartCharIndex, charIndex-1);
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Set the complete text of this token; it wipes any previous
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  changes to the text.
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function set text(text:String):void {
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			state.text = text;
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public override function reportError(e:RecognitionException):void {
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			displayRecognitionError(this.tokenNames, e);
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public override function getErrorMessage(e:RecognitionException, tokenNames:Array):String {
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var msg:String = null;
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( e is MismatchedTokenException ) {
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var mte:MismatchedTokenException = MismatchedTokenException(e);
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				msg = "mismatched character "+getCharErrorDisplay(e.c)+" expecting "+getCharErrorDisplay(mte.expecting);
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else if ( e is NoViableAltException ) {
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var nvae:NoViableAltException = NoViableAltException(e);
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>"
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// and "(decision="+nvae.decisionNumber+") and
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// "state "+nvae.stateNumber
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				msg = "no viable alternative at character "+getCharErrorDisplay(e.c);
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else if ( e is EarlyExitException ) {
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var eee:EarlyExitException = EarlyExitException(e);
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// for development, can add "(decision="+eee.decisionNumber+")"
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				msg = "required (...)+ loop did not match anything at character "+getCharErrorDisplay(e.c);
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else if ( e is MismatchedNotSetException ) {
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var mnse:MismatchedNotSetException = MismatchedNotSetException(e);
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				msg = "mismatched character "+getCharErrorDisplay(e.c)+" expecting set "+mnse.expecting;
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else if ( e is MismatchedSetException ) {
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var mse:MismatchedSetException = MismatchedSetException(e);
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				msg = "mismatched character "+getCharErrorDisplay(e.c)+" expecting set "+mse.expecting;
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else if ( e is MismatchedRangeException ) {
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var mre:MismatchedRangeException = MismatchedRangeException(e);
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				msg = "mismatched character "+getCharErrorDisplay(e.c)+" expecting set "+
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					getCharErrorDisplay(mre.a)+".."+getCharErrorDisplay(mre.b);
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				msg = super.getErrorMessage(e, tokenNames);
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return msg;
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function getCharErrorDisplay(c:int):String {
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var s:String = String.fromCharCode(c);
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			switch ( c ) {
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				case TokenConstants.EOF :
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					s = "<EOF>";
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					break;
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				case '\n' :
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					s = "\\n";
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					break;
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				case '\t' :
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					s = "\\t";
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					break;
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				case '\r' :
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					s = "\\r";
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					break;
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return "'"+s+"'";
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Lexers can normally match any char in it's vocabulary after matching
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  a token, so do the easy thing and just kill a character and hope
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  it all works out.  You can instead use the rule invocation stack
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  to do sophisticated error recovery if you are in a fragment rule.
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  @return This method should return the exception it was provided as an
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  argument.  This differs from the Java runtime so that an exception variable
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  does not need to be declared in the generated code, thus reducing a large
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  number of compiler warnings in generated code.
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function recover(re:RecognitionException):RecognitionException {
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			input.consume();
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return re;
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function traceIn(ruleName:String, ruleIndex:int):void {
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var inputSymbol:String = String.fromCharCode(input.LT(1))+" line="+ line +":"+ charPositionInLine;
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			super.traceInSymbol(ruleName, ruleIndex, inputSymbol);
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function traceOut(ruleName:String, ruleIndex:int):void {
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var inputSymbol:String = String.fromCharCode(input.LT(1))+" line="+ line +":"+ charPositionInLine;
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			super.traceOutSymbol(ruleName, ruleIndex, inputSymbol);
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}