xref: /aosp_15_r20/external/antlr/runtime/Delphi/Sources/Antlr3.Runtime/Antlr.Runtime.pas (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot unit Antlr.Runtime;
2*16467b97STreehugger Robot (*
3*16467b97STreehugger Robot [The "BSD licence"]
4*16467b97STreehugger Robot Copyright (c) 2008 Erik van Bilsen
5*16467b97STreehugger Robot Copyright (c) 2005-2007 Kunle Odutola
6*16467b97STreehugger Robot All rights reserved.
7*16467b97STreehugger Robot 
8*16467b97STreehugger Robot Redistribution and use in source and binary forms, with or without
9*16467b97STreehugger Robot modification, are permitted provided that the following conditions
10*16467b97STreehugger Robot are met:
11*16467b97STreehugger Robot 1. Redistributions of source code MUST RETAIN the above copyright
12*16467b97STreehugger Robot    notice, this list of conditions and the following disclaimer.
13*16467b97STreehugger Robot 2. Redistributions in binary form MUST REPRODUCE the above copyright
14*16467b97STreehugger Robot    notice, this list of conditions and the following disclaimer in
15*16467b97STreehugger Robot    the documentation and/or other materials provided with the
16*16467b97STreehugger Robot    distribution.
17*16467b97STreehugger Robot 3. The name of the author may not be used to endorse or promote products
18*16467b97STreehugger Robot    derived from this software without specific prior WRITTEN permission.
19*16467b97STreehugger Robot 4. Unless explicitly state otherwise, any contribution intentionally
20*16467b97STreehugger Robot    submitted for inclusion in this work to the copyright owner or licensor
21*16467b97STreehugger Robot    shall be under the terms and conditions of this license, without any
22*16467b97STreehugger Robot    additional terms or conditions.
23*16467b97STreehugger Robot 
24*16467b97STreehugger Robot THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25*16467b97STreehugger Robot IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26*16467b97STreehugger Robot OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27*16467b97STreehugger Robot IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28*16467b97STreehugger Robot INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29*16467b97STreehugger Robot NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30*16467b97STreehugger Robot DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31*16467b97STreehugger Robot THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*16467b97STreehugger Robot (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33*16467b97STreehugger Robot THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*16467b97STreehugger Robot *)
35*16467b97STreehugger Robot 
36*16467b97STreehugger Robot interface
37*16467b97STreehugger Robot 
38*16467b97STreehugger Robot {$IF CompilerVersion < 20}
39*16467b97STreehugger Robot {$MESSAGE ERROR 'You need Delphi 2009 or higher to use the Antlr runtime'}
40*16467b97STreehugger Robot {$IFEND}
41*16467b97STreehugger Robot 
42*16467b97STreehugger Robot uses
43*16467b97STreehugger Robot   SysUtils,
44*16467b97STreehugger Robot   Classes,
45*16467b97STreehugger Robot   Generics.Defaults,
46*16467b97STreehugger Robot   Generics.Collections,
47*16467b97STreehugger Robot   Antlr.Runtime.Tools,
48*16467b97STreehugger Robot   Antlr.Runtime.Collections;
49*16467b97STreehugger Robot 
50*16467b97STreehugger Robot type
51*16467b97STreehugger Robot   TCharStreamConstants = (cscEOF = -1);
52*16467b97STreehugger Robot 
53*16467b97STreehugger Robot type
54*16467b97STreehugger Robot   ERecognitionException = class;
55*16467b97STreehugger Robot   ENoViableAltException = class;
56*16467b97STreehugger Robot 
57*16467b97STreehugger Robot   /// <summary>
58*16467b97STreehugger Robot   /// A simple stream of integers. This is useful when all we care about is the char
59*16467b97STreehugger Robot   /// or token type sequence (such as for interpretation).
60*16467b97STreehugger Robot   /// </summary>
61*16467b97STreehugger Robot   IIntStream = interface(IANTLRInterface)
62*16467b97STreehugger Robot   ['{6B851BDB-DD9C-422B-AD1E-567E52D2654F}']
63*16467b97STreehugger Robot     { Property accessors }
GetSourceName()64*16467b97STreehugger Robot     function GetSourceName: String;
65*16467b97STreehugger Robot 
66*16467b97STreehugger Robot     { Methods }
67*16467b97STreehugger Robot     /// <summary>
68*16467b97STreehugger Robot     /// Advances the read position of the stream. Updates line and column state
69*16467b97STreehugger Robot     /// </summary>
70*16467b97STreehugger Robot     procedure Consume;
71*16467b97STreehugger Robot 
72*16467b97STreehugger Robot     /// <summary>
73*16467b97STreehugger Robot     /// Get int at current input pointer + I ahead (where I=1 is next int)
74*16467b97STreehugger Robot     /// Negative indexes are allowed.  LA(-1) is previous token (token just matched).
75*16467b97STreehugger Robot     /// LA(-i) where i is before first token should yield -1, invalid char or EOF.
76*16467b97STreehugger Robot     /// </summary>
LA(I: Integer)77*16467b97STreehugger Robot     function LA(I: Integer): Integer;
LAChar(I: Integer)78*16467b97STreehugger Robot     function LAChar(I: Integer): Char;
79*16467b97STreehugger Robot 
80*16467b97STreehugger Robot     /// <summary>Tell the stream to start buffering if it hasn't already.</summary>
81*16467b97STreehugger Robot     /// <remarks>
82*16467b97STreehugger Robot     /// Executing Rewind(Mark()) on a stream should not affect the input position.
83*16467b97STreehugger Robot     /// The Lexer tracks line/col info as well as input index so its markers are
84*16467b97STreehugger Robot     /// not pure input indexes.  Same for tree node streams.                          */
85*16467b97STreehugger Robot     /// </remarks>
86*16467b97STreehugger Robot     /// <returns>Return a marker that can be passed to
87*16467b97STreehugger Robot     /// <see cref="IIntStream.Rewind(Integer)"/> to return to the current position.
88*16467b97STreehugger Robot     /// This could be the current input position, a value return from
89*16467b97STreehugger Robot     /// <see cref="IIntStream.Index"/>, or some other marker.</returns>
Mark()90*16467b97STreehugger Robot     function Mark: Integer;
91*16467b97STreehugger Robot 
92*16467b97STreehugger Robot     /// <summary>
93*16467b97STreehugger Robot     /// Return the current input symbol index 0..N where N indicates the
94*16467b97STreehugger Robot     /// last symbol has been read. The index is the symbol about to be
95*16467b97STreehugger Robot     /// read not the most recently read symbol.
96*16467b97STreehugger Robot     /// </summary>
Index()97*16467b97STreehugger Robot     function Index: Integer;
98*16467b97STreehugger Robot 
99*16467b97STreehugger Robot     /// <summary>
100*16467b97STreehugger Robot     /// Resets the stream so that the next call to
101*16467b97STreehugger Robot     /// <see cref="IIntStream.Index"/> would  return marker.
102*16467b97STreehugger Robot     /// </summary>
103*16467b97STreehugger Robot     /// <remarks>
104*16467b97STreehugger Robot     /// The marker will usually be <see cref="IIntStream.Index"/> but
105*16467b97STreehugger Robot     /// it doesn't have to be.  It's just a marker to indicate what
106*16467b97STreehugger Robot     /// state the stream was in.  This is essentially calling
107*16467b97STreehugger Robot     /// <see cref="IIntStream.Release"/> and <see cref="IIntStream.Seek"/>.
108*16467b97STreehugger Robot     /// If there are other markers created after the specified marker,
109*16467b97STreehugger Robot     /// this routine must unroll them like a stack.  Assumes the state the
110*16467b97STreehugger Robot     /// stream was in when this marker was created.
111*16467b97STreehugger Robot     /// </remarks>
112*16467b97STreehugger Robot     procedure Rewind(const Marker: Integer); overload;
113*16467b97STreehugger Robot 
114*16467b97STreehugger Robot     /// <summary>
115*16467b97STreehugger Robot     /// Rewind to the input position of the last marker.
116*16467b97STreehugger Robot     /// </summary>
117*16467b97STreehugger Robot     /// <remarks>
118*16467b97STreehugger Robot     /// Used currently only after a cyclic DFA and just before starting
119*16467b97STreehugger Robot     /// a sem/syn predicate to get the input position back to the start
120*16467b97STreehugger Robot     /// of the decision. Do not "pop" the marker off the state.  Mark(I)
121*16467b97STreehugger Robot     /// and Rewind(I) should balance still. It is like invoking
122*16467b97STreehugger Robot     /// Rewind(last marker) but it should not "pop" the marker off.
123*16467b97STreehugger Robot     /// It's like Seek(last marker's input position).
124*16467b97STreehugger Robot     /// </remarks>
125*16467b97STreehugger Robot     procedure Rewind; overload;
126*16467b97STreehugger Robot 
127*16467b97STreehugger Robot     /// <summary>
128*16467b97STreehugger Robot     /// You may want to commit to a backtrack but don't want to force the
129*16467b97STreehugger Robot     /// stream to keep bookkeeping objects around for a marker that is
130*16467b97STreehugger Robot     /// no longer necessary.  This will have the same behavior as
131*16467b97STreehugger Robot     /// <see cref="IIntStream.Rewind(Integer)"/> except it releases resources without
132*16467b97STreehugger Robot     /// the backward seek.
133*16467b97STreehugger Robot     /// </summary>
134*16467b97STreehugger Robot     /// <remarks>
135*16467b97STreehugger Robot     /// This must throw away resources for all markers back to the marker
136*16467b97STreehugger Robot     /// argument. So if you're nested 5 levels of Mark(), and then Release(2)
137*16467b97STreehugger Robot     /// you have to release resources for depths 2..5.
138*16467b97STreehugger Robot     /// </remarks>
139*16467b97STreehugger Robot     procedure Release(const Marker: Integer);
140*16467b97STreehugger Robot 
141*16467b97STreehugger Robot     /// <summary>
142*16467b97STreehugger Robot     /// Set the input cursor to the position indicated by index.  This is
143*16467b97STreehugger Robot     /// normally used to seek ahead in the input stream.
144*16467b97STreehugger Robot     /// </summary>
145*16467b97STreehugger Robot     /// <remarks>
146*16467b97STreehugger Robot     /// No buffering is required to do this unless you know your stream
147*16467b97STreehugger Robot     /// will use seek to move backwards such as when backtracking.
148*16467b97STreehugger Robot     ///
149*16467b97STreehugger Robot     /// This is different from rewind in its multi-directional requirement
150*16467b97STreehugger Robot     /// and in that its argument is strictly an input cursor (index).
151*16467b97STreehugger Robot     ///
152*16467b97STreehugger Robot     /// For char streams, seeking forward must update the stream state such
153*16467b97STreehugger Robot     /// as line number.  For seeking backwards, you will be presumably
154*16467b97STreehugger Robot     /// backtracking using the
155*16467b97STreehugger Robot     /// <see cref="IIntStream.Mark"/>/<see cref="IIntStream.Rewind(Integer)"/>
156*16467b97STreehugger Robot     /// mechanism that restores state and so this method does not need to
157*16467b97STreehugger Robot     /// update state when seeking backwards.
158*16467b97STreehugger Robot     ///
159*16467b97STreehugger Robot     /// Currently, this method is only used for efficient backtracking using
160*16467b97STreehugger Robot     /// memoization, but in the future it may be used for incremental parsing.
161*16467b97STreehugger Robot     ///
162*16467b97STreehugger Robot     /// The index is 0..N-1. A seek to position i means that LA(1) will return
163*16467b97STreehugger Robot     /// the ith symbol.  So, seeking to 0 means LA(1) will return the first
164*16467b97STreehugger Robot     /// element in the stream.
165*16467b97STreehugger Robot     /// </remarks>
166*16467b97STreehugger Robot     procedure Seek(const Index: Integer);
167*16467b97STreehugger Robot 
168*16467b97STreehugger Robot     /// <summary>Returns the size of the entire stream.</summary>
169*16467b97STreehugger Robot     /// <remarks>
170*16467b97STreehugger Robot     /// Only makes sense for streams that buffer everything up probably,
171*16467b97STreehugger Robot     /// but might be useful to display the entire stream or for testing.
172*16467b97STreehugger Robot     /// This value includes a single EOF.
173*16467b97STreehugger Robot     /// </remarks>
Size()174*16467b97STreehugger Robot     function Size: Integer;
175*16467b97STreehugger Robot 
176*16467b97STreehugger Robot     { Properties }
177*16467b97STreehugger Robot 
178*16467b97STreehugger Robot     /// <summary>
179*16467b97STreehugger Robot     /// Where are you getting symbols from?  Normally, implementations will
180*16467b97STreehugger Robot     /// pass the buck all the way to the lexer who can ask its input stream
181*16467b97STreehugger Robot     /// for the file name or whatever.
182*16467b97STreehugger Robot     /// </summary>
183*16467b97STreehugger Robot     property SourceName: String read GetSourceName;
184*16467b97STreehugger Robot   end;
185*16467b97STreehugger Robot 
186*16467b97STreehugger Robot   /// <summary>A source of characters for an ANTLR lexer </summary>
187*16467b97STreehugger Robot   ICharStream = interface(IIntStream)
188*16467b97STreehugger Robot   ['{C30EF0DB-F4BD-4CBC-8C8F-828DABB6FF36}']
189*16467b97STreehugger Robot     { Property accessors }
GetLine()190*16467b97STreehugger Robot     function GetLine: Integer;
191*16467b97STreehugger Robot     procedure SetLine(const Value: Integer);
GetCharPositionInLine()192*16467b97STreehugger Robot     function GetCharPositionInLine: Integer;
193*16467b97STreehugger Robot     procedure SetCharPositionInLine(const Value: Integer);
194*16467b97STreehugger Robot 
195*16467b97STreehugger Robot     { Methods }
196*16467b97STreehugger Robot 
197*16467b97STreehugger Robot     /// <summary>
198*16467b97STreehugger Robot     /// Get the ith character of lookahead.  This is usually the same as
199*16467b97STreehugger Robot     /// LA(I).  This will be used for labels in the generated lexer code.
200*16467b97STreehugger Robot     /// I'd prefer to return a char here type-wise, but it's probably
201*16467b97STreehugger Robot     /// better to be 32-bit clean and be consistent with LA.
202*16467b97STreehugger Robot     /// </summary>
LT(const I: Integer)203*16467b97STreehugger Robot     function LT(const I: Integer): Integer;
204*16467b97STreehugger Robot 
205*16467b97STreehugger Robot     /// <summary>
206*16467b97STreehugger Robot     /// This primarily a useful interface for action code (just make sure
207*16467b97STreehugger Robot     /// actions don't use this on streams that don't support it).
208*16467b97STreehugger Robot     /// For infinite streams, you don't need this.
209*16467b97STreehugger Robot     /// </summary>
Substring(const Start, Stop: Integer)210*16467b97STreehugger Robot     function Substring(const Start, Stop: Integer): String;
211*16467b97STreehugger Robot 
212*16467b97STreehugger Robot     { Properties }
213*16467b97STreehugger Robot 
214*16467b97STreehugger Robot     /// <summary>
215*16467b97STreehugger Robot     /// The current line in the character stream (ANTLR tracks the
216*16467b97STreehugger Robot     /// line information automatically. To support rewinding character
217*16467b97STreehugger Robot     /// streams, we are able to [re-]set the line.
218*16467b97STreehugger Robot     /// </summary>
219*16467b97STreehugger Robot     property Line: Integer read GetLine write SetLine;
220*16467b97STreehugger Robot 
221*16467b97STreehugger Robot     /// <summary>
222*16467b97STreehugger Robot     /// The index of the character relative to the beginning of the
223*16467b97STreehugger Robot     /// line (0..N-1). To support rewinding character streams, we are
224*16467b97STreehugger Robot     /// able to [re-]set the character position.
225*16467b97STreehugger Robot     /// </summary>
226*16467b97STreehugger Robot     property CharPositionInLine: Integer read GetCharPositionInLine write SetCharPositionInLine;
227*16467b97STreehugger Robot   end;
228*16467b97STreehugger Robot 
229*16467b97STreehugger Robot   IToken = interface(IANTLRInterface)
230*16467b97STreehugger Robot   ['{73BF129C-2F45-4C68-838E-BF5D3536AC6D}']
231*16467b97STreehugger Robot     { Property accessors }
GetTokenType()232*16467b97STreehugger Robot     function GetTokenType: Integer;
233*16467b97STreehugger Robot     procedure SetTokenType(const Value: Integer);
GetLine()234*16467b97STreehugger Robot     function GetLine: Integer;
235*16467b97STreehugger Robot     procedure SetLine(const Value: Integer);
GetCharPositionInLine()236*16467b97STreehugger Robot     function GetCharPositionInLine: Integer;
237*16467b97STreehugger Robot     procedure SetCharPositionInLine(const Value: Integer);
GetChannel()238*16467b97STreehugger Robot     function GetChannel: Integer;
239*16467b97STreehugger Robot     procedure SetChannel(const Value: Integer);
GetTokenIndex()240*16467b97STreehugger Robot     function GetTokenIndex: Integer;
241*16467b97STreehugger Robot     procedure SetTokenIndex(const Value: Integer);
GetText()242*16467b97STreehugger Robot     function GetText: String;
243*16467b97STreehugger Robot     procedure SetText(const Value: String);
244*16467b97STreehugger Robot 
245*16467b97STreehugger Robot     { Properties }
246*16467b97STreehugger Robot     property TokenType: Integer read GetTokenType write SetTokenType;
247*16467b97STreehugger Robot 
248*16467b97STreehugger Robot     /// <summary>The line number on which this token was matched; line=1..N</summary>
249*16467b97STreehugger Robot     property Line: Integer read GetLine write SetLine;
250*16467b97STreehugger Robot 
251*16467b97STreehugger Robot     /// <summary>
252*16467b97STreehugger Robot     /// The index of the first character relative to the beginning of the line 0..N-1
253*16467b97STreehugger Robot     /// </summary>
254*16467b97STreehugger Robot     property CharPositionInLine: Integer read GetCharPositionInLine write SetCharPositionInLine;
255*16467b97STreehugger Robot 
256*16467b97STreehugger Robot     /// <summary>The line number on which this token was matched; line=1..N</summary>
257*16467b97STreehugger Robot     property Channel: Integer read GetChannel write SetChannel;
258*16467b97STreehugger Robot 
259*16467b97STreehugger Robot     /// <summary>
260*16467b97STreehugger Robot     /// An index from 0..N-1 of the token object in the input stream
261*16467b97STreehugger Robot     /// </summary>
262*16467b97STreehugger Robot     /// <remarks>
263*16467b97STreehugger Robot     /// This must be valid in order to use the ANTLRWorks debugger.
264*16467b97STreehugger Robot     /// </remarks>
265*16467b97STreehugger Robot     property TokenIndex: Integer read GetTokenIndex write SetTokenIndex;
266*16467b97STreehugger Robot 
267*16467b97STreehugger Robot     /// <summary>The text of the token</summary>
268*16467b97STreehugger Robot     /// <remarks>
269*16467b97STreehugger Robot     /// When setting the text, it might be a NOP such as for the CommonToken,
270*16467b97STreehugger Robot     /// which doesn't have string pointers, just indexes into a char buffer.
271*16467b97STreehugger Robot     /// </remarks>
272*16467b97STreehugger Robot     property Text: String read GetText write SetText;
273*16467b97STreehugger Robot   end;
274*16467b97STreehugger Robot 
275*16467b97STreehugger Robot   /// <summary>
276*16467b97STreehugger Robot   /// A source of tokens must provide a sequence of tokens via NextToken()
277*16467b97STreehugger Robot   /// and also must reveal it's source of characters; CommonToken's text is
278*16467b97STreehugger Robot   /// computed from a CharStream; it only store indices into the char stream.
279*16467b97STreehugger Robot   ///
280*16467b97STreehugger Robot   /// Errors from the lexer are never passed to the parser.  Either you want
281*16467b97STreehugger Robot   /// to keep going or you do not upon token recognition error.  If you do not
282*16467b97STreehugger Robot   /// want to continue lexing then you do not want to continue parsing.  Just
283*16467b97STreehugger Robot   /// throw an exception not under RecognitionException and Delphi will naturally
284*16467b97STreehugger Robot   /// toss you all the way out of the recognizers.  If you want to continue
285*16467b97STreehugger Robot   /// lexing then you should not throw an exception to the parser--it has already
286*16467b97STreehugger Robot   /// requested a token.  Keep lexing until you get a valid one.  Just report
287*16467b97STreehugger Robot   /// errors and keep going, looking for a valid token.
288*16467b97STreehugger Robot   /// </summary>
289*16467b97STreehugger Robot   ITokenSource = interface(IANTLRInterface)
290*16467b97STreehugger Robot   ['{2C71FAD0-AEEE-417D-B576-4059F7C4CEB4}']
291*16467b97STreehugger Robot     { Property accessors }
GetSourceName()292*16467b97STreehugger Robot     function GetSourceName: String;
293*16467b97STreehugger Robot 
294*16467b97STreehugger Robot     { Methods }
295*16467b97STreehugger Robot 
296*16467b97STreehugger Robot     /// <summary>
297*16467b97STreehugger Robot     /// Returns a Token object from the input stream (usually a CharStream).
298*16467b97STreehugger Robot     /// Does not fail/return upon lexing error; just keeps chewing on the
299*16467b97STreehugger Robot     /// characters until it gets a good one; errors are not passed through
300*16467b97STreehugger Robot     /// to the parser.
301*16467b97STreehugger Robot     /// </summary>
NextToken()302*16467b97STreehugger Robot     function NextToken: IToken;
303*16467b97STreehugger Robot 
304*16467b97STreehugger Robot     { Properties }
305*16467b97STreehugger Robot 
306*16467b97STreehugger Robot     /// <summary>
307*16467b97STreehugger Robot     /// Where are you getting tokens from? normally the implication will simply
308*16467b97STreehugger Robot     /// ask lexers input stream.
309*16467b97STreehugger Robot     /// </summary>
310*16467b97STreehugger Robot     property SourceName: String read GetSourceName;
311*16467b97STreehugger Robot   end;
312*16467b97STreehugger Robot 
313*16467b97STreehugger Robot   /// <summary>A stream of tokens accessing tokens from a TokenSource </summary>
314*16467b97STreehugger Robot   ITokenStream = interface(IIntStream)
315*16467b97STreehugger Robot   ['{59E5B39D-31A6-496D-9FA9-AC75CC584B68}']
316*16467b97STreehugger Robot     { Property accessors }
GetTokenSource()317*16467b97STreehugger Robot     function GetTokenSource: ITokenSource;
318*16467b97STreehugger Robot     procedure SetTokenSource(const Value: ITokenSource);
319*16467b97STreehugger Robot 
320*16467b97STreehugger Robot     { Methods }
321*16467b97STreehugger Robot 
322*16467b97STreehugger Robot     /// <summary>
323*16467b97STreehugger Robot     /// Get Token at current input pointer + I ahead (where I=1 is next
324*16467b97STreehugger Robot     /// Token).
325*16467b97STreehugger Robot     /// I &lt; 0 indicates tokens in the past.  So -1 is previous token and -2 is
326*16467b97STreehugger Robot     /// two tokens ago. LT(0) is undefined.  For I>=N, return Token.EOFToken.
327*16467b97STreehugger Robot     /// Return null for LT(0) and any index that results in an absolute address
328*16467b97STreehugger Robot     /// that is negative.
329*16467b97STreehugger Robot     /// </summary>
LT(const K: Integer)330*16467b97STreehugger Robot     function LT(const K: Integer): IToken;
331*16467b97STreehugger Robot 
332*16467b97STreehugger Robot     /// <summary>
333*16467b97STreehugger Robot     /// Get a token at an absolute index I; 0..N-1.  This is really only
334*16467b97STreehugger Robot     /// needed for profiling and debugging and token stream rewriting.
335*16467b97STreehugger Robot     /// If you don't want to buffer up tokens, then this method makes no
336*16467b97STreehugger Robot     /// sense for you.  Naturally you can't use the rewrite stream feature.
337*16467b97STreehugger Robot     /// I believe DebugTokenStream can easily be altered to not use
338*16467b97STreehugger Robot     /// this method, removing the dependency.
339*16467b97STreehugger Robot     /// </summary>
Get(const I: Integer)340*16467b97STreehugger Robot     function Get(const I: Integer): IToken;
341*16467b97STreehugger Robot 
342*16467b97STreehugger Robot     /// <summary>Return the text of all tokens from start to stop, inclusive.
343*16467b97STreehugger Robot     /// If the stream does not buffer all the tokens then it can just
344*16467b97STreehugger Robot     /// return '';  Users should not access $ruleLabel.text in
345*16467b97STreehugger Robot     /// an action of course in that case.
346*16467b97STreehugger Robot     /// </summary>
ToString(const Start, Stop: Integer)347*16467b97STreehugger Robot     function ToString(const Start, Stop: Integer): String; overload;
348*16467b97STreehugger Robot 
349*16467b97STreehugger Robot     /// <summary>Because the user is not required to use a token with an index stored
350*16467b97STreehugger Robot     /// in it, we must provide a means for two token objects themselves to
351*16467b97STreehugger Robot     /// indicate the start/end location.  Most often this will just delegate
352*16467b97STreehugger Robot     /// to the other ToString(Integer,Integer).  This is also parallel with
353*16467b97STreehugger Robot     /// the TreeNodeStream.ToString(Object,Object).
354*16467b97STreehugger Robot     /// </summary>
ToString(const Start, Stop: IToken)355*16467b97STreehugger Robot     function ToString(const Start, Stop: IToken): String; overload;
356*16467b97STreehugger Robot 
357*16467b97STreehugger Robot     { Properties }
358*16467b97STreehugger Robot     property TokenSource: ITokenSource read GetTokenSource write SetTokenSource;
359*16467b97STreehugger Robot   end;
360*16467b97STreehugger Robot 
361*16467b97STreehugger Robot   /// <summary>
362*16467b97STreehugger Robot   /// This is the complete state of a stream.
363*16467b97STreehugger Robot   ///
364*16467b97STreehugger Robot   /// When walking ahead with cyclic DFA for syntactic predicates, we
365*16467b97STreehugger Robot   /// need to record the state of the input stream (char index, line,
366*16467b97STreehugger Robot   /// etc...) so that we can rewind the state after scanning ahead.
367*16467b97STreehugger Robot   /// </summary>
368*16467b97STreehugger Robot   ICharStreamState = interface(IANTLRInterface)
369*16467b97STreehugger Robot   ['{62D2A1CD-ED3A-4C95-A366-AB8F2E54060B}']
370*16467b97STreehugger Robot     { Property accessors }
GetP()371*16467b97STreehugger Robot     function GetP: Integer;
372*16467b97STreehugger Robot     procedure SetP(const Value: Integer);
GetLine()373*16467b97STreehugger Robot     function GetLine: Integer;
374*16467b97STreehugger Robot     procedure SetLine(const Value: Integer);
GetCharPositionInLine()375*16467b97STreehugger Robot     function GetCharPositionInLine: Integer;
376*16467b97STreehugger Robot     procedure SetCharPositionInLine(const Value: Integer);
377*16467b97STreehugger Robot 
378*16467b97STreehugger Robot     { Properties }
379*16467b97STreehugger Robot     /// <summary>Index into the char stream of next lookahead char </summary>
380*16467b97STreehugger Robot     property P: Integer read GetP write SetP;
381*16467b97STreehugger Robot 
382*16467b97STreehugger Robot     /// <summary>What line number is the scanner at before processing buffer[P]? </summary>
383*16467b97STreehugger Robot     property Line: Integer read GetLine write SetLine;
384*16467b97STreehugger Robot 
385*16467b97STreehugger Robot     /// <summary>What char position 0..N-1 in line is scanner before processing buffer[P]? </summary>
386*16467b97STreehugger Robot     property CharPositionInLine: Integer read GetCharPositionInLine write SetCharPositionInLine;
387*16467b97STreehugger Robot   end;
388*16467b97STreehugger Robot 
389*16467b97STreehugger Robot   /// <summary>
390*16467b97STreehugger Robot   /// A pretty quick <see cref="ICharStream"/> that uses a character array
391*16467b97STreehugger Robot   /// directly as it's underlying source.
392*16467b97STreehugger Robot   /// </summary>
393*16467b97STreehugger Robot   IANTLRStringStream = interface(ICharStream)
394*16467b97STreehugger Robot   ['{2FA24299-FF97-4AB6-8CA6-5D3DA13C4AB2}']
395*16467b97STreehugger Robot     { Methods }
396*16467b97STreehugger Robot 
397*16467b97STreehugger Robot     /// <summary>
398*16467b97STreehugger Robot     /// Resets the stream so that it is in the same state it was
399*16467b97STreehugger Robot     /// when the object was created *except* the data array is not
400*16467b97STreehugger Robot     /// touched.
401*16467b97STreehugger Robot     /// </summary>
402*16467b97STreehugger Robot     procedure Reset;
403*16467b97STreehugger Robot 
404*16467b97STreehugger Robot   end;
405*16467b97STreehugger Robot 
406*16467b97STreehugger Robot   /// <summary>
407*16467b97STreehugger Robot   /// A character stream - an <see cref="ICharStream"/> - that loads
408*16467b97STreehugger Robot   /// and caches the contents of it's underlying file fully during
409*16467b97STreehugger Robot   /// object construction
410*16467b97STreehugger Robot   /// </summary>
411*16467b97STreehugger Robot   /// <remarks>
412*16467b97STreehugger Robot   /// This looks very much like an ANTLReaderStream or an ANTLRInputStream
413*16467b97STreehugger Robot   /// but, it is a special case. Since we know the exact size of the file to
414*16467b97STreehugger Robot   /// load, we can avoid lots of data copying and buffer resizing.
415*16467b97STreehugger Robot   /// </remarks>
416*16467b97STreehugger Robot   IANTLRFileStream = interface(IANTLRStringStream)
417*16467b97STreehugger Robot   ['{2B0145DB-2DAA-48A0-8316-B47A69EDDD1A}']
418*16467b97STreehugger Robot     { Methods }
419*16467b97STreehugger Robot 
420*16467b97STreehugger Robot     /// <summary>
421*16467b97STreehugger Robot     /// Loads and buffers the specified file to be used as this
422*16467b97STreehugger Robot     /// ANTLRFileStream's source
423*16467b97STreehugger Robot     /// </summary>
424*16467b97STreehugger Robot     /// <param name="FileName">File to load</param>
425*16467b97STreehugger Robot     /// <param name="Encoding">Encoding to apply to file</param>
426*16467b97STreehugger Robot     procedure Load(const FileName: String; const Encoding: TEncoding);
427*16467b97STreehugger Robot   end;
428*16467b97STreehugger Robot 
429*16467b97STreehugger Robot   /// <summary>
430*16467b97STreehugger Robot   /// A stripped-down version of org.antlr.misc.BitSet that is just
431*16467b97STreehugger Robot   /// good enough to handle runtime requirements such as FOLLOW sets
432*16467b97STreehugger Robot   /// for automatic error recovery.
433*16467b97STreehugger Robot   /// </summary>
434*16467b97STreehugger Robot   IBitSet = interface(IANTLRInterface)
435*16467b97STreehugger Robot   ['{F2045045-FC46-4779-A65D-56C65D257A8E}']
436*16467b97STreehugger Robot     { Property accessors }
GetIsNil()437*16467b97STreehugger Robot     function GetIsNil: Boolean;
438*16467b97STreehugger Robot 
439*16467b97STreehugger Robot     { Methods }
440*16467b97STreehugger Robot 
441*16467b97STreehugger Robot     /// <summary>return "this or a" in a new set </summary>
BitSetOr(const A: IBitSet)442*16467b97STreehugger Robot     function BitSetOr(const A: IBitSet): IBitSet;
443*16467b97STreehugger Robot 
444*16467b97STreehugger Robot     /// <summary>Or this element into this set (grow as necessary to accommodate)</summary>
445*16467b97STreehugger Robot     procedure Add(const El: Integer);
446*16467b97STreehugger Robot 
447*16467b97STreehugger Robot     /// <summary> Grows the set to a larger number of bits.</summary>
448*16467b97STreehugger Robot     /// <param name="bit">element that must fit in set
449*16467b97STreehugger Robot     /// </param>
450*16467b97STreehugger Robot     procedure GrowToInclude(const Bit: Integer);
451*16467b97STreehugger Robot 
452*16467b97STreehugger Robot     procedure OrInPlace(const A: IBitSet);
Size()453*16467b97STreehugger Robot     function Size: Integer;
Member(const El: Integer)454*16467b97STreehugger Robot     function Member(const El: Integer): Boolean;
455*16467b97STreehugger Robot 
456*16467b97STreehugger Robot     // remove this element from this set
457*16467b97STreehugger Robot     procedure Remove(const El: Integer);
458*16467b97STreehugger Robot 
NumBits()459*16467b97STreehugger Robot     function NumBits: Integer;
460*16467b97STreehugger Robot 
461*16467b97STreehugger Robot     /// <summary>return how much space is being used by the bits array not
462*16467b97STreehugger Robot     /// how many actually have member bits on.
463*16467b97STreehugger Robot     /// </summary>
LengthInLongWords()464*16467b97STreehugger Robot     function LengthInLongWords: Integer;
465*16467b97STreehugger Robot 
ToArray()466*16467b97STreehugger Robot     function ToArray: TIntegerArray;
ToPackedArray()467*16467b97STreehugger Robot     function ToPackedArray: TUInt64Array;
468*16467b97STreehugger Robot 
ToString()469*16467b97STreehugger Robot     function ToString: String; overload;
ToString(const TokenNames: TStringArray)470*16467b97STreehugger Robot     function ToString(const TokenNames: TStringArray): String; overload;
Equals(Obj: TObject)471*16467b97STreehugger Robot     function Equals(Obj: TObject): Boolean;
472*16467b97STreehugger Robot 
473*16467b97STreehugger Robot     { Properties }
474*16467b97STreehugger Robot     property IsNil: Boolean read GetIsNil;
475*16467b97STreehugger Robot   end;
476*16467b97STreehugger Robot   TBitSetArray = array of IBitSet;
477*16467b97STreehugger Robot 
478*16467b97STreehugger Robot   /// <summary>
479*16467b97STreehugger Robot   /// The set of fields needed by an abstract recognizer to recognize input
480*16467b97STreehugger Robot   /// and recover from errors
481*16467b97STreehugger Robot   /// </summary>
482*16467b97STreehugger Robot   /// <remarks>
483*16467b97STreehugger Robot   /// As a separate state object, it can be shared among multiple grammars;
484*16467b97STreehugger Robot   /// e.g., when one grammar imports another.
485*16467b97STreehugger Robot   /// These fields are publicly visible but the actual state pointer per
486*16467b97STreehugger Robot   /// parser is protected.
487*16467b97STreehugger Robot   /// </remarks>
488*16467b97STreehugger Robot   IRecognizerSharedState = interface(IANTLRInterface)
489*16467b97STreehugger Robot   ['{6CB6E17A-0B01-4AA7-8D49-5742A3CB8901}']
490*16467b97STreehugger Robot     { Property accessors }
GetFollowing()491*16467b97STreehugger Robot     function GetFollowing: TBitSetArray;
492*16467b97STreehugger Robot     procedure SetFollowing(const Value: TBitSetArray);
GetFollowingStackPointer()493*16467b97STreehugger Robot     function GetFollowingStackPointer: Integer;
494*16467b97STreehugger Robot     procedure SetFollowingStackPointer(const Value: Integer);
GetErrorRecovery()495*16467b97STreehugger Robot     function GetErrorRecovery: Boolean;
496*16467b97STreehugger Robot     procedure SetErrorRecovery(const Value: Boolean);
GetLastErrorIndex()497*16467b97STreehugger Robot     function GetLastErrorIndex: Integer;
498*16467b97STreehugger Robot     procedure SetLastErrorIndex(const Value: Integer);
GetFailed()499*16467b97STreehugger Robot     function GetFailed: Boolean;
500*16467b97STreehugger Robot     procedure SetFailed(const Value: Boolean);
GetSyntaxErrors()501*16467b97STreehugger Robot     function GetSyntaxErrors: Integer;
502*16467b97STreehugger Robot     procedure SetSyntaxErrors(const Value: Integer);
GetBacktracking()503*16467b97STreehugger Robot     function GetBacktracking: Integer;
504*16467b97STreehugger Robot     procedure SetBacktracking(const Value: Integer);
GetRuleMemo()505*16467b97STreehugger Robot     function GetRuleMemo: TDictionaryArray<Integer, Integer>;
GetRuleMemoCount()506*16467b97STreehugger Robot     function GetRuleMemoCount: Integer;
507*16467b97STreehugger Robot     procedure SetRuleMemoCount(const Value: Integer);
GetToken()508*16467b97STreehugger Robot     function GetToken: IToken;
509*16467b97STreehugger Robot     procedure SetToken(const Value: IToken);
GetTokenStartCharIndex()510*16467b97STreehugger Robot     function GetTokenStartCharIndex: Integer;
511*16467b97STreehugger Robot     procedure SetTokenStartCharIndex(const Value: Integer);
GetTokenStartLine()512*16467b97STreehugger Robot     function GetTokenStartLine: Integer;
513*16467b97STreehugger Robot     procedure SetTokenStartLine(const Value: Integer);
GetTokenStartCharPositionInLine()514*16467b97STreehugger Robot     function GetTokenStartCharPositionInLine: Integer;
515*16467b97STreehugger Robot     procedure SetTokenStartCharPositionInLine(const Value: Integer);
GetChannel()516*16467b97STreehugger Robot     function GetChannel: Integer;
517*16467b97STreehugger Robot     procedure SetChannel(const Value: Integer);
GetTokenType()518*16467b97STreehugger Robot     function GetTokenType: Integer;
519*16467b97STreehugger Robot     procedure SetTokenType(const Value: Integer);
GetText()520*16467b97STreehugger Robot     function GetText: String;
521*16467b97STreehugger Robot     procedure SetText(const Value: String);
522*16467b97STreehugger Robot 
523*16467b97STreehugger Robot     { Properties }
524*16467b97STreehugger Robot 
525*16467b97STreehugger Robot     /// <summary>
526*16467b97STreehugger Robot     /// Tracks the set of token types that can follow any rule invocation.
527*16467b97STreehugger Robot     /// Stack grows upwards.  When it hits the max, it grows 2x in size
528*16467b97STreehugger Robot     /// and keeps going.
529*16467b97STreehugger Robot     /// </summary>
530*16467b97STreehugger Robot     property Following: TBitSetArray read GetFollowing write SetFollowing;
531*16467b97STreehugger Robot     property FollowingStackPointer: Integer read GetFollowingStackPointer write SetFollowingStackPointer;
532*16467b97STreehugger Robot 
533*16467b97STreehugger Robot     /// <summary>
534*16467b97STreehugger Robot     /// This is true when we see an error and before having successfully
535*16467b97STreehugger Robot     /// matched a token.  Prevents generation of more than one error message
536*16467b97STreehugger Robot     /// per error.
537*16467b97STreehugger Robot     /// </summary>
538*16467b97STreehugger Robot     property ErrorRecovery: Boolean read GetErrorRecovery write SetErrorRecovery;
539*16467b97STreehugger Robot 
540*16467b97STreehugger Robot     /// <summary>
541*16467b97STreehugger Robot     /// The index into the input stream where the last error occurred.
542*16467b97STreehugger Robot     /// </summary>
543*16467b97STreehugger Robot     /// <remarks>
544*16467b97STreehugger Robot     /// This is used to prevent infinite loops where an error is found
545*16467b97STreehugger Robot     /// but no token is consumed during recovery...another error is found,
546*16467b97STreehugger Robot     /// ad naseum.  This is a failsafe mechanism to guarantee that at least
547*16467b97STreehugger Robot     /// one token/tree node is consumed for two errors.
548*16467b97STreehugger Robot     /// </remarks>
549*16467b97STreehugger Robot     property LastErrorIndex: Integer read GetLastErrorIndex write SetLastErrorIndex;
550*16467b97STreehugger Robot 
551*16467b97STreehugger Robot     /// <summary>
552*16467b97STreehugger Robot     /// In lieu of a return value, this indicates that a rule or token
553*16467b97STreehugger Robot     /// has failed to match.  Reset to false upon valid token match.
554*16467b97STreehugger Robot     /// </summary>
555*16467b97STreehugger Robot     property Failed: Boolean read GetFailed write SetFailed;
556*16467b97STreehugger Robot 
557*16467b97STreehugger Robot     /// <summary>
558*16467b97STreehugger Robot     /// Did the recognizer encounter a syntax error?  Track how many.
559*16467b97STreehugger Robot     /// </summary>
560*16467b97STreehugger Robot     property SyntaxErrors: Integer read GetSyntaxErrors write SetSyntaxErrors;
561*16467b97STreehugger Robot 
562*16467b97STreehugger Robot     /// <summary>
563*16467b97STreehugger Robot     /// If 0, no backtracking is going on.  Safe to exec actions etc...
564*16467b97STreehugger Robot     /// If >0 then it's the level of backtracking.
565*16467b97STreehugger Robot     /// </summary>
566*16467b97STreehugger Robot     property Backtracking: Integer read GetBacktracking write SetBacktracking;
567*16467b97STreehugger Robot 
568*16467b97STreehugger Robot     /// <summary>
569*16467b97STreehugger Robot     /// An array[size num rules] of Map&lt;Integer,Integer&gt; that tracks
570*16467b97STreehugger Robot     /// the stop token index for each rule.
571*16467b97STreehugger Robot     /// </summary>
572*16467b97STreehugger Robot     /// <remarks>
573*16467b97STreehugger Robot     ///  RuleMemo[RuleIndex] is the memoization table for RuleIndex.
574*16467b97STreehugger Robot     ///  For key RuleStartIndex, you get back the stop token for
575*16467b97STreehugger Robot     ///  associated rule or MEMO_RULE_FAILED.
576*16467b97STreehugger Robot     ///
577*16467b97STreehugger Robot     ///  This is only used if rule memoization is on (which it is by default).
578*16467b97STreehugger Robot     ///  </remarks>
579*16467b97STreehugger Robot     property RuleMemo: TDictionaryArray<Integer, Integer> read GetRuleMemo;
580*16467b97STreehugger Robot     property RuleMemoCount: Integer read GetRuleMemoCount write SetRuleMemoCount;
581*16467b97STreehugger Robot 
582*16467b97STreehugger Robot     // Lexer Specific Members
583*16467b97STreehugger Robot     // LEXER FIELDS (must be in same state object to avoid casting
584*16467b97STreehugger Robot     //               constantly in generated code and Lexer object) :(
585*16467b97STreehugger Robot 
586*16467b97STreehugger Robot     /// <summary>
587*16467b97STreehugger Robot     /// Token object normally returned by NextToken() after matching lexer rules.
588*16467b97STreehugger Robot     /// </summary>
589*16467b97STreehugger Robot     /// <remarks>
590*16467b97STreehugger Robot     /// The goal of all lexer rules/methods is to create a token object.
591*16467b97STreehugger Robot     /// This is an instance variable as multiple rules may collaborate to
592*16467b97STreehugger Robot     /// create a single token.  NextToken will return this object after
593*16467b97STreehugger Robot     /// matching lexer rule(s).  If you subclass to allow multiple token
594*16467b97STreehugger Robot     /// emissions, then set this to the last token to be matched or
595*16467b97STreehugger Robot     /// something nonnull so that the auto token emit mechanism will not
596*16467b97STreehugger Robot     /// emit another token.
597*16467b97STreehugger Robot     /// </remarks>
598*16467b97STreehugger Robot     property Token: IToken read GetToken write SetToken;
599*16467b97STreehugger Robot 
600*16467b97STreehugger Robot     /// <summary>
601*16467b97STreehugger Robot     /// What character index in the stream did the current token start at?
602*16467b97STreehugger Robot     /// </summary>
603*16467b97STreehugger Robot     /// <remarks>
604*16467b97STreehugger Robot     /// Needed, for example, to get the text for current token.  Set at
605*16467b97STreehugger Robot     /// the start of nextToken.
606*16467b97STreehugger Robot     /// </remarks>
607*16467b97STreehugger Robot     property TokenStartCharIndex: Integer read GetTokenStartCharIndex write SetTokenStartCharIndex;
608*16467b97STreehugger Robot 
609*16467b97STreehugger Robot     /// <summary>
610*16467b97STreehugger Robot     /// The line on which the first character of the token resides
611*16467b97STreehugger Robot     /// </summary>
612*16467b97STreehugger Robot     property TokenStartLine: Integer read GetTokenStartLine write SetTokenStartLine;
613*16467b97STreehugger Robot 
614*16467b97STreehugger Robot     /// <summary>The character position of first character within the line</summary>
615*16467b97STreehugger Robot     property TokenStartCharPositionInLine: Integer read GetTokenStartCharPositionInLine write SetTokenStartCharPositionInLine;
616*16467b97STreehugger Robot 
617*16467b97STreehugger Robot     /// <summary>The channel number for the current token</summary>
618*16467b97STreehugger Robot     property Channel: Integer read GetChannel write SetChannel;
619*16467b97STreehugger Robot 
620*16467b97STreehugger Robot     /// <summary>The token type for the current token</summary>
621*16467b97STreehugger Robot     property TokenType: Integer read GetTokenType write SetTokenType;
622*16467b97STreehugger Robot 
623*16467b97STreehugger Robot     /// <summary>
624*16467b97STreehugger Robot     /// You can set the text for the current token to override what is in
625*16467b97STreehugger Robot     /// the input char buffer.  Use setText() or can set this instance var.
626*16467b97STreehugger Robot     /// </summary>
627*16467b97STreehugger Robot     property Text: String read GetText write SetText;
628*16467b97STreehugger Robot   end;
629*16467b97STreehugger Robot 
630*16467b97STreehugger Robot   ICommonToken = interface(IToken)
631*16467b97STreehugger Robot   ['{06B1B0C3-2A0D-477A-AE30-414F51ACE8A0}']
632*16467b97STreehugger Robot     { Property accessors }
GetStartIndex()633*16467b97STreehugger Robot     function GetStartIndex: Integer;
634*16467b97STreehugger Robot     procedure SetStartIndex(const Value: Integer);
GetStopIndex()635*16467b97STreehugger Robot     function GetStopIndex: Integer;
636*16467b97STreehugger Robot     procedure SetStopIndex(const Value: Integer);
GetInputStream()637*16467b97STreehugger Robot     function GetInputStream: ICharStream;
638*16467b97STreehugger Robot     procedure SetInputStream(const Value: ICharStream);
639*16467b97STreehugger Robot 
640*16467b97STreehugger Robot     { Methods }
ToString()641*16467b97STreehugger Robot     function ToString: String;
642*16467b97STreehugger Robot 
643*16467b97STreehugger Robot     { Properties }
644*16467b97STreehugger Robot     property StartIndex: Integer read GetStartIndex write SetStartIndex;
645*16467b97STreehugger Robot     property StopIndex: Integer read GetStopIndex write SetStopIndex;
646*16467b97STreehugger Robot     property InputStream: ICharStream read GetInputStream write SetInputStream;
647*16467b97STreehugger Robot   end;
648*16467b97STreehugger Robot 
649*16467b97STreehugger Robot   /// <summary>
650*16467b97STreehugger Robot   /// A Token object like we'd use in ANTLR 2.x; has an actual string created
651*16467b97STreehugger Robot   /// and associated with this object.  These objects are needed for imaginary
652*16467b97STreehugger Robot   /// tree nodes that have payload objects.  We need to create a Token object
653*16467b97STreehugger Robot   /// that has a string; the tree node will point at this token.  CommonToken
654*16467b97STreehugger Robot   /// has indexes into a char stream and hence cannot be used to introduce
655*16467b97STreehugger Robot   /// new strings.
656*16467b97STreehugger Robot   /// </summary>
657*16467b97STreehugger Robot   IClassicToken = interface(IToken)
658*16467b97STreehugger Robot     { Property accessors }
GetTokenType()659*16467b97STreehugger Robot     function GetTokenType: Integer;
660*16467b97STreehugger Robot     procedure SetTokenType(const Value: Integer);
GetLine()661*16467b97STreehugger Robot     function GetLine: Integer;
662*16467b97STreehugger Robot     procedure SetLine(const Value: Integer);
GetCharPositionInLine()663*16467b97STreehugger Robot     function GetCharPositionInLine: Integer;
664*16467b97STreehugger Robot     procedure SetCharPositionInLine(const Value: Integer);
GetChannel()665*16467b97STreehugger Robot     function GetChannel: Integer;
666*16467b97STreehugger Robot     procedure SetChannel(const Value: Integer);
GetTokenIndex()667*16467b97STreehugger Robot     function GetTokenIndex: Integer;
668*16467b97STreehugger Robot     procedure SetTokenIndex(const Value: Integer);
GetText()669*16467b97STreehugger Robot     function GetText: String;
670*16467b97STreehugger Robot     procedure SetText(const Value: String);
GetInputStream()671*16467b97STreehugger Robot     function GetInputStream: ICharStream;
672*16467b97STreehugger Robot     procedure SetInputStream(const Value: ICharStream);
673*16467b97STreehugger Robot 
674*16467b97STreehugger Robot     { Properties }
675*16467b97STreehugger Robot     property TokenType: Integer read GetTokenType write SetTokenType;
676*16467b97STreehugger Robot     property Line: Integer read GetLine write SetLine;
677*16467b97STreehugger Robot     property CharPositionInLine: Integer read GetCharPositionInLine write SetCharPositionInLine;
678*16467b97STreehugger Robot     property Channel: Integer read GetChannel write SetChannel;
679*16467b97STreehugger Robot     property TokenIndex: Integer read GetTokenIndex write SetTokenIndex;
680*16467b97STreehugger Robot     property Text: String read GetText write SetText;
681*16467b97STreehugger Robot     property InputStream: ICharStream read GetInputStream write SetInputStream;
682*16467b97STreehugger Robot   end;
683*16467b97STreehugger Robot 
684*16467b97STreehugger Robot   /// <summary>
685*16467b97STreehugger Robot   /// A generic recognizer that can handle recognizers generated from
686*16467b97STreehugger Robot   /// lexer, parser, and tree grammars.  This is all the parsing
687*16467b97STreehugger Robot   /// support code essentially; most of it is error recovery stuff and
688*16467b97STreehugger Robot   /// backtracking.
689*16467b97STreehugger Robot   /// </summary>
690*16467b97STreehugger Robot   IBaseRecognizer = interface(IANTLRObject)
691*16467b97STreehugger Robot   ['{90813CE2-614B-4773-A26E-936E7DE7E9E9}']
692*16467b97STreehugger Robot     { Property accessors }
GetInput()693*16467b97STreehugger Robot     function GetInput: IIntStream;
GetBacktrackingLevel()694*16467b97STreehugger Robot     function GetBacktrackingLevel: Integer;
GetState()695*16467b97STreehugger Robot     function GetState: IRecognizerSharedState;
GetNumberOfSyntaxErrors()696*16467b97STreehugger Robot     function GetNumberOfSyntaxErrors: Integer;
GetGrammarFileName()697*16467b97STreehugger Robot     function GetGrammarFileName: String;
GetSourceName()698*16467b97STreehugger Robot     function GetSourceName: String;
GetTokenNames()699*16467b97STreehugger Robot     function GetTokenNames: TStringArray;
700*16467b97STreehugger Robot 
701*16467b97STreehugger Robot     { Methods }
702*16467b97STreehugger Robot     procedure BeginBacktrack(const Level: Integer);
703*16467b97STreehugger Robot     procedure EndBacktrack(const Level: Integer; const Successful: Boolean);
704*16467b97STreehugger Robot 
705*16467b97STreehugger Robot     /// <summary>Reset the parser's state. Subclasses must rewind the input stream.</summary>
706*16467b97STreehugger Robot     procedure Reset;
707*16467b97STreehugger Robot 
708*16467b97STreehugger Robot     /// <summary>
709*16467b97STreehugger Robot     /// Match current input symbol against ttype.  Attempt
710*16467b97STreehugger Robot     /// single token insertion or deletion error recovery.  If
711*16467b97STreehugger Robot     /// that fails, throw EMismatchedTokenException.
712*16467b97STreehugger Robot     /// </summary>
713*16467b97STreehugger Robot     /// <remarks>
714*16467b97STreehugger Robot     /// To turn off single token insertion or deletion error
715*16467b97STreehugger Robot     /// recovery, override MismatchRecover() and have it call
716*16467b97STreehugger Robot     /// plain Mismatch(), which does not recover. Then any error
717*16467b97STreehugger Robot     /// in a rule will cause an exception and immediate exit from
718*16467b97STreehugger Robot     /// rule. Rule would recover by resynchronizing to the set of
719*16467b97STreehugger Robot     /// symbols that can follow rule ref.
720*16467b97STreehugger Robot     /// </remarks>
Match(const Input: IIntStream; const TokenType: Integer;721*16467b97STreehugger Robot     function Match(const Input: IIntStream; const TokenType: Integer;
722*16467b97STreehugger Robot       const Follow: IBitSet): IANTLRInterface;
723*16467b97STreehugger Robot 
MismatchIsUnwantedToken(const Input: IIntStream;724*16467b97STreehugger Robot     function MismatchIsUnwantedToken(const Input: IIntStream;
725*16467b97STreehugger Robot       const TokenType: Integer): Boolean;
726*16467b97STreehugger Robot 
MismatchIsMissingToken(const Input: IIntStream;727*16467b97STreehugger Robot     function MismatchIsMissingToken(const Input: IIntStream;
728*16467b97STreehugger Robot       const Follow: IBitSet): Boolean;
729*16467b97STreehugger Robot 
730*16467b97STreehugger Robot     /// <summary>A hook to listen in on the token consumption during error recovery.
731*16467b97STreehugger Robot     /// The DebugParser subclasses this to fire events to the listenter.
732*16467b97STreehugger Robot     /// </summary>
733*16467b97STreehugger Robot     procedure BeginResync;
734*16467b97STreehugger Robot     procedure EndResync;
735*16467b97STreehugger Robot 
736*16467b97STreehugger Robot     /// <summary>
737*16467b97STreehugger Robot     /// Report a recognition problem.
738*16467b97STreehugger Robot     /// </summary>
739*16467b97STreehugger Robot     /// <remarks>
740*16467b97STreehugger Robot     /// This method sets errorRecovery to indicate the parser is recovering
741*16467b97STreehugger Robot     /// not parsing.  Once in recovery mode, no errors are generated.
742*16467b97STreehugger Robot     /// To get out of recovery mode, the parser must successfully Match
743*16467b97STreehugger Robot     /// a token (after a resync).  So it will go:
744*16467b97STreehugger Robot     ///
745*16467b97STreehugger Robot     /// 1. error occurs
746*16467b97STreehugger Robot     /// 2. enter recovery mode, report error
747*16467b97STreehugger Robot     /// 3. consume until token found in resynch set
748*16467b97STreehugger Robot     /// 4. try to resume parsing
749*16467b97STreehugger Robot     /// 5. next Match() will reset errorRecovery mode
750*16467b97STreehugger Robot     ///
751*16467b97STreehugger Robot     /// If you override, make sure to update syntaxErrors if you care about that.
752*16467b97STreehugger Robot     /// </remarks>
753*16467b97STreehugger Robot     procedure ReportError(const E: ERecognitionException);
754*16467b97STreehugger Robot 
755*16467b97STreehugger Robot     /// <summary> Match the wildcard: in a symbol</summary>
756*16467b97STreehugger Robot     procedure MatchAny(const Input: IIntStream);
757*16467b97STreehugger Robot 
758*16467b97STreehugger Robot     procedure DisplayRecognitionError(const TokenNames: TStringArray;
759*16467b97STreehugger Robot       const E: ERecognitionException);
760*16467b97STreehugger Robot 
761*16467b97STreehugger Robot     /// <summary>
762*16467b97STreehugger Robot     /// What error message should be generated for the various exception types?
763*16467b97STreehugger Robot     ///
764*16467b97STreehugger Robot     /// Not very object-oriented code, but I like having all error message generation
765*16467b97STreehugger Robot     /// within one method rather than spread among all of the exception classes. This
766*16467b97STreehugger Robot     /// also makes it much easier for the exception handling because the exception
767*16467b97STreehugger Robot     /// classes do not have to have pointers back to this object to access utility
768*16467b97STreehugger Robot     /// routines and so on. Also, changing the message for an exception type would be
769*16467b97STreehugger Robot     /// difficult because you would have to subclassing exception, but then somehow get
770*16467b97STreehugger Robot     /// ANTLR to make those kinds of exception objects instead of the default.
771*16467b97STreehugger Robot     ///
772*16467b97STreehugger Robot     /// This looks weird, but trust me--it makes the most sense in terms of flexibility.
773*16467b97STreehugger Robot     ///
774*16467b97STreehugger Robot     /// For grammar debugging, you will want to override this to add more information
775*16467b97STreehugger Robot     /// such as the stack frame with GetRuleInvocationStack(e, this.GetType().Fullname)
776*16467b97STreehugger Robot     /// and, for no viable alts, the decision description and state etc...
777*16467b97STreehugger Robot     ///
778*16467b97STreehugger Robot     /// Override this to change the message generated for one or more exception types.
779*16467b97STreehugger Robot     /// </summary>
GetErrorMessage(const E: ERecognitionException;780*16467b97STreehugger Robot     function GetErrorMessage(const E: ERecognitionException;
781*16467b97STreehugger Robot       const TokenNames: TStringArray): String;
782*16467b97STreehugger Robot 
783*16467b97STreehugger Robot     /// <summary>
784*16467b97STreehugger Robot     /// What is the error header, normally line/character position information?
785*16467b97STreehugger Robot     /// </summary>
GetErrorHeader(const E: ERecognitionException)786*16467b97STreehugger Robot     function GetErrorHeader(const E: ERecognitionException): String;
787*16467b97STreehugger Robot 
788*16467b97STreehugger Robot     /// <summary>
789*16467b97STreehugger Robot     /// How should a token be displayed in an error message? The default
790*16467b97STreehugger Robot     /// is to display just the text, but during development you might
791*16467b97STreehugger Robot     /// want to have a lot of information spit out.  Override in that case
792*16467b97STreehugger Robot     /// to use t.ToString() (which, for CommonToken, dumps everything about
793*16467b97STreehugger Robot     /// the token). This is better than forcing you to override a method in
794*16467b97STreehugger Robot     /// your token objects because you don't have to go modify your lexer
795*16467b97STreehugger Robot     /// so that it creates a new type.
796*16467b97STreehugger Robot     /// </summary>
GetTokenErrorDisplay(const T: IToken)797*16467b97STreehugger Robot     function GetTokenErrorDisplay(const T: IToken): String;
798*16467b97STreehugger Robot 
799*16467b97STreehugger Robot     /// <summary>
800*16467b97STreehugger Robot     /// Override this method to change where error messages go
801*16467b97STreehugger Robot     /// </summary>
802*16467b97STreehugger Robot     procedure EmitErrorMessage(const Msg: String);
803*16467b97STreehugger Robot 
804*16467b97STreehugger Robot     /// <summary>
805*16467b97STreehugger Robot     /// Recover from an error found on the input stream.  This is
806*16467b97STreehugger Robot     /// for NoViableAlt and mismatched symbol exceptions.  If you enable
807*16467b97STreehugger Robot     /// single token insertion and deletion, this will usually not
808*16467b97STreehugger Robot     /// handle mismatched symbol exceptions but there could be a mismatched
809*16467b97STreehugger Robot     /// token that the Match() routine could not recover from.
810*16467b97STreehugger Robot     /// </summary>
811*16467b97STreehugger Robot     procedure Recover(const Input: IIntStream; const RE: ERecognitionException);
812*16467b97STreehugger Robot 
813*16467b97STreehugger Robot     // Not currently used
RecoverFromMismatchedSet(const Input: IIntStream;814*16467b97STreehugger Robot     function RecoverFromMismatchedSet(const Input: IIntStream;
815*16467b97STreehugger Robot       const E: ERecognitionException; const Follow: IBitSet): IANTLRInterface;
816*16467b97STreehugger Robot 
817*16467b97STreehugger Robot     procedure ConsumeUntil(const Input: IIntStream; const TokenType: Integer); overload;
818*16467b97STreehugger Robot 
819*16467b97STreehugger Robot     /// <summary>Consume tokens until one matches the given token set </summary>
820*16467b97STreehugger Robot     procedure ConsumeUntil(const Input: IIntStream; const BitSet: IBitSet); overload;
821*16467b97STreehugger Robot 
822*16467b97STreehugger Robot     /// <summary>
823*16467b97STreehugger Robot     /// Returns List &lt;String&gt; of the rules in your parser instance
824*16467b97STreehugger Robot     /// leading up to a call to this method.  You could override if
825*16467b97STreehugger Robot     /// you want more details such as the file/line info of where
826*16467b97STreehugger Robot     /// in the parser source code a rule is invoked.
827*16467b97STreehugger Robot     /// </summary>
828*16467b97STreehugger Robot     /// <remarks>
829*16467b97STreehugger Robot     /// NOT IMPLEMENTED IN THE DELPHI VERSION YET
830*16467b97STreehugger Robot     /// This is very useful for error messages and for context-sensitive
831*16467b97STreehugger Robot     /// error recovery.
832*16467b97STreehugger Robot     /// </remarks>
833*16467b97STreehugger Robot     //function GetRuleInvocationStack: IList<IANTLRInterface>; overload;
834*16467b97STreehugger Robot 
835*16467b97STreehugger Robot     /// <summary>
836*16467b97STreehugger Robot     /// A more general version of GetRuleInvocationStack where you can
837*16467b97STreehugger Robot     /// pass in, for example, a RecognitionException to get it's rule
838*16467b97STreehugger Robot     /// stack trace.  This routine is shared with all recognizers, hence,
839*16467b97STreehugger Robot     /// static.
840*16467b97STreehugger Robot     ///
841*16467b97STreehugger Robot     /// TODO: move to a utility class or something; weird having lexer call this
842*16467b97STreehugger Robot     /// </summary>
843*16467b97STreehugger Robot     /// <remarks>
844*16467b97STreehugger Robot     /// NOT IMPLEMENTED IN THE DELPHI VERSION YET
845*16467b97STreehugger Robot     /// </remarks>
846*16467b97STreehugger Robot     //function GetRuleInvocationStack(const E: Exception;
847*16467b97STreehugger Robot     //  const RecognizerClassName: String): IList<IANTLRInterface>; overload;
848*16467b97STreehugger Robot 
849*16467b97STreehugger Robot     /// <summary>A convenience method for use most often with template rewrites.
850*16467b97STreehugger Robot     /// Convert a List&lt;Token&gt; to List&lt;String&gt;
851*16467b97STreehugger Robot     /// </summary>
ToStrings(const Tokens: IList<IToken>)852*16467b97STreehugger Robot     function ToStrings(const Tokens: IList<IToken>): IList<String>;
853*16467b97STreehugger Robot 
854*16467b97STreehugger Robot     /// <summary>
855*16467b97STreehugger Robot     /// Given a rule number and a start token index number, return
856*16467b97STreehugger Robot     /// MEMO_RULE_UNKNOWN if the rule has not parsed input starting from
857*16467b97STreehugger Robot     /// start index.  If this rule has parsed input starting from the
858*16467b97STreehugger Robot     /// start index before, then return where the rule stopped parsing.
859*16467b97STreehugger Robot     /// It returns the index of the last token matched by the rule.
860*16467b97STreehugger Robot     /// </summary>
861*16467b97STreehugger Robot     /// <remarks>
862*16467b97STreehugger Robot     /// For now we use a hashtable and just the slow Object-based one.
863*16467b97STreehugger Robot     /// Later, we can make a special one for ints and also one that
864*16467b97STreehugger Robot     /// tosses out data after we commit past input position i.
865*16467b97STreehugger Robot     /// </remarks>
GetRuleMemoization(const RuleIndex, RuleStartIndex: Integer)866*16467b97STreehugger Robot     function GetRuleMemoization(const RuleIndex, RuleStartIndex: Integer): Integer;
867*16467b97STreehugger Robot 
868*16467b97STreehugger Robot     /// <summary>
869*16467b97STreehugger Robot     /// Has this rule already parsed input at the current index in the
870*16467b97STreehugger Robot     /// input stream?  Return the stop token index or MEMO_RULE_UNKNOWN.
871*16467b97STreehugger Robot     /// If we attempted but failed to parse properly before, return
872*16467b97STreehugger Robot     /// MEMO_RULE_FAILED.
873*16467b97STreehugger Robot     ///
874*16467b97STreehugger Robot     /// This method has a side-effect: if we have seen this input for
875*16467b97STreehugger Robot     /// this rule and successfully parsed before, then seek ahead to
876*16467b97STreehugger Robot     /// 1 past the stop token matched for this rule last time.
877*16467b97STreehugger Robot     /// </summary>
AlreadyParsedRule(const Input: IIntStream;878*16467b97STreehugger Robot     function AlreadyParsedRule(const Input: IIntStream;
879*16467b97STreehugger Robot       const RuleIndex: Integer): Boolean;
880*16467b97STreehugger Robot 
881*16467b97STreehugger Robot     /// <summary>
882*16467b97STreehugger Robot     /// Record whether or not this rule parsed the input at this position
883*16467b97STreehugger Robot     /// successfully.  Use a standard hashtable for now.
884*16467b97STreehugger Robot     /// </summary>
885*16467b97STreehugger Robot     procedure Memoize(const Input: IIntStream; const RuleIndex,
886*16467b97STreehugger Robot       RuleStartIndex: Integer);
887*16467b97STreehugger Robot 
888*16467b97STreehugger Robot     /// <summary>
889*16467b97STreehugger Robot     /// Return how many rule/input-index pairs there are in total.
890*16467b97STreehugger Robot     ///  TODO: this includes synpreds. :(
891*16467b97STreehugger Robot     /// </summary>
892*16467b97STreehugger Robot     /// <returns></returns>
GetRuleMemoizationChaceSize()893*16467b97STreehugger Robot     function GetRuleMemoizationChaceSize: Integer;
894*16467b97STreehugger Robot 
895*16467b97STreehugger Robot     procedure TraceIn(const RuleName: String; const RuleIndex: Integer;
896*16467b97STreehugger Robot       const InputSymbol: String);
897*16467b97STreehugger Robot     procedure TraceOut(const RuleName: String; const RuleIndex: Integer;
898*16467b97STreehugger Robot       const InputSymbol: String);
899*16467b97STreehugger Robot 
900*16467b97STreehugger Robot     { Properties }
901*16467b97STreehugger Robot     property Input: IIntStream read GetInput;
902*16467b97STreehugger Robot     property BacktrackingLevel: Integer read GetBacktrackingLevel;
903*16467b97STreehugger Robot     property State: IRecognizerSharedState read GetState;
904*16467b97STreehugger Robot 
905*16467b97STreehugger Robot     /// <summary>
906*16467b97STreehugger Robot     /// Get number of recognition errors (lexer, parser, tree parser).  Each
907*16467b97STreehugger Robot     /// recognizer tracks its own number.  So parser and lexer each have
908*16467b97STreehugger Robot     /// separate count.  Does not count the spurious errors found between
909*16467b97STreehugger Robot     /// an error and next valid token match
910*16467b97STreehugger Robot     ///
911*16467b97STreehugger Robot     /// See also ReportError()
912*16467b97STreehugger Robot     /// </summary>
913*16467b97STreehugger Robot     property NumberOfSyntaxErrors: Integer read GetNumberOfSyntaxErrors;
914*16467b97STreehugger Robot 
915*16467b97STreehugger Robot     /// <summary>
916*16467b97STreehugger Robot     /// For debugging and other purposes, might want the grammar name.
917*16467b97STreehugger Robot     /// Have ANTLR generate an implementation for this property.
918*16467b97STreehugger Robot     /// </summary>
919*16467b97STreehugger Robot     /// <returns></returns>
920*16467b97STreehugger Robot     property GrammarFileName: String read GetGrammarFileName;
921*16467b97STreehugger Robot 
922*16467b97STreehugger Robot     /// <summary>
923*16467b97STreehugger Robot     /// For debugging and other purposes, might want the source name.
924*16467b97STreehugger Robot     /// Have ANTLR provide a hook for this property.
925*16467b97STreehugger Robot     /// </summary>
926*16467b97STreehugger Robot     /// <returns>The source name</returns>
927*16467b97STreehugger Robot     property SourceName: String read GetSourceName;
928*16467b97STreehugger Robot 
929*16467b97STreehugger Robot     /// <summary>
930*16467b97STreehugger Robot     /// Used to print out token names like ID during debugging and
931*16467b97STreehugger Robot     /// error reporting.  The generated parsers implement a method
932*16467b97STreehugger Robot     /// that overrides this to point to their string[] tokenNames.
933*16467b97STreehugger Robot     /// </summary>
934*16467b97STreehugger Robot     property TokenNames: TStringArray read GetTokenNames;
935*16467b97STreehugger Robot   end;
936*16467b97STreehugger Robot 
937*16467b97STreehugger Robot   /// <summary>
938*16467b97STreehugger Robot   /// The most common stream of tokens is one where every token is buffered up
939*16467b97STreehugger Robot   /// and tokens are prefiltered for a certain channel (the parser will only
940*16467b97STreehugger Robot   /// see these tokens and cannot change the filter channel number during the
941*16467b97STreehugger Robot   /// parse).
942*16467b97STreehugger Robot   ///
943*16467b97STreehugger Robot   /// TODO: how to access the full token stream?  How to track all tokens matched per rule?
944*16467b97STreehugger Robot   /// </summary>
945*16467b97STreehugger Robot   ICommonTokenStream = interface(ITokenStream)
946*16467b97STreehugger Robot     { Methods }
947*16467b97STreehugger Robot 
948*16467b97STreehugger Robot     /// <summary>
949*16467b97STreehugger Robot     /// A simple filter mechanism whereby you can tell this token stream
950*16467b97STreehugger Robot     /// to force all tokens of type TType to be on Channel.
951*16467b97STreehugger Robot     /// </summary>
952*16467b97STreehugger Robot     ///
953*16467b97STreehugger Robot     /// <remarks>
954*16467b97STreehugger Robot     /// For example,
955*16467b97STreehugger Robot     /// when interpreting, we cannot exec actions so we need to tell
956*16467b97STreehugger Robot     /// the stream to force all WS and NEWLINE to be a different, ignored
957*16467b97STreehugger Robot     /// channel.
958*16467b97STreehugger Robot     /// </remarks>
959*16467b97STreehugger Robot     procedure SetTokenTypeChannel(const TType, Channel: Integer);
960*16467b97STreehugger Robot 
961*16467b97STreehugger Robot     procedure DiscardTokenType(const TType: Integer);
962*16467b97STreehugger Robot 
963*16467b97STreehugger Robot     procedure DiscardOffChannelTokens(const Discard: Boolean);
964*16467b97STreehugger Robot 
GetTokens()965*16467b97STreehugger Robot     function GetTokens: IList<IToken>; overload;
GetTokens(const Start, Stop: Integer)966*16467b97STreehugger Robot     function GetTokens(const Start, Stop: Integer): IList<IToken>; overload;
967*16467b97STreehugger Robot 
968*16467b97STreehugger Robot     /// <summary>Given a start and stop index, return a List of all tokens in
969*16467b97STreehugger Robot     /// the token type BitSet.  Return null if no tokens were found.  This
970*16467b97STreehugger Robot     /// method looks at both on and off channel tokens.
971*16467b97STreehugger Robot     /// </summary>
GetTokens(const Start, Stop: Integer;972*16467b97STreehugger Robot     function GetTokens(const Start, Stop: Integer;
973*16467b97STreehugger Robot       const Types: IBitSet): IList<IToken>; overload;
974*16467b97STreehugger Robot 
GetTokens(const Start, Stop: Integer;975*16467b97STreehugger Robot     function GetTokens(const Start, Stop: Integer;
976*16467b97STreehugger Robot       const Types: IList<Integer>): IList<IToken>; overload;
977*16467b97STreehugger Robot 
GetTokens(const Start, Stop,978*16467b97STreehugger Robot     function GetTokens(const Start, Stop,
979*16467b97STreehugger Robot       TokenType: Integer): IList<IToken>; overload;
980*16467b97STreehugger Robot 
981*16467b97STreehugger Robot     procedure Reset;
982*16467b97STreehugger Robot   end;
983*16467b97STreehugger Robot 
984*16467b97STreehugger Robot   IDFA = interface;
985*16467b97STreehugger Robot 
onst()986*16467b97STreehugger Robot   TSpecialStateTransitionHandler = function(const DFA: IDFA; S: Integer;
987*16467b97STreehugger Robot     const Input: IIntStream): Integer of Object;
988*16467b97STreehugger Robot 
989*16467b97STreehugger Robot   /// <summary>
990*16467b97STreehugger Robot   ///  A DFA implemented as a set of transition tables.
991*16467b97STreehugger Robot   /// </summary>
992*16467b97STreehugger Robot   /// <remarks>
993*16467b97STreehugger Robot   /// <para>
994*16467b97STreehugger Robot   /// Any state that has a semantic predicate edge is special; those states are
995*16467b97STreehugger Robot   /// generated with if-then-else structures in a SpecialStateTransition()
996*16467b97STreehugger Robot   /// which is generated by cyclicDFA template.
997*16467b97STreehugger Robot   /// </para>
998*16467b97STreehugger Robot   /// <para>
999*16467b97STreehugger Robot   /// There are at most 32767 states (16-bit signed short). Could get away with byte
1000*16467b97STreehugger Robot   /// sometimes but would have to generate different types and the simulation code too.
1001*16467b97STreehugger Robot   /// </para>
1002*16467b97STreehugger Robot   /// <para>
1003*16467b97STreehugger Robot   /// As a point of reference, the Tokens rule DFA for the lexer in the Java grammar
1004*16467b97STreehugger Robot   /// sample has approximately 326 states.
1005*16467b97STreehugger Robot   /// </para>
1006*16467b97STreehugger Robot   /// </remarks>
1007*16467b97STreehugger Robot   IDFA = interface(IANTLRInterface)
1008*16467b97STreehugger Robot   ['{36312B59-B718-48EF-A0EC-4529DE70F4C2}']
1009*16467b97STreehugger Robot     { Property accessors }
GetSpecialStateTransitionHandler()1010*16467b97STreehugger Robot     function GetSpecialStateTransitionHandler: TSpecialStateTransitionHandler;
1011*16467b97STreehugger Robot     procedure SetSpecialStateTransitionHandler(const Value: TSpecialStateTransitionHandler);
1012*16467b97STreehugger Robot 
1013*16467b97STreehugger Robot     { Methods }
1014*16467b97STreehugger Robot 
1015*16467b97STreehugger Robot     /// <summary>
1016*16467b97STreehugger Robot     /// From the input stream, predict what alternative will succeed using this
1017*16467b97STreehugger Robot     /// DFA (representing the covering regular approximation to the underlying CFL).
1018*16467b97STreehugger Robot     /// </summary>
1019*16467b97STreehugger Robot     /// <param name="Input">Input stream</param>
1020*16467b97STreehugger Robot     /// <returns>Return an alternative number 1..N.  Throw an exception upon error.</returns>
Predict(const Input: IIntStream)1021*16467b97STreehugger Robot     function Predict(const Input: IIntStream): Integer;
1022*16467b97STreehugger Robot 
1023*16467b97STreehugger Robot     /// <summary>
1024*16467b97STreehugger Robot     /// A hook for debugging interface
1025*16467b97STreehugger Robot     /// </summary>
1026*16467b97STreehugger Robot     /// <param name="NVAE"></param>
1027*16467b97STreehugger Robot     procedure Error(const NVAE: ENoViableAltException);
1028*16467b97STreehugger Robot 
SpecialStateTransition(const S: Integer; const Input: IIntStream)1029*16467b97STreehugger Robot     function SpecialStateTransition(const S: Integer; const Input: IIntStream): Integer;
1030*16467b97STreehugger Robot 
Description()1031*16467b97STreehugger Robot     function Description: String;
1032*16467b97STreehugger Robot 
SpecialTransition(const State, Symbol: Integer)1033*16467b97STreehugger Robot     function SpecialTransition(const State, Symbol: Integer): Integer;
1034*16467b97STreehugger Robot 
1035*16467b97STreehugger Robot     { Properties }
1036*16467b97STreehugger Robot     property SpecialStateTransitionHandler: TSpecialStateTransitionHandler read GetSpecialStateTransitionHandler write SetSpecialStateTransitionHandler;
1037*16467b97STreehugger Robot   end;
1038*16467b97STreehugger Robot 
1039*16467b97STreehugger Robot   /// <summary>
1040*16467b97STreehugger Robot   /// A lexer is recognizer that draws input symbols from a character stream.
1041*16467b97STreehugger Robot   /// lexer grammars result in a subclass of this object. A Lexer object
1042*16467b97STreehugger Robot   /// uses simplified Match() and error recovery mechanisms in the interest
1043*16467b97STreehugger Robot   /// of speed.
1044*16467b97STreehugger Robot   /// </summary>
1045*16467b97STreehugger Robot   ILexer = interface(IBaseRecognizer)
1046*16467b97STreehugger Robot   ['{331AAB49-E7CD-40E7-AEF5-427F7D6577AD}']
1047*16467b97STreehugger Robot     { Property accessors }
GetCharStream()1048*16467b97STreehugger Robot     function GetCharStream: ICharStream;
1049*16467b97STreehugger Robot     procedure SetCharStream(const Value: ICharStream);
GetLine()1050*16467b97STreehugger Robot     function GetLine: Integer;
GetCharPositionInLine()1051*16467b97STreehugger Robot     function GetCharPositionInLine: Integer;
GetCharIndex()1052*16467b97STreehugger Robot     function GetCharIndex: Integer;
GetText()1053*16467b97STreehugger Robot     function GetText: String;
1054*16467b97STreehugger Robot     procedure SetText(const Value: String);
1055*16467b97STreehugger Robot 
1056*16467b97STreehugger Robot     { Methods }
1057*16467b97STreehugger Robot 
1058*16467b97STreehugger Robot     /// <summary>
1059*16467b97STreehugger Robot     /// Return a token from this source; i.e., Match a token on the char stream.
1060*16467b97STreehugger Robot     /// </summary>
NextToken()1061*16467b97STreehugger Robot     function NextToken: IToken;
1062*16467b97STreehugger Robot 
1063*16467b97STreehugger Robot     /// <summary>
1064*16467b97STreehugger Robot     /// Instruct the lexer to skip creating a token for current lexer rule and
1065*16467b97STreehugger Robot     /// look for another token.  NextToken() knows to keep looking when a lexer
1066*16467b97STreehugger Robot     /// rule finishes with token set to SKIP_TOKEN.  Recall that if token==null
1067*16467b97STreehugger Robot     /// at end of any token rule, it creates one for you and emits it.
1068*16467b97STreehugger Robot     /// </summary>
1069*16467b97STreehugger Robot     procedure Skip;
1070*16467b97STreehugger Robot 
1071*16467b97STreehugger Robot     /// <summary>This is the lexer entry point that sets instance var 'token' </summary>
1072*16467b97STreehugger Robot     procedure DoTokens;
1073*16467b97STreehugger Robot 
1074*16467b97STreehugger Robot     /// <summary>
1075*16467b97STreehugger Robot     /// Currently does not support multiple emits per nextToken invocation
1076*16467b97STreehugger Robot     /// for efficiency reasons.  Subclass and override this method and
1077*16467b97STreehugger Robot     /// NextToken (to push tokens into a list and pull from that list rather
1078*16467b97STreehugger Robot     /// than a single variable as this implementation does).
1079*16467b97STreehugger Robot     /// </summary>
1080*16467b97STreehugger Robot     procedure Emit(const Token: IToken); overload;
1081*16467b97STreehugger Robot 
1082*16467b97STreehugger Robot     /// <summary>
1083*16467b97STreehugger Robot     /// The standard method called to automatically emit a token at the
1084*16467b97STreehugger Robot     /// outermost lexical rule.  The token object should point into the
1085*16467b97STreehugger Robot     /// char buffer start..stop.  If there is a text override in 'text',
1086*16467b97STreehugger Robot     /// use that to set the token's text.
1087*16467b97STreehugger Robot     /// </summary>
1088*16467b97STreehugger Robot     /// <remarks><para>Override this method to emit custom Token objects.</para>
1089*16467b97STreehugger Robot     /// <para>If you are building trees, then you should also override
1090*16467b97STreehugger Robot     /// Parser or TreeParser.GetMissingSymbol().</para>
1091*16467b97STreehugger Robot     ///</remarks>
Emit()1092*16467b97STreehugger Robot     function Emit: IToken; overload;
1093*16467b97STreehugger Robot 
1094*16467b97STreehugger Robot     procedure Match(const S: String); overload;
1095*16467b97STreehugger Robot     procedure Match(const C: Integer); overload;
1096*16467b97STreehugger Robot     procedure MatchAny;
1097*16467b97STreehugger Robot     procedure MatchRange(const A, B: Integer);
1098*16467b97STreehugger Robot 
1099*16467b97STreehugger Robot     /// <summary>
1100*16467b97STreehugger Robot     /// Lexers can normally Match any char in it's vocabulary after matching
1101*16467b97STreehugger Robot     /// a token, so do the easy thing and just kill a character and hope
1102*16467b97STreehugger Robot     /// it all works out.  You can instead use the rule invocation stack
1103*16467b97STreehugger Robot     /// to do sophisticated error recovery if you are in a Fragment rule.
1104*16467b97STreehugger Robot     /// </summary>
1105*16467b97STreehugger Robot     procedure Recover(const RE: ERecognitionException);
1106*16467b97STreehugger Robot 
GetCharErrorDisplay(const C: Integer)1107*16467b97STreehugger Robot     function GetCharErrorDisplay(const C: Integer): String;
1108*16467b97STreehugger Robot 
1109*16467b97STreehugger Robot     procedure TraceIn(const RuleName: String; const RuleIndex: Integer);
1110*16467b97STreehugger Robot     procedure TraceOut(const RuleName: String; const RuleIndex: Integer);
1111*16467b97STreehugger Robot 
1112*16467b97STreehugger Robot     { Properties }
1113*16467b97STreehugger Robot 
1114*16467b97STreehugger Robot     /// <summary>Set the char stream and reset the lexer </summary>
1115*16467b97STreehugger Robot     property CharStream: ICharStream read GetCharStream write SetCharStream;
1116*16467b97STreehugger Robot     property Line: Integer read GetLine;
1117*16467b97STreehugger Robot     property CharPositionInLine: Integer read GetCharPositionInLine;
1118*16467b97STreehugger Robot 
1119*16467b97STreehugger Robot     /// <summary>What is the index of the current character of lookahead? </summary>
1120*16467b97STreehugger Robot     property CharIndex: Integer read GetCharIndex;
1121*16467b97STreehugger Robot 
1122*16467b97STreehugger Robot     /// <summary>
1123*16467b97STreehugger Robot     /// Gets or sets the 'lexeme' for the current token.
1124*16467b97STreehugger Robot     /// </summary>
1125*16467b97STreehugger Robot     /// <remarks>
1126*16467b97STreehugger Robot     /// <para>
1127*16467b97STreehugger Robot     /// The getter returns the text matched so far for the current token or any
1128*16467b97STreehugger Robot     /// text override.
1129*16467b97STreehugger Robot     /// </para>
1130*16467b97STreehugger Robot     /// <para>
1131*16467b97STreehugger Robot     /// The setter sets the complete text of this token. It overrides/wipes any
1132*16467b97STreehugger Robot     /// previous changes to the text.
1133*16467b97STreehugger Robot     /// </para>
1134*16467b97STreehugger Robot     /// </remarks>
1135*16467b97STreehugger Robot     property Text: String read GetText write SetText;
1136*16467b97STreehugger Robot   end;
1137*16467b97STreehugger Robot 
1138*16467b97STreehugger Robot   /// <summary>A parser for TokenStreams.  Parser grammars result in a subclass
1139*16467b97STreehugger Robot   /// of this.
1140*16467b97STreehugger Robot   /// </summary>
1141*16467b97STreehugger Robot   IParser = interface(IBaseRecognizer)
1142*16467b97STreehugger Robot   ['{7420879A-5D1F-43CA-BD49-2264D7514501}']
1143*16467b97STreehugger Robot     { Property accessors }
GetTokenStream()1144*16467b97STreehugger Robot     function GetTokenStream: ITokenStream;
1145*16467b97STreehugger Robot     procedure SetTokenStream(const Value: ITokenStream);
1146*16467b97STreehugger Robot 
1147*16467b97STreehugger Robot     { Methods }
1148*16467b97STreehugger Robot     procedure TraceIn(const RuleName: String; const RuleIndex: Integer);
1149*16467b97STreehugger Robot     procedure TraceOut(const RuleName: String; const RuleIndex: Integer);
1150*16467b97STreehugger Robot 
1151*16467b97STreehugger Robot     { Properties }
1152*16467b97STreehugger Robot 
1153*16467b97STreehugger Robot     /// <summary>Set the token stream and reset the parser </summary>
1154*16467b97STreehugger Robot     property TokenStream: ITokenStream read GetTokenStream write SetTokenStream;
1155*16467b97STreehugger Robot   end;
1156*16467b97STreehugger Robot 
1157*16467b97STreehugger Robot   /// <summary>
1158*16467b97STreehugger Robot   /// Rules can return start/stop info as well as possible trees and templates
1159*16467b97STreehugger Robot   /// </summary>
1160*16467b97STreehugger Robot   IRuleReturnScope = interface(IANTLRInterface)
1161*16467b97STreehugger Robot   ['{E9870056-BF6D-4CB2-B71C-10B80797C0B4}']
1162*16467b97STreehugger Robot     { Property accessors }
GetStart()1163*16467b97STreehugger Robot     function GetStart: IANTLRInterface;
1164*16467b97STreehugger Robot     procedure SetStart(const Value: IANTLRInterface);
GetStop()1165*16467b97STreehugger Robot     function GetStop: IANTLRInterface;
1166*16467b97STreehugger Robot     procedure SetStop(const Value: IANTLRInterface);
GetTree()1167*16467b97STreehugger Robot     function GetTree: IANTLRInterface;
1168*16467b97STreehugger Robot     procedure SetTree(const Value: IANTLRInterface);
GetTemplate()1169*16467b97STreehugger Robot     function GetTemplate: IANTLRInterface;
1170*16467b97STreehugger Robot 
1171*16467b97STreehugger Robot     { Properties }
1172*16467b97STreehugger Robot 
1173*16467b97STreehugger Robot     /// <summary>Return the start token or tree </summary>
1174*16467b97STreehugger Robot     property Start: IANTLRInterface read GetStart write SetStart;
1175*16467b97STreehugger Robot 
1176*16467b97STreehugger Robot     /// <summary>Return the stop token or tree </summary>
1177*16467b97STreehugger Robot     property Stop: IANTLRInterface read GetStop write SetStop;
1178*16467b97STreehugger Robot 
1179*16467b97STreehugger Robot     /// <summary>Has a value potentially if output=AST; </summary>
1180*16467b97STreehugger Robot     property Tree: IANTLRInterface read GetTree write SetTree;
1181*16467b97STreehugger Robot 
1182*16467b97STreehugger Robot     /// <summary>
1183*16467b97STreehugger Robot     /// Has a value potentially if output=template;
1184*16467b97STreehugger Robot     /// Don't use StringTemplate type to avoid dependency on ST assembly
1185*16467b97STreehugger Robot     /// </summary>
1186*16467b97STreehugger Robot     property Template: IANTLRInterface read GetTemplate;
1187*16467b97STreehugger Robot   end;
1188*16467b97STreehugger Robot 
1189*16467b97STreehugger Robot   /// <summary>
1190*16467b97STreehugger Robot   /// Rules that return more than a single value must return an object
1191*16467b97STreehugger Robot   /// containing all the values.  Besides the properties defined in
1192*16467b97STreehugger Robot   /// RuleLabelScope.PredefinedRulePropertiesScope there may be user-defined
1193*16467b97STreehugger Robot   /// return values.  This class simply defines the minimum properties that
1194*16467b97STreehugger Robot   /// are always defined and methods to access the others that might be
1195*16467b97STreehugger Robot   /// available depending on output option such as template and tree.
1196*16467b97STreehugger Robot   ///
1197*16467b97STreehugger Robot   /// Note text is not an actual property of the return value, it is computed
1198*16467b97STreehugger Robot   /// from start and stop using the input stream's ToString() method.  I
1199*16467b97STreehugger Robot   /// could add a ctor to this so that we can pass in and store the input
1200*16467b97STreehugger Robot   /// stream, but I'm not sure we want to do that.  It would seem to be undefined
1201*16467b97STreehugger Robot   /// to get the .text property anyway if the rule matches tokens from multiple
1202*16467b97STreehugger Robot   /// input streams.
1203*16467b97STreehugger Robot   ///
1204*16467b97STreehugger Robot   /// I do not use getters for fields of objects that are used simply to
1205*16467b97STreehugger Robot   /// group values such as this aggregate.
1206*16467b97STreehugger Robot   /// </summary>
1207*16467b97STreehugger Robot   IParserRuleReturnScope = interface(IRuleReturnScope)
1208*16467b97STreehugger Robot   ['{9FB62050-E23B-4FE4-87D5-2C1EE67AEC3E}']
1209*16467b97STreehugger Robot   end;
1210*16467b97STreehugger Robot 
1211*16467b97STreehugger Robot   /// <summary>Useful for dumping out the input stream after doing some
1212*16467b97STreehugger Robot   /// augmentation or other manipulations.
1213*16467b97STreehugger Robot   /// </summary>
1214*16467b97STreehugger Robot   ///
1215*16467b97STreehugger Robot   /// <remarks>
1216*16467b97STreehugger Robot   /// You can insert stuff, Replace, and delete chunks.  Note that the
1217*16467b97STreehugger Robot   /// operations are done lazily--only if you convert the buffer to a
1218*16467b97STreehugger Robot   /// String.  This is very efficient because you are not moving data around
1219*16467b97STreehugger Robot   /// all the time.  As the buffer of tokens is converted to strings, the
1220*16467b97STreehugger Robot   /// ToString() method(s) check to see if there is an operation at the
1221*16467b97STreehugger Robot   /// current index.  If so, the operation is done and then normal String
1222*16467b97STreehugger Robot   /// rendering continues on the buffer.  This is like having multiple Turing
1223*16467b97STreehugger Robot   /// machine instruction streams (programs) operating on a single input tape. :)
1224*16467b97STreehugger Robot   ///
1225*16467b97STreehugger Robot   /// Since the operations are done lazily at ToString-time, operations do not
1226*16467b97STreehugger Robot   /// screw up the token index values.  That is, an insert operation at token
1227*16467b97STreehugger Robot   /// index I does not change the index values for tokens I+1..N-1.
1228*16467b97STreehugger Robot   ///
1229*16467b97STreehugger Robot   /// Because operations never actually alter the buffer, you may always get
1230*16467b97STreehugger Robot   /// the original token stream back without undoing anything.  Since
1231*16467b97STreehugger Robot   /// the instructions are queued up, you can easily simulate transactions and
1232*16467b97STreehugger Robot   /// roll back any changes if there is an error just by removing instructions.
1233*16467b97STreehugger Robot   /// For example,
1234*16467b97STreehugger Robot   ///
1235*16467b97STreehugger Robot   /// var
1236*16467b97STreehugger Robot   ///   Input: ICharStream;
1237*16467b97STreehugger Robot   ///   Lex: ILexer;
1238*16467b97STreehugger Robot   ///   Tokens: ITokenRewriteStream;
1239*16467b97STreehugger Robot   ///   Parser: IParser;
1240*16467b97STreehugger Robot   /// Input := TANTLRFileStream.Create('input');
1241*16467b97STreehugger Robot   /// Lex := TLexer.Create(Input);
1242*16467b97STreehugger Robot   /// Tokens := TTokenRewriteStream.Create(Lex);
1243*16467b97STreehugger Robot   /// Parser := TParser.Create(tokens);
1244*16467b97STreehugger Robot   /// Parser.startRule();
1245*16467b97STreehugger Robot   ///
1246*16467b97STreehugger Robot   /// Then in the rules, you can execute
1247*16467b97STreehugger Robot   /// var
1248*16467b97STreehugger Robot   ///   t,u: IToken;
1249*16467b97STreehugger Robot   /// ...
1250*16467b97STreehugger Robot   /// Input.InsertAfter(t, 'text to put after t');
1251*16467b97STreehugger Robot   /// Input.InsertAfter(u, 'text after u');
1252*16467b97STreehugger Robot   /// WriteLn(Tokens.ToString());
1253*16467b97STreehugger Robot   ///
1254*16467b97STreehugger Robot   /// Actually, you have to cast the 'input' to a TokenRewriteStream. :(
1255*16467b97STreehugger Robot   ///
1256*16467b97STreehugger Robot   /// You can also have multiple "instruction streams" and get multiple
1257*16467b97STreehugger Robot   /// rewrites from a single pass over the input.  Just name the instruction
1258*16467b97STreehugger Robot   /// streams and use that name again when printing the buffer.  This could be
1259*16467b97STreehugger Robot   /// useful for generating a C file and also its header file--all from the
1260*16467b97STreehugger Robot   /// same buffer:
1261*16467b97STreehugger Robot   ///
1262*16467b97STreehugger Robot   /// Tokens.InsertAfter('pass1', t, 'text to put after t');
1263*16467b97STreehugger Robot   /// Tokens.InsertAfter('pass2', u, 'text after u');
1264*16467b97STreehugger Robot   /// WriteLn(Tokens.ToString('pass1'));
1265*16467b97STreehugger Robot   /// WriteLn(Tokens.ToString('pass2'));
1266*16467b97STreehugger Robot   ///
1267*16467b97STreehugger Robot   /// If you don't use named rewrite streams, a "default" stream is used as
1268*16467b97STreehugger Robot   /// the first example shows.
1269*16467b97STreehugger Robot   /// </remarks>
1270*16467b97STreehugger Robot   ITokenRewriteStream = interface(ICommonTokenStream)
1271*16467b97STreehugger Robot   ['{7B49CBB6-9395-4781-B616-F201889EEA13}']
1272*16467b97STreehugger Robot     { Methods }
1273*16467b97STreehugger Robot     procedure Rollback(const InstructionIndex: Integer); overload;
1274*16467b97STreehugger Robot 
1275*16467b97STreehugger Robot     /// <summary>Rollback the instruction stream for a program so that
1276*16467b97STreehugger Robot     /// the indicated instruction (via instructionIndex) is no
1277*16467b97STreehugger Robot     /// longer in the stream.  UNTESTED!
1278*16467b97STreehugger Robot     /// </summary>
1279*16467b97STreehugger Robot     procedure Rollback(const ProgramName: String;
1280*16467b97STreehugger Robot       const InstructionIndex: Integer); overload;
1281*16467b97STreehugger Robot 
1282*16467b97STreehugger Robot     procedure DeleteProgram; overload;
1283*16467b97STreehugger Robot 
1284*16467b97STreehugger Robot     /// <summary>Reset the program so that no instructions exist </summary>
1285*16467b97STreehugger Robot     procedure DeleteProgram(const ProgramName: String); overload;
1286*16467b97STreehugger Robot 
1287*16467b97STreehugger Robot     procedure InsertAfter(const T: IToken; const Text: IANTLRInterface); overload;
1288*16467b97STreehugger Robot     procedure InsertAfter(const Index: Integer; const Text: IANTLRInterface); overload;
1289*16467b97STreehugger Robot     procedure InsertAfter(const ProgramName: String; const T: IToken;
1290*16467b97STreehugger Robot       const Text: IANTLRInterface); overload;
1291*16467b97STreehugger Robot     procedure InsertAfter(const ProgramName: String; const Index: Integer;
1292*16467b97STreehugger Robot       const Text: IANTLRInterface); overload;
1293*16467b97STreehugger Robot     procedure InsertAfter(const T: IToken; const Text: String); overload;
1294*16467b97STreehugger Robot     procedure InsertAfter(const Index: Integer; const Text: String); overload;
1295*16467b97STreehugger Robot     procedure InsertAfter(const ProgramName: String; const T: IToken;
1296*16467b97STreehugger Robot       const Text: String); overload;
1297*16467b97STreehugger Robot     procedure InsertAfter(const ProgramName: String; const Index: Integer;
1298*16467b97STreehugger Robot       const Text: String); overload;
1299*16467b97STreehugger Robot 
1300*16467b97STreehugger Robot     procedure InsertBefore(const T: IToken; const Text: IANTLRInterface); overload;
1301*16467b97STreehugger Robot     procedure InsertBefore(const Index: Integer; const Text: IANTLRInterface); overload;
1302*16467b97STreehugger Robot     procedure InsertBefore(const ProgramName: String; const T: IToken;
1303*16467b97STreehugger Robot       const Text: IANTLRInterface); overload;
1304*16467b97STreehugger Robot     procedure InsertBefore(const ProgramName: String; const Index: Integer;
1305*16467b97STreehugger Robot       const Text: IANTLRInterface); overload;
1306*16467b97STreehugger Robot     procedure InsertBefore(const T: IToken; const Text: String); overload;
1307*16467b97STreehugger Robot     procedure InsertBefore(const Index: Integer; const Text: String); overload;
1308*16467b97STreehugger Robot     procedure InsertBefore(const ProgramName: String; const T: IToken;
1309*16467b97STreehugger Robot       const Text: String); overload;
1310*16467b97STreehugger Robot     procedure InsertBefore(const ProgramName: String; const Index: Integer;
1311*16467b97STreehugger Robot       const Text: String); overload;
1312*16467b97STreehugger Robot 
1313*16467b97STreehugger Robot     procedure Replace(const Index: Integer; const Text: IANTLRInterface); overload;
1314*16467b97STreehugger Robot     procedure Replace(const Start, Stop: Integer; const Text: IANTLRInterface); overload;
1315*16467b97STreehugger Robot     procedure Replace(const IndexT: IToken; const Text: IANTLRInterface); overload;
1316*16467b97STreehugger Robot     procedure Replace(const Start, Stop: IToken; const Text: IANTLRInterface); overload;
1317*16467b97STreehugger Robot     procedure Replace(const ProgramName: String; const Start, Stop: Integer;
1318*16467b97STreehugger Robot       const Text: IANTLRInterface); overload;
1319*16467b97STreehugger Robot     procedure Replace(const ProgramName: String; const Start, Stop: IToken;
1320*16467b97STreehugger Robot       const Text: IANTLRInterface); overload;
1321*16467b97STreehugger Robot     procedure Replace(const Index: Integer; const Text: String); overload;
1322*16467b97STreehugger Robot     procedure Replace(const Start, Stop: Integer; const Text: String); overload;
1323*16467b97STreehugger Robot     procedure Replace(const IndexT: IToken; const Text: String); overload;
1324*16467b97STreehugger Robot     procedure Replace(const Start, Stop: IToken; const Text: String); overload;
1325*16467b97STreehugger Robot     procedure Replace(const ProgramName: String; const Start, Stop: Integer;
1326*16467b97STreehugger Robot       const Text: String); overload;
1327*16467b97STreehugger Robot     procedure Replace(const ProgramName: String; const Start, Stop: IToken;
1328*16467b97STreehugger Robot       const Text: String); overload;
1329*16467b97STreehugger Robot 
1330*16467b97STreehugger Robot     procedure Delete(const Index: Integer); overload;
1331*16467b97STreehugger Robot     procedure Delete(const Start, Stop: Integer); overload;
1332*16467b97STreehugger Robot     procedure Delete(const IndexT: IToken); overload;
1333*16467b97STreehugger Robot     procedure Delete(const Start, Stop: IToken); overload;
1334*16467b97STreehugger Robot     procedure Delete(const ProgramName: String; const Start, Stop: Integer); overload;
1335*16467b97STreehugger Robot     procedure Delete(const ProgramName: String; const Start, Stop: IToken); overload;
1336*16467b97STreehugger Robot 
GetLastRewriteTokenIndex()1337*16467b97STreehugger Robot     function GetLastRewriteTokenIndex: Integer;
1338*16467b97STreehugger Robot 
ToOriginalString()1339*16467b97STreehugger Robot     function ToOriginalString: String; overload;
ToOriginalString(const Start, Stop: Integer)1340*16467b97STreehugger Robot     function ToOriginalString(const Start, Stop: Integer): String; overload;
1341*16467b97STreehugger Robot 
ToString(const ProgramName: String)1342*16467b97STreehugger Robot     function ToString(const ProgramName: String): String; overload;
ToString(const ProgramName: String;1343*16467b97STreehugger Robot     function ToString(const ProgramName: String;
1344*16467b97STreehugger Robot       const Start, Stop: Integer): String; overload;
1345*16467b97STreehugger Robot 
ToDebugString()1346*16467b97STreehugger Robot     function ToDebugString: String; overload;
ToDebugString(const Start, Stop: Integer)1347*16467b97STreehugger Robot     function ToDebugString(const Start, Stop: Integer): String; overload;
1348*16467b97STreehugger Robot   end;
1349*16467b97STreehugger Robot 
1350*16467b97STreehugger Robot   /// <summary>The root of the ANTLR exception hierarchy.</summary>
1351*16467b97STreehugger Robot   /// <remarks>
1352*16467b97STreehugger Robot   /// To avoid English-only error messages and to generally make things
1353*16467b97STreehugger Robot   /// as flexible as possible, these exceptions are not created with strings,
1354*16467b97STreehugger Robot   /// but rather the information necessary to generate an error.  Then
1355*16467b97STreehugger Robot   /// the various reporting methods in Parser and Lexer can be overridden
1356*16467b97STreehugger Robot   /// to generate a localized error message.  For example, MismatchedToken
1357*16467b97STreehugger Robot   /// exceptions are built with the expected token type.
1358*16467b97STreehugger Robot   /// So, don't expect getMessage() to return anything.
1359*16467b97STreehugger Robot   ///
1360*16467b97STreehugger Robot   /// You can access the stack trace, which means that you can compute the
1361*16467b97STreehugger Robot   /// complete trace of rules from the start symbol. This gives you considerable
1362*16467b97STreehugger Robot   /// context information with which to generate useful error messages.
1363*16467b97STreehugger Robot   ///
1364*16467b97STreehugger Robot   /// ANTLR generates code that throws exceptions upon recognition error and
1365*16467b97STreehugger Robot   /// also generates code to catch these exceptions in each rule.  If you
1366*16467b97STreehugger Robot   /// want to quit upon first error, you can turn off the automatic error
1367*16467b97STreehugger Robot   /// handling mechanism using rulecatch action, but you still need to
1368*16467b97STreehugger Robot   /// override methods mismatch and recoverFromMismatchSet.
1369*16467b97STreehugger Robot   ///
1370*16467b97STreehugger Robot   /// In general, the recognition exceptions can track where in a grammar a
1371*16467b97STreehugger Robot   /// problem occurred and/or what was the expected input.  While the parser
1372*16467b97STreehugger Robot   /// knows its state (such as current input symbol and line info) that
1373*16467b97STreehugger Robot   /// state can change before the exception is reported so current token index
1374*16467b97STreehugger Robot   /// is computed and stored at exception time.  From this info, you can
1375*16467b97STreehugger Robot   /// perhaps print an entire line of input not just a single token, for example.
1376*16467b97STreehugger Robot   /// Better to just say the recognizer had a problem and then let the parser
1377*16467b97STreehugger Robot   /// figure out a fancy report.
1378*16467b97STreehugger Robot   /// </remarks>
1379*16467b97STreehugger Robot   ERecognitionException = class(Exception)
1380*16467b97STreehugger Robot   strict private
1381*16467b97STreehugger Robot     FApproximateLineInfo: Boolean;
1382*16467b97STreehugger Robot   strict protected
1383*16467b97STreehugger Robot     /// <summary>What input stream did the error occur in? </summary>
1384*16467b97STreehugger Robot     FInput: IIntStream;
1385*16467b97STreehugger Robot 
1386*16467b97STreehugger Robot     /// <summary>
1387*16467b97STreehugger Robot     /// What is index of token/char were we looking at when the error occurred?
1388*16467b97STreehugger Robot     /// </summary>
1389*16467b97STreehugger Robot     FIndex: Integer;
1390*16467b97STreehugger Robot 
1391*16467b97STreehugger Robot     /// <summary>
1392*16467b97STreehugger Robot     /// The current Token when an error occurred.  Since not all streams
1393*16467b97STreehugger Robot     /// can retrieve the ith Token, we have to track the Token object.
1394*16467b97STreehugger Robot     /// </summary>
1395*16467b97STreehugger Robot     FToken: IToken;
1396*16467b97STreehugger Robot 
1397*16467b97STreehugger Robot     /// <summary>[Tree parser] Node with the problem.</summary>
1398*16467b97STreehugger Robot     FNode: IANTLRInterface;
1399*16467b97STreehugger Robot 
1400*16467b97STreehugger Robot     /// <summary>The current char when an error occurred. For lexers. </summary>
1401*16467b97STreehugger Robot     FC: Integer;
1402*16467b97STreehugger Robot 
1403*16467b97STreehugger Robot     /// <summary>Track the line at which the error occurred in case this is
1404*16467b97STreehugger Robot     /// generated from a lexer.  We need to track this since the
1405*16467b97STreehugger Robot     /// unexpected char doesn't carry the line info.
1406*16467b97STreehugger Robot     /// </summary>
1407*16467b97STreehugger Robot     FLine: Integer;
1408*16467b97STreehugger Robot     FCharPositionInLine: Integer;
1409*16467b97STreehugger Robot   strict protected
1410*16467b97STreehugger Robot     procedure ExtractInformationFromTreeNodeStream(const Input: IIntStream);
GetUnexpectedType()1411*16467b97STreehugger Robot     function GetUnexpectedType: Integer; virtual;
1412*16467b97STreehugger Robot   public
1413*16467b97STreehugger Robot     /// <summary>Used for remote debugger deserialization </summary>
1414*16467b97STreehugger Robot     constructor Create; overload;
1415*16467b97STreehugger Robot     constructor Create(const AMessage: String); overload;
1416*16467b97STreehugger Robot     constructor Create(const AInput: IIntStream); overload;
1417*16467b97STreehugger Robot     constructor Create(const AMessage: String; const AInput: IIntStream); overload;
1418*16467b97STreehugger Robot 
1419*16467b97STreehugger Robot     /// <summary>
1420*16467b97STreehugger Robot     /// If you are parsing a tree node stream, you will encounter some
1421*16467b97STreehugger Robot     /// imaginary nodes w/o line/col info.  We now search backwards looking
1422*16467b97STreehugger Robot     /// for most recent token with line/col info, but notify getErrorHeader()
1423*16467b97STreehugger Robot     /// that info is approximate.
1424*16467b97STreehugger Robot     /// </summary>
1425*16467b97STreehugger Robot     property ApproximateLineInfo: Boolean read FApproximateLineInfo write FApproximateLineInfo;
1426*16467b97STreehugger Robot 
1427*16467b97STreehugger Robot     /// <summary>
1428*16467b97STreehugger Robot     /// Returns the current Token when the error occurred (for parsers
1429*16467b97STreehugger Robot     /// although a tree parser might also set the token)
1430*16467b97STreehugger Robot     /// </summary>
1431*16467b97STreehugger Robot     property Token: IToken read FToken write FToken;
1432*16467b97STreehugger Robot 
1433*16467b97STreehugger Robot     /// <summary>
1434*16467b97STreehugger Robot     /// Returns the [tree parser] node where the error occured (for tree parsers).
1435*16467b97STreehugger Robot     /// </summary>
1436*16467b97STreehugger Robot     property Node: IANTLRInterface read FNode write FNode;
1437*16467b97STreehugger Robot 
1438*16467b97STreehugger Robot     /// <summary>
1439*16467b97STreehugger Robot     /// Returns the line at which the error occurred (for lexers)
1440*16467b97STreehugger Robot     /// </summary>
1441*16467b97STreehugger Robot     property Line: Integer read FLine write FLine;
1442*16467b97STreehugger Robot 
1443*16467b97STreehugger Robot     /// <summary>
1444*16467b97STreehugger Robot     /// Returns the character position in the line when the error
1445*16467b97STreehugger Robot     /// occurred (for lexers)
1446*16467b97STreehugger Robot     /// </summary>
1447*16467b97STreehugger Robot     property CharPositionInLine: Integer read FCharPositionInLine write FCharPositionInLine;
1448*16467b97STreehugger Robot 
1449*16467b97STreehugger Robot     /// <summary>Returns the input stream in which the error occurred</summary>
1450*16467b97STreehugger Robot     property Input: IIntStream read FInput write FInput;
1451*16467b97STreehugger Robot 
1452*16467b97STreehugger Robot     /// <summary>
1453*16467b97STreehugger Robot     /// Returns the token type or char of the unexpected input element
1454*16467b97STreehugger Robot     /// </summary>
1455*16467b97STreehugger Robot     property UnexpectedType: Integer read GetUnexpectedType;
1456*16467b97STreehugger Robot 
1457*16467b97STreehugger Robot     /// <summary>
1458*16467b97STreehugger Robot     /// Returns the current char when the error occurred (for lexers)
1459*16467b97STreehugger Robot     /// </summary>
1460*16467b97STreehugger Robot     property Character: Integer read FC write FC;
1461*16467b97STreehugger Robot 
1462*16467b97STreehugger Robot     /// <summary>
1463*16467b97STreehugger Robot     /// Returns the token/char index in the stream when the error occurred
1464*16467b97STreehugger Robot     /// </summary>
1465*16467b97STreehugger Robot     property Index: Integer read FIndex write FIndex;
1466*16467b97STreehugger Robot   end;
1467*16467b97STreehugger Robot 
1468*16467b97STreehugger Robot   /// <summary>
1469*16467b97STreehugger Robot   /// A mismatched char or Token or tree node.
1470*16467b97STreehugger Robot   /// </summary>
1471*16467b97STreehugger Robot   EMismatchedTokenException = class(ERecognitionException)
1472*16467b97STreehugger Robot   strict private
1473*16467b97STreehugger Robot     FExpecting: Integer;
1474*16467b97STreehugger Robot   public
1475*16467b97STreehugger Robot     constructor Create(const AExpecting: Integer; const AInput: IIntStream);
1476*16467b97STreehugger Robot 
ToString()1477*16467b97STreehugger Robot     function ToString: String; override;
1478*16467b97STreehugger Robot 
1479*16467b97STreehugger Robot     property Expecting: Integer read FExpecting write FExpecting;
1480*16467b97STreehugger Robot   end;
1481*16467b97STreehugger Robot 
1482*16467b97STreehugger Robot   EUnwantedTokenException = class(EMismatchedTokenException)
1483*16467b97STreehugger Robot   strict private
GetUnexpectedToken()1484*16467b97STreehugger Robot     function GetUnexpectedToken: IToken;
1485*16467b97STreehugger Robot   public
1486*16467b97STreehugger Robot     property UnexpectedToken: IToken read GetUnexpectedToken;
1487*16467b97STreehugger Robot 
ToString()1488*16467b97STreehugger Robot     function ToString: String; override;
1489*16467b97STreehugger Robot   end;
1490*16467b97STreehugger Robot 
1491*16467b97STreehugger Robot   /// <summary>
1492*16467b97STreehugger Robot   /// We were expecting a token but it's not found. The current token
1493*16467b97STreehugger Robot   /// is actually what we wanted next. Used for tree node errors too.
1494*16467b97STreehugger Robot   /// </summary>
1495*16467b97STreehugger Robot   EMissingTokenException = class(EMismatchedTokenException)
1496*16467b97STreehugger Robot   strict private
1497*16467b97STreehugger Robot     FInserted: IANTLRInterface;
GetMissingType()1498*16467b97STreehugger Robot     function GetMissingType: Integer;
1499*16467b97STreehugger Robot   public
1500*16467b97STreehugger Robot     constructor Create(const AExpecting: Integer; const AInput: IIntStream;
1501*16467b97STreehugger Robot       const AInserted: IANTLRInterface);
1502*16467b97STreehugger Robot 
ToString()1503*16467b97STreehugger Robot     function ToString: String; override;
1504*16467b97STreehugger Robot 
1505*16467b97STreehugger Robot     property MissingType: Integer read GetMissingType;
1506*16467b97STreehugger Robot     property Inserted: IANTLRInterface read FInserted write FInserted;
1507*16467b97STreehugger Robot   end;
1508*16467b97STreehugger Robot 
1509*16467b97STreehugger Robot   EMismatchedTreeNodeException = class(ERecognitionException)
1510*16467b97STreehugger Robot   strict private
1511*16467b97STreehugger Robot     FExpecting: Integer;
1512*16467b97STreehugger Robot   public
1513*16467b97STreehugger Robot     constructor Create(const AExpecting: Integer; const AInput: IIntStream);
1514*16467b97STreehugger Robot 
ToString()1515*16467b97STreehugger Robot     function ToString: String; override;
1516*16467b97STreehugger Robot 
1517*16467b97STreehugger Robot     property Expecting: Integer read FExpecting write FExpecting;
1518*16467b97STreehugger Robot   end;
1519*16467b97STreehugger Robot 
1520*16467b97STreehugger Robot   ENoViableAltException = class(ERecognitionException)
1521*16467b97STreehugger Robot   strict private
1522*16467b97STreehugger Robot     FGrammarDecisionDescription: String;
1523*16467b97STreehugger Robot     FDecisionNumber: Integer;
1524*16467b97STreehugger Robot     FStateNumber: Integer;
1525*16467b97STreehugger Robot   public
1526*16467b97STreehugger Robot     constructor Create(const AGrammarDecisionDescription: String;
1527*16467b97STreehugger Robot       const ADecisionNumber, AStateNumber: Integer; const AInput: IIntStream);
1528*16467b97STreehugger Robot 
ToString()1529*16467b97STreehugger Robot     function ToString: String; override;
1530*16467b97STreehugger Robot 
1531*16467b97STreehugger Robot     property GrammarDecisionDescription: String read FGrammarDecisionDescription;
1532*16467b97STreehugger Robot     property DecisionNumber: Integer read FDecisionNumber;
1533*16467b97STreehugger Robot     property StateNumber: Integer read FStateNumber;
1534*16467b97STreehugger Robot   end;
1535*16467b97STreehugger Robot 
1536*16467b97STreehugger Robot   EEarlyExitException = class(ERecognitionException)
1537*16467b97STreehugger Robot   strict private
1538*16467b97STreehugger Robot     FDecisionNumber: Integer;
1539*16467b97STreehugger Robot   public
1540*16467b97STreehugger Robot     constructor Create(const ADecisionNumber: Integer; const AInput: IIntStream);
1541*16467b97STreehugger Robot 
1542*16467b97STreehugger Robot     property DecisionNumber: Integer read FDecisionNumber;
1543*16467b97STreehugger Robot   end;
1544*16467b97STreehugger Robot 
1545*16467b97STreehugger Robot   EMismatchedSetException = class(ERecognitionException)
1546*16467b97STreehugger Robot   strict private
1547*16467b97STreehugger Robot     FExpecting: IBitSet;
1548*16467b97STreehugger Robot   public
1549*16467b97STreehugger Robot     constructor Create(const AExpecting: IBitSet; const AInput: IIntStream);
1550*16467b97STreehugger Robot 
ToString()1551*16467b97STreehugger Robot     function ToString: String; override;
1552*16467b97STreehugger Robot 
1553*16467b97STreehugger Robot     property Expecting: IBitSet read FExpecting write FExpecting;
1554*16467b97STreehugger Robot   end;
1555*16467b97STreehugger Robot 
1556*16467b97STreehugger Robot   EMismatchedNotSetException = class(EMismatchedSetException)
1557*16467b97STreehugger Robot 
1558*16467b97STreehugger Robot   public
ToString()1559*16467b97STreehugger Robot     function ToString: String; override;
1560*16467b97STreehugger Robot   end;
1561*16467b97STreehugger Robot 
1562*16467b97STreehugger Robot   EFailedPredicateException = class(ERecognitionException)
1563*16467b97STreehugger Robot   strict private
1564*16467b97STreehugger Robot     FRuleName: String;
1565*16467b97STreehugger Robot     FPredicateText: String;
1566*16467b97STreehugger Robot   public
1567*16467b97STreehugger Robot     constructor Create(const AInput: IIntStream; const ARuleName,
1568*16467b97STreehugger Robot       APredicateText: String);
1569*16467b97STreehugger Robot 
ToString()1570*16467b97STreehugger Robot     function ToString: String; override;
1571*16467b97STreehugger Robot 
1572*16467b97STreehugger Robot     property RuleName: String read FRuleName write FRuleName;
1573*16467b97STreehugger Robot     property PredicateText: String read FPredicateText write FPredicateText;
1574*16467b97STreehugger Robot   end;
1575*16467b97STreehugger Robot 
1576*16467b97STreehugger Robot   EMismatchedRangeException = class(ERecognitionException)
1577*16467b97STreehugger Robot   strict private
1578*16467b97STreehugger Robot     FA: Integer;
1579*16467b97STreehugger Robot     FB: Integer;
1580*16467b97STreehugger Robot   public
1581*16467b97STreehugger Robot     constructor Create(const AA, AB: Integer; const AInput: IIntStream);
1582*16467b97STreehugger Robot 
ToString()1583*16467b97STreehugger Robot     function ToString: String; override;
1584*16467b97STreehugger Robot 
1585*16467b97STreehugger Robot     property A: Integer read FA write FA;
1586*16467b97STreehugger Robot     property B: Integer read FB write FB;
1587*16467b97STreehugger Robot   end;
1588*16467b97STreehugger Robot 
1589*16467b97STreehugger Robot type
1590*16467b97STreehugger Robot   TCharStreamState = class(TANTLRObject, ICharStreamState)
1591*16467b97STreehugger Robot   strict private
1592*16467b97STreehugger Robot     FP: Integer;
1593*16467b97STreehugger Robot     FLine: Integer;
1594*16467b97STreehugger Robot     FCharPositionInLine: Integer;
1595*16467b97STreehugger Robot   protected
1596*16467b97STreehugger Robot     { ICharStreamState }
GetP()1597*16467b97STreehugger Robot     function GetP: Integer;
1598*16467b97STreehugger Robot     procedure SetP(const Value: Integer);
GetLine()1599*16467b97STreehugger Robot     function GetLine: Integer;
1600*16467b97STreehugger Robot     procedure SetLine(const Value: Integer);
GetCharPositionInLine()1601*16467b97STreehugger Robot     function GetCharPositionInLine: Integer;
1602*16467b97STreehugger Robot     procedure SetCharPositionInLine(const Value: Integer);
1603*16467b97STreehugger Robot   end;
1604*16467b97STreehugger Robot 
1605*16467b97STreehugger Robot type
1606*16467b97STreehugger Robot   TANTLRStringStream = class(TANTLRObject, IANTLRStringStream, ICharStream)
1607*16467b97STreehugger Robot   private
1608*16467b97STreehugger Robot     FData: PChar;
1609*16467b97STreehugger Robot     FOwnsData: Boolean;
1610*16467b97STreehugger Robot 
1611*16467b97STreehugger Robot     /// <summary>How many characters are actually in the buffer?</summary>
1612*16467b97STreehugger Robot     FN: Integer;
1613*16467b97STreehugger Robot 
1614*16467b97STreehugger Robot     /// <summary>Current line number within the input (1..n )</summary>
1615*16467b97STreehugger Robot     FLine: Integer;
1616*16467b97STreehugger Robot 
1617*16467b97STreehugger Robot     /// <summary>Index in our array for the next char (0..n-1)</summary>
1618*16467b97STreehugger Robot     FP: Integer;
1619*16467b97STreehugger Robot 
1620*16467b97STreehugger Robot     /// <summary>
1621*16467b97STreehugger Robot     /// The index of the character relative to the beginning of the
1622*16467b97STreehugger Robot     /// line (0..n-1)
1623*16467b97STreehugger Robot     /// </summary>
1624*16467b97STreehugger Robot     FCharPositionInLine: Integer;
1625*16467b97STreehugger Robot 
1626*16467b97STreehugger Robot     /// <summary>
1627*16467b97STreehugger Robot     /// Tracks the depth of nested <see cref="IIntStream.Mark"/> calls
1628*16467b97STreehugger Robot     /// </summary>
1629*16467b97STreehugger Robot     FMarkDepth: Integer;
1630*16467b97STreehugger Robot 
1631*16467b97STreehugger Robot     /// <summary>
1632*16467b97STreehugger Robot     /// A list of CharStreamState objects that tracks the stream state
1633*16467b97STreehugger Robot     /// (i.e. line, charPositionInLine, and p) that can change as you
1634*16467b97STreehugger Robot     /// move through the input stream.  Indexed from 1..markDepth.
1635*16467b97STreehugger Robot     /// A null is kept @ index 0.  Create upon first call to Mark().
1636*16467b97STreehugger Robot     /// </summary>
1637*16467b97STreehugger Robot     FMarkers: IList<ICharStreamState>;
1638*16467b97STreehugger Robot 
1639*16467b97STreehugger Robot     /// <summary>
1640*16467b97STreehugger Robot     /// Track the last Mark() call result value for use in Rewind().
1641*16467b97STreehugger Robot     /// </summary>
1642*16467b97STreehugger Robot     FLastMarker: Integer;
1643*16467b97STreehugger Robot     /// <summary>
1644*16467b97STreehugger Robot     /// What is name or source of this char stream?
1645*16467b97STreehugger Robot     /// </summary>
1646*16467b97STreehugger Robot     FName: String;
1647*16467b97STreehugger Robot   protected
1648*16467b97STreehugger Robot     { IIntStream }
GetSourceName()1649*16467b97STreehugger Robot     function GetSourceName: String; virtual;
1650*16467b97STreehugger Robot 
1651*16467b97STreehugger Robot     procedure Consume; virtual;
LA(I: Integer)1652*16467b97STreehugger Robot     function LA(I: Integer): Integer; virtual;
LAChar(I: Integer)1653*16467b97STreehugger Robot     function LAChar(I: Integer): Char;
Index()1654*16467b97STreehugger Robot     function Index: Integer;
Size()1655*16467b97STreehugger Robot     function Size: Integer;
Mark()1656*16467b97STreehugger Robot     function Mark: Integer; virtual;
1657*16467b97STreehugger Robot     procedure Rewind(const Marker: Integer); overload; virtual;
1658*16467b97STreehugger Robot     procedure Rewind; overload; virtual;
1659*16467b97STreehugger Robot     procedure Release(const Marker: Integer); virtual;
1660*16467b97STreehugger Robot     procedure Seek(const Index: Integer); virtual;
1661*16467b97STreehugger Robot 
1662*16467b97STreehugger Robot     property SourceName: String read GetSourceName write FName;
1663*16467b97STreehugger Robot   protected
1664*16467b97STreehugger Robot     { ICharStream }
GetLine()1665*16467b97STreehugger Robot     function GetLine: Integer; virtual;
1666*16467b97STreehugger Robot     procedure SetLine(const Value: Integer); virtual;
GetCharPositionInLine()1667*16467b97STreehugger Robot     function GetCharPositionInLine: Integer; virtual;
1668*16467b97STreehugger Robot     procedure SetCharPositionInLine(const Value: Integer); virtual;
LT(const I: Integer)1669*16467b97STreehugger Robot     function LT(const I: Integer): Integer; virtual;
Substring(const Start, Stop: Integer)1670*16467b97STreehugger Robot     function Substring(const Start, Stop: Integer): String; virtual;
1671*16467b97STreehugger Robot   protected
1672*16467b97STreehugger Robot     { IANTLRStringStream }
1673*16467b97STreehugger Robot     procedure Reset; virtual;
1674*16467b97STreehugger Robot   public
1675*16467b97STreehugger Robot     constructor Create; overload;
1676*16467b97STreehugger Robot 
1677*16467b97STreehugger Robot     /// <summary>
1678*16467b97STreehugger Robot     /// Initializes a new instance of the ANTLRStringStream class for the
1679*16467b97STreehugger Robot     /// specified string. This copies data from the string to a local
1680*16467b97STreehugger Robot     /// character array
1681*16467b97STreehugger Robot     /// </summary>
1682*16467b97STreehugger Robot     constructor Create(const AInput: String); overload;
1683*16467b97STreehugger Robot 
1684*16467b97STreehugger Robot     /// <summary>
1685*16467b97STreehugger Robot     /// Initializes a new instance of the ANTLRStringStream class for the
1686*16467b97STreehugger Robot     /// specified character array. This is the preferred constructor as
1687*16467b97STreehugger Robot     /// no data is copied
1688*16467b97STreehugger Robot     /// </summary>
1689*16467b97STreehugger Robot     constructor Create(const AData: PChar;
1690*16467b97STreehugger Robot       const ANumberOfActualCharsInArray: Integer); overload;
1691*16467b97STreehugger Robot 
1692*16467b97STreehugger Robot     destructor Destroy; override;
1693*16467b97STreehugger Robot   end;
1694*16467b97STreehugger Robot 
1695*16467b97STreehugger Robot   TANTLRFileStream = class(TANTLRStringStream, IANTLRFileStream)
1696*16467b97STreehugger Robot   strict private
1697*16467b97STreehugger Robot     /// <summary>Fully qualified name of the stream's underlying file</summary>
1698*16467b97STreehugger Robot     FFileName: String;
1699*16467b97STreehugger Robot   protected
1700*16467b97STreehugger Robot     { IIntStream }
GetSourceName()1701*16467b97STreehugger Robot     function GetSourceName: String; override;
1702*16467b97STreehugger Robot   protected
1703*16467b97STreehugger Robot     { IANTLRFileStream }
1704*16467b97STreehugger Robot 
1705*16467b97STreehugger Robot     procedure Load(const FileName: String; const Encoding: TEncoding); virtual;
1706*16467b97STreehugger Robot   public
1707*16467b97STreehugger Robot     /// <summary>
1708*16467b97STreehugger Robot     /// Initializes a new instance of the ANTLRFileStream class for the
1709*16467b97STreehugger Robot     /// specified file name
1710*16467b97STreehugger Robot     /// </summary>
1711*16467b97STreehugger Robot     constructor Create(const AFileName: String); overload;
1712*16467b97STreehugger Robot 
1713*16467b97STreehugger Robot     /// <summary>
1714*16467b97STreehugger Robot     /// Initializes a new instance of the ANTLRFileStream class for the
1715*16467b97STreehugger Robot     /// specified file name and encoding
1716*16467b97STreehugger Robot     /// </summary>
1717*16467b97STreehugger Robot     constructor Create(const AFileName: String; const AEncoding: TEncoding); overload;
1718*16467b97STreehugger Robot   end;
1719*16467b97STreehugger Robot 
1720*16467b97STreehugger Robot   TBitSet = class(TANTLRObject, IBitSet, ICloneable)
1721*16467b97STreehugger Robot   strict private
1722*16467b97STreehugger Robot     const
1723*16467b97STreehugger Robot       BITS = 64; // number of bits / ulong
1724*16467b97STreehugger Robot       LOG_BITS = 6; // 2 shl 6 = 64
1725*16467b97STreehugger Robot 
1726*16467b97STreehugger Robot       ///<summary> We will often need to do a mod operator (i mod nbits).
1727*16467b97STreehugger Robot       /// Its turns out that, for powers of two, this mod operation is
1728*16467b97STreehugger Robot       ///  same as <![CDATA[(I and (nbits-1))]]>.  Since mod is slow, we use a precomputed
1729*16467b97STreehugger Robot       /// mod mask to do the mod instead.
1730*16467b97STreehugger Robot       /// </summary>
1731*16467b97STreehugger Robot       MOD_MASK = BITS - 1;
1732*16467b97STreehugger Robot   strict private
1733*16467b97STreehugger Robot     /// <summary>The actual data bits </summary>
1734*16467b97STreehugger Robot     FBits: TUInt64Array;
1735*16467b97STreehugger Robot   strict private
WordNumber(const Bit: Integer)1736*16467b97STreehugger Robot     class function WordNumber(const Bit: Integer): Integer; static;
BitMask(const BitNumber: Integer)1737*16467b97STreehugger Robot     class function BitMask(const BitNumber: Integer): UInt64; static;
NumWordsToHold(const El: Integer)1738*16467b97STreehugger Robot     class function NumWordsToHold(const El: Integer): Integer; static;
1739*16467b97STreehugger Robot   protected
1740*16467b97STreehugger Robot     { ICloneable }
Clone()1741*16467b97STreehugger Robot     function Clone: IANTLRInterface; virtual;
1742*16467b97STreehugger Robot   protected
1743*16467b97STreehugger Robot     { IBitSet }
GetIsNil()1744*16467b97STreehugger Robot     function GetIsNil: Boolean; virtual;
BitSetOr(const A: IBitSet)1745*16467b97STreehugger Robot     function BitSetOr(const A: IBitSet): IBitSet; virtual;
1746*16467b97STreehugger Robot     procedure Add(const El: Integer); virtual;
1747*16467b97STreehugger Robot     procedure GrowToInclude(const Bit: Integer); virtual;
1748*16467b97STreehugger Robot     procedure OrInPlace(const A: IBitSet); virtual;
Size()1749*16467b97STreehugger Robot     function Size: Integer; virtual;
Member(const El: Integer)1750*16467b97STreehugger Robot     function Member(const El: Integer): Boolean; virtual;
1751*16467b97STreehugger Robot     procedure Remove(const El: Integer); virtual;
NumBits()1752*16467b97STreehugger Robot     function NumBits: Integer; virtual;
LengthInLongWords()1753*16467b97STreehugger Robot     function LengthInLongWords: Integer; virtual;
ToArray()1754*16467b97STreehugger Robot     function ToArray: TIntegerArray; virtual;
ToPackedArray()1755*16467b97STreehugger Robot     function ToPackedArray: TUInt64Array; virtual;
ToString(const TokenNames: TStringArray)1756*16467b97STreehugger Robot     function ToString(const TokenNames: TStringArray): String; reintroduce; overload; virtual;
1757*16467b97STreehugger Robot   public
1758*16467b97STreehugger Robot     /// <summary>Construct a bitset of size one word (64 bits) </summary>
1759*16467b97STreehugger Robot     constructor Create; overload;
1760*16467b97STreehugger Robot 
1761*16467b97STreehugger Robot     /// <summary>Construction from a static array of ulongs </summary>
1762*16467b97STreehugger Robot     constructor Create(const ABits: array of UInt64); overload;
1763*16467b97STreehugger Robot 
1764*16467b97STreehugger Robot     /// <summary>Construction from a list of integers </summary>
1765*16467b97STreehugger Robot     constructor Create(const AItems: IList<Integer>); overload;
1766*16467b97STreehugger Robot 
1767*16467b97STreehugger Robot     /// <summary>Construct a bitset given the size</summary>
1768*16467b97STreehugger Robot     /// <param name="nbits">The size of the bitset in bits</param>
1769*16467b97STreehugger Robot     constructor Create(const ANBits: Integer); overload;
1770*16467b97STreehugger Robot 
BitSetOf(const El: Integer)1771*16467b97STreehugger Robot     class function BitSetOf(const El: Integer): IBitSet; overload; static;
BitSetOf(const A, B: Integer)1772*16467b97STreehugger Robot     class function BitSetOf(const A, B: Integer): IBitSet; overload; static;
BitSetOf(const A, B, C: Integer)1773*16467b97STreehugger Robot     class function BitSetOf(const A, B, C: Integer): IBitSet; overload; static;
BitSetOf(const A, B, C, D: Integer)1774*16467b97STreehugger Robot     class function BitSetOf(const A, B, C, D: Integer): IBitSet; overload; static;
1775*16467b97STreehugger Robot 
ToString()1776*16467b97STreehugger Robot     function ToString: String; overload; override;
Equals(Obj: TObject)1777*16467b97STreehugger Robot     function Equals(Obj: TObject): Boolean; override;
1778*16467b97STreehugger Robot   end;
1779*16467b97STreehugger Robot 
1780*16467b97STreehugger Robot   TRecognizerSharedState = class(TANTLRObject, IRecognizerSharedState)
1781*16467b97STreehugger Robot   strict private
1782*16467b97STreehugger Robot     FFollowing: TBitSetArray;
1783*16467b97STreehugger Robot     FFollowingStackPointer: Integer;
1784*16467b97STreehugger Robot     FErrorRecovery: Boolean;
1785*16467b97STreehugger Robot     FLastErrorIndex: Integer;
1786*16467b97STreehugger Robot     FFailed: Boolean;
1787*16467b97STreehugger Robot     FSyntaxErrors: Integer;
1788*16467b97STreehugger Robot     FBacktracking: Integer;
1789*16467b97STreehugger Robot     FRuleMemo: TDictionaryArray<Integer, Integer>;
1790*16467b97STreehugger Robot     FToken: IToken;
1791*16467b97STreehugger Robot     FTokenStartCharIndex: Integer;
1792*16467b97STreehugger Robot     FTokenStartLine: Integer;
1793*16467b97STreehugger Robot     FTokenStartCharPositionInLine: Integer;
1794*16467b97STreehugger Robot     FChannel: Integer;
1795*16467b97STreehugger Robot     FTokenType: Integer;
1796*16467b97STreehugger Robot     FText: String;
1797*16467b97STreehugger Robot   protected
1798*16467b97STreehugger Robot     { IRecognizerSharedState }
GetFollowing()1799*16467b97STreehugger Robot     function GetFollowing: TBitSetArray;
1800*16467b97STreehugger Robot     procedure SetFollowing(const Value: TBitSetArray);
GetFollowingStackPointer()1801*16467b97STreehugger Robot     function GetFollowingStackPointer: Integer;
1802*16467b97STreehugger Robot     procedure SetFollowingStackPointer(const Value: Integer);
GetErrorRecovery()1803*16467b97STreehugger Robot     function GetErrorRecovery: Boolean;
1804*16467b97STreehugger Robot     procedure SetErrorRecovery(const Value: Boolean);
GetLastErrorIndex()1805*16467b97STreehugger Robot     function GetLastErrorIndex: Integer;
1806*16467b97STreehugger Robot     procedure SetLastErrorIndex(const Value: Integer);
GetFailed()1807*16467b97STreehugger Robot     function GetFailed: Boolean;
1808*16467b97STreehugger Robot     procedure SetFailed(const Value: Boolean);
GetSyntaxErrors()1809*16467b97STreehugger Robot     function GetSyntaxErrors: Integer;
1810*16467b97STreehugger Robot     procedure SetSyntaxErrors(const Value: Integer);
GetBacktracking()1811*16467b97STreehugger Robot     function GetBacktracking: Integer;
1812*16467b97STreehugger Robot     procedure SetBacktracking(const Value: Integer);
GetRuleMemo()1813*16467b97STreehugger Robot     function GetRuleMemo: TDictionaryArray<Integer, Integer>;
GetRuleMemoCount()1814*16467b97STreehugger Robot     function GetRuleMemoCount: Integer;
1815*16467b97STreehugger Robot     procedure SetRuleMemoCount(const Value: Integer);
GetToken()1816*16467b97STreehugger Robot     function GetToken: IToken;
1817*16467b97STreehugger Robot     procedure SetToken(const Value: IToken);
GetTokenStartCharIndex()1818*16467b97STreehugger Robot     function GetTokenStartCharIndex: Integer;
1819*16467b97STreehugger Robot     procedure SetTokenStartCharIndex(const Value: Integer);
GetTokenStartLine()1820*16467b97STreehugger Robot     function GetTokenStartLine: Integer;
1821*16467b97STreehugger Robot     procedure SetTokenStartLine(const Value: Integer);
GetTokenStartCharPositionInLine()1822*16467b97STreehugger Robot     function GetTokenStartCharPositionInLine: Integer;
1823*16467b97STreehugger Robot     procedure SetTokenStartCharPositionInLine(const Value: Integer);
GetChannel()1824*16467b97STreehugger Robot     function GetChannel: Integer;
1825*16467b97STreehugger Robot     procedure SetChannel(const Value: Integer);
GetTokenType()1826*16467b97STreehugger Robot     function GetTokenType: Integer;
1827*16467b97STreehugger Robot     procedure SetTokenType(const Value: Integer);
GetText()1828*16467b97STreehugger Robot     function GetText: String;
1829*16467b97STreehugger Robot     procedure SetText(const Value: String);
1830*16467b97STreehugger Robot   public
1831*16467b97STreehugger Robot     constructor Create;
1832*16467b97STreehugger Robot   end;
1833*16467b97STreehugger Robot 
1834*16467b97STreehugger Robot   TCommonToken = class(TANTLRObject, ICommonToken, IToken)
1835*16467b97STreehugger Robot   strict protected
1836*16467b97STreehugger Robot     FTokenType: Integer;
1837*16467b97STreehugger Robot     FLine: Integer;
1838*16467b97STreehugger Robot     FCharPositionInLine: Integer;
1839*16467b97STreehugger Robot     FChannel: Integer;
1840*16467b97STreehugger Robot     FInput: ICharStream;
1841*16467b97STreehugger Robot 
1842*16467b97STreehugger Robot     /// <summary>We need to be able to change the text once in a while.  If
1843*16467b97STreehugger Robot     /// this is non-null, then getText should return this.  Note that
1844*16467b97STreehugger Robot     /// start/stop are not affected by changing this.
1845*16467b97STreehugger Robot     /// </summary>
1846*16467b97STreehugger Robot     FText: String;
1847*16467b97STreehugger Robot 
1848*16467b97STreehugger Robot     /// <summary>What token number is this from 0..n-1 tokens; &lt; 0 implies invalid index </summary>
1849*16467b97STreehugger Robot     FIndex: Integer;
1850*16467b97STreehugger Robot 
1851*16467b97STreehugger Robot     /// <summary>The char position into the input buffer where this token starts </summary>
1852*16467b97STreehugger Robot     FStart: Integer;
1853*16467b97STreehugger Robot 
1854*16467b97STreehugger Robot     /// <summary>The char position into the input buffer where this token stops </summary>
1855*16467b97STreehugger Robot     FStop: Integer;
1856*16467b97STreehugger Robot   protected
1857*16467b97STreehugger Robot     { IToken }
GetTokenType()1858*16467b97STreehugger Robot     function GetTokenType: Integer; virtual;
1859*16467b97STreehugger Robot     procedure SetTokenType(const Value: Integer); virtual;
GetLine()1860*16467b97STreehugger Robot     function GetLine: Integer; virtual;
1861*16467b97STreehugger Robot     procedure SetLine(const Value: Integer); virtual;
GetCharPositionInLine()1862*16467b97STreehugger Robot     function GetCharPositionInLine: Integer; virtual;
1863*16467b97STreehugger Robot     procedure SetCharPositionInLine(const Value: Integer); virtual;
GetChannel()1864*16467b97STreehugger Robot     function GetChannel: Integer; virtual;
1865*16467b97STreehugger Robot     procedure SetChannel(const Value: Integer); virtual;
GetTokenIndex()1866*16467b97STreehugger Robot     function GetTokenIndex: Integer; virtual;
1867*16467b97STreehugger Robot     procedure SetTokenIndex(const Value: Integer); virtual;
GetText()1868*16467b97STreehugger Robot     function GetText: String; virtual;
1869*16467b97STreehugger Robot     procedure SetText(const Value: String); virtual;
1870*16467b97STreehugger Robot   protected
1871*16467b97STreehugger Robot     { ICommonToken }
GetStartIndex()1872*16467b97STreehugger Robot     function GetStartIndex: Integer;
1873*16467b97STreehugger Robot     procedure SetStartIndex(const Value: Integer);
GetStopIndex()1874*16467b97STreehugger Robot     function GetStopIndex: Integer;
1875*16467b97STreehugger Robot     procedure SetStopIndex(const Value: Integer);
GetInputStream()1876*16467b97STreehugger Robot     function GetInputStream: ICharStream;
1877*16467b97STreehugger Robot     procedure SetInputStream(const Value: ICharStream);
1878*16467b97STreehugger Robot   protected
1879*16467b97STreehugger Robot     constructor Create; overload;
1880*16467b97STreehugger Robot   public
1881*16467b97STreehugger Robot     constructor Create(const ATokenType: Integer); overload;
1882*16467b97STreehugger Robot     constructor Create(const AInput: ICharStream; const ATokenType, AChannel,
1883*16467b97STreehugger Robot       AStart, AStop: Integer); overload;
1884*16467b97STreehugger Robot     constructor Create(const ATokenType: Integer; const AText: String); overload;
1885*16467b97STreehugger Robot     constructor Create(const AOldToken: IToken); overload;
1886*16467b97STreehugger Robot 
ToString()1887*16467b97STreehugger Robot     function ToString: String; override;
1888*16467b97STreehugger Robot   end;
1889*16467b97STreehugger Robot 
1890*16467b97STreehugger Robot   TClassicToken = class(TANTLRObject, IClassicToken, IToken)
1891*16467b97STreehugger Robot   strict private
1892*16467b97STreehugger Robot     FText: String;
1893*16467b97STreehugger Robot     FTokenType: Integer;
1894*16467b97STreehugger Robot     FLine: Integer;
1895*16467b97STreehugger Robot     FCharPositionInLine: Integer;
1896*16467b97STreehugger Robot     FChannel: Integer;
1897*16467b97STreehugger Robot 
1898*16467b97STreehugger Robot     /// <summary>What token number is this from 0..n-1 tokens </summary>
1899*16467b97STreehugger Robot     FIndex: Integer;
1900*16467b97STreehugger Robot   protected
1901*16467b97STreehugger Robot     { IClassicToken }
GetTokenType()1902*16467b97STreehugger Robot     function GetTokenType: Integer; virtual;
1903*16467b97STreehugger Robot     procedure SetTokenType(const Value: Integer); virtual;
GetLine()1904*16467b97STreehugger Robot     function GetLine: Integer; virtual;
1905*16467b97STreehugger Robot     procedure SetLine(const Value: Integer); virtual;
GetCharPositionInLine()1906*16467b97STreehugger Robot     function GetCharPositionInLine: Integer; virtual;
1907*16467b97STreehugger Robot     procedure SetCharPositionInLine(const Value: Integer); virtual;
GetChannel()1908*16467b97STreehugger Robot     function GetChannel: Integer; virtual;
1909*16467b97STreehugger Robot     procedure SetChannel(const Value: Integer); virtual;
GetTokenIndex()1910*16467b97STreehugger Robot     function GetTokenIndex: Integer; virtual;
1911*16467b97STreehugger Robot     procedure SetTokenIndex(const Value: Integer); virtual;
GetText()1912*16467b97STreehugger Robot     function GetText: String; virtual;
1913*16467b97STreehugger Robot     procedure SetText(const Value: String); virtual;
GetInputStream()1914*16467b97STreehugger Robot     function GetInputStream: ICharStream; virtual;
1915*16467b97STreehugger Robot     procedure SetInputStream(const Value: ICharStream); virtual;
1916*16467b97STreehugger Robot   public
1917*16467b97STreehugger Robot     constructor Create(const ATokenType: Integer); overload;
1918*16467b97STreehugger Robot     constructor Create(const AOldToken: IToken); overload;
1919*16467b97STreehugger Robot     constructor Create(const ATokenType: Integer; const AText: String); overload;
1920*16467b97STreehugger Robot     constructor Create(const ATokenType: Integer; const AText: String;
1921*16467b97STreehugger Robot       const AChannel: Integer); overload;
1922*16467b97STreehugger Robot 
ToString()1923*16467b97STreehugger Robot     function ToString: String; override;
1924*16467b97STreehugger Robot   end;
1925*16467b97STreehugger Robot 
1926*16467b97STreehugger Robot   TToken = class sealed
1927*16467b97STreehugger Robot   public
1928*16467b97STreehugger Robot     const
1929*16467b97STreehugger Robot       EOR_TOKEN_TYPE = 1;
1930*16467b97STreehugger Robot 
1931*16467b97STreehugger Robot       /// <summary>imaginary tree navigation type; traverse "get child" link </summary>
1932*16467b97STreehugger Robot       DOWN = 2;
1933*16467b97STreehugger Robot 
1934*16467b97STreehugger Robot       /// <summary>imaginary tree navigation type; finish with a child list </summary>
1935*16467b97STreehugger Robot       UP = 3;
1936*16467b97STreehugger Robot 
1937*16467b97STreehugger Robot       MIN_TOKEN_TYPE = UP + 1;
1938*16467b97STreehugger Robot       EOF = Integer(cscEOF);
1939*16467b97STreehugger Robot       INVALID_TOKEN_TYPE = 0;
1940*16467b97STreehugger Robot 
1941*16467b97STreehugger Robot       /// <summary>
1942*16467b97STreehugger Robot       /// All tokens go to the parser (unless skip() is called in that rule)
1943*16467b97STreehugger Robot       /// on a particular "channel".  The parser tunes to a particular channel
1944*16467b97STreehugger Robot       /// so that whitespace etc... can go to the parser on a "hidden" channel.
1945*16467b97STreehugger Robot       /// </summary>
1946*16467b97STreehugger Robot       DEFAULT_CHANNEL = 0;
1947*16467b97STreehugger Robot 
1948*16467b97STreehugger Robot       /// <summary>
1949*16467b97STreehugger Robot       /// Anything on different channel than DEFAULT_CHANNEL is not parsed by parser.
1950*16467b97STreehugger Robot       /// </summary>
1951*16467b97STreehugger Robot       HIDDEN_CHANNEL = 99;
1952*16467b97STreehugger Robot   public
1953*16467b97STreehugger Robot     class var
1954*16467b97STreehugger Robot       EOF_TOKEN: IToken;
1955*16467b97STreehugger Robot       INVALID_TOKEN: IToken;
1956*16467b97STreehugger Robot       /// <summary>
1957*16467b97STreehugger Robot       /// In an action, a lexer rule can set token to this SKIP_TOKEN and ANTLR
1958*16467b97STreehugger Robot       /// will avoid creating a token for this symbol and try to fetch another.
1959*16467b97STreehugger Robot       /// </summary>
1960*16467b97STreehugger Robot       SKIP_TOKEN: IToken;
1961*16467b97STreehugger Robot   private
1962*16467b97STreehugger Robot     class procedure Initialize; static;
1963*16467b97STreehugger Robot   end;
1964*16467b97STreehugger Robot 
1965*16467b97STreehugger Robot   /// <summary>
1966*16467b97STreehugger Robot     /// Global constants
1967*16467b97STreehugger Robot   /// </summary>
1968*16467b97STreehugger Robot   TConstants = class sealed
1969*16467b97STreehugger Robot   public
1970*16467b97STreehugger Robot     const
1971*16467b97STreehugger Robot       VERSION = '3.1b1';
1972*16467b97STreehugger Robot 
1973*16467b97STreehugger Robot       // Moved to version 2 for v3.1: added grammar name to enter/exit Rule
1974*16467b97STreehugger Robot       DEBUG_PROTOCOL_VERSION = '2';
1975*16467b97STreehugger Robot 
1976*16467b97STreehugger Robot       ANTLRWORKS_DIR = 'antlrworks';
1977*16467b97STreehugger Robot   end;
1978*16467b97STreehugger Robot 
1979*16467b97STreehugger Robot   TBaseRecognizer = class abstract(TANTLRObject, IBaseRecognizer)
1980*16467b97STreehugger Robot   public
1981*16467b97STreehugger Robot     const
1982*16467b97STreehugger Robot       MEMO_RULE_FAILED = -2;
1983*16467b97STreehugger Robot       MEMO_RULE_UNKNOWN = -1;
1984*16467b97STreehugger Robot       INITIAL_FOLLOW_STACK_SIZE = 100;
1985*16467b97STreehugger Robot       NEXT_TOKEN_RULE_NAME = 'nextToken';
1986*16467b97STreehugger Robot       // copies from Token object for convenience in actions
1987*16467b97STreehugger Robot       DEFAULT_TOKEN_CHANNEL = TToken.DEFAULT_CHANNEL;
1988*16467b97STreehugger Robot       HIDDEN = TToken.HIDDEN_CHANNEL;
1989*16467b97STreehugger Robot   strict protected
1990*16467b97STreehugger Robot     /// <summary>
1991*16467b97STreehugger Robot     /// An externalized representation of the - shareable - internal state of
1992*16467b97STreehugger Robot     /// this lexer, parser or tree parser.
1993*16467b97STreehugger Robot     /// </summary>
1994*16467b97STreehugger Robot     /// <remarks>
1995*16467b97STreehugger Robot     /// The state of a lexer, parser, or tree parser are collected into
1996*16467b97STreehugger Robot     /// external state objects so that the state can be shared. This sharing
1997*16467b97STreehugger Robot     /// is needed to have one grammar import others and share same error
1998*16467b97STreehugger Robot     /// variables and other state variables.  It's a kind of explicit multiple
1999*16467b97STreehugger Robot     /// inheritance via delegation of methods and shared state.
2000*16467b97STreehugger Robot     /// </remarks>
2001*16467b97STreehugger Robot     FState: IRecognizerSharedState;
2002*16467b97STreehugger Robot 
2003*16467b97STreehugger Robot     property State: IRecognizerSharedState read FState;
2004*16467b97STreehugger Robot   strict protected
2005*16467b97STreehugger Robot     /// <summary>
2006*16467b97STreehugger Robot     /// Match needs to return the current input symbol, which gets put
2007*16467b97STreehugger Robot     /// into the label for the associated token ref; e.g., x=ID.  Token
2008*16467b97STreehugger Robot     /// and tree parsers need to return different objects. Rather than test
2009*16467b97STreehugger Robot     /// for input stream type or change the IntStream interface, I use
2010*16467b97STreehugger Robot     /// a simple method to ask the recognizer to tell me what the current
2011*16467b97STreehugger Robot     /// input symbol is.
2012*16467b97STreehugger Robot     /// </summary>
2013*16467b97STreehugger Robot     /// <remarks>This is ignored for lexers.</remarks>
GetCurrentInputSymbol(const Input: IIntStream)2014*16467b97STreehugger Robot     function GetCurrentInputSymbol(const Input: IIntStream): IANTLRInterface; virtual;
2015*16467b97STreehugger Robot 
2016*16467b97STreehugger Robot     /// <summary>
2017*16467b97STreehugger Robot     /// Factor out what to do upon token mismatch so tree parsers can behave
2018*16467b97STreehugger Robot     /// differently.  Override and call MismatchRecover(input, ttype, follow)
2019*16467b97STreehugger Robot     /// to get single token insertion and deletion. Use this to turn off
2020*16467b97STreehugger Robot     /// single token insertion and deletion. Override mismatchRecover
2021*16467b97STreehugger Robot     /// to call this instead.
2022*16467b97STreehugger Robot     /// </summary>
2023*16467b97STreehugger Robot     procedure Mismatch(const Input: IIntStream; const TokenType: Integer;
2024*16467b97STreehugger Robot       const Follow: IBitSet); virtual;
2025*16467b97STreehugger Robot 
2026*16467b97STreehugger Robot     /// <summary>
2027*16467b97STreehugger Robot     /// Attempt to Recover from a single missing or extra token.
2028*16467b97STreehugger Robot     /// </summary>
2029*16467b97STreehugger Robot     /// <remarks>
2030*16467b97STreehugger Robot     /// EXTRA TOKEN
2031*16467b97STreehugger Robot     ///
2032*16467b97STreehugger Robot     /// LA(1) is not what we are looking for.  If LA(2) has the right token,
2033*16467b97STreehugger Robot     /// however, then assume LA(1) is some extra spurious token.  Delete it
2034*16467b97STreehugger Robot     /// and LA(2) as if we were doing a normal Match(), which advances the
2035*16467b97STreehugger Robot     /// input.
2036*16467b97STreehugger Robot     ///
2037*16467b97STreehugger Robot     /// MISSING TOKEN
2038*16467b97STreehugger Robot     ///
2039*16467b97STreehugger Robot     /// If current token is consistent with what could come after
2040*16467b97STreehugger Robot     /// ttype then it is ok to "insert" the missing token, else throw
2041*16467b97STreehugger Robot     /// exception For example, Input "i=(3;" is clearly missing the
2042*16467b97STreehugger Robot     /// ')'.  When the parser returns from the nested call to expr, it
2043*16467b97STreehugger Robot     /// will have call chain:
2044*16467b97STreehugger Robot     ///
2045*16467b97STreehugger Robot     /// stat -> expr -> atom
2046*16467b97STreehugger Robot     ///
2047*16467b97STreehugger Robot     /// and it will be trying to Match the ')' at this point in the
2048*16467b97STreehugger Robot     /// derivation:
2049*16467b97STreehugger Robot     ///
2050*16467b97STreehugger Robot     /// => ID '=' '(' INT ')' ('+' atom)* ';'
2051*16467b97STreehugger Robot     /// ^
2052*16467b97STreehugger Robot     /// Match() will see that ';' doesn't Match ')' and report a
2053*16467b97STreehugger Robot     /// mismatched token error.  To Recover, it sees that LA(1)==';'
2054*16467b97STreehugger Robot     /// is in the set of tokens that can follow the ')' token
2055*16467b97STreehugger Robot     /// reference in rule atom.  It can assume that you forgot the ')'.
2056*16467b97STreehugger Robot     /// </remarks>
RecoverFromMismatchedToken(const Input: IIntStream;2057*16467b97STreehugger Robot     function RecoverFromMismatchedToken(const Input: IIntStream;
2058*16467b97STreehugger Robot       const TokenType: Integer; const Follow: IBitSet): IANTLRInterface; virtual;
2059*16467b97STreehugger Robot 
2060*16467b97STreehugger Robot     /// <summary>
2061*16467b97STreehugger Robot     /// Conjure up a missing token during error recovery.
2062*16467b97STreehugger Robot     /// </summary>
2063*16467b97STreehugger Robot     /// <remarks>
2064*16467b97STreehugger Robot     /// The recognizer attempts to recover from single missing
2065*16467b97STreehugger Robot     /// symbols. But, actions might refer to that missing symbol.
2066*16467b97STreehugger Robot     /// For example, x=ID {f($x);}. The action clearly assumes
2067*16467b97STreehugger Robot     /// that there has been an identifier matched previously and that
2068*16467b97STreehugger Robot     /// $x points at that token. If that token is missing, but
2069*16467b97STreehugger Robot     /// the next token in the stream is what we want we assume that
2070*16467b97STreehugger Robot     /// this token is missing and we keep going. Because we
2071*16467b97STreehugger Robot     /// have to return some token to replace the missing token,
2072*16467b97STreehugger Robot     /// we have to conjure one up. This method gives the user control
2073*16467b97STreehugger Robot     /// over the tokens returned for missing tokens. Mostly,
2074*16467b97STreehugger Robot     /// you will want to create something special for identifier
2075*16467b97STreehugger Robot     /// tokens. For literals such as '{' and ',', the default
2076*16467b97STreehugger Robot     /// action in the parser or tree parser works. It simply creates
2077*16467b97STreehugger Robot     /// a CommonToken of the appropriate type. The text will be the token.
2078*16467b97STreehugger Robot     /// If you change what tokens must be created by the lexer,
2079*16467b97STreehugger Robot     /// override this method to create the appropriate tokens.
2080*16467b97STreehugger Robot     /// </remarks>
GetMissingSymbol(const Input: IIntStream;2081*16467b97STreehugger Robot     function GetMissingSymbol(const Input: IIntStream;
2082*16467b97STreehugger Robot       const E: ERecognitionException; const ExpectedTokenType: Integer;
2083*16467b97STreehugger Robot       const Follow: IBitSet): IANTLRInterface; virtual;
2084*16467b97STreehugger Robot 
2085*16467b97STreehugger Robot     /// <summary>
2086*16467b97STreehugger Robot     /// Push a rule's follow set using our own hardcoded stack
2087*16467b97STreehugger Robot     /// </summary>
2088*16467b97STreehugger Robot     /// <param name="fset"></param>
2089*16467b97STreehugger Robot     procedure PushFollow(const FSet: IBitSet);
2090*16467b97STreehugger Robot 
2091*16467b97STreehugger Robot     /// <summary>Compute the context-sensitive FOLLOW set for current rule.
2092*16467b97STreehugger Robot     /// This is set of token types that can follow a specific rule
2093*16467b97STreehugger Robot     /// reference given a specific call chain.  You get the set of
2094*16467b97STreehugger Robot     /// viable tokens that can possibly come next (lookahead depth 1)
2095*16467b97STreehugger Robot     /// given the current call chain.  Contrast this with the
2096*16467b97STreehugger Robot     /// definition of plain FOLLOW for rule r:
2097*16467b97STreehugger Robot     ///
2098*16467b97STreehugger Robot     /// FOLLOW(r)={x | S=>*alpha r beta in G and x in FIRST(beta)}
2099*16467b97STreehugger Robot     ///
2100*16467b97STreehugger Robot     /// where x in T* and alpha, beta in V*; T is set of terminals and
2101*16467b97STreehugger Robot     /// V is the set of terminals and nonterminals.  In other words,
2102*16467b97STreehugger Robot     /// FOLLOW(r) is the set of all tokens that can possibly follow
2103*16467b97STreehugger Robot     /// references to r in *any* sentential form (context).  At
2104*16467b97STreehugger Robot     /// runtime, however, we know precisely which context applies as
2105*16467b97STreehugger Robot     /// we have the call chain.  We may compute the exact (rather
2106*16467b97STreehugger Robot     /// than covering superset) set of following tokens.
2107*16467b97STreehugger Robot     ///
2108*16467b97STreehugger Robot     /// For example, consider grammar:
2109*16467b97STreehugger Robot     ///
2110*16467b97STreehugger Robot     /// stat : ID '=' expr ';'      // FOLLOW(stat)=={EOF}
2111*16467b97STreehugger Robot     /// | "return" expr '.'
2112*16467b97STreehugger Robot     /// ;
2113*16467b97STreehugger Robot     /// expr : atom ('+' atom)* ;   // FOLLOW(expr)=={';','.',')'}
2114*16467b97STreehugger Robot     /// atom : INT                  // FOLLOW(atom)=={'+',')',';','.'}
2115*16467b97STreehugger Robot     /// | '(' expr ')'
2116*16467b97STreehugger Robot     /// ;
2117*16467b97STreehugger Robot     ///
2118*16467b97STreehugger Robot     /// The FOLLOW sets are all inclusive whereas context-sensitive
2119*16467b97STreehugger Robot     /// FOLLOW sets are precisely what could follow a rule reference.
2120*16467b97STreehugger Robot     /// For input input "i=(3);", here is the derivation:
2121*16467b97STreehugger Robot     ///
2122*16467b97STreehugger Robot     /// stat => ID '=' expr ';'
2123*16467b97STreehugger Robot     /// => ID '=' atom ('+' atom)* ';'
2124*16467b97STreehugger Robot     /// => ID '=' '(' expr ')' ('+' atom)* ';'
2125*16467b97STreehugger Robot     /// => ID '=' '(' atom ')' ('+' atom)* ';'
2126*16467b97STreehugger Robot     /// => ID '=' '(' INT ')' ('+' atom)* ';'
2127*16467b97STreehugger Robot     /// => ID '=' '(' INT ')' ';'
2128*16467b97STreehugger Robot     ///
2129*16467b97STreehugger Robot     /// At the "3" token, you'd have a call chain of
2130*16467b97STreehugger Robot     ///
2131*16467b97STreehugger Robot     /// stat -> expr -> atom -> expr -> atom
2132*16467b97STreehugger Robot     ///
2133*16467b97STreehugger Robot     /// What can follow that specific nested ref to atom?  Exactly ')'
2134*16467b97STreehugger Robot     /// as you can see by looking at the derivation of this specific
2135*16467b97STreehugger Robot     /// input.  Contrast this with the FOLLOW(atom)={'+',')',';','.'}.
2136*16467b97STreehugger Robot     ///
2137*16467b97STreehugger Robot     /// You want the exact viable token set when recovering from a
2138*16467b97STreehugger Robot     /// token mismatch.  Upon token mismatch, if LA(1) is member of
2139*16467b97STreehugger Robot     /// the viable next token set, then you know there is most likely
2140*16467b97STreehugger Robot     /// a missing token in the input stream.  "Insert" one by just not
2141*16467b97STreehugger Robot     /// throwing an exception.
2142*16467b97STreehugger Robot     /// </summary>
ComputeContextSensitiveRuleFOLLOW()2143*16467b97STreehugger Robot     function ComputeContextSensitiveRuleFOLLOW: IBitSet; virtual;
2144*16467b97STreehugger Robot 
2145*16467b97STreehugger Robot     (*  Compute the error recovery set for the current rule.  During
2146*16467b97STreehugger Robot     *  rule invocation, the parser pushes the set of tokens that can
2147*16467b97STreehugger Robot     *  follow that rule reference on the stack; this amounts to
2148*16467b97STreehugger Robot     *  computing FIRST of what follows the rule reference in the
2149*16467b97STreehugger Robot     *  enclosing rule. This local follow set only includes tokens
2150*16467b97STreehugger Robot     *  from within the rule; i.e., the FIRST computation done by
2151*16467b97STreehugger Robot     *  ANTLR stops at the end of a rule.
2152*16467b97STreehugger Robot     *
2153*16467b97STreehugger Robot     *  EXAMPLE
2154*16467b97STreehugger Robot     *
2155*16467b97STreehugger Robot     *  When you find a "no viable alt exception", the input is not
2156*16467b97STreehugger Robot     *  consistent with any of the alternatives for rule r.  The best
2157*16467b97STreehugger Robot     *  thing to do is to consume tokens until you see something that
2158*16467b97STreehugger Robot     *  can legally follow a call to r *or* any rule that called r.
2159*16467b97STreehugger Robot     *  You don't want the exact set of viable next tokens because the
2160*16467b97STreehugger Robot     *  input might just be missing a token--you might consume the
2161*16467b97STreehugger Robot     *  rest of the input looking for one of the missing tokens.
2162*16467b97STreehugger Robot     *
2163*16467b97STreehugger Robot     *  Consider grammar:
2164*16467b97STreehugger Robot     *
2165*16467b97STreehugger Robot     *  a : '[' b ']'
2166*16467b97STreehugger Robot     *    | '(' b ')'
2167*16467b97STreehugger Robot     *    ;
2168*16467b97STreehugger Robot     *  b : c '^' INT ;
2169*16467b97STreehugger Robot     *  c : ID
2170*16467b97STreehugger Robot     *    | INT
2171*16467b97STreehugger Robot     *    ;
2172*16467b97STreehugger Robot     *
2173*16467b97STreehugger Robot     *  At each rule invocation, the set of tokens that could follow
2174*16467b97STreehugger Robot     *  that rule is pushed on a stack.  Here are the various "local"
2175*16467b97STreehugger Robot     *  follow sets:
2176*16467b97STreehugger Robot     *
2177*16467b97STreehugger Robot     *  FOLLOW(b1_in_a) = FIRST(']') = ']'
2178*16467b97STreehugger Robot     *  FOLLOW(b2_in_a) = FIRST(')') = ')'
2179*16467b97STreehugger Robot     *  FOLLOW(c_in_b) = FIRST('^') = '^'
2180*16467b97STreehugger Robot     *
2181*16467b97STreehugger Robot     *  Upon erroneous input "[]", the call chain is
2182*16467b97STreehugger Robot     *
2183*16467b97STreehugger Robot     *  a -> b -> c
2184*16467b97STreehugger Robot     *
2185*16467b97STreehugger Robot     *  and, hence, the follow context stack is:
2186*16467b97STreehugger Robot     *
2187*16467b97STreehugger Robot     *  depth  local follow set     after call to rule
2188*16467b97STreehugger Robot     *    0         <EOF>                    a (from main())
2189*16467b97STreehugger Robot     *    1          ']'                     b
2190*16467b97STreehugger Robot     *    3          '^'                     c
2191*16467b97STreehugger Robot     *
2192*16467b97STreehugger Robot     *  Notice that ')' is not included, because b would have to have
2193*16467b97STreehugger Robot     *  been called from a different context in rule a for ')' to be
2194*16467b97STreehugger Robot     *  included.
2195*16467b97STreehugger Robot     *
2196*16467b97STreehugger Robot     *  For error recovery, we cannot consider FOLLOW(c)
2197*16467b97STreehugger Robot     *  (context-sensitive or otherwise).  We need the combined set of
2198*16467b97STreehugger Robot     *  all context-sensitive FOLLOW sets--the set of all tokens that
2199*16467b97STreehugger Robot     *  could follow any reference in the call chain.  We need to
2200*16467b97STreehugger Robot     *  resync to one of those tokens.  Note that FOLLOW(c)='^' and if
2201*16467b97STreehugger Robot     *  we resync'd to that token, we'd consume until EOF.  We need to
2202*16467b97STreehugger Robot     *  sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.
2203*16467b97STreehugger Robot     *  In this case, for input "[]", LA(1) is in this set so we would
2204*16467b97STreehugger Robot     *  not consume anything and after printing an error rule c would
2205*16467b97STreehugger Robot     *  return normally.  It would not find the required '^' though.
2206*16467b97STreehugger Robot     *  At this point, it gets a mismatched token error and throws an
2207*16467b97STreehugger Robot     *  exception (since LA(1) is not in the viable following token
2208*16467b97STreehugger Robot     *  set).  The rule exception handler tries to Recover, but finds
2209*16467b97STreehugger Robot     *  the same recovery set and doesn't consume anything.  Rule b
2210*16467b97STreehugger Robot     *  exits normally returning to rule a.  Now it finds the ']' (and
2211*16467b97STreehugger Robot     *  with the successful Match exits errorRecovery mode).
2212*16467b97STreehugger Robot     *
2213*16467b97STreehugger Robot     *  So, you cna see that the parser walks up call chain looking
2214*16467b97STreehugger Robot     *  for the token that was a member of the recovery set.
2215*16467b97STreehugger Robot     *
2216*16467b97STreehugger Robot     *  Errors are not generated in errorRecovery mode.
2217*16467b97STreehugger Robot     *
2218*16467b97STreehugger Robot     *  ANTLR's error recovery mechanism is based upon original ideas:
2219*16467b97STreehugger Robot     *
2220*16467b97STreehugger Robot     *  "Algorithms + Data Structures = Programs" by Niklaus Wirth
2221*16467b97STreehugger Robot     *
2222*16467b97STreehugger Robot     *  and
2223*16467b97STreehugger Robot     *
2224*16467b97STreehugger Robot     *  "A note on error recovery in recursive descent parsers":
2225*16467b97STreehugger Robot     *  http://portal.acm.org/citation.cfm?id=947902.947905
2226*16467b97STreehugger Robot     *
2227*16467b97STreehugger Robot     *  Later, Josef Grosch had some good ideas:
2228*16467b97STreehugger Robot     *
2229*16467b97STreehugger Robot     *  "Efficient and Comfortable Error Recovery in Recursive Descent
2230*16467b97STreehugger Robot     *  Parsers":
2231*16467b97STreehugger Robot     *  ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip
2232*16467b97STreehugger Robot     *
2233*16467b97STreehugger Robot     *  Like Grosch I implemented local FOLLOW sets that are combined
2234*16467b97STreehugger Robot     *  at run-time upon error to avoid overhead during parsing.
2235*16467b97STreehugger Robot     *)
ComputeErrorRecoverySet()2236*16467b97STreehugger Robot     function ComputeErrorRecoverySet: IBitSet; virtual;
2237*16467b97STreehugger Robot 
CombineFollows(const Exact: Boolean)2238*16467b97STreehugger Robot     function CombineFollows(const Exact: Boolean): IBitSet;
2239*16467b97STreehugger Robot   protected
2240*16467b97STreehugger Robot     { IBaseRecognizer }
GetInput()2241*16467b97STreehugger Robot     function GetInput: IIntStream; virtual; abstract;
GetBacktrackingLevel()2242*16467b97STreehugger Robot     function GetBacktrackingLevel: Integer;
GetState()2243*16467b97STreehugger Robot     function GetState: IRecognizerSharedState;
GetNumberOfSyntaxErrors()2244*16467b97STreehugger Robot     function GetNumberOfSyntaxErrors: Integer;
GetGrammarFileName()2245*16467b97STreehugger Robot     function GetGrammarFileName: String; virtual;
GetSourceName()2246*16467b97STreehugger Robot     function GetSourceName: String; virtual; abstract;
GetTokenNames()2247*16467b97STreehugger Robot     function GetTokenNames: TStringArray; virtual;
2248*16467b97STreehugger Robot 
2249*16467b97STreehugger Robot     procedure BeginBacktrack(const Level: Integer); virtual;
2250*16467b97STreehugger Robot     procedure EndBacktrack(const Level: Integer; const Successful: Boolean); virtual;
2251*16467b97STreehugger Robot     procedure Reset; virtual;
Match(const Input: IIntStream; const TokenType: Integer;2252*16467b97STreehugger Robot     function Match(const Input: IIntStream; const TokenType: Integer;
2253*16467b97STreehugger Robot       const Follow: IBitSet): IANTLRInterface; virtual;
MismatchIsUnwantedToken(const Input: IIntStream;2254*16467b97STreehugger Robot     function MismatchIsUnwantedToken(const Input: IIntStream;
2255*16467b97STreehugger Robot       const TokenType: Integer): Boolean;
MismatchIsMissingToken(const Input: IIntStream;2256*16467b97STreehugger Robot     function MismatchIsMissingToken(const Input: IIntStream;
2257*16467b97STreehugger Robot       const Follow: IBitSet): Boolean;
2258*16467b97STreehugger Robot     procedure BeginResync; virtual;
2259*16467b97STreehugger Robot     procedure EndResync; virtual;
2260*16467b97STreehugger Robot     procedure ReportError(const E: ERecognitionException); virtual;
2261*16467b97STreehugger Robot     procedure MatchAny(const Input: IIntStream); virtual;
2262*16467b97STreehugger Robot     procedure DisplayRecognitionError(const TokenNames: TStringArray;
2263*16467b97STreehugger Robot       const E: ERecognitionException); virtual;
GetErrorMessage(const E: ERecognitionException;2264*16467b97STreehugger Robot     function GetErrorMessage(const E: ERecognitionException;
2265*16467b97STreehugger Robot       const TokenNames: TStringArray): String; virtual;
GetErrorHeader(const E: ERecognitionException)2266*16467b97STreehugger Robot     function GetErrorHeader(const E: ERecognitionException): String; virtual;
GetTokenErrorDisplay(const T: IToken)2267*16467b97STreehugger Robot     function GetTokenErrorDisplay(const T: IToken): String; virtual;
2268*16467b97STreehugger Robot     procedure EmitErrorMessage(const Msg: String); virtual;
2269*16467b97STreehugger Robot     procedure Recover(const Input: IIntStream; const RE: ERecognitionException); virtual;
RecoverFromMismatchedSet(const Input: IIntStream;2270*16467b97STreehugger Robot     function RecoverFromMismatchedSet(const Input: IIntStream;
2271*16467b97STreehugger Robot       const E: ERecognitionException; const Follow: IBitSet): IANTLRInterface; virtual;
2272*16467b97STreehugger Robot     procedure ConsumeUntil(const Input: IIntStream; const TokenType: Integer); overload; virtual;
2273*16467b97STreehugger Robot     procedure ConsumeUntil(const Input: IIntStream; const BitSet: IBitSet); overload; virtual;
2274*16467b97STreehugger Robot     //function GetRuleInvocationStack: IList<IANTLRInterface>; overload; virtual;
2275*16467b97STreehugger Robot     //function GetRuleInvocationStack(const E: Exception;
2276*16467b97STreehugger Robot     //  const RecognizerClassName: String): IList<IANTLRInterface>; overload;
ToStrings(const Tokens: IList<IToken>)2277*16467b97STreehugger Robot     function ToStrings(const Tokens: IList<IToken>): IList<String>; virtual;
GetRuleMemoization(const RuleIndex, RuleStartIndex: Integer)2278*16467b97STreehugger Robot     function GetRuleMemoization(const RuleIndex, RuleStartIndex: Integer): Integer; virtual;
AlreadyParsedRule(const Input: IIntStream;2279*16467b97STreehugger Robot     function AlreadyParsedRule(const Input: IIntStream;
2280*16467b97STreehugger Robot       const RuleIndex: Integer): Boolean; virtual;
2281*16467b97STreehugger Robot     procedure Memoize(const Input: IIntStream; const RuleIndex,
2282*16467b97STreehugger Robot       RuleStartIndex: Integer); virtual;
GetRuleMemoizationChaceSize()2283*16467b97STreehugger Robot     function GetRuleMemoizationChaceSize: Integer;
2284*16467b97STreehugger Robot 
2285*16467b97STreehugger Robot     procedure TraceIn(const RuleName: String; const RuleIndex: Integer;
2286*16467b97STreehugger Robot       const InputSymbol: String); virtual;
2287*16467b97STreehugger Robot     procedure TraceOut(const RuleName: String; const RuleIndex: Integer;
2288*16467b97STreehugger Robot       const InputSymbol: String); virtual;
2289*16467b97STreehugger Robot 
2290*16467b97STreehugger Robot     property Input: IIntStream read GetInput;
2291*16467b97STreehugger Robot   public
2292*16467b97STreehugger Robot     constructor Create; overload;
2293*16467b97STreehugger Robot     constructor Create(const AState: IRecognizerSharedState); overload;
2294*16467b97STreehugger Robot   end;
2295*16467b97STreehugger Robot 
2296*16467b97STreehugger Robot   TCommonTokenStream = class(TANTLRObject, ICommonTokenStream, ITokenStream)
2297*16467b97STreehugger Robot   strict private
2298*16467b97STreehugger Robot     FTokenSource: ITokenSource;
2299*16467b97STreehugger Robot 
2300*16467b97STreehugger Robot     /// <summary>Record every single token pulled from the source so we can reproduce
2301*16467b97STreehugger Robot     /// chunks of it later.
2302*16467b97STreehugger Robot     /// </summary>
2303*16467b97STreehugger Robot     FTokens: IList<IToken>;
2304*16467b97STreehugger Robot 
2305*16467b97STreehugger Robot     /// <summary><![CDATA[Map<tokentype, channel>]]> to override some Tokens' channel numbers </summary>
2306*16467b97STreehugger Robot     FChannelOverrideMap: IDictionary<Integer, Integer>;
2307*16467b97STreehugger Robot 
2308*16467b97STreehugger Robot     /// <summary><![CDATA[Set<tokentype>;]]> discard any tokens with this type </summary>
2309*16467b97STreehugger Robot     FDiscardSet: IHashList<Integer, Integer>;
2310*16467b97STreehugger Robot 
2311*16467b97STreehugger Robot     /// <summary>Skip tokens on any channel but this one; this is how we skip whitespace... </summary>
2312*16467b97STreehugger Robot     FChannel: Integer;
2313*16467b97STreehugger Robot 
2314*16467b97STreehugger Robot     /// <summary>By default, track all incoming tokens </summary>
2315*16467b97STreehugger Robot     FDiscardOffChannelTokens: Boolean;
2316*16467b97STreehugger Robot 
2317*16467b97STreehugger Robot     /// <summary>Track the last Mark() call result value for use in Rewind().</summary>
2318*16467b97STreehugger Robot     FLastMarker: Integer;
2319*16467b97STreehugger Robot 
2320*16467b97STreehugger Robot     /// <summary>
2321*16467b97STreehugger Robot     /// The index into the tokens list of the current token (next token
2322*16467b97STreehugger Robot     /// to consume).  p==-1 indicates that the tokens list is empty
2323*16467b97STreehugger Robot     /// </summary>
2324*16467b97STreehugger Robot     FP: Integer;
2325*16467b97STreehugger Robot   strict protected
2326*16467b97STreehugger Robot     /// <summary>Load all tokens from the token source and put in tokens.
2327*16467b97STreehugger Robot     /// This is done upon first LT request because you might want to
2328*16467b97STreehugger Robot     /// set some token type / channel overrides before filling buffer.
2329*16467b97STreehugger Robot     /// </summary>
2330*16467b97STreehugger Robot     procedure FillBuffer; virtual;
2331*16467b97STreehugger Robot 
2332*16467b97STreehugger Robot     /// <summary>Look backwards k tokens on-channel tokens </summary>
LB(const K: Integer)2333*16467b97STreehugger Robot     function LB(const K: Integer): IToken; virtual;
2334*16467b97STreehugger Robot 
2335*16467b97STreehugger Robot     /// <summary>Given a starting index, return the index of the first on-channel
2336*16467b97STreehugger Robot     /// token.
2337*16467b97STreehugger Robot     /// </summary>
SkipOffTokenChannels(const I: Integer)2338*16467b97STreehugger Robot     function SkipOffTokenChannels(const I: Integer): Integer; virtual;
SkipOffTokenChannelsReverse(const I: Integer)2339*16467b97STreehugger Robot     function SkipOffTokenChannelsReverse(const I: Integer): Integer; virtual;
2340*16467b97STreehugger Robot   protected
2341*16467b97STreehugger Robot     { IIntStream }
GetSourceName()2342*16467b97STreehugger Robot     function GetSourceName: String; virtual;
2343*16467b97STreehugger Robot 
2344*16467b97STreehugger Robot     procedure Consume; virtual;
LA(I: Integer)2345*16467b97STreehugger Robot     function LA(I: Integer): Integer; virtual;
LAChar(I: Integer)2346*16467b97STreehugger Robot     function LAChar(I: Integer): Char;
Mark()2347*16467b97STreehugger Robot     function Mark: Integer; virtual;
Index()2348*16467b97STreehugger Robot     function Index: Integer; virtual;
2349*16467b97STreehugger Robot     procedure Rewind(const Marker: Integer); overload; virtual;
2350*16467b97STreehugger Robot     procedure Rewind; overload; virtual;
2351*16467b97STreehugger Robot     procedure Release(const Marker: Integer); virtual;
2352*16467b97STreehugger Robot     procedure Seek(const Index: Integer); virtual;
Size()2353*16467b97STreehugger Robot     function Size: Integer; virtual;
2354*16467b97STreehugger Robot   protected
2355*16467b97STreehugger Robot     { ITokenStream }
GetTokenSource()2356*16467b97STreehugger Robot     function GetTokenSource: ITokenSource; virtual;
2357*16467b97STreehugger Robot     procedure SetTokenSource(const Value: ITokenSource); virtual;
2358*16467b97STreehugger Robot 
LT(const K: Integer)2359*16467b97STreehugger Robot     function LT(const K: Integer): IToken; virtual;
Get(const I: Integer)2360*16467b97STreehugger Robot     function Get(const I: Integer): IToken; virtual;
ToString(const Start, Stop: Integer)2361*16467b97STreehugger Robot     function ToString(const Start, Stop: Integer): String; reintroduce; overload; virtual;
ToString(const Start, Stop: IToken)2362*16467b97STreehugger Robot     function ToString(const Start, Stop: IToken): String; reintroduce; overload; virtual;
2363*16467b97STreehugger Robot   protected
2364*16467b97STreehugger Robot     { ICommonTokenStream }
2365*16467b97STreehugger Robot     procedure SetTokenTypeChannel(const TType, Channel: Integer);
2366*16467b97STreehugger Robot     procedure DiscardTokenType(const TType: Integer);
2367*16467b97STreehugger Robot     procedure DiscardOffChannelTokens(const Discard: Boolean);
GetTokens()2368*16467b97STreehugger Robot     function GetTokens: IList<IToken>; overload;
GetTokens(const Start, Stop: Integer)2369*16467b97STreehugger Robot     function GetTokens(const Start, Stop: Integer): IList<IToken>; overload;
GetTokens(const Start, Stop: Integer;2370*16467b97STreehugger Robot     function GetTokens(const Start, Stop: Integer;
2371*16467b97STreehugger Robot       const Types: IBitSet): IList<IToken>; overload;
GetTokens(const Start, Stop: Integer;2372*16467b97STreehugger Robot     function GetTokens(const Start, Stop: Integer;
2373*16467b97STreehugger Robot       const Types: IList<Integer>): IList<IToken>; overload;
GetTokens(const Start, Stop,2374*16467b97STreehugger Robot     function GetTokens(const Start, Stop,
2375*16467b97STreehugger Robot       TokenType: Integer): IList<IToken>; overload;
2376*16467b97STreehugger Robot     procedure Reset; virtual;
2377*16467b97STreehugger Robot   public
2378*16467b97STreehugger Robot     constructor Create; overload;
2379*16467b97STreehugger Robot     constructor Create(const ATokenSource: ITokenSource); overload;
2380*16467b97STreehugger Robot     constructor Create(const ATokenSource: ITokenSource;
2381*16467b97STreehugger Robot       const AChannel: Integer); overload;
2382*16467b97STreehugger Robot     constructor Create(const ALexer: ILexer); overload;
2383*16467b97STreehugger Robot     constructor Create(const ALexer: ILexer;
2384*16467b97STreehugger Robot       const AChannel: Integer); overload;
2385*16467b97STreehugger Robot 
ToString()2386*16467b97STreehugger Robot     function ToString: String; overload; override;
2387*16467b97STreehugger Robot   end;
2388*16467b97STreehugger Robot 
2389*16467b97STreehugger Robot   TDFA = class abstract(TANTLRObject, IDFA)
2390*16467b97STreehugger Robot   strict private
2391*16467b97STreehugger Robot     FSpecialStateTransitionHandler: TSpecialStateTransitionHandler;
2392*16467b97STreehugger Robot     FEOT: TSmallintArray;
2393*16467b97STreehugger Robot     FEOF: TSmallintArray;
2394*16467b97STreehugger Robot     FMin: TCharArray;
2395*16467b97STreehugger Robot     FMax: TCharArray;
2396*16467b97STreehugger Robot     FAccept: TSmallintArray;
2397*16467b97STreehugger Robot     FSpecial: TSmallintArray;
2398*16467b97STreehugger Robot     FTransition: TSmallintMatrix;
2399*16467b97STreehugger Robot     FDecisionNumber: Integer;
2400*16467b97STreehugger Robot     FRecognizer: Pointer; { IBaseRecognizer }
GetRecognizer()2401*16467b97STreehugger Robot     function GetRecognizer: IBaseRecognizer;
2402*16467b97STreehugger Robot     procedure SetRecognizer(const Value: IBaseRecognizer);
2403*16467b97STreehugger Robot   strict protected
2404*16467b97STreehugger Robot     procedure NoViableAlt(const S: Integer; const Input: IIntStream);
2405*16467b97STreehugger Robot 
2406*16467b97STreehugger Robot     property Recognizer: IBaseRecognizer read GetRecognizer write SetRecognizer;
2407*16467b97STreehugger Robot     property DecisionNumber: Integer read FDecisionNumber write FDecisionNumber;
2408*16467b97STreehugger Robot     property EOT: TSmallintArray read FEOT write FEOT;
2409*16467b97STreehugger Robot     property EOF: TSmallintArray read FEOF write FEOF;
2410*16467b97STreehugger Robot     property Min: TCharArray read FMin write FMin;
2411*16467b97STreehugger Robot     property Max: TCharArray read FMax write FMax;
2412*16467b97STreehugger Robot     property Accept: TSmallintArray read FAccept write FAccept;
2413*16467b97STreehugger Robot     property Special: TSmallintArray read FSpecial write FSpecial;
2414*16467b97STreehugger Robot     property Transition: TSmallintMatrix read FTransition write FTransition;
2415*16467b97STreehugger Robot   protected
2416*16467b97STreehugger Robot     { IDFA }
GetSpecialStateTransitionHandler()2417*16467b97STreehugger Robot     function GetSpecialStateTransitionHandler: TSpecialStateTransitionHandler;
2418*16467b97STreehugger Robot     procedure SetSpecialStateTransitionHandler(const Value: TSpecialStateTransitionHandler);
2419*16467b97STreehugger Robot 
Predict(const Input: IIntStream)2420*16467b97STreehugger Robot     function Predict(const Input: IIntStream): Integer;
2421*16467b97STreehugger Robot     procedure Error(const NVAE: ENoViableAltException); virtual;
SpecialStateTransition(const S: Integer;2422*16467b97STreehugger Robot     function SpecialStateTransition(const S: Integer;
2423*16467b97STreehugger Robot       const Input: IIntStream): Integer; virtual;
Description()2424*16467b97STreehugger Robot     function Description: String; virtual;
SpecialTransition(const State, Symbol: Integer)2425*16467b97STreehugger Robot     function SpecialTransition(const State, Symbol: Integer): Integer;
2426*16467b97STreehugger Robot   public
UnpackEncodedString(const EncodedString: String)2427*16467b97STreehugger Robot     class function UnpackEncodedString(const EncodedString: String): TSmallintArray; static;
UnpackEncodedStringArray(const EncodedStrings: TStringArray)2428*16467b97STreehugger Robot     class function UnpackEncodedStringArray(const EncodedStrings: TStringArray): TSmallintMatrix; overload; static;
UnpackEncodedStringArray(const EncodedStrings: array of String)2429*16467b97STreehugger Robot     class function UnpackEncodedStringArray(const EncodedStrings: array of String): TSmallintMatrix; overload; static;
UnpackEncodedStringToUnsignedChars(const EncodedString: String)2430*16467b97STreehugger Robot     class function UnpackEncodedStringToUnsignedChars(const EncodedString: String): TCharArray; static;
2431*16467b97STreehugger Robot   end;
2432*16467b97STreehugger Robot 
2433*16467b97STreehugger Robot   TLexer = class abstract(TBaseRecognizer, ILexer, ITokenSource)
2434*16467b97STreehugger Robot   strict private
2435*16467b97STreehugger Robot     const
2436*16467b97STreehugger Robot       TOKEN_dot_EOF = Ord(cscEOF);
2437*16467b97STreehugger Robot   strict private
2438*16467b97STreehugger Robot     /// <summary>Where is the lexer drawing characters from? </summary>
2439*16467b97STreehugger Robot     FInput: ICharStream;
2440*16467b97STreehugger Robot   protected
2441*16467b97STreehugger Robot     { IBaseRecognizer }
GetSourceName()2442*16467b97STreehugger Robot     function GetSourceName: String; override;
GetInput()2443*16467b97STreehugger Robot     function GetInput: IIntStream; override;
2444*16467b97STreehugger Robot     procedure Reset; override;
2445*16467b97STreehugger Robot     procedure ReportError(const E: ERecognitionException); override;
GetErrorMessage(const E: ERecognitionException;2446*16467b97STreehugger Robot     function GetErrorMessage(const E: ERecognitionException;
2447*16467b97STreehugger Robot       const TokenNames: TStringArray): String; override;
2448*16467b97STreehugger Robot   protected
2449*16467b97STreehugger Robot     { ILexer }
GetCharStream()2450*16467b97STreehugger Robot     function GetCharStream: ICharStream; virtual;
2451*16467b97STreehugger Robot     procedure SetCharStream(const Value: ICharStream); virtual;
GetLine()2452*16467b97STreehugger Robot     function GetLine: Integer; virtual;
GetCharPositionInLine()2453*16467b97STreehugger Robot     function GetCharPositionInLine: Integer; virtual;
GetCharIndex()2454*16467b97STreehugger Robot     function GetCharIndex: Integer; virtual;
GetText()2455*16467b97STreehugger Robot     function GetText: String; virtual;
2456*16467b97STreehugger Robot     procedure SetText(const Value: String); virtual;
2457*16467b97STreehugger Robot 
NextToken()2458*16467b97STreehugger Robot     function NextToken: IToken; virtual;
2459*16467b97STreehugger Robot     procedure Skip;
2460*16467b97STreehugger Robot     procedure DoTokens; virtual; abstract;
2461*16467b97STreehugger Robot     procedure Emit(const Token: IToken); overload; virtual;
Emit()2462*16467b97STreehugger Robot     function Emit: IToken; overload; virtual;
2463*16467b97STreehugger Robot     procedure Match(const S: String); reintroduce; overload; virtual;
2464*16467b97STreehugger Robot     procedure Match(const C: Integer); reintroduce; overload; virtual;
2465*16467b97STreehugger Robot     procedure MatchAny; reintroduce; overload; virtual;
2466*16467b97STreehugger Robot     procedure MatchRange(const A, B: Integer); virtual;
2467*16467b97STreehugger Robot     procedure Recover(const RE: ERecognitionException); reintroduce; overload; virtual;
GetCharErrorDisplay(const C: Integer)2468*16467b97STreehugger Robot     function GetCharErrorDisplay(const C: Integer): String;
2469*16467b97STreehugger Robot     procedure TraceIn(const RuleName: String; const RuleIndex: Integer); reintroduce; overload; virtual;
2470*16467b97STreehugger Robot     procedure TraceOut(const RuleName: String; const RuleIndex: Integer); reintroduce; overload; virtual;
2471*16467b97STreehugger Robot   strict protected
2472*16467b97STreehugger Robot     property Input: ICharStream read FInput;
2473*16467b97STreehugger Robot     property CharIndex: Integer read GetCharIndex;
2474*16467b97STreehugger Robot     property Text: String read GetText write SetText;
2475*16467b97STreehugger Robot   public
2476*16467b97STreehugger Robot     constructor Create; overload;
2477*16467b97STreehugger Robot     constructor Create(const AInput: ICharStream); overload;
2478*16467b97STreehugger Robot     constructor Create(const AInput: ICharStream;
2479*16467b97STreehugger Robot       const AState: IRecognizerSharedState); overload;
2480*16467b97STreehugger Robot   end;
2481*16467b97STreehugger Robot 
2482*16467b97STreehugger Robot   TParser = class(TBaseRecognizer, IParser)
2483*16467b97STreehugger Robot   strict private
2484*16467b97STreehugger Robot     FInput: ITokenStream;
2485*16467b97STreehugger Robot   protected
2486*16467b97STreehugger Robot     property Input: ITokenStream read FInput;
2487*16467b97STreehugger Robot   protected
2488*16467b97STreehugger Robot     { IBaseRecognizer }
2489*16467b97STreehugger Robot     procedure Reset; override;
GetCurrentInputSymbol(const Input: IIntStream)2490*16467b97STreehugger Robot     function GetCurrentInputSymbol(const Input: IIntStream): IANTLRInterface; override;
GetMissingSymbol(const Input: IIntStream;2491*16467b97STreehugger Robot     function GetMissingSymbol(const Input: IIntStream;
2492*16467b97STreehugger Robot       const E: ERecognitionException; const ExpectedTokenType: Integer;
2493*16467b97STreehugger Robot       const Follow: IBitSet): IANTLRInterface; override;
GetSourceName()2494*16467b97STreehugger Robot     function GetSourceName: String; override;
GetInput()2495*16467b97STreehugger Robot     function GetInput: IIntStream; override;
2496*16467b97STreehugger Robot   protected
2497*16467b97STreehugger Robot     { IParser }
GetTokenStream()2498*16467b97STreehugger Robot     function GetTokenStream: ITokenStream; virtual;
2499*16467b97STreehugger Robot     procedure SetTokenStream(const Value: ITokenStream); virtual;
2500*16467b97STreehugger Robot 
2501*16467b97STreehugger Robot     procedure TraceIn(const RuleName: String; const RuleIndex: Integer); reintroduce; overload;
2502*16467b97STreehugger Robot     procedure TraceOut(const RuleName: String; const RuleIndex: Integer); reintroduce; overload;
2503*16467b97STreehugger Robot   public
2504*16467b97STreehugger Robot     constructor Create(const AInput: ITokenStream); overload;
2505*16467b97STreehugger Robot     constructor Create(const AInput: ITokenStream;
2506*16467b97STreehugger Robot       const AState: IRecognizerSharedState); overload;
2507*16467b97STreehugger Robot   end;
2508*16467b97STreehugger Robot 
2509*16467b97STreehugger Robot   TRuleReturnScope = class(TANTLRObject, IRuleReturnScope)
2510*16467b97STreehugger Robot   protected
2511*16467b97STreehugger Robot     { IRuleReturnScope }
GetStart()2512*16467b97STreehugger Robot     function GetStart: IANTLRInterface; virtual;
2513*16467b97STreehugger Robot     procedure SetStart(const Value: IANTLRInterface); virtual;
GetStop()2514*16467b97STreehugger Robot     function GetStop: IANTLRInterface; virtual;
2515*16467b97STreehugger Robot     procedure SetStop(const Value: IANTLRInterface); virtual;
GetTree()2516*16467b97STreehugger Robot     function GetTree: IANTLRInterface; virtual;
2517*16467b97STreehugger Robot     procedure SetTree(const Value: IANTLRInterface); virtual;
GetTemplate()2518*16467b97STreehugger Robot     function GetTemplate: IANTLRInterface; virtual;
2519*16467b97STreehugger Robot   end;
2520*16467b97STreehugger Robot 
2521*16467b97STreehugger Robot   TParserRuleReturnScope = class(TRuleReturnScope, IParserRuleReturnScope)
2522*16467b97STreehugger Robot   strict private
2523*16467b97STreehugger Robot     FStart: IToken;
2524*16467b97STreehugger Robot     FStop: IToken;
2525*16467b97STreehugger Robot   protected
2526*16467b97STreehugger Robot     { IRuleReturnScope }
GetStart()2527*16467b97STreehugger Robot     function GetStart: IANTLRInterface; override;
2528*16467b97STreehugger Robot     procedure SetStart(const Value: IANTLRInterface); override;
GetStop()2529*16467b97STreehugger Robot     function GetStop: IANTLRInterface; override;
2530*16467b97STreehugger Robot     procedure SetStop(const Value: IANTLRInterface); override;
2531*16467b97STreehugger Robot   end;
2532*16467b97STreehugger Robot 
2533*16467b97STreehugger Robot   TTokenRewriteStream = class(TCommonTokenStream, ITokenRewriteStream)
2534*16467b97STreehugger Robot   public
2535*16467b97STreehugger Robot     const
2536*16467b97STreehugger Robot       DEFAULT_PROGRAM_NAME = 'default';
2537*16467b97STreehugger Robot       PROGRAM_INIT_SIZE = 100;
2538*16467b97STreehugger Robot       MIN_TOKEN_INDEX = 0;
2539*16467b97STreehugger Robot   strict protected
2540*16467b97STreehugger Robot     // Define the rewrite operation hierarchy
2541*16467b97STreehugger Robot     type
2542*16467b97STreehugger Robot       IRewriteOperation = interface(IANTLRInterface)
2543*16467b97STreehugger Robot       ['{285A54ED-58FF-44B1-A268-2686476D4419}']
2544*16467b97STreehugger Robot         { Property accessors }
GetInstructionIndex()2545*16467b97STreehugger Robot         function GetInstructionIndex: Integer;
2546*16467b97STreehugger Robot         procedure SetInstructionIndex(const Value: Integer);
GetIndex()2547*16467b97STreehugger Robot         function GetIndex: Integer;
2548*16467b97STreehugger Robot         procedure SetIndex(const Value: Integer);
GetText()2549*16467b97STreehugger Robot         function GetText: IANTLRInterface;
2550*16467b97STreehugger Robot         procedure SetText(const Value: IANTLRInterface);
GetParent()2551*16467b97STreehugger Robot         function GetParent: ITokenRewriteStream;
2552*16467b97STreehugger Robot         procedure SetParent(const Value: ITokenRewriteStream);
2553*16467b97STreehugger Robot 
2554*16467b97STreehugger Robot         { Methods }
2555*16467b97STreehugger Robot 
2556*16467b97STreehugger Robot         /// <summary>Execute the rewrite operation by possibly adding to the buffer.
2557*16467b97STreehugger Robot         /// Return the index of the next token to operate on.
2558*16467b97STreehugger Robot         /// </summary>
Execute(const Buf: TStringBuilder)2559*16467b97STreehugger Robot         function Execute(const Buf: TStringBuilder): Integer;
2560*16467b97STreehugger Robot 
2561*16467b97STreehugger Robot         { Properties }
2562*16467b97STreehugger Robot         property InstructionIndex: Integer read GetInstructionIndex write SetInstructionIndex;
2563*16467b97STreehugger Robot         property Index: Integer read GetIndex write SetIndex;
2564*16467b97STreehugger Robot         property Text: IANTLRInterface read GetText write SetText;
2565*16467b97STreehugger Robot         property Parent: ITokenRewriteStream read GetParent write SetParent;
2566*16467b97STreehugger Robot       end;
2567*16467b97STreehugger Robot 
2568*16467b97STreehugger Robot       TRewriteOperation = class(TANTLRObject, IRewriteOperation)
2569*16467b97STreehugger Robot       strict private
2570*16467b97STreehugger Robot         // What index into rewrites List are we?
2571*16467b97STreehugger Robot         FInstructionIndex: Integer;
2572*16467b97STreehugger Robot         // Token buffer index
2573*16467b97STreehugger Robot         FIndex: Integer;
2574*16467b97STreehugger Robot         FText: IANTLRInterface;
2575*16467b97STreehugger Robot         FParent: Pointer; {ITokenRewriteStream;}
2576*16467b97STreehugger Robot       protected
2577*16467b97STreehugger Robot         { IRewriteOperation }
GetInstructionIndex()2578*16467b97STreehugger Robot         function GetInstructionIndex: Integer;
2579*16467b97STreehugger Robot         procedure SetInstructionIndex(const Value: Integer);
GetIndex()2580*16467b97STreehugger Robot         function GetIndex: Integer;
2581*16467b97STreehugger Robot         procedure SetIndex(const Value: Integer);
GetText()2582*16467b97STreehugger Robot         function GetText: IANTLRInterface;
2583*16467b97STreehugger Robot         procedure SetText(const Value: IANTLRInterface);
GetParent()2584*16467b97STreehugger Robot         function GetParent: ITokenRewriteStream;
2585*16467b97STreehugger Robot         procedure SetParent(const Value: ITokenRewriteStream);
2586*16467b97STreehugger Robot 
Execute(const Buf: TStringBuilder)2587*16467b97STreehugger Robot         function Execute(const Buf: TStringBuilder): Integer; virtual;
2588*16467b97STreehugger Robot       protected
2589*16467b97STreehugger Robot         constructor Create(const AIndex: Integer; const AText: IANTLRInterface;
2590*16467b97STreehugger Robot           const AParent: ITokenRewriteStream);
2591*16467b97STreehugger Robot 
2592*16467b97STreehugger Robot         property Index: Integer read FIndex write FIndex;
2593*16467b97STreehugger Robot         property Text: IANTLRInterface read FText write FText;
2594*16467b97STreehugger Robot         property Parent: ITokenRewriteStream read GetParent write SetParent;
2595*16467b97STreehugger Robot       public
ToString()2596*16467b97STreehugger Robot         function ToString: String; override;
2597*16467b97STreehugger Robot       end;
2598*16467b97STreehugger Robot 
2599*16467b97STreehugger Robot       IInsertBeforeOp = interface(IRewriteOperation)
2600*16467b97STreehugger Robot       ['{BFB732E2-BE6A-4691-AE3B-5C8013DE924E}']
2601*16467b97STreehugger Robot       end;
2602*16467b97STreehugger Robot 
2603*16467b97STreehugger Robot       TInsertBeforeOp = class(TRewriteOperation, IInsertBeforeOp)
2604*16467b97STreehugger Robot       protected
2605*16467b97STreehugger Robot         { IRewriteOperation }
Execute(const Buf: TStringBuilder)2606*16467b97STreehugger Robot         function Execute(const Buf: TStringBuilder): Integer; override;
2607*16467b97STreehugger Robot       end;
2608*16467b97STreehugger Robot 
2609*16467b97STreehugger Robot       /// <summary>I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp
2610*16467b97STreehugger Robot       /// instructions.
2611*16467b97STreehugger Robot       /// </summary>
2612*16467b97STreehugger Robot       IReplaceOp = interface(IRewriteOperation)
2613*16467b97STreehugger Robot       ['{630C434A-99EA-4589-A65D-64A7B3DAC407}']
2614*16467b97STreehugger Robot         { Property accessors }
GetLastIndex()2615*16467b97STreehugger Robot         function GetLastIndex: Integer;
2616*16467b97STreehugger Robot         procedure SetLastIndex(const Value: Integer);
2617*16467b97STreehugger Robot 
2618*16467b97STreehugger Robot         { Properties }
2619*16467b97STreehugger Robot         property LastIndex: Integer read GetLastIndex write SetLastIndex;
2620*16467b97STreehugger Robot       end;
2621*16467b97STreehugger Robot 
2622*16467b97STreehugger Robot       TReplaceOp = class(TRewriteOperation, IReplaceOp)
2623*16467b97STreehugger Robot       private
2624*16467b97STreehugger Robot         FLastIndex: Integer;
2625*16467b97STreehugger Robot       protected
2626*16467b97STreehugger Robot         { IRewriteOperation }
Execute(const Buf: TStringBuilder)2627*16467b97STreehugger Robot         function Execute(const Buf: TStringBuilder): Integer; override;
2628*16467b97STreehugger Robot       protected
2629*16467b97STreehugger Robot         { IReplaceOp }
GetLastIndex()2630*16467b97STreehugger Robot         function GetLastIndex: Integer;
2631*16467b97STreehugger Robot         procedure SetLastIndex(const Value: Integer);
2632*16467b97STreehugger Robot       public
2633*16467b97STreehugger Robot         constructor Create(const AStart, AStop: Integer;
2634*16467b97STreehugger Robot           const AText: IANTLRInterface; const AParent: ITokenRewriteStream);
2635*16467b97STreehugger Robot 
ToString()2636*16467b97STreehugger Robot         function ToString: String; override;
2637*16467b97STreehugger Robot       end;
2638*16467b97STreehugger Robot 
2639*16467b97STreehugger Robot       IDeleteOp = interface(IRewriteOperation)
2640*16467b97STreehugger Robot       ['{C39345BC-F170-4C3A-A989-65E6B9F0712B}']
2641*16467b97STreehugger Robot       end;
2642*16467b97STreehugger Robot 
2643*16467b97STreehugger Robot       TDeleteOp = class(TReplaceOp)
2644*16467b97STreehugger Robot       public
ToString()2645*16467b97STreehugger Robot         function ToString: String; override;
2646*16467b97STreehugger Robot       end;
2647*16467b97STreehugger Robot   strict private
2648*16467b97STreehugger Robot     type
2649*16467b97STreehugger Robot       TRewriteOpComparer<T: IRewriteOperation> = class(TComparer<T>)
2650*16467b97STreehugger Robot       public
Compare(const Left, Right: T)2651*16467b97STreehugger Robot         function Compare(const Left, Right: T): Integer; override;
2652*16467b97STreehugger Robot       end;
2653*16467b97STreehugger Robot   strict private
2654*16467b97STreehugger Robot     /// <summary>You may have multiple, named streams of rewrite operations.
2655*16467b97STreehugger Robot     /// I'm calling these things "programs."
2656*16467b97STreehugger Robot     /// Maps String (name) -> rewrite (IList)
2657*16467b97STreehugger Robot     /// </summary>
2658*16467b97STreehugger Robot     FPrograms: IDictionary<String, IList<IRewriteOperation>>;
2659*16467b97STreehugger Robot 
2660*16467b97STreehugger Robot     /// <summary>Map String (program name) -> Integer index </summary>
2661*16467b97STreehugger Robot     FLastRewriteTokenIndexes: IDictionary<String, Integer>;
2662*16467b97STreehugger Robot   strict private
InitializeProgram(const Name: String)2663*16467b97STreehugger Robot     function InitializeProgram(const Name: String): IList<IRewriteOperation>;
2664*16467b97STreehugger Robot   protected
2665*16467b97STreehugger Robot     { ITokenRewriteStream }
2666*16467b97STreehugger Robot     procedure Rollback(const InstructionIndex: Integer); overload; virtual;
2667*16467b97STreehugger Robot     procedure Rollback(const ProgramName: String;
2668*16467b97STreehugger Robot       const InstructionIndex: Integer); overload; virtual;
2669*16467b97STreehugger Robot 
2670*16467b97STreehugger Robot     procedure DeleteProgram; overload; virtual;
2671*16467b97STreehugger Robot     procedure DeleteProgram(const ProgramName: String); overload; virtual;
2672*16467b97STreehugger Robot 
2673*16467b97STreehugger Robot     procedure InsertAfter(const T: IToken; const Text: IANTLRInterface); overload; virtual;
2674*16467b97STreehugger Robot     procedure InsertAfter(const Index: Integer; const Text: IANTLRInterface); overload; virtual;
2675*16467b97STreehugger Robot     procedure InsertAfter(const ProgramName: String; const T: IToken;
2676*16467b97STreehugger Robot       const Text: IANTLRInterface); overload; virtual;
2677*16467b97STreehugger Robot     procedure InsertAfter(const ProgramName: String; const Index: Integer;
2678*16467b97STreehugger Robot       const Text: IANTLRInterface); overload; virtual;
2679*16467b97STreehugger Robot     procedure InsertAfter(const T: IToken; const Text: String); overload;
2680*16467b97STreehugger Robot     procedure InsertAfter(const Index: Integer; const Text: String); overload;
2681*16467b97STreehugger Robot     procedure InsertAfter(const ProgramName: String; const T: IToken;
2682*16467b97STreehugger Robot       const Text: String); overload;
2683*16467b97STreehugger Robot     procedure InsertAfter(const ProgramName: String; const Index: Integer;
2684*16467b97STreehugger Robot       const Text: String); overload;
2685*16467b97STreehugger Robot 
2686*16467b97STreehugger Robot     procedure InsertBefore(const T: IToken; const Text: IANTLRInterface); overload; virtual;
2687*16467b97STreehugger Robot     procedure InsertBefore(const Index: Integer; const Text: IANTLRInterface); overload; virtual;
2688*16467b97STreehugger Robot     procedure InsertBefore(const ProgramName: String; const T: IToken;
2689*16467b97STreehugger Robot       const Text: IANTLRInterface); overload; virtual;
2690*16467b97STreehugger Robot     procedure InsertBefore(const ProgramName: String; const Index: Integer;
2691*16467b97STreehugger Robot       const Text: IANTLRInterface); overload; virtual;
2692*16467b97STreehugger Robot     procedure InsertBefore(const T: IToken; const Text: String); overload;
2693*16467b97STreehugger Robot     procedure InsertBefore(const Index: Integer; const Text: String); overload;
2694*16467b97STreehugger Robot     procedure InsertBefore(const ProgramName: String; const T: IToken;
2695*16467b97STreehugger Robot       const Text: String); overload;
2696*16467b97STreehugger Robot     procedure InsertBefore(const ProgramName: String; const Index: Integer;
2697*16467b97STreehugger Robot       const Text: String); overload;
2698*16467b97STreehugger Robot 
2699*16467b97STreehugger Robot     procedure Replace(const Index: Integer; const Text: IANTLRInterface); overload; virtual;
2700*16467b97STreehugger Robot     procedure Replace(const Start, Stop: Integer; const Text: IANTLRInterface); overload; virtual;
2701*16467b97STreehugger Robot     procedure Replace(const IndexT: IToken; const Text: IANTLRInterface); overload; virtual;
2702*16467b97STreehugger Robot     procedure Replace(const Start, Stop: IToken; const Text: IANTLRInterface); overload; virtual;
2703*16467b97STreehugger Robot     procedure Replace(const ProgramName: String; const Start, Stop: Integer;
2704*16467b97STreehugger Robot       const Text: IANTLRInterface); overload; virtual;
2705*16467b97STreehugger Robot     procedure Replace(const ProgramName: String; const Start, Stop: IToken;
2706*16467b97STreehugger Robot       const Text: IANTLRInterface); overload; virtual;
2707*16467b97STreehugger Robot     procedure Replace(const Index: Integer; const Text: String); overload;
2708*16467b97STreehugger Robot     procedure Replace(const Start, Stop: Integer; const Text: String); overload;
2709*16467b97STreehugger Robot     procedure Replace(const IndexT: IToken; const Text: String); overload;
2710*16467b97STreehugger Robot     procedure Replace(const Start, Stop: IToken; const Text: String); overload;
2711*16467b97STreehugger Robot     procedure Replace(const ProgramName: String; const Start, Stop: Integer;
2712*16467b97STreehugger Robot       const Text: String); overload;
2713*16467b97STreehugger Robot     procedure Replace(const ProgramName: String; const Start, Stop: IToken;
2714*16467b97STreehugger Robot       const Text: String); overload;
2715*16467b97STreehugger Robot 
2716*16467b97STreehugger Robot     procedure Delete(const Index: Integer); overload; virtual;
2717*16467b97STreehugger Robot     procedure Delete(const Start, Stop: Integer); overload; virtual;
2718*16467b97STreehugger Robot     procedure Delete(const IndexT: IToken); overload; virtual;
2719*16467b97STreehugger Robot     procedure Delete(const Start, Stop: IToken); overload; virtual;
2720*16467b97STreehugger Robot     procedure Delete(const ProgramName: String; const Start, Stop: Integer); overload; virtual;
2721*16467b97STreehugger Robot     procedure Delete(const ProgramName: String; const Start, Stop: IToken); overload; virtual;
2722*16467b97STreehugger Robot 
GetLastRewriteTokenIndex()2723*16467b97STreehugger Robot     function GetLastRewriteTokenIndex: Integer; overload; virtual;
2724*16467b97STreehugger Robot 
ToOriginalString()2725*16467b97STreehugger Robot     function ToOriginalString: String; overload; virtual;
ToOriginalString(const Start, Stop: Integer)2726*16467b97STreehugger Robot     function ToOriginalString(const Start, Stop: Integer): String; overload; virtual;
2727*16467b97STreehugger Robot 
ToString(const ProgramName: String)2728*16467b97STreehugger Robot     function ToString(const ProgramName: String): String; overload; virtual;
ToString(const ProgramName: String;2729*16467b97STreehugger Robot     function ToString(const ProgramName: String;
2730*16467b97STreehugger Robot       const Start, Stop: Integer): String; overload; virtual;
2731*16467b97STreehugger Robot 
ToDebugString()2732*16467b97STreehugger Robot     function ToDebugString: String; overload; virtual;
ToDebugString(const Start, Stop: Integer)2733*16467b97STreehugger Robot     function ToDebugString(const Start, Stop: Integer): String; overload; virtual;
2734*16467b97STreehugger Robot   protected
2735*16467b97STreehugger Robot     { ITokenStream }
ToString(const Start, Stop: Integer)2736*16467b97STreehugger Robot     function ToString(const Start, Stop: Integer): String; overload; override;
2737*16467b97STreehugger Robot   strict protected
2738*16467b97STreehugger Robot     procedure Init; virtual;
GetProgram(const Name: String)2739*16467b97STreehugger Robot     function GetProgram(const Name: String): IList<IRewriteOperation>; virtual;
GetLastRewriteTokenIndex(const ProgramName: String)2740*16467b97STreehugger Robot     function GetLastRewriteTokenIndex(const ProgramName: String): Integer; overload; virtual;
2741*16467b97STreehugger Robot     procedure SetLastRewriteTokenIndex(const ProgramName: String; const I: Integer); overload; virtual;
2742*16467b97STreehugger Robot 
2743*16467b97STreehugger Robot     /// <summary>
2744*16467b97STreehugger Robot     /// Return a map from token index to operation.
2745*16467b97STreehugger Robot     /// </summary>
2746*16467b97STreehugger Robot     /// <remarks>We need to combine operations and report invalid operations (like
2747*16467b97STreehugger Robot     /// overlapping replaces that are not completed nested).  Inserts to
2748*16467b97STreehugger Robot     /// same index need to be combined etc...   Here are the cases:
2749*16467b97STreehugger Robot     ///
2750*16467b97STreehugger Robot     /// I.i.u I.j.v               leave alone, nonoverlapping
2751*16467b97STreehugger Robot     /// I.i.u I.i.v               combine: Iivu
2752*16467b97STreehugger Robot     ///
2753*16467b97STreehugger Robot     /// R.i-j.u R.x-y.v | i-j in x-y      delete first R
2754*16467b97STreehugger Robot     /// R.i-j.u R.i-j.v             delete first R
2755*16467b97STreehugger Robot     /// R.i-j.u R.x-y.v | x-y in i-j      ERROR
2756*16467b97STreehugger Robot     /// R.i-j.u R.x-y.v | boundaries overlap  ERROR
2757*16467b97STreehugger Robot     ///
2758*16467b97STreehugger Robot     /// I.i.u R.x-y.v | i in x-y        delete I
2759*16467b97STreehugger Robot     /// I.i.u R.x-y.v | i not in x-y      leave alone, nonoverlapping
2760*16467b97STreehugger Robot     /// R.x-y.v I.i.u | i in x-y        ERROR
2761*16467b97STreehugger Robot     /// R.x-y.v I.x.u               R.x-y.uv (combine, delete I)
2762*16467b97STreehugger Robot     /// R.x-y.v I.i.u | i not in x-y      leave alone, nonoverlapping
2763*16467b97STreehugger Robot     ///
2764*16467b97STreehugger Robot     /// I.i.u = insert u before op @ index i
2765*16467b97STreehugger Robot     /// R.x-y.u = replace x-y indexed tokens with u
2766*16467b97STreehugger Robot     ///
2767*16467b97STreehugger Robot     /// First we need to examine replaces.  For any replace op:
2768*16467b97STreehugger Robot     ///
2769*16467b97STreehugger Robot     ///   1. wipe out any insertions before op within that range.
2770*16467b97STreehugger Robot     ///   2. Drop any replace op before that is contained completely within
2771*16467b97STreehugger Robot     ///        that range.
2772*16467b97STreehugger Robot     ///   3. Throw exception upon boundary overlap with any previous replace.
2773*16467b97STreehugger Robot     ///
2774*16467b97STreehugger Robot     /// Then we can deal with inserts:
2775*16467b97STreehugger Robot     ///
2776*16467b97STreehugger Robot     ///   1. for any inserts to same index, combine even if not adjacent.
2777*16467b97STreehugger Robot     ///   2. for any prior replace with same left boundary, combine this
2778*16467b97STreehugger Robot     ///        insert with replace and delete this replace.
2779*16467b97STreehugger Robot     ///   3. throw exception if index in same range as previous replace
2780*16467b97STreehugger Robot     ///
2781*16467b97STreehugger Robot     /// Don't actually delete; make op null in list. Easier to walk list.
2782*16467b97STreehugger Robot     /// Later we can throw as we add to index -> op map.
2783*16467b97STreehugger Robot     ///
2784*16467b97STreehugger Robot     /// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
2785*16467b97STreehugger Robot     /// inserted stuff would be before the replace range.  But, if you
2786*16467b97STreehugger Robot     /// add tokens in front of a method body '{' and then delete the method
2787*16467b97STreehugger Robot     /// body, I think the stuff before the '{' you added should disappear too.
2788*16467b97STreehugger Robot     /// </remarks>
ReduceToSingleOperationPerIndex(2789*16467b97STreehugger Robot     function ReduceToSingleOperationPerIndex(
2790*16467b97STreehugger Robot       const Rewrites: IList<IRewriteOperation>): IDictionary<Integer, IRewriteOperation>;
2791*16467b97STreehugger Robot 
GetKindOfOps(const Rewrites: IList<IRewriteOperation>;2792*16467b97STreehugger Robot     function GetKindOfOps(const Rewrites: IList<IRewriteOperation>;
2793*16467b97STreehugger Robot       const Kind: TGUID): IList<IRewriteOperation>; overload;
2794*16467b97STreehugger Robot     /// <summary>
2795*16467b97STreehugger Robot     /// Get all operations before an index of a particular kind
2796*16467b97STreehugger Robot     /// </summary>
GetKindOfOps(const Rewrites: IList<IRewriteOperation>;2797*16467b97STreehugger Robot     function GetKindOfOps(const Rewrites: IList<IRewriteOperation>;
2798*16467b97STreehugger Robot       const Kind: TGUID; const Before: Integer): IList<IRewriteOperation>; overload;
2799*16467b97STreehugger Robot 
CatOpText(const A, B: IANTLRInterface)2800*16467b97STreehugger Robot     function CatOpText(const A, B: IANTLRInterface): IANTLRInterface;
2801*16467b97STreehugger Robot   public
2802*16467b97STreehugger Robot     constructor Create; overload;
2803*16467b97STreehugger Robot     constructor Create(const ATokenSource: ITokenSource); overload;
2804*16467b97STreehugger Robot     constructor Create(const ATokenSource: ITokenSource;
2805*16467b97STreehugger Robot       const AChannel: Integer); overload;
2806*16467b97STreehugger Robot     constructor Create(const ALexer: ILexer); overload;
2807*16467b97STreehugger Robot     constructor Create(const ALexer: ILexer;
2808*16467b97STreehugger Robot       const AChannel: Integer); overload;
2809*16467b97STreehugger Robot 
ToString()2810*16467b97STreehugger Robot     function ToString: String; overload; override;
2811*16467b97STreehugger Robot   end;
2812*16467b97STreehugger Robot 
2813*16467b97STreehugger Robot { These functions return X or, if X = nil, an empty default instance }
Def(const X: IToken)2814*16467b97STreehugger Robot function Def(const X: IToken): IToken; overload;
Def(const X: IRuleReturnScope)2815*16467b97STreehugger Robot function Def(const X: IRuleReturnScope): IRuleReturnScope; overload;
2816*16467b97STreehugger Robot 
2817*16467b97STreehugger Robot implementation
2818*16467b97STreehugger Robot 
2819*16467b97STreehugger Robot uses
2820*16467b97STreehugger Robot   StrUtils,
2821*16467b97STreehugger Robot   Math,
2822*16467b97STreehugger Robot   Antlr.Runtime.Tree;
2823*16467b97STreehugger Robot 
2824*16467b97STreehugger Robot { ERecognitionException }
2825*16467b97STreehugger Robot 
2826*16467b97STreehugger Robot constructor ERecognitionException.Create;
2827*16467b97STreehugger Robot begin
2828*16467b97STreehugger Robot   Create('', nil);
2829*16467b97STreehugger Robot end;
2830*16467b97STreehugger Robot 
2831*16467b97STreehugger Robot constructor ERecognitionException.Create(const AMessage: String);
2832*16467b97STreehugger Robot begin
2833*16467b97STreehugger Robot   Create(AMessage, nil);
2834*16467b97STreehugger Robot end;
2835*16467b97STreehugger Robot 
2836*16467b97STreehugger Robot constructor ERecognitionException.Create(const AInput: IIntStream);
2837*16467b97STreehugger Robot begin
2838*16467b97STreehugger Robot   Create('', AInput);
2839*16467b97STreehugger Robot end;
2840*16467b97STreehugger Robot 
2841*16467b97STreehugger Robot constructor ERecognitionException.Create(const AMessage: String;
2842*16467b97STreehugger Robot   const AInput: IIntStream);
2843*16467b97STreehugger Robot var
2844*16467b97STreehugger Robot   TokenStream: ITokenStream;
2845*16467b97STreehugger Robot   CharStream: ICharStream;
2846*16467b97STreehugger Robot begin
2847*16467b97STreehugger Robot   inherited Create(AMessage);
2848*16467b97STreehugger Robot   FInput := AInput;
2849*16467b97STreehugger Robot   FIndex := AInput.Index;
2850*16467b97STreehugger Robot 
2851*16467b97STreehugger Robot   if Supports(AInput, ITokenStream, TokenStream) then
2852*16467b97STreehugger Robot   begin
2853*16467b97STreehugger Robot     FToken := TokenStream.LT(1);
2854*16467b97STreehugger Robot     FLine := FToken.Line;
2855*16467b97STreehugger Robot     FCharPositionInLine := FToken.CharPositionInLine;
2856*16467b97STreehugger Robot   end;
2857*16467b97STreehugger Robot 
2858*16467b97STreehugger Robot   if Supports(AInput, ITreeNodeStream) then
2859*16467b97STreehugger Robot     ExtractInformationFromTreeNodeStream(AInput)
2860*16467b97STreehugger Robot   else
2861*16467b97STreehugger Robot   begin
2862*16467b97STreehugger Robot     if Supports(AInput, ICharStream, CharStream) then
2863*16467b97STreehugger Robot     begin
2864*16467b97STreehugger Robot       FC := AInput.LA(1);
2865*16467b97STreehugger Robot       FLine := CharStream.Line;
2866*16467b97STreehugger Robot       FCharPositionInLine := CharStream.CharPositionInLine;
2867*16467b97STreehugger Robot     end
2868*16467b97STreehugger Robot     else
2869*16467b97STreehugger Robot       FC := AInput.LA(1);
2870*16467b97STreehugger Robot   end;
2871*16467b97STreehugger Robot end;
2872*16467b97STreehugger Robot 
2873*16467b97STreehugger Robot procedure ERecognitionException.ExtractInformationFromTreeNodeStream(
2874*16467b97STreehugger Robot   const Input: IIntStream);
2875*16467b97STreehugger Robot var
2876*16467b97STreehugger Robot   Nodes: ITreeNodeStream;
2877*16467b97STreehugger Robot   Adaptor: ITreeAdaptor;
2878*16467b97STreehugger Robot   Payload, PriorPayload: IToken;
2879*16467b97STreehugger Robot   I, NodeType: Integer;
2880*16467b97STreehugger Robot   PriorNode: IANTLRInterface;
2881*16467b97STreehugger Robot   Tree: ITree;
2882*16467b97STreehugger Robot   Text: String;
2883*16467b97STreehugger Robot   CommonTree: ICommonTree;
2884*16467b97STreehugger Robot begin
2885*16467b97STreehugger Robot   Nodes := Input as ITreeNodeStream;
2886*16467b97STreehugger Robot   FNode := Nodes.LT(1);
2887*16467b97STreehugger Robot   Adaptor := Nodes.TreeAdaptor;
2888*16467b97STreehugger Robot   Payload := Adaptor.GetToken(FNode);
2889*16467b97STreehugger Robot 
2890*16467b97STreehugger Robot   if Assigned(Payload) then
2891*16467b97STreehugger Robot   begin
2892*16467b97STreehugger Robot     FToken := Payload;
2893*16467b97STreehugger Robot     if (Payload.Line <= 0) then
2894*16467b97STreehugger Robot     begin
2895*16467b97STreehugger Robot       // imaginary node; no line/pos info; scan backwards
2896*16467b97STreehugger Robot       I := -1;
2897*16467b97STreehugger Robot       PriorNode := Nodes.LT(I);
2898*16467b97STreehugger Robot       while Assigned(PriorNode) do
2899*16467b97STreehugger Robot       begin
2900*16467b97STreehugger Robot         PriorPayload := Adaptor.GetToken(PriorNode);
2901*16467b97STreehugger Robot         if Assigned(PriorPayload) and (PriorPayload.Line > 0) then
2902*16467b97STreehugger Robot         begin
2903*16467b97STreehugger Robot           // we found the most recent real line / pos info
2904*16467b97STreehugger Robot           FLine := PriorPayload.Line;
2905*16467b97STreehugger Robot           FCharPositionInLine := PriorPayload.CharPositionInLine;
2906*16467b97STreehugger Robot           FApproximateLineInfo := True;
2907*16467b97STreehugger Robot           Break;
2908*16467b97STreehugger Robot         end;
2909*16467b97STreehugger Robot         Dec(I);
2910*16467b97STreehugger Robot         PriorNode := Nodes.LT(I)
2911*16467b97STreehugger Robot       end;
2912*16467b97STreehugger Robot     end
2913*16467b97STreehugger Robot     else
2914*16467b97STreehugger Robot     begin
2915*16467b97STreehugger Robot       // node created from real token
2916*16467b97STreehugger Robot       FLine := Payload.Line;
2917*16467b97STreehugger Robot       FCharPositionInLine := Payload.CharPositionInLine;
2918*16467b97STreehugger Robot     end;
2919*16467b97STreehugger Robot   end else
2920*16467b97STreehugger Robot     if Supports(FNode, ITree, Tree) then
2921*16467b97STreehugger Robot     begin
2922*16467b97STreehugger Robot       FLine := Tree.Line;
2923*16467b97STreehugger Robot       FCharPositionInLine := Tree.CharPositionInLine;
2924*16467b97STreehugger Robot       if Supports(FNode, ICommonTree, CommonTree) then
2925*16467b97STreehugger Robot         FToken := CommonTree.Token;
2926*16467b97STreehugger Robot     end
2927*16467b97STreehugger Robot     else
2928*16467b97STreehugger Robot     begin
2929*16467b97STreehugger Robot       NodeType := Adaptor.GetNodeType(FNode);
2930*16467b97STreehugger Robot       Text := Adaptor.GetNodeText(FNode);
2931*16467b97STreehugger Robot       FToken := TCommonToken.Create(NodeType, Text);
2932*16467b97STreehugger Robot     end;
2933*16467b97STreehugger Robot end;
2934*16467b97STreehugger Robot 
ERecognitionException.GetUnexpectedType()2935*16467b97STreehugger Robot function ERecognitionException.GetUnexpectedType: Integer;
2936*16467b97STreehugger Robot var
2937*16467b97STreehugger Robot   Nodes: ITreeNodeStream;
2938*16467b97STreehugger Robot   Adaptor: ITreeAdaptor;
2939*16467b97STreehugger Robot begin
2940*16467b97STreehugger Robot   if Supports(FInput, ITokenStream) then
2941*16467b97STreehugger Robot     Result := FToken.TokenType
2942*16467b97STreehugger Robot   else
2943*16467b97STreehugger Robot     if Supports(FInput, ITreeNodeStream, Nodes) then
2944*16467b97STreehugger Robot     begin
2945*16467b97STreehugger Robot       Adaptor := Nodes.TreeAdaptor;
2946*16467b97STreehugger Robot       Result := Adaptor.GetNodeType(FNode);
2947*16467b97STreehugger Robot     end else
2948*16467b97STreehugger Robot       Result := FC;
2949*16467b97STreehugger Robot end;
2950*16467b97STreehugger Robot 
2951*16467b97STreehugger Robot { EMismatchedTokenException }
2952*16467b97STreehugger Robot 
2953*16467b97STreehugger Robot constructor EMismatchedTokenException.Create(const AExpecting: Integer;
2954*16467b97STreehugger Robot   const AInput: IIntStream);
2955*16467b97STreehugger Robot begin
2956*16467b97STreehugger Robot   inherited Create(AInput);
2957*16467b97STreehugger Robot   FExpecting := AExpecting;
2958*16467b97STreehugger Robot end;
2959*16467b97STreehugger Robot 
EMismatchedTokenException.ToString()2960*16467b97STreehugger Robot function EMismatchedTokenException.ToString: String;
2961*16467b97STreehugger Robot begin
2962*16467b97STreehugger Robot   Result := 'MismatchedTokenException(' + IntToStr(UnexpectedType)
2963*16467b97STreehugger Robot     + '!=' + IntToStr(Expecting) + ')';
2964*16467b97STreehugger Robot 
2965*16467b97STreehugger Robot end;
2966*16467b97STreehugger Robot 
2967*16467b97STreehugger Robot { EUnwantedTokenException }
2968*16467b97STreehugger Robot 
EUnwantedTokenException.GetUnexpectedToken()2969*16467b97STreehugger Robot function EUnwantedTokenException.GetUnexpectedToken: IToken;
2970*16467b97STreehugger Robot begin
2971*16467b97STreehugger Robot   Result := FToken;
2972*16467b97STreehugger Robot end;
2973*16467b97STreehugger Robot 
EUnwantedTokenException.ToString()2974*16467b97STreehugger Robot function EUnwantedTokenException.ToString: String;
2975*16467b97STreehugger Robot var
2976*16467b97STreehugger Robot   Exp: String;
2977*16467b97STreehugger Robot begin
2978*16467b97STreehugger Robot   if (Expecting = TToken.INVALID_TOKEN_TYPE) then
2979*16467b97STreehugger Robot     Exp := ''
2980*16467b97STreehugger Robot   else
2981*16467b97STreehugger Robot     Exp := ', expected ' + IntToStr(Expecting);
2982*16467b97STreehugger Robot   if (Token = nil) then
2983*16467b97STreehugger Robot     Result := 'UnwantedTokenException(found=nil' + Exp + ')'
2984*16467b97STreehugger Robot   else
2985*16467b97STreehugger Robot     Result := 'UnwantedTokenException(found=' + Token.Text + Exp + ')'
2986*16467b97STreehugger Robot end;
2987*16467b97STreehugger Robot 
2988*16467b97STreehugger Robot { EMissingTokenException }
2989*16467b97STreehugger Robot 
2990*16467b97STreehugger Robot constructor EMissingTokenException.Create(const AExpecting: Integer;
2991*16467b97STreehugger Robot   const AInput: IIntStream; const AInserted: IANTLRInterface);
2992*16467b97STreehugger Robot begin
2993*16467b97STreehugger Robot   inherited Create(AExpecting, AInput);
2994*16467b97STreehugger Robot   FInserted := AInserted;
2995*16467b97STreehugger Robot end;
2996*16467b97STreehugger Robot 
EMissingTokenException.GetMissingType()2997*16467b97STreehugger Robot function EMissingTokenException.GetMissingType: Integer;
2998*16467b97STreehugger Robot begin
2999*16467b97STreehugger Robot   Result := Expecting;
3000*16467b97STreehugger Robot end;
3001*16467b97STreehugger Robot 
EMissingTokenException.ToString()3002*16467b97STreehugger Robot function EMissingTokenException.ToString: String;
3003*16467b97STreehugger Robot begin
3004*16467b97STreehugger Robot   if Assigned(FInserted) and Assigned(FToken) then
3005*16467b97STreehugger Robot     Result := 'MissingTokenException(inserted ' + FInserted.ToString
3006*16467b97STreehugger Robot       + ' at ' + FToken.Text + ')'
3007*16467b97STreehugger Robot   else
3008*16467b97STreehugger Robot     if Assigned(FToken) then
3009*16467b97STreehugger Robot       Result := 'MissingTokenException(at ' + FToken.Text + ')'
3010*16467b97STreehugger Robot     else
3011*16467b97STreehugger Robot       Result := 'MissingTokenException';
3012*16467b97STreehugger Robot end;
3013*16467b97STreehugger Robot 
3014*16467b97STreehugger Robot { EMismatchedTreeNodeException }
3015*16467b97STreehugger Robot 
3016*16467b97STreehugger Robot constructor EMismatchedTreeNodeException.Create(const AExpecting: Integer;
3017*16467b97STreehugger Robot   const AInput: IIntStream);
3018*16467b97STreehugger Robot begin
3019*16467b97STreehugger Robot   inherited Create(AInput);
3020*16467b97STreehugger Robot   FExpecting := AExpecting;
3021*16467b97STreehugger Robot end;
3022*16467b97STreehugger Robot 
EMismatchedTreeNodeException.ToString()3023*16467b97STreehugger Robot function EMismatchedTreeNodeException.ToString: String;
3024*16467b97STreehugger Robot begin
3025*16467b97STreehugger Robot   Result := 'MismatchedTreeNodeException(' + IntToStr(UnexpectedType)
3026*16467b97STreehugger Robot     + '!=' + IntToStr(Expecting) + ')';
3027*16467b97STreehugger Robot end;
3028*16467b97STreehugger Robot 
3029*16467b97STreehugger Robot { ENoViableAltException }
3030*16467b97STreehugger Robot 
3031*16467b97STreehugger Robot constructor ENoViableAltException.Create(
3032*16467b97STreehugger Robot   const AGrammarDecisionDescription: String; const ADecisionNumber,
3033*16467b97STreehugger Robot   AStateNumber: Integer; const AInput: IIntStream);
3034*16467b97STreehugger Robot begin
3035*16467b97STreehugger Robot   inherited Create(AInput);
3036*16467b97STreehugger Robot   FGrammarDecisionDescription := AGrammarDecisionDescription;
3037*16467b97STreehugger Robot   FDecisionNumber := ADecisionNumber;
3038*16467b97STreehugger Robot   FStateNumber := AStateNumber;
3039*16467b97STreehugger Robot end;
3040*16467b97STreehugger Robot 
ENoViableAltException.ToString()3041*16467b97STreehugger Robot function ENoViableAltException.ToString: String;
3042*16467b97STreehugger Robot begin
3043*16467b97STreehugger Robot   if Supports(Input, ICharStream) then
3044*16467b97STreehugger Robot     Result := 'NoViableAltException(''' + Char(UnexpectedType) + '''@['
3045*16467b97STreehugger Robot       + FGrammarDecisionDescription + '])'
3046*16467b97STreehugger Robot   else
3047*16467b97STreehugger Robot     Result := 'NoViableAltException(''' + IntToStr(UnexpectedType) + '''@['
3048*16467b97STreehugger Robot       + FGrammarDecisionDescription + '])'
3049*16467b97STreehugger Robot end;
3050*16467b97STreehugger Robot 
3051*16467b97STreehugger Robot { EEarlyExitException }
3052*16467b97STreehugger Robot 
3053*16467b97STreehugger Robot constructor EEarlyExitException.Create(const ADecisionNumber: Integer;
3054*16467b97STreehugger Robot   const AInput: IIntStream);
3055*16467b97STreehugger Robot begin
3056*16467b97STreehugger Robot   inherited Create(AInput);
3057*16467b97STreehugger Robot   FDecisionNumber := ADecisionNumber;
3058*16467b97STreehugger Robot end;
3059*16467b97STreehugger Robot 
3060*16467b97STreehugger Robot { EMismatchedSetException }
3061*16467b97STreehugger Robot 
3062*16467b97STreehugger Robot constructor EMismatchedSetException.Create(const AExpecting: IBitSet;
3063*16467b97STreehugger Robot   const AInput: IIntStream);
3064*16467b97STreehugger Robot begin
3065*16467b97STreehugger Robot   inherited Create(AInput);
3066*16467b97STreehugger Robot   FExpecting := AExpecting;
3067*16467b97STreehugger Robot end;
3068*16467b97STreehugger Robot 
EMismatchedSetException.ToString()3069*16467b97STreehugger Robot function EMismatchedSetException.ToString: String;
3070*16467b97STreehugger Robot begin
3071*16467b97STreehugger Robot   Result := 'MismatchedSetException(' + IntToStr(UnexpectedType)
3072*16467b97STreehugger Robot     + '!=' + Expecting.ToString + ')';
3073*16467b97STreehugger Robot end;
3074*16467b97STreehugger Robot 
3075*16467b97STreehugger Robot { EMismatchedNotSetException }
3076*16467b97STreehugger Robot 
EMismatchedNotSetException.ToString()3077*16467b97STreehugger Robot function EMismatchedNotSetException.ToString: String;
3078*16467b97STreehugger Robot begin
3079*16467b97STreehugger Robot   Result := 'MismatchedNotSetException(' + IntToStr(UnexpectedType)
3080*16467b97STreehugger Robot     + '!=' + Expecting.ToString + ')';
3081*16467b97STreehugger Robot end;
3082*16467b97STreehugger Robot 
3083*16467b97STreehugger Robot { EFailedPredicateException }
3084*16467b97STreehugger Robot 
3085*16467b97STreehugger Robot constructor EFailedPredicateException.Create(const AInput: IIntStream;
3086*16467b97STreehugger Robot   const ARuleName, APredicateText: String);
3087*16467b97STreehugger Robot begin
3088*16467b97STreehugger Robot   inherited Create(AInput);
3089*16467b97STreehugger Robot   FRuleName := ARuleName;
3090*16467b97STreehugger Robot   FPredicateText := APredicateText;
3091*16467b97STreehugger Robot end;
3092*16467b97STreehugger Robot 
EFailedPredicateException.ToString()3093*16467b97STreehugger Robot function EFailedPredicateException.ToString: String;
3094*16467b97STreehugger Robot begin
3095*16467b97STreehugger Robot   Result := 'FailedPredicateException(' + FRuleName + ',{' + FPredicateText + '}?)';
3096*16467b97STreehugger Robot end;
3097*16467b97STreehugger Robot 
3098*16467b97STreehugger Robot { EMismatchedRangeException }
3099*16467b97STreehugger Robot 
3100*16467b97STreehugger Robot constructor EMismatchedRangeException.Create(const AA, AB: Integer;
3101*16467b97STreehugger Robot   const AInput: IIntStream);
3102*16467b97STreehugger Robot begin
3103*16467b97STreehugger Robot   inherited Create(FInput);
3104*16467b97STreehugger Robot   FA := AA;
3105*16467b97STreehugger Robot   FB := AB;
3106*16467b97STreehugger Robot end;
3107*16467b97STreehugger Robot 
EMismatchedRangeException.ToString()3108*16467b97STreehugger Robot function EMismatchedRangeException.ToString: String;
3109*16467b97STreehugger Robot begin
3110*16467b97STreehugger Robot   Result := 'MismatchedNotSetException(' + IntToStr(UnexpectedType)
3111*16467b97STreehugger Robot     + ' not in [' + IntToStr(FA)+ ',' + IntToStr(FB) + '])';
3112*16467b97STreehugger Robot end;
3113*16467b97STreehugger Robot 
3114*16467b97STreehugger Robot { TCharStreamState }
3115*16467b97STreehugger Robot 
GetCharPositionInLinenull3116*16467b97STreehugger Robot function TCharStreamState.GetCharPositionInLine: Integer;
3117*16467b97STreehugger Robot begin
3118*16467b97STreehugger Robot   Result := FCharPositionInLine;
3119*16467b97STreehugger Robot end;
3120*16467b97STreehugger Robot 
GetLinenull3121*16467b97STreehugger Robot function TCharStreamState.GetLine: Integer;
3122*16467b97STreehugger Robot begin
3123*16467b97STreehugger Robot   Result := FLine;
3124*16467b97STreehugger Robot end;
3125*16467b97STreehugger Robot 
TCharStreamState.GetP()3126*16467b97STreehugger Robot function TCharStreamState.GetP: Integer;
3127*16467b97STreehugger Robot begin
3128*16467b97STreehugger Robot   Result := FP;
3129*16467b97STreehugger Robot end;
3130*16467b97STreehugger Robot 
3131*16467b97STreehugger Robot procedure TCharStreamState.SetCharPositionInLine(const Value: Integer);
3132*16467b97STreehugger Robot begin
3133*16467b97STreehugger Robot   FCharPositionInLine := Value;
3134*16467b97STreehugger Robot end;
3135*16467b97STreehugger Robot 
3136*16467b97STreehugger Robot procedure TCharStreamState.SetLine(const Value: Integer);
3137*16467b97STreehugger Robot begin
3138*16467b97STreehugger Robot   FLine := Value;
3139*16467b97STreehugger Robot end;
3140*16467b97STreehugger Robot 
3141*16467b97STreehugger Robot procedure TCharStreamState.SetP(const Value: Integer);
3142*16467b97STreehugger Robot begin
3143*16467b97STreehugger Robot   FP := Value;
3144*16467b97STreehugger Robot end;
3145*16467b97STreehugger Robot 
3146*16467b97STreehugger Robot { TANTLRStringStream }
3147*16467b97STreehugger Robot 
3148*16467b97STreehugger Robot constructor TANTLRStringStream.Create(const AInput: String);
3149*16467b97STreehugger Robot begin
3150*16467b97STreehugger Robot   inherited Create;
3151*16467b97STreehugger Robot   FLine := 1;
3152*16467b97STreehugger Robot   FOwnsData := True;
3153*16467b97STreehugger Robot   FN := Length(AInput);
3154*16467b97STreehugger Robot   if (FN > 0) then
3155*16467b97STreehugger Robot   begin
3156*16467b97STreehugger Robot     GetMem(FData,FN * SizeOf(Char));
3157*16467b97STreehugger Robot     Move(AInput[1],FData^,FN * SizeOf(Char));
3158*16467b97STreehugger Robot   end;
3159*16467b97STreehugger Robot end;
3160*16467b97STreehugger Robot 
3161*16467b97STreehugger Robot procedure TANTLRStringStream.Consume;
3162*16467b97STreehugger Robot begin
3163*16467b97STreehugger Robot   if (FP < FN) then
3164*16467b97STreehugger Robot   begin
3165*16467b97STreehugger Robot     Inc(FCharPositionInLine);
3166*16467b97STreehugger Robot     if (FData[FP] = #10) then
3167*16467b97STreehugger Robot     begin
3168*16467b97STreehugger Robot       Inc(FLine);
3169*16467b97STreehugger Robot       FCharPositionInLine := 0;
3170*16467b97STreehugger Robot     end;
3171*16467b97STreehugger Robot     Inc(FP);
3172*16467b97STreehugger Robot   end;
3173*16467b97STreehugger Robot end;
3174*16467b97STreehugger Robot 
3175*16467b97STreehugger Robot constructor TANTLRStringStream.Create(const AData: PChar;
3176*16467b97STreehugger Robot   const ANumberOfActualCharsInArray: Integer);
3177*16467b97STreehugger Robot begin
3178*16467b97STreehugger Robot   inherited Create;
3179*16467b97STreehugger Robot   FLine := 1;
3180*16467b97STreehugger Robot   FOwnsData := False;
3181*16467b97STreehugger Robot   FData := AData;
3182*16467b97STreehugger Robot   FN := ANumberOfActualCharsInArray;
3183*16467b97STreehugger Robot end;
3184*16467b97STreehugger Robot 
3185*16467b97STreehugger Robot constructor TANTLRStringStream.Create;
3186*16467b97STreehugger Robot begin
3187*16467b97STreehugger Robot   inherited Create;
3188*16467b97STreehugger Robot   FLine := 1;
3189*16467b97STreehugger Robot end;
3190*16467b97STreehugger Robot 
3191*16467b97STreehugger Robot destructor TANTLRStringStream.Destroy;
3192*16467b97STreehugger Robot begin
3193*16467b97STreehugger Robot   if (FOwnsData) then
3194*16467b97STreehugger Robot     FreeMem(FData);
3195*16467b97STreehugger Robot   inherited;
3196*16467b97STreehugger Robot end;
3197*16467b97STreehugger Robot 
TANTLRStringStream.GetCharPositionInLine()3198*16467b97STreehugger Robot function TANTLRStringStream.GetCharPositionInLine: Integer;
3199*16467b97STreehugger Robot begin
3200*16467b97STreehugger Robot   Result := FCharPositionInLine;
3201*16467b97STreehugger Robot end;
3202*16467b97STreehugger Robot 
GetLinenull3203*16467b97STreehugger Robot function TANTLRStringStream.GetLine: Integer;
3204*16467b97STreehugger Robot begin
3205*16467b97STreehugger Robot   Result := FLine;
3206*16467b97STreehugger Robot end;
3207*16467b97STreehugger Robot 
GetSourceNamenull3208*16467b97STreehugger Robot function TANTLRStringStream.GetSourceName: String;
3209*16467b97STreehugger Robot begin
3210*16467b97STreehugger Robot   Result := FName;
3211*16467b97STreehugger Robot end;
3212*16467b97STreehugger Robot 
Indexnull3213*16467b97STreehugger Robot function TANTLRStringStream.Index: Integer;
3214*16467b97STreehugger Robot begin
3215*16467b97STreehugger Robot   Result := FP;
3216*16467b97STreehugger Robot end;
3217*16467b97STreehugger Robot 
LAnull3218*16467b97STreehugger Robot function TANTLRStringStream.LA(I: Integer): Integer;
3219*16467b97STreehugger Robot begin
3220*16467b97STreehugger Robot   if (I = 0) then
3221*16467b97STreehugger Robot     Result := 0 // undefined
3222*16467b97STreehugger Robot   else begin
3223*16467b97STreehugger Robot     if (I < 0) then
3224*16467b97STreehugger Robot     begin
3225*16467b97STreehugger Robot       Inc(I); // e.g., translate LA(-1) to use offset i=0; then data[p+0-1]
3226*16467b97STreehugger Robot       if ((FP + I - 1) < 0) then
3227*16467b97STreehugger Robot       begin
3228*16467b97STreehugger Robot         Result := Integer(cscEOF);
3229*16467b97STreehugger Robot         Exit;
3230*16467b97STreehugger Robot       end;
3231*16467b97STreehugger Robot     end;
3232*16467b97STreehugger Robot 
3233*16467b97STreehugger Robot     if ((FP + I - 1) >= FN) then
3234*16467b97STreehugger Robot       Result := Integer(cscEOF)
3235*16467b97STreehugger Robot     else
3236*16467b97STreehugger Robot       Result := Integer(FData[FP + I - 1]);
3237*16467b97STreehugger Robot   end;
3238*16467b97STreehugger Robot end;
3239*16467b97STreehugger Robot 
TANTLRStringStream.LAChar(I: Integer)3240*16467b97STreehugger Robot function TANTLRStringStream.LAChar(I: Integer): Char;
3241*16467b97STreehugger Robot begin
3242*16467b97STreehugger Robot   Result := Char(LA(I));
3243*16467b97STreehugger Robot end;
3244*16467b97STreehugger Robot 
LTnull3245*16467b97STreehugger Robot function TANTLRStringStream.LT(const I: Integer): Integer;
3246*16467b97STreehugger Robot begin
3247*16467b97STreehugger Robot   Result := LA(I);
3248*16467b97STreehugger Robot end;
3249*16467b97STreehugger Robot 
TANTLRStringStream.Mark()3250*16467b97STreehugger Robot function TANTLRStringStream.Mark: Integer;
3251*16467b97STreehugger Robot var
3252*16467b97STreehugger Robot   State: ICharStreamState;
3253*16467b97STreehugger Robot begin
3254*16467b97STreehugger Robot   if (FMarkers = nil) then
3255*16467b97STreehugger Robot   begin
3256*16467b97STreehugger Robot     FMarkers := TList<ICharStreamState>.Create;
3257*16467b97STreehugger Robot     FMarkers.Add(nil);  // depth 0 means no backtracking, leave blank
3258*16467b97STreehugger Robot   end;
3259*16467b97STreehugger Robot 
3260*16467b97STreehugger Robot   Inc(FMarkDepth);
3261*16467b97STreehugger Robot   if (FMarkDepth >= FMarkers.Count) then
3262*16467b97STreehugger Robot   begin
3263*16467b97STreehugger Robot     State := TCharStreamState.Create;
3264*16467b97STreehugger Robot     FMarkers.Add(State);
3265*16467b97STreehugger Robot   end
3266*16467b97STreehugger Robot   else
3267*16467b97STreehugger Robot     State := FMarkers[FMarkDepth];
3268*16467b97STreehugger Robot 
3269*16467b97STreehugger Robot   State.P := FP;
3270*16467b97STreehugger Robot   State.Line := FLine;
3271*16467b97STreehugger Robot   State.CharPositionInLine := FCharPositionInLine;
3272*16467b97STreehugger Robot   FLastMarker := FMarkDepth;
3273*16467b97STreehugger Robot   Result := FMarkDepth;
3274*16467b97STreehugger Robot end;
3275*16467b97STreehugger Robot 
3276*16467b97STreehugger Robot procedure TANTLRStringStream.Release(const Marker: Integer);
3277*16467b97STreehugger Robot begin
3278*16467b97STreehugger Robot   // unwind any other markers made after m and release m
3279*16467b97STreehugger Robot   FMarkDepth := Marker;
3280*16467b97STreehugger Robot   // release this marker
3281*16467b97STreehugger Robot   Dec(FMarkDepth);
3282*16467b97STreehugger Robot end;
3283*16467b97STreehugger Robot 
3284*16467b97STreehugger Robot procedure TANTLRStringStream.Reset;
3285*16467b97STreehugger Robot begin
3286*16467b97STreehugger Robot   FP := 0;
3287*16467b97STreehugger Robot   FLine := 1;
3288*16467b97STreehugger Robot   FCharPositionInLine := 0;
3289*16467b97STreehugger Robot   FMarkDepth := 0;
3290*16467b97STreehugger Robot end;
3291*16467b97STreehugger Robot 
3292*16467b97STreehugger Robot procedure TANTLRStringStream.Rewind(const Marker: Integer);
3293*16467b97STreehugger Robot var
3294*16467b97STreehugger Robot   State: ICharStreamState;
3295*16467b97STreehugger Robot begin
3296*16467b97STreehugger Robot   State := FMarkers[Marker];
3297*16467b97STreehugger Robot   // restore stream state
3298*16467b97STreehugger Robot   Seek(State.P);
3299*16467b97STreehugger Robot   FLine := State.Line;
3300*16467b97STreehugger Robot   FCharPositionInLine := State.CharPositionInLine;
3301*16467b97STreehugger Robot   Release(Marker);
3302*16467b97STreehugger Robot end;
3303*16467b97STreehugger Robot 
3304*16467b97STreehugger Robot procedure TANTLRStringStream.Rewind;
3305*16467b97STreehugger Robot begin
3306*16467b97STreehugger Robot   Rewind(FLastMarker);
3307*16467b97STreehugger Robot end;
3308*16467b97STreehugger Robot 
3309*16467b97STreehugger Robot procedure TANTLRStringStream.Seek(const Index: Integer);
3310*16467b97STreehugger Robot begin
3311*16467b97STreehugger Robot   if (Index <= FP) then
3312*16467b97STreehugger Robot     FP := Index // just jump; don't update stream state (line, ...)
3313*16467b97STreehugger Robot   else begin
3314*16467b97STreehugger Robot     // seek forward, consume until p hits index
3315*16467b97STreehugger Robot     while (FP < Index) do
3316*16467b97STreehugger Robot       Consume;
3317*16467b97STreehugger Robot   end;
3318*16467b97STreehugger Robot end;
3319*16467b97STreehugger Robot 
3320*16467b97STreehugger Robot procedure TANTLRStringStream.SetCharPositionInLine(const Value: Integer);
3321*16467b97STreehugger Robot begin
3322*16467b97STreehugger Robot   FCharPositionInLine := Value;
3323*16467b97STreehugger Robot end;
3324*16467b97STreehugger Robot 
3325*16467b97STreehugger Robot procedure TANTLRStringStream.SetLine(const Value: Integer);
3326*16467b97STreehugger Robot begin
3327*16467b97STreehugger Robot   FLine := Value;
3328*16467b97STreehugger Robot end;
3329*16467b97STreehugger Robot 
TANTLRStringStream.Size()3330*16467b97STreehugger Robot function TANTLRStringStream.Size: Integer;
3331*16467b97STreehugger Robot begin
3332*16467b97STreehugger Robot   Result := FN;
3333*16467b97STreehugger Robot end;
3334*16467b97STreehugger Robot 
Substringnull3335*16467b97STreehugger Robot function TANTLRStringStream.Substring(const Start, Stop: Integer): String;
3336*16467b97STreehugger Robot begin
3337*16467b97STreehugger Robot   Result := Copy(FData, Start + 1, Stop - Start + 1);
3338*16467b97STreehugger Robot end;
3339*16467b97STreehugger Robot 
3340*16467b97STreehugger Robot { TANTLRFileStream }
3341*16467b97STreehugger Robot 
3342*16467b97STreehugger Robot constructor TANTLRFileStream.Create(const AFileName: String);
3343*16467b97STreehugger Robot begin
3344*16467b97STreehugger Robot   Create(AFilename,TEncoding.Default);
3345*16467b97STreehugger Robot end;
3346*16467b97STreehugger Robot 
3347*16467b97STreehugger Robot constructor TANTLRFileStream.Create(const AFileName: String;
3348*16467b97STreehugger Robot   const AEncoding: TEncoding);
3349*16467b97STreehugger Robot begin
3350*16467b97STreehugger Robot   inherited Create;
3351*16467b97STreehugger Robot   FFileName := AFileName;
3352*16467b97STreehugger Robot   Load(FFileName, AEncoding);
3353*16467b97STreehugger Robot end;
3354*16467b97STreehugger Robot 
GetSourceNamenull3355*16467b97STreehugger Robot function TANTLRFileStream.GetSourceName: String;
3356*16467b97STreehugger Robot begin
3357*16467b97STreehugger Robot   Result := FFileName;
3358*16467b97STreehugger Robot end;
3359*16467b97STreehugger Robot 
3360*16467b97STreehugger Robot procedure TANTLRFileStream.Load(const FileName: String;
3361*16467b97STreehugger Robot   const Encoding: TEncoding);
3362*16467b97STreehugger Robot var
3363*16467b97STreehugger Robot   FR: TStreamReader;
3364*16467b97STreehugger Robot   S: String;
3365*16467b97STreehugger Robot begin
3366*16467b97STreehugger Robot   if (FFileName <> '') then
3367*16467b97STreehugger Robot   begin
3368*16467b97STreehugger Robot     if (Encoding = nil) then
3369*16467b97STreehugger Robot       FR := TStreamReader.Create(FileName,TEncoding.Default)
3370*16467b97STreehugger Robot     else
3371*16467b97STreehugger Robot       FR := TStreamReader.Create(FileName,Encoding);
3372*16467b97STreehugger Robot 
3373*16467b97STreehugger Robot     try
3374*16467b97STreehugger Robot       if (FOwnsData) then
3375*16467b97STreehugger Robot       begin
3376*16467b97STreehugger Robot         FreeMem(FData);
3377*16467b97STreehugger Robot         FData := nil;
3378*16467b97STreehugger Robot       end;
3379*16467b97STreehugger Robot 
3380*16467b97STreehugger Robot       FOwnsData := True;
3381*16467b97STreehugger Robot       S := FR.ReadToEnd;
3382*16467b97STreehugger Robot       FN := Length(S);
3383*16467b97STreehugger Robot       if (FN > 0) then
3384*16467b97STreehugger Robot       begin
3385*16467b97STreehugger Robot         GetMem(FData,FN * SizeOf(Char));
3386*16467b97STreehugger Robot         Move(S[1],FData^,FN * SizeOf(Char));
3387*16467b97STreehugger Robot       end;
3388*16467b97STreehugger Robot     finally
3389*16467b97STreehugger Robot       FR.Free;
3390*16467b97STreehugger Robot     end;
3391*16467b97STreehugger Robot   end;
3392*16467b97STreehugger Robot end;
3393*16467b97STreehugger Robot 
3394*16467b97STreehugger Robot { TBitSet }
3395*16467b97STreehugger Robot 
TBitSet.BitSetOf(const El: Integer)3396*16467b97STreehugger Robot class function TBitSet.BitSetOf(const El: Integer): IBitSet;
3397*16467b97STreehugger Robot begin
3398*16467b97STreehugger Robot   Result := TBitSet.Create(El + 1);
3399*16467b97STreehugger Robot   Result.Add(El);
3400*16467b97STreehugger Robot end;
3401*16467b97STreehugger Robot 
TBitSet.BitSetOf(const A, B: Integer)3402*16467b97STreehugger Robot class function TBitSet.BitSetOf(const A, B: Integer): IBitSet;
3403*16467b97STreehugger Robot begin
3404*16467b97STreehugger Robot   Result := TBitSet.Create(Max(A,B) + 1);
3405*16467b97STreehugger Robot   Result.Add(A);
3406*16467b97STreehugger Robot   Result.Add(B);
3407*16467b97STreehugger Robot end;
3408*16467b97STreehugger Robot 
TBitSet.BitSetOf(const A, B, C: Integer)3409*16467b97STreehugger Robot class function TBitSet.BitSetOf(const A, B, C: Integer): IBitSet;
3410*16467b97STreehugger Robot begin
3411*16467b97STreehugger Robot   Result := TBitSet.Create;
3412*16467b97STreehugger Robot   Result.Add(A);
3413*16467b97STreehugger Robot   Result.Add(B);
3414*16467b97STreehugger Robot   Result.Add(C);
3415*16467b97STreehugger Robot end;
3416*16467b97STreehugger Robot 
TBitSet.BitSetOf(const A, B, C, D: Integer)3417*16467b97STreehugger Robot class function TBitSet.BitSetOf(const A, B, C, D: Integer): IBitSet;
3418*16467b97STreehugger Robot begin
3419*16467b97STreehugger Robot   Result := TBitSet.Create;
3420*16467b97STreehugger Robot   Result.Add(A);
3421*16467b97STreehugger Robot   Result.Add(B);
3422*16467b97STreehugger Robot   Result.Add(C);
3423*16467b97STreehugger Robot   Result.Add(D);
3424*16467b97STreehugger Robot end;
3425*16467b97STreehugger Robot 
3426*16467b97STreehugger Robot procedure TBitSet.Add(const El: Integer);
3427*16467b97STreehugger Robot var
3428*16467b97STreehugger Robot   N: Integer;
3429*16467b97STreehugger Robot begin
3430*16467b97STreehugger Robot   N := WordNumber(El);
3431*16467b97STreehugger Robot   if (N >= Length(FBits)) then
3432*16467b97STreehugger Robot     GrowToInclude(El);
3433*16467b97STreehugger Robot   FBits[N] := FBits[N] or BitMask(El);
3434*16467b97STreehugger Robot end;
3435*16467b97STreehugger Robot 
TBitSet.BitMask(const BitNumber: Integer)3436*16467b97STreehugger Robot class function TBitSet.BitMask(const BitNumber: Integer): UInt64;
3437*16467b97STreehugger Robot var
3438*16467b97STreehugger Robot   BitPosition: Integer;
3439*16467b97STreehugger Robot begin
3440*16467b97STreehugger Robot   BitPosition := BitNumber and MOD_MASK;
3441*16467b97STreehugger Robot   Result := UInt64(1) shl BitPosition;
3442*16467b97STreehugger Robot end;
3443*16467b97STreehugger Robot 
BitSetOrnull3444*16467b97STreehugger Robot function TBitSet.BitSetOr(const A: IBitSet): IBitSet;
3445*16467b97STreehugger Robot begin
3446*16467b97STreehugger Robot   Result := Clone as IBitSet;
3447*16467b97STreehugger Robot   Result.OrInPlace(A);
3448*16467b97STreehugger Robot end;
3449*16467b97STreehugger Robot 
TBitSet.Clone()3450*16467b97STreehugger Robot function TBitSet.Clone: IANTLRInterface;
3451*16467b97STreehugger Robot var
3452*16467b97STreehugger Robot   BS: TBitSet;
3453*16467b97STreehugger Robot begin
3454*16467b97STreehugger Robot   BS := TBitSet.Create;
3455*16467b97STreehugger Robot   Result := BS;
3456*16467b97STreehugger Robot   SetLength(BS.FBits,Length(FBits));
3457*16467b97STreehugger Robot   if (Length(FBits) > 0) then
3458*16467b97STreehugger Robot     Move(FBits[0],BS.FBits[0],Length(FBits) * SizeOf(UInt64));
3459*16467b97STreehugger Robot end;
3460*16467b97STreehugger Robot 
3461*16467b97STreehugger Robot constructor TBitSet.Create;
3462*16467b97STreehugger Robot begin
3463*16467b97STreehugger Robot   Create(BITS);
3464*16467b97STreehugger Robot end;
3465*16467b97STreehugger Robot 
3466*16467b97STreehugger Robot constructor TBitSet.Create(const ABits: array of UInt64);
3467*16467b97STreehugger Robot begin
3468*16467b97STreehugger Robot   inherited Create;
3469*16467b97STreehugger Robot   SetLength(FBits, Length(ABits));
3470*16467b97STreehugger Robot   if (Length(ABits) > 0) then
3471*16467b97STreehugger Robot     Move(ABits[0], FBits[0], Length(ABits) * SizeOf(UInt64));
3472*16467b97STreehugger Robot end;
3473*16467b97STreehugger Robot 
3474*16467b97STreehugger Robot constructor TBitSet.Create(const AItems: IList<Integer>);
3475*16467b97STreehugger Robot var
3476*16467b97STreehugger Robot   V: Integer;
3477*16467b97STreehugger Robot begin
3478*16467b97STreehugger Robot   Create(BITS);
3479*16467b97STreehugger Robot   for V in AItems do
3480*16467b97STreehugger Robot     Add(V);
3481*16467b97STreehugger Robot end;
3482*16467b97STreehugger Robot 
3483*16467b97STreehugger Robot constructor TBitSet.Create(const ANBits: Integer);
3484*16467b97STreehugger Robot begin
3485*16467b97STreehugger Robot   inherited Create;
3486*16467b97STreehugger Robot   SetLength(FBits,((ANBits - 1) shr LOG_BITS) + 1);
3487*16467b97STreehugger Robot end;
3488*16467b97STreehugger Robot 
Equalsnull3489*16467b97STreehugger Robot function TBitSet.Equals(Obj: TObject): Boolean;
3490*16467b97STreehugger Robot var
3491*16467b97STreehugger Robot   OtherSet: TBitSet absolute Obj;
3492*16467b97STreehugger Robot   I, N: Integer;
3493*16467b97STreehugger Robot begin
3494*16467b97STreehugger Robot   Result := False;
3495*16467b97STreehugger Robot   if (Obj = nil) or (not (Obj is TBitSet)) then
3496*16467b97STreehugger Robot     Exit;
3497*16467b97STreehugger Robot 
3498*16467b97STreehugger Robot   N := Min(Length(FBits), Length(OtherSet.FBits));
3499*16467b97STreehugger Robot 
3500*16467b97STreehugger Robot   // for any bits in common, compare
3501*16467b97STreehugger Robot   for I := 0 to N - 1 do
3502*16467b97STreehugger Robot   begin
3503*16467b97STreehugger Robot     if (FBits[I] <> OtherSet.FBits[I]) then
3504*16467b97STreehugger Robot       Exit;
3505*16467b97STreehugger Robot   end;
3506*16467b97STreehugger Robot 
3507*16467b97STreehugger Robot   // make sure any extra bits are off
3508*16467b97STreehugger Robot   if (Length(FBits) > N) then
3509*16467b97STreehugger Robot   begin
3510*16467b97STreehugger Robot     for I := N + 1 to Length(FBits) - 1 do
3511*16467b97STreehugger Robot     begin
3512*16467b97STreehugger Robot       if (FBits[I] <> 0) then
3513*16467b97STreehugger Robot         Exit;
3514*16467b97STreehugger Robot     end;
3515*16467b97STreehugger Robot   end
3516*16467b97STreehugger Robot   else
3517*16467b97STreehugger Robot     if (Length(OtherSet.FBits) > N) then
3518*16467b97STreehugger Robot     begin
3519*16467b97STreehugger Robot       for I := N + 1 to Length(OtherSet.FBits) - 1 do
3520*16467b97STreehugger Robot       begin
3521*16467b97STreehugger Robot         if (OtherSet.FBits[I] <> 0) then
3522*16467b97STreehugger Robot           Exit;
3523*16467b97STreehugger Robot       end;
3524*16467b97STreehugger Robot     end;
3525*16467b97STreehugger Robot 
3526*16467b97STreehugger Robot   Result := True;
3527*16467b97STreehugger Robot end;
3528*16467b97STreehugger Robot 
GetIsNilnull3529*16467b97STreehugger Robot function TBitSet.GetIsNil: Boolean;
3530*16467b97STreehugger Robot var
3531*16467b97STreehugger Robot   I: Integer;
3532*16467b97STreehugger Robot begin
3533*16467b97STreehugger Robot   for I := Length(FBits) - 1 downto 0 do
3534*16467b97STreehugger Robot     if (FBits[I] <> 0) then
3535*16467b97STreehugger Robot     begin
3536*16467b97STreehugger Robot       Result := False;
3537*16467b97STreehugger Robot       Exit;
3538*16467b97STreehugger Robot     end;
3539*16467b97STreehugger Robot   Result := True;
3540*16467b97STreehugger Robot end;
3541*16467b97STreehugger Robot 
3542*16467b97STreehugger Robot procedure TBitSet.GrowToInclude(const Bit: Integer);
3543*16467b97STreehugger Robot var
3544*16467b97STreehugger Robot   NewSize: Integer;
3545*16467b97STreehugger Robot begin
3546*16467b97STreehugger Robot   NewSize := Max(Length(FBits) shl 1,NumWordsToHold(Bit));
3547*16467b97STreehugger Robot   SetLength(FBits,NewSize);
3548*16467b97STreehugger Robot end;
3549*16467b97STreehugger Robot 
TBitSet.LengthInLongWords()3550*16467b97STreehugger Robot function TBitSet.LengthInLongWords: Integer;
3551*16467b97STreehugger Robot begin
3552*16467b97STreehugger Robot   Result := Length(FBits);
3553*16467b97STreehugger Robot end;
3554*16467b97STreehugger Robot 
TBitSet.Member(const El: Integer)3555*16467b97STreehugger Robot function TBitSet.Member(const El: Integer): Boolean;
3556*16467b97STreehugger Robot var
3557*16467b97STreehugger Robot   N: Integer;
3558*16467b97STreehugger Robot begin
3559*16467b97STreehugger Robot   if (El < 0) then
3560*16467b97STreehugger Robot     Result := False
3561*16467b97STreehugger Robot   else
3562*16467b97STreehugger Robot   begin
3563*16467b97STreehugger Robot     N := WordNumber(El);
3564*16467b97STreehugger Robot     if (N >= Length(FBits)) then
3565*16467b97STreehugger Robot       Result := False
3566*16467b97STreehugger Robot     else
3567*16467b97STreehugger Robot       Result := ((FBits[N] and BitMask(El)) <> 0);
3568*16467b97STreehugger Robot   end;
3569*16467b97STreehugger Robot end;
3570*16467b97STreehugger Robot 
NumBitsnull3571*16467b97STreehugger Robot function TBitSet.NumBits: Integer;
3572*16467b97STreehugger Robot begin
3573*16467b97STreehugger Robot   Result := Length(FBits) shl LOG_BITS;
3574*16467b97STreehugger Robot end;
3575*16467b97STreehugger Robot 
TBitSet.NumWordsToHold(const El: Integer)3576*16467b97STreehugger Robot class function TBitSet.NumWordsToHold(const El: Integer): Integer;
3577*16467b97STreehugger Robot begin
3578*16467b97STreehugger Robot   Result := (El shr LOG_BITS) + 1;
3579*16467b97STreehugger Robot end;
3580*16467b97STreehugger Robot 
3581*16467b97STreehugger Robot procedure TBitSet.OrInPlace(const A: IBitSet);
3582*16467b97STreehugger Robot var
3583*16467b97STreehugger Robot   I, M: Integer;
3584*16467b97STreehugger Robot   ABits: TUInt64Array;
3585*16467b97STreehugger Robot begin
3586*16467b97STreehugger Robot   if Assigned(A) then
3587*16467b97STreehugger Robot   begin
3588*16467b97STreehugger Robot     // If this is smaller than a, grow this first
3589*16467b97STreehugger Robot     if (A.LengthInLongWords > Length(FBits)) then
3590*16467b97STreehugger Robot       SetLength(FBits,A.LengthInLongWords);
3591*16467b97STreehugger Robot     M := Min(Length(FBits), A.LengthInLongWords);
3592*16467b97STreehugger Robot     ABits := A.ToPackedArray;
3593*16467b97STreehugger Robot     for I := M - 1 downto 0 do
3594*16467b97STreehugger Robot       FBits[I] := FBits[I] or ABits[I];
3595*16467b97STreehugger Robot   end;
3596*16467b97STreehugger Robot end;
3597*16467b97STreehugger Robot 
3598*16467b97STreehugger Robot procedure TBitSet.Remove(const El: Integer);
3599*16467b97STreehugger Robot var
3600*16467b97STreehugger Robot   N: Integer;
3601*16467b97STreehugger Robot begin
3602*16467b97STreehugger Robot   N := WordNumber(El);
3603*16467b97STreehugger Robot   if (N < Length(FBits)) then
3604*16467b97STreehugger Robot     FBits[N] := (FBits[N] and not BitMask(El));
3605*16467b97STreehugger Robot end;
3606*16467b97STreehugger Robot 
Sizenull3607*16467b97STreehugger Robot function TBitSet.Size: Integer;
3608*16467b97STreehugger Robot var
3609*16467b97STreehugger Robot   I, Bit: Integer;
3610*16467b97STreehugger Robot   W: UInt64;
3611*16467b97STreehugger Robot begin
3612*16467b97STreehugger Robot   Result := 0;
3613*16467b97STreehugger Robot   for I := Length(FBits) - 1 downto 0 do
3614*16467b97STreehugger Robot   begin
3615*16467b97STreehugger Robot     W := FBits[I];
3616*16467b97STreehugger Robot     if (W <> 0) then
3617*16467b97STreehugger Robot     begin
3618*16467b97STreehugger Robot       for Bit := BITS - 1 downto 0 do
3619*16467b97STreehugger Robot       begin
3620*16467b97STreehugger Robot         if ((W and (UInt64(1) shl Bit)) <> 0) then
3621*16467b97STreehugger Robot           Inc(Result);
3622*16467b97STreehugger Robot       end;
3623*16467b97STreehugger Robot     end;
3624*16467b97STreehugger Robot   end;
3625*16467b97STreehugger Robot end;
3626*16467b97STreehugger Robot 
ToArraynull3627*16467b97STreehugger Robot function TBitSet.ToArray: TIntegerArray;
3628*16467b97STreehugger Robot var
3629*16467b97STreehugger Robot   I, En: Integer;
3630*16467b97STreehugger Robot begin
3631*16467b97STreehugger Robot   SetLength(Result,Size);
3632*16467b97STreehugger Robot   En := 0;
3633*16467b97STreehugger Robot   for I := 0 to (Length(FBits) shl LOG_BITS) - 1 do
3634*16467b97STreehugger Robot   begin
3635*16467b97STreehugger Robot     if Member(I) then
3636*16467b97STreehugger Robot     begin
3637*16467b97STreehugger Robot       Result[En] := I;
3638*16467b97STreehugger Robot       Inc(En);
3639*16467b97STreehugger Robot     end;
3640*16467b97STreehugger Robot   end;
3641*16467b97STreehugger Robot end;
3642*16467b97STreehugger Robot 
TBitSet.ToPackedArray()3643*16467b97STreehugger Robot function TBitSet.ToPackedArray: TUInt64Array;
3644*16467b97STreehugger Robot begin
3645*16467b97STreehugger Robot   Result := FBits;
3646*16467b97STreehugger Robot end;
3647*16467b97STreehugger Robot 
TBitSet.ToString()3648*16467b97STreehugger Robot function TBitSet.ToString: String;
3649*16467b97STreehugger Robot begin
3650*16467b97STreehugger Robot   Result := ToString(nil);
3651*16467b97STreehugger Robot end;
3652*16467b97STreehugger Robot 
TBitSet.ToString(const TokenNames: TStringArray)3653*16467b97STreehugger Robot function TBitSet.ToString(const TokenNames: TStringArray): String;
3654*16467b97STreehugger Robot var
3655*16467b97STreehugger Robot   Buf: TStringBuilder;
3656*16467b97STreehugger Robot   I: Integer;
3657*16467b97STreehugger Robot   HavePrintedAnElement: Boolean;
3658*16467b97STreehugger Robot begin
3659*16467b97STreehugger Robot   HavePrintedAnElement := False;
3660*16467b97STreehugger Robot   Buf := TStringBuilder.Create;
3661*16467b97STreehugger Robot   try
3662*16467b97STreehugger Robot     Buf.Append('{');
3663*16467b97STreehugger Robot     for I := 0 to (Length(FBits) shl LOG_BITS) - 1 do
3664*16467b97STreehugger Robot     begin
3665*16467b97STreehugger Robot       if Member(I) then
3666*16467b97STreehugger Robot       begin
3667*16467b97STreehugger Robot         if (I > 0) and HavePrintedAnElement then
3668*16467b97STreehugger Robot           Buf.Append(',');
3669*16467b97STreehugger Robot         if Assigned(TokenNames) then
3670*16467b97STreehugger Robot           Buf.Append(TokenNames[I])
3671*16467b97STreehugger Robot         else
3672*16467b97STreehugger Robot           Buf.Append(I);
3673*16467b97STreehugger Robot         HavePrintedAnElement := True;
3674*16467b97STreehugger Robot       end;
3675*16467b97STreehugger Robot     end;
3676*16467b97STreehugger Robot     Buf.Append('}');
3677*16467b97STreehugger Robot     Result := Buf.ToString;
3678*16467b97STreehugger Robot   finally
3679*16467b97STreehugger Robot     Buf.Free;
3680*16467b97STreehugger Robot   end;
3681*16467b97STreehugger Robot end;
3682*16467b97STreehugger Robot 
TBitSet.WordNumber(const Bit: Integer)3683*16467b97STreehugger Robot class function TBitSet.WordNumber(const Bit: Integer): Integer;
3684*16467b97STreehugger Robot begin
3685*16467b97STreehugger Robot   Result := Bit shr LOG_BITS; // Bit / BITS
3686*16467b97STreehugger Robot end;
3687*16467b97STreehugger Robot 
3688*16467b97STreehugger Robot { TRecognizerSharedState }
3689*16467b97STreehugger Robot 
3690*16467b97STreehugger Robot constructor TRecognizerSharedState.Create;
3691*16467b97STreehugger Robot var
3692*16467b97STreehugger Robot   I: Integer;
3693*16467b97STreehugger Robot begin
3694*16467b97STreehugger Robot   inherited;
3695*16467b97STreehugger Robot   SetLength(FFollowing,TBaseRecognizer.INITIAL_FOLLOW_STACK_SIZE);
3696*16467b97STreehugger Robot   for I := 0 to TBaseRecognizer.INITIAL_FOLLOW_STACK_SIZE - 1 do
3697*16467b97STreehugger Robot     FFollowing[I] := TBitSet.Create;
3698*16467b97STreehugger Robot   FFollowingStackPointer := -1;
3699*16467b97STreehugger Robot   FLastErrorIndex := -1;
3700*16467b97STreehugger Robot   FTokenStartCharIndex := -1;
3701*16467b97STreehugger Robot end;
3702*16467b97STreehugger Robot 
TRecognizerSharedState.GetBacktracking()3703*16467b97STreehugger Robot function TRecognizerSharedState.GetBacktracking: Integer;
3704*16467b97STreehugger Robot begin
3705*16467b97STreehugger Robot   Result := FBacktracking;
3706*16467b97STreehugger Robot end;
3707*16467b97STreehugger Robot 
GetChannelnull3708*16467b97STreehugger Robot function TRecognizerSharedState.GetChannel: Integer;
3709*16467b97STreehugger Robot begin
3710*16467b97STreehugger Robot   Result := FChannel;
3711*16467b97STreehugger Robot end;
3712*16467b97STreehugger Robot 
GetErrorRecoverynull3713*16467b97STreehugger Robot function TRecognizerSharedState.GetErrorRecovery: Boolean;
3714*16467b97STreehugger Robot begin
3715*16467b97STreehugger Robot   Result := FErrorRecovery;
3716*16467b97STreehugger Robot end;
3717*16467b97STreehugger Robot 
GetFailednull3718*16467b97STreehugger Robot function TRecognizerSharedState.GetFailed: Boolean;
3719*16467b97STreehugger Robot begin
3720*16467b97STreehugger Robot   Result := FFailed;
3721*16467b97STreehugger Robot end;
3722*16467b97STreehugger Robot 
TRecognizerSharedState.GetFollowing()3723*16467b97STreehugger Robot function TRecognizerSharedState.GetFollowing: TBitSetArray;
3724*16467b97STreehugger Robot begin
3725*16467b97STreehugger Robot   Result := FFollowing;
3726*16467b97STreehugger Robot end;
3727*16467b97STreehugger Robot 
GetFollowingStackPointernull3728*16467b97STreehugger Robot function TRecognizerSharedState.GetFollowingStackPointer: Integer;
3729*16467b97STreehugger Robot begin
3730*16467b97STreehugger Robot   Result := FFollowingStackPointer;
3731*16467b97STreehugger Robot end;
3732*16467b97STreehugger Robot 
TRecognizerSharedState.GetLastErrorIndex()3733*16467b97STreehugger Robot function TRecognizerSharedState.GetLastErrorIndex: Integer;
3734*16467b97STreehugger Robot begin
3735*16467b97STreehugger Robot   Result := FLastErrorIndex;
3736*16467b97STreehugger Robot end;
3737*16467b97STreehugger Robot 
GetRuleMemonull3738*16467b97STreehugger Robot function TRecognizerSharedState.GetRuleMemo: TDictionaryArray<Integer, Integer>;
3739*16467b97STreehugger Robot begin
3740*16467b97STreehugger Robot   Result := FRuleMemo;
3741*16467b97STreehugger Robot end;
3742*16467b97STreehugger Robot 
TRecognizerSharedState.GetRuleMemoCount()3743*16467b97STreehugger Robot function TRecognizerSharedState.GetRuleMemoCount: Integer;
3744*16467b97STreehugger Robot begin
3745*16467b97STreehugger Robot   Result := Length(FRuleMemo);
3746*16467b97STreehugger Robot end;
3747*16467b97STreehugger Robot 
GetSyntaxErrorsnull3748*16467b97STreehugger Robot function TRecognizerSharedState.GetSyntaxErrors: Integer;
3749*16467b97STreehugger Robot begin
3750*16467b97STreehugger Robot   Result := FSyntaxErrors;
3751*16467b97STreehugger Robot end;
3752*16467b97STreehugger Robot 
GetTextnull3753*16467b97STreehugger Robot function TRecognizerSharedState.GetText: String;
3754*16467b97STreehugger Robot begin
3755*16467b97STreehugger Robot   Result := FText;
3756*16467b97STreehugger Robot end;
3757*16467b97STreehugger Robot 
TRecognizerSharedState.GetToken()3758*16467b97STreehugger Robot function TRecognizerSharedState.GetToken: IToken;
3759*16467b97STreehugger Robot begin
3760*16467b97STreehugger Robot   Result := FToken;
3761*16467b97STreehugger Robot end;
3762*16467b97STreehugger Robot 
GetTokenStartCharIndexnull3763*16467b97STreehugger Robot function TRecognizerSharedState.GetTokenStartCharIndex: Integer;
3764*16467b97STreehugger Robot begin
3765*16467b97STreehugger Robot   Result := FTokenStartCharIndex;
3766*16467b97STreehugger Robot end;
3767*16467b97STreehugger Robot 
GetTokenStartCharPositionInLinenull3768*16467b97STreehugger Robot function TRecognizerSharedState.GetTokenStartCharPositionInLine: Integer;
3769*16467b97STreehugger Robot begin
3770*16467b97STreehugger Robot   Result := FTokenStartCharPositionInLine;
3771*16467b97STreehugger Robot end;
3772*16467b97STreehugger Robot 
GetTokenStartLinenull3773*16467b97STreehugger Robot function TRecognizerSharedState.GetTokenStartLine: Integer;
3774*16467b97STreehugger Robot begin
3775*16467b97STreehugger Robot   Result := FTokenStartLine;
3776*16467b97STreehugger Robot end;
3777*16467b97STreehugger Robot 
GetTokenTypenull3778*16467b97STreehugger Robot function TRecognizerSharedState.GetTokenType: Integer;
3779*16467b97STreehugger Robot begin
3780*16467b97STreehugger Robot   Result := FTokenType;
3781*16467b97STreehugger Robot end;
3782*16467b97STreehugger Robot 
3783*16467b97STreehugger Robot procedure TRecognizerSharedState.SetBacktracking(const Value: Integer);
3784*16467b97STreehugger Robot begin
3785*16467b97STreehugger Robot   FBacktracking := Value;
3786*16467b97STreehugger Robot end;
3787*16467b97STreehugger Robot 
3788*16467b97STreehugger Robot procedure TRecognizerSharedState.SetChannel(const Value: Integer);
3789*16467b97STreehugger Robot begin
3790*16467b97STreehugger Robot   FChannel := Value;
3791*16467b97STreehugger Robot end;
3792*16467b97STreehugger Robot 
3793*16467b97STreehugger Robot procedure TRecognizerSharedState.SetErrorRecovery(const Value: Boolean);
3794*16467b97STreehugger Robot begin
3795*16467b97STreehugger Robot   FErrorRecovery := Value;
3796*16467b97STreehugger Robot end;
3797*16467b97STreehugger Robot 
3798*16467b97STreehugger Robot procedure TRecognizerSharedState.SetFailed(const Value: Boolean);
3799*16467b97STreehugger Robot begin
3800*16467b97STreehugger Robot   FFailed := Value;
3801*16467b97STreehugger Robot end;
3802*16467b97STreehugger Robot 
3803*16467b97STreehugger Robot procedure TRecognizerSharedState.SetFollowing(const Value: TBitSetArray);
3804*16467b97STreehugger Robot begin
3805*16467b97STreehugger Robot   FFollowing := Value;
3806*16467b97STreehugger Robot end;
3807*16467b97STreehugger Robot 
3808*16467b97STreehugger Robot procedure TRecognizerSharedState.SetFollowingStackPointer(const Value: Integer);
3809*16467b97STreehugger Robot begin
3810*16467b97STreehugger Robot   FFollowingStackPointer := Value;
3811*16467b97STreehugger Robot end;
3812*16467b97STreehugger Robot 
3813*16467b97STreehugger Robot procedure TRecognizerSharedState.SetLastErrorIndex(const Value: Integer);
3814*16467b97STreehugger Robot begin
3815*16467b97STreehugger Robot   FLastErrorIndex := Value;
3816*16467b97STreehugger Robot end;
3817*16467b97STreehugger Robot 
3818*16467b97STreehugger Robot procedure TRecognizerSharedState.SetRuleMemoCount(const Value: Integer);
3819*16467b97STreehugger Robot begin
3820*16467b97STreehugger Robot   SetLength(FRuleMemo, Value);
3821*16467b97STreehugger Robot end;
3822*16467b97STreehugger Robot 
3823*16467b97STreehugger Robot procedure TRecognizerSharedState.SetSyntaxErrors(const Value: Integer);
3824*16467b97STreehugger Robot begin
3825*16467b97STreehugger Robot   FSyntaxErrors := Value;
3826*16467b97STreehugger Robot end;
3827*16467b97STreehugger Robot 
3828*16467b97STreehugger Robot procedure TRecognizerSharedState.SetText(const Value: String);
3829*16467b97STreehugger Robot begin
3830*16467b97STreehugger Robot   FText := Value;
3831*16467b97STreehugger Robot end;
3832*16467b97STreehugger Robot 
3833*16467b97STreehugger Robot procedure TRecognizerSharedState.SetToken(const Value: IToken);
3834*16467b97STreehugger Robot begin
3835*16467b97STreehugger Robot   FToken := Value;
3836*16467b97STreehugger Robot end;
3837*16467b97STreehugger Robot 
3838*16467b97STreehugger Robot procedure TRecognizerSharedState.SetTokenStartCharIndex(const Value: Integer);
3839*16467b97STreehugger Robot begin
3840*16467b97STreehugger Robot   FTokenStartCharIndex := Value;
3841*16467b97STreehugger Robot end;
3842*16467b97STreehugger Robot 
3843*16467b97STreehugger Robot procedure TRecognizerSharedState.SetTokenStartCharPositionInLine(
3844*16467b97STreehugger Robot   const Value: Integer);
3845*16467b97STreehugger Robot begin
3846*16467b97STreehugger Robot   FTokenStartCharPositionInLine := Value;
3847*16467b97STreehugger Robot end;
3848*16467b97STreehugger Robot 
3849*16467b97STreehugger Robot procedure TRecognizerSharedState.SetTokenStartLine(const Value: Integer);
3850*16467b97STreehugger Robot begin
3851*16467b97STreehugger Robot   FTokenStartLine := Value;
3852*16467b97STreehugger Robot end;
3853*16467b97STreehugger Robot 
3854*16467b97STreehugger Robot procedure TRecognizerSharedState.SetTokenType(const Value: Integer);
3855*16467b97STreehugger Robot begin
3856*16467b97STreehugger Robot   FTokenType := Value;
3857*16467b97STreehugger Robot end;
3858*16467b97STreehugger Robot 
3859*16467b97STreehugger Robot { TCommonToken }
3860*16467b97STreehugger Robot 
3861*16467b97STreehugger Robot constructor TCommonToken.Create;
3862*16467b97STreehugger Robot begin
3863*16467b97STreehugger Robot   inherited;
3864*16467b97STreehugger Robot   FChannel := TToken.DEFAULT_CHANNEL;
3865*16467b97STreehugger Robot   FCharPositionInLine := -1;
3866*16467b97STreehugger Robot   FIndex := -1;
3867*16467b97STreehugger Robot end;
3868*16467b97STreehugger Robot 
3869*16467b97STreehugger Robot constructor TCommonToken.Create(const ATokenType: Integer);
3870*16467b97STreehugger Robot begin
3871*16467b97STreehugger Robot   Create;
3872*16467b97STreehugger Robot   FTokenType := ATokenType;
3873*16467b97STreehugger Robot end;
3874*16467b97STreehugger Robot 
3875*16467b97STreehugger Robot constructor TCommonToken.Create(const AInput: ICharStream; const ATokenType,
3876*16467b97STreehugger Robot   AChannel, AStart, AStop: Integer);
3877*16467b97STreehugger Robot begin
3878*16467b97STreehugger Robot   Create;
3879*16467b97STreehugger Robot   FInput := AInput;
3880*16467b97STreehugger Robot   FTokenType := ATokenType;
3881*16467b97STreehugger Robot   FChannel := AChannel;
3882*16467b97STreehugger Robot   FStart := AStart;
3883*16467b97STreehugger Robot   FStop := AStop;
3884*16467b97STreehugger Robot end;
3885*16467b97STreehugger Robot 
3886*16467b97STreehugger Robot constructor TCommonToken.Create(const ATokenType: Integer; const AText: String);
3887*16467b97STreehugger Robot begin
3888*16467b97STreehugger Robot   Create;
3889*16467b97STreehugger Robot   FTokenType := ATokenType;
3890*16467b97STreehugger Robot   FChannel := TToken.DEFAULT_CHANNEL;
3891*16467b97STreehugger Robot   FText := AText;
3892*16467b97STreehugger Robot end;
3893*16467b97STreehugger Robot 
TCommonToken.GetChannel()3894*16467b97STreehugger Robot function TCommonToken.GetChannel: Integer;
3895*16467b97STreehugger Robot begin
3896*16467b97STreehugger Robot   Result := FChannel;
3897*16467b97STreehugger Robot end;
3898*16467b97STreehugger Robot 
TCommonToken.GetCharPositionInLine()3899*16467b97STreehugger Robot function TCommonToken.GetCharPositionInLine: Integer;
3900*16467b97STreehugger Robot begin
3901*16467b97STreehugger Robot   Result := FCharPositionInLine;
3902*16467b97STreehugger Robot end;
3903*16467b97STreehugger Robot 
GetInputStreamnull3904*16467b97STreehugger Robot function TCommonToken.GetInputStream: ICharStream;
3905*16467b97STreehugger Robot begin
3906*16467b97STreehugger Robot   Result := FInput;
3907*16467b97STreehugger Robot end;
3908*16467b97STreehugger Robot 
GetLinenull3909*16467b97STreehugger Robot function TCommonToken.GetLine: Integer;
3910*16467b97STreehugger Robot begin
3911*16467b97STreehugger Robot   Result := FLine;
3912*16467b97STreehugger Robot end;
3913*16467b97STreehugger Robot 
GetStartIndexnull3914*16467b97STreehugger Robot function TCommonToken.GetStartIndex: Integer;
3915*16467b97STreehugger Robot begin
3916*16467b97STreehugger Robot   Result := FStart;
3917*16467b97STreehugger Robot end;
3918*16467b97STreehugger Robot 
GetStopIndexnull3919*16467b97STreehugger Robot function TCommonToken.GetStopIndex: Integer;
3920*16467b97STreehugger Robot begin
3921*16467b97STreehugger Robot   Result := FStop;
3922*16467b97STreehugger Robot end;
3923*16467b97STreehugger Robot 
GetTextnull3924*16467b97STreehugger Robot function TCommonToken.GetText: String;
3925*16467b97STreehugger Robot begin
3926*16467b97STreehugger Robot   if (FText <> '') then
3927*16467b97STreehugger Robot     Result := FText
3928*16467b97STreehugger Robot   else
3929*16467b97STreehugger Robot     if (FInput = nil) then
3930*16467b97STreehugger Robot       Result := ''
3931*16467b97STreehugger Robot     else
3932*16467b97STreehugger Robot       Result := FInput.Substring(FStart, FStop);
3933*16467b97STreehugger Robot end;
3934*16467b97STreehugger Robot 
GetTokenIndexnull3935*16467b97STreehugger Robot function TCommonToken.GetTokenIndex: Integer;
3936*16467b97STreehugger Robot begin
3937*16467b97STreehugger Robot   Result := FIndex;
3938*16467b97STreehugger Robot end;
3939*16467b97STreehugger Robot 
TCommonToken.GetTokenType()3940*16467b97STreehugger Robot function TCommonToken.GetTokenType: Integer;
3941*16467b97STreehugger Robot begin
3942*16467b97STreehugger Robot   Result := FTokenType;
3943*16467b97STreehugger Robot end;
3944*16467b97STreehugger Robot 
3945*16467b97STreehugger Robot procedure TCommonToken.SetChannel(const Value: Integer);
3946*16467b97STreehugger Robot begin
3947*16467b97STreehugger Robot   FChannel := Value;
3948*16467b97STreehugger Robot end;
3949*16467b97STreehugger Robot 
3950*16467b97STreehugger Robot procedure TCommonToken.SetCharPositionInLine(const Value: Integer);
3951*16467b97STreehugger Robot begin
3952*16467b97STreehugger Robot   FCharPositionInLine := Value;
3953*16467b97STreehugger Robot end;
3954*16467b97STreehugger Robot 
3955*16467b97STreehugger Robot procedure TCommonToken.SetInputStream(const Value: ICharStream);
3956*16467b97STreehugger Robot begin
3957*16467b97STreehugger Robot   FInput := Value;
3958*16467b97STreehugger Robot end;
3959*16467b97STreehugger Robot 
3960*16467b97STreehugger Robot procedure TCommonToken.SetLine(const Value: Integer);
3961*16467b97STreehugger Robot begin
3962*16467b97STreehugger Robot   FLine := Value;
3963*16467b97STreehugger Robot end;
3964*16467b97STreehugger Robot 
3965*16467b97STreehugger Robot procedure TCommonToken.SetStartIndex(const Value: Integer);
3966*16467b97STreehugger Robot begin
3967*16467b97STreehugger Robot   FStart := Value;
3968*16467b97STreehugger Robot end;
3969*16467b97STreehugger Robot 
3970*16467b97STreehugger Robot procedure TCommonToken.SetStopIndex(const Value: Integer);
3971*16467b97STreehugger Robot begin
3972*16467b97STreehugger Robot   FStop := Value;
3973*16467b97STreehugger Robot end;
3974*16467b97STreehugger Robot 
3975*16467b97STreehugger Robot procedure TCommonToken.SetText(const Value: String);
3976*16467b97STreehugger Robot begin
3977*16467b97STreehugger Robot   (* Override the text for this token.  The property getter
3978*16467b97STreehugger Robot    * will return this text rather than pulling from the buffer.
3979*16467b97STreehugger Robot    * Note that this does not mean that start/stop indexes are
3980*16467b97STreehugger Robot    * not valid.  It means that the input was converted to a new
3981*16467b97STreehugger Robot    * string in the token object.
3982*16467b97STreehugger Robot    *)
3983*16467b97STreehugger Robot   FText := Value;
3984*16467b97STreehugger Robot end;
3985*16467b97STreehugger Robot 
3986*16467b97STreehugger Robot procedure TCommonToken.SetTokenIndex(const Value: Integer);
3987*16467b97STreehugger Robot begin
3988*16467b97STreehugger Robot   FIndex := Value;
3989*16467b97STreehugger Robot end;
3990*16467b97STreehugger Robot 
3991*16467b97STreehugger Robot procedure TCommonToken.SetTokenType(const Value: Integer);
3992*16467b97STreehugger Robot begin
3993*16467b97STreehugger Robot   FTokenType := Value;
3994*16467b97STreehugger Robot end;
3995*16467b97STreehugger Robot 
ToStringnull3996*16467b97STreehugger Robot function TCommonToken.ToString: String;
3997*16467b97STreehugger Robot var
3998*16467b97STreehugger Robot   ChannelStr, Txt: String;
3999*16467b97STreehugger Robot begin
4000*16467b97STreehugger Robot   if (FChannel > 0) then
4001*16467b97STreehugger Robot     ChannelStr := ',channel=' + IntToStr(FChannel)
4002*16467b97STreehugger Robot   else
4003*16467b97STreehugger Robot     ChannelStr := '';
4004*16467b97STreehugger Robot 
4005*16467b97STreehugger Robot   Txt := GetText;
4006*16467b97STreehugger Robot   if (Txt <> '') then
4007*16467b97STreehugger Robot   begin
4008*16467b97STreehugger Robot     Txt := ReplaceStr(Txt,#10,'\n');
4009*16467b97STreehugger Robot     Txt := ReplaceStr(Txt,#13,'\r');
4010*16467b97STreehugger Robot     Txt := ReplaceStr(Txt,#9,'\t');
4011*16467b97STreehugger Robot   end else
4012*16467b97STreehugger Robot     Txt := '<no text>';
4013*16467b97STreehugger Robot 
4014*16467b97STreehugger Robot   Result := Format('[@%d,%d:%d=''%s'',<%d>%s,%d:%d]',
4015*16467b97STreehugger Robot     [FIndex,FStart,FStop,Txt,FTokenType,ChannelStr,FLine,FCharPositionInLine]);
4016*16467b97STreehugger Robot end;
4017*16467b97STreehugger Robot 
4018*16467b97STreehugger Robot constructor TCommonToken.Create(const AOldToken: IToken);
4019*16467b97STreehugger Robot var
4020*16467b97STreehugger Robot   OldCommonToken: ICommonToken;
4021*16467b97STreehugger Robot begin
4022*16467b97STreehugger Robot   Create;
4023*16467b97STreehugger Robot   FText := AOldToken.Text;
4024*16467b97STreehugger Robot   FTokenType := AOldToken.TokenType;
4025*16467b97STreehugger Robot   FLine := AOldToken.Line;
4026*16467b97STreehugger Robot   FIndex := AOldToken.TokenIndex;
4027*16467b97STreehugger Robot   FCharPositionInLine := AOldToken.CharPositionInLine;
4028*16467b97STreehugger Robot   FChannel := AOldToken.Channel;
4029*16467b97STreehugger Robot   if Supports(AOldToken, ICommonToken, OldCommonToken) then
4030*16467b97STreehugger Robot   begin
4031*16467b97STreehugger Robot     FStart := OldCommonToken.StartIndex;
4032*16467b97STreehugger Robot     FStop := OldCommonToken.StopIndex;
4033*16467b97STreehugger Robot   end;
4034*16467b97STreehugger Robot end;
4035*16467b97STreehugger Robot 
4036*16467b97STreehugger Robot { TClassicToken }
4037*16467b97STreehugger Robot 
4038*16467b97STreehugger Robot constructor TClassicToken.Create(const AOldToken: IToken);
4039*16467b97STreehugger Robot begin
4040*16467b97STreehugger Robot   inherited Create;
4041*16467b97STreehugger Robot   FText := AOldToken.Text;
4042*16467b97STreehugger Robot   FTokenType := AOldToken.TokenType;
4043*16467b97STreehugger Robot   FLine := AOldToken.Line;
4044*16467b97STreehugger Robot   FCharPositionInLine := AOldToken.CharPositionInLine;
4045*16467b97STreehugger Robot   FChannel := AOldToken.Channel;
4046*16467b97STreehugger Robot end;
4047*16467b97STreehugger Robot 
4048*16467b97STreehugger Robot constructor TClassicToken.Create(const ATokenType: Integer);
4049*16467b97STreehugger Robot begin
4050*16467b97STreehugger Robot   inherited Create;
4051*16467b97STreehugger Robot   FTokenType := ATokenType;
4052*16467b97STreehugger Robot end;
4053*16467b97STreehugger Robot 
4054*16467b97STreehugger Robot constructor TClassicToken.Create(const ATokenType: Integer; const AText: String;
4055*16467b97STreehugger Robot   const AChannel: Integer);
4056*16467b97STreehugger Robot begin
4057*16467b97STreehugger Robot   inherited Create;
4058*16467b97STreehugger Robot   FTokenType := ATokenType;
4059*16467b97STreehugger Robot   FText := AText;
4060*16467b97STreehugger Robot   FChannel := AChannel;
4061*16467b97STreehugger Robot end;
4062*16467b97STreehugger Robot 
4063*16467b97STreehugger Robot constructor TClassicToken.Create(const ATokenType: Integer;
4064*16467b97STreehugger Robot   const AText: String);
4065*16467b97STreehugger Robot begin
4066*16467b97STreehugger Robot   inherited Create;
4067*16467b97STreehugger Robot   FTokenType := ATokenType;
4068*16467b97STreehugger Robot   FText := AText;
4069*16467b97STreehugger Robot end;
4070*16467b97STreehugger Robot 
GetChannelnull4071*16467b97STreehugger Robot function TClassicToken.GetChannel: Integer;
4072*16467b97STreehugger Robot begin
4073*16467b97STreehugger Robot   Result := FChannel;
4074*16467b97STreehugger Robot end;
4075*16467b97STreehugger Robot 
GetCharPositionInLinenull4076*16467b97STreehugger Robot function TClassicToken.GetCharPositionInLine: Integer;
4077*16467b97STreehugger Robot begin
4078*16467b97STreehugger Robot   Result := FCharPositionInLine;
4079*16467b97STreehugger Robot end;
4080*16467b97STreehugger Robot 
GetInputStreamnull4081*16467b97STreehugger Robot function TClassicToken.GetInputStream: ICharStream;
4082*16467b97STreehugger Robot begin
4083*16467b97STreehugger Robot   // No default implementation
4084*16467b97STreehugger Robot   Result := nil;
4085*16467b97STreehugger Robot end;
4086*16467b97STreehugger Robot 
GetLinenull4087*16467b97STreehugger Robot function TClassicToken.GetLine: Integer;
4088*16467b97STreehugger Robot begin
4089*16467b97STreehugger Robot   Result := FLine;
4090*16467b97STreehugger Robot end;
4091*16467b97STreehugger Robot 
GetTextnull4092*16467b97STreehugger Robot function TClassicToken.GetText: String;
4093*16467b97STreehugger Robot begin
4094*16467b97STreehugger Robot   Result := FText;
4095*16467b97STreehugger Robot end;
4096*16467b97STreehugger Robot 
TClassicToken.GetTokenIndex()4097*16467b97STreehugger Robot function TClassicToken.GetTokenIndex: Integer;
4098*16467b97STreehugger Robot begin
4099*16467b97STreehugger Robot   Result := FIndex;
4100*16467b97STreehugger Robot end;
4101*16467b97STreehugger Robot 
TClassicToken.GetTokenType()4102*16467b97STreehugger Robot function TClassicToken.GetTokenType: Integer;
4103*16467b97STreehugger Robot begin
4104*16467b97STreehugger Robot   Result := FTokenType;
4105*16467b97STreehugger Robot end;
4106*16467b97STreehugger Robot 
4107*16467b97STreehugger Robot procedure TClassicToken.SetChannel(const Value: Integer);
4108*16467b97STreehugger Robot begin
4109*16467b97STreehugger Robot   FChannel := Value;
4110*16467b97STreehugger Robot end;
4111*16467b97STreehugger Robot 
4112*16467b97STreehugger Robot procedure TClassicToken.SetCharPositionInLine(const Value: Integer);
4113*16467b97STreehugger Robot begin
4114*16467b97STreehugger Robot   FCharPositionInLine := Value;
4115*16467b97STreehugger Robot end;
4116*16467b97STreehugger Robot 
4117*16467b97STreehugger Robot procedure TClassicToken.SetInputStream(const Value: ICharStream);
4118*16467b97STreehugger Robot begin
4119*16467b97STreehugger Robot   // No default implementation
4120*16467b97STreehugger Robot end;
4121*16467b97STreehugger Robot 
4122*16467b97STreehugger Robot procedure TClassicToken.SetLine(const Value: Integer);
4123*16467b97STreehugger Robot begin
4124*16467b97STreehugger Robot   FLine := Value;
4125*16467b97STreehugger Robot end;
4126*16467b97STreehugger Robot 
4127*16467b97STreehugger Robot procedure TClassicToken.SetText(const Value: String);
4128*16467b97STreehugger Robot begin
4129*16467b97STreehugger Robot   FText := Value;
4130*16467b97STreehugger Robot end;
4131*16467b97STreehugger Robot 
4132*16467b97STreehugger Robot procedure TClassicToken.SetTokenIndex(const Value: Integer);
4133*16467b97STreehugger Robot begin
4134*16467b97STreehugger Robot   FIndex := Value;
4135*16467b97STreehugger Robot end;
4136*16467b97STreehugger Robot 
4137*16467b97STreehugger Robot procedure TClassicToken.SetTokenType(const Value: Integer);
4138*16467b97STreehugger Robot begin
4139*16467b97STreehugger Robot   FTokenType := Value;
4140*16467b97STreehugger Robot end;
4141*16467b97STreehugger Robot 
ToStringnull4142*16467b97STreehugger Robot function TClassicToken.ToString: String;
4143*16467b97STreehugger Robot var
4144*16467b97STreehugger Robot   ChannelStr, Txt: String;
4145*16467b97STreehugger Robot begin
4146*16467b97STreehugger Robot   if (FChannel > 0) then
4147*16467b97STreehugger Robot     ChannelStr := ',channel=' + IntToStr(FChannel)
4148*16467b97STreehugger Robot   else
4149*16467b97STreehugger Robot     ChannelStr := '';
4150*16467b97STreehugger Robot   Txt := FText;
4151*16467b97STreehugger Robot   if (Txt <> '') then
4152*16467b97STreehugger Robot   begin
4153*16467b97STreehugger Robot     Txt := ReplaceStr(Txt,#10,'\n');
4154*16467b97STreehugger Robot     Txt := ReplaceStr(Txt,#13,'\r');
4155*16467b97STreehugger Robot     Txt := ReplaceStr(Txt,#9,'\t');
4156*16467b97STreehugger Robot   end else
4157*16467b97STreehugger Robot     Txt := '<no text>';
4158*16467b97STreehugger Robot 
4159*16467b97STreehugger Robot   Result := Format('[@%d,''%s'',<%d>%s,%d:%d]',
4160*16467b97STreehugger Robot     [FIndex,Txt,FTokenType,ChannelStr,FLine,FCharPositionInLine]);
4161*16467b97STreehugger Robot end;
4162*16467b97STreehugger Robot 
4163*16467b97STreehugger Robot { TToken }
4164*16467b97STreehugger Robot 
4165*16467b97STreehugger Robot class procedure TToken.Initialize;
4166*16467b97STreehugger Robot begin
4167*16467b97STreehugger Robot   EOF_TOKEN := TCommonToken.Create(EOF);
4168*16467b97STreehugger Robot   INVALID_TOKEN := TCommonToken.Create(INVALID_TOKEN_TYPE);
4169*16467b97STreehugger Robot   SKIP_TOKEN := TCommonToken.Create(INVALID_TOKEN_TYPE);
4170*16467b97STreehugger Robot end;
4171*16467b97STreehugger Robot 
4172*16467b97STreehugger Robot { TBaseRecognizer }
4173*16467b97STreehugger Robot 
4174*16467b97STreehugger Robot constructor TBaseRecognizer.Create;
4175*16467b97STreehugger Robot begin
4176*16467b97STreehugger Robot   inherited;
4177*16467b97STreehugger Robot   FState := TRecognizerSharedState.Create;
4178*16467b97STreehugger Robot end;
4179*16467b97STreehugger Robot 
TBaseRecognizer.AlreadyParsedRule(const Input: IIntStream;4180*16467b97STreehugger Robot function TBaseRecognizer.AlreadyParsedRule(const Input: IIntStream;
4181*16467b97STreehugger Robot   const RuleIndex: Integer): Boolean;
4182*16467b97STreehugger Robot var
4183*16467b97STreehugger Robot   StopIndex: Integer;
4184*16467b97STreehugger Robot begin
4185*16467b97STreehugger Robot   StopIndex := GetRuleMemoization(RuleIndex, Input.Index);
4186*16467b97STreehugger Robot   Result := (StopIndex <> MEMO_RULE_UNKNOWN);
4187*16467b97STreehugger Robot   if Result then
4188*16467b97STreehugger Robot   begin
4189*16467b97STreehugger Robot     if (StopIndex = MEMO_RULE_FAILED) then
4190*16467b97STreehugger Robot       FState.Failed := True
4191*16467b97STreehugger Robot     else
4192*16467b97STreehugger Robot       Input.Seek(StopIndex + 1);  // jump to one past stop token
4193*16467b97STreehugger Robot   end;
4194*16467b97STreehugger Robot end;
4195*16467b97STreehugger Robot 
4196*16467b97STreehugger Robot procedure TBaseRecognizer.BeginBacktrack(const Level: Integer);
4197*16467b97STreehugger Robot begin
4198*16467b97STreehugger Robot   // No defeault implementation
4199*16467b97STreehugger Robot end;
4200*16467b97STreehugger Robot 
4201*16467b97STreehugger Robot procedure TBaseRecognizer.BeginResync;
4202*16467b97STreehugger Robot begin
4203*16467b97STreehugger Robot   // No defeault implementation
4204*16467b97STreehugger Robot end;
4205*16467b97STreehugger Robot 
4206*16467b97STreehugger Robot procedure TBaseRecognizer.ConsumeUntil(const Input: IIntStream;
4207*16467b97STreehugger Robot   const TokenType: Integer);
4208*16467b97STreehugger Robot var
4209*16467b97STreehugger Robot   TType: Integer;
4210*16467b97STreehugger Robot begin
4211*16467b97STreehugger Robot   TType := Input.LA(1);
4212*16467b97STreehugger Robot   while (TType <> TToken.EOF) and (TType <> TokenType) do
4213*16467b97STreehugger Robot   begin
4214*16467b97STreehugger Robot     Input.Consume;
4215*16467b97STreehugger Robot     TType := Input.LA(1);
4216*16467b97STreehugger Robot   end;
4217*16467b97STreehugger Robot end;
4218*16467b97STreehugger Robot 
TBaseRecognizer.CombineFollows(const Exact: Boolean)4219*16467b97STreehugger Robot function TBaseRecognizer.CombineFollows(const Exact: Boolean): IBitSet;
4220*16467b97STreehugger Robot var
4221*16467b97STreehugger Robot   I, Top: Integer;
4222*16467b97STreehugger Robot   LocalFollowSet: IBitSet;
4223*16467b97STreehugger Robot begin
4224*16467b97STreehugger Robot   Top := FState.FollowingStackPointer;
4225*16467b97STreehugger Robot   Result := TBitSet.Create;
4226*16467b97STreehugger Robot   for I := Top downto 0 do
4227*16467b97STreehugger Robot   begin
4228*16467b97STreehugger Robot     LocalFollowSet := FState.Following[I];
4229*16467b97STreehugger Robot     Result.OrInPlace(LocalFollowSet);
4230*16467b97STreehugger Robot     if (Exact) then
4231*16467b97STreehugger Robot     begin
4232*16467b97STreehugger Robot       // can we see end of rule?
4233*16467b97STreehugger Robot       if LocalFollowSet.Member(TToken.EOR_TOKEN_TYPE) then
4234*16467b97STreehugger Robot       begin
4235*16467b97STreehugger Robot         // Only leave EOR in set if at top (start rule); this lets
4236*16467b97STreehugger Robot         // us know if have to include follow(start rule); i.e., EOF
4237*16467b97STreehugger Robot         if (I > 0) then
4238*16467b97STreehugger Robot           Result.Remove(TToken.EOR_TOKEN_TYPE);
4239*16467b97STreehugger Robot       end
4240*16467b97STreehugger Robot       else
4241*16467b97STreehugger Robot         // can't see end of rule, quit
4242*16467b97STreehugger Robot         Break;
4243*16467b97STreehugger Robot     end;
4244*16467b97STreehugger Robot   end;
4245*16467b97STreehugger Robot end;
4246*16467b97STreehugger Robot 
ComputeContextSensitiveRuleFOLLOWnull4247*16467b97STreehugger Robot function TBaseRecognizer.ComputeContextSensitiveRuleFOLLOW: IBitSet;
4248*16467b97STreehugger Robot begin
4249*16467b97STreehugger Robot   Result := CombineFollows(True);
4250*16467b97STreehugger Robot end;
4251*16467b97STreehugger Robot 
TBaseRecognizer.ComputeErrorRecoverySet()4252*16467b97STreehugger Robot function TBaseRecognizer.ComputeErrorRecoverySet: IBitSet;
4253*16467b97STreehugger Robot begin
4254*16467b97STreehugger Robot   Result := CombineFollows(False);
4255*16467b97STreehugger Robot end;
4256*16467b97STreehugger Robot 
4257*16467b97STreehugger Robot procedure TBaseRecognizer.ConsumeUntil(const Input: IIntStream;
4258*16467b97STreehugger Robot   const BitSet: IBitSet);
4259*16467b97STreehugger Robot var
4260*16467b97STreehugger Robot   TType: Integer;
4261*16467b97STreehugger Robot begin
4262*16467b97STreehugger Robot   TType := Input.LA(1);
4263*16467b97STreehugger Robot   while (TType <> TToken.EOF) and (not BitSet.Member(TType)) do
4264*16467b97STreehugger Robot   begin
4265*16467b97STreehugger Robot     Input.Consume;
4266*16467b97STreehugger Robot     TType := Input.LA(1);
4267*16467b97STreehugger Robot   end;
4268*16467b97STreehugger Robot end;
4269*16467b97STreehugger Robot 
4270*16467b97STreehugger Robot constructor TBaseRecognizer.Create(const AState: IRecognizerSharedState);
4271*16467b97STreehugger Robot begin
4272*16467b97STreehugger Robot   if (AState = nil) then
4273*16467b97STreehugger Robot     Create
4274*16467b97STreehugger Robot   else
4275*16467b97STreehugger Robot   begin
4276*16467b97STreehugger Robot     inherited Create;
4277*16467b97STreehugger Robot     FState := AState;
4278*16467b97STreehugger Robot   end;
4279*16467b97STreehugger Robot end;
4280*16467b97STreehugger Robot 
4281*16467b97STreehugger Robot procedure TBaseRecognizer.DisplayRecognitionError(
4282*16467b97STreehugger Robot   const TokenNames: TStringArray; const E: ERecognitionException);
4283*16467b97STreehugger Robot var
4284*16467b97STreehugger Robot   Hdr, Msg: String;
4285*16467b97STreehugger Robot begin
4286*16467b97STreehugger Robot   Hdr := GetErrorHeader(E);
4287*16467b97STreehugger Robot   Msg := GetErrorMessage(E, TokenNames);
4288*16467b97STreehugger Robot   EmitErrorMessage(Hdr + ' ' + Msg);
4289*16467b97STreehugger Robot end;
4290*16467b97STreehugger Robot 
4291*16467b97STreehugger Robot procedure TBaseRecognizer.EmitErrorMessage(const Msg: String);
4292*16467b97STreehugger Robot begin
4293*16467b97STreehugger Robot   WriteLn(Msg);
4294*16467b97STreehugger Robot end;
4295*16467b97STreehugger Robot 
4296*16467b97STreehugger Robot procedure TBaseRecognizer.EndBacktrack(const Level: Integer;
4297*16467b97STreehugger Robot   const Successful: Boolean);
4298*16467b97STreehugger Robot begin
4299*16467b97STreehugger Robot   // No defeault implementation
4300*16467b97STreehugger Robot end;
4301*16467b97STreehugger Robot 
4302*16467b97STreehugger Robot procedure TBaseRecognizer.EndResync;
4303*16467b97STreehugger Robot begin
4304*16467b97STreehugger Robot   // No defeault implementation
4305*16467b97STreehugger Robot end;
4306*16467b97STreehugger Robot 
GetBacktrackingLevelnull4307*16467b97STreehugger Robot function TBaseRecognizer.GetBacktrackingLevel: Integer;
4308*16467b97STreehugger Robot begin
4309*16467b97STreehugger Robot   Result := FState.Backtracking;
4310*16467b97STreehugger Robot end;
4311*16467b97STreehugger Robot 
TBaseRecognizer.GetCurrentInputSymbol(4312*16467b97STreehugger Robot function TBaseRecognizer.GetCurrentInputSymbol(
4313*16467b97STreehugger Robot   const Input: IIntStream): IANTLRInterface;
4314*16467b97STreehugger Robot begin
4315*16467b97STreehugger Robot   // No defeault implementation
4316*16467b97STreehugger Robot   Result := nil;
4317*16467b97STreehugger Robot end;
4318*16467b97STreehugger Robot 
GetErrorHeadernull4319*16467b97STreehugger Robot function TBaseRecognizer.GetErrorHeader(const E: ERecognitionException): String;
4320*16467b97STreehugger Robot begin
4321*16467b97STreehugger Robot   Result := 'line ' + IntToStr(E.Line) + ':' + IntToStr(E.CharPositionInLine);
4322*16467b97STreehugger Robot end;
4323*16467b97STreehugger Robot 
TBaseRecognizer.GetErrorMessage(const E: ERecognitionException;4324*16467b97STreehugger Robot function TBaseRecognizer.GetErrorMessage(const E: ERecognitionException;
4325*16467b97STreehugger Robot   const TokenNames: TStringArray): String;
4326*16467b97STreehugger Robot var
4327*16467b97STreehugger Robot   UTE: EUnwantedTokenException absolute E;
4328*16467b97STreehugger Robot   MTE: EMissingTokenException absolute E;
4329*16467b97STreehugger Robot   MMTE: EMismatchedTokenException absolute E;
4330*16467b97STreehugger Robot   MTNE: EMismatchedTreeNodeException absolute E;
4331*16467b97STreehugger Robot   NVAE: ENoViableAltException absolute E;
4332*16467b97STreehugger Robot   EEE: EEarlyExitException absolute E;
4333*16467b97STreehugger Robot   MSE: EMismatchedSetException absolute E;
4334*16467b97STreehugger Robot   MNSE: EMismatchedNotSetException absolute E;
4335*16467b97STreehugger Robot   FPE: EFailedPredicateException absolute E;
4336*16467b97STreehugger Robot   TokenName: String;
4337*16467b97STreehugger Robot begin
4338*16467b97STreehugger Robot   Result := E.Message;
4339*16467b97STreehugger Robot   if (E is EUnwantedTokenException) then
4340*16467b97STreehugger Robot   begin
4341*16467b97STreehugger Robot     if (UTE.Expecting = TToken.EOF) then
4342*16467b97STreehugger Robot       TokenName := 'EOF'
4343*16467b97STreehugger Robot     else
4344*16467b97STreehugger Robot       TokenName := TokenNames[UTE.Expecting];
4345*16467b97STreehugger Robot     Result := 'extraneous input ' + GetTokenErrorDisplay(UTE.UnexpectedToken)
4346*16467b97STreehugger Robot       + ' expecting ' + TokenName;
4347*16467b97STreehugger Robot   end
4348*16467b97STreehugger Robot   else
4349*16467b97STreehugger Robot     if (E is EMissingTokenException) then
4350*16467b97STreehugger Robot     begin
4351*16467b97STreehugger Robot       if (MTE.Expecting = TToken.EOF) then
4352*16467b97STreehugger Robot         TokenName := 'EOF'
4353*16467b97STreehugger Robot       else
4354*16467b97STreehugger Robot         TokenName := TokenNames[MTE.Expecting];
4355*16467b97STreehugger Robot       Result := 'missing ' + TokenName + ' at ' + GetTokenErrorDisplay(E.Token);
4356*16467b97STreehugger Robot     end
4357*16467b97STreehugger Robot     else
4358*16467b97STreehugger Robot       if (E is EMismatchedTokenException) then
4359*16467b97STreehugger Robot       begin
4360*16467b97STreehugger Robot         if (MMTE.Expecting = TToken.EOF) then
4361*16467b97STreehugger Robot           TokenName := 'EOF'
4362*16467b97STreehugger Robot         else
4363*16467b97STreehugger Robot           TokenName := TokenNames[MMTE.Expecting];
4364*16467b97STreehugger Robot         Result := 'mismatched input ' + GetTokenErrorDisplay(E.Token)
4365*16467b97STreehugger Robot           + ' expecting ' + TokenName;
4366*16467b97STreehugger Robot       end
4367*16467b97STreehugger Robot       else
4368*16467b97STreehugger Robot         if (E is EMismatchedTreeNodeException) then
4369*16467b97STreehugger Robot         begin
4370*16467b97STreehugger Robot           if (MTNE.Expecting = TToken.EOF) then
4371*16467b97STreehugger Robot             Result := 'EOF'
4372*16467b97STreehugger Robot           else
4373*16467b97STreehugger Robot             Result := TokenNames[MTNE.Expecting];
4374*16467b97STreehugger Robot           // The ternary operator is only necessary because of a bug in the .NET framework
4375*16467b97STreehugger Robot           Result := 'mismatched tree node: ';
4376*16467b97STreehugger Robot           if (MTNE.Node <> nil) and (MTNE.Node.ToString <> '') then
4377*16467b97STreehugger Robot             Result := Result + MTNE.Node.ToString;
4378*16467b97STreehugger Robot           Result := Result + ' expecting ' + TokenName;
4379*16467b97STreehugger Robot         end
4380*16467b97STreehugger Robot         else
4381*16467b97STreehugger Robot           if (E is ENoViableAltException) then
4382*16467b97STreehugger Robot           begin
4383*16467b97STreehugger Robot             // for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>"
4384*16467b97STreehugger Robot             // and "(decision="+nvae.decisionNumber+") and
4385*16467b97STreehugger Robot             // "state "+nvae.stateNumber
4386*16467b97STreehugger Robot             Result := 'no viable alternative at input ' + GetTokenErrorDisplay(E.Token);
4387*16467b97STreehugger Robot           end
4388*16467b97STreehugger Robot           else
4389*16467b97STreehugger Robot             if (E is EEarlyExitException) then
4390*16467b97STreehugger Robot             begin
4391*16467b97STreehugger Robot               // for development, can add "(decision="+eee.decisionNumber+")"
4392*16467b97STreehugger Robot               Result := 'required (...)+ loop did not  match anyting at input '
4393*16467b97STreehugger Robot                 + GetTokenErrorDisplay(E.Token);
4394*16467b97STreehugger Robot             end else
4395*16467b97STreehugger Robot               if (E is EMismatchedSetException) then
4396*16467b97STreehugger Robot               begin
4397*16467b97STreehugger Robot                 Result := 'mismatched input ' + GetTokenErrorDisplay(E.Token)
4398*16467b97STreehugger Robot                   + ' expecting set ' + MSE.Expecting.ToString;
4399*16467b97STreehugger Robot               end
4400*16467b97STreehugger Robot               else
4401*16467b97STreehugger Robot                 if (E is EMismatchedNotSetException) then
4402*16467b97STreehugger Robot                 begin
4403*16467b97STreehugger Robot                   Result := 'mismatched input ' + GetTokenErrorDisplay(E.Token)
4404*16467b97STreehugger Robot                     + ' expecting set ' + MSE.Expecting.ToString;
4405*16467b97STreehugger Robot                 end
4406*16467b97STreehugger Robot                 else
4407*16467b97STreehugger Robot                   if (E is EFailedPredicateException) then
4408*16467b97STreehugger Robot                   begin
4409*16467b97STreehugger Robot                     Result := 'rule ' + FPE.RuleName
4410*16467b97STreehugger Robot                       + ' failed predicate: {' + FPE.PredicateText + '}?';
4411*16467b97STreehugger Robot                   end;
4412*16467b97STreehugger Robot end;
4413*16467b97STreehugger Robot 
TBaseRecognizer.GetGrammarFileName()4414*16467b97STreehugger Robot function TBaseRecognizer.GetGrammarFileName: String;
4415*16467b97STreehugger Robot begin
4416*16467b97STreehugger Robot   // No defeault implementation
4417*16467b97STreehugger Robot   Result := '';
4418*16467b97STreehugger Robot end;
4419*16467b97STreehugger Robot 
TBaseRecognizer.GetMissingSymbol(const Input: IIntStream;4420*16467b97STreehugger Robot function TBaseRecognizer.GetMissingSymbol(const Input: IIntStream;
4421*16467b97STreehugger Robot   const E: ERecognitionException; const ExpectedTokenType: Integer;
4422*16467b97STreehugger Robot   const Follow: IBitSet): IANTLRInterface;
4423*16467b97STreehugger Robot begin
4424*16467b97STreehugger Robot   // No defeault implementation
4425*16467b97STreehugger Robot   Result := nil;
4426*16467b97STreehugger Robot end;
4427*16467b97STreehugger Robot 
GetNumberOfSyntaxErrorsnull4428*16467b97STreehugger Robot function TBaseRecognizer.GetNumberOfSyntaxErrors: Integer;
4429*16467b97STreehugger Robot begin
4430*16467b97STreehugger Robot   Result := FState.SyntaxErrors;
4431*16467b97STreehugger Robot end;
4432*16467b97STreehugger Robot 
GetRuleMemoizationnull4433*16467b97STreehugger Robot function TBaseRecognizer.GetRuleMemoization(const RuleIndex,
4434*16467b97STreehugger Robot   RuleStartIndex: Integer): Integer;
4435*16467b97STreehugger Robot var
4436*16467b97STreehugger Robot   Dict: IDictionary<Integer, Integer>;
4437*16467b97STreehugger Robot begin
4438*16467b97STreehugger Robot   Dict := FState.RuleMemo[RuleIndex];
4439*16467b97STreehugger Robot   if (Dict = nil) then
4440*16467b97STreehugger Robot   begin
4441*16467b97STreehugger Robot     Dict := TDictionary<Integer, Integer>.Create;
4442*16467b97STreehugger Robot     FState.RuleMemo[RuleIndex] := Dict;
4443*16467b97STreehugger Robot   end;
4444*16467b97STreehugger Robot   if (not Dict.TryGetValue(RuleStartIndex, Result)) then
4445*16467b97STreehugger Robot     Result := MEMO_RULE_UNKNOWN;
4446*16467b97STreehugger Robot end;
4447*16467b97STreehugger Robot 
TBaseRecognizer.GetRuleMemoizationChaceSize()4448*16467b97STreehugger Robot function TBaseRecognizer.GetRuleMemoizationChaceSize: Integer;
4449*16467b97STreehugger Robot var
4450*16467b97STreehugger Robot   RuleMap: IDictionary<Integer, Integer>;
4451*16467b97STreehugger Robot begin
4452*16467b97STreehugger Robot   Result := 0;
4453*16467b97STreehugger Robot   if Assigned(FState.RuleMemo) then
4454*16467b97STreehugger Robot   begin
4455*16467b97STreehugger Robot     for RuleMap in FState.RuleMemo do
4456*16467b97STreehugger Robot       if Assigned(RuleMap) then
4457*16467b97STreehugger Robot         Inc(Result,RuleMap.Count);  // how many input indexes are recorded?
4458*16467b97STreehugger Robot   end;
4459*16467b97STreehugger Robot end;
4460*16467b97STreehugger Robot 
TBaseRecognizer.GetState()4461*16467b97STreehugger Robot function TBaseRecognizer.GetState: IRecognizerSharedState;
4462*16467b97STreehugger Robot begin
4463*16467b97STreehugger Robot   Result := FState;
4464*16467b97STreehugger Robot end;
4465*16467b97STreehugger Robot 
GetTokenErrorDisplaynull4466*16467b97STreehugger Robot function TBaseRecognizer.GetTokenErrorDisplay(const T: IToken): String;
4467*16467b97STreehugger Robot begin
4468*16467b97STreehugger Robot   Result := T.Text;
4469*16467b97STreehugger Robot   if (Result = '') then
4470*16467b97STreehugger Robot   begin
4471*16467b97STreehugger Robot     if (T.TokenType = TToken.EOF) then
4472*16467b97STreehugger Robot       Result := '<EOF>'
4473*16467b97STreehugger Robot     else
4474*16467b97STreehugger Robot       Result := '<' + IntToStr(T.TokenType) + '>';
4475*16467b97STreehugger Robot   end;
4476*16467b97STreehugger Robot   Result := ReplaceStr(Result,#10,'\n');
4477*16467b97STreehugger Robot   Result := ReplaceStr(Result,#13,'\r');
4478*16467b97STreehugger Robot   Result := ReplaceStr(Result,#9,'\t');
4479*16467b97STreehugger Robot   Result := '''' + Result + '''';
4480*16467b97STreehugger Robot end;
4481*16467b97STreehugger Robot 
GetTokenNamesnull4482*16467b97STreehugger Robot function TBaseRecognizer.GetTokenNames: TStringArray;
4483*16467b97STreehugger Robot begin
4484*16467b97STreehugger Robot   // no default implementation
4485*16467b97STreehugger Robot   Result := nil;
4486*16467b97STreehugger Robot end;
4487*16467b97STreehugger Robot 
TBaseRecognizer.Match(const Input: IIntStream;4488*16467b97STreehugger Robot function TBaseRecognizer.Match(const Input: IIntStream;
4489*16467b97STreehugger Robot   const TokenType: Integer; const Follow: IBitSet): IANTLRInterface;
4490*16467b97STreehugger Robot begin
4491*16467b97STreehugger Robot   Result := GetCurrentInputSymbol(Input);
4492*16467b97STreehugger Robot   if (Input.LA(1) = TokenType) then
4493*16467b97STreehugger Robot   begin
4494*16467b97STreehugger Robot     Input.Consume;
4495*16467b97STreehugger Robot     FState.ErrorRecovery := False;
4496*16467b97STreehugger Robot     FState.Failed := False;
4497*16467b97STreehugger Robot   end else
4498*16467b97STreehugger Robot   begin
4499*16467b97STreehugger Robot     if (FState.Backtracking > 0) then
4500*16467b97STreehugger Robot       FState.Failed := True
4501*16467b97STreehugger Robot     else
4502*16467b97STreehugger Robot     begin
4503*16467b97STreehugger Robot       Mismatch(Input, TokenType, Follow);
4504*16467b97STreehugger Robot       Result := RecoverFromMismatchedToken(Input, TokenType, Follow);
4505*16467b97STreehugger Robot     end;
4506*16467b97STreehugger Robot   end;
4507*16467b97STreehugger Robot end;
4508*16467b97STreehugger Robot 
4509*16467b97STreehugger Robot procedure TBaseRecognizer.MatchAny(const Input: IIntStream);
4510*16467b97STreehugger Robot begin
4511*16467b97STreehugger Robot   FState.ErrorRecovery := False;
4512*16467b97STreehugger Robot   FState.Failed := False;
4513*16467b97STreehugger Robot   Input.Consume;
4514*16467b97STreehugger Robot end;
4515*16467b97STreehugger Robot 
4516*16467b97STreehugger Robot procedure TBaseRecognizer.Memoize(const Input: IIntStream; const RuleIndex,
4517*16467b97STreehugger Robot   RuleStartIndex: Integer);
4518*16467b97STreehugger Robot var
4519*16467b97STreehugger Robot   StopTokenIndex: Integer;
4520*16467b97STreehugger Robot   Dict: IDictionary<Integer, Integer>;
4521*16467b97STreehugger Robot begin
4522*16467b97STreehugger Robot   Dict := FState.RuleMemo[RuleIndex];
4523*16467b97STreehugger Robot   if Assigned(Dict) then
4524*16467b97STreehugger Robot   begin
4525*16467b97STreehugger Robot     if FState.Failed then
4526*16467b97STreehugger Robot       StopTokenIndex := MEMO_RULE_FAILED
4527*16467b97STreehugger Robot     else
4528*16467b97STreehugger Robot       StopTokenIndex := Input.Index - 1;
4529*16467b97STreehugger Robot     Dict.AddOrSetValue(RuleStartIndex, StopTokenIndex);
4530*16467b97STreehugger Robot   end;
4531*16467b97STreehugger Robot end;
4532*16467b97STreehugger Robot 
4533*16467b97STreehugger Robot procedure TBaseRecognizer.Mismatch(const Input: IIntStream;
4534*16467b97STreehugger Robot   const TokenType: Integer; const Follow: IBitSet);
4535*16467b97STreehugger Robot begin
4536*16467b97STreehugger Robot   if MismatchIsUnwantedToken(Input, TokenType) then
4537*16467b97STreehugger Robot     raise EUnwantedTokenException.Create(TokenType, Input)
4538*16467b97STreehugger Robot   else
4539*16467b97STreehugger Robot     if MismatchIsMissingToken(Input, Follow) then
4540*16467b97STreehugger Robot       raise EMissingTokenException.Create(TokenType, Input, nil)
4541*16467b97STreehugger Robot     else
4542*16467b97STreehugger Robot       raise EMismatchedTokenException.Create(TokenType, Input);
4543*16467b97STreehugger Robot end;
4544*16467b97STreehugger Robot 
TBaseRecognizer.MismatchIsMissingToken(const Input: IIntStream;4545*16467b97STreehugger Robot function TBaseRecognizer.MismatchIsMissingToken(const Input: IIntStream;
4546*16467b97STreehugger Robot   const Follow: IBitSet): Boolean;
4547*16467b97STreehugger Robot var
4548*16467b97STreehugger Robot   ViableTokensFollowingThisRule, Follow2: IBitSet;
4549*16467b97STreehugger Robot begin
4550*16467b97STreehugger Robot   if (Follow = nil) then
4551*16467b97STreehugger Robot     // we have no information about the follow; we can only consume
4552*16467b97STreehugger Robot     // a single token and hope for the best
4553*16467b97STreehugger Robot     Result := False
4554*16467b97STreehugger Robot   else
4555*16467b97STreehugger Robot   begin
4556*16467b97STreehugger Robot     Follow2 := Follow;
4557*16467b97STreehugger Robot     // compute what can follow this grammar element reference
4558*16467b97STreehugger Robot     if (Follow.Member(TToken.EOR_TOKEN_TYPE)) then
4559*16467b97STreehugger Robot     begin
4560*16467b97STreehugger Robot       ViableTokensFollowingThisRule := ComputeContextSensitiveRuleFOLLOW();
4561*16467b97STreehugger Robot       Follow2 := Follow.BitSetOr(ViableTokensFollowingThisRule);
4562*16467b97STreehugger Robot       if (FState.FollowingStackPointer >= 0) then
4563*16467b97STreehugger Robot         // remove EOR if we're not the start symbol
4564*16467b97STreehugger Robot         Follow2.Remove(TToken.EOR_TOKEN_TYPE);
4565*16467b97STreehugger Robot     end;
4566*16467b97STreehugger Robot 
4567*16467b97STreehugger Robot     // if current token is consistent with what could come after set
4568*16467b97STreehugger Robot     // then we know we're missing a token; error recovery is free to
4569*16467b97STreehugger Robot     // "insert" the missing token
4570*16467b97STreehugger Robot 
4571*16467b97STreehugger Robot     // BitSet cannot handle negative numbers like -1 (EOF) so I leave EOR
4572*16467b97STreehugger Robot     // in follow set to indicate that the fall of the start symbol is
4573*16467b97STreehugger Robot     // in the set (EOF can follow).
4574*16467b97STreehugger Robot     if (Follow2.Member(Input.LA(1)) or Follow2.Member(TToken.EOR_TOKEN_TYPE)) then
4575*16467b97STreehugger Robot       Result := True
4576*16467b97STreehugger Robot     else
4577*16467b97STreehugger Robot       Result := False;
4578*16467b97STreehugger Robot   end;
4579*16467b97STreehugger Robot end;
4580*16467b97STreehugger Robot 
MismatchIsUnwantedTokennull4581*16467b97STreehugger Robot function TBaseRecognizer.MismatchIsUnwantedToken(const Input: IIntStream;
4582*16467b97STreehugger Robot   const TokenType: Integer): Boolean;
4583*16467b97STreehugger Robot begin
4584*16467b97STreehugger Robot   Result := (Input.LA(2) = TokenType);
4585*16467b97STreehugger Robot end;
4586*16467b97STreehugger Robot 
4587*16467b97STreehugger Robot procedure TBaseRecognizer.PushFollow(const FSet: IBitSet);
4588*16467b97STreehugger Robot var
4589*16467b97STreehugger Robot   F: TBitSetArray;
4590*16467b97STreehugger Robot   I: Integer;
4591*16467b97STreehugger Robot begin
4592*16467b97STreehugger Robot   if ((FState.FollowingStackPointer + 1) >= Length(FState.Following)) then
4593*16467b97STreehugger Robot   begin
4594*16467b97STreehugger Robot     SetLength(F, Length(FState.Following) * 2);
4595*16467b97STreehugger Robot     FillChar(F[0], Length(F) * SizeOf(IBitSet), 0);
4596*16467b97STreehugger Robot     for I := 0 to Length(FState.Following) - 1 do
4597*16467b97STreehugger Robot       F[I] := FState.Following[I];
4598*16467b97STreehugger Robot     FState.Following := F;
4599*16467b97STreehugger Robot   end;
4600*16467b97STreehugger Robot   FState.FollowingStackPointer := FState.FollowingStackPointer + 1;
4601*16467b97STreehugger Robot   FState.Following[FState.FollowingStackPointer] := FSet;
4602*16467b97STreehugger Robot end;
4603*16467b97STreehugger Robot 
4604*16467b97STreehugger Robot procedure TBaseRecognizer.Recover(const Input: IIntStream;
4605*16467b97STreehugger Robot   const RE: ERecognitionException);
4606*16467b97STreehugger Robot var
4607*16467b97STreehugger Robot   FollowSet: IBitSet;
4608*16467b97STreehugger Robot begin
4609*16467b97STreehugger Robot   if (FState.LastErrorIndex = Input.Index) then
4610*16467b97STreehugger Robot     // uh oh, another error at same token index; must be a case
4611*16467b97STreehugger Robot     // where LT(1) is in the recovery token set so nothing is
4612*16467b97STreehugger Robot     // consumed; consume a single token so at least to prevent
4613*16467b97STreehugger Robot     // an infinite loop; this is a failsafe.
4614*16467b97STreehugger Robot     Input.Consume;
4615*16467b97STreehugger Robot   FState.LastErrorIndex := Input.Index;
4616*16467b97STreehugger Robot   FollowSet := ComputeErrorRecoverySet;
4617*16467b97STreehugger Robot   BeginResync;
4618*16467b97STreehugger Robot   ConsumeUntil(Input,FollowSet);
4619*16467b97STreehugger Robot   EndResync;
4620*16467b97STreehugger Robot end;
4621*16467b97STreehugger Robot 
TBaseRecognizer.RecoverFromMismatchedSet(const Input: IIntStream;4622*16467b97STreehugger Robot function TBaseRecognizer.RecoverFromMismatchedSet(const Input: IIntStream;
4623*16467b97STreehugger Robot   const E: ERecognitionException; const Follow: IBitSet): IANTLRInterface;
4624*16467b97STreehugger Robot begin
4625*16467b97STreehugger Robot   if MismatchIsMissingToken(Input, Follow) then
4626*16467b97STreehugger Robot   begin
4627*16467b97STreehugger Robot     ReportError(E);
4628*16467b97STreehugger Robot     // we don't know how to conjure up a token for sets yet
4629*16467b97STreehugger Robot     Result := GetMissingSymbol(Input, E, TToken.INVALID_TOKEN_TYPE, Follow);
4630*16467b97STreehugger Robot   end
4631*16467b97STreehugger Robot   else
4632*16467b97STreehugger Robot   begin
4633*16467b97STreehugger Robot     // TODO do single token deletion like above for Token mismatch
4634*16467b97STreehugger Robot     Result := nil;
4635*16467b97STreehugger Robot     raise E;
4636*16467b97STreehugger Robot   end;
4637*16467b97STreehugger Robot end;
4638*16467b97STreehugger Robot 
RecoverFromMismatchedTokennull4639*16467b97STreehugger Robot function TBaseRecognizer.RecoverFromMismatchedToken(const Input: IIntStream;
4640*16467b97STreehugger Robot   const TokenType: Integer; const Follow: IBitSet): IANTLRInterface;
4641*16467b97STreehugger Robot var
4642*16467b97STreehugger Robot   E: ERecognitionException;
4643*16467b97STreehugger Robot begin
4644*16467b97STreehugger Robot   // if next token is what we are looking for then "delete" this token
4645*16467b97STreehugger Robot   if MismatchIsUnwantedToken(Input, TokenType) then
4646*16467b97STreehugger Robot   begin
4647*16467b97STreehugger Robot     E := EUnwantedTokenException.Create(TokenType, Input);
4648*16467b97STreehugger Robot     BeginResync;
4649*16467b97STreehugger Robot     Input.Consume; // simply delete extra token
4650*16467b97STreehugger Robot     EndResync;
4651*16467b97STreehugger Robot     ReportError(E);  // report after consuming so AW sees the token in the exception
4652*16467b97STreehugger Robot     // we want to return the token we're actually matching
4653*16467b97STreehugger Robot     Result := GetCurrentInputSymbol(Input);
4654*16467b97STreehugger Robot     Input.Consume;  // move past ttype token as if all were ok
4655*16467b97STreehugger Robot   end
4656*16467b97STreehugger Robot   else
4657*16467b97STreehugger Robot   begin
4658*16467b97STreehugger Robot     // can't recover with single token deletion, try insertion
4659*16467b97STreehugger Robot     if MismatchIsMissingToken(Input, Follow) then
4660*16467b97STreehugger Robot     begin
4661*16467b97STreehugger Robot       E := nil;
4662*16467b97STreehugger Robot       Result := GetMissingSymbol(Input, E, TokenType, Follow);
4663*16467b97STreehugger Robot       E := EMissingTokenException.Create(TokenType, Input, Result);
4664*16467b97STreehugger Robot       ReportError(E);  // report after inserting so AW sees the token in the exception
4665*16467b97STreehugger Robot     end
4666*16467b97STreehugger Robot     else
4667*16467b97STreehugger Robot     begin
4668*16467b97STreehugger Robot       // even that didn't work; must throw the exception
4669*16467b97STreehugger Robot       raise EMismatchedTokenException.Create(TokenType, Input);
4670*16467b97STreehugger Robot     end;
4671*16467b97STreehugger Robot   end;
4672*16467b97STreehugger Robot end;
4673*16467b97STreehugger Robot 
4674*16467b97STreehugger Robot procedure TBaseRecognizer.ReportError(const E: ERecognitionException);
4675*16467b97STreehugger Robot begin
4676*16467b97STreehugger Robot   // if we've already reported an error and have not matched a token
4677*16467b97STreehugger Robot   // yet successfully, don't report any errors.
4678*16467b97STreehugger Robot   if (not FState.ErrorRecovery) then
4679*16467b97STreehugger Robot   begin
4680*16467b97STreehugger Robot     FState.SyntaxErrors := FState.SyntaxErrors + 1; // don't count spurious
4681*16467b97STreehugger Robot     FState.ErrorRecovery := True;
4682*16467b97STreehugger Robot     DisplayRecognitionError(GetTokenNames, E);
4683*16467b97STreehugger Robot   end;
4684*16467b97STreehugger Robot end;
4685*16467b97STreehugger Robot 
4686*16467b97STreehugger Robot procedure TBaseRecognizer.Reset;
4687*16467b97STreehugger Robot var
4688*16467b97STreehugger Robot   I: Integer;
4689*16467b97STreehugger Robot begin
4690*16467b97STreehugger Robot   // wack everything related to error recovery
4691*16467b97STreehugger Robot   if (FState = nil) then
4692*16467b97STreehugger Robot     Exit;  // no shared state work to do
4693*16467b97STreehugger Robot 
4694*16467b97STreehugger Robot   FState.FollowingStackPointer := -1;
4695*16467b97STreehugger Robot   FState.ErrorRecovery := False;
4696*16467b97STreehugger Robot   FState.LastErrorIndex := -1;
4697*16467b97STreehugger Robot   FState.Failed := False;
4698*16467b97STreehugger Robot   FState.SyntaxErrors := 0;
4699*16467b97STreehugger Robot 
4700*16467b97STreehugger Robot   // wack everything related to backtracking and memoization
4701*16467b97STreehugger Robot   FState.Backtracking := 0;
4702*16467b97STreehugger Robot   if Assigned(FState.RuleMemo) then
4703*16467b97STreehugger Robot     for I := 0 to Length(FState.RuleMemo) - 1 do
4704*16467b97STreehugger Robot     begin
4705*16467b97STreehugger Robot       // wipe cache
4706*16467b97STreehugger Robot       FState.RuleMemo[I] := nil;
4707*16467b97STreehugger Robot     end;
4708*16467b97STreehugger Robot end;
4709*16467b97STreehugger Robot 
ToStringsnull4710*16467b97STreehugger Robot function TBaseRecognizer.ToStrings(const Tokens: IList<IToken>): IList<String>;
4711*16467b97STreehugger Robot var
4712*16467b97STreehugger Robot   Token: IToken;
4713*16467b97STreehugger Robot begin
4714*16467b97STreehugger Robot   if (Tokens = nil) then
4715*16467b97STreehugger Robot     Result := nil
4716*16467b97STreehugger Robot   else
4717*16467b97STreehugger Robot   begin
4718*16467b97STreehugger Robot     Result := TList<String>.Create;
4719*16467b97STreehugger Robot     for Token in Tokens do
4720*16467b97STreehugger Robot       Result.Add(Token.Text);
4721*16467b97STreehugger Robot   end;
4722*16467b97STreehugger Robot end;
4723*16467b97STreehugger Robot 
4724*16467b97STreehugger Robot procedure TBaseRecognizer.TraceIn(const RuleName: String;
4725*16467b97STreehugger Robot   const RuleIndex: Integer; const InputSymbol: String);
4726*16467b97STreehugger Robot begin
4727*16467b97STreehugger Robot   Write('enter ' + RuleName + ' ' + InputSymbol);
4728*16467b97STreehugger Robot   if (FState.Failed) then
4729*16467b97STreehugger Robot     WriteLn(' failed=True');
4730*16467b97STreehugger Robot   if (FState.Backtracking > 0) then
4731*16467b97STreehugger Robot     Write(' backtracking=' + IntToStr(FState.Backtracking));
4732*16467b97STreehugger Robot   WriteLn;
4733*16467b97STreehugger Robot end;
4734*16467b97STreehugger Robot 
4735*16467b97STreehugger Robot procedure TBaseRecognizer.TraceOut(const RuleName: String;
4736*16467b97STreehugger Robot   const RuleIndex: Integer; const InputSymbol: String);
4737*16467b97STreehugger Robot begin
4738*16467b97STreehugger Robot   Write('exit ' + RuleName + ' ' + InputSymbol);
4739*16467b97STreehugger Robot   if (FState.Failed) then
4740*16467b97STreehugger Robot     WriteLn(' failed=True');
4741*16467b97STreehugger Robot   if (FState.Backtracking > 0) then
4742*16467b97STreehugger Robot     Write(' backtracking=' + IntToStr(FState.Backtracking));
4743*16467b97STreehugger Robot   WriteLn;
4744*16467b97STreehugger Robot end;
4745*16467b97STreehugger Robot 
4746*16467b97STreehugger Robot { TCommonTokenStream }
4747*16467b97STreehugger Robot 
4748*16467b97STreehugger Robot procedure TCommonTokenStream.Consume;
4749*16467b97STreehugger Robot begin
4750*16467b97STreehugger Robot   if (FP < FTokens.Count) then
4751*16467b97STreehugger Robot   begin
4752*16467b97STreehugger Robot     Inc(FP);
4753*16467b97STreehugger Robot     FP := SkipOffTokenChannels(FP); // leave p on valid token
4754*16467b97STreehugger Robot   end;
4755*16467b97STreehugger Robot end;
4756*16467b97STreehugger Robot 
4757*16467b97STreehugger Robot constructor TCommonTokenStream.Create;
4758*16467b97STreehugger Robot begin
4759*16467b97STreehugger Robot   inherited;
4760*16467b97STreehugger Robot   FP := -1;
4761*16467b97STreehugger Robot   FChannel := TToken.DEFAULT_CHANNEL;
4762*16467b97STreehugger Robot   FTokens := TList<IToken>.Create;
4763*16467b97STreehugger Robot   FTokens.Capacity := 500;
4764*16467b97STreehugger Robot end;
4765*16467b97STreehugger Robot 
4766*16467b97STreehugger Robot constructor TCommonTokenStream.Create(const ATokenSource: ITokenSource);
4767*16467b97STreehugger Robot begin
4768*16467b97STreehugger Robot   Create;
4769*16467b97STreehugger Robot   FTokenSource := ATokenSource;
4770*16467b97STreehugger Robot end;
4771*16467b97STreehugger Robot 
4772*16467b97STreehugger Robot procedure TCommonTokenStream.DiscardOffChannelTokens(const Discard: Boolean);
4773*16467b97STreehugger Robot begin
4774*16467b97STreehugger Robot   FDiscardOffChannelTokens := Discard;
4775*16467b97STreehugger Robot end;
4776*16467b97STreehugger Robot 
4777*16467b97STreehugger Robot procedure TCommonTokenStream.DiscardTokenType(const TType: Integer);
4778*16467b97STreehugger Robot begin
4779*16467b97STreehugger Robot   if (FDiscardSet = nil) then
4780*16467b97STreehugger Robot     FDiscardSet := THashList<Integer, Integer>.Create;
4781*16467b97STreehugger Robot   FDiscardSet.Add(TType, TType);
4782*16467b97STreehugger Robot end;
4783*16467b97STreehugger Robot 
4784*16467b97STreehugger Robot procedure TCommonTokenStream.FillBuffer;
4785*16467b97STreehugger Robot var
4786*16467b97STreehugger Robot   Index: Integer;
4787*16467b97STreehugger Robot   T: IToken;
4788*16467b97STreehugger Robot   Discard: Boolean;
4789*16467b97STreehugger Robot begin
4790*16467b97STreehugger Robot   Index := 0;
4791*16467b97STreehugger Robot   T := FTokenSource.NextToken;
4792*16467b97STreehugger Robot   while Assigned(T) and (T.TokenType <> Integer(cscEOF)) do
4793*16467b97STreehugger Robot   begin
4794*16467b97STreehugger Robot     Discard := False;
4795*16467b97STreehugger Robot     // is there a channel override for token type?
4796*16467b97STreehugger Robot     if Assigned(FChannelOverrideMap) then
4797*16467b97STreehugger Robot       if FChannelOverrideMap.ContainsKey(T.TokenType) then
4798*16467b97STreehugger Robot         T.Channel := FChannelOverrideMap[T.TokenType];
4799*16467b97STreehugger Robot 
4800*16467b97STreehugger Robot     if Assigned(FDiscardSet) and FDiscardSet.ContainsKey(T.TokenType) then
4801*16467b97STreehugger Robot       Discard := True
4802*16467b97STreehugger Robot     else
4803*16467b97STreehugger Robot       if FDiscardOffChannelTokens and (T.Channel <> FChannel) then
4804*16467b97STreehugger Robot         Discard := True;
4805*16467b97STreehugger Robot 
4806*16467b97STreehugger Robot     if (not Discard) then
4807*16467b97STreehugger Robot     begin
4808*16467b97STreehugger Robot       T.TokenIndex := Index;
4809*16467b97STreehugger Robot       FTokens.Add(T);
4810*16467b97STreehugger Robot       Inc(Index);
4811*16467b97STreehugger Robot     end;
4812*16467b97STreehugger Robot 
4813*16467b97STreehugger Robot     T := FTokenSource.NextToken;
4814*16467b97STreehugger Robot   end;
4815*16467b97STreehugger Robot   // leave p pointing at first token on channel
4816*16467b97STreehugger Robot   FP := 0;
4817*16467b97STreehugger Robot   FP := SkipOffTokenChannels(FP);
4818*16467b97STreehugger Robot end;
4819*16467b97STreehugger Robot 
TCommonTokenStream.Get(const I: Integer)4820*16467b97STreehugger Robot function TCommonTokenStream.Get(const I: Integer): IToken;
4821*16467b97STreehugger Robot begin
4822*16467b97STreehugger Robot   Result := FTokens[I];
4823*16467b97STreehugger Robot end;
4824*16467b97STreehugger Robot 
GetSourceNamenull4825*16467b97STreehugger Robot function TCommonTokenStream.GetSourceName: String;
4826*16467b97STreehugger Robot begin
4827*16467b97STreehugger Robot   Result := FTokenSource.SourceName;
4828*16467b97STreehugger Robot end;
4829*16467b97STreehugger Robot 
GetTokensnull4830*16467b97STreehugger Robot function TCommonTokenStream.GetTokens(const Start, Stop: Integer;
4831*16467b97STreehugger Robot   const Types: IList<Integer>): IList<IToken>;
4832*16467b97STreehugger Robot begin
4833*16467b97STreehugger Robot   Result := GetTokens(Start, Stop, TBitSet.Create(Types));
4834*16467b97STreehugger Robot end;
4835*16467b97STreehugger Robot 
GetTokensnull4836*16467b97STreehugger Robot function TCommonTokenStream.GetTokens(const Start, Stop,
4837*16467b97STreehugger Robot   TokenType: Integer): IList<IToken>;
4838*16467b97STreehugger Robot begin
4839*16467b97STreehugger Robot   Result := GetTokens(Start, Stop, TBitSet.BitSetOf(TokenType));
4840*16467b97STreehugger Robot end;
4841*16467b97STreehugger Robot 
GetTokensnull4842*16467b97STreehugger Robot function TCommonTokenStream.GetTokens(const Start, Stop: Integer;
4843*16467b97STreehugger Robot   const Types: IBitSet): IList<IToken>;
4844*16467b97STreehugger Robot var
4845*16467b97STreehugger Robot   I, StartIndex, StopIndex: Integer;
4846*16467b97STreehugger Robot   T: IToken;
4847*16467b97STreehugger Robot begin
4848*16467b97STreehugger Robot   if (FP = -1) then
4849*16467b97STreehugger Robot     FillBuffer;
4850*16467b97STreehugger Robot   StopIndex := Min(Stop,FTokens.Count - 1);
4851*16467b97STreehugger Robot   StartIndex := Max(Start,0);
4852*16467b97STreehugger Robot   if (StartIndex > StopIndex) then
4853*16467b97STreehugger Robot     Result := nil
4854*16467b97STreehugger Robot   else
4855*16467b97STreehugger Robot   begin
4856*16467b97STreehugger Robot     Result := TList<IToken>.Create;
4857*16467b97STreehugger Robot     for I := StartIndex to StopIndex do
4858*16467b97STreehugger Robot     begin
4859*16467b97STreehugger Robot       T := FTokens[I];
4860*16467b97STreehugger Robot       if (Types = nil) or Types.Member(T.TokenType) then
4861*16467b97STreehugger Robot         Result.Add(T);
4862*16467b97STreehugger Robot     end;
4863*16467b97STreehugger Robot     if (Result.Count = 0) then
4864*16467b97STreehugger Robot       Result := nil;
4865*16467b97STreehugger Robot   end;
4866*16467b97STreehugger Robot end;
4867*16467b97STreehugger Robot 
GetTokensnull4868*16467b97STreehugger Robot function TCommonTokenStream.GetTokens: IList<IToken>;
4869*16467b97STreehugger Robot begin
4870*16467b97STreehugger Robot   if (FP = -1) then
4871*16467b97STreehugger Robot     FillBuffer;
4872*16467b97STreehugger Robot   Result := FTokens;
4873*16467b97STreehugger Robot end;
4874*16467b97STreehugger Robot 
GetTokensnull4875*16467b97STreehugger Robot function TCommonTokenStream.GetTokens(const Start,
4876*16467b97STreehugger Robot   Stop: Integer): IList<IToken>;
4877*16467b97STreehugger Robot begin
4878*16467b97STreehugger Robot   Result := GetTokens(Start, Stop, IBitSet(nil));
4879*16467b97STreehugger Robot end;
4880*16467b97STreehugger Robot 
TCommonTokenStream.GetTokenSource()4881*16467b97STreehugger Robot function TCommonTokenStream.GetTokenSource: ITokenSource;
4882*16467b97STreehugger Robot begin
4883*16467b97STreehugger Robot   Result := FTokenSource;
4884*16467b97STreehugger Robot end;
4885*16467b97STreehugger Robot 
TCommonTokenStream.Index()4886*16467b97STreehugger Robot function TCommonTokenStream.Index: Integer;
4887*16467b97STreehugger Robot begin
4888*16467b97STreehugger Robot   Result := FP;
4889*16467b97STreehugger Robot end;
4890*16467b97STreehugger Robot 
LAnull4891*16467b97STreehugger Robot function TCommonTokenStream.LA(I: Integer): Integer;
4892*16467b97STreehugger Robot begin
4893*16467b97STreehugger Robot   Result := LT(I).TokenType;
4894*16467b97STreehugger Robot end;
4895*16467b97STreehugger Robot 
TCommonTokenStream.LAChar(I: Integer)4896*16467b97STreehugger Robot function TCommonTokenStream.LAChar(I: Integer): Char;
4897*16467b97STreehugger Robot begin
4898*16467b97STreehugger Robot   Result := Char(LA(I));
4899*16467b97STreehugger Robot end;
4900*16467b97STreehugger Robot 
LBnull4901*16467b97STreehugger Robot function TCommonTokenStream.LB(const K: Integer): IToken;
4902*16467b97STreehugger Robot var
4903*16467b97STreehugger Robot   I, N: Integer;
4904*16467b97STreehugger Robot begin
4905*16467b97STreehugger Robot   if (FP = -1) then
4906*16467b97STreehugger Robot     FillBuffer;
4907*16467b97STreehugger Robot   if (K = 0) then
4908*16467b97STreehugger Robot     Result := nil
4909*16467b97STreehugger Robot   else
4910*16467b97STreehugger Robot     if ((FP - K) < 0) then
4911*16467b97STreehugger Robot       Result := nil
4912*16467b97STreehugger Robot     else
4913*16467b97STreehugger Robot     begin
4914*16467b97STreehugger Robot       I := FP;
4915*16467b97STreehugger Robot       N := 1;
4916*16467b97STreehugger Robot       // find k good tokens looking backwards
4917*16467b97STreehugger Robot       while (N <= K) do
4918*16467b97STreehugger Robot       begin
4919*16467b97STreehugger Robot         // skip off-channel tokens
4920*16467b97STreehugger Robot         I := SkipOffTokenChannelsReverse(I - 1); // leave p on valid token
4921*16467b97STreehugger Robot         Inc(N);
4922*16467b97STreehugger Robot       end;
4923*16467b97STreehugger Robot       if (I < 0) then
4924*16467b97STreehugger Robot         Result := nil
4925*16467b97STreehugger Robot       else
4926*16467b97STreehugger Robot         Result := FTokens[I];
4927*16467b97STreehugger Robot     end;
4928*16467b97STreehugger Robot end;
4929*16467b97STreehugger Robot 
LTnull4930*16467b97STreehugger Robot function TCommonTokenStream.LT(const K: Integer): IToken;
4931*16467b97STreehugger Robot var
4932*16467b97STreehugger Robot   I, N: Integer;
4933*16467b97STreehugger Robot begin
4934*16467b97STreehugger Robot   if (FP = -1) then
4935*16467b97STreehugger Robot     FillBuffer;
4936*16467b97STreehugger Robot   if (K = 0) then
4937*16467b97STreehugger Robot     Result := nil
4938*16467b97STreehugger Robot   else
4939*16467b97STreehugger Robot     if (K < 0) then
4940*16467b97STreehugger Robot       Result := LB(-K)
4941*16467b97STreehugger Robot     else
4942*16467b97STreehugger Robot       if ((FP + K - 1) >= FTokens.Count) then
4943*16467b97STreehugger Robot         Result := TToken.EOF_TOKEN
4944*16467b97STreehugger Robot       else
4945*16467b97STreehugger Robot       begin
4946*16467b97STreehugger Robot         I := FP;
4947*16467b97STreehugger Robot         N := 1;
4948*16467b97STreehugger Robot         // find k good tokens
4949*16467b97STreehugger Robot         while (N < K) do
4950*16467b97STreehugger Robot         begin
4951*16467b97STreehugger Robot           // skip off-channel tokens
4952*16467b97STreehugger Robot           I := SkipOffTokenChannels(I + 1); // leave p on valid token
4953*16467b97STreehugger Robot           Inc(N);
4954*16467b97STreehugger Robot         end;
4955*16467b97STreehugger Robot         if (I >= FTokens.Count) then
4956*16467b97STreehugger Robot           Result := TToken.EOF_TOKEN
4957*16467b97STreehugger Robot         else
4958*16467b97STreehugger Robot           Result := FTokens[I];
4959*16467b97STreehugger Robot       end;
4960*16467b97STreehugger Robot end;
4961*16467b97STreehugger Robot 
Marknull4962*16467b97STreehugger Robot function TCommonTokenStream.Mark: Integer;
4963*16467b97STreehugger Robot begin
4964*16467b97STreehugger Robot   if (FP = -1) then
4965*16467b97STreehugger Robot     FillBuffer;
4966*16467b97STreehugger Robot   FLastMarker := Index;
4967*16467b97STreehugger Robot   Result := FLastMarker;
4968*16467b97STreehugger Robot end;
4969*16467b97STreehugger Robot 
4970*16467b97STreehugger Robot procedure TCommonTokenStream.Release(const Marker: Integer);
4971*16467b97STreehugger Robot begin
4972*16467b97STreehugger Robot   // no resources to release
4973*16467b97STreehugger Robot end;
4974*16467b97STreehugger Robot 
4975*16467b97STreehugger Robot procedure TCommonTokenStream.Reset;
4976*16467b97STreehugger Robot begin
4977*16467b97STreehugger Robot   FP := 0;
4978*16467b97STreehugger Robot   FLastMarker := 0;
4979*16467b97STreehugger Robot end;
4980*16467b97STreehugger Robot 
4981*16467b97STreehugger Robot procedure TCommonTokenStream.Rewind(const Marker: Integer);
4982*16467b97STreehugger Robot begin
4983*16467b97STreehugger Robot   Seek(Marker);
4984*16467b97STreehugger Robot end;
4985*16467b97STreehugger Robot 
4986*16467b97STreehugger Robot procedure TCommonTokenStream.Rewind;
4987*16467b97STreehugger Robot begin
4988*16467b97STreehugger Robot   Seek(FLastMarker);
4989*16467b97STreehugger Robot end;
4990*16467b97STreehugger Robot 
4991*16467b97STreehugger Robot procedure TCommonTokenStream.Seek(const Index: Integer);
4992*16467b97STreehugger Robot begin
4993*16467b97STreehugger Robot   FP := Index;
4994*16467b97STreehugger Robot end;
4995*16467b97STreehugger Robot 
4996*16467b97STreehugger Robot procedure TCommonTokenStream.SetTokenSource(const Value: ITokenSource);
4997*16467b97STreehugger Robot begin
4998*16467b97STreehugger Robot   FTokenSource := Value;
4999*16467b97STreehugger Robot   FTokens.Clear;
5000*16467b97STreehugger Robot   FP := -1;
5001*16467b97STreehugger Robot   FChannel := TToken.DEFAULT_CHANNEL;
5002*16467b97STreehugger Robot end;
5003*16467b97STreehugger Robot 
5004*16467b97STreehugger Robot procedure TCommonTokenStream.SetTokenTypeChannel(const TType, Channel: Integer);
5005*16467b97STreehugger Robot begin
5006*16467b97STreehugger Robot   if (FChannelOverrideMap = nil) then
5007*16467b97STreehugger Robot     FChannelOverrideMap := TDictionary<Integer, Integer>.Create;
5008*16467b97STreehugger Robot   FChannelOverrideMap[TType] := Channel;
5009*16467b97STreehugger Robot end;
5010*16467b97STreehugger Robot 
Sizenull5011*16467b97STreehugger Robot function TCommonTokenStream.Size: Integer;
5012*16467b97STreehugger Robot begin
5013*16467b97STreehugger Robot   Result := FTokens.Count;
5014*16467b97STreehugger Robot end;
5015*16467b97STreehugger Robot 
SkipOffTokenChannelsnull5016*16467b97STreehugger Robot function TCommonTokenStream.SkipOffTokenChannels(const I: Integer): Integer;
5017*16467b97STreehugger Robot var
5018*16467b97STreehugger Robot   N: Integer;
5019*16467b97STreehugger Robot begin
5020*16467b97STreehugger Robot   Result := I;
5021*16467b97STreehugger Robot   N := FTokens.Count;
5022*16467b97STreehugger Robot   while (Result < N) and (FTokens[Result].Channel <> FChannel) do
5023*16467b97STreehugger Robot     Inc(Result);
5024*16467b97STreehugger Robot end;
5025*16467b97STreehugger Robot 
TCommonTokenStream.SkipOffTokenChannelsReverse(5026*16467b97STreehugger Robot function TCommonTokenStream.SkipOffTokenChannelsReverse(
5027*16467b97STreehugger Robot   const I: Integer): Integer;
5028*16467b97STreehugger Robot begin
5029*16467b97STreehugger Robot   Result := I;
5030*16467b97STreehugger Robot   while (Result >= 0) and (FTokens[Result].Channel <> FChannel) do
5031*16467b97STreehugger Robot     Dec(Result);
5032*16467b97STreehugger Robot end;
5033*16467b97STreehugger Robot 
TCommonTokenStream.ToString()5034*16467b97STreehugger Robot function TCommonTokenStream.ToString: String;
5035*16467b97STreehugger Robot begin
5036*16467b97STreehugger Robot   if (FP = -1) then
5037*16467b97STreehugger Robot     FillBuffer;
5038*16467b97STreehugger Robot   Result := ToString(0, FTokens.Count - 1);
5039*16467b97STreehugger Robot end;
5040*16467b97STreehugger Robot 
TCommonTokenStream.ToString(const Start, Stop: Integer)5041*16467b97STreehugger Robot function TCommonTokenStream.ToString(const Start, Stop: Integer): String;
5042*16467b97STreehugger Robot var
5043*16467b97STreehugger Robot   I, Finish: Integer;
5044*16467b97STreehugger Robot   Buf: TStringBuilder;
5045*16467b97STreehugger Robot   T: IToken;
5046*16467b97STreehugger Robot begin
5047*16467b97STreehugger Robot   if (Start < 0) or (Stop < 0) then
5048*16467b97STreehugger Robot     Result := ''
5049*16467b97STreehugger Robot   else
5050*16467b97STreehugger Robot   begin
5051*16467b97STreehugger Robot     if (FP = -1) then
5052*16467b97STreehugger Robot       FillBuffer;
5053*16467b97STreehugger Robot     if (Stop >= FTokens.Count) then
5054*16467b97STreehugger Robot       Finish := FTokens.Count - 1
5055*16467b97STreehugger Robot     else
5056*16467b97STreehugger Robot       Finish := Stop;
5057*16467b97STreehugger Robot     Buf := TStringBuilder.Create;
5058*16467b97STreehugger Robot     try
5059*16467b97STreehugger Robot       for I := Start to Finish do
5060*16467b97STreehugger Robot       begin
5061*16467b97STreehugger Robot         T := FTokens[I];
5062*16467b97STreehugger Robot         Buf.Append(T.Text);
5063*16467b97STreehugger Robot       end;
5064*16467b97STreehugger Robot       Result := Buf.ToString;
5065*16467b97STreehugger Robot     finally
5066*16467b97STreehugger Robot       Buf.Free;
5067*16467b97STreehugger Robot     end;
5068*16467b97STreehugger Robot   end;
5069*16467b97STreehugger Robot end;
5070*16467b97STreehugger Robot 
TCommonTokenStream.ToString(const Start, Stop: IToken)5071*16467b97STreehugger Robot function TCommonTokenStream.ToString(const Start, Stop: IToken): String;
5072*16467b97STreehugger Robot begin
5073*16467b97STreehugger Robot   if Assigned(Start) and Assigned(Stop) then
5074*16467b97STreehugger Robot     Result := ToString(Start.TokenIndex, Stop.TokenIndex)
5075*16467b97STreehugger Robot   else
5076*16467b97STreehugger Robot     Result := '';
5077*16467b97STreehugger Robot end;
5078*16467b97STreehugger Robot 
5079*16467b97STreehugger Robot constructor TCommonTokenStream.Create(const ATokenSource: ITokenSource;
5080*16467b97STreehugger Robot   const AChannel: Integer);
5081*16467b97STreehugger Robot begin
5082*16467b97STreehugger Robot   Create(ATokenSource);
5083*16467b97STreehugger Robot   FChannel := AChannel;
5084*16467b97STreehugger Robot end;
5085*16467b97STreehugger Robot 
5086*16467b97STreehugger Robot constructor TCommonTokenStream.Create(const ALexer: ILexer);
5087*16467b97STreehugger Robot begin
5088*16467b97STreehugger Robot   Create(ALexer as ITokenSource);
5089*16467b97STreehugger Robot end;
5090*16467b97STreehugger Robot 
5091*16467b97STreehugger Robot constructor TCommonTokenStream.Create(const ALexer: ILexer;
5092*16467b97STreehugger Robot   const AChannel: Integer);
5093*16467b97STreehugger Robot begin
5094*16467b97STreehugger Robot   Create(ALexer as ITokenSource, AChannel);
5095*16467b97STreehugger Robot end;
5096*16467b97STreehugger Robot 
5097*16467b97STreehugger Robot { TDFA }
5098*16467b97STreehugger Robot 
TDFA.Description()5099*16467b97STreehugger Robot function TDFA.Description: String;
5100*16467b97STreehugger Robot begin
5101*16467b97STreehugger Robot   Result := 'n/a';
5102*16467b97STreehugger Robot end;
5103*16467b97STreehugger Robot 
5104*16467b97STreehugger Robot procedure TDFA.Error(const NVAE: ENoViableAltException);
5105*16467b97STreehugger Robot begin
5106*16467b97STreehugger Robot   // No default implementation
5107*16467b97STreehugger Robot end;
5108*16467b97STreehugger Robot 
GetRecognizernull5109*16467b97STreehugger Robot function TDFA.GetRecognizer: IBaseRecognizer;
5110*16467b97STreehugger Robot begin
5111*16467b97STreehugger Robot   Result := IBaseRecognizer(FRecognizer);
5112*16467b97STreehugger Robot end;
5113*16467b97STreehugger Robot 
GetSpecialStateTransitionHandlernull5114*16467b97STreehugger Robot function TDFA.GetSpecialStateTransitionHandler: TSpecialStateTransitionHandler;
5115*16467b97STreehugger Robot begin
5116*16467b97STreehugger Robot   Result := FSpecialStateTransitionHandler;
5117*16467b97STreehugger Robot end;
5118*16467b97STreehugger Robot 
5119*16467b97STreehugger Robot procedure TDFA.NoViableAlt(const S: Integer; const Input: IIntStream);
5120*16467b97STreehugger Robot var
5121*16467b97STreehugger Robot   NVAE: ENoViableAltException;
5122*16467b97STreehugger Robot begin
5123*16467b97STreehugger Robot   if (Recognizer.State.Backtracking > 0) then
5124*16467b97STreehugger Robot     Recognizer.State.Failed := True
5125*16467b97STreehugger Robot   else
5126*16467b97STreehugger Robot   begin
5127*16467b97STreehugger Robot     NVAE := ENoViableAltException.Create(Description, FDecisionNumber, S, Input);
5128*16467b97STreehugger Robot     Error(NVAE);
5129*16467b97STreehugger Robot     raise NVAE;
5130*16467b97STreehugger Robot   end;
5131*16467b97STreehugger Robot end;
5132*16467b97STreehugger Robot 
Predictnull5133*16467b97STreehugger Robot function TDFA.Predict(const Input: IIntStream): Integer;
5134*16467b97STreehugger Robot var
5135*16467b97STreehugger Robot   Mark, S, SNext, SpecialState: Integer;
5136*16467b97STreehugger Robot   C: Char;
5137*16467b97STreehugger Robot begin
5138*16467b97STreehugger Robot   Result := 0;
5139*16467b97STreehugger Robot   Mark := Input.Mark; // remember where decision started in input
5140*16467b97STreehugger Robot   S := 0; // we always start at s0
5141*16467b97STreehugger Robot   try
5142*16467b97STreehugger Robot     while True do
5143*16467b97STreehugger Robot     begin
5144*16467b97STreehugger Robot       SpecialState := FSpecial[S];
5145*16467b97STreehugger Robot       if (SpecialState >= 0) then
5146*16467b97STreehugger Robot       begin
5147*16467b97STreehugger Robot         S := FSpecialStateTransitionHandler(Self, SpecialState, Input);
5148*16467b97STreehugger Robot         if (S = -1) then
5149*16467b97STreehugger Robot         begin
5150*16467b97STreehugger Robot           NoViableAlt(S, Input);
5151*16467b97STreehugger Robot           Exit;
5152*16467b97STreehugger Robot         end;
5153*16467b97STreehugger Robot         Input.Consume;
5154*16467b97STreehugger Robot         Continue;
5155*16467b97STreehugger Robot       end;
5156*16467b97STreehugger Robot 
5157*16467b97STreehugger Robot       if (FAccept[S] >= 1) then
5158*16467b97STreehugger Robot       begin
5159*16467b97STreehugger Robot         Result := FAccept[S];
5160*16467b97STreehugger Robot         Exit;
5161*16467b97STreehugger Robot       end;
5162*16467b97STreehugger Robot 
5163*16467b97STreehugger Robot       // look for a normal char transition
5164*16467b97STreehugger Robot       C := Char(Input.LA(1)); // -1 == \uFFFF, all tokens fit in 65000 space
5165*16467b97STreehugger Robot       if (C >= FMin[S]) and (C <= FMax[S]) then
5166*16467b97STreehugger Robot       begin
5167*16467b97STreehugger Robot         SNext := FTransition[S,Integer(C) - Integer(FMin[S])];  // move to next state
5168*16467b97STreehugger Robot         if (SNext < 0) then
5169*16467b97STreehugger Robot         begin
5170*16467b97STreehugger Robot           // was in range but not a normal transition
5171*16467b97STreehugger Robot           // must check EOT, which is like the else clause.
5172*16467b97STreehugger Robot           // eot[s]>=0 indicates that an EOT edge goes to another
5173*16467b97STreehugger Robot           // state.
5174*16467b97STreehugger Robot           if (FEOT[S] >= 0) then  // EOT Transition to accept state?
5175*16467b97STreehugger Robot           begin
5176*16467b97STreehugger Robot             S := FEOT[S];
5177*16467b97STreehugger Robot             Input.Consume;
5178*16467b97STreehugger Robot             // TODO: I had this as return accept[eot[s]]
5179*16467b97STreehugger Robot             // which assumed here that the EOT edge always
5180*16467b97STreehugger Robot             // went to an accept...faster to do this, but
5181*16467b97STreehugger Robot             // what about predicated edges coming from EOT
5182*16467b97STreehugger Robot             // target?
5183*16467b97STreehugger Robot             Continue;
5184*16467b97STreehugger Robot           end;
5185*16467b97STreehugger Robot 
5186*16467b97STreehugger Robot           NoViableAlt(S, Input);
5187*16467b97STreehugger Robot           Exit;
5188*16467b97STreehugger Robot         end;
5189*16467b97STreehugger Robot         S := SNext;
5190*16467b97STreehugger Robot         Input.Consume;
5191*16467b97STreehugger Robot         Continue;
5192*16467b97STreehugger Robot       end;
5193*16467b97STreehugger Robot 
5194*16467b97STreehugger Robot       if (FEOT[S] >= 0) then
5195*16467b97STreehugger Robot       begin
5196*16467b97STreehugger Robot         // EOT Transition?
5197*16467b97STreehugger Robot         S := FEOT[S];
5198*16467b97STreehugger Robot         Input.Consume;
5199*16467b97STreehugger Robot         Continue;
5200*16467b97STreehugger Robot       end;
5201*16467b97STreehugger Robot 
5202*16467b97STreehugger Robot       if (C = Char(TToken.EOF)) and (FEOF[S] >= 0) then
5203*16467b97STreehugger Robot       begin
5204*16467b97STreehugger Robot         // EOF Transition to accept state?
5205*16467b97STreehugger Robot         Result := FAccept[FEOF[S]];
5206*16467b97STreehugger Robot         Exit;
5207*16467b97STreehugger Robot       end;
5208*16467b97STreehugger Robot 
5209*16467b97STreehugger Robot       // not in range and not EOF/EOT, must be invalid symbol
5210*16467b97STreehugger Robot       NoViableAlt(S, Input);
5211*16467b97STreehugger Robot       Exit;
5212*16467b97STreehugger Robot     end;
5213*16467b97STreehugger Robot   finally
5214*16467b97STreehugger Robot     Input.Rewind(Mark);
5215*16467b97STreehugger Robot   end;
5216*16467b97STreehugger Robot end;
5217*16467b97STreehugger Robot 
5218*16467b97STreehugger Robot procedure TDFA.SetRecognizer(const Value: IBaseRecognizer);
5219*16467b97STreehugger Robot begin
5220*16467b97STreehugger Robot   FRecognizer := Pointer(Value);
5221*16467b97STreehugger Robot end;
5222*16467b97STreehugger Robot 
5223*16467b97STreehugger Robot procedure TDFA.SetSpecialStateTransitionHandler(
5224*16467b97STreehugger Robot   const Value: TSpecialStateTransitionHandler);
5225*16467b97STreehugger Robot begin
5226*16467b97STreehugger Robot   FSpecialStateTransitionHandler := Value;
5227*16467b97STreehugger Robot end;
5228*16467b97STreehugger Robot 
SpecialStateTransitionnull5229*16467b97STreehugger Robot function TDFA.SpecialStateTransition(const S: Integer;
5230*16467b97STreehugger Robot   const Input: IIntStream): Integer;
5231*16467b97STreehugger Robot begin
5232*16467b97STreehugger Robot   // No default implementation
5233*16467b97STreehugger Robot   Result := -1;
5234*16467b97STreehugger Robot end;
5235*16467b97STreehugger Robot 
SpecialTransitionnull5236*16467b97STreehugger Robot function TDFA.SpecialTransition(const State, Symbol: Integer): Integer;
5237*16467b97STreehugger Robot begin
5238*16467b97STreehugger Robot   Result := 0;
5239*16467b97STreehugger Robot end;
5240*16467b97STreehugger Robot 
TDFA.UnpackEncodedString(5241*16467b97STreehugger Robot class function TDFA.UnpackEncodedString(
5242*16467b97STreehugger Robot   const EncodedString: String): TSmallintArray;
5243*16467b97STreehugger Robot var
5244*16467b97STreehugger Robot   I, J, DI, Size: Integer;
5245*16467b97STreehugger Robot   N, V: Char;
5246*16467b97STreehugger Robot begin
5247*16467b97STreehugger Robot   Size := 0;
5248*16467b97STreehugger Robot   I := 1;
5249*16467b97STreehugger Robot   while (I <= Length(EncodedString)) do
5250*16467b97STreehugger Robot   begin
5251*16467b97STreehugger Robot     Inc(Size,Integer(EncodedString[I]));
5252*16467b97STreehugger Robot     Inc(I,2);
5253*16467b97STreehugger Robot   end;
5254*16467b97STreehugger Robot 
5255*16467b97STreehugger Robot   SetLength(Result,Size);
5256*16467b97STreehugger Robot   DI := 0;
5257*16467b97STreehugger Robot   I := 1;
5258*16467b97STreehugger Robot   while (I <= Length(EncodedString)) do
5259*16467b97STreehugger Robot   begin
5260*16467b97STreehugger Robot     N := EncodedString[I];
5261*16467b97STreehugger Robot     V := EncodedString[I + 1];
5262*16467b97STreehugger Robot     // add v n times to data
5263*16467b97STreehugger Robot     for J := 1 to Integer(N) do
5264*16467b97STreehugger Robot     begin
5265*16467b97STreehugger Robot       Result[DI] := Smallint(V);
5266*16467b97STreehugger Robot       Inc(DI);
5267*16467b97STreehugger Robot     end;
5268*16467b97STreehugger Robot     Inc(I,2);
5269*16467b97STreehugger Robot   end;
5270*16467b97STreehugger Robot end;
5271*16467b97STreehugger Robot 
TDFA.UnpackEncodedStringArray(5272*16467b97STreehugger Robot class function TDFA.UnpackEncodedStringArray(
5273*16467b97STreehugger Robot   const EncodedStrings: array of String): TSmallintMatrix;
5274*16467b97STreehugger Robot var
5275*16467b97STreehugger Robot   I: Integer;
5276*16467b97STreehugger Robot begin
5277*16467b97STreehugger Robot   SetLength(Result,Length(EncodedStrings));
5278*16467b97STreehugger Robot   for I := 0 to Length(EncodedStrings) - 1 do
5279*16467b97STreehugger Robot     Result[I] := UnpackEncodedString(EncodedStrings[I]);
5280*16467b97STreehugger Robot end;
5281*16467b97STreehugger Robot 
TDFA.UnpackEncodedStringArray(5282*16467b97STreehugger Robot class function TDFA.UnpackEncodedStringArray(
5283*16467b97STreehugger Robot   const EncodedStrings: TStringArray): TSmallintMatrix;
5284*16467b97STreehugger Robot var
5285*16467b97STreehugger Robot   I: Integer;
5286*16467b97STreehugger Robot begin
5287*16467b97STreehugger Robot   SetLength(Result,Length(EncodedStrings));
5288*16467b97STreehugger Robot   for I := 0 to Length(EncodedStrings) - 1 do
5289*16467b97STreehugger Robot     Result[I] := UnpackEncodedString(EncodedStrings[I]);
5290*16467b97STreehugger Robot end;
5291*16467b97STreehugger Robot 
TDFA.UnpackEncodedStringToUnsignedChars(5292*16467b97STreehugger Robot class function TDFA.UnpackEncodedStringToUnsignedChars(
5293*16467b97STreehugger Robot   const EncodedString: String): TCharArray;
5294*16467b97STreehugger Robot var
5295*16467b97STreehugger Robot   I, J, DI, Size: Integer;
5296*16467b97STreehugger Robot   N, V: Char;
5297*16467b97STreehugger Robot begin
5298*16467b97STreehugger Robot   Size := 0;
5299*16467b97STreehugger Robot   I := 1;
5300*16467b97STreehugger Robot   while (I <= Length(EncodedString)) do
5301*16467b97STreehugger Robot   begin
5302*16467b97STreehugger Robot     Inc(Size,Integer(EncodedString[I]));
5303*16467b97STreehugger Robot     Inc(I,2);
5304*16467b97STreehugger Robot   end;
5305*16467b97STreehugger Robot 
5306*16467b97STreehugger Robot   SetLength(Result,Size);
5307*16467b97STreehugger Robot   DI := 0;
5308*16467b97STreehugger Robot   I := 1;
5309*16467b97STreehugger Robot   while (I <= Length(EncodedString)) do
5310*16467b97STreehugger Robot   begin
5311*16467b97STreehugger Robot     N := EncodedString[I];
5312*16467b97STreehugger Robot     V := EncodedString[I + 1];
5313*16467b97STreehugger Robot     // add v n times to data
5314*16467b97STreehugger Robot     for J := 1 to Integer(N) do
5315*16467b97STreehugger Robot     begin
5316*16467b97STreehugger Robot       Result[DI] := V;
5317*16467b97STreehugger Robot       Inc(DI);
5318*16467b97STreehugger Robot     end;
5319*16467b97STreehugger Robot     Inc(I,2);
5320*16467b97STreehugger Robot   end;
5321*16467b97STreehugger Robot end;
5322*16467b97STreehugger Robot 
5323*16467b97STreehugger Robot { TLexer }
5324*16467b97STreehugger Robot 
5325*16467b97STreehugger Robot constructor TLexer.Create;
5326*16467b97STreehugger Robot begin
5327*16467b97STreehugger Robot   inherited;
5328*16467b97STreehugger Robot end;
5329*16467b97STreehugger Robot 
5330*16467b97STreehugger Robot constructor TLexer.Create(const AInput: ICharStream);
5331*16467b97STreehugger Robot begin
5332*16467b97STreehugger Robot   inherited Create;
5333*16467b97STreehugger Robot   FInput := AInput;
5334*16467b97STreehugger Robot end;
5335*16467b97STreehugger Robot 
5336*16467b97STreehugger Robot constructor TLexer.Create(const AInput: ICharStream;
5337*16467b97STreehugger Robot   const AState: IRecognizerSharedState);
5338*16467b97STreehugger Robot begin
5339*16467b97STreehugger Robot   inherited Create(AState);
5340*16467b97STreehugger Robot   FInput := AInput;
5341*16467b97STreehugger Robot end;
5342*16467b97STreehugger Robot 
Emitnull5343*16467b97STreehugger Robot function TLexer.Emit: IToken;
5344*16467b97STreehugger Robot begin
5345*16467b97STreehugger Robot   Result := TCommonToken.Create(FInput, FState.TokenType, FState.Channel,
5346*16467b97STreehugger Robot     FState.TokenStartCharIndex, GetCharIndex - 1);
5347*16467b97STreehugger Robot   Result.Line := FState.TokenStartLine;
5348*16467b97STreehugger Robot   Result.Text := FState.Text;
5349*16467b97STreehugger Robot   Result.CharPositionInLine := FState.TokenStartCharPositionInLine;
5350*16467b97STreehugger Robot   Emit(Result);
5351*16467b97STreehugger Robot end;
5352*16467b97STreehugger Robot 
5353*16467b97STreehugger Robot procedure TLexer.Emit(const Token: IToken);
5354*16467b97STreehugger Robot begin
5355*16467b97STreehugger Robot   FState.Token := Token;
5356*16467b97STreehugger Robot end;
5357*16467b97STreehugger Robot 
GetCharErrorDisplaynull5358*16467b97STreehugger Robot function TLexer.GetCharErrorDisplay(const C: Integer): String;
5359*16467b97STreehugger Robot begin
5360*16467b97STreehugger Robot   case C of
5361*16467b97STreehugger Robot     // TToken.EOF
5362*16467b97STreehugger Robot     TOKEN_dot_EOF:
5363*16467b97STreehugger Robot       Result := '<EOF>';
5364*16467b97STreehugger Robot     10:
5365*16467b97STreehugger Robot       Result := '\n';
5366*16467b97STreehugger Robot     9:
5367*16467b97STreehugger Robot       Result := '\t';
5368*16467b97STreehugger Robot     13:
5369*16467b97STreehugger Robot       Result := '\r';
5370*16467b97STreehugger Robot     else
5371*16467b97STreehugger Robot       Result := Char(C);
5372*16467b97STreehugger Robot   end;
5373*16467b97STreehugger Robot   Result := '''' + Result + '''';
5374*16467b97STreehugger Robot end;
5375*16467b97STreehugger Robot 
GetCharIndexnull5376*16467b97STreehugger Robot function TLexer.GetCharIndex: Integer;
5377*16467b97STreehugger Robot begin
5378*16467b97STreehugger Robot   Result := FInput.Index;
5379*16467b97STreehugger Robot end;
5380*16467b97STreehugger Robot 
GetCharPositionInLinenull5381*16467b97STreehugger Robot function TLexer.GetCharPositionInLine: Integer;
5382*16467b97STreehugger Robot begin
5383*16467b97STreehugger Robot   Result := FInput.CharPositionInLine;
5384*16467b97STreehugger Robot end;
5385*16467b97STreehugger Robot 
TLexer.GetCharStream()5386*16467b97STreehugger Robot function TLexer.GetCharStream: ICharStream;
5387*16467b97STreehugger Robot begin
5388*16467b97STreehugger Robot   Result := FInput;
5389*16467b97STreehugger Robot end;
5390*16467b97STreehugger Robot 
GetErrorMessagenull5391*16467b97STreehugger Robot function TLexer.GetErrorMessage(const E: ERecognitionException;
5392*16467b97STreehugger Robot   const TokenNames: TStringArray): String;
5393*16467b97STreehugger Robot var
5394*16467b97STreehugger Robot   MTE: EMismatchedTokenException absolute E;
5395*16467b97STreehugger Robot   NVAE: ENoViableAltException absolute E;
5396*16467b97STreehugger Robot   EEE: EEarlyExitException absolute E;
5397*16467b97STreehugger Robot   MNSE: EMismatchedNotSetException absolute E;
5398*16467b97STreehugger Robot   MSE: EMismatchedSetException absolute E;
5399*16467b97STreehugger Robot   MRE: EMismatchedRangeException absolute E;
5400*16467b97STreehugger Robot begin
5401*16467b97STreehugger Robot   if (E is EMismatchedTokenException) then
5402*16467b97STreehugger Robot     Result := 'mismatched character ' + GetCharErrorDisplay(E.Character)
5403*16467b97STreehugger Robot       + ' expecting ' + GetCharErrorDisplay(MTE.Expecting)
5404*16467b97STreehugger Robot   else
5405*16467b97STreehugger Robot     if (E is ENoViableAltException) then
5406*16467b97STreehugger Robot       // for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>"
5407*16467b97STreehugger Robot       // and "(decision="+nvae.decisionNumber+") and
5408*16467b97STreehugger Robot       // "state "+nvae.stateNumber
5409*16467b97STreehugger Robot       Result := 'no viable alternative at character ' + GetCharErrorDisplay(NVAE.Character)
5410*16467b97STreehugger Robot     else
5411*16467b97STreehugger Robot       if (E is EEarlyExitException) then
5412*16467b97STreehugger Robot         // for development, can add "(decision="+eee.decisionNumber+")"
5413*16467b97STreehugger Robot         Result := 'required (...)+ loop did not match anything at character '
5414*16467b97STreehugger Robot           + GetCharErrorDisplay(EEE.Character)
5415*16467b97STreehugger Robot       else
5416*16467b97STreehugger Robot         if (E is EMismatchedNotSetException) then
5417*16467b97STreehugger Robot           Result := 'mismatched character ' + GetCharErrorDisplay(MNSE.Character)
5418*16467b97STreehugger Robot             + ' expecting set ' + MNSE.Expecting.ToString
5419*16467b97STreehugger Robot         else
5420*16467b97STreehugger Robot           if (E is EMismatchedSetException) then
5421*16467b97STreehugger Robot             Result := 'mismatched character ' + GetCharErrorDisplay(MSE.Character)
5422*16467b97STreehugger Robot               + ' expecting set ' + MSE.Expecting.ToString
5423*16467b97STreehugger Robot           else
5424*16467b97STreehugger Robot             if (E is EMismatchedRangeException) then
5425*16467b97STreehugger Robot               Result := 'mismatched character ' + GetCharErrorDisplay(MRE.Character)
5426*16467b97STreehugger Robot                 + ' expecting set ' + GetCharErrorDisplay(MRE.A) + '..'
5427*16467b97STreehugger Robot                 + GetCharErrorDisplay(MRE.B)
5428*16467b97STreehugger Robot             else
5429*16467b97STreehugger Robot               Result := inherited GetErrorMessage(E, TokenNames);
5430*16467b97STreehugger Robot end;
5431*16467b97STreehugger Robot 
TLexer.GetInput()5432*16467b97STreehugger Robot function TLexer.GetInput: IIntStream;
5433*16467b97STreehugger Robot begin
5434*16467b97STreehugger Robot   Result := FInput;
5435*16467b97STreehugger Robot end;
5436*16467b97STreehugger Robot 
GetLinenull5437*16467b97STreehugger Robot function TLexer.GetLine: Integer;
5438*16467b97STreehugger Robot begin
5439*16467b97STreehugger Robot   Result := FInput.Line;
5440*16467b97STreehugger Robot end;
5441*16467b97STreehugger Robot 
GetSourceNamenull5442*16467b97STreehugger Robot function TLexer.GetSourceName: String;
5443*16467b97STreehugger Robot begin
5444*16467b97STreehugger Robot   Result := FInput.SourceName;
5445*16467b97STreehugger Robot end;
5446*16467b97STreehugger Robot 
TLexer.GetText()5447*16467b97STreehugger Robot function TLexer.GetText: String;
5448*16467b97STreehugger Robot begin
5449*16467b97STreehugger Robot   if (FState.Text <> '') then
5450*16467b97STreehugger Robot     Result := FState.Text
5451*16467b97STreehugger Robot   else
5452*16467b97STreehugger Robot     Result := FInput.Substring(FState.TokenStartCharIndex, GetCharIndex - 1)
5453*16467b97STreehugger Robot end;
5454*16467b97STreehugger Robot 
5455*16467b97STreehugger Robot procedure TLexer.Match(const S: String);
5456*16467b97STreehugger Robot var
5457*16467b97STreehugger Robot   I: Integer;
5458*16467b97STreehugger Robot   MTE: EMismatchedTokenException;
5459*16467b97STreehugger Robot begin
5460*16467b97STreehugger Robot   for I := 1 to Length(S) do
5461*16467b97STreehugger Robot   begin
5462*16467b97STreehugger Robot     if (FInput.LA(1) <> Integer(S[I])) then
5463*16467b97STreehugger Robot     begin
5464*16467b97STreehugger Robot       if (FState.Backtracking > 0) then
5465*16467b97STreehugger Robot       begin
5466*16467b97STreehugger Robot         FState.Failed := True;
5467*16467b97STreehugger Robot         Exit;
5468*16467b97STreehugger Robot       end;
5469*16467b97STreehugger Robot       MTE := EMismatchedTokenException.Create(Integer(S[I]), FInput);
5470*16467b97STreehugger Robot       Recover(MTE); // don't really recover; just consume in lexer
5471*16467b97STreehugger Robot       raise MTE;
5472*16467b97STreehugger Robot     end;
5473*16467b97STreehugger Robot     FInput.Consume;
5474*16467b97STreehugger Robot     FState.Failed := False;
5475*16467b97STreehugger Robot   end;
5476*16467b97STreehugger Robot end;
5477*16467b97STreehugger Robot 
5478*16467b97STreehugger Robot procedure TLexer.Match(const C: Integer);
5479*16467b97STreehugger Robot var
5480*16467b97STreehugger Robot   MTE: EMismatchedTokenException;
5481*16467b97STreehugger Robot begin
5482*16467b97STreehugger Robot   if (FInput.LA(1) <> C) then
5483*16467b97STreehugger Robot   begin
5484*16467b97STreehugger Robot     if (FState.Backtracking > 0) then
5485*16467b97STreehugger Robot     begin
5486*16467b97STreehugger Robot       FState.Failed := True;
5487*16467b97STreehugger Robot       Exit;
5488*16467b97STreehugger Robot     end;
5489*16467b97STreehugger Robot     MTE := EMismatchedTokenException.Create(C, FInput);
5490*16467b97STreehugger Robot     Recover(MTE);
5491*16467b97STreehugger Robot     raise MTE;
5492*16467b97STreehugger Robot   end;
5493*16467b97STreehugger Robot   FInput.Consume;
5494*16467b97STreehugger Robot   FState.Failed := False;
5495*16467b97STreehugger Robot end;
5496*16467b97STreehugger Robot 
5497*16467b97STreehugger Robot procedure TLexer.MatchAny;
5498*16467b97STreehugger Robot begin
5499*16467b97STreehugger Robot   FInput.Consume;
5500*16467b97STreehugger Robot end;
5501*16467b97STreehugger Robot 
5502*16467b97STreehugger Robot procedure TLexer.MatchRange(const A, B: Integer);
5503*16467b97STreehugger Robot var
5504*16467b97STreehugger Robot   MRE: EMismatchedRangeException;
5505*16467b97STreehugger Robot begin
5506*16467b97STreehugger Robot   if (FInput.LA(1) < A) or (FInput.LA(1) > B) then
5507*16467b97STreehugger Robot   begin
5508*16467b97STreehugger Robot     if (FState.Backtracking > 0) then
5509*16467b97STreehugger Robot     begin
5510*16467b97STreehugger Robot       FState.Failed := True;
5511*16467b97STreehugger Robot       Exit;
5512*16467b97STreehugger Robot     end;
5513*16467b97STreehugger Robot     MRE := EMismatchedRangeException.Create(A, B, FInput);
5514*16467b97STreehugger Robot     Recover(MRE);
5515*16467b97STreehugger Robot     raise MRE;
5516*16467b97STreehugger Robot   end;
5517*16467b97STreehugger Robot   FInput.Consume;
5518*16467b97STreehugger Robot   FState.Failed := False;
5519*16467b97STreehugger Robot end;
5520*16467b97STreehugger Robot 
NextTokennull5521*16467b97STreehugger Robot function TLexer.NextToken: IToken;
5522*16467b97STreehugger Robot begin
5523*16467b97STreehugger Robot   while True do
5524*16467b97STreehugger Robot   begin
5525*16467b97STreehugger Robot     FState.Token := nil;
5526*16467b97STreehugger Robot     FState.Channel := TToken.DEFAULT_CHANNEL;
5527*16467b97STreehugger Robot     FState.TokenStartCharIndex := FInput.Index;
5528*16467b97STreehugger Robot     FState.TokenStartCharPositionInLine := FInput.CharPositionInLine;
5529*16467b97STreehugger Robot     FState.TokenStartLine := Finput.Line;
5530*16467b97STreehugger Robot     FState.Text := '';
5531*16467b97STreehugger Robot     if (FInput.LA(1) = Integer(cscEOF)) then
5532*16467b97STreehugger Robot     begin
5533*16467b97STreehugger Robot       Result := TToken.EOF_TOKEN;
5534*16467b97STreehugger Robot       Exit;
5535*16467b97STreehugger Robot     end;
5536*16467b97STreehugger Robot 
5537*16467b97STreehugger Robot     try
5538*16467b97STreehugger Robot       DoTokens;
5539*16467b97STreehugger Robot       if (FState.Token = nil) then
5540*16467b97STreehugger Robot         Emit
5541*16467b97STreehugger Robot       else
5542*16467b97STreehugger Robot         if (FState.Token = TToken.SKIP_TOKEN) then
5543*16467b97STreehugger Robot           Continue;
5544*16467b97STreehugger Robot       Exit(FState.Token);
5545*16467b97STreehugger Robot     except
5546*16467b97STreehugger Robot       on NVA: ENoViableAltException do
5547*16467b97STreehugger Robot       begin
5548*16467b97STreehugger Robot         ReportError(NVA);
5549*16467b97STreehugger Robot         Recover(NVA);  // throw out current char and try again
5550*16467b97STreehugger Robot       end;
5551*16467b97STreehugger Robot 
5552*16467b97STreehugger Robot       on RE: ERecognitionException do
5553*16467b97STreehugger Robot       begin
5554*16467b97STreehugger Robot         ReportError(RE);
5555*16467b97STreehugger Robot         // Match() routine has already called Recover()
5556*16467b97STreehugger Robot       end;
5557*16467b97STreehugger Robot     end;
5558*16467b97STreehugger Robot   end;
5559*16467b97STreehugger Robot end;
5560*16467b97STreehugger Robot 
5561*16467b97STreehugger Robot procedure TLexer.Recover(const RE: ERecognitionException);
5562*16467b97STreehugger Robot begin
5563*16467b97STreehugger Robot   FInput.Consume;
5564*16467b97STreehugger Robot end;
5565*16467b97STreehugger Robot 
5566*16467b97STreehugger Robot procedure TLexer.ReportError(const E: ERecognitionException);
5567*16467b97STreehugger Robot begin
5568*16467b97STreehugger Robot   DisplayRecognitionError(GetTokenNames, E);
5569*16467b97STreehugger Robot end;
5570*16467b97STreehugger Robot 
5571*16467b97STreehugger Robot procedure TLexer.Reset;
5572*16467b97STreehugger Robot begin
5573*16467b97STreehugger Robot   inherited; // reset all recognizer state variables
5574*16467b97STreehugger Robot   // wack Lexer state variables
5575*16467b97STreehugger Robot   if Assigned(FInput) then
5576*16467b97STreehugger Robot     FInput.Seek(0);  // rewind the input
5577*16467b97STreehugger Robot   if (FState = nil) then
5578*16467b97STreehugger Robot     Exit;  // no shared state work to do
5579*16467b97STreehugger Robot   FState.Token := nil;
5580*16467b97STreehugger Robot   FState.TokenType := TToken.INVALID_TOKEN_TYPE;
5581*16467b97STreehugger Robot   FState.Channel := TToken.DEFAULT_CHANNEL;
5582*16467b97STreehugger Robot   FState.TokenStartCharIndex := -1;
5583*16467b97STreehugger Robot   FState.TokenStartCharPositionInLine := -1;
5584*16467b97STreehugger Robot   FState.TokenStartLine := -1;
5585*16467b97STreehugger Robot   FState.Text := '';
5586*16467b97STreehugger Robot end;
5587*16467b97STreehugger Robot 
5588*16467b97STreehugger Robot procedure TLexer.SetCharStream(const Value: ICharStream);
5589*16467b97STreehugger Robot begin
5590*16467b97STreehugger Robot   FInput := nil;
5591*16467b97STreehugger Robot   Reset;
5592*16467b97STreehugger Robot   FInput := Value;
5593*16467b97STreehugger Robot end;
5594*16467b97STreehugger Robot 
5595*16467b97STreehugger Robot procedure TLexer.SetText(const Value: String);
5596*16467b97STreehugger Robot begin
5597*16467b97STreehugger Robot   FState.Text := Value;
5598*16467b97STreehugger Robot end;
5599*16467b97STreehugger Robot 
5600*16467b97STreehugger Robot procedure TLexer.Skip;
5601*16467b97STreehugger Robot begin
5602*16467b97STreehugger Robot   FState.Token := TToken.SKIP_TOKEN;
5603*16467b97STreehugger Robot end;
5604*16467b97STreehugger Robot 
5605*16467b97STreehugger Robot procedure TLexer.TraceIn(const RuleName: String; const RuleIndex: Integer);
5606*16467b97STreehugger Robot var
5607*16467b97STreehugger Robot   InputSymbol: String;
5608*16467b97STreehugger Robot begin
5609*16467b97STreehugger Robot   InputSymbol := Char(FInput.LT(1)) + ' line=' + IntToStr(GetLine) + ':'
5610*16467b97STreehugger Robot     + IntToStr(GetCharPositionInLine);
5611*16467b97STreehugger Robot   inherited TraceIn(RuleName, RuleIndex, InputSymbol);
5612*16467b97STreehugger Robot end;
5613*16467b97STreehugger Robot 
5614*16467b97STreehugger Robot procedure TLexer.TraceOut(const RuleName: String; const RuleIndex: Integer);
5615*16467b97STreehugger Robot var
5616*16467b97STreehugger Robot   InputSymbol: String;
5617*16467b97STreehugger Robot begin
5618*16467b97STreehugger Robot   InputSymbol := Char(FInput.LT(1)) + ' line=' + IntToStr(GetLine) + ':'
5619*16467b97STreehugger Robot     + IntToStr(GetCharPositionInLine);
5620*16467b97STreehugger Robot   inherited TraceOut(RuleName, RuleIndex, InputSymbol);
5621*16467b97STreehugger Robot end;
5622*16467b97STreehugger Robot 
5623*16467b97STreehugger Robot { TParser }
5624*16467b97STreehugger Robot 
5625*16467b97STreehugger Robot constructor TParser.Create(const AInput: ITokenStream);
5626*16467b97STreehugger Robot begin
5627*16467b97STreehugger Robot   inherited Create; // highlight that we go to base class to set state object
5628*16467b97STreehugger Robot   SetTokenStream(AInput);
5629*16467b97STreehugger Robot end;
5630*16467b97STreehugger Robot 
5631*16467b97STreehugger Robot constructor TParser.Create(const AInput: ITokenStream;
5632*16467b97STreehugger Robot   const AState: IRecognizerSharedState);
5633*16467b97STreehugger Robot begin
5634*16467b97STreehugger Robot   inherited Create(AState); // share the state object with another parser
5635*16467b97STreehugger Robot   SetTokenStream(AInput);
5636*16467b97STreehugger Robot end;
5637*16467b97STreehugger Robot 
TParser.GetCurrentInputSymbol(5638*16467b97STreehugger Robot function TParser.GetCurrentInputSymbol(
5639*16467b97STreehugger Robot   const Input: IIntStream): IANTLRInterface;
5640*16467b97STreehugger Robot begin
5641*16467b97STreehugger Robot   Result := FInput.LT(1)
5642*16467b97STreehugger Robot end;
5643*16467b97STreehugger Robot 
TParser.GetInput()5644*16467b97STreehugger Robot function TParser.GetInput: IIntStream;
5645*16467b97STreehugger Robot begin
5646*16467b97STreehugger Robot   Result := FInput;
5647*16467b97STreehugger Robot end;
5648*16467b97STreehugger Robot 
GetMissingSymbolnull5649*16467b97STreehugger Robot function TParser.GetMissingSymbol(const Input: IIntStream;
5650*16467b97STreehugger Robot   const E: ERecognitionException; const ExpectedTokenType: Integer;
5651*16467b97STreehugger Robot   const Follow: IBitSet): IANTLRInterface;
5652*16467b97STreehugger Robot var
5653*16467b97STreehugger Robot   TokenText: String;
5654*16467b97STreehugger Robot   T: ICommonToken;
5655*16467b97STreehugger Robot   Current: IToken;
5656*16467b97STreehugger Robot begin
5657*16467b97STreehugger Robot   if (ExpectedTokenType = TToken.EOF) then
5658*16467b97STreehugger Robot     TokenText := '<missing EOF>'
5659*16467b97STreehugger Robot   else
5660*16467b97STreehugger Robot     TokenText := '<missing ' + GetTokenNames[ExpectedTokenType] + '>';
5661*16467b97STreehugger Robot   T := TCommonToken.Create(ExpectedTokenType, TokenText);
5662*16467b97STreehugger Robot   Current := FInput.LT(1);
5663*16467b97STreehugger Robot   if (Current.TokenType = TToken.EOF) then
5664*16467b97STreehugger Robot     Current := FInput.LT(-1);
5665*16467b97STreehugger Robot   T.Line := Current.Line;
5666*16467b97STreehugger Robot   T.CharPositionInLine := Current.CharPositionInLine;
5667*16467b97STreehugger Robot   T.Channel := DEFAULT_TOKEN_CHANNEL;
5668*16467b97STreehugger Robot   Result := T;
5669*16467b97STreehugger Robot end;
5670*16467b97STreehugger Robot 
TParser.GetSourceName()5671*16467b97STreehugger Robot function TParser.GetSourceName: String;
5672*16467b97STreehugger Robot begin
5673*16467b97STreehugger Robot   Result := FInput.SourceName;
5674*16467b97STreehugger Robot end;
5675*16467b97STreehugger Robot 
TParser.GetTokenStream()5676*16467b97STreehugger Robot function TParser.GetTokenStream: ITokenStream;
5677*16467b97STreehugger Robot begin
5678*16467b97STreehugger Robot   Result := FInput;
5679*16467b97STreehugger Robot end;
5680*16467b97STreehugger Robot 
5681*16467b97STreehugger Robot procedure TParser.Reset;
5682*16467b97STreehugger Robot begin
5683*16467b97STreehugger Robot   inherited; // reset all recognizer state variables
5684*16467b97STreehugger Robot   if Assigned(FInput) then
5685*16467b97STreehugger Robot     FInput.Seek(0); // rewind the input
5686*16467b97STreehugger Robot end;
5687*16467b97STreehugger Robot 
5688*16467b97STreehugger Robot procedure TParser.SetTokenStream(const Value: ITokenStream);
5689*16467b97STreehugger Robot begin
5690*16467b97STreehugger Robot   FInput := nil;
5691*16467b97STreehugger Robot   Reset;
5692*16467b97STreehugger Robot   FInput := Value;
5693*16467b97STreehugger Robot end;
5694*16467b97STreehugger Robot 
5695*16467b97STreehugger Robot procedure TParser.TraceIn(const RuleName: String; const RuleIndex: Integer);
5696*16467b97STreehugger Robot begin
5697*16467b97STreehugger Robot   inherited TraceIn(RuleName, RuleIndex, FInput.LT(1).ToString);
5698*16467b97STreehugger Robot end;
5699*16467b97STreehugger Robot 
5700*16467b97STreehugger Robot procedure TParser.TraceOut(const RuleName: String; const RuleIndex: Integer);
5701*16467b97STreehugger Robot begin
5702*16467b97STreehugger Robot   inherited TraceOut(RuleName, RuleIndex, FInput.LT(1).ToString);
5703*16467b97STreehugger Robot end;
5704*16467b97STreehugger Robot 
5705*16467b97STreehugger Robot { TRuleReturnScope }
5706*16467b97STreehugger Robot 
TRuleReturnScope.GetStart()5707*16467b97STreehugger Robot function TRuleReturnScope.GetStart: IANTLRInterface;
5708*16467b97STreehugger Robot begin
5709*16467b97STreehugger Robot   Result := nil;
5710*16467b97STreehugger Robot end;
5711*16467b97STreehugger Robot 
GetStopnull5712*16467b97STreehugger Robot function TRuleReturnScope.GetStop: IANTLRInterface;
5713*16467b97STreehugger Robot begin
5714*16467b97STreehugger Robot   Result := nil;
5715*16467b97STreehugger Robot end;
5716*16467b97STreehugger Robot 
TRuleReturnScope.GetTemplate()5717*16467b97STreehugger Robot function TRuleReturnScope.GetTemplate: IANTLRInterface;
5718*16467b97STreehugger Robot begin
5719*16467b97STreehugger Robot   Result := nil;
5720*16467b97STreehugger Robot end;
5721*16467b97STreehugger Robot 
TRuleReturnScope.GetTree()5722*16467b97STreehugger Robot function TRuleReturnScope.GetTree: IANTLRInterface;
5723*16467b97STreehugger Robot begin
5724*16467b97STreehugger Robot   Result := nil;
5725*16467b97STreehugger Robot end;
5726*16467b97STreehugger Robot 
5727*16467b97STreehugger Robot procedure TRuleReturnScope.SetStart(const Value: IANTLRInterface);
5728*16467b97STreehugger Robot begin
5729*16467b97STreehugger Robot   raise EInvalidOperation.Create('Setter has not been defined for this property.');
5730*16467b97STreehugger Robot end;
5731*16467b97STreehugger Robot 
5732*16467b97STreehugger Robot procedure TRuleReturnScope.SetStop(const Value: IANTLRInterface);
5733*16467b97STreehugger Robot begin
5734*16467b97STreehugger Robot   raise EInvalidOperation.Create('Setter has not been defined for this property.');
5735*16467b97STreehugger Robot end;
5736*16467b97STreehugger Robot 
5737*16467b97STreehugger Robot procedure TRuleReturnScope.SetTree(const Value: IANTLRInterface);
5738*16467b97STreehugger Robot begin
5739*16467b97STreehugger Robot   raise EInvalidOperation.Create('Setter has not been defined for this property.');
5740*16467b97STreehugger Robot end;
5741*16467b97STreehugger Robot 
5742*16467b97STreehugger Robot { TParserRuleReturnScope }
5743*16467b97STreehugger Robot 
TParserRuleReturnScope.GetStart()5744*16467b97STreehugger Robot function TParserRuleReturnScope.GetStart: IANTLRInterface;
5745*16467b97STreehugger Robot begin
5746*16467b97STreehugger Robot   Result := FStart;
5747*16467b97STreehugger Robot end;
5748*16467b97STreehugger Robot 
GetStopnull5749*16467b97STreehugger Robot function TParserRuleReturnScope.GetStop: IANTLRInterface;
5750*16467b97STreehugger Robot begin
5751*16467b97STreehugger Robot   Result := FStop;
5752*16467b97STreehugger Robot end;
5753*16467b97STreehugger Robot 
5754*16467b97STreehugger Robot procedure TParserRuleReturnScope.SetStart(const Value: IANTLRInterface);
5755*16467b97STreehugger Robot begin
5756*16467b97STreehugger Robot   FStart := Value as IToken;
5757*16467b97STreehugger Robot end;
5758*16467b97STreehugger Robot 
5759*16467b97STreehugger Robot procedure TParserRuleReturnScope.SetStop(const Value: IANTLRInterface);
5760*16467b97STreehugger Robot begin
5761*16467b97STreehugger Robot   FStop := Value as IToken;
5762*16467b97STreehugger Robot end;
5763*16467b97STreehugger Robot 
5764*16467b97STreehugger Robot { TTokenRewriteStream }
5765*16467b97STreehugger Robot 
5766*16467b97STreehugger Robot procedure TTokenRewriteStream.Delete(const Start, Stop: IToken);
5767*16467b97STreehugger Robot begin
5768*16467b97STreehugger Robot   Delete(DEFAULT_PROGRAM_NAME, Start, Stop);
5769*16467b97STreehugger Robot end;
5770*16467b97STreehugger Robot 
5771*16467b97STreehugger Robot procedure TTokenRewriteStream.Delete(const IndexT: IToken);
5772*16467b97STreehugger Robot begin
5773*16467b97STreehugger Robot   Delete(DEFAULT_PROGRAM_NAME, IndexT, IndexT);
5774*16467b97STreehugger Robot end;
5775*16467b97STreehugger Robot 
5776*16467b97STreehugger Robot constructor TTokenRewriteStream.Create;
5777*16467b97STreehugger Robot begin
5778*16467b97STreehugger Robot   inherited;
5779*16467b97STreehugger Robot   Init;
5780*16467b97STreehugger Robot end;
5781*16467b97STreehugger Robot 
5782*16467b97STreehugger Robot constructor TTokenRewriteStream.Create(const ATokenSource: ITokenSource);
5783*16467b97STreehugger Robot begin
5784*16467b97STreehugger Robot   inherited Create(ATokenSource);
5785*16467b97STreehugger Robot   Init;
5786*16467b97STreehugger Robot end;
5787*16467b97STreehugger Robot 
5788*16467b97STreehugger Robot constructor TTokenRewriteStream.Create(const ALexer: ILexer);
5789*16467b97STreehugger Robot begin
5790*16467b97STreehugger Robot   Create(ALexer as ITokenSource);
5791*16467b97STreehugger Robot end;
5792*16467b97STreehugger Robot 
5793*16467b97STreehugger Robot constructor TTokenRewriteStream.Create(const ALexer: ILexer;
5794*16467b97STreehugger Robot   const AChannel: Integer);
5795*16467b97STreehugger Robot begin
5796*16467b97STreehugger Robot   Create(ALexer as ITokenSource, AChannel);
5797*16467b97STreehugger Robot end;
5798*16467b97STreehugger Robot 
CatOpTextnull5799*16467b97STreehugger Robot function TTokenRewriteStream.CatOpText(const A, B: IANTLRInterface): IANTLRInterface;
5800*16467b97STreehugger Robot var
5801*16467b97STreehugger Robot   X, Y: String;
5802*16467b97STreehugger Robot begin
5803*16467b97STreehugger Robot   if Assigned(A) then
5804*16467b97STreehugger Robot     X := A.ToString
5805*16467b97STreehugger Robot   else
5806*16467b97STreehugger Robot     X := '';
5807*16467b97STreehugger Robot 
5808*16467b97STreehugger Robot   if Assigned(B) then
5809*16467b97STreehugger Robot     Y := B.ToString
5810*16467b97STreehugger Robot   else
5811*16467b97STreehugger Robot     Y := '';
5812*16467b97STreehugger Robot 
5813*16467b97STreehugger Robot   Result := TANTLRString.Create(X + Y);
5814*16467b97STreehugger Robot end;
5815*16467b97STreehugger Robot 
5816*16467b97STreehugger Robot constructor TTokenRewriteStream.Create(const ATokenSource: ITokenSource;
5817*16467b97STreehugger Robot   const AChannel: Integer);
5818*16467b97STreehugger Robot begin
5819*16467b97STreehugger Robot   inherited Create(ATokenSource, AChannel);
5820*16467b97STreehugger Robot   Init;
5821*16467b97STreehugger Robot end;
5822*16467b97STreehugger Robot 
5823*16467b97STreehugger Robot procedure TTokenRewriteStream.Delete(const ProgramName: String; const Start,
5824*16467b97STreehugger Robot   Stop: IToken);
5825*16467b97STreehugger Robot begin
5826*16467b97STreehugger Robot   Replace(ProgramName, Start, Stop, nil);
5827*16467b97STreehugger Robot end;
5828*16467b97STreehugger Robot 
5829*16467b97STreehugger Robot procedure TTokenRewriteStream.Delete(const ProgramName: String; const Start,
5830*16467b97STreehugger Robot   Stop: Integer);
5831*16467b97STreehugger Robot begin
5832*16467b97STreehugger Robot   Replace(ProgramName, Start, Stop, nil);
5833*16467b97STreehugger Robot end;
5834*16467b97STreehugger Robot 
5835*16467b97STreehugger Robot procedure TTokenRewriteStream.Delete(const Start, Stop: Integer);
5836*16467b97STreehugger Robot begin
5837*16467b97STreehugger Robot   Delete(DEFAULT_PROGRAM_NAME, Start, Stop);
5838*16467b97STreehugger Robot end;
5839*16467b97STreehugger Robot 
5840*16467b97STreehugger Robot procedure TTokenRewriteStream.Delete(const Index: Integer);
5841*16467b97STreehugger Robot begin
5842*16467b97STreehugger Robot   Delete(DEFAULT_PROGRAM_NAME, Index, Index);
5843*16467b97STreehugger Robot end;
5844*16467b97STreehugger Robot 
5845*16467b97STreehugger Robot procedure TTokenRewriteStream.DeleteProgram(const ProgramName: String);
5846*16467b97STreehugger Robot begin
5847*16467b97STreehugger Robot   Rollback(ProgramName, MIN_TOKEN_INDEX);
5848*16467b97STreehugger Robot end;
5849*16467b97STreehugger Robot 
5850*16467b97STreehugger Robot procedure TTokenRewriteStream.DeleteProgram;
5851*16467b97STreehugger Robot begin
5852*16467b97STreehugger Robot   DeleteProgram(DEFAULT_PROGRAM_NAME);
5853*16467b97STreehugger Robot end;
5854*16467b97STreehugger Robot 
GetLastRewriteTokenIndexnull5855*16467b97STreehugger Robot function TTokenRewriteStream.GetLastRewriteTokenIndex: Integer;
5856*16467b97STreehugger Robot begin
5857*16467b97STreehugger Robot   Result := GetLastRewriteTokenIndex(DEFAULT_PROGRAM_NAME);
5858*16467b97STreehugger Robot end;
5859*16467b97STreehugger Robot 
GetKindOfOpsnull5860*16467b97STreehugger Robot function TTokenRewriteStream.GetKindOfOps(
5861*16467b97STreehugger Robot   const Rewrites: IList<IRewriteOperation>;
5862*16467b97STreehugger Robot   const Kind: TGUID): IList<IRewriteOperation>;
5863*16467b97STreehugger Robot begin
5864*16467b97STreehugger Robot   Result := GetKindOfOps(Rewrites, Kind, Rewrites.Count);
5865*16467b97STreehugger Robot end;
5866*16467b97STreehugger Robot 
GetKindOfOpsnull5867*16467b97STreehugger Robot function TTokenRewriteStream.GetKindOfOps(
5868*16467b97STreehugger Robot   const Rewrites: IList<IRewriteOperation>; const Kind: TGUID;
5869*16467b97STreehugger Robot   const Before: Integer): IList<IRewriteOperation>;
5870*16467b97STreehugger Robot var
5871*16467b97STreehugger Robot   I: Integer;
5872*16467b97STreehugger Robot   Op: IRewriteOperation;
5873*16467b97STreehugger Robot   Obj: IInterface;
5874*16467b97STreehugger Robot begin
5875*16467b97STreehugger Robot   Result := TList<IRewriteOperation>.Create;
5876*16467b97STreehugger Robot   I := 0;
5877*16467b97STreehugger Robot   while (I < Before) and (I < Rewrites.Count) do
5878*16467b97STreehugger Robot   begin
5879*16467b97STreehugger Robot     Op := Rewrites[I];
5880*16467b97STreehugger Robot     if Assigned(Op) and (Op.QueryInterface(Kind, Obj) = 0) then
5881*16467b97STreehugger Robot       Result.Add(Op);
5882*16467b97STreehugger Robot     Inc(I);
5883*16467b97STreehugger Robot   end;
5884*16467b97STreehugger Robot end;
5885*16467b97STreehugger Robot 
GetLastRewriteTokenIndexnull5886*16467b97STreehugger Robot function TTokenRewriteStream.GetLastRewriteTokenIndex(
5887*16467b97STreehugger Robot   const ProgramName: String): Integer;
5888*16467b97STreehugger Robot begin
5889*16467b97STreehugger Robot   if (not FLastRewriteTokenIndexes.TryGetValue(ProgramName, Result)) then
5890*16467b97STreehugger Robot     Result := -1;
5891*16467b97STreehugger Robot end;
5892*16467b97STreehugger Robot 
GetProgramnull5893*16467b97STreehugger Robot function TTokenRewriteStream.GetProgram(
5894*16467b97STreehugger Robot   const Name: String): IList<IRewriteOperation>;
5895*16467b97STreehugger Robot var
5896*16467b97STreehugger Robot   InstructionStream: IList<IRewriteOperation>;
5897*16467b97STreehugger Robot begin
5898*16467b97STreehugger Robot   InstructionStream := FPrograms[Name];
5899*16467b97STreehugger Robot   if (InstructionStream = nil) then
5900*16467b97STreehugger Robot     InstructionStream := InitializeProgram(Name);
5901*16467b97STreehugger Robot   Result := InstructionStream;
5902*16467b97STreehugger Robot end;
5903*16467b97STreehugger Robot 
5904*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertAfter(const ProgramName: String;
5905*16467b97STreehugger Robot   const T: IToken; const Text: IANTLRInterface);
5906*16467b97STreehugger Robot begin
5907*16467b97STreehugger Robot   InsertAfter(ProgramName, T.TokenIndex, Text);
5908*16467b97STreehugger Robot end;
5909*16467b97STreehugger Robot 
5910*16467b97STreehugger Robot procedure TTokenRewriteStream.Init;
5911*16467b97STreehugger Robot var
5912*16467b97STreehugger Robot   List: IList<IRewriteOperation>;
5913*16467b97STreehugger Robot begin
5914*16467b97STreehugger Robot   FPrograms := TDictionary<String, IList<IRewriteOperation>>.Create;
5915*16467b97STreehugger Robot   List := TList<IRewriteOperation>.Create;
5916*16467b97STreehugger Robot   List.Capacity := PROGRAM_INIT_SIZE;
5917*16467b97STreehugger Robot   FPrograms.Add(DEFAULT_PROGRAM_NAME, List);
5918*16467b97STreehugger Robot   FLastRewriteTokenIndexes := TDictionary<String, Integer>.Create;
5919*16467b97STreehugger Robot end;
5920*16467b97STreehugger Robot 
TTokenRewriteStream.InitializeProgram(5921*16467b97STreehugger Robot function TTokenRewriteStream.InitializeProgram(
5922*16467b97STreehugger Robot   const Name: String): IList<IRewriteOperation>;
5923*16467b97STreehugger Robot begin
5924*16467b97STreehugger Robot   Result := TList<IRewriteOperation>.Create;
5925*16467b97STreehugger Robot   Result.Capacity := PROGRAM_INIT_SIZE;
5926*16467b97STreehugger Robot   FPrograms[Name] := Result;
5927*16467b97STreehugger Robot end;
5928*16467b97STreehugger Robot 
5929*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertAfter(const ProgramName: String;
5930*16467b97STreehugger Robot   const Index: Integer; const Text: IANTLRInterface);
5931*16467b97STreehugger Robot begin
5932*16467b97STreehugger Robot   // to insert after, just insert before next index (even if past end)
5933*16467b97STreehugger Robot   InsertBefore(ProgramName, Index + 1, Text);
5934*16467b97STreehugger Robot end;
5935*16467b97STreehugger Robot 
5936*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertAfter(const T: IToken;
5937*16467b97STreehugger Robot   const Text: IANTLRInterface);
5938*16467b97STreehugger Robot begin
5939*16467b97STreehugger Robot   InsertAfter(DEFAULT_PROGRAM_NAME, T, Text);
5940*16467b97STreehugger Robot end;
5941*16467b97STreehugger Robot 
5942*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertAfter(const Index: Integer;
5943*16467b97STreehugger Robot   const Text: IANTLRInterface);
5944*16467b97STreehugger Robot begin
5945*16467b97STreehugger Robot   InsertAfter(DEFAULT_PROGRAM_NAME, Index, Text);
5946*16467b97STreehugger Robot end;
5947*16467b97STreehugger Robot 
5948*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertBefore(const Index: Integer;
5949*16467b97STreehugger Robot   const Text: IANTLRInterface);
5950*16467b97STreehugger Robot begin
5951*16467b97STreehugger Robot   InsertBefore(DEFAULT_PROGRAM_NAME, Index, Text);
5952*16467b97STreehugger Robot end;
5953*16467b97STreehugger Robot 
5954*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertBefore(const ProgramName: String;
5955*16467b97STreehugger Robot   const T: IToken; const Text: IANTLRInterface);
5956*16467b97STreehugger Robot begin
5957*16467b97STreehugger Robot   InsertBefore(ProgramName, T.TokenIndex, Text);
5958*16467b97STreehugger Robot end;
5959*16467b97STreehugger Robot 
5960*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertBefore(const ProgramName: String;
5961*16467b97STreehugger Robot   const Index: Integer; const Text: IANTLRInterface);
5962*16467b97STreehugger Robot var
5963*16467b97STreehugger Robot   Op: IRewriteOperation;
5964*16467b97STreehugger Robot begin
5965*16467b97STreehugger Robot   Op := TInsertBeforeOp.Create(Index, Text, Self);
5966*16467b97STreehugger Robot   GetProgram(ProgramName).Add(Op);
5967*16467b97STreehugger Robot end;
5968*16467b97STreehugger Robot 
5969*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertBefore(const T: IToken;
5970*16467b97STreehugger Robot   const Text: IANTLRInterface);
5971*16467b97STreehugger Robot begin
5972*16467b97STreehugger Robot   InsertBefore(DEFAULT_PROGRAM_NAME, T, Text);
5973*16467b97STreehugger Robot end;
5974*16467b97STreehugger Robot 
5975*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const Start, Stop: IToken;
5976*16467b97STreehugger Robot   const Text: IANTLRInterface);
5977*16467b97STreehugger Robot begin
5978*16467b97STreehugger Robot   Replace(DEFAULT_PROGRAM_NAME, Stop, Stop, Text);
5979*16467b97STreehugger Robot end;
5980*16467b97STreehugger Robot 
5981*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const IndexT: IToken;
5982*16467b97STreehugger Robot   const Text: IANTLRInterface);
5983*16467b97STreehugger Robot begin
5984*16467b97STreehugger Robot   Replace(DEFAULT_PROGRAM_NAME, IndexT, IndexT, Text);
5985*16467b97STreehugger Robot end;
5986*16467b97STreehugger Robot 
5987*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const ProgramName: String; const Start,
5988*16467b97STreehugger Robot   Stop: Integer; const Text: IANTLRInterface);
5989*16467b97STreehugger Robot var
5990*16467b97STreehugger Robot   Op: IRewriteOperation;
5991*16467b97STreehugger Robot   Rewrites: IList<IRewriteOperation>;
5992*16467b97STreehugger Robot begin
5993*16467b97STreehugger Robot   if (Start > Stop) or (Start < 0) or (Stop < 0) or (Stop >= GetTokens.Count) then
5994*16467b97STreehugger Robot     raise EArgumentOutOfRangeException.Create('replace: range invalid: '
5995*16467b97STreehugger Robot       + IntToStr(Start) + '..' + IntToStr(Stop) + '(size='
5996*16467b97STreehugger Robot       + IntToStr(GetTokens.Count) + ')');
5997*16467b97STreehugger Robot 
5998*16467b97STreehugger Robot   Op := TReplaceOp.Create(Start, Stop, Text, Self);
5999*16467b97STreehugger Robot   Rewrites := GetProgram(ProgramName);
6000*16467b97STreehugger Robot   Op.InstructionIndex := Rewrites.Count;
6001*16467b97STreehugger Robot   Rewrites.Add(Op);
6002*16467b97STreehugger Robot end;
6003*16467b97STreehugger Robot 
ReduceToSingleOperationPerIndexnull6004*16467b97STreehugger Robot function TTokenRewriteStream.ReduceToSingleOperationPerIndex(
6005*16467b97STreehugger Robot   const Rewrites: IList<IRewriteOperation>): IDictionary<Integer, IRewriteOperation>;
6006*16467b97STreehugger Robot var
6007*16467b97STreehugger Robot   I, J: Integer;
6008*16467b97STreehugger Robot   Op: IRewriteOperation;
6009*16467b97STreehugger Robot   ROp, PrevROp: IReplaceOp;
6010*16467b97STreehugger Robot   IOp, PrevIOp: IInsertBeforeOp;
6011*16467b97STreehugger Robot   Inserts, PrevInserts, PrevReplaces: IList<IRewriteOperation>;
6012*16467b97STreehugger Robot   Disjoint, Same: Boolean;
6013*16467b97STreehugger Robot begin
6014*16467b97STreehugger Robot   // WALK REPLACES
6015*16467b97STreehugger Robot   for I := 0 to Rewrites.Count - 1 do
6016*16467b97STreehugger Robot   begin
6017*16467b97STreehugger Robot     Op := Rewrites[I];
6018*16467b97STreehugger Robot     if (Op = nil) then
6019*16467b97STreehugger Robot       Continue;
6020*16467b97STreehugger Robot     if (not Supports(Op, IReplaceOp, ROp)) then
6021*16467b97STreehugger Robot       Continue;
6022*16467b97STreehugger Robot 
6023*16467b97STreehugger Robot     // Wipe prior inserts within range
6024*16467b97STreehugger Robot     Inserts := GetKindOfOps(Rewrites, IInsertBeforeOp, I);
6025*16467b97STreehugger Robot     for J := 0 to Inserts.Count - 1 do
6026*16467b97STreehugger Robot     begin
6027*16467b97STreehugger Robot       IOp := Inserts[J] as IInsertBeforeOp;
6028*16467b97STreehugger Robot       if (IOp.Index >= ROp.Index) and (IOp.Index <= ROp.LastIndex) then
6029*16467b97STreehugger Robot       begin
6030*16467b97STreehugger Robot         // delete insert as it's a no-op.
6031*16467b97STreehugger Robot         Rewrites[IOp.InstructionIndex] := nil;
6032*16467b97STreehugger Robot       end;
6033*16467b97STreehugger Robot     end;
6034*16467b97STreehugger Robot 
6035*16467b97STreehugger Robot     // Drop any prior replaces contained within
6036*16467b97STreehugger Robot     PrevReplaces := GetKindOfOps(Rewrites, IReplaceOp, I);
6037*16467b97STreehugger Robot     for J := 0 to PrevReplaces.Count - 1 do
6038*16467b97STreehugger Robot     begin
6039*16467b97STreehugger Robot       PrevROp := PrevReplaces[J] as IReplaceOp;
6040*16467b97STreehugger Robot       if (PrevROp.Index >= ROp.Index) and (PrevROp.LastIndex <= ROp.LastIndex) then
6041*16467b97STreehugger Robot       begin
6042*16467b97STreehugger Robot         // delete replace as it's a no-op.
6043*16467b97STreehugger Robot         Rewrites[PrevROp.InstructionIndex] := nil;
6044*16467b97STreehugger Robot         Continue;
6045*16467b97STreehugger Robot       end;
6046*16467b97STreehugger Robot       // throw exception unless disjoint or identical
6047*16467b97STreehugger Robot       Disjoint := (PrevROp.LastIndex < ROp.Index) or (PrevROp.Index > ROp.LastIndex);
6048*16467b97STreehugger Robot       Same := (PrevROp.Index = ROp.Index) and (PrevROp.LastIndex = ROp.LastIndex);
6049*16467b97STreehugger Robot       if (not Disjoint) and (not Same) then
6050*16467b97STreehugger Robot         raise EArgumentOutOfRangeException.Create('replace of boundaries of '
6051*16467b97STreehugger Robot           + ROp.ToString + ' overlap with previous ' + PrevROp.ToString);
6052*16467b97STreehugger Robot     end;
6053*16467b97STreehugger Robot   end;
6054*16467b97STreehugger Robot 
6055*16467b97STreehugger Robot   // WALK INSERTS
6056*16467b97STreehugger Robot   for I := 0 to Rewrites.Count - 1 do
6057*16467b97STreehugger Robot   begin
6058*16467b97STreehugger Robot     Op := Rewrites[I];
6059*16467b97STreehugger Robot     if (Op = nil) then
6060*16467b97STreehugger Robot       Continue;
6061*16467b97STreehugger Robot     if (not Supports(Op, IInsertBeforeOp, IOp)) then
6062*16467b97STreehugger Robot       Continue;
6063*16467b97STreehugger Robot 
6064*16467b97STreehugger Robot     // combine current insert with prior if any at same index
6065*16467b97STreehugger Robot     PrevInserts := GetKindOfOps(Rewrites, IInsertBeforeOp, I);
6066*16467b97STreehugger Robot     for J := 0 to PrevInserts.Count - 1 do
6067*16467b97STreehugger Robot     begin
6068*16467b97STreehugger Robot       PrevIOp := PrevInserts[J] as IInsertBeforeOp;
6069*16467b97STreehugger Robot       if (PrevIOp.Index = IOp.Index) then
6070*16467b97STreehugger Robot       begin
6071*16467b97STreehugger Robot         // combine objects
6072*16467b97STreehugger Robot         // convert to strings...we're in process of toString'ing
6073*16467b97STreehugger Robot         // whole token buffer so no lazy eval issue with any templates
6074*16467b97STreehugger Robot         IOp.Text := CatOpText(IOp.Text, PrevIOp.Text);
6075*16467b97STreehugger Robot         // delete redundant prior insert
6076*16467b97STreehugger Robot         Rewrites[PrevIOp.InstructionIndex] := nil;
6077*16467b97STreehugger Robot       end;
6078*16467b97STreehugger Robot     end;
6079*16467b97STreehugger Robot 
6080*16467b97STreehugger Robot     // look for replaces where iop.index is in range; error
6081*16467b97STreehugger Robot     PrevReplaces := GetKindOfOps(Rewrites, IReplaceOp, I);
6082*16467b97STreehugger Robot     for J := 0 to PrevReplaces.Count - 1 do
6083*16467b97STreehugger Robot     begin
6084*16467b97STreehugger Robot       Rop := PrevReplaces[J] as IReplaceOp;
6085*16467b97STreehugger Robot       if (IOp.Index = ROp.Index) then
6086*16467b97STreehugger Robot       begin
6087*16467b97STreehugger Robot         ROp.Text := CatOpText(IOp.Text, ROp.Text);
6088*16467b97STreehugger Robot         Rewrites[I] := nil;  // delete current insert
6089*16467b97STreehugger Robot         Continue;
6090*16467b97STreehugger Robot       end;
6091*16467b97STreehugger Robot       if (IOp.Index >= ROp.Index) and (IOp.Index <= ROp.LastIndex) then
6092*16467b97STreehugger Robot         raise EArgumentOutOfRangeException.Create('insert op '
6093*16467b97STreehugger Robot           + IOp.ToString + ' within boundaries of previous ' + ROp.ToString);
6094*16467b97STreehugger Robot     end;
6095*16467b97STreehugger Robot   end;
6096*16467b97STreehugger Robot 
6097*16467b97STreehugger Robot   Result := TDictionary<Integer, IRewriteOperation>.Create;
6098*16467b97STreehugger Robot   for Op in Rewrites do
6099*16467b97STreehugger Robot   begin
6100*16467b97STreehugger Robot     if (Op = nil) then
6101*16467b97STreehugger Robot       Continue; // ignore deleted ops
6102*16467b97STreehugger Robot     if (Result.ContainsKey(Op.Index)) then
6103*16467b97STreehugger Robot       raise Exception.Create('should only be one op per index');
6104*16467b97STreehugger Robot     Result.Add(Op.Index, Op);
6105*16467b97STreehugger Robot   end;
6106*16467b97STreehugger Robot end;
6107*16467b97STreehugger Robot 
6108*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const ProgramName: String; const Start,
6109*16467b97STreehugger Robot   Stop: IToken; const Text: IANTLRInterface);
6110*16467b97STreehugger Robot begin
6111*16467b97STreehugger Robot   Replace(ProgramName, Start.TokenIndex, Stop.TokenIndex, Text);
6112*16467b97STreehugger Robot end;
6113*16467b97STreehugger Robot 
6114*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const Index: Integer;
6115*16467b97STreehugger Robot   const Text: IANTLRInterface);
6116*16467b97STreehugger Robot begin
6117*16467b97STreehugger Robot   Replace(DEFAULT_PROGRAM_NAME, Index, Index, Text);
6118*16467b97STreehugger Robot end;
6119*16467b97STreehugger Robot 
6120*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const Start, Stop: Integer;
6121*16467b97STreehugger Robot   const Text: IANTLRInterface);
6122*16467b97STreehugger Robot begin
6123*16467b97STreehugger Robot   Replace(DEFAULT_PROGRAM_NAME, Start, Stop, Text);
6124*16467b97STreehugger Robot end;
6125*16467b97STreehugger Robot 
6126*16467b97STreehugger Robot procedure TTokenRewriteStream.Rollback(const InstructionIndex: Integer);
6127*16467b97STreehugger Robot begin
6128*16467b97STreehugger Robot   Rollback(DEFAULT_PROGRAM_NAME, InstructionIndex);
6129*16467b97STreehugger Robot end;
6130*16467b97STreehugger Robot 
6131*16467b97STreehugger Robot procedure TTokenRewriteStream.Rollback(const ProgramName: String;
6132*16467b97STreehugger Robot   const InstructionIndex: Integer);
6133*16467b97STreehugger Robot var
6134*16467b97STreehugger Robot   InstructionStream: IList<IRewriteOperation>;
6135*16467b97STreehugger Robot begin
6136*16467b97STreehugger Robot   InstructionStream := FPrograms[ProgramName];
6137*16467b97STreehugger Robot   if Assigned(InstructionStream) then
6138*16467b97STreehugger Robot     FPrograms[ProgramName] := InstructionStream.GetRange(MIN_TOKEN_INDEX,
6139*16467b97STreehugger Robot       InstructionIndex - MIN_TOKEN_INDEX);
6140*16467b97STreehugger Robot end;
6141*16467b97STreehugger Robot 
6142*16467b97STreehugger Robot procedure TTokenRewriteStream.SetLastRewriteTokenIndex(
6143*16467b97STreehugger Robot   const ProgramName: String; const I: Integer);
6144*16467b97STreehugger Robot begin
6145*16467b97STreehugger Robot   FLastRewriteTokenIndexes[ProgramName] := I;
6146*16467b97STreehugger Robot end;
6147*16467b97STreehugger Robot 
ToDebugStringnull6148*16467b97STreehugger Robot function TTokenRewriteStream.ToDebugString: String;
6149*16467b97STreehugger Robot begin
6150*16467b97STreehugger Robot   Result := ToDebugString(MIN_TOKEN_INDEX, Size - 1);
6151*16467b97STreehugger Robot end;
6152*16467b97STreehugger Robot 
ToDebugStringnull6153*16467b97STreehugger Robot function TTokenRewriteStream.ToDebugString(const Start, Stop: Integer): String;
6154*16467b97STreehugger Robot var
6155*16467b97STreehugger Robot   Buf: TStringBuilder;
6156*16467b97STreehugger Robot   I: Integer;
6157*16467b97STreehugger Robot begin
6158*16467b97STreehugger Robot   Buf := TStringBuilder.Create;
6159*16467b97STreehugger Robot   try
6160*16467b97STreehugger Robot     if (Start >= MIN_TOKEN_INDEX) then
6161*16467b97STreehugger Robot       for I := Start to Min(Stop,GetTokens.Count - 1) do
6162*16467b97STreehugger Robot         Buf.Append(Get(I).ToString);
6163*16467b97STreehugger Robot   finally
6164*16467b97STreehugger Robot     Buf.Free;
6165*16467b97STreehugger Robot   end;
6166*16467b97STreehugger Robot end;
6167*16467b97STreehugger Robot 
ToOriginalStringnull6168*16467b97STreehugger Robot function TTokenRewriteStream.ToOriginalString: String;
6169*16467b97STreehugger Robot begin
6170*16467b97STreehugger Robot   Result := ToOriginalString(MIN_TOKEN_INDEX, Size - 1);
6171*16467b97STreehugger Robot end;
6172*16467b97STreehugger Robot 
ToOriginalStringnull6173*16467b97STreehugger Robot function TTokenRewriteStream.ToOriginalString(const Start,
6174*16467b97STreehugger Robot   Stop: Integer): String;
6175*16467b97STreehugger Robot var
6176*16467b97STreehugger Robot   Buf: TStringBuilder;
6177*16467b97STreehugger Robot   I: Integer;
6178*16467b97STreehugger Robot begin
6179*16467b97STreehugger Robot   Buf := TStringBuilder.Create;
6180*16467b97STreehugger Robot   try
6181*16467b97STreehugger Robot     if (Start >= MIN_TOKEN_INDEX) then
6182*16467b97STreehugger Robot       for I := Start to Min(Stop, GetTokens.Count - 1) do
6183*16467b97STreehugger Robot         Buf.Append(Get(I).Text);
6184*16467b97STreehugger Robot     Result := Buf.ToString;
6185*16467b97STreehugger Robot   finally
6186*16467b97STreehugger Robot     Buf.Free;
6187*16467b97STreehugger Robot   end;
6188*16467b97STreehugger Robot end;
6189*16467b97STreehugger Robot 
TTokenRewriteStream.ToString()6190*16467b97STreehugger Robot function TTokenRewriteStream.ToString: String;
6191*16467b97STreehugger Robot begin
6192*16467b97STreehugger Robot   Result := ToString(MIN_TOKEN_INDEX, Size - 1);
6193*16467b97STreehugger Robot end;
6194*16467b97STreehugger Robot 
TTokenRewriteStream.ToString(const ProgramName: String)6195*16467b97STreehugger Robot function TTokenRewriteStream.ToString(const ProgramName: String): String;
6196*16467b97STreehugger Robot begin
6197*16467b97STreehugger Robot   Result := ToString(ProgramName, MIN_TOKEN_INDEX, Size - 1);
6198*16467b97STreehugger Robot end;
6199*16467b97STreehugger Robot 
TTokenRewriteStream.ToString(const ProgramName: String; const Start,6200*16467b97STreehugger Robot function TTokenRewriteStream.ToString(const ProgramName: String; const Start,
6201*16467b97STreehugger Robot   Stop: Integer): String;
6202*16467b97STreehugger Robot var
6203*16467b97STreehugger Robot   Rewrites: IList<IRewriteOperation>;
6204*16467b97STreehugger Robot   I, StartIndex, StopIndex: Integer;
6205*16467b97STreehugger Robot   IndexToOp: IDictionary<Integer, IRewriteOperation>;
6206*16467b97STreehugger Robot   Buf: TStringBuilder;
6207*16467b97STreehugger Robot   Tokens: IList<IToken>;
6208*16467b97STreehugger Robot   T: IToken;
6209*16467b97STreehugger Robot   Op: IRewriteOperation;
6210*16467b97STreehugger Robot   Pair: TPair<Integer, IRewriteOperation>;
6211*16467b97STreehugger Robot begin
6212*16467b97STreehugger Robot   Rewrites := FPrograms[ProgramName];
6213*16467b97STreehugger Robot   Tokens := GetTokens;
6214*16467b97STreehugger Robot   // ensure start/end are in range
6215*16467b97STreehugger Robot   StopIndex := Min(Stop,Tokens.Count - 1);
6216*16467b97STreehugger Robot   StartIndex := Max(Start,0);
6217*16467b97STreehugger Robot 
6218*16467b97STreehugger Robot   if (Rewrites = nil) or (Rewrites.Count = 0) then
6219*16467b97STreehugger Robot   begin
6220*16467b97STreehugger Robot      // no instructions to execute
6221*16467b97STreehugger Robot     Result := ToOriginalString(StartIndex, StopIndex);
6222*16467b97STreehugger Robot     Exit;
6223*16467b97STreehugger Robot   end;
6224*16467b97STreehugger Robot 
6225*16467b97STreehugger Robot   Buf := TStringBuilder.Create;
6226*16467b97STreehugger Robot   try
6227*16467b97STreehugger Robot     // First, optimize instruction stream
6228*16467b97STreehugger Robot     IndexToOp := ReduceToSingleOperationPerIndex(Rewrites);
6229*16467b97STreehugger Robot 
6230*16467b97STreehugger Robot     // Walk buffer, executing instructions and emitting tokens
6231*16467b97STreehugger Robot     I := StartIndex;
6232*16467b97STreehugger Robot     while (I <= StopIndex) and (I < Tokens.Count) do
6233*16467b97STreehugger Robot     begin
6234*16467b97STreehugger Robot       if (not IndexToOp.TryGetValue(I, Op)) then
6235*16467b97STreehugger Robot         Op := nil;
6236*16467b97STreehugger Robot       IndexToOp.Remove(I); // remove so any left have index size-1
6237*16467b97STreehugger Robot       T := Tokens[I];
6238*16467b97STreehugger Robot       if (Op = nil) then
6239*16467b97STreehugger Robot       begin
6240*16467b97STreehugger Robot         // no operation at that index, just dump token
6241*16467b97STreehugger Robot         Buf.Append(T.Text);
6242*16467b97STreehugger Robot         Inc(I); // move to next token
6243*16467b97STreehugger Robot       end
6244*16467b97STreehugger Robot       else
6245*16467b97STreehugger Robot         I := Op.Execute(Buf); // execute operation and skip
6246*16467b97STreehugger Robot     end;
6247*16467b97STreehugger Robot 
6248*16467b97STreehugger Robot     // include stuff after end if it's last index in buffer
6249*16467b97STreehugger Robot     // So, if they did an insertAfter(lastValidIndex, "foo"), include
6250*16467b97STreehugger Robot     // foo if end==lastValidIndex.
6251*16467b97STreehugger Robot     if (StopIndex = Tokens.Count - 1) then
6252*16467b97STreehugger Robot     begin
6253*16467b97STreehugger Robot       // Scan any remaining operations after last token
6254*16467b97STreehugger Robot       // should be included (they will be inserts).
6255*16467b97STreehugger Robot       for Pair in IndexToOp do
6256*16467b97STreehugger Robot       begin
6257*16467b97STreehugger Robot         if (Pair.Value.Index >= Tokens.Count - 1) then
6258*16467b97STreehugger Robot           Buf.Append(Pair.Value.Text.ToString);
6259*16467b97STreehugger Robot       end;
6260*16467b97STreehugger Robot     end;
6261*16467b97STreehugger Robot     Result := Buf.ToString;
6262*16467b97STreehugger Robot   finally
6263*16467b97STreehugger Robot     Buf.Free;
6264*16467b97STreehugger Robot   end;
6265*16467b97STreehugger Robot end;
6266*16467b97STreehugger Robot 
TTokenRewriteStream.ToString(const Start, Stop: Integer)6267*16467b97STreehugger Robot function TTokenRewriteStream.ToString(const Start, Stop: Integer): String;
6268*16467b97STreehugger Robot begin
6269*16467b97STreehugger Robot   Result := ToString(DEFAULT_PROGRAM_NAME, Start, Stop);
6270*16467b97STreehugger Robot end;
6271*16467b97STreehugger Robot 
6272*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertBefore(const Index: Integer;
6273*16467b97STreehugger Robot   const Text: String);
6274*16467b97STreehugger Robot var
6275*16467b97STreehugger Robot   S: IANTLRString;
6276*16467b97STreehugger Robot begin
6277*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6278*16467b97STreehugger Robot   InsertBefore(Index, S);
6279*16467b97STreehugger Robot end;
6280*16467b97STreehugger Robot 
6281*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertBefore(const T: IToken; const Text: String);
6282*16467b97STreehugger Robot var
6283*16467b97STreehugger Robot   S: IANTLRString;
6284*16467b97STreehugger Robot begin
6285*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6286*16467b97STreehugger Robot   InsertBefore(T, S);
6287*16467b97STreehugger Robot end;
6288*16467b97STreehugger Robot 
6289*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertBefore(const ProgramName: String;
6290*16467b97STreehugger Robot   const Index: Integer; const Text: String);
6291*16467b97STreehugger Robot var
6292*16467b97STreehugger Robot   S: IANTLRString;
6293*16467b97STreehugger Robot begin
6294*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6295*16467b97STreehugger Robot   InsertBefore(ProgramName, Index, S);
6296*16467b97STreehugger Robot end;
6297*16467b97STreehugger Robot 
6298*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertBefore(const ProgramName: String;
6299*16467b97STreehugger Robot   const T: IToken; const Text: String);
6300*16467b97STreehugger Robot var
6301*16467b97STreehugger Robot   S: IANTLRString;
6302*16467b97STreehugger Robot begin
6303*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6304*16467b97STreehugger Robot   InsertBefore(ProgramName, T, S);
6305*16467b97STreehugger Robot end;
6306*16467b97STreehugger Robot 
6307*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertAfter(const Index: Integer;
6308*16467b97STreehugger Robot   const Text: String);
6309*16467b97STreehugger Robot var
6310*16467b97STreehugger Robot   S: IANTLRString;
6311*16467b97STreehugger Robot begin
6312*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6313*16467b97STreehugger Robot   InsertAfter(Index,S);
6314*16467b97STreehugger Robot end;
6315*16467b97STreehugger Robot 
6316*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertAfter(const T: IToken; const Text: String);
6317*16467b97STreehugger Robot var
6318*16467b97STreehugger Robot   S: IANTLRString;
6319*16467b97STreehugger Robot begin
6320*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6321*16467b97STreehugger Robot   InsertAfter(T,S);
6322*16467b97STreehugger Robot end;
6323*16467b97STreehugger Robot 
6324*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertAfter(const ProgramName: String;
6325*16467b97STreehugger Robot   const Index: Integer; const Text: String);
6326*16467b97STreehugger Robot var
6327*16467b97STreehugger Robot   S: IANTLRString;
6328*16467b97STreehugger Robot begin
6329*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6330*16467b97STreehugger Robot   InsertAfter(ProgramName,Index,S);
6331*16467b97STreehugger Robot end;
6332*16467b97STreehugger Robot 
6333*16467b97STreehugger Robot procedure TTokenRewriteStream.InsertAfter(const ProgramName: String;
6334*16467b97STreehugger Robot   const T: IToken; const Text: String);
6335*16467b97STreehugger Robot var
6336*16467b97STreehugger Robot   S: IANTLRString;
6337*16467b97STreehugger Robot begin
6338*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6339*16467b97STreehugger Robot   InsertAfter(ProgramName,T,S);
6340*16467b97STreehugger Robot end;
6341*16467b97STreehugger Robot 
6342*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const IndexT: IToken; const Text: String);
6343*16467b97STreehugger Robot var
6344*16467b97STreehugger Robot   S: IANTLRString;
6345*16467b97STreehugger Robot begin
6346*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6347*16467b97STreehugger Robot   Replace(IndexT, S);
6348*16467b97STreehugger Robot end;
6349*16467b97STreehugger Robot 
6350*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const Start, Stop: Integer;
6351*16467b97STreehugger Robot   const Text: String);
6352*16467b97STreehugger Robot var
6353*16467b97STreehugger Robot   S: IANTLRString;
6354*16467b97STreehugger Robot begin
6355*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6356*16467b97STreehugger Robot   Replace(Start, Stop, S);
6357*16467b97STreehugger Robot end;
6358*16467b97STreehugger Robot 
6359*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const Index: Integer; const Text: String);
6360*16467b97STreehugger Robot var
6361*16467b97STreehugger Robot   S: IANTLRString;
6362*16467b97STreehugger Robot begin
6363*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6364*16467b97STreehugger Robot   Replace(Index, S);
6365*16467b97STreehugger Robot end;
6366*16467b97STreehugger Robot 
6367*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const ProgramName: String; const Start,
6368*16467b97STreehugger Robot   Stop: IToken; const Text: String);
6369*16467b97STreehugger Robot var
6370*16467b97STreehugger Robot   S: IANTLRString;
6371*16467b97STreehugger Robot begin
6372*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6373*16467b97STreehugger Robot   Replace(ProgramName, Start, Stop, S);
6374*16467b97STreehugger Robot end;
6375*16467b97STreehugger Robot 
6376*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const ProgramName: String; const Start,
6377*16467b97STreehugger Robot   Stop: Integer; const Text: String);
6378*16467b97STreehugger Robot var
6379*16467b97STreehugger Robot   S: IANTLRString;
6380*16467b97STreehugger Robot begin
6381*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6382*16467b97STreehugger Robot   Replace(ProgramName, Start, Stop, S);
6383*16467b97STreehugger Robot end;
6384*16467b97STreehugger Robot 
6385*16467b97STreehugger Robot procedure TTokenRewriteStream.Replace(const Start, Stop: IToken;
6386*16467b97STreehugger Robot   const Text: String);
6387*16467b97STreehugger Robot var
6388*16467b97STreehugger Robot   S: IANTLRString;
6389*16467b97STreehugger Robot begin
6390*16467b97STreehugger Robot   S := TANTLRString.Create(Text);
6391*16467b97STreehugger Robot   Replace(Start, Stop, S);
6392*16467b97STreehugger Robot end;
6393*16467b97STreehugger Robot 
6394*16467b97STreehugger Robot { TTokenRewriteStream.TRewriteOperation }
6395*16467b97STreehugger Robot 
6396*16467b97STreehugger Robot constructor TTokenRewriteStream.TRewriteOperation.Create(const AIndex: Integer;
6397*16467b97STreehugger Robot   const AText: IANTLRInterface; const AParent: ITokenRewriteStream);
6398*16467b97STreehugger Robot begin
6399*16467b97STreehugger Robot   inherited Create;
6400*16467b97STreehugger Robot   FIndex := AIndex;
6401*16467b97STreehugger Robot   FText := AText;
6402*16467b97STreehugger Robot   FParent := Pointer(AParent);
6403*16467b97STreehugger Robot end;
6404*16467b97STreehugger Robot 
TRewriteOperationnull6405*16467b97STreehugger Robot function TTokenRewriteStream.TRewriteOperation.Execute(
6406*16467b97STreehugger Robot   const Buf: TStringBuilder): Integer;
6407*16467b97STreehugger Robot begin
6408*16467b97STreehugger Robot   Result := FIndex;
6409*16467b97STreehugger Robot end;
6410*16467b97STreehugger Robot 
TRewriteOperationnull6411*16467b97STreehugger Robot function TTokenRewriteStream.TRewriteOperation.GetIndex: Integer;
6412*16467b97STreehugger Robot begin
6413*16467b97STreehugger Robot   Result := FIndex;
6414*16467b97STreehugger Robot end;
6415*16467b97STreehugger Robot 
TRewriteOperationnull6416*16467b97STreehugger Robot function TTokenRewriteStream.TRewriteOperation.GetInstructionIndex: Integer;
6417*16467b97STreehugger Robot begin
6418*16467b97STreehugger Robot   Result := FInstructionIndex;
6419*16467b97STreehugger Robot end;
6420*16467b97STreehugger Robot 
TRewriteOperationnull6421*16467b97STreehugger Robot function TTokenRewriteStream.TRewriteOperation.GetParent: ITokenRewriteStream;
6422*16467b97STreehugger Robot begin
6423*16467b97STreehugger Robot   Result := ITokenRewriteStream(FParent);
6424*16467b97STreehugger Robot end;
6425*16467b97STreehugger Robot 
TRewriteOperationnull6426*16467b97STreehugger Robot function TTokenRewriteStream.TRewriteOperation.GetText: IANTLRInterface;
6427*16467b97STreehugger Robot begin
6428*16467b97STreehugger Robot   Result := FText;
6429*16467b97STreehugger Robot end;
6430*16467b97STreehugger Robot 
6431*16467b97STreehugger Robot procedure TTokenRewriteStream.TRewriteOperation.SetIndex(const Value: Integer);
6432*16467b97STreehugger Robot begin
6433*16467b97STreehugger Robot   FIndex := Value;
6434*16467b97STreehugger Robot end;
6435*16467b97STreehugger Robot 
6436*16467b97STreehugger Robot procedure TTokenRewriteStream.TRewriteOperation.SetInstructionIndex(
6437*16467b97STreehugger Robot   const Value: Integer);
6438*16467b97STreehugger Robot begin
6439*16467b97STreehugger Robot   FInstructionIndex := Value;
6440*16467b97STreehugger Robot end;
6441*16467b97STreehugger Robot 
6442*16467b97STreehugger Robot procedure TTokenRewriteStream.TRewriteOperation.SetParent(
6443*16467b97STreehugger Robot   const Value: ITokenRewriteStream);
6444*16467b97STreehugger Robot begin
6445*16467b97STreehugger Robot   FParent := Pointer(Value);
6446*16467b97STreehugger Robot end;
6447*16467b97STreehugger Robot 
6448*16467b97STreehugger Robot procedure TTokenRewriteStream.TRewriteOperation.SetText(
6449*16467b97STreehugger Robot   const Value: IANTLRInterface);
6450*16467b97STreehugger Robot begin
6451*16467b97STreehugger Robot   FText := Value;
6452*16467b97STreehugger Robot end;
6453*16467b97STreehugger Robot 
TRewriteOperationnull6454*16467b97STreehugger Robot function TTokenRewriteStream.TRewriteOperation.ToString: String;
6455*16467b97STreehugger Robot var
6456*16467b97STreehugger Robot   OpName: String;
6457*16467b97STreehugger Robot   DollarIndex: Integer;
6458*16467b97STreehugger Robot begin
6459*16467b97STreehugger Robot   OpName := ClassName;
6460*16467b97STreehugger Robot   DollarIndex := Pos('$',OpName) - 1; // Delphi strings are 1-based
6461*16467b97STreehugger Robot   if (DollarIndex >= 0) then
6462*16467b97STreehugger Robot     OpName := Copy(OpName,DollarIndex + 1,Length(OpName) - (DollarIndex + 1));
6463*16467b97STreehugger Robot   Result := '<' + OpName + '@' + IntToStr(FIndex) + ':"' + FText.ToString + '">';
6464*16467b97STreehugger Robot end;
6465*16467b97STreehugger Robot 
6466*16467b97STreehugger Robot { TTokenRewriteStream.TRewriteOpComparer<T> }
6467*16467b97STreehugger Robot 
TTokenRewriteStream.TRewriteOpComparer(const Left,6468*16467b97STreehugger Robot function TTokenRewriteStream.TRewriteOpComparer<T>.Compare(const Left,
6469*16467b97STreehugger Robot   Right: T): Integer;
6470*16467b97STreehugger Robot begin
6471*16467b97STreehugger Robot   if (Left.GetIndex < Right.GetIndex) then
6472*16467b97STreehugger Robot     Result := -1
6473*16467b97STreehugger Robot   else
6474*16467b97STreehugger Robot     if (Left.GetIndex > Right.GetIndex) then
6475*16467b97STreehugger Robot       Result := 1
6476*16467b97STreehugger Robot     else
6477*16467b97STreehugger Robot       Result := 0;
6478*16467b97STreehugger Robot end;
6479*16467b97STreehugger Robot 
6480*16467b97STreehugger Robot { TTokenRewriteStream.TInsertBeforeOp }
6481*16467b97STreehugger Robot 
TTokenRewriteStream.TInsertBeforeOp.Execute(6482*16467b97STreehugger Robot function TTokenRewriteStream.TInsertBeforeOp.Execute(
6483*16467b97STreehugger Robot   const Buf: TStringBuilder): Integer;
6484*16467b97STreehugger Robot begin
6485*16467b97STreehugger Robot   Buf.Append(Text.ToString);
6486*16467b97STreehugger Robot   Buf.Append(Parent.Get(Index).Text);
6487*16467b97STreehugger Robot   Result := Index + 1;
6488*16467b97STreehugger Robot end;
6489*16467b97STreehugger Robot 
6490*16467b97STreehugger Robot { TTokenRewriteStream.TReplaceOp }
6491*16467b97STreehugger Robot 
6492*16467b97STreehugger Robot constructor TTokenRewriteStream.TReplaceOp.Create(const AStart, AStop: Integer;
6493*16467b97STreehugger Robot   const AText: IANTLRInterface; const AParent: ITokenRewriteStream);
6494*16467b97STreehugger Robot begin
6495*16467b97STreehugger Robot   inherited Create(AStart, AText, AParent);
6496*16467b97STreehugger Robot   FLastIndex := AStop;
6497*16467b97STreehugger Robot end;
6498*16467b97STreehugger Robot 
TTokenRewriteStream.TReplaceOp.Execute(6499*16467b97STreehugger Robot function TTokenRewriteStream.TReplaceOp.Execute(
6500*16467b97STreehugger Robot   const Buf: TStringBuilder): Integer;
6501*16467b97STreehugger Robot begin
6502*16467b97STreehugger Robot   if (Text <> nil) then
6503*16467b97STreehugger Robot     Buf.Append(Text.ToString);
6504*16467b97STreehugger Robot   Result := FLastIndex + 1;
6505*16467b97STreehugger Robot end;
6506*16467b97STreehugger Robot 
TReplaceOpnull6507*16467b97STreehugger Robot function TTokenRewriteStream.TReplaceOp.GetLastIndex: Integer;
6508*16467b97STreehugger Robot begin
6509*16467b97STreehugger Robot   Result := FLastIndex;
6510*16467b97STreehugger Robot end;
6511*16467b97STreehugger Robot 
6512*16467b97STreehugger Robot procedure TTokenRewriteStream.TReplaceOp.SetLastIndex(const Value: Integer);
6513*16467b97STreehugger Robot begin
6514*16467b97STreehugger Robot   FLastIndex := Value;
6515*16467b97STreehugger Robot end;
6516*16467b97STreehugger Robot 
TReplaceOpnull6517*16467b97STreehugger Robot function TTokenRewriteStream.TReplaceOp.ToString: String;
6518*16467b97STreehugger Robot begin
6519*16467b97STreehugger Robot   Result := '<ReplaceOp@' + IntToStr(Index) + '..' + IntToStr(FLastIndex)
6520*16467b97STreehugger Robot     + ':"' + Text.ToString + '">';
6521*16467b97STreehugger Robot end;
6522*16467b97STreehugger Robot 
6523*16467b97STreehugger Robot { TTokenRewriteStream.TDeleteOp }
6524*16467b97STreehugger Robot 
TTokenRewriteStream.TDeleteOp.ToString()6525*16467b97STreehugger Robot function TTokenRewriteStream.TDeleteOp.ToString: String;
6526*16467b97STreehugger Robot begin
6527*16467b97STreehugger Robot   Result := '<DeleteOp@' + IntToStr(Index) + '..' + IntToStr(FLastIndex) + '>';
6528*16467b97STreehugger Robot end;
6529*16467b97STreehugger Robot 
6530*16467b97STreehugger Robot { Utilities }
6531*16467b97STreehugger Robot 
6532*16467b97STreehugger Robot var
6533*16467b97STreehugger Robot   EmptyToken: IToken = nil;
6534*16467b97STreehugger Robot   EmptyRuleReturnScope: IRuleReturnScope = nil;
6535*16467b97STreehugger Robot 
Def(const X: IToken)6536*16467b97STreehugger Robot function Def(const X: IToken): IToken; overload;
6537*16467b97STreehugger Robot begin
6538*16467b97STreehugger Robot   if Assigned(X) then
6539*16467b97STreehugger Robot     Result := X
6540*16467b97STreehugger Robot   else
6541*16467b97STreehugger Robot   begin
6542*16467b97STreehugger Robot     if (EmptyToken = nil) then
6543*16467b97STreehugger Robot       EmptyToken := TCommonToken.Create;
6544*16467b97STreehugger Robot     Result := EmptyToken;
6545*16467b97STreehugger Robot   end;
6546*16467b97STreehugger Robot end;
6547*16467b97STreehugger Robot 
Def(const X: IRuleReturnScope)6548*16467b97STreehugger Robot function Def(const X: IRuleReturnScope): IRuleReturnScope;
6549*16467b97STreehugger Robot begin
6550*16467b97STreehugger Robot   if Assigned(X) then
6551*16467b97STreehugger Robot     Result := X
6552*16467b97STreehugger Robot   else
6553*16467b97STreehugger Robot   begin
6554*16467b97STreehugger Robot     if (EmptyRuleReturnScope = nil) then
6555*16467b97STreehugger Robot       EmptyRuleReturnScope := TRuleReturnScope.Create;
6556*16467b97STreehugger Robot     Result := EmptyRuleReturnScope;
6557*16467b97STreehugger Robot   end;
6558*16467b97STreehugger Robot end;
6559*16467b97STreehugger Robot 
6560*16467b97STreehugger Robot initialization
6561*16467b97STreehugger Robot   TToken.Initialize;
6562*16467b97STreehugger Robot 
6563*16467b97STreehugger Robot end.
6564