67 Tools for constructing patterns. 69 Permission to use, modify, and distribute this software is given under the 70 terms of the NumPy License. See http://scipy.org. 72 NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 73 Author: Pearu Peterson <pearu@cens.ioc.ee> 84 p1 | p2 -> <p1> | <p2> 89 ~~~p1 -> <p1> [ <p1> ]... 91 abs(p1) -> whole string match of <p1> 92 p1.named(name) -> match of <p1> has name 93 p1.match(string) -> return string match with <p1> 95 p1.rsplit(..) -> split a string from the rightmost p1 occurrence 96 p1.lsplit(..) -> split a string from the leftmost p1 occurrence 99 _special_symbol_map = {
118 def __init__(self, label, pattern, optional=0, flags=0, value=None):
125 def flags(self, *flags):
133 def get_compiled(self):
136 except AttributeError:
140 def match(self, string):
143 def search(self, string):
148 Return (<lhs>, <pattern_match>, <rhs>) where 149 string = lhs + pattern_match + rhs 150 and rhs does not contain pattern_match. 151 If no pattern_match is found in string, return None. 154 t = compiled.split(string)
156 n =
"".join(t[-3:]).replace(
" ",
"")
157 if abs_real_literal_constant.match(n):
164 pattern_match = t[-2].strip()
165 assert abs(self).match(pattern_match), repr((self, string, t, pattern_match))
166 lhs = (
"".join(t[:-2])).strip()
167 return lhs, pattern_match, rhs
171 Return (<lhs>, <pattern_match>, <rhs>) where 172 string = lhs + pattern_match + rhs 173 and rhs does not contain pattern_match. 174 If no pattern_match is found in string, return None. 177 t = compiled.split(string)
181 pattern_match = t[1].strip()
182 rhs = (
"".join(t[2:])).strip()
183 assert abs(self).match(pattern_match), repr(pattern_match)
184 return lhs, pattern_match, rhs
195 return "%s(%r, %r)" % (self.__class__.__name__, self.
label, self.
pattern)
197 def __or__(self, other):
198 label =
"( %s OR %s )" % (self.
label, other.label)
199 if self.
pattern == other.pattern:
203 pattern =
"(%s|%s)" % (self.
pattern, other.pattern)
204 flags = self.
_flags | other._flags
205 return Pattern(label, pattern, flags=flags)
207 def __and__(self, other):
208 if isinstance(other, Pattern):
209 label =
"%s%s" % (self.
label, other.label)
210 pattern = self.
pattern + other.pattern
211 flags = self.
_flags | other._flags
213 assert isinstance(other, str), repr(other)
214 label =
"%s%s" % (self.
label, other)
217 return Pattern(label, pattern, flags=flags)
219 def __rand__(self, other):
220 assert isinstance(other, str), repr(other)
221 label =
"%s%s" % (other, self.
label)
225 def __invert__(self):
236 "%s %s" % (self.
label[1:-4].strip(), self.
label),
242 label =
"[ %s ]" % (self.
label)
243 pattern =
"(%s)?" % (self.
pattern)
244 return Pattern(label, pattern, optional=1, flags=self.
_flags)
246 def __add__(self, other):
247 if isinstance(other, Pattern):
248 label =
"%s %s" % (self.
label, other.label)
249 pattern = self.
pattern +
r"\s*" + other.pattern
250 flags = self.
_flags | other._flags
252 assert isinstance(other, str), repr(other)
253 label =
"%s %s" % (self.
label, other)
255 pattern = self.
pattern +
r"\s*" + other
257 return Pattern(label, pattern, flags=flags)
259 def __radd__(self, other):
260 assert isinstance(other, str), repr(other)
261 label =
"%s %s" % (other, self.
label)
263 pattern = other +
r"\s*" + self.
pattern 266 def named(self, name=None):
269 assert label[0] + label[-1] ==
"<>" and " " not in label, repr(label)
271 label =
"<%s>" % (name)
272 pattern =
"(?P%s%s)" % (label.replace(
"-",
"_"), self.
pattern)
275 def rename(self, label):
276 if label[0] + label[-1] !=
"<>":
277 label =
"<%s>" % (label)
286 def __call__(self, string):
287 m = self.
match(string)
290 if self.
value is not None:
298 letter =
Pattern(
"<letter>",
"[A-Z]", flags=re.I)
300 name =
Pattern(
"<name>",
r"[A-Z][\w$]*", flags=re.I)
302 name =
Pattern(
"<name>",
r"[A-Z]\w*", flags=re.I)
307 file_name =
Pattern(
"<file_name>",
r"^(\S|\S.*\S)$", flags=re.I)
308 macro_name =
Pattern(
"<macro_name>",
r"[A-Z_]\w*", flags=re.I)
309 abs_macro_name = abs(macro_name)
310 digit =
Pattern(
"<digit>",
r"\d")
311 underscore =
Pattern(
"<underscore>",
"_")
312 binary_digit =
Pattern(
"<binary-digit>",
r"[01]")
313 octal_digit =
Pattern(
"<octal-digit>",
r"[0-7]")
314 hex_digit =
Pattern(
"<hex-digit>",
r"[\dA-F]", flags=re.I)
316 digit_string =
Pattern(
"<digit-string>",
r"\d+")
317 abs_digit_string = abs(digit_string)
318 abs_digit_string_named = abs(digit_string.named(
"value"))
319 binary_digit_string =
Pattern(
"<binary-digit-string>",
r"[01]+")
320 octal_digit_string =
Pattern(
"<octal-digit-string>",
r"[0-7]+")
321 hex_digit_string =
Pattern(
"<hex-digit-string>",
r"[\dA-F]+", flags=re.I)
323 sign =
Pattern(
"<sign>",
r"[+-]")
324 exponent_letter =
Pattern(
"<exponent-letter>",
r"[ED]", flags=re.I)
326 alphanumeric_character =
Pattern(
"<alphanumeric-character>",
r"\w")
328 "<special-character>",
r'[ =+-*/\()[\]{},.:;!"%&~<>?,\'`^|$#@]' 330 character = alphanumeric_character | special_character
332 kind_param = digit_string | name
333 kind_param_named = kind_param.named(
"kind-param")
334 signed_digit_string = ~sign + digit_string
335 int_literal_constant = digit_string + ~(
"_" + kind_param)
336 signed_int_literal_constant = ~sign + int_literal_constant
337 int_literal_constant_named = digit_string.named(
"value") + ~(
"_" + kind_param_named)
338 signed_int_literal_constant_named = (~sign + digit_string).named(
"value") + ~(
339 "_" + kind_param_named
343 "B" + (
"'" & binary_digit_string &
"'" |
'"' & binary_digit_string &
'"')
346 "O" + (
"'" & octal_digit_string &
"'" |
'"' & octal_digit_string &
'"')
349 "Z" + (
"'" & hex_digit_string &
"'" |
'"' & hex_digit_string &
'"')
351 boz_literal_constant = binary_constant | octal_constant | hex_constant
353 exponent = signed_digit_string
354 significand = digit_string +
"." + ~digit_string |
"." + digit_string
355 real_literal_constant = significand + ~(exponent_letter + exponent) + ~(
357 ) | digit_string + exponent_letter + exponent + ~(
"_" + kind_param)
358 real_literal_constant_named = (
359 significand + ~(exponent_letter + exponent)
360 | digit_string + exponent_letter + exponent
361 ).named(
"value") + ~(
"_" + kind_param_named)
362 signed_real_literal_constant_named = (
365 significand + ~(exponent_letter + exponent)
366 | digit_string + exponent_letter + exponent
368 ).named(
"value") + ~(
"_" + kind_param_named)
369 signed_real_literal_constant = ~sign + real_literal_constant
371 named_constant = name
372 real_part = signed_int_literal_constant | signed_real_literal_constant | named_constant
373 imag_part = real_part
374 complex_literal_constant =
"(" + real_part +
"," + imag_part +
")" 376 a_n_rep_char =
Pattern(
"<alpha-numeric-rep-char>",
r"\w")
377 rep_char =
Pattern(
"<rep-char>",
r".")
378 char_literal_constant = ~(kind_param +
"_") + (
379 "'" + ~~rep_char +
"'" |
'"' + ~~rep_char +
'"' 381 a_n_char_literal_constant_named1 = ~(kind_param_named +
"_") + (
382 ~~~(
"'" + ~~a_n_rep_char +
"'")
384 a_n_char_literal_constant_named2 = ~(kind_param_named +
"_") + (
385 ~~~(
'"' + ~~a_n_rep_char +
'"')
388 logical_literal_constant = (
r"[.]\s*(TRUE|FALSE)\s*[.]" + ~(
"_" + kind_param)).flags(
391 logical_literal_constant_named =
Pattern(
392 "<value>",
r"[.]\s*(TRUE|FALSE)\s*[.]", flags=re.I
393 ).named() + ~(
"_" + kind_param_named)
396 | real_literal_constant
397 | complex_literal_constant
398 | logical_literal_constant
399 | char_literal_constant
400 | boz_literal_constant
402 constant = literal_constant | named_constant
403 int_constant = int_literal_constant | boz_literal_constant | named_constant
404 char_constant = char_literal_constant | named_constant
407 part_ref = name + ~((
r"[(]" + name +
r"[)]"))
408 data_ref = part_ref + ~~~(
r"[%]" + part_ref)
409 primary = constant | name | data_ref | (
r"[(]" + name +
r"[)]")
411 power_op =
Pattern(
"<power-op>",
r"(?<![*])[*]{2}(?![*])")
412 mult_op =
Pattern(
"<mult-op>",
r"(?<![*])[*](?![*])|(?<![/])[/](?![/])")
413 add_op =
Pattern(
"<add-op>",
r"[+-]")
414 concat_op =
Pattern(
"<concat-op>",
r"(?<![/])[/]\s*[/](?![/])")
417 r"[.]\s*EQ\s*[.]|[.]\s*NE\s*[.]|[.]\s*LT\s*[.]|[.]\s*LE\s*[.]|" 418 r"[.]\s*GT\s*[.]|[.]\s*GE\s*[.]|[=]{2}|/[=]|[<][=]|[<]|[>][=]|[>]",
421 not_op =
Pattern(
"<not-op>",
r"[.]\s*NOT\s*[.]", flags=re.I)
422 and_op =
Pattern(
"<and-op>",
r"[.]\s*AND\s*[.]", flags=re.I)
423 or_op =
Pattern(
"<or-op>",
r"[.]\s*OR\s*[.]", flags=re.I)
424 equiv_op =
Pattern(
"<equiv-op>",
r"[.]\s*EQV\s*[.]|[.]\s*NEQV\s*[.]", flags=re.I)
425 percent_op =
Pattern(
"<percent-op>",
r"%", flags=re.I)
426 intrinsic_operator = (
437 extended_intrinsic_operator = intrinsic_operator
439 defined_unary_op =
Pattern(
"<defined-unary-op>",
r"[.]\s*[A-Z]+\s*[.]", flags=re.I)
440 defined_binary_op =
Pattern(
"<defined-binary-op>",
r"[.]\s*[A-Z]+\s*[.]", flags=re.I)
441 defined_operator = defined_unary_op | defined_binary_op | extended_intrinsic_operator
442 abs_defined_operator = abs(defined_operator)
443 defined_op =
Pattern(
"<defined-op>",
"[.][A-Z]+[.]", flags=re.I)
444 abs_defined_op = abs(defined_op)
446 non_defined_binary_op = intrinsic_operator | logical_literal_constant
448 label =
Pattern(
"<label>",
r"\d{1,5}")
449 abs_label = abs(label)
452 keyword_equal = keyword +
"=" 454 abs_constant = abs(constant)
455 abs_literal_constant = abs(literal_constant)
456 abs_int_literal_constant = abs(int_literal_constant)
457 abs_signed_int_literal_constant = abs(signed_int_literal_constant)
458 abs_signed_int_literal_constant_named = abs(signed_int_literal_constant_named)
459 abs_int_literal_constant_named = abs(int_literal_constant_named)
460 abs_real_literal_constant = abs(real_literal_constant)
461 abs_signed_real_literal_constant = abs(signed_real_literal_constant)
462 abs_signed_real_literal_constant_named = abs(signed_real_literal_constant_named)
463 abs_real_literal_constant_named = abs(real_literal_constant_named)
464 abs_complex_literal_constant = abs(complex_literal_constant)
465 abs_logical_literal_constant = abs(logical_literal_constant)
466 abs_char_literal_constant = abs(char_literal_constant)
467 abs_boz_literal_constant = abs(boz_literal_constant)
469 abs_a_n_char_literal_constant_named1 = abs(a_n_char_literal_constant_named1)
470 abs_a_n_char_literal_constant_named2 = abs(a_n_char_literal_constant_named2)
471 abs_logical_literal_constant_named = abs(logical_literal_constant_named)
472 abs_binary_constant = abs(binary_constant)
473 abs_octal_constant = abs(octal_constant)
474 abs_hex_constant = abs(hex_constant)
477 "<intrinsic-type-name>",
478 r"(INTEGER|REAL|COMPLEX|LOGICAL|CHARACTER|DOUBLE\s*COMPLEX|" 479 r"DOUBLE\s*PRECISION|BYTE)",
482 abs_intrinsic_type_name = abs(intrinsic_type_name)
484 "<double-complex-name>",
r"DOUBLE\s*COMPLEX", flags=re.I, value=
"DOUBLE COMPLEX" 486 double_precision_name =
Pattern(
487 "<double-precision-name>",
488 r"DOUBLE\s*PRECISION",
490 value=
"DOUBLE PRECISION",
492 abs_double_complex_name = abs(double_complex_name)
493 abs_double_precision_name = abs(double_precision_name)
495 access_spec =
Pattern(
"<access-spec>",
r"PUBLIC|PRIVATE", flags=re.I)
496 abs_access_spec = abs(access_spec)
499 "<implicit-none>",
r"IMPLICIT\s*NONE", flags=re.I, value=
"IMPLICIT NONE" 501 abs_implicit_none = abs(implicit_none)
505 r"(ALLOCATABLE|ASYNCHRONOUS|EXTERNAL|INTENT|INTRINSIC|" 506 "OPTIONAL|PARAMETER|POINTER|PROTECTED|SAVE|TARGET|VALUE|VOLATILE)",
509 abs_attr_spec = abs(attr_spec)
515 sorted(attr_spec.pattern.strip(
"()").split(
"|") + [
"CONTIGUOUS"])
520 abs_attr_spec_f08 = abs(attr_spec_f08)
522 dimension =
Pattern(
"<dimension>",
r"DIMENSION", flags=re.I)
523 abs_dimension = abs(dimension)
525 intent =
Pattern(
"<intent>",
r"INTENT", flags=re.I)
526 abs_intent = abs(intent)
528 intent_spec =
Pattern(
"<intent-spec>",
r"INOUT|IN|OUT", flags=re.I)
529 abs_intent_spec = abs(intent_spec)
531 function =
Pattern(
"<function>",
r"FUNCTION", flags=re.I)
532 subroutine =
Pattern(
"<subroutine>",
r"SUBROUTINE", flags=re.I)
535 "<select-case>",
r"SELECT\s*CASE", flags=re.I, value=
"SELECT CASE" 537 abs_select_case = abs(select_case)