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 < 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<Integer,Integer> 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 <String> 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<Token> to List<String>
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; < 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