annotate gcc/ada/libgnat/g-spipat.ads @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT LIBRARY COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- G N A T . S P I T B O L . P A T T E R N S --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- S p e c --
kono
parents:
diff changeset
8 -- --
kono
parents:
diff changeset
9 -- Copyright (C) 1997-2017, AdaCore --
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 -- SPITBOL-like pattern construction and matching
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 -- This child package of GNAT.SPITBOL provides a complete implementation
kono
parents:
diff changeset
35 -- of the SPITBOL-like pattern construction and matching operations. This
kono
parents:
diff changeset
36 -- package is based on Macro-SPITBOL created by Robert Dewar.
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 ------------------------------------------------------------
kono
parents:
diff changeset
39 -- Summary of Pattern Matching Packages in GNAT Hierarchy --
kono
parents:
diff changeset
40 ------------------------------------------------------------
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 -- There are three related packages that perform pattern matching functions.
kono
parents:
diff changeset
43 -- the following is an outline of these packages, to help you determine
kono
parents:
diff changeset
44 -- which is best for your needs.
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 -- GNAT.Regexp (files g-regexp.ads/g-regexp.adb)
kono
parents:
diff changeset
47 -- This is a simple package providing Unix-style regular expression
kono
parents:
diff changeset
48 -- matching with the restriction that it matches entire strings. It
kono
parents:
diff changeset
49 -- is particularly useful for file name matching, and in particular
kono
parents:
diff changeset
50 -- it provides "globbing patterns" that are useful in implementing
kono
parents:
diff changeset
51 -- unix or DOS style wild card matching for file names.
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 -- GNAT.Regpat (files g-regpat.ads/g-regpat.adb)
kono
parents:
diff changeset
54 -- This is a more complete implementation of Unix-style regular
kono
parents:
diff changeset
55 -- expressions, copied from the original V7 style regular expression
kono
parents:
diff changeset
56 -- library written in C by Henry Spencer. It is functionally the
kono
parents:
diff changeset
57 -- same as this library, and uses the same internal data structures
kono
parents:
diff changeset
58 -- stored in a binary compatible manner.
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 -- GNAT.Spitbol.Patterns (files g-spipat.ads/g-spipat.adb)
kono
parents:
diff changeset
61 -- This is a completely general patterm matching package based on the
kono
parents:
diff changeset
62 -- pattern language of SNOBOL4, as implemented in SPITBOL. The pattern
kono
parents:
diff changeset
63 -- language is modeled on context free grammars, with context sensitive
kono
parents:
diff changeset
64 -- extensions that provide full (type 0) computational capabilities.
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 with Ada.Strings.Maps; use Ada.Strings.Maps;
kono
parents:
diff changeset
67 with Ada.Text_IO; use Ada.Text_IO;
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 package GNAT.Spitbol.Patterns is
kono
parents:
diff changeset
70 pragma Elaborate_Body;
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 -------------------------------
kono
parents:
diff changeset
73 -- Pattern Matching Tutorial --
kono
parents:
diff changeset
74 -------------------------------
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 -- A pattern matching operation (a call to one of the Match subprograms)
kono
parents:
diff changeset
77 -- takes a subject string and a pattern, and optionally a replacement
kono
parents:
diff changeset
78 -- string. The replacement string option is only allowed if the subject
kono
parents:
diff changeset
79 -- is a variable.
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 -- The pattern is matched against the subject string, and either the
kono
parents:
diff changeset
82 -- match fails, or it succeeds matching a contiguous substring. If a
kono
parents:
diff changeset
83 -- replacement string is specified, then the subject string is modified
kono
parents:
diff changeset
84 -- by replacing the matched substring with the given replacement.
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 -- Concatenation and Alternation
kono
parents:
diff changeset
87 -- =============================
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 -- A pattern consists of a series of pattern elements. The pattern is
kono
parents:
diff changeset
90 -- built up using either the concatenation operator:
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 -- A & B
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 -- which means match A followed immediately by matching B, or the
kono
parents:
diff changeset
95 -- alternation operator:
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 -- A or B
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 -- which means first attempt to match A, and then if that does not
kono
parents:
diff changeset
100 -- succeed, match B.
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 -- There is full backtracking, which means that if a given pattern
kono
parents:
diff changeset
103 -- element fails to match, then previous alternatives are matched.
kono
parents:
diff changeset
104 -- For example if we have the pattern:
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 -- (A or B) & (C or D) & (E or F)
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 -- First we attempt to match A, if that succeeds, then we go on to try
kono
parents:
diff changeset
109 -- to match C, and if that succeeds, we go on to try to match E. If E
kono
parents:
diff changeset
110 -- fails, then we try F. If F fails, then we go back and try matching
kono
parents:
diff changeset
111 -- D instead of C. Let's make this explicit using a specific example,
kono
parents:
diff changeset
112 -- and introducing the simplest kind of pattern element, which is a
kono
parents:
diff changeset
113 -- literal string. The meaning of this pattern element is simply to
kono
parents:
diff changeset
114 -- match the characters that correspond to the string characters. Now
kono
parents:
diff changeset
115 -- let's rewrite the above pattern form with specific string literals
kono
parents:
diff changeset
116 -- as the pattern elements:
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 -- ("ABC" or "AB") & ("DEF" or "CDE") & ("GH" or "IJ")
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 -- The following strings will be attempted in sequence:
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 -- ABC . DEF . GH
kono
parents:
diff changeset
123 -- ABC . DEF . IJ
kono
parents:
diff changeset
124 -- ABC . CDE . GH
kono
parents:
diff changeset
125 -- ABC . CDE . IJ
kono
parents:
diff changeset
126 -- AB . DEF . GH
kono
parents:
diff changeset
127 -- AB . DEF . IJ
kono
parents:
diff changeset
128 -- AB . CDE . GH
kono
parents:
diff changeset
129 -- AB . CDE . IJ
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 -- Here we use the dot simply to separate the pieces of the string
kono
parents:
diff changeset
132 -- matched by the three separate elements.
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 -- Moving the Start Point
kono
parents:
diff changeset
135 -- ======================
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 -- A pattern is not required to match starting at the first character
kono
parents:
diff changeset
138 -- of the string, and is not required to match to the end of the string.
kono
parents:
diff changeset
139 -- The first attempt does indeed attempt to match starting at the first
kono
parents:
diff changeset
140 -- character of the string, trying all the possible alternatives. But
kono
parents:
diff changeset
141 -- if all alternatives fail, then the starting point of the match is
kono
parents:
diff changeset
142 -- moved one character, and all possible alternatives are attempted at
kono
parents:
diff changeset
143 -- the new anchor point.
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 -- The entire match fails only when every possible starting point has
kono
parents:
diff changeset
146 -- been attempted. As an example, suppose that we had the subject
kono
parents:
diff changeset
147 -- string
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 -- "ABABCDEIJKL"
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 -- matched using the pattern in the previous example:
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 -- ("ABC" or "AB") & ("DEF" or "CDE") & ("GH" or "IJ")
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 -- would succeed, after two anchor point moves:
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 -- "ABABCDEIJKL"
kono
parents:
diff changeset
158 -- ^^^^^^^
kono
parents:
diff changeset
159 -- matched
kono
parents:
diff changeset
160 -- section
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 -- This mode of pattern matching is called the unanchored mode. It is
kono
parents:
diff changeset
163 -- also possible to put the pattern matcher into anchored mode by
kono
parents:
diff changeset
164 -- setting the global variable Anchored_Mode to True. This will cause
kono
parents:
diff changeset
165 -- all subsequent matches to be performed in anchored mode, where the
kono
parents:
diff changeset
166 -- match is required to start at the first character.
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 -- We will also see later how the effect of an anchored match can be
kono
parents:
diff changeset
169 -- obtained for a single specified anchor point if this is desired.
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 -- Other Pattern Elements
kono
parents:
diff changeset
172 -- ======================
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 -- In addition to strings (or single characters), there are many special
kono
parents:
diff changeset
175 -- pattern elements that correspond to special predefined alternations:
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 -- Arb Matches any string. First it matches the null string, and
kono
parents:
diff changeset
178 -- then on a subsequent failure, matches one character, and
kono
parents:
diff changeset
179 -- then two characters, and so on. It only fails if the
kono
parents:
diff changeset
180 -- entire remaining string is matched.
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 -- Bal Matches a non-empty string that is parentheses balanced
kono
parents:
diff changeset
183 -- with respect to ordinary () characters. Examples of
kono
parents:
diff changeset
184 -- balanced strings are "ABC", "A((B)C)", and "A(B)C(D)E".
kono
parents:
diff changeset
185 -- Bal matches the shortest possible balanced string on the
kono
parents:
diff changeset
186 -- first attempt, and if there is a subsequent failure,
kono
parents:
diff changeset
187 -- attempts to extend the string.
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 -- Cancel Immediately aborts the entire pattern match, signalling
kono
parents:
diff changeset
190 -- failure. This is a specialized pattern element, which is
kono
parents:
diff changeset
191 -- useful in conjunction with some of the special pattern
kono
parents:
diff changeset
192 -- elements that have side effects.
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 -- Fail The null alternation. Matches no possible strings, so it
kono
parents:
diff changeset
195 -- always signals failure. This is a specialized pattern
kono
parents:
diff changeset
196 -- element, which is useful in conjunction with some of the
kono
parents:
diff changeset
197 -- special pattern elements that have side effects.
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 -- Fence Matches the null string at first, and then if a failure
kono
parents:
diff changeset
200 -- causes alternatives to be sought, aborts the match (like
kono
parents:
diff changeset
201 -- a Cancel). Note that using Fence at the start of a pattern
kono
parents:
diff changeset
202 -- has the same effect as matching in anchored mode.
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 -- Rest Matches from the current point to the last character in
kono
parents:
diff changeset
205 -- the string. This is a specialized pattern element, which
kono
parents:
diff changeset
206 -- is useful in conjunction with some of the special pattern
kono
parents:
diff changeset
207 -- elements that have side effects.
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 -- Succeed Repeatedly matches the null string (it is equivalent to
kono
parents:
diff changeset
210 -- the alternation ("" or "" or "" ....). This is a special
kono
parents:
diff changeset
211 -- pattern element, which is useful in conjunction with some
kono
parents:
diff changeset
212 -- of the special pattern elements that have side effects.
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 -- Pattern Construction Functions
kono
parents:
diff changeset
215 -- ==============================
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 -- The following functions construct additional pattern elements
kono
parents:
diff changeset
218
kono
parents:
diff changeset
219 -- Any(S) Where S is a string, matches a single character that is
kono
parents:
diff changeset
220 -- any one of the characters in S. Fails if the current
kono
parents:
diff changeset
221 -- character is not one of the given set of characters.
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 -- Arbno(P) Where P is any pattern, matches any number of instances
kono
parents:
diff changeset
224 -- of the pattern, starting with zero occurrences. It is
kono
parents:
diff changeset
225 -- thus equivalent to ("" or (P & ("" or (P & ("" ....)))).
kono
parents:
diff changeset
226 -- The pattern P may contain any number of pattern elements
kono
parents:
diff changeset
227 -- including the use of alternation and concatenation.
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 -- Break(S) Where S is a string, matches a string of zero or more
kono
parents:
diff changeset
230 -- characters up to but not including a break character
kono
parents:
diff changeset
231 -- that is one of the characters given in the string S.
kono
parents:
diff changeset
232 -- Can match the null string, but cannot match the last
kono
parents:
diff changeset
233 -- character in the string, since a break character is
kono
parents:
diff changeset
234 -- required to be present.
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 -- BreakX(S) Where S is a string, behaves exactly like Break(S) when
kono
parents:
diff changeset
237 -- it first matches, but if a string is successfully matched,
kono
parents:
diff changeset
238 -- then a subsequent failure causes an attempt to extend the
kono
parents:
diff changeset
239 -- matched string.
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 -- Fence(P) Where P is a pattern, attempts to match the pattern P
kono
parents:
diff changeset
242 -- including trying all possible alternatives of P. If none
kono
parents:
diff changeset
243 -- of these alternatives succeeds, then the Fence pattern
kono
parents:
diff changeset
244 -- fails. If one alternative succeeds, then the pattern
kono
parents:
diff changeset
245 -- match proceeds, but on a subsequent failure, no attempt
kono
parents:
diff changeset
246 -- is made to search for alternative matches of P. The
kono
parents:
diff changeset
247 -- pattern P may contain any number of pattern elements
kono
parents:
diff changeset
248 -- including the use of alternation and concatenation.
kono
parents:
diff changeset
249
kono
parents:
diff changeset
250 -- Len(N) Where N is a natural number, matches the given number of
kono
parents:
diff changeset
251 -- characters. For example, Len(10) matches any string that
kono
parents:
diff changeset
252 -- is exactly ten characters long.
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 -- NotAny(S) Where S is a string, matches a single character that is
kono
parents:
diff changeset
255 -- not one of the characters of S. Fails if the current
kono
parents:
diff changeset
256 -- character is one of the given set of characters.
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 -- NSpan(S) Where S is a string, matches a string of zero or more
kono
parents:
diff changeset
259 -- characters that is among the characters given in the
kono
parents:
diff changeset
260 -- string. Always matches the longest possible such string.
kono
parents:
diff changeset
261 -- Always succeeds, since it can match the null string.
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263 -- Pos(N) Where N is a natural number, matches the null string
kono
parents:
diff changeset
264 -- if exactly N characters have been matched so far, and
kono
parents:
diff changeset
265 -- otherwise fails.
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 -- Rpos(N) Where N is a natural number, matches the null string
kono
parents:
diff changeset
268 -- if exactly N characters remain to be matched, and
kono
parents:
diff changeset
269 -- otherwise fails.
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 -- Rtab(N) Where N is a natural number, matches characters from
kono
parents:
diff changeset
272 -- the current position until exactly N characters remain
kono
parents:
diff changeset
273 -- to be matched in the string. Fails if fewer than N
kono
parents:
diff changeset
274 -- unmatched characters remain in the string.
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 -- Tab(N) Where N is a natural number, matches characters from
kono
parents:
diff changeset
277 -- the current position until exactly N characters have
kono
parents:
diff changeset
278 -- been matched in all. Fails if more than N characters
kono
parents:
diff changeset
279 -- have already been matched.
kono
parents:
diff changeset
280
kono
parents:
diff changeset
281 -- Span(S) Where S is a string, matches a string of one or more
kono
parents:
diff changeset
282 -- characters that is among the characters given in the
kono
parents:
diff changeset
283 -- string. Always matches the longest possible such string.
kono
parents:
diff changeset
284 -- Fails if the current character is not one of the given
kono
parents:
diff changeset
285 -- set of characters.
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 -- Recursive Pattern Matching
kono
parents:
diff changeset
288 -- ==========================
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 -- The plus operator (+P) where P is a pattern variable, creates
kono
parents:
diff changeset
291 -- a recursive pattern that will, at pattern matching time, follow
kono
parents:
diff changeset
292 -- the pointer to obtain the referenced pattern, and then match this
kono
parents:
diff changeset
293 -- pattern. This may be used to construct recursive patterns. Consider
kono
parents:
diff changeset
294 -- for example:
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 -- P := ("A" or ("B" & (+P)))
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 -- On the first attempt, this pattern attempts to match the string "A".
kono
parents:
diff changeset
299 -- If this fails, then the alternative matches a "B", followed by an
kono
parents:
diff changeset
300 -- attempt to match P again. This second attempt first attempts to
kono
parents:
diff changeset
301 -- match "A", and so on. The result is a pattern that will match a
kono
parents:
diff changeset
302 -- string of B's followed by a single A.
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 -- This particular example could simply be written as NSpan('B') & 'A',
kono
parents:
diff changeset
305 -- but the use of recursive patterns in the general case can construct
kono
parents:
diff changeset
306 -- complex patterns which could not otherwise be built.
kono
parents:
diff changeset
307
kono
parents:
diff changeset
308 -- Pattern Assignment Operations
kono
parents:
diff changeset
309 -- =============================
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 -- In addition to the overall result of a pattern match, which indicates
kono
parents:
diff changeset
312 -- success or failure, it is often useful to be able to keep track of
kono
parents:
diff changeset
313 -- the pieces of the subject string that are matched by individual
kono
parents:
diff changeset
314 -- pattern elements, or subsections of the pattern.
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 -- The pattern assignment operators allow this capability. The first
kono
parents:
diff changeset
317 -- form is the immediate assignment:
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 -- P * S
kono
parents:
diff changeset
320
kono
parents:
diff changeset
321 -- Here P is an arbitrary pattern, and S is a variable of type VString
kono
parents:
diff changeset
322 -- that will be set to the substring matched by P. This assignment
kono
parents:
diff changeset
323 -- happens during pattern matching, so if P matches more than once,
kono
parents:
diff changeset
324 -- then the assignment happens more than once.
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 -- The deferred assignment operation:
kono
parents:
diff changeset
327
kono
parents:
diff changeset
328 -- P ** S
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 -- avoids these multiple assignments by deferring the assignment to the
kono
parents:
diff changeset
331 -- end of the match. If the entire match is successful, and if the
kono
parents:
diff changeset
332 -- pattern P was part of the successful match, then at the end of the
kono
parents:
diff changeset
333 -- matching operation the assignment to S of the string matching P is
kono
parents:
diff changeset
334 -- performed.
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 -- The cursor assignment operation:
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 -- Setcur(N'Access)
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340 -- assigns the current cursor position to the natural variable N. The
kono
parents:
diff changeset
341 -- cursor position is defined as the count of characters that have been
kono
parents:
diff changeset
342 -- matched so far (including any start point moves).
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 -- Finally the operations * and ** may be used with values of type
kono
parents:
diff changeset
345 -- Text_IO.File_Access. The effect is to do a Put_Line operation of
kono
parents:
diff changeset
346 -- the matched substring. These are particularly useful in debugging
kono
parents:
diff changeset
347 -- pattern matches.
kono
parents:
diff changeset
348
kono
parents:
diff changeset
349 -- Deferred Matching
kono
parents:
diff changeset
350 -- =================
kono
parents:
diff changeset
351
kono
parents:
diff changeset
352 -- The pattern construction functions (such as Len and Any) all permit
kono
parents:
diff changeset
353 -- the use of pointers to natural or string values, or functions that
kono
parents:
diff changeset
354 -- return natural or string values. These forms cause the actual value
kono
parents:
diff changeset
355 -- to be obtained at pattern matching time. This allows interesting
kono
parents:
diff changeset
356 -- possibilities for constructing dynamic patterns as illustrated in
kono
parents:
diff changeset
357 -- the examples section.
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 -- In addition the (+S) operator may be used where S is a pointer to
kono
parents:
diff changeset
360 -- string or function returning string, with a similar deferred effect.
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 -- A special use of deferred matching is the construction of predicate
kono
parents:
diff changeset
363 -- functions. The element (+P) where P is an access to a function that
kono
parents:
diff changeset
364 -- returns a Boolean value, causes the function to be called at the
kono
parents:
diff changeset
365 -- time the element is matched. If the function returns True, then the
kono
parents:
diff changeset
366 -- null string is matched, if the function returns False, then failure
kono
parents:
diff changeset
367 -- is signalled and previous alternatives are sought.
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 -- Deferred Replacement
kono
parents:
diff changeset
370 -- ====================
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 -- The simple model given for pattern replacement (where the matched
kono
parents:
diff changeset
373 -- substring is replaced by the string given as the third argument to
kono
parents:
diff changeset
374 -- Match) works fine in simple cases, but this approach does not work
kono
parents:
diff changeset
375 -- in the case where the expression used as the replacement string is
kono
parents:
diff changeset
376 -- dependent on values set by the match.
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 -- For example, suppose we want to find an instance of a parenthesized
kono
parents:
diff changeset
379 -- character, and replace the parentheses with square brackets. At first
kono
parents:
diff changeset
380 -- glance it would seem that:
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 -- Match (Subject, '(' & Len (1) * Char & ')', '[' & Char & ']');
kono
parents:
diff changeset
383
kono
parents:
diff changeset
384 -- would do the trick, but that does not work, because the third
kono
parents:
diff changeset
385 -- argument to Match gets evaluated too early, before the call to
kono
parents:
diff changeset
386 -- Match, and before the pattern match has had a chance to set Char.
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 -- To solve this problem we provide the deferred replacement capability.
kono
parents:
diff changeset
389 -- With this approach, which of course is only needed if the pattern
kono
parents:
diff changeset
390 -- involved has side effects, is to do the match in two stages. The
kono
parents:
diff changeset
391 -- call to Match sets a pattern result in a variable of the private
kono
parents:
diff changeset
392 -- type Match_Result, and then a subsequent Replace operation uses
kono
parents:
diff changeset
393 -- this Match_Result object to perform the required replacement.
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 -- Using this approach, we can now write the above operation properly
kono
parents:
diff changeset
396 -- in a manner that will work:
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 -- M : Match_Result;
kono
parents:
diff changeset
399 -- ...
kono
parents:
diff changeset
400 -- Match (Subject, '(' & Len (1) * Char & ')', M);
kono
parents:
diff changeset
401 -- Replace (M, '[' & Char & ']');
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 -- As with other Match cases, there is a function and procedure form
kono
parents:
diff changeset
404 -- of this match call. A call to Replace after a failed match has no
kono
parents:
diff changeset
405 -- effect. Note that Subject should not be modified between the calls.
kono
parents:
diff changeset
406
kono
parents:
diff changeset
407 -- Examples of Pattern Matching
kono
parents:
diff changeset
408 -- ============================
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 -- First a simple example of the use of pattern replacement to remove
kono
parents:
diff changeset
411 -- a line number from the start of a string. We assume that the line
kono
parents:
diff changeset
412 -- number has the form of a string of decimal digits followed by a
kono
parents:
diff changeset
413 -- period, followed by one or more spaces.
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 -- Digs : constant Pattern := Span("0123456789");
kono
parents:
diff changeset
416
kono
parents:
diff changeset
417 -- Lnum : constant Pattern := Pos(0) & Digs & '.' & Span(' ');
kono
parents:
diff changeset
418
kono
parents:
diff changeset
419 -- Now to use this pattern we simply do a match with a replacement:
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 -- Match (Line, Lnum, "");
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423 -- which replaces the line number by the null string. Note that it is
kono
parents:
diff changeset
424 -- also possible to use an Ada.Strings.Maps.Character_Set value as an
kono
parents:
diff changeset
425 -- argument to Span and similar functions, and in particular all the
kono
parents:
diff changeset
426 -- useful constants 'in Ada.Strings.Maps.Constants are available. This
kono
parents:
diff changeset
427 -- means that we could define Digs as:
kono
parents:
diff changeset
428
kono
parents:
diff changeset
429 -- Digs : constant Pattern := Span(Decimal_Digit_Set);
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 -- The style we use here, of defining constant patterns and then using
kono
parents:
diff changeset
432 -- them is typical. It is possible to build up patterns dynamically,
kono
parents:
diff changeset
433 -- but it is usually more efficient to build them in pieces in advance
kono
parents:
diff changeset
434 -- using constant declarations. Note in particular that although it is
kono
parents:
diff changeset
435 -- possible to construct a pattern directly as an argument for the
kono
parents:
diff changeset
436 -- Match routine, it is much more efficient to preconstruct the pattern
kono
parents:
diff changeset
437 -- as we did in this example.
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 -- Now let's look at the use of pattern assignment to break a
kono
parents:
diff changeset
440 -- string into sections. Suppose that the input string has two
kono
parents:
diff changeset
441 -- unsigned decimal integers, separated by spaces or a comma,
kono
parents:
diff changeset
442 -- with spaces allowed anywhere. Then we can isolate the two
kono
parents:
diff changeset
443 -- numbers with the following pattern:
kono
parents:
diff changeset
444
kono
parents:
diff changeset
445 -- Num1, Num2 : aliased VString;
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 -- B : constant Pattern := NSpan(' ');
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 -- N : constant Pattern := Span("0123456789");
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 -- T : constant Pattern :=
kono
parents:
diff changeset
452 -- NSpan(' ') & N * Num1 & Span(" ,") & N * Num2;
kono
parents:
diff changeset
453
kono
parents:
diff changeset
454 -- The match operation Match (" 124, 257 ", T) would assign the
kono
parents:
diff changeset
455 -- string 124 to Num1 and the string 257 to Num2.
kono
parents:
diff changeset
456
kono
parents:
diff changeset
457 -- Now let's see how more complex elements can be built from the
kono
parents:
diff changeset
458 -- set of primitive elements. The following pattern matches strings
kono
parents:
diff changeset
459 -- that have the syntax of Ada 95 based literals:
kono
parents:
diff changeset
460
kono
parents:
diff changeset
461 -- Digs : constant Pattern := Span(Decimal_Digit_Set);
kono
parents:
diff changeset
462 -- UDigs : constant Pattern := Digs & Arbno('_' & Digs);
kono
parents:
diff changeset
463
kono
parents:
diff changeset
464 -- Edig : constant Pattern := Span(Hexadecimal_Digit_Set);
kono
parents:
diff changeset
465 -- UEdig : constant Pattern := Edig & Arbno('_' & Edig);
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 -- Bnum : constant Pattern := Udigs & '#' & UEdig & '#';
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 -- A match against Bnum will now match the desired strings, e.g.
kono
parents:
diff changeset
470 -- it will match 16#123_abc#, but not a#b#. However, this pattern
kono
parents:
diff changeset
471 -- is not quite complete, since it does not allow colons to replace
kono
parents:
diff changeset
472 -- the pound signs. The following is more complete:
kono
parents:
diff changeset
473
kono
parents:
diff changeset
474 -- Bchar : constant Pattern := Any("#:");
kono
parents:
diff changeset
475 -- Bnum : constant Pattern := Udigs & Bchar & UEdig & Bchar;
kono
parents:
diff changeset
476
kono
parents:
diff changeset
477 -- but that is still not quite right, since it allows # and : to be
kono
parents:
diff changeset
478 -- mixed, and they are supposed to be used consistently. We solve
kono
parents:
diff changeset
479 -- this by using a deferred match.
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 -- Temp : aliased VString;
kono
parents:
diff changeset
482
kono
parents:
diff changeset
483 -- Bnum : constant Pattern :=
kono
parents:
diff changeset
484 -- Udigs & Bchar * Temp & UEdig & (+Temp)
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 -- Here the first instance of the base character is stored in Temp, and
kono
parents:
diff changeset
487 -- then later in the pattern we rematch the value that was assigned.
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 -- For an example of a recursive pattern, let's define a pattern
kono
parents:
diff changeset
490 -- that is like the built in Bal, but the string matched is balanced
kono
parents:
diff changeset
491 -- with respect to square brackets or curly brackets.
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 -- The language for such strings might be defined in extended BNF as
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 -- ELEMENT ::= <any character other than [] or {}>
kono
parents:
diff changeset
496 -- | '[' BALANCED_STRING ']'
kono
parents:
diff changeset
497 -- | '{' BALANCED_STRING '}'
kono
parents:
diff changeset
498
kono
parents:
diff changeset
499 -- BALANCED_STRING ::= ELEMENT {ELEMENT}
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 -- Here we use {} to indicate zero or more occurrences of a term, as
kono
parents:
diff changeset
502 -- is common practice in extended BNF. Now we can translate the above
kono
parents:
diff changeset
503 -- BNF into recursive patterns as follows:
kono
parents:
diff changeset
504
kono
parents:
diff changeset
505 -- Element, Balanced_String : aliased Pattern;
kono
parents:
diff changeset
506 -- .
kono
parents:
diff changeset
507 -- .
kono
parents:
diff changeset
508 -- .
kono
parents:
diff changeset
509 -- Element := NotAny ("[]{}")
kono
parents:
diff changeset
510 -- or
kono
parents:
diff changeset
511 -- ('[' & (+Balanced_String) & ']')
kono
parents:
diff changeset
512 -- or
kono
parents:
diff changeset
513 -- ('{' & (+Balanced_String) & '}');
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 -- Balanced_String := Element & Arbno (Element);
kono
parents:
diff changeset
516
kono
parents:
diff changeset
517 -- Note the important use of + here to refer to a pattern not yet
kono
parents:
diff changeset
518 -- defined. Note also that we use assignments precisely because we
kono
parents:
diff changeset
519 -- cannot refer to as yet undeclared variables in initializations.
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 -- Now that this pattern is constructed, we can use it as though it
kono
parents:
diff changeset
522 -- were a new primitive pattern element, and for example, the match:
kono
parents:
diff changeset
523
kono
parents:
diff changeset
524 -- Match ("xy[ab{cd}]", Balanced_String * Current_Output & Fail);
kono
parents:
diff changeset
525
kono
parents:
diff changeset
526 -- will generate the output:
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 -- x
kono
parents:
diff changeset
529 -- xy
kono
parents:
diff changeset
530 -- xy[ab{cd}]
kono
parents:
diff changeset
531 -- y
kono
parents:
diff changeset
532 -- y[ab{cd}]
kono
parents:
diff changeset
533 -- [ab{cd}]
kono
parents:
diff changeset
534 -- a
kono
parents:
diff changeset
535 -- ab
kono
parents:
diff changeset
536 -- ab{cd}
kono
parents:
diff changeset
537 -- b
kono
parents:
diff changeset
538 -- b{cd}
kono
parents:
diff changeset
539 -- {cd}
kono
parents:
diff changeset
540 -- c
kono
parents:
diff changeset
541 -- cd
kono
parents:
diff changeset
542 -- d
kono
parents:
diff changeset
543
kono
parents:
diff changeset
544 -- Note that the function of the fail here is simply to force the
kono
parents:
diff changeset
545 -- pattern Balanced_String to match all possible alternatives. Studying
kono
parents:
diff changeset
546 -- the operation of this pattern in detail is highly instructive.
kono
parents:
diff changeset
547
kono
parents:
diff changeset
548 -- Finally we give a rather elaborate example of the use of deferred
kono
parents:
diff changeset
549 -- matching. The following declarations build up a pattern which will
kono
parents:
diff changeset
550 -- find the longest string of decimal digits in the subject string.
kono
parents:
diff changeset
551
kono
parents:
diff changeset
552 -- Max, Cur : VString;
kono
parents:
diff changeset
553 -- Loc : Natural;
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 -- function GtS return Boolean is
kono
parents:
diff changeset
556 -- begin
kono
parents:
diff changeset
557 -- return Length (Cur) > Length (Max);
kono
parents:
diff changeset
558 -- end GtS;
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 -- Digit : constant Character_Set := Decimal_Digit_Set;
kono
parents:
diff changeset
561
kono
parents:
diff changeset
562 -- Digs : constant Pattern := Span(Digit);
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 -- Find : constant Pattern :=
kono
parents:
diff changeset
565 -- "" * Max & Fence & -- initialize Max to null
kono
parents:
diff changeset
566 -- BreakX (Digit) & -- scan looking for digits
kono
parents:
diff changeset
567 -- ((Span(Digit) * Cur & -- assign next string to Cur
kono
parents:
diff changeset
568 -- (+GtS'Unrestricted_Access) & -- check size(Cur) > Size(Max)
kono
parents:
diff changeset
569 -- Setcur(Loc'Access)) -- if so, save location
kono
parents:
diff changeset
570 -- * Max) & -- and assign to Max
kono
parents:
diff changeset
571 -- Fail; -- seek all alternatives
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 -- As we see from the comments here, complex patterns like this take
kono
parents:
diff changeset
574 -- on aspects of sequential programs. In fact they are sequential
kono
parents:
diff changeset
575 -- programs with general backtracking. In this pattern, we first use
kono
parents:
diff changeset
576 -- a pattern assignment that matches null and assigns it to Max, so
kono
parents:
diff changeset
577 -- that it is initialized for the new match. Now BreakX scans to the
kono
parents:
diff changeset
578 -- next digit. Arb would do here, but BreakX will be more efficient.
kono
parents:
diff changeset
579 -- Once we have found a digit, we scan out the longest string of
kono
parents:
diff changeset
580 -- digits with Span, and assign it to Cur. The deferred call to GtS
kono
parents:
diff changeset
581 -- tests if the string we assigned to Cur is the longest so far. If
kono
parents:
diff changeset
582 -- not, then failure is signalled, and we seek alternatives (this
kono
parents:
diff changeset
583 -- means that BreakX will extend and look for the next digit string).
kono
parents:
diff changeset
584 -- If the call to GtS succeeds then the matched string is assigned
kono
parents:
diff changeset
585 -- as the largest string so far into Max and its location is saved
kono
parents:
diff changeset
586 -- in Loc. Finally Fail forces the match to fail and seek alternatives,
kono
parents:
diff changeset
587 -- so that the entire string is searched.
kono
parents:
diff changeset
588
kono
parents:
diff changeset
589 -- If the pattern Find is matched against a string, the variable Max
kono
parents:
diff changeset
590 -- at the end of the pattern will have the longest string of digits,
kono
parents:
diff changeset
591 -- and Loc will be the starting character location of the string. For
kono
parents:
diff changeset
592 -- example, Match("ab123cd4657ef23", Find) will assign "4657" to Max
kono
parents:
diff changeset
593 -- and 11 to Loc (indicating that the string ends with the eleventh
kono
parents:
diff changeset
594 -- character of the string).
kono
parents:
diff changeset
595
kono
parents:
diff changeset
596 -- Note: the use of Unrestricted_Access to reference GtS will not
kono
parents:
diff changeset
597 -- be needed if GtS is defined at the outer level, but definitely
kono
parents:
diff changeset
598 -- will be necessary if GtS is a nested function (in which case of
kono
parents:
diff changeset
599 -- course the scope of the pattern Find will be restricted to this
kono
parents:
diff changeset
600 -- nested scope, and this cannot be checked, i.e. use of the pattern
kono
parents:
diff changeset
601 -- outside this scope is erroneous). Generally it is a good idea to
kono
parents:
diff changeset
602 -- define patterns and the functions they call at the outer level
kono
parents:
diff changeset
603 -- where possible, to avoid such problems.
kono
parents:
diff changeset
604
kono
parents:
diff changeset
605 -- Correspondence with Pattern Matching in SPITBOL
kono
parents:
diff changeset
606 -- ===============================================
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 -- Generally the Ada syntax and names correspond closely to SPITBOL
kono
parents:
diff changeset
609 -- syntax for pattern matching construction.
kono
parents:
diff changeset
610
kono
parents:
diff changeset
611 -- The basic pattern construction operators are renamed as follows:
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 -- Spitbol Ada
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 -- (space) &
kono
parents:
diff changeset
616 -- | or
kono
parents:
diff changeset
617 -- $ *
kono
parents:
diff changeset
618 -- . **
kono
parents:
diff changeset
619
kono
parents:
diff changeset
620 -- The Ada operators were chosen so that the relative precedences of
kono
parents:
diff changeset
621 -- these operators corresponds to that of the Spitbol operators, but
kono
parents:
diff changeset
622 -- as always, the use of parentheses is advisable to clarify.
kono
parents:
diff changeset
623
kono
parents:
diff changeset
624 -- The pattern construction operators all have similar names except for
kono
parents:
diff changeset
625
kono
parents:
diff changeset
626 -- Spitbol Ada
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 -- Abort Cancel
kono
parents:
diff changeset
629 -- Rem Rest
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 -- where we have clashes with Ada reserved names
kono
parents:
diff changeset
632
kono
parents:
diff changeset
633 -- Ada requires the use of 'Access to refer to functions used in the
kono
parents:
diff changeset
634 -- pattern match, and often the use of 'Unrestricted_Access may be
kono
parents:
diff changeset
635 -- necessary to get around the scope restrictions if the functions
kono
parents:
diff changeset
636 -- are not declared at the outer level.
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 -- The actual pattern matching syntax is modified in Ada as follows:
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 -- Spitbol Ada
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 -- X Y Match (X, Y);
kono
parents:
diff changeset
643 -- X Y = Z Match (X, Y, Z);
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 -- and pattern failure is indicated by returning a Boolean result from
kono
parents:
diff changeset
646 -- the Match function (True for success, False for failure).
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 -----------------------
kono
parents:
diff changeset
649 -- Type Declarations --
kono
parents:
diff changeset
650 -----------------------
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 type Pattern is private;
kono
parents:
diff changeset
653 -- Type representing a pattern. This package provides a complete set of
kono
parents:
diff changeset
654 -- operations for constructing patterns that can be used in the pattern
kono
parents:
diff changeset
655 -- matching operations provided.
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 type Boolean_Func is access function return Boolean;
kono
parents:
diff changeset
658 -- General Boolean function type. When this type is used as a formal
kono
parents:
diff changeset
659 -- parameter type in this package, it indicates a deferred predicate
kono
parents:
diff changeset
660 -- pattern. The function will be called when the pattern element is
kono
parents:
diff changeset
661 -- matched and failure signalled if False is returned.
kono
parents:
diff changeset
662
kono
parents:
diff changeset
663 type Natural_Func is access function return Natural;
kono
parents:
diff changeset
664 -- General Natural function type. When this type is used as a formal
kono
parents:
diff changeset
665 -- parameter type in this package, it indicates a deferred pattern.
kono
parents:
diff changeset
666 -- The function will be called when the pattern element is matched
kono
parents:
diff changeset
667 -- to obtain the currently referenced Natural value.
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 type VString_Func is access function return VString;
kono
parents:
diff changeset
670 -- General VString function type. When this type is used as a formal
kono
parents:
diff changeset
671 -- parameter type in this package, it indicates a deferred pattern.
kono
parents:
diff changeset
672 -- The function will be called when the pattern element is matched
kono
parents:
diff changeset
673 -- to obtain the currently referenced string value.
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 subtype PString is String;
kono
parents:
diff changeset
676 -- This subtype is used in the remainder of the package to indicate a
kono
parents:
diff changeset
677 -- formal parameter that is converted to its corresponding pattern,
kono
parents:
diff changeset
678 -- i.e. a pattern that matches the characters of the string.
kono
parents:
diff changeset
679
kono
parents:
diff changeset
680 subtype PChar is Character;
kono
parents:
diff changeset
681 -- Similarly, this subtype is used in the remainder of the package to
kono
parents:
diff changeset
682 -- indicate a formal parameter that is converted to its corresponding
kono
parents:
diff changeset
683 -- pattern, i.e. a pattern that matches this one character.
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 subtype VString_Var is VString;
kono
parents:
diff changeset
686 subtype Pattern_Var is Pattern;
kono
parents:
diff changeset
687 -- These synonyms are used as formal parameter types to a function where,
kono
parents:
diff changeset
688 -- if the language allowed, we would use in out parameters, but we are
kono
parents:
diff changeset
689 -- not allowed to have in out parameters for functions. Instead we pass
kono
parents:
diff changeset
690 -- actuals which must be variables, and with a bit of trickery in the
kono
parents:
diff changeset
691 -- body, manage to interpret them properly as though they were indeed
kono
parents:
diff changeset
692 -- in out parameters.
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 pragma Warnings (Off, VString_Var);
kono
parents:
diff changeset
695 pragma Warnings (Off, Pattern_Var);
kono
parents:
diff changeset
696 -- We turn off warnings for these two types so that when variables are used
kono
parents:
diff changeset
697 -- as arguments in this context, warnings about them not being assigned in
kono
parents:
diff changeset
698 -- the source program will be suppressed.
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 --------------------------------
kono
parents:
diff changeset
701 -- Basic Pattern Construction --
kono
parents:
diff changeset
702 --------------------------------
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 function "&" (L : Pattern; R : Pattern) return Pattern;
kono
parents:
diff changeset
705 function "&" (L : PString; R : Pattern) return Pattern;
kono
parents:
diff changeset
706 function "&" (L : Pattern; R : PString) return Pattern;
kono
parents:
diff changeset
707 function "&" (L : PChar; R : Pattern) return Pattern;
kono
parents:
diff changeset
708 function "&" (L : Pattern; R : PChar) return Pattern;
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 -- Pattern concatenation. Matches L followed by R
kono
parents:
diff changeset
711
kono
parents:
diff changeset
712 function "or" (L : Pattern; R : Pattern) return Pattern;
kono
parents:
diff changeset
713 function "or" (L : PString; R : Pattern) return Pattern;
kono
parents:
diff changeset
714 function "or" (L : Pattern; R : PString) return Pattern;
kono
parents:
diff changeset
715 function "or" (L : PString; R : PString) return Pattern;
kono
parents:
diff changeset
716 function "or" (L : PChar; R : Pattern) return Pattern;
kono
parents:
diff changeset
717 function "or" (L : Pattern; R : PChar) return Pattern;
kono
parents:
diff changeset
718 function "or" (L : PChar; R : PChar) return Pattern;
kono
parents:
diff changeset
719 function "or" (L : PString; R : PChar) return Pattern;
kono
parents:
diff changeset
720 function "or" (L : PChar; R : PString) return Pattern;
kono
parents:
diff changeset
721 -- Pattern alternation. Creates a pattern that will first try to match
kono
parents:
diff changeset
722 -- L and then on a subsequent failure, attempts to match R instead.
kono
parents:
diff changeset
723
kono
parents:
diff changeset
724 ----------------------------------
kono
parents:
diff changeset
725 -- Pattern Assignment Functions --
kono
parents:
diff changeset
726 ----------------------------------
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 function "*" (P : Pattern; Var : VString_Var) return Pattern;
kono
parents:
diff changeset
729 function "*" (P : PString; Var : VString_Var) return Pattern;
kono
parents:
diff changeset
730 function "*" (P : PChar; Var : VString_Var) return Pattern;
kono
parents:
diff changeset
731 -- Matches P, and if the match succeeds, assigns the matched substring
kono
parents:
diff changeset
732 -- to the given VString variable Var. This assignment happens as soon as
kono
parents:
diff changeset
733 -- the substring is matched, and if the pattern P1 is matched more than
kono
parents:
diff changeset
734 -- once during the course of the match, then the assignment will occur
kono
parents:
diff changeset
735 -- more than once.
kono
parents:
diff changeset
736
kono
parents:
diff changeset
737 function "**" (P : Pattern; Var : VString_Var) return Pattern;
kono
parents:
diff changeset
738 function "**" (P : PString; Var : VString_Var) return Pattern;
kono
parents:
diff changeset
739 function "**" (P : PChar; Var : VString_Var) return Pattern;
kono
parents:
diff changeset
740 -- Like "*" above, except that the assignment happens at most once
kono
parents:
diff changeset
741 -- after the entire match is completed successfully. If the match
kono
parents:
diff changeset
742 -- fails, then no assignment takes place.
kono
parents:
diff changeset
743
kono
parents:
diff changeset
744 ----------------------------------
kono
parents:
diff changeset
745 -- Deferred Matching Operations --
kono
parents:
diff changeset
746 ----------------------------------
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 function "+" (Str : VString_Var) return Pattern;
kono
parents:
diff changeset
749 -- Here Str must be a VString variable. This function constructs a
kono
parents:
diff changeset
750 -- pattern which at pattern matching time will access the current
kono
parents:
diff changeset
751 -- value of this variable, and match against these characters.
kono
parents:
diff changeset
752
kono
parents:
diff changeset
753 function "+" (Str : VString_Func) return Pattern;
kono
parents:
diff changeset
754 -- Constructs a pattern which at pattern matching time calls the given
kono
parents:
diff changeset
755 -- function, and then matches against the string or character value
kono
parents:
diff changeset
756 -- that is returned by the call.
kono
parents:
diff changeset
757
kono
parents:
diff changeset
758 function "+" (P : Pattern_Var) return Pattern;
kono
parents:
diff changeset
759 -- Here P must be a Pattern variable. This function constructs a
kono
parents:
diff changeset
760 -- pattern which at pattern matching time will access the current
kono
parents:
diff changeset
761 -- value of this variable, and match against the pattern value.
kono
parents:
diff changeset
762
kono
parents:
diff changeset
763 function "+" (P : Boolean_Func) return Pattern;
kono
parents:
diff changeset
764 -- Constructs a predicate pattern function that at pattern matching time
kono
parents:
diff changeset
765 -- calls the given function. If True is returned, then the pattern matches.
kono
parents:
diff changeset
766 -- If False is returned, then failure is signalled.
kono
parents:
diff changeset
767
kono
parents:
diff changeset
768 --------------------------------
kono
parents:
diff changeset
769 -- Pattern Building Functions --
kono
parents:
diff changeset
770 --------------------------------
kono
parents:
diff changeset
771
kono
parents:
diff changeset
772 function Arb return Pattern;
kono
parents:
diff changeset
773 -- Constructs a pattern that will match any string. On the first attempt,
kono
parents:
diff changeset
774 -- the pattern matches a null string, then on each successive failure, it
kono
parents:
diff changeset
775 -- matches one more character, and only fails if matching the entire rest
kono
parents:
diff changeset
776 -- of the string.
kono
parents:
diff changeset
777
kono
parents:
diff changeset
778 function Arbno (P : Pattern) return Pattern;
kono
parents:
diff changeset
779 function Arbno (P : PString) return Pattern;
kono
parents:
diff changeset
780 function Arbno (P : PChar) return Pattern;
kono
parents:
diff changeset
781 -- Pattern repetition. First matches null, then on a subsequent failure
kono
parents:
diff changeset
782 -- attempts to match an additional instance of the given pattern.
kono
parents:
diff changeset
783 -- Equivalent to (but more efficient than) P & ("" or (P & ("" or ...
kono
parents:
diff changeset
784
kono
parents:
diff changeset
785 function Any (Str : String) return Pattern;
kono
parents:
diff changeset
786 function Any (Str : VString) return Pattern;
kono
parents:
diff changeset
787 function Any (Str : Character) return Pattern;
kono
parents:
diff changeset
788 function Any (Str : Character_Set) return Pattern;
kono
parents:
diff changeset
789 function Any (Str : not null access VString) return Pattern;
kono
parents:
diff changeset
790 function Any (Str : VString_Func) return Pattern;
kono
parents:
diff changeset
791 -- Constructs a pattern that matches a single character that is one of
kono
parents:
diff changeset
792 -- the characters in the given argument. The pattern fails if the current
kono
parents:
diff changeset
793 -- character is not in Str.
kono
parents:
diff changeset
794
kono
parents:
diff changeset
795 function Bal return Pattern;
kono
parents:
diff changeset
796 -- Constructs a pattern that will match any non-empty string that is
kono
parents:
diff changeset
797 -- parentheses balanced with respect to the normal parentheses characters.
kono
parents:
diff changeset
798 -- Attempts to extend the string if a subsequent failure occurs.
kono
parents:
diff changeset
799
kono
parents:
diff changeset
800 function Break (Str : String) return Pattern;
kono
parents:
diff changeset
801 function Break (Str : VString) return Pattern;
kono
parents:
diff changeset
802 function Break (Str : Character) return Pattern;
kono
parents:
diff changeset
803 function Break (Str : Character_Set) return Pattern;
kono
parents:
diff changeset
804 function Break (Str : not null access VString) return Pattern;
kono
parents:
diff changeset
805 function Break (Str : VString_Func) return Pattern;
kono
parents:
diff changeset
806 -- Constructs a pattern that matches a (possibly null) string which
kono
parents:
diff changeset
807 -- is immediately followed by a character in the given argument. This
kono
parents:
diff changeset
808 -- character is not part of the matched string. The pattern fails if
kono
parents:
diff changeset
809 -- the remaining characters to be matched do not include any of the
kono
parents:
diff changeset
810 -- characters in Str.
kono
parents:
diff changeset
811
kono
parents:
diff changeset
812 function BreakX (Str : String) return Pattern;
kono
parents:
diff changeset
813 function BreakX (Str : VString) return Pattern;
kono
parents:
diff changeset
814 function BreakX (Str : Character) return Pattern;
kono
parents:
diff changeset
815 function BreakX (Str : Character_Set) return Pattern;
kono
parents:
diff changeset
816 function BreakX (Str : not null access VString) return Pattern;
kono
parents:
diff changeset
817 function BreakX (Str : VString_Func) return Pattern;
kono
parents:
diff changeset
818 -- Like Break, but the pattern attempts to extend on a failure to find
kono
parents:
diff changeset
819 -- the next occurrence of a character in Str, and only fails when the
kono
parents:
diff changeset
820 -- last such instance causes a failure.
kono
parents:
diff changeset
821
kono
parents:
diff changeset
822 function Cancel return Pattern;
kono
parents:
diff changeset
823 -- Constructs a pattern that immediately aborts the entire match
kono
parents:
diff changeset
824
kono
parents:
diff changeset
825 function Fail return Pattern;
kono
parents:
diff changeset
826 -- Constructs a pattern that always fails
kono
parents:
diff changeset
827
kono
parents:
diff changeset
828 function Fence return Pattern;
kono
parents:
diff changeset
829 -- Constructs a pattern that matches null on the first attempt, and then
kono
parents:
diff changeset
830 -- causes the entire match to be aborted if a subsequent failure occurs.
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 function Fence (P : Pattern) return Pattern;
kono
parents:
diff changeset
833 -- Constructs a pattern that first matches P. If P fails, then the
kono
parents:
diff changeset
834 -- constructed pattern fails. If P succeeds, then the match proceeds,
kono
parents:
diff changeset
835 -- but if subsequent failure occurs, alternatives in P are not sought.
kono
parents:
diff changeset
836 -- The idea of Fence is that each time the pattern is matched, just
kono
parents:
diff changeset
837 -- one attempt is made to match P, without trying alternatives.
kono
parents:
diff changeset
838
kono
parents:
diff changeset
839 function Len (Count : Natural) return Pattern;
kono
parents:
diff changeset
840 function Len (Count : not null access Natural) return Pattern;
kono
parents:
diff changeset
841 function Len (Count : Natural_Func) return Pattern;
kono
parents:
diff changeset
842 -- Constructs a pattern that matches exactly the given number of
kono
parents:
diff changeset
843 -- characters. The pattern fails if fewer than this number of characters
kono
parents:
diff changeset
844 -- remain to be matched in the string.
kono
parents:
diff changeset
845
kono
parents:
diff changeset
846 function NotAny (Str : String) return Pattern;
kono
parents:
diff changeset
847 function NotAny (Str : VString) return Pattern;
kono
parents:
diff changeset
848 function NotAny (Str : Character) return Pattern;
kono
parents:
diff changeset
849 function NotAny (Str : Character_Set) return Pattern;
kono
parents:
diff changeset
850 function NotAny (Str : not null access VString) return Pattern;
kono
parents:
diff changeset
851 function NotAny (Str : VString_Func) return Pattern;
kono
parents:
diff changeset
852 -- Constructs a pattern that matches a single character that is not
kono
parents:
diff changeset
853 -- one of the characters in the given argument. The pattern Fails if
kono
parents:
diff changeset
854 -- the current character is in Str.
kono
parents:
diff changeset
855
kono
parents:
diff changeset
856 function NSpan (Str : String) return Pattern;
kono
parents:
diff changeset
857 function NSpan (Str : VString) return Pattern;
kono
parents:
diff changeset
858 function NSpan (Str : Character) return Pattern;
kono
parents:
diff changeset
859 function NSpan (Str : Character_Set) return Pattern;
kono
parents:
diff changeset
860 function NSpan (Str : not null access VString) return Pattern;
kono
parents:
diff changeset
861 function NSpan (Str : VString_Func) return Pattern;
kono
parents:
diff changeset
862 -- Constructs a pattern that matches the longest possible string
kono
parents:
diff changeset
863 -- consisting entirely of characters from the given argument. The
kono
parents:
diff changeset
864 -- string may be empty, so this pattern always succeeds.
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 function Pos (Count : Natural) return Pattern;
kono
parents:
diff changeset
867 function Pos (Count : not null access Natural) return Pattern;
kono
parents:
diff changeset
868 function Pos (Count : Natural_Func) return Pattern;
kono
parents:
diff changeset
869 -- Constructs a pattern that matches the null string if exactly Count
kono
parents:
diff changeset
870 -- characters have already been matched, and otherwise fails.
kono
parents:
diff changeset
871
kono
parents:
diff changeset
872 function Rest return Pattern;
kono
parents:
diff changeset
873 -- Constructs a pattern that always succeeds, matching the remaining
kono
parents:
diff changeset
874 -- unmatched characters in the pattern.
kono
parents:
diff changeset
875
kono
parents:
diff changeset
876 function Rpos (Count : Natural) return Pattern;
kono
parents:
diff changeset
877 function Rpos (Count : not null access Natural) return Pattern;
kono
parents:
diff changeset
878 function Rpos (Count : Natural_Func) return Pattern;
kono
parents:
diff changeset
879 -- Constructs a pattern that matches the null string if exactly Count
kono
parents:
diff changeset
880 -- characters remain to be matched in the string, and otherwise fails.
kono
parents:
diff changeset
881
kono
parents:
diff changeset
882 function Rtab (Count : Natural) return Pattern;
kono
parents:
diff changeset
883 function Rtab (Count : not null access Natural) return Pattern;
kono
parents:
diff changeset
884 function Rtab (Count : Natural_Func) return Pattern;
kono
parents:
diff changeset
885 -- Constructs a pattern that matches from the current location until
kono
parents:
diff changeset
886 -- exactly Count characters remain to be matched in the string. The
kono
parents:
diff changeset
887 -- pattern fails if fewer than Count characters remain to be matched.
kono
parents:
diff changeset
888
kono
parents:
diff changeset
889 function Setcur (Var : not null access Natural) return Pattern;
kono
parents:
diff changeset
890 -- Constructs a pattern that matches the null string, and assigns the
kono
parents:
diff changeset
891 -- current cursor position in the string. This value is the number of
kono
parents:
diff changeset
892 -- characters matched so far. So it is zero at the start of the match.
kono
parents:
diff changeset
893
kono
parents:
diff changeset
894 function Span (Str : String) return Pattern;
kono
parents:
diff changeset
895 function Span (Str : VString) return Pattern;
kono
parents:
diff changeset
896 function Span (Str : Character) return Pattern;
kono
parents:
diff changeset
897 function Span (Str : Character_Set) return Pattern;
kono
parents:
diff changeset
898 function Span (Str : not null access VString) return Pattern;
kono
parents:
diff changeset
899 function Span (Str : VString_Func) return Pattern;
kono
parents:
diff changeset
900 -- Constructs a pattern that matches the longest possible string
kono
parents:
diff changeset
901 -- consisting entirely of characters from the given argument. The
kono
parents:
diff changeset
902 -- string cannot be empty, so the pattern fails if the current
kono
parents:
diff changeset
903 -- character is not one of the characters in Str.
kono
parents:
diff changeset
904
kono
parents:
diff changeset
905 function Succeed return Pattern;
kono
parents:
diff changeset
906 -- Constructs a pattern that succeeds matching null, both on the first
kono
parents:
diff changeset
907 -- attempt, and on any rematch attempt, i.e. it is equivalent to an
kono
parents:
diff changeset
908 -- infinite alternation of null strings.
kono
parents:
diff changeset
909
kono
parents:
diff changeset
910 function Tab (Count : Natural) return Pattern;
kono
parents:
diff changeset
911 function Tab (Count : not null access Natural) return Pattern;
kono
parents:
diff changeset
912 function Tab (Count : Natural_Func) return Pattern;
kono
parents:
diff changeset
913 -- Constructs a pattern that from the current location until Count
kono
parents:
diff changeset
914 -- characters have been matched. The pattern fails if more than Count
kono
parents:
diff changeset
915 -- characters have already been matched.
kono
parents:
diff changeset
916
kono
parents:
diff changeset
917 ---------------------------------
kono
parents:
diff changeset
918 -- Pattern Matching Operations --
kono
parents:
diff changeset
919 ---------------------------------
kono
parents:
diff changeset
920
kono
parents:
diff changeset
921 -- The Match function performs an actual pattern matching operation.
kono
parents:
diff changeset
922 -- The versions with three parameters perform a match without modifying
kono
parents:
diff changeset
923 -- the subject string and return a Boolean result indicating if the
kono
parents:
diff changeset
924 -- match is successful or not. The Anchor parameter is set to True to
kono
parents:
diff changeset
925 -- obtain an anchored match in which the pattern is required to match
kono
parents:
diff changeset
926 -- the first character of the string. In an unanchored match, which is
kono
parents:
diff changeset
927
kono
parents:
diff changeset
928 -- the default, successive attempts are made to match the given pattern
kono
parents:
diff changeset
929 -- at each character of the subject string until a match succeeds, or
kono
parents:
diff changeset
930 -- until all possibilities have failed.
kono
parents:
diff changeset
931
kono
parents:
diff changeset
932 -- Note that pattern assignment functions in the pattern may generate
kono
parents:
diff changeset
933 -- side effects, so these functions are not necessarily pure.
kono
parents:
diff changeset
934
kono
parents:
diff changeset
935 Anchored_Mode : Boolean := False;
kono
parents:
diff changeset
936 -- This global variable can be set True to cause all subsequent pattern
kono
parents:
diff changeset
937 -- matches to operate in anchored mode. In anchored mode, no attempt is
kono
parents:
diff changeset
938 -- made to move the anchor point, so that if the match succeeds it must
kono
parents:
diff changeset
939 -- succeed starting at the first character. Note that the effect of
kono
parents:
diff changeset
940 -- anchored mode may be achieved in individual pattern matches by using
kono
parents:
diff changeset
941 -- Fence or Pos(0) at the start of the pattern.
kono
parents:
diff changeset
942
kono
parents:
diff changeset
943 Pattern_Stack_Overflow : exception;
kono
parents:
diff changeset
944 -- Exception raised if internal pattern matching stack overflows. This
kono
parents:
diff changeset
945 -- is typically the result of runaway pattern recursion. If there is a
kono
parents:
diff changeset
946 -- genuine case of stack overflow, then either the match must be broken
kono
parents:
diff changeset
947 -- down into simpler steps, or the stack limit must be reset.
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 Stack_Size : constant Positive := 2000;
kono
parents:
diff changeset
950 -- Size used for internal pattern matching stack. Increase this size if
kono
parents:
diff changeset
951 -- complex patterns cause Pattern_Stack_Overflow to be raised.
kono
parents:
diff changeset
952
kono
parents:
diff changeset
953 -- Simple match functions. The subject is matched against the pattern.
kono
parents:
diff changeset
954 -- Any immediate or deferred assignments or writes are executed, and
kono
parents:
diff changeset
955 -- the returned value indicates whether or not the match succeeded.
kono
parents:
diff changeset
956
kono
parents:
diff changeset
957 function Match
kono
parents:
diff changeset
958 (Subject : VString;
kono
parents:
diff changeset
959 Pat : Pattern) return Boolean;
kono
parents:
diff changeset
960
kono
parents:
diff changeset
961 function Match
kono
parents:
diff changeset
962 (Subject : VString;
kono
parents:
diff changeset
963 Pat : PString) return Boolean;
kono
parents:
diff changeset
964
kono
parents:
diff changeset
965 function Match
kono
parents:
diff changeset
966 (Subject : String;
kono
parents:
diff changeset
967 Pat : Pattern) return Boolean;
kono
parents:
diff changeset
968
kono
parents:
diff changeset
969 function Match
kono
parents:
diff changeset
970 (Subject : String;
kono
parents:
diff changeset
971 Pat : PString) return Boolean;
kono
parents:
diff changeset
972
kono
parents:
diff changeset
973 -- Replacement functions. The subject is matched against the pattern.
kono
parents:
diff changeset
974 -- Any immediate or deferred assignments or writes are executed, and
kono
parents:
diff changeset
975 -- the returned value indicates whether or not the match succeeded.
kono
parents:
diff changeset
976 -- If the match succeeds, then the matched part of the subject string
kono
parents:
diff changeset
977 -- is replaced by the given Replace string.
kono
parents:
diff changeset
978
kono
parents:
diff changeset
979 function Match
kono
parents:
diff changeset
980 (Subject : VString_Var;
kono
parents:
diff changeset
981 Pat : Pattern;
kono
parents:
diff changeset
982 Replace : VString) return Boolean;
kono
parents:
diff changeset
983
kono
parents:
diff changeset
984 function Match
kono
parents:
diff changeset
985 (Subject : VString_Var;
kono
parents:
diff changeset
986 Pat : PString;
kono
parents:
diff changeset
987 Replace : VString) return Boolean;
kono
parents:
diff changeset
988
kono
parents:
diff changeset
989 function Match
kono
parents:
diff changeset
990 (Subject : VString_Var;
kono
parents:
diff changeset
991 Pat : Pattern;
kono
parents:
diff changeset
992 Replace : String) return Boolean;
kono
parents:
diff changeset
993
kono
parents:
diff changeset
994 function Match
kono
parents:
diff changeset
995 (Subject : VString_Var;
kono
parents:
diff changeset
996 Pat : PString;
kono
parents:
diff changeset
997 Replace : String) return Boolean;
kono
parents:
diff changeset
998
kono
parents:
diff changeset
999 -- Simple match procedures. The subject is matched against the pattern.
kono
parents:
diff changeset
1000 -- Any immediate or deferred assignments or writes are executed. No
kono
parents:
diff changeset
1001 -- indication of success or failure is returned.
kono
parents:
diff changeset
1002
kono
parents:
diff changeset
1003 procedure Match
kono
parents:
diff changeset
1004 (Subject : VString;
kono
parents:
diff changeset
1005 Pat : Pattern);
kono
parents:
diff changeset
1006
kono
parents:
diff changeset
1007 procedure Match
kono
parents:
diff changeset
1008 (Subject : VString;
kono
parents:
diff changeset
1009 Pat : PString);
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 procedure Match
kono
parents:
diff changeset
1012 (Subject : String;
kono
parents:
diff changeset
1013 Pat : Pattern);
kono
parents:
diff changeset
1014
kono
parents:
diff changeset
1015 procedure Match
kono
parents:
diff changeset
1016 (Subject : String;
kono
parents:
diff changeset
1017 Pat : PString);
kono
parents:
diff changeset
1018
kono
parents:
diff changeset
1019 -- Replacement procedures. The subject is matched against the pattern.
kono
parents:
diff changeset
1020 -- Any immediate or deferred assignments or writes are executed. No
kono
parents:
diff changeset
1021 -- indication of success or failure is returned. If the match succeeds,
kono
parents:
diff changeset
1022 -- then the matched part of the subject string is replaced by the given
kono
parents:
diff changeset
1023 -- Replace string.
kono
parents:
diff changeset
1024
kono
parents:
diff changeset
1025 procedure Match
kono
parents:
diff changeset
1026 (Subject : in out VString;
kono
parents:
diff changeset
1027 Pat : Pattern;
kono
parents:
diff changeset
1028 Replace : VString);
kono
parents:
diff changeset
1029
kono
parents:
diff changeset
1030 procedure Match
kono
parents:
diff changeset
1031 (Subject : in out VString;
kono
parents:
diff changeset
1032 Pat : PString;
kono
parents:
diff changeset
1033 Replace : VString);
kono
parents:
diff changeset
1034
kono
parents:
diff changeset
1035 procedure Match
kono
parents:
diff changeset
1036 (Subject : in out VString;
kono
parents:
diff changeset
1037 Pat : Pattern;
kono
parents:
diff changeset
1038 Replace : String);
kono
parents:
diff changeset
1039
kono
parents:
diff changeset
1040 procedure Match
kono
parents:
diff changeset
1041 (Subject : in out VString;
kono
parents:
diff changeset
1042 Pat : PString;
kono
parents:
diff changeset
1043 Replace : String);
kono
parents:
diff changeset
1044
kono
parents:
diff changeset
1045 -- Deferred Replacement
kono
parents:
diff changeset
1046
kono
parents:
diff changeset
1047 type Match_Result is private;
kono
parents:
diff changeset
1048 -- Type used to record result of pattern match
kono
parents:
diff changeset
1049
kono
parents:
diff changeset
1050 subtype Match_Result_Var is Match_Result;
kono
parents:
diff changeset
1051 -- This synonyms is used as a formal parameter type to a function where,
kono
parents:
diff changeset
1052 -- if the language allowed, we would use an in out parameter, but we are
kono
parents:
diff changeset
1053 -- not allowed to have in out parameters for functions. Instead we pass
kono
parents:
diff changeset
1054 -- actuals which must be variables, and with a bit of trickery in the
kono
parents:
diff changeset
1055 -- body, manage to interpret them properly as though they were indeed
kono
parents:
diff changeset
1056 -- in out parameters.
kono
parents:
diff changeset
1057
kono
parents:
diff changeset
1058 function Match
kono
parents:
diff changeset
1059 (Subject : VString_Var;
kono
parents:
diff changeset
1060 Pat : Pattern;
kono
parents:
diff changeset
1061 Result : Match_Result_Var) return Boolean;
kono
parents:
diff changeset
1062
kono
parents:
diff changeset
1063 procedure Match
kono
parents:
diff changeset
1064 (Subject : in out VString;
kono
parents:
diff changeset
1065 Pat : Pattern;
kono
parents:
diff changeset
1066 Result : out Match_Result);
kono
parents:
diff changeset
1067
kono
parents:
diff changeset
1068 procedure Replace
kono
parents:
diff changeset
1069 (Result : in out Match_Result;
kono
parents:
diff changeset
1070 Replace : VString);
kono
parents:
diff changeset
1071 -- Given a previous call to Match which set Result, performs a pattern
kono
parents:
diff changeset
1072 -- replacement if the match was successful. Has no effect if the match
kono
parents:
diff changeset
1073 -- failed. This call should immediately follow the Match call.
kono
parents:
diff changeset
1074
kono
parents:
diff changeset
1075 ------------------------
kono
parents:
diff changeset
1076 -- Debugging Routines --
kono
parents:
diff changeset
1077 ------------------------
kono
parents:
diff changeset
1078
kono
parents:
diff changeset
1079 -- Debugging pattern matching operations can often be quite complex,
kono
parents:
diff changeset
1080 -- since there is no obvious way to trace the progress of the match.
kono
parents:
diff changeset
1081 -- The declarations in this section provide some debugging assistance.
kono
parents:
diff changeset
1082
kono
parents:
diff changeset
1083 Debug_Mode : Boolean := False;
kono
parents:
diff changeset
1084 -- This global variable can be set True to generate debugging on all
kono
parents:
diff changeset
1085 -- subsequent calls to Match. The debugging output is a full trace of
kono
parents:
diff changeset
1086 -- the actions of the pattern matcher, written to Standard_Output. The
kono
parents:
diff changeset
1087 -- level of this information is intended to be comprehensible at the
kono
parents:
diff changeset
1088 -- abstract level of this package declaration. However, note that the
kono
parents:
diff changeset
1089 -- use of this switch often generates large amounts of output.
kono
parents:
diff changeset
1090
kono
parents:
diff changeset
1091 function "*" (P : Pattern; Fil : File_Access) return Pattern;
kono
parents:
diff changeset
1092 function "*" (P : PString; Fil : File_Access) return Pattern;
kono
parents:
diff changeset
1093 function "*" (P : PChar; Fil : File_Access) return Pattern;
kono
parents:
diff changeset
1094 function "**" (P : Pattern; Fil : File_Access) return Pattern;
kono
parents:
diff changeset
1095 function "**" (P : PString; Fil : File_Access) return Pattern;
kono
parents:
diff changeset
1096 function "**" (P : PChar; Fil : File_Access) return Pattern;
kono
parents:
diff changeset
1097 -- These are similar to the corresponding pattern assignment operations
kono
parents:
diff changeset
1098 -- except that instead of setting the value of a variable, the matched
kono
parents:
diff changeset
1099 -- substring is written to the appropriate file. This can be useful in
kono
parents:
diff changeset
1100 -- following the progress of a match without generating the full amount
kono
parents:
diff changeset
1101 -- of information obtained by setting Debug_Mode to True.
kono
parents:
diff changeset
1102
kono
parents:
diff changeset
1103 Terminal : constant File_Access := Standard_Error;
kono
parents:
diff changeset
1104 Output : constant File_Access := Standard_Output;
kono
parents:
diff changeset
1105 -- Two handy synonyms for use with the above pattern write operations
kono
parents:
diff changeset
1106
kono
parents:
diff changeset
1107 -- Finally we have some routines that are useful for determining what
kono
parents:
diff changeset
1108 -- patterns are in use, particularly if they are constructed dynamically.
kono
parents:
diff changeset
1109
kono
parents:
diff changeset
1110 function Image (P : Pattern) return String;
kono
parents:
diff changeset
1111 function Image (P : Pattern) return VString;
kono
parents:
diff changeset
1112 -- This procedures yield strings that corresponds to the syntax needed
kono
parents:
diff changeset
1113 -- to create the given pattern using the functions in this package. The
kono
parents:
diff changeset
1114 -- form of this string is such that it could actually be compiled and
kono
parents:
diff changeset
1115 -- evaluated to yield the required pattern except for references to
kono
parents:
diff changeset
1116 -- variables and functions, which are output using one of the following
kono
parents:
diff changeset
1117 -- forms:
kono
parents:
diff changeset
1118 --
kono
parents:
diff changeset
1119 -- access Natural NP(16#...#)
kono
parents:
diff changeset
1120 -- access Pattern PP(16#...#)
kono
parents:
diff changeset
1121 -- access VString VP(16#...#)
kono
parents:
diff changeset
1122 --
kono
parents:
diff changeset
1123 -- Natural_Func NF(16#...#)
kono
parents:
diff changeset
1124 -- VString_Func VF(16#...#)
kono
parents:
diff changeset
1125 --
kono
parents:
diff changeset
1126 -- where 16#...# is the hex representation of the integer address that
kono
parents:
diff changeset
1127 -- corresponds to the given access value
kono
parents:
diff changeset
1128
kono
parents:
diff changeset
1129 procedure Dump (P : Pattern);
kono
parents:
diff changeset
1130 -- This procedure writes information about the pattern to Standard_Out.
kono
parents:
diff changeset
1131 -- The format of this information is keyed to the internal data structures
kono
parents:
diff changeset
1132 -- used to implement patterns. The information provided by Dump is thus
kono
parents:
diff changeset
1133 -- more precise than that yielded by Image, but is also a bit more obscure
kono
parents:
diff changeset
1134 -- (i.e. it cannot be interpreted solely in terms of this spec, you have
kono
parents:
diff changeset
1135 -- to know something about the data structures).
kono
parents:
diff changeset
1136
kono
parents:
diff changeset
1137 ------------------
kono
parents:
diff changeset
1138 -- Private Part --
kono
parents:
diff changeset
1139 ------------------
kono
parents:
diff changeset
1140
kono
parents:
diff changeset
1141 private
kono
parents:
diff changeset
1142 type PE;
kono
parents:
diff changeset
1143 -- Pattern element, a pattern is a complex structure of PE's. This type
kono
parents:
diff changeset
1144 -- is defined and described in the body of this package.
kono
parents:
diff changeset
1145
kono
parents:
diff changeset
1146 type PE_Ptr is access all PE;
kono
parents:
diff changeset
1147 -- Pattern reference. PE's use PE_Ptr values to reference other PE's
kono
parents:
diff changeset
1148
kono
parents:
diff changeset
1149 type Pattern is new Controlled with record
kono
parents:
diff changeset
1150 Stk : Natural := 0;
kono
parents:
diff changeset
1151 -- Maximum number of stack entries required for matching this
kono
parents:
diff changeset
1152 -- pattern. See description of pattern history stack in body.
kono
parents:
diff changeset
1153
kono
parents:
diff changeset
1154 P : PE_Ptr := null;
kono
parents:
diff changeset
1155 -- Pointer to initial pattern element for pattern
kono
parents:
diff changeset
1156 end record;
kono
parents:
diff changeset
1157
kono
parents:
diff changeset
1158 pragma Finalize_Storage_Only (Pattern);
kono
parents:
diff changeset
1159
kono
parents:
diff changeset
1160 procedure Adjust (Object : in out Pattern);
kono
parents:
diff changeset
1161 -- Adjust routine used to copy pattern objects
kono
parents:
diff changeset
1162
kono
parents:
diff changeset
1163 procedure Finalize (Object : in out Pattern);
kono
parents:
diff changeset
1164 -- Finalization routine used to release storage allocated for a pattern
kono
parents:
diff changeset
1165
kono
parents:
diff changeset
1166 type VString_Ptr is access all VString;
kono
parents:
diff changeset
1167
kono
parents:
diff changeset
1168 type Match_Result is record
kono
parents:
diff changeset
1169 Var : VString_Ptr;
kono
parents:
diff changeset
1170 -- Pointer to subject string. Set to null if match failed
kono
parents:
diff changeset
1171
kono
parents:
diff changeset
1172 Start : Natural := 1;
kono
parents:
diff changeset
1173 -- Starting index position (1's origin) of matched section of
kono
parents:
diff changeset
1174 -- subject string. Only valid if Var is non-null.
kono
parents:
diff changeset
1175
kono
parents:
diff changeset
1176 Stop : Natural := 0;
kono
parents:
diff changeset
1177 -- Ending index position (1's origin) of matched section of
kono
parents:
diff changeset
1178 -- subject string. Only valid if Var is non-null.
kono
parents:
diff changeset
1179
kono
parents:
diff changeset
1180 end record;
kono
parents:
diff changeset
1181
kono
parents:
diff changeset
1182 pragma Volatile (Match_Result);
kono
parents:
diff changeset
1183 -- This ensures that the Result parameter is passed by reference, so
kono
parents:
diff changeset
1184 -- that we can play our games with the bogus Match_Result_Var parameter
kono
parents:
diff changeset
1185 -- in the function case to treat it as though it were an in out parameter.
kono
parents:
diff changeset
1186
kono
parents:
diff changeset
1187 end GNAT.Spitbol.Patterns;