1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD licence"] 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2005-2008 Terence Parr 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Conversion to C#: 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met: 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer. 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer in the 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * documentation and/or other materials provided with the distribution. 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * derived from this software without specific prior written permission. 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace Antlr.Runtime { 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using ConditionalAttribute = System.Diagnostics.ConditionalAttribute; 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * A lexer is recognizer that draws input symbols from a character stream. 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * lexer grammars result in a subclass of this object. A Lexer object 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * uses simplified match() and error recovery mechanisms in the interest 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of speed. 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract class Lexer : BaseRecognizer, ITokenSource { 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>Where is the lexer drawing characters from?</summary> */ 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected ICharStream input; 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Lexer() { 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Lexer(ICharStream input) { 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.input = input; 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Lexer(ICharStream input, RecognizerSharedState state) 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : base(state) { 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.input = input; 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #region Properties 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public string Text { 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>Return the text matched so far for the current token or any text override.</summary> */ 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get { 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (state.text != null) { 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return state.text; 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return input.Substring(state.tokenStartCharIndex, CharIndex - state.tokenStartCharIndex); 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>Set the complete text of this token; it wipes any previous changes to the text.</summary> */ 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set { 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.text = value; 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int Line { 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get { 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return input.Line; 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set { 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input.Line = value; 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int CharPositionInLine { 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get { 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return input.CharPositionInLine; 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set { 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input.CharPositionInLine = value; 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #endregion 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public override void Reset() { 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver base.Reset(); // reset all recognizer state variables 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // wack Lexer state variables 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (input != null) { 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input.Seek(0); // rewind the input 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (state == null) { 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; // no shared state work to do 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.token = null; 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.type = TokenTypes.Invalid; 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.channel = TokenChannels.Default; 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.tokenStartCharIndex = -1; 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.tokenStartCharPositionInLine = -1; 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.tokenStartLine = -1; 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.text = null; 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>Return a token from this source; i.e., match a token on the char stream.</summary> */ 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual IToken NextToken() { 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (; ; ) { 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.token = null; 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.channel = TokenChannels.Default; 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.tokenStartCharIndex = input.Index; 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.tokenStartCharPositionInLine = input.CharPositionInLine; 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.tokenStartLine = input.Line; 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.text = null; 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (input.LA(1) == CharStreamConstants.EndOfFile) { 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver IToken eof = new CommonToken((ICharStream)input, CharStreamConstants.EndOfFile, TokenChannels.Default, input.Index, input.Index); 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eof.Line = Line; 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eof.CharPositionInLine = CharPositionInLine; 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return eof; 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver try { 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver mTokens(); 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (state.token == null) { 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Emit(); 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (state.token == Tokens.Skip) { 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver continue; 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return state.token; 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } catch (NoViableAltException nva) { 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ReportError(nva); 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Recover(nva); // throw out current char and try again 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } catch (RecognitionException re) { 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ReportError(re); 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // match() routine has already called recover() 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Instruct the lexer to skip creating a token for current lexer rule 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * and look for another token. nextToken() knows to keep looking when 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a lexer rule finishes with token set to SKIP_TOKEN. Recall that 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * if token==null at end of any token rule, it creates one for you 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * and emits it. 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Skip() { 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.token = Tokens.Skip; 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>This is the lexer entry point that sets instance var 'token'</summary> */ 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract void mTokens(); 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual ICharStream CharStream { 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get { 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return input; 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>Set the char stream and reset the lexer</summary> */ 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set { 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input = null; 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Reset(); 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input = value; 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public override string SourceName { 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get { 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return input.SourceName; 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Currently does not support multiple emits per nextToken invocation 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * for efficiency reasons. Subclass and override this method and 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * nextToken (to push tokens into a list and pull from that list rather 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * than a single variable as this implementation does). 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Emit(IToken token) { 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.token = token; 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * The standard method called to automatically emit a token at the 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * outermost lexical rule. The token object should point into the 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * char buffer start..stop. If there is a text override in 'text', 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * use that to set the token's text. Override this method to emit 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * custom Token objects. 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * <remarks> 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If you are building trees, then you should also override 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Parser or TreeParser.getMissingSymbol(). 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </remarks> 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual IToken Emit() { 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver IToken t = new CommonToken(input, state.type, state.channel, state.tokenStartCharIndex, CharIndex - 1); 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.Line = state.tokenStartLine; 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.Text = state.text; 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.CharPositionInLine = state.tokenStartCharPositionInLine; 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Emit(t); 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return t; 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Match(string s) { 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int i = 0; 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (i < s.Length) { 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (input.LA(1) != s[i]) { 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (state.backtracking > 0) { 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.failed = true; 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver MismatchedTokenException mte = new MismatchedTokenException(s[i], input, TokenNames); 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Recover(mte); 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw mte; 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver i++; 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input.Consume(); 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.failed = false; 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void MatchAny() { 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input.Consume(); 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Match(int c) { 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (input.LA(1) != c) { 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (state.backtracking > 0) { 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.failed = true; 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver MismatchedTokenException mte = new MismatchedTokenException(c, input, TokenNames); 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Recover(mte); // don't really recover; just consume in lexer 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw mte; 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input.Consume(); 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.failed = false; 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void MatchRange(int a, int b) { 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (input.LA(1) < a || input.LA(1) > b) { 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (state.backtracking > 0) { 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.failed = true; 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver MismatchedRangeException mre = new MismatchedRangeException(a, b, input); 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Recover(mre); 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw mre; 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input.Consume(); 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver state.failed = false; 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>What is the index of the current character of lookahead?</summary> */ 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int CharIndex { 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver get { 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return input.Index; 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public override void ReportError(RecognitionException e) { 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** TODO: not thought about recovery in lexer yet. 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // if we've already reported an error and have not matched a token 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // yet successfully, don't report any errors. 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( errorRecovery ) { 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.err.print("[SPURIOUS] "); 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver errorRecovery = true; 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DisplayRecognitionError(this.TokenNames, e); 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public override string GetErrorMessage(RecognitionException e, string[] tokenNames) { 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver string msg = null; 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (e is MismatchedTokenException) { 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver MismatchedTokenException mte = (MismatchedTokenException)e; 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver msg = "mismatched character " + GetCharErrorDisplay(e.Character) + " expecting " + GetCharErrorDisplay(mte.Expecting); 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (e is NoViableAltException) { 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver NoViableAltException nvae = (NoViableAltException)e; 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>" 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // and "(decision="+nvae.decisionNumber+") and 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // "state "+nvae.stateNumber 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver msg = "no viable alternative at character " + GetCharErrorDisplay(e.Character); 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (e is EarlyExitException) { 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver EarlyExitException eee = (EarlyExitException)e; 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // for development, can add "(decision="+eee.decisionNumber+")" 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver msg = "required (...)+ loop did not match anything at character " + GetCharErrorDisplay(e.Character); 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (e is MismatchedNotSetException) { 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver MismatchedNotSetException mse = (MismatchedNotSetException)e; 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver msg = "mismatched character " + GetCharErrorDisplay(e.Character) + " expecting set " + mse.Expecting; 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (e is MismatchedSetException) { 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver MismatchedSetException mse = (MismatchedSetException)e; 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver msg = "mismatched character " + GetCharErrorDisplay(e.Character) + " expecting set " + mse.Expecting; 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (e is MismatchedRangeException) { 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver MismatchedRangeException mre = (MismatchedRangeException)e; 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver msg = "mismatched character " + GetCharErrorDisplay(e.Character) + " expecting set " + 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GetCharErrorDisplay(mre.A) + ".." + GetCharErrorDisplay(mre.B); 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver msg = base.GetErrorMessage(e, tokenNames); 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return msg; 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual string GetCharErrorDisplay(int c) { 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver string s = ((char)c).ToString(); 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver switch (c) { 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case TokenTypes.EndOfFile: 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver s = "<EOF>"; 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case '\n': 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver s = "\\n"; 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case '\t': 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver s = "\\t"; 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case '\r': 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver s = "\\r"; 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return "'" + s + "'"; 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Lexers can normally match any char in it's vocabulary after matching 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a token, so do the easy thing and just kill a character and hope 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * it all works out. You can instead use the rule invocation stack 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * to do sophisticated error recovery if you are in a fragment rule. 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void Recover(RecognitionException re) { 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("consuming char "+(char)input.LA(1)+" during recovery"); 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //re.printStackTrace(); 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input.Consume(); 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver [Conditional("ANTLR_TRACE")] 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void TraceIn(string ruleName, int ruleIndex) { 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver string inputSymbol = ((char)input.LT(1)) + " line=" + Line + ":" + CharPositionInLine; 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver base.TraceIn(ruleName, ruleIndex, inputSymbol); 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver [Conditional("ANTLR_TRACE")] 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void TraceOut(string ruleName, int ruleIndex) { 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver string inputSymbol = ((char)input.LT(1)) + " line=" + Line + ":" + CharPositionInLine; 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver base.TraceOut(ruleName, ruleIndex, inputSymbol); 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 356