68 """Fortran 2003 Syntax Rules. 89 Type_Declaration_StmtBase,
122 Represents a Fortran Comment. 130 Create a new Comment instance. 132 :param type cls: the class of object to create. 133 :param string: (source of) Fortran string to parse. 134 :type string: str or :py:class:`FortranReaderBase` 135 :param parent_cls: the parent class of this object. 136 :type parent_cls: :py:type:`type` 141 if isinstance(string, readfortran.Comment):
145 obj = object.__new__(cls)
148 elif isinstance(string, FortranReaderBase):
150 item = reader.get_item()
153 if isinstance(item, readfortran.Comment):
158 reader.put_item(item)
166 Initialise this Comment 168 :param comment: The comment object produced by the reader 169 :type comment: :py:class:`readfortran.Comment` 171 self.
items = [comment.comment]
176 :returns: this comment as a string. 177 :rtype: :py:class:`str` 179 return str(self.
items[0])
183 Undo the read of this comment by putting its content back 184 into the reader (which has a FIFO buffer) 186 :param reader: the reader instance to return the comment to 187 :type reader: :py:class:`fparser.readfortran.FortranReaderBase` 189 reader.put_item(self.
item)
192 def match_comment_or_include(reader):
193 """Creates a comment or include object from the current line. 195 :param reader: the fortran file reader containing the line \ 196 of code that we are trying to match 197 :type reader: :py:class:`fparser.common.readfortran.FortranFileReader` \ 199 :py:class:`fparser.common.readfortran.FortranStringReader` 201 :return: a comment or include object if found, otherwise `None`. 202 :rtype: :py:class:`fparser.two.Fortran2003.Comment` or \ 203 :py:class:`fparser.two.Fortran2003.Include_Stmt` 211 def add_comments_includes_directives(content, reader):
212 """Creates comment, include, and/or cpp directive objects and adds them to 213 the content list. Comment, include, and/or directive objects are added 214 until a line that is not a comment, include, or directive is found. 216 :param content: a `list` of matched objects. Any matched comments, \ 217 includes, or directives in this routine are added to \ 219 :type content: :obj:`list` 220 :param reader: the fortran file reader containing the line(s) \ 221 of code that we are trying to match 222 :type reader: :py:class:`fparser.common.readfortran.FortranFileReader` \ 224 :py:class:`fparser.common.readfortran.FortranStringReader` 229 obj = match_comment_or_include(reader)
230 obj = match_cpp_directive(reader)
if not obj
else obj
233 obj = match_comment_or_include(reader)
234 obj = match_cpp_directive(reader)
if not obj
else obj
239 Fortran 2003 rule R201 240 program is program-unit 246 use_names = [
"Program_Unit"]
249 def __new__(cls, string):
250 """Wrapper around base class __new__ to catch an internal NoMatchError 251 exception and raise it as an external FortranSyntaxError exception. 253 :param type cls: the class of object to create 254 :param string: (source of) Fortran string to parse 255 :type string: :py:class:`FortranReaderBase` 256 :raises FortranSyntaxError: if the code is not valid Fortran 261 return Base.__new__(cls, string)
265 raise FortranSyntaxError(string,
"")
266 except InternalSyntaxError
as excinfo:
272 raise FortranSyntaxError(string, excinfo)
276 """Implements the matching for a Program. Whilst the rule looks like 277 it could make use of BlockBase, the parser must not match if an 278 optional program_unit has a syntax error, which the BlockBase 279 match implementation does not do. 281 :param reader: the fortran file reader containing the line(s) 282 of code that we are trying to match 283 :type reader: :py:class:`fparser.common.readfortran.FortranFileReader` 285 :py:class:`fparser.common.readfortran.FortranStringReader` 286 :return: `tuple` containing a single `list` which contains 287 instance of the classes that have matched if there is 288 a match or `None` if there is no match 292 add_comments_includes_directives(content, reader)
293 comments = content != []
298 add_comments_includes_directives(content, reader)
300 next_line = reader.next()
302 reader.put_item(next_line)
308 result = BlockBase.match(Main_Program0, [],
None, reader)
309 if not result
and comments:
314 except StopIteration:
322 """Implements the matching of a filename from an include statement.""" 329 """Match the string with the regular expression file_name in the 330 pattern_tools file. The only content that is not accepted is 331 an empty string or white space at the start or end of the 334 :param str string: the string to match with the pattern rule. 335 :return: a tuple of size 1 containing a string with the \ 336 matched name if there is a match, or None if there is not. 337 :rtype: (str) or NoneType 340 return StringBase.match(pattern.file_name, string)
345 """Implements the matching of a Fortran include statement. There is no 346 rule for this as the compiler is expected to inline any content 347 from an include statement when one is found. However, for a parser 348 it can make sense to represent an include statement in a parse 351 include-stmt is INCLUDE ['filename' or "filename"] 355 use_names = [
"Include_Filename"]
359 """Implements the matching for an include statement. 361 :param str string: the string to match with as an include statement. 362 :returns: a tuple of size 1 containing an Include_Filename \ 363 object with the matched filename if there is a match, or None \ 365 :rtype: (:py:class:`fparser.two.Fortran2003.Include_Filename`) \ 372 line = string.strip()
373 if line[:7].upper() !=
"INCLUDE":
377 rhs = line[7:].strip()
378 if rhs
is None or len(rhs) < 3:
384 (rhs[0] ==
"'" and rhs[-1] ==
"'")
or (rhs[0] ==
'"' and rhs[-1] ==
'"')
390 file_name = rhs[1:-1]
395 "Fortran2003.py:Include_Stmt:match Include_Filename should " 396 "never return None or an empty name" 402 :return: this include_stmt as a string 406 return "INCLUDE '{0}'".format(self.items[0])
412 <program-unit> = <main-program> 413 | <external-subprogram> 421 "External_Subprogram",
430 <external-subprogram> = <function-subprogram> 431 | <subroutine-subprogram> 434 subclass_names = [
"Comment",
"Function_Subprogram",
"Subroutine_Subprogram"]
440 <specification-part> = [ <use-stmt> ]... 443 [ <declaration-construct> ]... 447 use_names = [
"Use_Stmt",
"Import_Stmt",
"Implicit_Part",
"Declaration_Construct"]
451 return BlockBase.match(
453 [Use_Stmt, Import_Stmt, Implicit_Part, Declaration_Construct],
462 <implicit-part> = [ <implicit-part-stmt> ]... 467 use_names = [
"Implicit_Part_Stmt",
"Implicit_Stmt"]
471 return BlockBase.match(
None, [Implicit_Part_Stmt],
None, reader)
477 <implicit-part-stmt> = <implicit-stmt> 493 """Fortran 2003 rule R207 495 declaration-construct is derived-type-def 501 or procedure-declaration-stmt 502 or specification-stmt 503 or type-declaration-stmt 504 or stmt-function-stmt 506 Note, stmt-function-stmt is not currently matched. 522 "Procedure_Declaration_Stmt",
523 "Specification_Stmt",
524 "Type_Declaration_Stmt",
530 <execution-part> = <executable-construct> 531 | [ <execution-part-construct> ]... 533 <execution-part> shall not contain <end-function-stmt>, 534 <end-program-stmt>, <end-subroutine-stmt> 539 use_names = [
"Executable_Construct_C201",
"Execution_Part_Construct_C201"]
543 return BlockBase.match(
544 Executable_Construct_C201, [Execution_Part_Construct_C201],
None, string
550 <execution-part-construct> = <executable-construct> 558 "Executable_Construct",
568 "Executable_Construct_C201",
577 <internal-subprogram-part> = <contains-stmt> 578 <internal-subprogram> 579 [ <internal-subprogram> ]... 583 use_names = [
"Contains_Stmt",
"Internal_Subprogram"]
587 return BlockBase.match(Contains_Stmt, [Internal_Subprogram],
None, reader)
592 <internal-subprogram> = <function-subprogram> 593 | <subroutine-subprogram> 596 subclass_names = [
"Function_Subprogram",
"Subroutine_Subprogram"]
601 <specification-stmt> = <access-stmt> 603 | <asynchronous-stmt> 650 Fortran 2003 rule R213 651 executable-construct is action-stmt 652 or associate-construct 657 or select-type-construct 663 "Associate_Construct",
668 "Select_Type_Construct",
674 subclass_names = Executable_Construct.subclass_names[:]
675 subclass_names[subclass_names.index(
"Action_Stmt")] =
"Action_Stmt_C201" 680 <action-stmt> = <allocate-stmt> 689 | <end-function-stmt> 691 | <end-subroutine-stmt> 700 | <pointer-assignment-stmt> 709 | <arithmetic-if-stmt> 710 | <computed-goto-stmt> 725 "End_Subroutine_Stmt",
734 "Pointer_Assignment_Stmt",
743 "Arithmetic_If_Stmt",
744 "Computed_Goto_Stmt",
750 <action-stmt-c201> = <action-stmt> 754 subclass_names = Action_Stmt.subclass_names[:]
755 subclass_names.remove(
"End_Function_Stmt")
756 subclass_names.remove(
"End_Subroutine_Stmt")
762 <action-stmt-c802> = <action-stmt> 766 subclass_names = Action_Stmt.subclass_names[:]
767 subclass_names.remove(
"End_Function_Stmt")
768 subclass_names.remove(
"End_Subroutine_Stmt")
769 subclass_names.remove(
"If_Stmt")
774 <action-stmt-c824> = <action-stmt> 778 subclass_names = Action_Stmt.subclass_names[:]
779 subclass_names.remove(
"End_Function_Stmt")
780 subclass_names.remove(
"End_Subroutine_Stmt")
781 subclass_names.remove(
"Continue_Stmt")
782 subclass_names.remove(
"Goto_Stmt")
783 subclass_names.remove(
"Return_Stmt")
784 subclass_names.remove(
"Stop_Stmt")
785 subclass_names.remove(
"Exit_Stmt")
786 subclass_names.remove(
"Cycle_Stmt")
787 subclass_names.remove(
"Arithmetic_If_Stmt")
795 subclass_names = [
"Name"]
809 Fortran 2003 rule R304 810 name is letter [ alphanumeric_character ]... 819 """Match the string with the regular expression abs_name in the 822 :param str string: the string to match with the pattern rule. 823 :return: a tuple of size 1 containing a string with the \ 824 matched name if there is a match, or None if there is not. 825 :rtype: (str) or None 828 return StringBase.match(pattern.abs_name, string.strip())
833 <constant> = <literal-constant> 837 subclass_names = [
"Literal_Constant",
"Named_Constant"]
842 <literal-constant> = <int-literal-constant> 843 | <real-literal-constant> 844 | <complex-literal-constant> 845 | <logical-literal-constant> 846 | <char-literal-constant> 847 | <boz-literal-constant> 851 "Int_Literal_Constant",
852 "Real_Literal_Constant",
853 "Complex_Literal_Constant",
854 "Logical_Literal_Constant",
855 "Char_Literal_Constant",
856 "Boz_Literal_Constant",
862 <named-constant> = <name> 865 subclass_names = [
"Name"]
870 <int-constant> = <constant> 873 subclass_names = [
"Constant"]
878 <char-constant> = <constant> 881 subclass_names = [
"Constant"]
894 """Fortran 2003 rule R311 895 R311 defined-operator is defined-unary-op 897 or extended-intrinsic-op 899 Note, defined-operator is defined in pattern_tools.py so could be 900 called directly via a stringbase match. However, the defined unary 901 and binary op rules have constraints which would not be checked if 904 Note, whilst we subclass for both Defined Unary and Binary ops, 905 the match is the same so we will only ever match with the first 906 (so the second is not really necessary here). This is OK from a 907 parsing point of view as they both return a Defined_Op class, so 908 are identical from the parsers point of view. 912 subclass_names = [
"Defined_Unary_Op",
"Defined_Binary_Op",
"Extended_Intrinsic_Op"]
916 """Fortran 2003 rule R312 917 R312 extended-intrinsic-op is intrinsic-operator 919 Note, extended-intrinsic-op is only ever used by R311 and is 920 defined in pattern_tools.py so could be matched directly in the 921 Defined_Operator class (by changing it to STRINGBase and moving 922 the match in this class into the Defined_Operator class). This 923 would mean that this class would not be required. However, the 924 parse tree would then not have the concept of an 925 Extended_Intrinsic_Op which might be useful for code manipulation 932 """Implements the matching for the extended-intrinsic-op 933 rule. Matches the string with the regular expression 934 extended_intrinsic_operator in the pattern_tools file. 936 :param str string: the string to match with the pattern rule. 937 :return: a tuple of size 1 containing a string with the \ 938 matched name if there is a match, or None if there is not. 939 :rtype: (str) or None 942 return StringBase.match(pattern.extended_intrinsic_operator, string)
948 <label> = <digit> [ <digit> [ <digit> [ <digit> [ <digit> ] ] ] ] 959 return StringBase.match(pattern.abs_label, string)
962 return int(self.string)
972 <type-spec> = <intrinsic-type-spec> 973 | <derived-type-spec> 976 subclass_names = [
"Intrinsic_Type_Spec",
"Derived_Type_Spec"]
981 <type-param-value> = <scalar-int-expr> 986 subclass_names = [
"Scalar_Int_Expr"]
991 return StringBase.match([
"*",
":"], string)
996 <intrinsic-type-spec> = INTEGER [ <kind-selector> ] 997 | REAL [ <kind-selector> ] 999 | COMPLEX [ <kind-selector> ] 1000 | CHARACTER [ <char-selector> ] 1001 | LOGICAL [ <kind-selector> ] 1008 use_names = [
"Kind_Selector",
"Char_Selector"]
1013 (
"INTEGER", Kind_Selector),
1014 (
"REAL", Kind_Selector),
1015 (
"COMPLEX", Kind_Selector),
1016 (
"LOGICAL", Kind_Selector),
1017 (
"CHARACTER", Char_Selector),
1018 (pattern.abs_double_complex_name,
None),
1019 (pattern.abs_double_precision_name,
None),
1023 obj = WORDClsBase.match(w, cls, string)
1024 except NoMatchError:
1033 Fortran 2003 rule R404 1034 kind-selector is ( [ KIND = ] scalar-int-initialization-expr ) 1035 A non-standard extension is also supported here: 1038 There is an associated constraint that we can't enforce in fparser: 1040 'C404 (R404) The value of scalar-int-initialization-expr shall be 1041 nonnegative and shall specify a representation method that 1042 exists on the processor.' 1047 use_names = [
"Char_Length",
"Scalar_Int_Initialization_Expr"]
1051 """Implements the matching for a Kind_Selector. 1053 :param str string: a string containing the code to match 1054 :return: `None` if there is no match, otherwise a `tuple` of \ 1055 size 3 containing a '(', a single `list` which contains an \ 1056 instance of classes that have matched and a ')', or a `tuple` \ 1057 of size 2 containing a '*' and an instance of classes that \ 1059 :rtype: `NoneType` or ( str, [ MatchedClasses ], str) or ( \ 1060 str, :py:class:`fparser.two.Fortran2003.Char_Length`) 1062 :raises InternalError: if None is passed instead of a \ 1063 string. The parent rule should not pass None and the logic in \ 1064 this routine relies on a valid string. 1066 :raises InternalError: if the string passed is <=1 characters \ 1067 long. The parent rule passing this string should ensure the \ 1068 string is at least 2 characters long and the logic in this \ 1069 routine relies on this. The reason there is a minimum of two \ 1070 is that the pattern '*n' where 'n' is a number is the smallest \ 1071 valid pattern. The other valid pattern must have at least a \ 1072 name with one character surrounded by brackets e.g. '(x)' so \ 1073 should be at least 3 characters long. 1077 raise InternalError(
1078 "String argument in class Kind_Selector method match() " "is None." 1080 if len(string) <= 1:
1081 raise InternalError(
1082 "String argument '{0}' in class Kind_Selector method " 1083 "match() is too short to be valid.".format(string)
1087 string = string.strip()
1089 if string[0] + string[-1] !=
"()":
1091 if not string.startswith(
"*"):
1096 string = string[1:-1].strip()
1100 if string[:4].upper() ==
"KIND" and string[4:].lstrip()[0] ==
"=":
1102 string = string[4:].lstrip()[1:].lstrip()
1103 return "(", Scalar_Int_Initialization_Expr(string),
")" 1107 :return: this kind_selector as a string 1110 if len(self.items) == 2:
1111 result =
"{0[0]}{0[1]}".format(self.items)
1112 elif len(self.items) == 3:
1113 result =
"{0[0]}KIND = {0[1]}{0[2]}".format(self.items)
1115 raise InternalError(
1116 "Class Kind_Selector method tostr() has '{0}' items, " 1117 "but expecting 2 or 3.".format(len(self.items))
1124 <signed-int-literal-constant> = [ <sign> ] <int-literal-constant> 1128 subclass_names = [
"Int_Literal_Constant"]
1132 return NumberBase.match(pattern.abs_signed_int_literal_constant_named, string)
1137 <int-literal-constant> = <digit-string> [ _ <kind-param> ] 1144 return NumberBase.match(pattern.abs_int_literal_constant_named, string)
1149 <digit-string> = <digit> [ <digit> ]... 1156 return NumberBase.match(pattern.abs_digit_string_named, string)
1167 <boz-literal-constant> = <binary-constant> 1172 subclass_names = [
"Binary_Constant",
"Octal_Constant",
"Hex_Constant"]
1177 <binary-constant> = B ' <digit> [ <digit> ]... ' 1178 | B \" <digit> [ <digit> ]... \" 1185 return STRINGBase.match(pattern.abs_binary_constant, string)
1190 <octal-constant> = O ' <digit> [ <digit> ]... ' 1191 | O \" <digit> [ <digit> ]... \" 1198 return STRINGBase.match(pattern.abs_octal_constant, string)
1203 <hex-constant> = Z ' <digit> [ <digit> ]... ' 1204 | Z \" <digit> [ <digit> ]... \" 1211 return STRINGBase.match(pattern.abs_hex_constant, string)
1219 <signed-real-literal-constant> = [ <sign> ] <real-literal-constant> 1222 subclass_names = [
"Real_Literal_Constant"]
1226 return NumberBase.match(pattern.abs_signed_real_literal_constant_named, string)
1236 return NumberBase.match(pattern.abs_real_literal_constant_named, string)
1246 <complex-literal-constant> = ( <real-part>, <imag-part> ) 1250 use_names = [
"Real_Part",
"Imag_Part"]
1254 if not string
or string[0] + string[-1] !=
"()":
1256 if not pattern.abs_complex_literal_constant.match(string):
1258 r, i = string[1:-1].split(
",")
1262 return "(%s, %s)" % tuple(self.items)
1267 <real-part> = <signed-int-literal-constant> 1268 | <signed-real-literal-constant> 1273 "Signed_Int_Literal_Constant",
1274 "Signed_Real_Literal_Constant",
1281 <imag-part> = <real-part> 1285 "Signed_Int_Literal_Constant",
1286 "Signed_Real_Literal_Constant",
1293 <char-selector> = <length-selector> 1294 | ( LEN = <type-param-value> , 1295 KIND = <scalar-int-initialization-expr> ) 1296 | ( <type-param-value> , 1297 [ KIND = ] <scalar-int-initialization-expr> ) 1298 | ( KIND = <scalar-int-initialization-expr> 1299 [ , LEN = <type-param-value> ] ) 1302 subclass_names = [
"Length_Selector"]
1303 use_names = [
"Type_Param_Value",
"Scalar_Int_Initialization_Expr"]
1307 if string[0] + string[-1] !=
"()":
1309 line, repmap = string_replace_map(string[1:-1].strip())
1310 if line[:3].upper() ==
"LEN" and line[3:].lstrip().startswith(
"="):
1311 line = line[3:].lstrip()
1312 line = line[1:].lstrip()
1316 v = line[:i].rstrip()
1317 line = line[i + 1 :].lstrip()
1318 if line[:4].upper() !=
"KIND":
1320 line = line[4:].lstrip()
1321 if not line.startswith(
"="):
1323 line = line[1:].lstrip()
1327 elif line[:4].upper() ==
"KIND" and line[4:].lstrip().startswith(
"="):
1328 line = line[4:].lstrip()
1329 line = line[1:].lstrip()
1332 return None, Scalar_Int_Initialization_Expr(line)
1333 v = line[i + 1 :].lstrip()
1334 line = line[:i].rstrip()
1335 if v[:3].upper() !=
"LEN":
1338 if not v.startswith(
"="):
1346 v = line[:i].rstrip()
1347 line = line[i + 1 :].lstrip()
1348 if line[:4].upper() ==
"KIND" and line[4:].lstrip().startswith(
"="):
1349 line = line[4:].lstrip()
1350 line = line[1:].lstrip()
1355 if self.items[0]
is None:
1356 return "(KIND = %s)" % (self.items[1])
1357 return "(LEN = %s, KIND = %s)" % (self.items[0], self.items[1])
1362 <length -selector> = ( [ LEN = ] <type-param-value> ) 1363 | * <char-length> [ , ] 1367 use_names = [
"Type_Param_Value",
"Char_Length"]
1371 if string[0] + string[-1] ==
"()":
1372 line = string[1:-1].strip()
1373 if line[:3].upper() ==
"LEN" and line[3:].lstrip().startswith(
"="):
1374 line = line[3:].lstrip()
1375 line = line[1:].lstrip()
1377 if not string.startswith(
"*"):
1379 line = string[1:].lstrip()
1380 if string[-1] ==
",":
1381 line = line[:-1].rstrip()
1385 if len(self.items) == 2:
1386 return "%s%s" % tuple(self.items)
1387 return "%sLEN = %s%s" % tuple(self.items)
1392 <char-length> = ( <type-param-value> ) 1393 | <scalar-int-literal-constant> 1396 subclass_names = [
"Scalar_Int_Literal_Constant"]
1397 use_names = [
"Type_Param_Value"]
1401 return BracketBase.match(
"()", Type_Param_Value, string)
1406 Fortran 2003 rule R427 1408 char-literal-constant is [ kind-param _ ] ' rep-char ' 1409 or [ kind-param _ ] " rep-char " 1413 rep = pattern.char_literal_constant
1417 """Implements the matching for a Char_Literal_Constant. For example 1421 nondefaultcharset_"nondefaultchars" 1423 There is an associated constraint C422: "The value of 1424 kind-param shall specify a representation method that exists 1425 on the processor." However, this cannot be validated by 1426 fparser so no checks are performed. 1428 :param str string: a string containing the code to match. 1429 :return: `None` if there is no match, otherwise a `tuple` of 1430 size 2 containing the character constant and the kind 1432 :rtype: `NoneType` or (`str`, `NoneType`) or (`str`, `str`) 1437 strip_string = string.strip()
1438 if not strip_string:
1441 if strip_string[-1]
not in "\"'":
1443 if strip_string[-1] ==
'"':
1444 abs_a_n_char_literal_constant_named = (
1445 pattern.abs_a_n_char_literal_constant_named2
1448 abs_a_n_char_literal_constant_named = (
1449 pattern.abs_a_n_char_literal_constant_named1
1451 line, repmap = string_replace_map(strip_string)
1452 match = abs_a_n_char_literal_constant_named.match(line)
1455 kind_param = match.group(
"kind_param")
1456 line = match.group(
"value")
1458 return line, kind_param
1462 :return: this Char_Literal_Constant as a string. 1465 :raises InternalError: if the internal items list variable is \ 1466 not the expected size. 1467 :raises InternalError: if the first element of the internal \ 1468 items list is None or is an empty string. 1470 if len(self.items) != 2:
1471 raise InternalError(
1472 "Class Char_Literal_Constant method tostr() has '{0}' items, " 1473 "but expecting 2.".format(len(self.items))
1475 if not self.items[0]:
1479 raise InternalError(
1480 "Class Char_Literal_Constant method tostr(). 'Items' entry 0 " 1481 "should not be empty" 1483 char_str = str(self.items[0])
1484 if not self.items[1]:
1487 kind_str = str(self.items[1])
1488 return f
"{kind_str}_{char_str}" 1493 <logical-literal-constant> = .TRUE. [ _ <kind-param> ] 1494 | .FALSE. [ _ <kind-param> ] 1501 return NumberBase.match(pattern.abs_logical_literal_constant_named, string)
1506 <derived-type-def> = <derived-type-stmt> 1507 [ <type-param-def-stmt> ]... 1508 [ <private-or-sequence> ]... 1509 [ <component-part> ] 1510 [ <type-bound-procedure-part> ] 1516 "Derived_Type_Stmt",
1517 "Type_Param_Def_Stmt",
1518 "Private_Or_Sequence",
1520 "Type_Bound_Procedure_Part",
1526 return BlockBase.match(
1529 Type_Param_Def_Stmt,
1530 Private_Or_Sequence,
1532 Type_Bound_Procedure_Part,
1542 Fortran 2003 rule R430 1544 derived-type-stmt is TYPE [ [ , type-attr-spec-list ] :: ] 1545 type-name [ ( type-param-name-list ) ] 1550 use_names = [
"Type_Attr_Spec_List",
"Type_Name",
"Type_Param_Name_List"]
1554 """Implements the matching for a Derived Type Statement. 1556 :param str string: a string containing the code to match 1557 :return: `None` if there is no match, otherwise a `tuple` of \ 1558 size 3 containing an `Attribute_Spec_List` (or `None` if \ 1559 there isn't one), the name of the type (in a `Name` \ 1560 class) and a `Parameter_Name_List` (or `None` is there \ 1562 :rtype: ( `Type_Attr_Spec_List` or `None`, `Name`, \ 1563 `Type_Param_Name_List` or `None` ) or `None` 1566 string_strip = string.strip()
1567 if string_strip[:4].upper() !=
"TYPE":
1569 line = string_strip[4:].lstrip()
1570 position = line.find(
"::")
1573 if line.startswith(
","):
1574 lstrip = line[1:position].strip()
1579 attr_specs = Type_Attr_Spec_List(lstrip)
1580 elif line[:position].strip():
1583 line = line[position + 2 :].lstrip()
1584 match = pattern.name.match(line)
1589 line = line[match.end() :].lstrip()
1591 return attr_specs, name,
None 1592 if line[0] + line[-1] !=
"()":
1594 return attr_specs, name, Type_Param_Name_List(line[1:-1].strip())
1598 :return: this derived type statement as a string 1600 :raises InternalError: if items array is not the expected size 1601 :raises InternalError: if items array[1] has no content 1604 if len(self.items) != 3:
1605 raise InternalError(
1606 "Derived_Type_Stmt.tostr(). 'items' should be of size 3 but " 1607 "found '{0}'.".format(len(self.items))
1609 if not self.items[1]:
1610 raise InternalError(
1611 "Derived_Type_Stmt.tostr(). 'items[1]' should be a Name " 1612 "instance containing the derived type name but it is empty" 1616 string +=
", {0} :: {1}".format(self.items[0], self.items[1])
1618 string +=
" :: {0}".format(self.items[1])
1620 string +=
"({0})".format(self.items[2])
1623 def get_start_name(self):
1625 :return: this derived type statement's name as a string 1629 return self.items[1].string
1634 <type-name> = <name> 1635 <type-name> shall not be DOUBLEPRECISION or the name of intrinsic type 1643 if pattern.abs_intrinsic_type_name.match(string):
1645 return Name.match(string)
1650 <type-attr-spec> = <access-spec> 1651 | EXTENDS ( <parent-type-name> ) 1656 subclass_names = [
"Access_Spec",
"Language_Binding_Spec"][:-1]
1657 use_names = [
"Parent_Type_Name"]
1661 if len(string) == 8
and string.upper() ==
"ABSTRACT":
1662 return "ABSTRACT",
None 1663 if string[:4].upper() ==
"BIND":
1664 line = string[4:].lstrip()
1665 if not line
or line[0] + line[-1] !=
"()":
1667 line = line[1:-1].strip()
1668 if line.upper() ==
"C":
1670 elif string[:7].upper() ==
"EXTENDS":
1671 line = string[7:].lstrip()
1672 if not line
or line[0] + line[-1] !=
"()":
1674 return "EXTENDS", Parent_Type_Name(line[1:-1].strip())
1677 if self.items[1]
is None:
1678 return "%s" % (self.items[0])
1679 return "%s(%s)" % (self.items)
1684 <private-or-sequence> = <private-components-stmt> 1688 subclass_names = [
"Private_Components_Stmt",
"Sequence_Stmt"]
1693 <end-type-stmt> = END TYPE [ <type-name> ] 1697 use_names = [
"Type_Name"]
1701 return EndStmtBase.match(
"TYPE", Type_Name, string, require_stmt_type=
True)
1706 <sequence-stmt> = SEQUENCE 1713 return STRINGBase.match(
"SEQUENCE", string)
1718 <type-param-def-stmt> = INTEGER [ <kind-selector> ] , 1719 <type-param-attr-spec> :: <type-param-decl-list> 1723 use_names = [
"Kind_Selector",
"Type_Param_Attr_Spec",
"Type_Param_Decl_List"]
1727 if string[:7].upper() !=
"INTEGER":
1729 line, repmap = string_replace_map(string[7:].lstrip())
1735 kind_selector = repmap(line[:i].rstrip())
or None 1736 line = repmap(line[i + 1 :].lstrip())
1740 l1 = line[:i].rstrip()
1741 l2 = line[i + 2 :].lstrip()
1742 if not l1
or not l2:
1750 if self.items[0]
is not None:
1751 s +=
"%s, %s :: %s" % tuple(self.items)
1753 s +=
", %s :: %s" % tuple(self.items[1:])
1759 <type-param-decl> = <type-param-name> 1760 [ = <scalar-int-initialization-expr> ] 1763 subclass_names = [
"Type_Param_Name"]
1764 use_names = [
"Scalar_Int_Initialization_Expr"]
1768 if "=" not in string:
1770 lhs, rhs = string.split(
"=", 1)
1773 if not lhs
or not rhs:
1775 return Type_Param_Name(lhs),
"=", Scalar_Int_Initialization_Expr(rhs)
1780 <type-param-attr-spec> = KIND 1788 return STRINGBase.match([
"KIND",
"LEN"], string)
1793 <component-part> is [ <component-def-stmt> ]... 1797 use_names = [
"Component_Def_Stmt"]
1805 except NoMatchError:
1814 def tofortran(self, tab="", isfix=None):
1816 Converts this node (and all children) into Fortran. 1818 :param str tab: white space to prefix to output. 1819 :param bool isfix: whether or not to generate fixed-format output. 1821 :returns: Fortran code. 1826 for item
in self.content:
1827 mylist.append(item.tofortran(tab=tab, isfix=isfix))
1828 return "\n".join(mylist)
1833 <component-def-stmt> is <data-component-def-stmt> 1834 or <proc-component-def-stmt> 1837 subclass_names = [
"Data_Component_Def_Stmt",
"Proc_Component_Def_Stmt"]
1842 Fortran 2003 rule 440 1843 <data-component-def-stmt> is <declaration-type-spec> [ 1844 [ , <component-attr-spec-list> ] :: ] <component-decl-list> 1846 Associated constraints are: 1848 "C436 (R440) No component-attr-spec shall appear more than once in a given 1849 component-def-stmt." 1850 "C437 (R440) A component declared with the CLASS keyword shall have the 1851 ALLOCATABLE or POINTER attribute." 1852 "C438 (R440) If the POINTER attribute is not specified for a component, 1853 the declaration-type-spec in the component-def-stmt shall be CLASS(*) 1854 or shall specify an intrinsic type or a previously defined derived 1856 "C439 (R440) If the POINTER attribute is specified for a component, the 1857 declaration-type-spec in the component-def-stmt shall be CLASS(*) or 1858 shall specify an intrinsic type or any accessible derived type 1859 including the type being defined." 1860 "C440 (R440) If the POINTER or ALLOCATABLE attribute is specified, each 1861 component-array-spec shall be a deferred-shape-spec-list." 1862 "C441 (R440) If neither the POINTER attribute nor the ALLOCATABLE 1863 attribute is specified, each component-array-spec shall be an 1864 explicit-shape-spec-list." 1865 "C443 (R440) A component shall not have both the ALLOCATABLE and the 1867 "C446 (R440) If component-initialization appears, a double-colon separator 1868 shall appear before the component-decl-list." 1869 "C447 (R440) If => appears in component-initialization, POINTER shall 1870 appear in the component-attr-spec-list. If = appears in 1871 component-initialization, POINTER or ALLOCATABLE shall not appear in 1872 the component-attr-spec-list." 1874 C436-C441, C443, C446-C447 are currently not checked - issue #258. 1880 "Declaration_Type_Spec",
1881 "Component_Attr_Spec_List",
1882 "Component_Decl_List",
1887 return Type_Declaration_StmtBase.match(
1888 Declaration_Type_Spec, Component_Attr_Spec_List, Component_Decl_List, string
1894 <dimension-component-attr-spec> = DIMENSION ( <component-array-spec> ) 1898 use_names = [
"Component_Array_Spec"]
1902 return CALLBase.match(
"DIMENSION", Component_Array_Spec, string)
1907 <component-attr-spec> = POINTER 1908 | DIMENSION ( <component-array-spec> ) 1913 subclass_names = [
"Access_Spec",
"Dimension_Component_Attr_Spec"]
1915 attributes = [
"POINTER",
"ALLOCATABLE"]
1918 def match(cls, string):
1919 """Implements the matching for component attribute specifications. 1921 Note that this is implemented as a `classmethod` (not a 1922 `staticmethod`), using attribute keywords from the list provided 1923 as a class property. This allows expanding this list for 1924 Fortran 2008 without having to reimplement the matching. 1926 :param str string: the string to match as an attribute. 1928 :return: None if there is no match, otherwise a 1-tuple \ 1929 containing the matched attribute string. 1930 :rtype: NoneType or (str,) 1933 return STRINGBase.match(cls.attributes, string)
1938 <component-decl> = <component-name> [ ( <component-array-spec> ) ] 1939 [ * <char-length> ] [ <component-initialization> ] 1945 "Component_Array_Spec",
1947 "Component_Initialization",
1952 m = pattern.name.match(string)
1955 name = Component_Name(m.group())
1956 newline = string[m.end() :].lstrip()
1958 return name,
None,
None,
None 1962 if newline.startswith(
"("):
1963 line, repmap = string_replace_map(newline)
1968 newline = repmap(line[i + 1 :].lstrip())
1969 if newline.startswith(
"*"):
1970 line, repmap = string_replace_map(newline)
1973 char_length = repmap(line[1:i].strip())
1974 newline = repmap(newline[i:].lstrip())
1976 char_length = repmap(newline[1:].strip())
1979 if newline.startswith(
"="):
1982 assert newline ==
"", repr(newline)
1983 return name, array_spec, char_length, init
1986 s = str(self.items[0])
1987 if self.items[1]
is not None:
1988 s +=
"(" + str(self.items[1]) +
")" 1989 if self.items[2]
is not None:
1990 s +=
"*" + str(self.items[2])
1991 if self.items[3]
is not None:
1992 s +=
" " + str(self.items[3])
1998 <component-array-spec> = <explicit-shape-spec-list> 1999 | <deferred-shape-spec-list> 2002 subclass_names = [
"Explicit_Shape_Spec_List",
"Deferred_Shape_Spec_List"]
2007 <component-initialization> = = <initialization-expr> 2012 use_names = [
"Initialization_Expr",
"Null_Init"]
2016 if string.startswith(
"=>"):
2017 return "=>",
Null_Init(string[2:].lstrip())
2018 if string.startswith(
"="):
2023 return "%s %s" % tuple(self.items)
2028 <proc-component-def-stmt> is PROCEDURE ( [ <proc-interface> ] ) 2029 , <proc-component-attr-spec-list> :: <proc-decl-list> 2033 proc-component-attr-spec is POINTER 2034 or PASS [ (arg-name) ] 2038 The standard specifies the following constraints: 2040 "C448 The same proc-component-attr-spec shall not appear more than once 2041 in a given proc-component-def-stmt." Not checked by fparser - #232. 2043 "C449 POINTER shall appear in each proc-component-attr-spec-list." 2045 "C450 If the procedure pointer component has an implicit interface or 2046 has no arguments, NOPASS shall be specified." Not checked by 2049 "C451 If PASS (arg-name) appears, the interface shall have a dummy argument 2050 named arg-name." Not checked by fparser - #232. 2052 "C452 PASS and NOPASS shall not both appear in the same 2053 proc-component-attr-spec-list." Not checked by fparser - #232. 2057 use_names = [
"Proc_Interface",
"Proc_Component_Attr_Spec_List",
"Proc_Decl_List"]
2062 Attempts to match the supplied string with the pattern for a 2063 declaration of a procedure part of a component. 2065 :param str string: the string to test for a match. 2067 :returns: None (if no match) or a tuple consisting of the procedure \ 2068 interface, the list of attributes and a list of procedure \ 2070 :rtype: NoneType or \ 2071 (:py:class:`fparser.two.Fortran2003.Proc_Interface`, \ 2072 :py:class:`fparser.two.Fortran2003.Proc_Component_Attr_Spec_List`,\ 2073 :py:class:`fparser.two.Fortran2003.Proc_Decl_List`) 2075 if string[:9].upper() !=
"PROCEDURE":
2077 line, repmap = string_replace_map(string[9:].lstrip())
2078 if not line.startswith(
"("):
2080 idx = line.find(
")")
2083 pinterface = repmap(line[: idx + 1])[1:-1].strip()
or None 2086 line = line[idx + 1 :].lstrip()
2087 if not line.startswith(
","):
2089 line = line[1:].strip()
2090 idx = line.find(
"::")
2093 attr_spec_list = Proc_Component_Attr_Spec_List(repmap(line[:idx].rstrip()))
2100 Proc_Decl_List(repmap(line[idx + 2 :].lstrip())),
2104 if self.items[0]
is not None:
2105 return "PROCEDURE(%s), %s :: %s" % (self.items)
2106 return "PROCEDURE(), %s :: %s" % (self.items[1:])
2111 <proc-component-PASS-arg-name> = PASS ( <arg-name> ) 2115 use_names = [
"Arg_Name"]
2119 return CALLBase.match(
"PASS", Arg_Name, string)
2124 <proc-component-attr-spec> = POINTER 2125 | PASS [ ( <arg-name> ) ] 2130 subclass_names = [
"Access_Spec",
"Proc_Component_PASS_Arg_Name"]
2134 return STRINGBase.match([
"POINTER",
"PASS",
"NOPASS"], string.upper())
2141 Fortran 2003 rule R447 2142 that specifies support for private components statement 2143 within a derived type. 2145 <private-components-stmt> = PRIVATE 2153 :param str string: Fortran code to check for a match 2154 :return: keyword "PRIVATE" or None if no match is found 2157 return StringBase.match(
"PRIVATE", string.upper())
2164 Fortran 2003 rule R448 2165 that specifies the type-bound procedure part of a derived type. 2167 <type-bound-procedure-part> = <contains-stmt> 2168 [ <binding-private-stmt> ] 2170 [ <proc-binding-stmt> ]... 2174 use_names = [
"Contains_Stmt",
"Binding_Private_Stmt",
"Proc_Binding_Stmt"]
2179 :param reader: the Fortran reader containing the line(s) of code \ 2180 that we are trying to match 2181 :type reader: :py:class:`fparser.common.readfortran.FortranReaderBase` 2182 :return: code block containing instances of the classes that match \ 2183 the syntax of the type-bound procedure part of a derived type. 2184 :rtype: ([`Contains_Stmt`, `Specific_Binding`, `str`, `Name`, \ 2187 return BlockBase.match(
2188 Contains_Stmt, [Binding_Private_Stmt, Proc_Binding_Stmt],
None, reader
2196 Fortran 2003 rule R449 2197 for binding private statement within the type-bound procedure 2198 part of a derived type. 2200 <binding-private-stmt> = PRIVATE 2208 :param str string: Fortran code to check for a match 2209 :return: keyword "PRIVATE" or None if no match is found 2212 return StringBase.match(
"PRIVATE", string.upper())
2219 Fortran 2003 rule R450 2220 that specifies procedure binding for the type-bound procedures 2221 within a derived type. 2223 <proc-binding-stmt> = <specific-binding> 2228 subclass_names = [
"Specific_Binding",
"Generic_Binding",
"Final_Binding"]
2234 Fortran 2003 rule R451 2235 that specifies syntax of specific binding for a type-bound 2236 procedure within a derived type. 2238 <specific-binding> = PROCEDURE [ ( <interface-name> ) ] [ 2239 [ , <binding-attr-list> ] :: ] <binding-name> [ => <procedure-name> ] 2241 The following are associated constraints: 2243 "C456 (R451) If => procedure-name appears, the double-colon 2244 separator shall appear." 2246 "C457 (R451) If => procedure-name appears, interface-name shall not 2249 "C458 (R451) The procedure-name shall be the name of an accessible 2250 module procedure or an external procedure that has an explicit 2251 interface." Note, this is not checked by fparser. 2258 "Binding_Attr_List",
2266 :param str string: Fortran code to check for a match 2267 :return: 5-tuple containing strings and instances of the classes 2268 describing a specific type-bound procedure (optional 2269 interface name, optional binding attribute list, 2270 optional double colon delimiter, mandatory binding 2271 name and optional procedure name) 2272 :rtype: 5-tuple of objects (1 mandatory and 4 optional) 2275 string_strip = string.strip()
2276 if string_strip[:9].upper() !=
"PROCEDURE":
2279 if len(string_strip) < 11:
2284 if string_strip[9] ==
" ":
2286 line = string_strip[9:].lstrip()
2289 if line.startswith(
"("):
2290 index = line.find(
")")
2295 line = line[index + 1 :].lstrip()
2299 index = line.find(
"::")
2302 if line.startswith(
","):
2303 mylist = Binding_Attr_List(line[1:index].strip())
2304 elif line[:index].strip():
2309 line = line[index + 2 :].lstrip()
2310 if not iname
and not dcolon:
2319 index = line.find(
"=>")
2322 pname = Procedure_Name(line[index + 2 :].lstrip())
2323 line = line[:index].rstrip()
2333 return iname, mylist, dcolon, Binding_Name(line), pname
2337 :return: parsed representation of a specific type-bound procedure 2341 if len(self.items) != 5:
2342 raise InternalError(
2343 "Class Specific_Binding method tostr() has '{0}' items, " 2344 "but expecting 5.".format(len(self.items))
2350 stmt +=
"({0})".format(self.items[0])
2353 if self.items[1]
and self.items[2]:
2354 stmt +=
", {0} {1}".format(self.items[1], self.items[2])
2355 elif not self.items[1]
and self.items[2]:
2356 stmt +=
" {0}".format(self.items[2])
2358 stmt +=
" {0}".format(self.items[3])
2361 stmt +=
" => {0}".format(self.items[4])
2370 Fortran 2003 helper rule (for R453) 2371 that specifies syntax of passed-object dummy argument for a 2372 specific type-bound procedure. 2374 <binding-PASS-arg-name> = PASS ( <arg-name> ) 2377 use_names = [
"Arg_Name"]
2382 :param str string: Fortran code to check for a match 2383 :return: keyword "PASS" with the name of a passed-object 2384 dummy argument or nothing if no match is found 2387 return CALLBase.match(
"PASS", Arg_Name, string)
2395 Fortran 2003 rule R452 2396 that specifies syntax of generic binding for a type-bound 2397 procedure within a derived type. 2399 <generic-binding> = GENERIC [ , <access-spec> ] :: 2400 <generic-spec> => <binding-name-list> 2403 use_names = [
"Access_Spec",
"Generic_Spec",
"Binding_Name_List"]
2408 :param str string: Fortran code to check for a match 2409 :return: 3-tuple containing strings and instances of the 2410 classes describing a generic type-bound procedure 2411 (optional access specifier, mandatory generic 2412 identifier and mandatory binding name list) 2413 :rtype: 3-tuple of objects (2 mandatory and 1 optional) 2416 if string[:7].upper() !=
"GENERIC":
2418 line = string[7:].lstrip()
2425 if line.startswith(
","):
2427 line = line[i + 2 :].lstrip()
2435 Binding_Name_List(line[i + 3 :].lstrip()),
2440 :return: parsed representation of a "GENERIC" type-bound procedure 2443 if self.items[0]
is None:
2444 return "GENERIC :: %s => %s" % (self.items[1:])
2445 return "GENERIC, %s :: %s => %s" % (self.items)
2453 Fortran 2003 rule R453 2454 that specifies syntax of allowed binding attributes for a 2455 specific type-bound procedure binding. 2457 <binding-attr> = PASS [ ( <arg-name> ) ] 2464 subclass_names = [
"Access_Spec",
"Binding_PASS_Arg_Name"]
2469 :return: keywords for allowed binding attributes or 2470 nothing if no match is found 2473 return STRINGBase.match(
2474 [
"PASS",
"NOPASS",
"NON_OVERRIDABLE",
"DEFERRED"], string
2483 Fortran 2003 rule R454 2484 that specifies syntax of final binding for a type-bound 2485 procedure within a derived type. 2487 <final-binding> = FINAL [ :: ] <final-subroutine-name-list> 2491 use_names = [
"Final_Subroutine_Name_List"]
2496 :return: keyword "FINAL" with the list of "FINAL" type-bound 2497 procedures or nothing if no match is found 2500 return WORDClsBase.match(
2501 "FINAL", Final_Subroutine_Name_List, string, colons=
True, require_cls=
True 2505 tostr = WORDClsBase.tostr_a
2510 <derived-type-spec> = <type-name> [ ( <type-param-spec-list> ) ] 2513 subclass_names = [
"Type_Name"]
2514 use_names = [
"Type_Param_Spec_List"]
2518 return CallBase.match(Type_Name, Type_Param_Spec_List, string)
2523 <type-param-spec> = [ <keyword> = ] <type-param-value> 2526 subclass_names = [
"Type_Param_Value"]
2527 use_names = [
"Keyword"]
2531 return KeywordValueBase.match(Keyword, Type_Param_Value, string)
2536 <structure-constructor> = <derived-type-spec> ( [ <component-spec-list> ] ) 2540 use_names = [
"Derived_Type_Spec",
"Component_Spec_List"]
2544 return CallBase.match(Derived_Type_Spec, Component_Spec_List, string)
2549 <component-spec> = [ <keyword> = ] <component-data-source> 2552 subclass_names = [
"Component_Data_Source"]
2553 use_names = [
"Keyword"]
2557 return KeywordValueBase.match(Keyword, Component_Data_Source, string)
2562 <component-data-source> = <expr> 2567 subclass_names = [
"Proc_Target",
"Data_Target",
"Expr"]
2572 <enum-def> = <enum-def-stmt> 2573 <enumerator-def-stmt> 2574 [ <enumerator-def-stmt> ]... 2579 use_names = [
"Enum_Def_Stmt",
"Enumerator_Def_Stmt",
"End_Enum_Stmt"]
2583 return BlockBase.match(
2584 Enum_Def_Stmt, [Enumerator_Def_Stmt], End_Enum_Stmt, reader
2590 <enum-def-stmt> = ENUM, BIND(C) 2598 if string.upper().replace(
" ",
"") !=
"ENUM,BIND(C)":
2600 return (
"ENUM, BIND(C)",)
2603 return "%s" % (self.items[0])
2608 <enumerator-def-stmt> = ENUMERATOR [ :: ] <enumerator-list> 2612 use_names = [
"Enumerator_List"]
2616 return WORDClsBase.match(
2617 "ENUMERATOR", Enumerator_List, string, colons=
True, require_cls=
True 2620 tostr = WORDClsBase.tostr_a
2625 <enumerator> = <named-constant> [ = <scalar-int-initialization-expr> ] 2628 subclass_names = [
"Named_Constant"]
2629 use_names = [
"Scalar_Int_Initialization_Expr"]
2633 if "=" not in string:
2635 lhs, rhs = string.split(
"=", 1)
2639 Scalar_Int_Initialization_Expr(rhs.lstrip()),
2645 <end-enum-stmt> = END ENUM 2652 return EndStmtBase.match(
"ENUM",
None, string, require_stmt_type=
True)
2657 <array-constructor> = (/ <ac-spec> /) 2658 | <left-square-bracket> <ac-spec> 2659 <right-square-bracket> 2664 use_names = [
"Ac_Spec"]
2669 obj = BracketBase.match(
"(//)", Ac_Spec, string)
2670 except NoMatchError:
2673 obj = BracketBase.match(
"[]", Ac_Spec, string)
2679 <ac-spec> = <type-spec> :: 2680 | [ <type-spec> :: ] <ac-value-list> 2683 subclass_names = [
"Ac_Value_List"]
2684 use_names = [
"Type_Spec"]
2688 if string.endswith(
"::"):
2689 return Type_Spec(string[:-2].rstrip()),
None 2690 line, repmap = string_replace_map(string)
2694 ts = line[:i].rstrip()
2695 line = line[i + 2 :].lstrip()
2698 return Type_Spec(ts), Ac_Value_List(line)
2701 if self.items[0]
is None:
2702 return str(self.items[1])
2703 if self.items[1]
is None:
2704 return str(self.items[0]) +
" ::" 2705 return "%s :: %s" % self.items
2718 subclass_names = [
"Ac_Implied_Do",
"Expr"]
2723 Fortran2003 rule R470. 2724 Describes the form of implicit do loop used within an array constructor. 2726 ac-implied-do is ( ac-value-list , ac-implied-do-control ) 2728 Subject to the following constraint: 2730 "C497 (R470) The ac-do-variable of an ac-implied-do that is in another 2731 ac-implied-do shall not appear as the ac-do-variable of the 2732 containing ac-implied-do." 2734 C497 is currently not checked - issue #257. 2739 use_names = [
"Ac_Value_List",
"Ac_Implied_Do_Control"]
2743 if string[0] + string[-1] !=
"()":
2745 line, repmap = string_replace_map(string[1:-1].strip())
2749 j = line[:i].rfind(
",")
2751 s1 = repmap(line[:j].rstrip())
2752 s2 = repmap(line[j + 1 :].lstrip())
2756 return "(%s, %s)" % tuple(self.items)
2761 Fortran2003 rule R471. 2762 Specifies the syntax for the control of an implicit loop within an 2765 ac-implied-do-control is ac-do-variable = scalar-int-expr, 2766 scalar-int-expr [ , scalar-int-expr ] 2768 where (R472) ac-do-variable is scalar-int-variable 2773 use_names = [
"Ac_Do_Variable",
"Scalar_Int_Expr"]
2777 """ Attempts to match the supplied string with the pattern for 2780 :param str string: the string to test for a match. 2782 :returns: None if there is no match or a 2-tuple containing the \ 2783 do-variable name and the list of integer expressions (for \ 2784 start, stop [, step]). 2785 :rtype: NoneType or \ 2786 (:py:class:`fparser.two.Fortran2003.Ac_Do_Variable`, list) 2788 idx = string.find(
"=")
2791 do_var = string[:idx].rstrip()
2792 line, repmap = string_replace_map(string[idx + 1 :].lstrip())
2793 int_exprns = line.split(
",")
2794 if not (2 <= len(int_exprns) <= 3):
2796 exprn_list = [Scalar_Int_Expr(repmap(s.strip()))
for s
in int_exprns]
2800 return "%s = %s" % (self.items[0],
", ".join(map(str, self.items[1])))
2805 Fortran2003 rule R472. 2806 Specifies the permitted form of an implicit do-loop variable within an 2809 ac-do-variable is scalar-int-variable 2810 ac-do-variable shall be a named variable 2812 Subject to the following constraint: 2814 "C493 (R472) ac-do-variable shall be a named variable." 2816 C493 is currently not checked - issue #257. 2820 subclass_names = [
"Scalar_Int_Variable"]
2830 Fortran 2003 rule 501 2831 <type-declaration-stmt> = <declaration-type-spec> [ 2832 [ , <attr-spec> ]... :: ] <entity-decl-list> 2834 Associated constraints are: 2836 "C507 (R501) The same attr-spec shall not appear more than once in a given 2837 type-declaration-stmt." 2838 "C509 (R501) An entity declared with the CLASS keyword shall be a dummy 2839 argument or have the ALLOCATABLE or POINTER attribute." 2840 "C510 (R501) An array that has the POINTER or ALLOCATABLE attribute shall 2841 be specified with an array-spec that is a deferred-shape-spec-list." 2842 "C511 (R501) An array-spec for an object-name that is a function result 2843 that does not have the ALLOCATABLE or POINTER attribute shall be an 2844 explicit-shape-spec-list." 2845 "C512 (R501) If the POINTER attribute is specified, the ALLOCATABLE, 2846 TARGET, EXTERNAL, or INTRINSIC attribute shall not be specified." 2847 "C513 (R501) If the TARGET attribute is specified, the POINTER, EXTERNAL, 2848 INTRINSIC, or PARAMETER attribute shall not be specified." 2849 "C514 (R501) The PARAMETER attribute shall not be specified for a dummy 2850 argument, a pointer, an allocatable entity, a function, or an object 2852 "C515 (R501) The INTENT, VALUE, and OPTIONAL attributes may be specified 2853 only for dummy arguments." 2854 "C516 (R501) The INTENT attribute shall not be specified for a dummy 2855 procedure without the POINTER attribute." 2856 "C517 (R501) The SAVE attribute shall not be specified for an object that 2857 is in a common block, a dummy argument, a procedure, a function 2858 result, an automatic data object, or an object with the PARAMETER 2860 "C519 (R501) An entity in an entity-decl-list shall not have the EXTERNAL 2861 or INTRINSIC attribute specified unless it is a function." 2862 "C522 (R501) The initialization shall appear if the statement contains a 2863 PARAMETER attribute." 2864 "C523 (R501) If initialization appears, a double-colon separator shall 2865 appear before the entity-decl-list." 2866 "C526 (R501) If the VOLATILE attribute is specified, the PARAMETER, 2867 INTRINSIC, EXTERNAL, or INTENT(IN) attribute shall not be specified." 2868 "C527 (R501) If the VALUE attribute is specified, the PARAMETER, EXTERNAL, 2869 POINTER, ALLOCATABLE, DIMENSION, VOLATILE, INTENT(INOUT), or 2870 INTENT(OUT) attribute shall not be specified." 2871 "C528 (R501) If the VALUE attribute is specified, the length type 2872 parameter values shall be omitted or specified by initialization 2874 "C529 (R501) The VALUE attribute shall not be specified for a dummy 2876 "C530 (R501) The ALLOCATABLE, POINTER, or OPTIONAL attribute shall not be 2877 specified for adummy argument of a procedure that has 2878 aproc-language-binding-spec." 2879 "C532 (R501) If a language-binding-spec is specified, the entity declared 2880 shall be an interoperable variable." 2881 "C533 (R501) If a language-binding-spec with a NAME= specifier appears, 2882 the entity-decl-list shall consist of a single entity-decl." 2883 "C534 (R503) The PROTECTED attribute is permitted only in the 2884 specification part of a module." 2885 "C535 (R501) The PROTECTED attribute is permitted only for a procedure 2886 pointer or named variable that is not in a common block." 2887 "C536 (R501) If the PROTECTED attribute is specified, the EXTERNAL, 2888 INTRINSIC, or PARAMETER attribute shall not be specified." 2890 C507, C509-C517, C519, C522-C523, C526-C530, C532-C533, C535-C536 are 2891 currently not checked - issue #259. 2896 use_names = [
"Declaration_Type_Spec",
"Attr_Spec_List",
"Entity_Decl_List"]
2899 def get_attr_spec_list_cls():
2900 """Return the type used to match the attr-spec-list 2902 This method allows to overwrite the type used in :py:meth:`match` 2904 (e.g., :py:class:`fparser.two.Fortran2008.Type_Declaration_Stmt`). 2906 This cannot be implemented as an attribute because the relevant type 2907 :class:`Attr_Spec_List` is auto-generated at the end of the file 2908 using the :attr:`use_names` property of the class. 2911 return Attr_Spec_List
2914 def add_to_symbol_table(result):
2915 """Capture the declared symbols in the symbol table of the current 2918 :param result: the declared type, attributes and entities or None 2919 :type result: `NoneType` or \ 2920 (Declaration_Type_Spec, Attr_Spec_List or NoneType, \ 2926 table = SYMBOL_TABLES.current_scope
2928 if table
and isinstance(result[0], Intrinsic_Type_Spec):
2930 decl_list = walk(result, Entity_Decl)
2931 for decl
in decl_list:
2934 table.add_data_symbol(decl.items[0].string, str(result[0]))
2938 def match(cls, string):
2940 Attempts to match the supplied string as a type declaration. If the 2941 match is successful the declared symbols are added to the symbol table 2942 of the current scope (if there is one). 2944 Note that this is implemented as a class method to allow parameterizing 2945 the type used to match attr-spec-list via :py:meth:`get_attr_spec_list_cls`. 2947 :param str string: the string to match. 2949 :returns: 3-tuple containing the matched declaration. 2950 :rtype: (Declaration_Type_Spec, Attr_Spec_List or NoneType, \ 2954 result = Type_Declaration_StmtBase.match(
2955 Declaration_Type_Spec,
2956 cls.get_attr_spec_list_cls(),
2960 cls.add_to_symbol_table(result)
2965 line, repmap = string_replace_map(string)
2968 j = line[:i].find(
",")
2972 if line[:6].upper() ==
"DOUBLE":
2973 m = re.search(
r"\s[a-z_]", line[6:].lstrip(), re.I)
2976 i = m.start() + len(line) - len(line[6:].lstrip())
2978 m = re.search(
r"\s[a-z_]", line, re.I)
2983 if type_spec
is None:
2985 line = line[i:].lstrip()
2986 if line.startswith(
","):
2990 attr_specs = Attr_Spec_List(repmap(line[1:i].strip()))
2991 if attr_specs
is None:
2996 if line.startswith(
"::"):
2997 line = line[2:].lstrip()
2998 entity_decls = Entity_Decl_List(repmap(line))
2999 if entity_decls
is None:
3001 return type_spec, attr_specs, entity_decls
3004 if self.items[1]
is None:
3005 return "%s :: %s" % (self.items[0], self.items[2])
3007 return "%s, %s :: %s" % self.items
3012 <declaration-type-spec> = <intrinsic-type-spec> 3013 | TYPE ( <derived-type-spec> ) 3014 | CLASS ( <derived-type-spec> ) 3018 subclass_names = [
"Intrinsic_Type_Spec"]
3019 use_names = [
"Derived_Type_Spec"]
3023 """Implements the matching of a declaration type specification. 3025 :param str string: the reader or string to match as a \ 3026 declaration type specification. 3028 :return: A tuple of size 2 containing a string with the value \ 3029 'TYPE' or 'CLASS' and a 'Derived_Type_Spec' instance if there \ 3030 is a match or None if not. 3032 py:class:`fparser.two.Fortran2003.Derived_Type_Spec`,) or \ 3038 if string[-1] !=
")":
3040 start = string[:4].upper()
3042 line = string[4:].lstrip()
3043 if not line.startswith(
"("):
3046 start = string[:5].upper()
3047 if start ==
"CLASS":
3048 line = string[5:].lstrip()
3049 if not line.startswith(
"("):
3051 line = line[1:-1].strip()
3058 return "%s(%s)" % self.items
3063 <dimension-attr-spec> = DIMENSION ( <array-spec> ) 3067 use_names = [
"Array_Spec"]
3071 return CALLBase.match(
"DIMENSION", Array_Spec, string)
3076 <intent-attr-spec> = INTENT ( <intent-spec> ) 3080 use_names = [
"Intent_Spec"]
3084 return CALLBase.match(
"INTENT", Intent_Spec, string)
3089 <attr-spec> = <access-spec> 3092 | DIMENSION ( <array-spec> ) 3094 | INTENT ( <intent-spec> ) 3096 | <language-binding-spec> 3109 "Language_Binding_Spec",
3110 "Dimension_Attr_Spec",
3117 return STRINGBase.match(pattern.abs_attr_spec, string)
3122 <entity-decl> = <object-name> [ ( <array-spec> ) ] 3123 [ * <char-length> ] [ <initialization> ] 3124 | <function-name> [ * <char-length> ] 3137 def match(string, target=False):
3138 m = pattern.name.match(string)
3141 name =
Name(m.group())
3142 newline = string[m.end() :].lstrip()
3144 return name,
None,
None,
None 3148 if newline.startswith(
"("):
3149 line, repmap = string_replace_map(newline)
3153 array_spec =
Array_Spec(repmap(line[1:i].strip()))
3154 newline = repmap(line[i + 1 :].lstrip())
3158 return name, array_spec,
None,
None 3159 if newline.startswith(
"*"):
3160 line, repmap = string_replace_map(newline)
3163 char_length = repmap(line[1:i].strip())
3164 newline = repmap(newline[i:].lstrip())
3166 char_length = repmap(newline[1:].strip())
3169 if newline.startswith(
"="):
3174 assert newline ==
"", repr((newline, string))
3175 return name, array_spec, char_length, init
3178 s = str(self.items[0])
3179 if self.items[1]
is not None:
3180 s +=
"(" + str(self.items[1]) +
")" 3181 if self.items[2]
is not None:
3182 s +=
"*" + str(self.items[2])
3183 if self.items[3]
is not None:
3184 s +=
" " + str(self.items[3])
3188 """Provides the entity name as an instance of the :py:class:`Name` class. 3190 :rtype: :py:class:`Name` 3192 return self.items[0]
3197 <object-name> = <name> 3200 subclass_names = [
"Name"]
3205 <initialization> = = <initialization-expr> 3210 use_names = [
"Initialization_Expr",
"Null_Init"]
3214 if string.startswith(
"=>"):
3215 return "=>",
Null_Init(string[2:].lstrip())
3216 if string.startswith(
"="):
3221 return "%s %s" % self.items
3226 <null-init> = <function-reference> 3228 <function-reference> shall be a reference to the NULL 3229 intrinsic function with no arguments. 3232 subclass_names = [
"Function_Reference"]
3236 return STRINGBase.match(
"NULL", string)
3242 <access-spec> = PUBLIC 3250 return STRINGBase.match([
"PUBLIC",
"PRIVATE"], string)
3256 <language-binding-spec> = BIND ( C [ , 3257 NAME = <scalar-char-initialization-expr> ] ) 3261 use_names = [
"Scalar_Char_Initialization_Expr"]
3265 start = string[:4].upper()
3268 line = string[4:].lstrip()
3269 if not line
or line[0] + line[-1] !=
"()":
3271 line = line[1:-1].strip()
3274 start = line[0].upper()
3277 line = line[1:].lstrip()
3280 if not line.startswith(
","):
3282 line = line[1:].lstrip()
3283 start = line[:4].upper()
3286 line = line[4:].lstrip()
3287 if not line.startswith(
"="):
3292 if self.items[0]
is None:
3294 return "BIND(C, NAME = %s)" % (self.items[0])
3300 <array-spec> = <explicit-shape-spec-list> 3301 | <assumed-shape-spec-list> 3302 | <deferred-shape-spec-list> 3303 | <assumed-size-spec> 3307 "Assumed_Size_Spec",
3308 "Explicit_Shape_Spec_List",
3309 "Assumed_Shape_Spec_List",
3310 "Deferred_Shape_Spec_List",
3316 <explicit-shape-spec> = [ <lower-bound> : ] <upper-bound> 3320 use_names = [
"Lower_Bound",
"Upper_Bound"]
3324 line, repmap = string_replace_map(string)
3327 lower, upper = line.split(
":", 1)
3328 lower = lower.rstrip()
3329 upper = upper.lstrip()
3337 if self.items[0]
is None:
3338 return str(self.items[1])
3339 return SeparatorBase.tostr(self)
3344 <lower-bound> = <specification-expr> 3347 subclass_names = [
"Specification_Expr"]
3352 <upper-bound> = <specification-expr> 3355 subclass_names = [
"Specification_Expr"]
3361 <assumed-shape-spec> = [ <lower-bound> ] : 3365 use_names = [
"Lower_Bound"]
3369 return SeparatorBase.match(Lower_Bound,
None, string)
3375 <deferred_shape_spec> = : 3390 <assumed-size-spec> = [ <explicit-shape-spec-list> , ] 3391 [ <lower-bound> : ] * 3395 use_names = [
"Explicit_Shape_Spec_List",
"Lower_Bound"]
3399 if not string.endswith(
"*"):
3401 line = string[:-1].rstrip()
3404 if line.endswith(
":"):
3405 line, repmap = string_replace_map(line[:-1].rstrip())
3410 Explicit_Shape_Spec_List(repmap(line[:i].rstrip())),
3413 if not line.endswith(
","):
3415 line = line[:-1].rstrip()
3416 return Explicit_Shape_Spec_List(line),
None 3420 if self.items[0]
is not None:
3421 s += str(self.items[0]) +
", " 3422 if self.items[1]
is not None:
3423 s += str(self.items[1]) +
" : " 3439 return STRINGBase.match(pattern.abs_intent_spec, string)
3445 <access-stmt> = <access-spec> [ [ :: ] <access-id-list> ] 3449 use_names = [
"Access_Spec",
"Access_Id_List"]
3453 return WORDClsBase.match(
3454 [
"PUBLIC",
"PRIVATE"],
3461 tostr = WORDClsBase.tostr_a
3467 <access-id> = <use-name> 3471 subclass_names = [
"Use_Name",
"Generic_Spec"]
3476 <..> = <object-name> [ ( <deferred-shape-spec-list> ) ] 3479 subclass_names = [
"Object_Name"]
3480 use_names = [
"Deferred_Shape_Spec_List"]
3484 return CallBase.match(
3485 Object_Name, Deferred_Shape_Spec_List, string, require_rhs=
True 3492 <allocateble-stmt> = ALLOCATABLE [ :: ] <object-name> [ 3493 ( <deferred-shape-spec-list> ) ] [ , <object-name> 3494 [ ( <deferred-shape-spec-list> ) ] ]... 3498 use_names = [
"Object_Name_Deferred_Shape_Spec_List_Item_List"]
3502 return WORDClsBase.match(
3504 Object_Name_Deferred_Shape_Spec_List_Item_List,
3514 <asynchronous-stmt> = ASYNCHRONOUS [ :: ] <object-name-list> 3518 use_names = [
"Object_Name_List"]
3522 return WORDClsBase.match(
3523 "ASYNCHRONOUS", Object_Name_List, string, colons=
True, require_cls=
True 3530 <bind-stmt> = <language-binding-spec> [ :: ] <bind-entity-list> 3534 use_names = [
"Language_Binding_Spec",
"Bind_Entity_List"]
3538 i = string.find(
"::")
3540 i = string.find(
")")
3543 lhs, rhs = string[:i], string[i + 1 :]
3545 lhs, rhs = string.split(
"::", 1)
3548 if not lhs
or not rhs:
3553 return "%s :: %s" % self.items
3558 <bind-entity> = <entity-name> 3559 | / <common-block-name> / 3562 subclass_names = [
"Entity_Name"]
3563 use_names = [
"Common_Block_Name"]
3567 return BracketBase.match(
"//", Common_Block_Name, string)
3573 <data-stmt> = DATA <data-stmt-set> [ [ , ] <data-stmt-set> ]... 3577 use_names = [
"Data_Stmt_Set"]
3581 if string[:4].upper() !=
"DATA":
3583 line, repmap = string_replace_map(string[4:].lstrip())
3587 i = line.find(
"/", i + 1)
3591 line = line[i + 1 :].lstrip()
3593 if line.startswith(
","):
3594 line = line[1:].lstrip()
3598 i = line.find(
"/", i + 1)
3602 line = line[i + 1 :].lstrip()
3606 return "DATA " +
", ".join(map(str, self.items))
3612 <data-stmt-set> = <data-stmt-object-list> / <data-stmt-value-list> / 3616 use_names = [
"Data_Stmt_Object_List",
"Data_Stmt_Value_List"]
3620 if not string.endswith(
"/"):
3622 line, repmap = string_replace_map(string)
3626 data_stmt_object_list = Data_Stmt_Object_List(repmap(line[:i].rstrip()))
3627 data_stmt_value_list = Data_Stmt_Value_List(repmap(line[i + 1 : -1].strip()))
3628 return data_stmt_object_list, data_stmt_value_list
3630 data_stmt_object_list = property(
lambda self: self.items[0])
3631 data_stmt_value_list = property(
lambda self: self.items[1])
3634 return "%s / %s /" % tuple(self.items)
3640 <data-stmt-object> = <variable> 3644 subclass_names = [
"Variable",
"Data_Implied_Do"]
3650 <data-implied-do> = ( <data-i-do-object-list> , 3651 <data-i-do-variable> = <scalar-int-expr > , 3652 <scalar-int-expr> [ , <scalar-int-expr> ] ) 3656 use_names = [
"Data_I_Do_Object_List",
"Data_I_Do_Variable",
"Scalar_Int_Expr"]
3660 if not (string.startswith(
"(")
and string.endswith(
")")):
3662 line, repmap = string_replace_map(string[1:-1].strip())
3663 s = line.split(
"=", 1)
3668 s1 = lhs.rsplit(
",", 1)
3672 if len(s2)
not in [2, 3]:
3674 data_i_do_object_list = Data_I_Do_Object_List(repmap(s1[0].rstrip()))
3676 scalar_int_expr1 = Scalar_Int_Expr(repmap(s2[0].rstrip()))
3677 scalar_int_expr2 = Scalar_Int_Expr(repmap(s2[1].strip()))
3679 scalar_int_expr3 = Scalar_Int_Expr(repmap(s2[2].lstrip()))
3681 scalar_int_expr3 =
None 3683 data_i_do_object_list,
3690 data_i_do_object_list = property(
lambda self: self.items[0])
3691 data_i_do_variable = property(
lambda self: self.items[1])
3692 scalar_int_expr1 = property(
lambda self: self.items[2])
3693 scalar_int_expr2 = property(
lambda self: self.items[3])
3694 scalar_int_expr3 = property(
lambda self: self.items[4])
3697 tmp =
"%s, %s = %s, %s" % tuple(self.items[:4])
3698 if self.items[4]
is not None:
3699 tmp +=
", %s" % (self.items[4])
3700 return "(" + tmp +
")" 3705 <data-i-do-object> = <array-element> 3706 | <scalar-structure-component> 3710 subclass_names = [
"Array_Element",
"Scalar_Structure_Component",
"Data_Implied_Do"]
3715 <data-i-do-variable> = <scalar-int-variable> 3718 subclass_names = [
"Scalar_Int_Variable"]
3723 <data-stmt-value> = [ <data-stmt-repeat> * ] <data-stmt-constant> 3726 subclass_names = [
"Data_Stmt_Constant"]
3727 use_names = [
"Data_Stmt_Repeat"]
3731 line, repmap = string_replace_map(string)
3732 s = line.split(
"*", 1)
3735 lhs = repmap(s[0].rstrip())
3736 rhs = repmap(s[1].lstrip())
3737 if not lhs
or not rhs:
3742 return "%s * %s" % self.items
3747 <data-stmt-repeat> = <scalar-int-constant> 3748 | <scalar-int-constant-subobject> 3751 subclass_names = [
"Scalar_Int_Constant",
"Scalar_Int_Constant_Subobject"]
3756 <data-stmt-constant> = <scalar-constant> 3757 | <scalar-constant-subobject> 3758 | <signed-int-literal-constant> 3759 | <signed-real-literal-constant> 3761 | <structure-constructor> 3766 "Scalar_Constant_Subobject",
3767 "Signed_Int_Literal_Constant",
3768 "Signed_Real_Literal_Constant",
3770 "Structure_Constructor",
3776 <int-constant-subobject> = <constant-subobject> 3779 subclass_names = [
"Constant_Subobject"]
3784 <constant-subobject> = <designator> 3787 subclass_names = [
"Designator"]
3792 <dimension-stmt> = DIMENSION [ :: ] <array-name> ( <array-spec> ) 3793 [ , <array-name> ( <array-spec> ) ]... 3797 use_names = [
"Array_Name",
"Array_Spec"]
3801 if string[:9].upper() !=
"DIMENSION":
3803 line, repmap = string_replace_map(string[9:].lstrip())
3804 if line.startswith(
"::"):
3805 line = line[2:].lstrip()
3807 for s
in line.split(
","):
3809 if not s.endswith(
")"):
3816 Array_Name(repmap(s[:i].rstrip())),
3825 return "DIMENSION :: " +
", ".join([
"%s(%s)" % ns
for ns
in self.items[0]])
3830 <intent-stmt> = INTENT ( <intent-spec> ) [ :: ] <dummy-arg-name-list> 3834 use_names = [
"Intent_Spec",
"Dummy_Arg_Name_List"]
3838 if string[:6].upper() !=
"INTENT":
3840 line = string[6:].lstrip()
3841 if not line
or not line.startswith(
"("):
3846 spec = line[1:i].strip()
3849 line = line[i + 1 :].lstrip()
3850 if line.startswith(
"::"):
3851 line = line[2:].lstrip()
3854 return Intent_Spec(spec), Dummy_Arg_Name_List(line)
3857 return "INTENT(%s) :: %s" % self.items
3862 <optional-stmt> = OPTIONAL [ :: ] <dummy-arg-name-list> 3866 use_names = [
"Dummy_Arg_Name_List"]
3870 return WORDClsBase.match(
3871 "OPTIONAL", Dummy_Arg_Name_List, string, colons=
True, require_cls=
True 3874 tostr = WORDClsBase.tostr_a
3879 <parameter-stmt> = PARAMETER ( <named-constant-def-list> ) 3883 use_names = [
"Named_Constant_Def_List"]
3887 return CALLBase.match(
3888 "PARAMETER", Named_Constant_Def_List, string, require_rhs=
True 3894 <named-constant-def> = <named-constant> = <initialization-expr> 3898 use_names = [
"Named_Constant",
"Initialization_Expr"]
3902 return KeywordValueBase.match(Named_Constant, Initialization_Expr, string)
3907 cray-pointer-stmt is POINTER cray-pointer-decl-list 3911 use_names = [
"Cray_Pointer_Decl_List"]
3915 """Implements the matching for a Cray-pointer statement. 3917 :param string: the reader or string to match as a Cray-pointer \ 3920 :py:class:`fparser.common.readfortran.FortranReaderBase` or \ 3922 :return: a tuple of size 2 containing a string with the name \ 3923 "POINTER" and a cray-pointer-decl-list, if there is a match, \ 3924 or `None` if there is not. 3925 :rtype: (str, Cray_Pointer_Decl_List) or None 3930 if "cray-pointer" not in EXTENSIONS:
3932 return WORDClsBase.match(
3933 "POINTER", Cray_Pointer_Decl_List, string, require_cls=
True 3939 cray-pointer-decl is ( cray-pointer-name, cray-pointee-decl ) 3942 use_names = [
"Cray_Pointer_Name",
"Cray_Pointee_Name",
"Cray_Pointee_Decl"]
3946 """Implements the matching for a Cray-pointer declaration. 3948 :param str string: the string to match as a Cray-pointer \ 3950 :return: None if there is no match, otherwise a tuple of size \ 3951 2 containing the name of the pointer as the first argument and \ 3952 either the name of the pointee as the second argument or a \ 3953 Cray-pointee declaration. 3954 :rtype: None, (Name, Name) or (Name, Cray_Pointee_Decl) 3959 strip_string = string.strip()
3960 if not strip_string:
3962 if not strip_string[0] ==
"(":
3964 if not strip_string[-1] ==
")":
3966 strip_string_nobr = strip_string[1:-1].strip()
3967 line, repmap = string_replace_map(strip_string_nobr)
3968 split_list = line.split(
",")
3969 if len(split_list) != 2:
3971 pointer_name = repmap(split_list[0]).strip()
3972 pointee_str = repmap(split_list[1]).strip()
3973 if pointee_str[-1] ==
")":
3975 return Cray_Pointer_Name(pointer_name), Cray_Pointee_Name(pointee_str)
3979 :return: this Cray-pointee declaration as a string 3981 :raises InternalError: if the internal items list variable is \ 3982 not the expected size. 3983 :raises InternalError: if the first element of the internal \ 3984 items list is None or is empty. 3985 :raises InternalError: if the second element of the internal \ 3986 items list is None or is empty. 3988 if len(self.items) != 2:
3989 raise InternalError(
3990 "Cray_Pointer_Decl.tostr(). 'Items' should be of size 2 but " 3991 "found '{0}'.".format(len(self.items))
3993 if not self.items[0]:
3994 raise InternalError(
3995 "Cray_Pointer_Decl_Stmt.tostr(). 'Items' " 3996 "entry 0 should be a pointer name but it is " 3999 if not self.items[1]:
4000 raise InternalError(
4001 "Cray_Pointer_Decl_Stmt.tostr(). 'Items' " 4002 "entry 1 should be a pointee name or pointee " 4003 "declaration but it is empty" 4005 return "({0}, {1})".format(self.items[0], self.items[1])
4010 cray-pointee-decl is cray-pointee-name ( cray-pointee-array-spec ) 4015 use_names = [
"Cray_Pointee_Name",
"Cray_Pointee_Array_Spec"]
4019 """Implements the matching for a Cray-pointee declaration. 4021 :param str string: the string to match as a Cray-pointee \ 4023 :return: None if there is no match, otherwise a tuple of size \ 4024 2 containing the name of the pointee as the first argument and \ 4025 a Cray-pointee array spec as the second argument. 4026 :rtype: None or (Name, Cray_Pointee_Array_Spec) 4029 return CallBase.match(
4030 Cray_Pointee_Name, Cray_Pointee_Array_Spec, string, require_rhs=
True 4035 """cray-pointee-array-spec is explicit-shape-spec-list 4036 or assumed-size-spec 4038 The above two forms of declaration are the only ones allowed 4040 http://pubs.cray.com/content/S-3901/8.6/ 4041 cray-fortran-reference-manual-s-3901-86/types) or 4042 https://docs.oracle.com/cd/E19957-01/805-4941/z40000a54ba7/index.html 4046 subclass_names = [
"Assumed_Size_Spec",
"Explicit_Shape_Spec_List"]
4051 <pointer-stmt> = POINTER [ :: ] <pointer-decl-list> 4055 use_names = [
"Pointer_Decl_List"]
4059 return WORDClsBase.match(
4060 "POINTER", Pointer_Decl_List, string, colons=
True, require_cls=
True 4063 tostr = WORDClsBase.tostr_a
4068 <pointer-decl> = <object-name> [ ( <deferred-shape-spec-list> ) ] 4069 | <proc-entity-name> 4072 subclass_names = [
"Proc_Entity_Name",
"Object_Name"]
4073 use_names = [
"Deferred_Shape_Spec_List"]
4077 return CallBase.match(
4078 Object_Name, Deferred_Shape_Spec_List, string, require_rhs=
True 4084 <protected-stmt> = PROTECTED [ :: ] <entity-name-list> 4088 use_names = [
"Entity_Name_List"]
4092 return WORDClsBase.match(
4093 "PROTECTED", Entity_Name_List, string, colons=
True, require_cls=
True 4096 tostr = WORDClsBase.tostr_a
4101 <save-stmt> = SAVE [ [ :: ] <saved-entity-list> ] 4105 use_names = [
"Saved_Entity_List"]
4109 return WORDClsBase.match(
4110 "SAVE", Saved_Entity_List, string, colons=
True, require_cls=
False 4113 tostr = WORDClsBase.tostr_a
4118 <saved-entity> = <object-name> 4119 | <proc-pointer-name> 4120 | / <common-block-name> / 4123 subclass_names = [
"Object_Name",
"Proc_Pointer_Name"]
4124 use_names = [
"Common_Block_Name"]
4128 return BracketBase.match(
"//", Common_Block_Name, string)
4133 <proc-pointer-name> = <name> 4136 subclass_names = [
"Name"]
4141 <target-entity-decl> = <object-name> [ ( <array-spec> ) ] 4145 use_names = [
"Object_Name",
"Array_Spec"]
4149 return Entity_Decl.match(string, target=
True)
4154 <target-stmt> = TARGET [ :: ] <target-entity-decl-list> 4158 use_names = [
"Target_Entity_Decl_List"]
4162 if string[:6].upper() !=
"TARGET":
4164 line = string[6:].lstrip()
4165 if line.startswith(
"::"):
4166 line = line[2:].lstrip()
4167 return (Target_Entity_Decl_List(line),)
4170 return "TARGET :: %s" % (self.items[0])
4175 <value-stmt> = VALUE [ :: ] <dummy-arg-name-list> 4179 use_names = [
"Dummy_Arg_Name_List"]
4183 return WORDClsBase.match(
4184 "VALUE", Dummy_Arg_Name_List, string, colons=
True, require_cls=
True 4187 tostr = WORDClsBase.tostr_a
4192 <volatile-stmt> = VOLATILE [ :: ] <object-name-list> 4196 use_names = [
"Object_Name_List"]
4200 return WORDClsBase.match(
4201 "VOLATILE", Object_Name_List, string, colons=
True, require_cls=
True 4204 tostr = WORDClsBase.tostr_a
4210 <implicit-stmt> = IMPLICIT <implicit-spec-list> 4215 items : ({'NONE', Implicit_Spec_List},) 4219 use_names = [
"Implicit_Spec_List"]
4223 if string[:8].upper() !=
"IMPLICIT":
4225 line = string[8:].lstrip()
4226 if len(line) == 4
and line.upper() ==
"NONE":
4228 return (Implicit_Spec_List(line),)
4230 (pattern.abs_implicit_none,
None),
4231 (
"IMPLICIT", Implicit_Spec_List),
4234 obj = WORDClsBase.match(w, cls, string)
4235 except NoMatchError:
4242 return "IMPLICIT %s" % (self.items[0])
4247 <implicit-spec> = <declaration-type-spec> ( <letter-spec-list> ) 4251 use_names = [
"Declaration_Type_Spec",
"Letter_Spec_List"]
4255 if not string.endswith(
")"):
4257 i = string.rfind(
"(")
4260 s1 = string[:i].rstrip()
4261 s2 = string[i + 1 : -1].strip()
4262 if not s1
or not s2:
4269 <letter-spec> = <letter> [ - <letter> ] 4276 if len(string) == 1:
4277 lhs = string.upper()
4278 if "A" <= lhs <=
"Z":
4281 if "-" not in string:
4283 lhs, rhs = string.split(
"-", 1)
4284 lhs = lhs.strip().upper()
4285 rhs = rhs.strip().upper()
4286 if not len(lhs) == len(rhs) == 1:
4288 if not (
"A" <= lhs <= rhs <=
"Z"):
4293 if self.items[1]
is None:
4294 return str(self.items[0])
4295 return "%s - %s" % tuple(self.items)
4301 <namelist-stmt> = NAMELIST / <namelist-group-name> / 4302 <namelist-group-object-list> [ [ , ] / <namelist-group-name> / 4303 <namelist-group-object-list> ]... 4307 items : (Namelist_Group_Name, Namelist_Group_Object_List)-tuple 4311 use_names = [
"Namelist_Group_Name",
"Namelist_Group_Object_List"]
4315 if string[:8].upper() !=
"NAMELIST":
4317 line = string[8:].lstrip()
4318 parts = line.split(
"/")
4321 assert not fst, repr((fst, parts))
4322 while len(parts) >= 2:
4323 name, lst = parts[:2]
4327 if lst.endswith(
","):
4328 lst = lst[:-1].rstrip()
4329 items.append((Namelist_Group_Name(name), Namelist_Group_Object_List(lst)))
4330 assert not parts, repr(parts)
4334 return "NAMELIST " +
", ".join(
4335 "/%s/ %s" % (name_lst)
for name_lst
in self.items
4341 <namelist-group-object> = <variable-name> 4344 subclass_names = [
"Variable_Name"]
4349 <equivalence-stmt> = EQUIVALENCE <equivalence-set-list> 4353 use_names = [
"Equivalence_Set_List"]
4357 return WORDClsBase.match(
"EQUIVALENCE", Equivalence_Set_List, string)
4362 <equivalence-set> = ( <equivalence-object> , <equivalence-object-list> ) 4366 use_names = [
"Equivalence_Object",
"Equivalence_Object_List"]
4370 if not string
or string[0] + string[-1] !=
"()":
4372 line = string[1:-1].strip()
4375 tmp = Equivalence_Object_List(line)
4377 tmp.items = tmp.items[1:]
4383 return "(%s, %s)" % tuple(self.items)
4388 <equivalence-object> = <variable-name> 4393 subclass_names = [
"Variable_Name",
"Array_Element",
"Substring"]
4398 <common-stmt> = COMMON [ / [ <common-block-name> ] / ] 4399 <common-block-object-list> [ [ , ] / [ <common-block-name> ] 4400 / <common-block-object-list> ]... 4404 use_names = [
"Common_Block_Name",
"Common_Block_Object_List"]
4408 if string[:6].upper() !=
"COMMON":
4411 if not line
or "A" <= line[0].upper() <=
"Z" or line[0] ==
"_":
4413 line, repmap = string_replace_map(line.lstrip())
4415 if line.startswith(
"/"):
4416 i = line.find(
"/", 1)
4419 name = line[1:i].strip()
or None 4420 if name
is not None:
4421 name = Common_Block_Name(name)
4422 line = line[i + 1 :].lstrip()
4425 lst = Common_Block_Object_List(repmap(line))
4428 tmp = line[:i].rstrip()
4429 if tmp.endswith(
","):
4430 tmp = tmp[:-1].rstrip()
4433 lst = Common_Block_Object_List(repmap(tmp))
4434 line = line[i:].lstrip()
4439 lst = Common_Block_Object_List(repmap(line))
4442 tmp = line[:i].rstrip()
4443 if tmp.endswith(
","):
4444 tmp = tmp[:-1].rstrip()
4447 lst = Common_Block_Object_List(repmap(tmp))
4448 line = line[i:].lstrip()
4449 items.append((name, lst))
4451 if line.startswith(
","):
4452 line = line[1:].lstrip()
4453 if not line.startswith(
"/"):
4455 i = line.find(
"/", 1)
4456 name = line[1:i].strip()
or None 4457 if name
is not None:
4458 name = Common_Block_Name(name)
4459 line = line[i + 1 :].lstrip()
4462 lst = Common_Block_Object_List(repmap(line))
4465 tmp = line[:i].rstrip()
4466 if tmp.endswith(
","):
4467 tmp = tmp[:-1].rstrip()
4470 lst = Common_Block_Object_List(repmap(tmp))
4471 line = line[i:].lstrip()
4472 items.append((name, lst))
4477 for (name, lst)
in self.items[0]:
4478 if name
is not None:
4479 s +=
" /%s/ %s" % (name, lst)
4481 s +=
" // %s" % (lst)
4487 <common-block-object> = <variable-name> [ ( <explicit-shape-spec-list> ) ] 4488 | <proc-pointer-name> 4491 subclass_names = [
"Proc_Pointer_Name",
"Variable_Name"]
4492 use_names = [
"Variable_Name",
"Explicit_Shape_Spec_List"]
4496 return CallBase.match(
4497 Variable_Name, Explicit_Shape_Spec_List, string, require_rhs=
True 4508 <variable> = <designator> 4511 subclass_names = [
"Designator"]
4516 <variable-name> = <name> 4519 subclass_names = [
"Name"]
4524 Fortran 2003 rule 603 4526 designator is object-name 4529 or structure-component 4544 "Structure_Component",
4551 <logical-variable> = <variable> 4554 subclass_names = [
"Variable"]
4559 <default-logical-variable> = <variable> 4562 subclass_names = [
"Variable"]
4567 <char-variable> = <variable> 4570 subclass_names = [
"Variable"]
4575 <default-char-variable> = <variable> 4578 subclass_names = [
"Variable"]
4583 <int-variable> = <variable> 4586 subclass_names = [
"Variable"]
4591 <substring> = <parent-string> ( <substring-range> ) 4595 use_names = [
"Parent_String",
"Substring_Range"]
4599 return CallBase.match(Parent_String, Substring_Range, string, require_rhs=
True)
4604 <parent-string> = <scalar-variable-name> 4606 | <scalar-structure-component> 4611 "Scalar_Variable_Name",
4613 "Scalar_Structure_Component",
4620 <substring-range> = [ <scalar-int-expr> ] : [ <scalar-int-expr> ] 4624 use_names = [
"Scalar_Int_Expr"]
4628 return SeparatorBase.match(Scalar_Int_Expr, Scalar_Int_Expr, string)
4633 Fortran 2003 Rule R612 4635 data-ref is part-ref [ % part-ref ] ... 4637 If there is only one part-ref then return a 'Part_Ref' object (or 4638 another object from a matching sub-rule). If there is more than 4639 one part-ref then return a 'Data_Ref' object containing the 4644 subclass_names = [
"Part_Ref"]
4649 """Implements the matching for a data-reference. This defines a series 4650 of dereferences e.g. a%b%c. 4652 If there is more than one part-ref then return a 'Data_Ref' 4653 object containing the part-ref's, otherwise return 'None'. A 4654 single 'part-ref' is purposely not matched here. 4656 :param str string: Fortran code to check for a match 4658 :return: `None` if there is no match, or a tuple containing \ 4659 the matched operator as a string and another tuple \ 4660 containing the matched subclasses. 4662 :rtype: NoneType or (str, (obj, obj, ...)) 4667 result = SequenceBase.match(
r"%", Part_Ref, string)
4669 if len(entries) > 1:
4681 <part-ref> = <part-name> [ ( <section-subscript-list> ) ] 4684 subclass_names = [
"Part_Name"]
4685 use_names = [
"Section_Subscript_List"]
4689 return CallBase.match(
4690 Part_Name, Section_Subscript_List, string, require_rhs=
True 4696 <structure-component> = <data-ref> 4699 subclass_names = [
"Data_Ref"]
4704 <type-param-inquiry> = <designator> % <type-param-name> 4708 use_names = [
"Designator",
"Type_Param_Name"]
4712 return BinaryOpBase.match(
4713 Designator, pattern.percent_op.named(), Type_Param_Name, string
4719 <array-element> = <data-ref> 4722 subclass_names = [
"Data_Ref"]
4727 <array-section> = <data-ref> [ ( <substring-range> ) ] 4730 subclass_names = [
"Data_Ref"]
4731 use_names = [
"Substring_Range"]
4735 return CallBase.match(Data_Ref, Substring_Range, string, require_rhs=
True)
4740 <subscript> = <scalar-int-expr> 4743 subclass_names = [
"Scalar_Int_Expr"]
4748 <section-subscript> = <subscript> 4749 | <subscript-triplet> 4750 | <vector-subscript> 4753 subclass_names = [
"Subscript_Triplet",
"Vector_Subscript",
"Subscript"]
4758 <subscript-triplet> = [ <subscript> ] : [ <subscript> ] [ : <stride> ] 4762 use_names = [
"Subscript",
"Stride"]
4766 line, repmap = string_replace_map(string)
4768 if len(t) <= 1
or len(t) > 3:
4770 lhs_obj, rhs_obj, stride_obj =
None,
None,
None 4772 lhs, rhs = t[0].rstrip(), t[1].lstrip()
4774 lhs, rhs, stride = t[0].rstrip(), t[1].strip(), t[2].lstrip()
4776 stride_obj =
Stride(repmap(stride))
4781 return lhs_obj, rhs_obj, stride_obj
4785 if self.items[0]
is not None:
4786 s += str(self.items[0]) +
" :" 4789 if self.items[1]
is not None:
4790 s +=
" " + str(self.items[1])
4791 if self.items[2]
is not None:
4792 s +=
" : " + str(self.items[2])
4798 <stride> = <scalar-int-expr> 4801 subclass_names = [
"Scalar_Int_Expr"]
4806 <vector-subscript> = <int-expr> 4809 subclass_names = [
"Int_Expr"]
4814 Fortran2003 rule R623 4815 allocate-stmt is ALLOCATE ( [ type-spec :: ] allocation-list 4816 [, alloc-opt-list ] ) 4818 Subject to the following constraints: 4820 C622 (R629) Each allocate-object shall be a nonprocedure pointer or an 4821 allocatable variable. 4822 C623 (R623) If any allocate-object in the statement has a deferred type 4823 parameter, either type-spec or SOURCE= shall appear. 4824 C624 (R623) If a type-spec appears, it shall specify a type with which 4825 each allocate-object is type compatible. 4826 C625 (R623) If any allocate-object is unlimited polymorphic, either 4827 type-spec or SOURCE= shall appear. 4828 C626 (R623) A type-param-value in a type-spec shall be an asterisk if and 4829 only if each allocate-object is a dummy argument for which the 4830 corresponding type parameter is assumed. 4831 C627 (R623) If a type-spec appears, the kind type parameter values of each 4832 allocate-object shall be the same as the corresponding type 4833 parameter values of the type-spec. 4834 C628 (R628) An allocate-shape-spec-list shall appear if and only if the 4835 allocate-object is an array. 4836 C629 (R628) The number of allocate-shape-specs in an 4837 allocate-shape-spec-list shall be the same as the rank of the 4839 C630 (R624) No alloc-opt shall appear more than once in a given 4841 C631 (R623) If SOURCE= appears, type-spec shall not appear and 4842 allocation-list shall contain only one allocate-object, which 4843 shall be type compatible (5.1.1.2) with source-expr. 4844 C632 (R623) The source-expr shall be a scalar or have the same rank as 4846 C633 (R623) Corresponding kind type parameters of allocate-object and 4847 source-expr shall have the same values. 4849 None of these constraints are currently applied - issue #355. 4854 use_names = [
"Type_Spec",
"Allocation_List",
"Alloc_Opt_List"]
4857 def match(cls, string):
4859 Attempts to match the supplied string as an Allocate_Stmt. 4861 :param str string: the string to attempt to match. 4863 :returns: A 2-tuple giving the Type_Spec and Allocation_List if the \ 4864 match is successful, None otherwise. 4866 Tuple[Optional[:py:class:`fparser.two.Fortran2003.Type_Spec`], \ 4867 :py:class:`fparser.two.Fortran2003.Allocation_List`]] 4869 if string[:8].upper() !=
"ALLOCATE":
4871 line = string[8:].lstrip()
4872 if not line
or line[0] !=
"(" or line[-1] !=
")":
4874 line, repmap = string_replace_map(line[1:-1].strip())
4875 idx = line.find(
"::")
4878 spec =
Type_Spec(repmap(line[:idx].rstrip()))
4879 line = line[idx + 2 :].lstrip()
4880 idx = line.find(
"=")
4883 jdx = line[:idx].rfind(
",")
4891 opts = cls.alloc_opt_list()(repmap(line[jdx + 1 :].lstrip()))
4892 line = line[:jdx].rstrip()
4893 return spec, Allocation_List(repmap(line)), opts
4896 def alloc_opt_list(cls):
4898 :returns: the Fortran2003 flavour of Alloc_Opt_List. 4901 return Alloc_Opt_List
4904 spec, lst, opts = self.items
4905 if spec
is not None:
4906 if opts
is not None:
4907 return "ALLOCATE(%s::%s, %s)" % (spec, lst, opts)
4909 return "ALLOCATE(%s::%s)" % (spec, lst)
4910 elif opts
is not None:
4911 return "ALLOCATE(%s, %s)" % (lst, opts)
4913 return "ALLOCATE(%s)" % (lst)
4918 <stat-variable> = <scalar-int-variable> 4921 subclass_names = [
"Scalar_Int_Variable"]
4926 <errmsg-variable> = <scalar-default-char-variable> 4929 subclass_names = [
"Scalar_Default_Char_Variable"]
4934 <source-expr> = <expr> 4937 subclass_names = [
"Expr"]
4942 <alloc-opt> = STAT = <stat-variable> 4943 | ERRMSG = <errmsg-variable> 4944 | SOURCE = <source-expr> 4948 use_names = [
"Stat_Variable",
"Errmsg_Variable",
"Source_Expr"]
4951 (
"STAT", Stat_Variable),
4952 (
"ERRMSG", Errmsg_Variable),
4953 (
"SOURCE", Source_Expr),
4957 def match(cls, string):
4958 for (k, v)
in cls._keyword_pairs:
4959 obj = KeywordValueBase.match(k, v, string, upper_lhs=
True)
4967 <allocation> = <allocate-object> [ ( <allocate-shape-spec-list> ) ] 4971 subclass_names = [
"Variable_Name",
"Allocate_Object"]
4972 use_names = [
"Allocate_Shape_Spec_List"]
4976 return CallBase.match(
4977 Allocate_Object, Allocate_Shape_Spec_List, string, require_rhs=
True 4983 <allocate-object> = <variable-name> 4984 | <structure-component> 4987 subclass_names = [
"Variable_Name",
"Structure_Component"]
4992 <allocate-shape-spec> = [ <lower-bound-expr> : ] <upper-bound-expr> 4996 use_names = [
"Lower_Bound_Expr",
"Upper_Bound_Expr"]
5000 line, repmap = string_replace_map(string)
5003 lower, upper = line.split(
":", 1)
5004 lower = lower.rstrip()
5005 upper = upper.lstrip()
5013 if self.items[0]
is None:
5014 return str(self.items[1])
5015 return SeparatorBase.tostr(self)
5020 <lower-bound-expr> = <scalar-int-expr> 5023 subclass_names = [
"Scalar_Int_Expr"]
5028 <upper-bound-expr> = <scalar-int-expr> 5031 subclass_names = [
"Scalar_Int_Expr"]
5036 <nullify-stmt> = NULLIFY ( <pointer-object-list> ) 5040 use_names = [
"Pointer_Object_List"]
5044 return CALLBase.match(
"NULLIFY", Pointer_Object_List, string, require_rhs=
True)
5049 <pointer-object> = <variable-name> 5050 | <structure-component> 5051 | <proc-pointer-name> 5054 subclass_names = [
"Variable_Name",
"Structure_Component",
"Proc_Pointer_Name"]
5059 <deallocate-stmt> = DEALLOCATE ( <allocate-object-list> [ 5060 , <dealloc-opt-list> ] ) 5064 use_names = [
"Allocate_Object_List",
"Dealloc_Opt_List"]
5068 if string[:10].upper() !=
"DEALLOCATE":
5070 line = string[10:].lstrip()
5071 if not line
or line[0] !=
"(" or line[-1] !=
")":
5073 line, repmap = string_replace_map(line[1:-1].strip())
5077 j = line[:i].rfind(
",")
5078 assert j != -1, repr((i, j, line))
5079 opts = Dealloc_Opt_List(repmap(line[j + 1 :].lstrip()))
5080 line = line[:j].rstrip()
5081 return Allocate_Object_List(repmap(line)), opts
5084 if self.items[1]
is not None:
5085 return "DEALLOCATE(%s, %s)" % (self.items)
5086 return "DEALLOCATE(%s)" % (self.items[0])
5091 <dealloc-opt> = STAT = <stat-variable> 5092 | ERRMSG = <errmsg-variable> 5096 use_names = [
"Stat_Variable",
"Errmsg_Variable"]
5100 for (k, v)
in [(
"STAT", Stat_Variable), (
"ERRMSG", Errmsg_Variable)]:
5102 obj = KeywordValueBase.match(k, v, string, upper_lhs=
True)
5103 except NoMatchError:
5111 subclass_names = [
"Char_Initialization_Expr"]
5120 """Fortran 2003 rule R701 5122 primary is intrinsic_function_reference 5125 or array-constructor 5126 or structure-constructor 5127 or function-reference 5128 or type-param-inquiry 5132 `intrinsic_function_reference` is not part of rule R701 but is 5133 required for fparser to recognise intrinsic functions. This is 5134 placed before array-constructor in the `subclass_names` list so 5135 that an intrinsic is not (incorrectly) matched as an array (as 5136 class `Base` matches rules in list order). 5138 Note, ( expr ) is implemented in the Parenthesis subclass. 5143 "Intrinsic_Function_Reference",
5146 "Array_Constructor",
5147 "Structure_Constructor",
5148 "Function_Reference",
5149 "Type_Param_Inquiry",
5157 Part of Fortran 2003 rule R701 5159 parenthesis = ( expr ) 5164 use_names = [
"Expr"]
5168 """Implements the matching of round brackets surrounding an expression 5169 which is specified as one of the matches in R701. 5171 :param str string: Fortran code to check for a match. 5173 :returns: `None` if there is no match, or a 3-tuple containing \ 5174 the left bracket, the matched expression and the right \ 5176 :rtype: NoneType or (str, subclass of \ 5177 :py:class:`fparser.two.utils.Base`, str) 5180 return BracketBase.match(
"()", Expr, string)
5185 <level-1-expr> = [ <defined-unary-op> ] <primary> 5186 <defined-unary-op> = . <letter> [ <letter> ]... . 5189 subclass_names = [
"Primary"]
5194 return UnaryOpBase.match(pattern.defined_unary_op.named(), Primary, string)
5201 Fortran 2003 rule R703 5203 defined-unary-op is . letter [ letter ]... . 5205 C704 (R703) A defined-unary-op shall not contain more than 63 5206 letters and shall not be the same as any intrinsic-operator or 5207 logical-literal-constant. 5209 Implemented in Defined_Op class. 5213 subclass_names = [
"Defined_Op"]
5218 Utility class that Implements the functionality of rules R703 and 5219 R723 (as the rules are the same) 5221 defined-op is . letter [ letter ]... . 5223 C704 (R723) A defined-binary-op shall not contain more than 63 5224 letters and shall not be the same as any intrinsic-operator or 5225 logical-literal-constant. 5227 C704 (R703) A defined-unary-op shall not contain more than 63 5228 letters and shall not be the same as any intrinsic-operator or 5229 logical-literal-constant. 5237 """Implements the matching for a (user) Defined Unary or Binary 5240 :param str string: Fortran code to check for a match 5241 :return: `None` if there is no match, or a tuple containing \ 5242 the matched operator as a string 5243 :rtype: None or (str) 5246 strip_string = string.strip()
5247 if len(strip_string) > 65:
5251 if pattern.non_defined_binary_op.match(strip_string):
5255 return STRINGBase.match(pattern.abs_defined_op, strip_string)
5260 <mult-operand> = <level-1-expr> [ <power-op> <mult-operand> ] 5264 subclass_names = [
"Level_1_Expr"]
5265 use_names = [
"Mult_Operand"]
5269 return BinaryOpBase.match(
5270 Level_1_Expr, pattern.power_op.named(), Mult_Operand, string, right=
False 5275 """Fortran 2003 rule R705 5277 add-operand is [ add-operand mult-op ] mult-operand 5279 Rule R705 is implemented in two parts, the first with the optional 5280 part included (in the match method for this class) and the second 5281 without the optional part (specified in subclass_names). 5283 Note rule R708 (mult-op is * or /) is implemented directly here as 5284 the mult_op pattern. 5286 There is potential to accidentally match a sign in an exponent as the 5287 plus/minus sign in a level-2-expr. If this were to happen then it is 5288 possible to end up matching a * or / (a level 1 expression) before 5289 matching a valid + or - which would normally result in no match 5290 overall as * or / are matched after + or -. This situation is 5291 avoided by tokenising the string before performing the match so 5292 that any numerical constants involving exponents are replaced by 5293 simple symbols. (The tokenisation is performed by 5294 `fparser.common.splitline.string_replace_map`.) 5298 subclass_names = [
"Mult_Operand"]
5299 use_names = [
"Mult_Operand"]
5303 """Implement the matching for the add-operand rule. Makes use of the 5304 pre-defined mult_op pattern and the BinaryOpBase baseclass. 5306 :param str string: the string to match. 5308 :returns: a tuple of size 3 containing an fparser2 class \ 5309 instance matching a level-2-expr expression, a string \ 5310 containing the matched operator and an fparser2 class \ 5311 instance matching a mult-operand if there is a match, or \ 5312 None if there is not. 5313 :rtype: (subclass of :py:class:`fparser.two.utils.Base`, str, \ 5314 subclass of :py:class:`fparser.two.utils.Base`) or NoneType 5317 return BinaryOpBase.match(
5318 Add_Operand, pattern.mult_op.named(), Mult_Operand, string
5324 <level-2-expr> = [ [ <level-2-expr> ] <add-op> ] <add-operand> 5325 <level-2-expr> = [ <level-2-expr> <add-op> ] <add-operand> 5326 | <level-2-unary-expr> 5331 subclass_names = [
"Level_2_Unary_Expr"]
5332 use_names = [
"Level_2_Expr"]
5336 return BinaryOpBase.match(
5337 Level_2_Expr, pattern.add_op.named(), Add_Operand, string
5343 <level-2-unary-expr> = [ <add-op> ] <add-operand> 5346 subclass_names = [
"Add_Operand"]
5351 return UnaryOpBase.match(pattern.add_op.named(), Add_Operand, string)
5361 <level-3-expr> = [ <level-3-expr> <concat-op> ] <level-2-expr> 5365 subclass_names = [
"Level_2_Expr"]
5366 use_names = [
"Level_3_Expr"]
5370 return BinaryOpBase.match(
5371 Level_3_Expr, pattern.concat_op.named(), Level_2_Expr, string
5380 <level-4-expr> = [ <level-3-expr> <rel-op> ] <level-3-expr> 5381 <rel-op> = .EQ. | .NE. | .LT. | .LE. | .GT. | .GE. | == | 5382 /= | < | <= | > | >= 5385 subclass_names = [
"Level_3_Expr"]
5390 return BinaryOpBase.match(
5391 Level_3_Expr, pattern.rel_op.named(), Level_3_Expr, string
5401 <and-operand> = [ <not-op> ] <level-4-expr> 5405 subclass_names = [
"Level_4_Expr"]
5410 return UnaryOpBase.match(pattern.not_op.named(), Level_4_Expr, string)
5415 <or-operand> = [ <or-operand> <and-op> ] <and-operand> 5419 subclass_names = [
"And_Operand"]
5420 use_names = [
"Or_Operand",
"And_Operand"]
5424 return BinaryOpBase.match(
5425 Or_Operand, pattern.and_op.named(), And_Operand, string
5431 <equiv-operand> = [ <equiv-operand> <or-op> ] <or-operand> 5435 subclass_names = [
"Or_Operand"]
5436 use_names = [
"Equiv_Operand"]
5440 return BinaryOpBase.match(
5441 Equiv_Operand, pattern.or_op.named(), Or_Operand, string
5447 <level-5-expr> = [ <level-5-expr> <equiv-op> ] <equiv-operand> 5452 subclass_names = [
"Equiv_Operand"]
5453 use_names = [
"Level_5_Expr"]
5457 return BinaryOpBase.match(
5458 Level_5_Expr, pattern.equiv_op.named(), Equiv_Operand, string
5470 <expr> = [ <expr> <defined-binary-op> ] <level-5-expr> 5471 <defined-binary-op> = . <letter> [ <letter> ]... . 5474 subclass_names = [
"Level_5_Expr"]
5475 use_names = [
"Expr"]
5479 return BinaryOpBase.match(
5481 pattern.defined_binary_op.named(),
5484 exclude_op_pattern=pattern.non_defined_binary_op,
5490 Fortran 2003 rule R723 5492 defined-binary-op is . letter [ letter ]... . 5494 C704 (R723) A defined-binary-op shall not contain more than 63 5495 letters and shall not be the same as any intrinsic-operator or 5496 logical-literal-constant. 5498 Implemented in Defined_Op class. 5502 subclass_names = [
"Defined_Op"]
5507 Fortran 2003 rule R724 5509 logical-expr is expr 5511 C705 logical-expr shall be of type logical. 5519 """Implements the matching for a logical expression. 5521 Note, whilst we exclude Signed_Int_Literal_Constant and 5522 Signed_Real_Literal_Constant, it seems that it is not possible 5523 to create these from code as a "-" sign is treated as a unary 5526 :param str string: Fortran code to check for a match. 5527 :returns: `None` if there is no match, or an fparser2 class \ 5528 instance containing the matched expression. 5529 :rtype: NoneType or :py:class:`fparser.two.utils.Base` 5533 Signed_Int_Literal_Constant,
5534 Int_Literal_Constant,
5538 Signed_Real_Literal_Constant,
5539 Real_Literal_Constant,
5540 Complex_Literal_Constant,
5541 Char_Literal_Constant,
5544 result =
Expr(string)
5549 if isinstance(result, excluded):
5556 Fortran 2003 rule R725 5560 C706 char-expr shall be of type character. 5568 """Implements the matching for a character expression. 5570 :param str string: Fortran code to check for a match. 5571 :returns: `None` if there is no match, or an fparser2 class \ 5572 instance containing the matched expression. 5573 :rtype: NoneType or :py:class:`fparser.two.utils.Base` 5577 Signed_Int_Literal_Constant,
5578 Int_Literal_Constant,
5582 Signed_Real_Literal_Constant,
5583 Real_Literal_Constant,
5584 Complex_Literal_Constant,
5585 Logical_Literal_Constant,
5588 result =
Expr(string)
5593 if isinstance(result, excluded):
5600 Fortran 2003 rule R726 5602 default-char-expr is expr 5604 C707 default-char-expr shall be of type default character. 5612 """Implements the matching for a default character expression. 5614 :param str string: Fortran code to check for a match. 5615 :returns: `None` if there is no match, or an fparser2 class \ 5616 instance containing the matched expression. 5617 :rtype: NoneType or :py:class:`fparser.two.utils.Base` 5621 Signed_Int_Literal_Constant,
5622 Int_Literal_Constant,
5626 Signed_Real_Literal_Constant,
5627 Real_Literal_Constant,
5628 Complex_Literal_Constant,
5629 Logical_Literal_Constant,
5632 result =
Expr(string)
5637 if isinstance(result, excluded):
5644 Fortran 2003 rule R727 5648 C708 int-expr shall be of type integer. 5656 """Implements the matching for an integer expression. 5658 :param str string: Fortran code to check for a match. 5659 :returns: `None` if there is no match, or an fparser2 class \ 5660 instance containing the matched expression. 5661 :rtype: NoneType or :py:class:`fparser.two.utils.Base` 5668 Signed_Real_Literal_Constant,
5669 Real_Literal_Constant,
5670 Complex_Literal_Constant,
5671 Char_Literal_Constant,
5672 Logical_Literal_Constant,
5675 result =
Expr(string)
5680 if isinstance(result, excluded):
5687 Fortran 2003 rule R728 5689 numeric-expr is expr 5691 C709 numeric-expr shall be of type integer, real or complex. 5699 """Implements the matching for a numeric expression. 5701 :param str string: Fortran code to check for a match. 5702 :returns: `None` if there is no match, or an fparser2 class \ 5703 instance containing the matched expression. 5704 :rtype: NoneType or :py:class:`fparser.two.utils.Base` 5711 Char_Literal_Constant,
5712 Logical_Literal_Constant,
5715 result =
Expr(string)
5721 if isinstance(result, excluded):
5728 <specification-expr> = <scalar-int-expr> 5731 subclass_names = [
"Scalar_Int_Expr"]
5736 <initialization-expr> = <expr> 5739 subclass_names = [
"Expr"]
5744 <char-initialization-expr> = <char-expr> 5747 subclass_names = [
"Char_Expr"]
5752 <int-initialization-expr> = <int-expr> 5755 subclass_names = [
"Int_Expr"]
5760 <logical-initialization-expr> = <logical-expr> 5763 subclass_names = [
"Logical_Expr"]
5768 <assignment-stmt> = <variable> = <expr> 5772 use_names = [
"Variable",
"Expr"]
5776 return BinaryOpBase.match(Variable,
"=", Expr, string, right=
False)
5781 <pointer-assignment-stmt> = <data-pointer-object> [ 5782 ( <bounds-spec-list> ) ] => <data-target> 5783 | <data-pointer-object> ( <bounds-remapping-list> ) => <data-target> 5784 | <proc-pointer-object> => <proc-target> 5789 "Data_Pointer_Object",
5792 "Bounds_Remapping_List",
5793 "Proc_Pointer_Object",
5799 line, repmap = string_replace_map(string)
5803 lhs = line[:i].rstrip()
5804 rhs = repmap(line[i + 2 :].lstrip())
5805 if lhs.endswith(
")"):
5809 o = repmap(lhs[:i].rstrip())
5810 tmp = repmap(lhs[i + 1 : -1].strip())
5813 except NoMatchError
as msg:
5816 Bounds_Remapping_List(tmp),
5823 except NoMatchError
as msg:
5827 if self.items[1]
is None:
5828 return "%s => %s" % (self.items[0], self.items[2])
5829 return "%s(%s) => %s" % (self.items)
5834 <data-pointer-object> = <variable-name> 5835 | <variable> % <data-pointer-component-name> 5838 subclass_names = [
"Variable_Name"]
5839 use_names = [
"Variable",
"Data_Pointer_Component_Name"]
5843 return BinaryOpBase.match(Variable,
r"%", Data_Pointer_Component_Name, string)
5848 <bounds-spec> = <lower-bound-expr> : 5852 use_names = [
"Lower_Bound_Expr"]
5856 return SeparatorBase.match(Lower_Bound_Expr,
None, string, require_lhs=
True)
5861 <bounds-remapping> = <lower-bound-expr> : <upper-bound-expr> 5865 use_classes = [
"Lower_Bound_Expr",
"Upper_Bound_Expr"]
5869 return SeparatorBase.match(
5880 <data-target> = <variable> 5884 subclass_names = [
"Variable",
"Expr"]
5889 <proc-pointer-object> = <proc-pointer-name> 5890 | <proc-component-ref> 5893 subclass_names = [
"Proc_Pointer_Name",
"Proc_Component_Ref"]
5898 <proc-component-ref> = <variable> % <procedure-component-name> 5902 use_names = [
"Variable",
"Procedure_Component_Name"]
5906 return BinaryOpBase.match(Variable,
r"%", Procedure_Component_Name, string)
5911 <proc-target> = <expr> 5913 | <proc-component-ref> 5916 subclass_names = [
"Proc_Component_Ref",
"Procedure_Name",
"Expr"]
5921 <where-stmt> = WHERE ( <mask-expr> ) <where-assignment-stmt> 5925 use_names = [
"Mask_Expr",
"Where_Assignment_Stmt"]
5929 if string[:5].upper() !=
"WHERE":
5931 line, repmap = string_replace_map(string[5:].lstrip())
5932 if not line.startswith(
"("):
5937 stmt = repmap(line[i + 1 :].lstrip())
5940 expr = repmap(line[1:i].strip())
5946 return "WHERE (%s) %s" % tuple(self.items)
5951 <where-construct> = <where-construct-stmt> 5952 [ <where-body-construct> ]... 5953 [ <masked-elsewhere-stmt> 5954 [ <where-body-construct> ]... 5957 [ <where-body-construct> ]... ] 5963 "Where_Construct_Stmt",
5964 "Where_Body_Construct",
5965 "Masked_Elsewhere_Stmt",
5972 return BlockBase.match(
5973 Where_Construct_Stmt,
5975 Where_Body_Construct,
5976 Masked_Elsewhere_Stmt,
5977 Where_Body_Construct,
5979 Where_Body_Construct,
5984 strict_match_names=
True,
5985 match_name_classes=(
5986 Masked_Elsewhere_Stmt,
5990 enable_where_construct_hook=
True,
5993 def tofortran(self, tab="", isfix=None):
5995 Converts this node (and all children) into Fortran. 5997 :param str tab: white space to prefix to output. 5998 :param bool isfix: whether or not to generate fixed-format output. 6000 :returns: Fortran code. 6005 start = self.content[0]
6006 end = self.content[-1]
6007 tmp.append(start.tofortran(tab=tab, isfix=isfix))
6008 for item
in self.content[1:-1]:
6009 if isinstance(item, (Masked_Elsewhere_Stmt, Elsewhere_Stmt)):
6010 tmp.append(item.tofortran(tab=tab, isfix=isfix))
6012 tmp.append(item.tofortran(tab=tab +
" ", isfix=isfix))
6013 tmp.append(end.tofortran(tab=tab, isfix=isfix))
6014 return "\n".join(tmp)
6019 <where-construct-stmt> = [ <where-construct-name> : ] WHERE ( <mask-expr> ) 6023 use_names = [
"Where_Construct_Name",
"Mask_Expr"]
6027 if string[:5].upper() !=
"WHERE":
6029 line = string[5:].lstrip()
6032 if line[0] + line[-1] !=
"()":
6034 line = line[1:-1].strip()
6040 return "WHERE (%s)" % tuple(self.items)
6042 def get_start_name(self):
6043 return self.item.name
6049 <where-body-construct> = <where-assignment-stmt> 6054 subclass_names = [
"Where_Assignment_Stmt",
"Where_Stmt",
"Where_Construct"]
6060 <where-assignment-stmt> = <assignment-stmt> 6063 subclass_names = [
"Assignment_Stmt"]
6068 <mask-expr> = <logical-expr> 6071 subclass_names = [
"Logical_Expr"]
6076 <masked-elsewhere-stmt> = ELSEWHERE 6077 ( <mask-expr> ) [ <where-construct-name> ] 6083 use_names = [
"Mask_Expr",
"Where_Construct_Name"]
6087 if not Elsewhere_Stmt._regex.match(string):
6089 idx = string.upper().index(
"WHERE")
6090 line = string[idx + 5 :].lstrip()
6092 if not line.startswith(
"("):
6097 expr = line[1:i].strip()
6100 line = line[i + 1 :].rstrip()
6102 return Mask_Expr(expr), Where_Construct_Name(line)
6106 if self.items[1]
is None:
6107 return "ELSEWHERE(%s)" % (self.items[0])
6108 return "ELSEWHERE(%s) %s" % self.items
6110 def get_end_name(self):
6112 :return: the name at the END of this block, if it exists 6113 :rtype: str or NoneType 6115 name = self.items[1]
6116 if name
is not None:
6123 <elsewhere-stmt> = ELSEWHERE [ <where-construct-name> ] 6127 use_names = [
"Where_Construct_Name"]
6128 _regex = re.compile(
r"ELSE\s*WHERE", re.I)
6132 if not Elsewhere_Stmt._regex.match(string):
6134 idx = string.upper().index(
"WHERE")
6135 line = string[idx + 5 :].lstrip()
6137 return "ELSEWHERE", Where_Construct_Name(line)
6138 return "ELSEWHERE",
None 6140 def get_end_name(self):
6142 :return: the name at the END of this block, if it exists 6143 :rtype: str or NoneType 6145 name = self.items[1]
6146 if name
is not None:
6153 <end-where-stmt> = END WHERE [ <where-construct-name> ] 6157 use_names = [
"Where_Construct_Name"]
6161 return EndStmtBase.match(
6162 "WHERE", Where_Construct_Name, string, require_stmt_type=
True 6168 <forall-construct> = <forall-construct-stmt> 6169 [ <forall-body-construct> ]... 6174 use_names = [
"Forall_Construct_Stmt",
"Forall_Body_Construct",
"End_Forall_Stmt"]
6178 return BlockBase.match(
6179 Forall_Construct_Stmt,
6180 [Forall_Body_Construct],
6184 strict_match_names=
True,
6190 <forall-construct-stmt> = [ <forall-construct-name> : ] 6191 FORALL <forall-header> 6195 use_names = [
"Forall_Construct_Name",
"Forall_Header"]
6199 return WORDClsBase.match(
"FORALL", Forall_Header, string, require_cls=
True)
6201 def get_start_name(self):
6202 return self.item.name
6207 Fortran 2003 rule R754 6208 forall-header is ( forall-triplet-spec-list [, scalar-mask-expr ] ) 6213 use_names = [
"Forall_Triplet_Spec_List",
"Scalar_Mask_Expr"]
6217 """Implements the matching for a Forall_Header. 6219 :param str string: A string containing the code to match. 6220 :return: `None` if there is no match, otherwise a `tuple` of \ 6221 size 2 containing a class of type \ 6222 `Forall_Triplet_Spec_List` and a class of type \ 6223 `Scalar_Mask_Expr` if there is a scalar mask \ 6224 expresssion and `None` if not. 6225 :rtype: (`Forall_Triplet_Spec_List`, `Scalar_Mask_Expr`) or \ 6226 (`Forall_Triplet_Spec_List`, `None`) or `None` 6229 strip_string = string.strip()
6230 if not strip_string:
6233 if strip_string[0] + strip_string[-1] !=
"()":
6236 strip_string_nobr = strip_string[1:-1].strip()
6239 return Forall_Triplet_Spec_List(strip_string_nobr),
None 6240 except NoMatchError:
6245 mapped_string, repmap = string_replace_map(strip_string_nobr)
6246 split_string = mapped_string.rsplit(
",", 1)
6247 if len(split_string) != 2:
6249 left_str = repmap(split_string[0].rstrip())
6250 right_str = repmap(split_string[1].lstrip())
6251 return (Forall_Triplet_Spec_List(left_str), Scalar_Mask_Expr(right_str))
6254 """:return: this Forall Header as a string 6256 :raises InternalError: if the length of the internal items \ 6258 :raises InternalError: if the first entry of the internal \ 6259 items list has no content, as a Forall_Triplet_List is \ 6263 if len(self.items) != 2:
6264 raise InternalError(
6265 "Forall_Header.tostr(). 'items' should be of size 2 but " 6266 "found '{0}'.".format(len(self.items))
6268 if not self.items[0]:
6269 raise InternalError(
6270 "Forall_Header.tostr(). 'items[0]' should be a " 6271 "Forall_Triplet_Spec_List instance but it is empty." 6273 if not self.items[1]:
6275 return "({0})".format(self.items[0])
6276 return "({0}, {1})".format(self.items[0], self.items[1])
6281 <forall-triplet-spec> = <index-name> = <subscript> : 6282 <subscript> [ : <stride> ] 6286 use_names = [
"Index_Name",
"Subscript",
"Stride"]
6290 line, repmap = string_replace_map(string)
6294 n = Index_Name(repmap(line[:i].rstrip()))
6295 line = line[i + 1 :].lstrip()
6296 s = [repmap(s.strip())
for s
in line.split(
":")]
6303 if self.items[3]
is None:
6304 return "%s = %s : %s" % (self.items[:3])
6305 return "%s = %s : %s : %s" % (self.items)
6310 <forall-body-construct> = <forall-assignment-stmt> 6313 | <forall-construct> 6318 "Forall_Assignment_Stmt",
6328 <forall-assignment-stmt> = <assignment-stmt> 6329 | <pointer-assignment-stmt> 6332 subclass_names = [
"Assignment_Stmt",
"Pointer_Assignment_Stmt"]
6337 <end-forall-stmt> = END FORALL [ <forall-construct-name> ] 6341 use_names = [
"Forall_Construct_Name"]
6345 return EndStmtBase.match(
6346 "FORALL", Forall_Construct_Name, string, require_stmt_type=
True 6352 Fortran 2003 rule R759 6353 forall-stmt is FORALL forall-header forall-assignment-stmt 6358 use_names = [
"Forall_Header",
"Forall_Assignment_Stmt"]
6362 """Implements the matching for a forall statement. 6364 :param string: A string or the fortran reader containing the \ 6365 line of code that we are trying to match. 6366 :type string: `str` or \ 6367 :py:class:`fparser.common.readfortran.FortranReader` 6368 :return: `None` if there is no match or a `tuple` of size 2 \ 6369 containing an instance of the Forall_Header class followed by \ 6370 an instance of the Forall_Assignment_Stmt class. 6371 :rtype: `None` or ( \ 6372 :py:class:`fparser.two.Fortran2003.Forall_Header`, \ 6373 :py:class:`fparser.two.Fortran2003.Forall_Assignment_Stmt`) 6376 strip_string = string.strip()
6377 if strip_string[:6].upper() !=
"FORALL":
6379 line, repmap = string_replace_map(strip_string[6:].lstrip())
6380 if not line.startswith(
"("):
6382 index = line.find(
")")
6385 header = repmap(line[: index + 1])
6388 line = repmap(line[index + 1 :].lstrip())
6395 :return: this forall statement as a string 6397 :raises InternalError: if the internal items list variable is \ 6398 not the expected size. 6399 :raises InternalError: if the first element of the internal \ 6400 items list is None or is an empty string. 6401 :raises InternalError: if the second element of the internal \ 6402 items list is None or is an empty string. 6404 if len(self.items) != 2:
6405 raise InternalError(
6406 "Class Forall_Stmt method tostr() has '{0}' items, " 6407 "but expecting 2.".format(len(self.items))
6409 if not self.items[0]:
6410 raise InternalError(
6411 "Class Forall_Stmt method tostr(). 'Items' entry 0 " 6412 "should be a valid Forall_Header." 6414 if not self.items[1]:
6415 raise InternalError(
6416 "Class Forall_Stmt method tostr(). 'Items' entry 1 should " 6417 "be a valid Forall_Assignment_Stmt" 6419 return "FORALL {0} {1}".format(self.items[0], self.items[1])
6429 <block> = [ <execution-part-construct> ]... 6433 use_names = [
"Execution_Part_Construct"]
6437 return BlockBase.match(
None, [Execution_Part_Construct],
None, string)
6442 <if-construct> = <if-then-stmt> 6454 use_names = [
"If_Then_Stmt",
"Block",
"Else_If_Stmt",
"Else_Stmt",
"End_If_Stmt"]
6458 return BlockBase.match(
6461 Execution_Part_Construct,
6463 Execution_Part_Construct,
6465 Execution_Part_Construct,
6470 strict_match_names=
True,
6471 match_name_classes=(Else_If_Stmt, Else_Stmt, End_If_Stmt),
6472 enable_if_construct_hook=
True,
6475 def tofortran(self, tab="", isfix=None):
6477 Converts this node (and all children) into Fortran. 6479 :param str tab: white space to prefix to output. 6480 :param bool isfix: whether or not to generate fixed-format output. 6482 :returns: Fortran code. 6487 start = self.content[0]
6488 end = self.content[-1]
6489 tmp.append(start.tofortran(tab=tab, isfix=isfix))
6490 for item
in self.content[1:-1]:
6491 if isinstance(item, (Else_If_Stmt, Else_Stmt)):
6492 tmp.append(item.tofortran(tab=tab, isfix=isfix))
6494 tmp.append(item.tofortran(tab=tab +
" ", isfix=isfix))
6495 tmp.append(end.tofortran(tab=tab, isfix=isfix))
6496 return "\n".join(tmp)
6501 <if-then-stmt> = [ <if-construct-name> : ] 6502 IF ( <scalar-logical-expr> ) THEN 6506 use_names = [
"If_Construct_Name",
"Scalar_Logical_Expr"]
6510 if string[:2].upper() !=
"IF":
6512 if string[-4:].upper() !=
"THEN":
6514 line = string[2:-4].strip()
6517 if line[0] + line[-1] !=
"()":
6519 return (Scalar_Logical_Expr(line[1:-1].strip()),)
6522 return "IF (%s) THEN" % self.items
6524 def get_start_name(self):
6525 return self.item.name
6530 <else-if-stmt> = ELSE IF ( <scalar-logical-expr> ) THEN 6531 [ <if-construct-name> ] 6535 use_names = [
"Scalar_Logical_Expr",
"If_Construct_Name"]
6539 if string[:4].upper() !=
"ELSE":
6541 line = string[4:].lstrip()
6542 if line[:2].upper() !=
"IF":
6544 line = line[2:].lstrip()
6545 if not line.startswith(
"("):
6550 expr = line[1:i].strip()
6551 line = line[i + 1 :].lstrip()
6552 if line[:4].upper() !=
"THEN":
6554 line = line[4:].lstrip()
6556 return Scalar_Logical_Expr(expr), If_Construct_Name(line)
6557 return Scalar_Logical_Expr(expr),
None 6560 if self.items[1]
is None:
6561 return "ELSE IF (%s) THEN" % (self.items[0])
6562 return "ELSE IF (%s) THEN %s" % self.items
6564 def get_end_name(self):
6566 :return: the name at the END of this block, if it exists 6567 :rtype: str or NoneType 6569 name = self.items[1]
6570 if name
is not None:
6577 <else-stmt> = ELSE [ <if-construct-name> ] 6581 use_names = [
"If_Construct_Name"]
6585 if string[:4].upper() !=
"ELSE":
6587 line = string[4:].lstrip()
6589 return (If_Construct_Name(line),)
6593 if self.items[0]
is None:
6595 return "ELSE %s" % self.items
6597 def get_end_name(self):
6599 :return: the name at the END of this block, if it exists 6600 :rtype: str or NoneType 6602 name = self.items[0]
6603 if name
is not None:
6610 <end-if-stmt> = END IF [ <if-construct-name> ] 6614 use_names = [
"If_Construct_Name"]
6618 return EndStmtBase.match(
6619 "IF", If_Construct_Name, string, require_stmt_type=
True 6625 Fortran 2003 rule R807 6627 if-stmt is IF ( scalar-logical-expr ) action-stmt 6629 C802 (R807) The action-stmt in the if-stmt shall not be an if-stmt, 6630 end-program-stmt, end-function-stmt, or end-subroutine-stmt. 6635 use_names = [
"Scalar_Logical_Expr",
"Action_Stmt_C802"]
6636 action_stmt_cls = Action_Stmt_C802
6639 def match(cls, string):
6640 """Implements the matching for an if statement that controls a single 6643 This is implemented as a class method to allow parameterizing the 6644 type that is used to match the action-stmt. It is specified by the 6645 attribute :py:attr:`action_stmt_cls`, which can be overwritten in 6646 derived classes to specify an updated version, so done for example 6647 in the Fortran 2008 version :py:class:`fparser.two.Fortran2008.If_Stmt`. 6649 :param str string: Text that we are trying to match. 6651 :returns: None if there is no match or, if there is a match, a \ 6652 2-tuple containing the logical expression as an object matched by \ 6653 :py:class:`fparser.two.Fortran2003.Scalar_Logical_Expr` and the \ 6654 action statement as an object matching ``cls.action_stmt_cls``. 6655 :rtype: (:py:class:`fparser.two.Fortran2003.Scalar_Logical_Expr`, 6656 :py:class:`fparser.two.Fortran2003.Action_Stmt_C802`) \ 6660 if string[:2].upper() !=
"IF":
6662 line, repmap = string_replace_map(string)
6663 line = line[2:].lstrip()
6664 if not line.startswith(
"("):
6669 expr = repmap(line[1:i].strip())
6670 stmt = repmap(line[i + 1 :].lstrip())
6671 return Scalar_Logical_Expr(expr), cls.action_stmt_cls(stmt)
6674 return "IF (%s) %s" % self.items
6679 <case-construct> = <select-case-stmt> 6681 <block> == [<execution-part-construct>].. 6691 "Execution_Part_Construct",
6696 return BlockBase.match(
6698 [Case_Stmt, Execution_Part_Construct, Case_Stmt],
6702 strict_match_names=
True,
6703 match_name_classes=(Case_Stmt),
6706 def tofortran(self, tab="", isfix=None):
6708 Converts this node (and all children) into Fortran. 6710 :param str tab: white space to prefix to output. 6711 :param bool isfix: whether or not to generate fixed-format output. 6713 :returns: Fortran code. 6718 start = self.content[0]
6719 end = self.content[-1]
6720 tmp.append(start.tofortran(tab=tab, isfix=isfix))
6721 for item
in self.content[1:-1]:
6722 if isinstance(item, Case_Stmt):
6723 tmp.append(item.tofortran(tab=tab, isfix=isfix))
6725 tmp.append(item.tofortran(tab=tab +
" ", isfix=isfix))
6726 tmp.append(end.tofortran(tab=tab, isfix=isfix))
6727 return "\n".join(tmp)
6732 <select-case-stmt> = [ <case-construct-name> : ] 6733 SELECT CASE ( <case-expr> ) 6737 use_names = [
"Case_Construct_Name",
"Case_Expr"]
6741 if string[:6].upper() !=
"SELECT":
6743 line = string[6:].lstrip()
6744 if line[:4].upper() !=
"CASE":
6746 line = line[4:].lstrip()
6747 if not line
or line[0] + line[-1] !=
"()":
6749 line = line[1:-1].strip()
6753 return "SELECT CASE (%s)" % (self.items[0])
6755 def get_start_name(self):
6756 return self.item.name
6761 <case-stmt> = CASE <case-selector> [ <case-construct-name> ] 6765 use_names = [
"Case_Selector",
"Case_Construct_Name"]
6769 if string[:4].upper() !=
"CASE":
6771 line, repmap = string_replace_map(string[4:].lstrip())
6772 if line.startswith(
"("):
6776 n = line[i + 1 :].lstrip()
or None 6778 n = Case_Construct_Name(repmap(n))
6780 if line[:7].upper() ==
"DEFAULT":
6781 n = repmap(line[7:].lstrip())
or None 6783 n = Case_Construct_Name(repmap(n))
6787 if self.items[1]
is None:
6788 return "CASE %s" % (self.items[0])
6789 return "CASE %s %s" % (self.items)
6791 def get_end_name(self):
6793 :return: the name at the END of this block, if it exists 6794 :rtype: str or NoneType 6796 name = self.items[1]
6797 if name
is not None:
6804 <end-select-stmt> = END SELECT [ <case-construct-name> ] 6808 use_names = [
"Case_Construct_Name"]
6812 return EndStmtBase.match(
6813 "SELECT", Case_Construct_Name, string, require_stmt_type=
True 6819 <case-expr> = <scalar-int-expr> 6820 | <scalar-char-expr> 6821 | <scalar-logical-expr> 6825 subclass_names = [
"Scalar_Int_Expr",
"Scalar_Char_Expr",
"Scalar_Logical_Expr"]
6830 <case-selector> = ( <case-value-range-list> ) 6835 use_names = [
"Case_Value_Range_List"]
6839 if len(string) == 7
and string.upper() ==
"DEFAULT":
6841 if not (string.startswith(
"(")
and string.endswith(
")")):
6843 return (Case_Value_Range_List(string[1:-1].strip()),)
6846 if self.items[0]
is None:
6848 return "(%s)" % (self.items[0])
6853 <case-value-range> = <case-value> 6856 | <case-value> : <case-value> 6859 subclass_names = [
"Case_Value"]
6863 return SeparatorBase.match(Case_Value, Case_Value, string)
6868 <case-value> = <scalar-int-initialization-expr> 6869 | <scalar-char-initialization-expr> 6870 | <scalar-logical-initialization-expr> 6874 "Scalar_Int_Initialization_Expr",
6875 "Scalar_Char_Initialization_Expr",
6876 "Scalar_Logical_Initialization_Expr",
6882 <associate-construct> = <associate-stmt> 6883 <block> == [ <execution-part-construct> ]... 6884 <end-associate-stmt> 6888 use_names = [
"Associate_Stmt",
"Execution_Part_Construct",
"End_Associate_Stmt"]
6892 return BlockBase.match(
6894 [Execution_Part_Construct],
6898 strict_match_names=
True,
6904 <associate-stmt> = [ <associate-construct-name> : ] 6905 ASSOCIATE ( <association-list> ) 6909 use_names = [
"Associate_Construct_Name",
"Association_List"]
6913 return CALLBase.match(
"ASSOCIATE", Association_List, string)
6915 def get_start_name(self):
6916 return self.item.name
6921 <association> = <associate-name> => <selector> 6925 use_names = [
"Associate_Name",
"Selector"]
6929 return BinaryOpBase.match(Associate_Name,
"=>", Selector, string)
6938 subclass_names = [
"Expr",
"Variable"]
6943 <end-associate-stmt> = END ASSOCIATE [ <associate-construct-name> ] 6947 use_names = [
"Associate_Construct_Name"]
6951 return EndStmtBase.match(
6952 "ASSOCIATE", Associate_Construct_Name, string, require_stmt_type=
True 6958 <select-type-construct> = <select-type-stmt> 6960 <block> == [<execution-part-construct>].. 6962 <end-select-type-stmt> 6969 "Execution_Part_Construct",
6970 "End_Select_Type_Stmt",
6975 return BlockBase.match(
6977 [Type_Guard_Stmt, Execution_Part_Construct, Type_Guard_Stmt],
6978 End_Select_Type_Stmt,
6981 strict_match_names=
True,
6982 match_name_classes=(Type_Guard_Stmt),
6988 <select-type-stmt> = [ <select-construct-name> : ] SELECT TYPE 6989 ( [ <associate-name> => ] <selector> ) 6993 use_names = [
"Select_Construct_Name",
"Associate_Name",
"Selector"]
6997 if string[:6].upper() !=
"SELECT":
6999 line = string[6:].lstrip()
7000 if line[:4].upper() !=
"TYPE":
7002 line = line[4:].lstrip()
7003 if not line
or line[0] + line[-1] !=
"()":
7005 line = line[1:-1].strip()
7008 return Associate_Name(line[:i].rstrip()),
Selector(line[i + 2 :].lstrip())
7012 if self.items[0]
is None:
7013 return "SELECT TYPE(%s)" % (self.items[1])
7014 return "SELECT TYPE(%s=>%s)" % (self.items)
7016 def get_start_name(self):
7017 return self.item.name
7023 <type-guard-stmt> = TYPE IS ( <type-spec> ) [ <select-construct-name> ] 7024 | CLASS IS ( <type-spec> ) [ <select-construct-name> ] 7025 | CLASS DEFAULT [ <select-construct-name> ] 7029 items : ({'TYPE IS', 'CLASS IS', 'CLASS DEFAULT'}, Type_Spec, 7030 Select_Construct_Name) 7034 use_names = [
"Type_Spec",
"Select_Construct_Name"]
7038 if string[:4].upper() ==
"TYPE":
7039 line = string[4:].lstrip()
7040 if not line[:2].upper() ==
"IS":
7042 line = line[2:].lstrip()
7044 elif string[:5].upper() ==
"CLASS":
7045 line = string[5:].lstrip()
7046 if line[:2].upper() ==
"IS":
7047 line = line[2:].lstrip()
7049 elif line[:7].upper() ==
"DEFAULT":
7050 line = line[7:].lstrip()
7052 if isalnum(line[0]):
7054 return "CLASS DEFAULT",
None, Select_Construct_Name(line)
7055 return "CLASS DEFAULT",
None,
None 7060 if not line.startswith(
"("):
7065 tmp = line[1:i].strip()
7068 line = line[i + 1 :].lstrip()
7070 return kind,
Type_Spec(tmp), Select_Construct_Name(line)
7074 s = str(self.items[0])
7075 if self.items[1]
is not None:
7076 s +=
" (%s)" % (self.items[1])
7077 if self.items[2]
is not None:
7078 s +=
" %s" % (self.items[2])
7081 def get_end_name(self):
7083 :return: the name at the END of this block, if it exists 7084 :rtype: str or NoneType 7086 name = self.items[-1]
7087 if name
is not None:
7094 <end-select-type-stmt> = END SELECT [ <select-construct-name> ] 7098 use_names = [
"Select_Construct_Name"]
7102 return EndStmtBase.match(
7103 "SELECT", Select_Construct_Name, string, require_stmt_type=
True 7111 <do-construct> = <block-do-construct> 7112 | <nonblock-do-construct> 7115 subclass_names = [
"Block_Do_Construct",
"Nonblock_Do_Construct"]
7122 <block-do-construct> = <block-label-do-construct> 7123 | <block-nonlabel-do-construct> 7126 subclass_names = [
"Block_Label_Do_Construct",
"Block_Nonlabel_Do_Construct"]
7133 <block-label-do-construct> = <label-do-stmt> 7134 [ <execution-part-construct> ]... 7139 use_names = [
"Label_Do_Stmt",
"Execution_Part_Construct",
"End_Do"]
7144 :param reader: instance of `FortranReaderBase` class 7145 :type reader: :py:class:`FortranReaderBase` 7146 :return: code block matching the labeled "DO" construct 7149 return BlockBase.match(
7151 [Execution_Part_Construct],
7155 enable_do_label_construct_hook=
True,
7158 def tofortran(self, tab="", isfix=None):
7160 :param str tab: tab character or empty string. 7161 :param bool isfix: whether the reader is in fixed format. 7163 :return: parsed representation of the labeled "DO" construct. 7167 start = self.content[0]
7168 end = self.content[-1]
7170 lblock.append(start.tofortran(tab=tab, isfix=isfix))
7171 for item
in self.content[1:-1]:
7172 lblock.append(item.tofortran(tab=tab + extra_tab, isfix=isfix))
7173 if len(self.content) > 1:
7174 lblock.append(end.tofortran(tab=tab, isfix=isfix))
7175 return "\n".join(lblock)
7182 <block-nonlabel-do-construct> = <nonlabel-do-stmt> 7183 [ <execution-part-construct> ]... 7188 use_names = [
"Nonlabel_Do_Stmt",
"Execution_Part_Construct",
"End_Do_Stmt"]
7193 :param reader: instance of `FortranReaderBase` class 7194 :type reader: :py:class:`FortranReaderBase` 7195 :return: code block matching the nonlabeled "DO" construct 7198 return BlockBase.match(
7200 [Execution_Part_Construct],
7204 strict_match_names=
True,
7212 <do-stmt> = <label-do-stmt> 7213 | <nonlabel-do-stmt> 7216 subclass_names = [
"Label_Do_Stmt",
"Nonlabel_Do_Stmt"]
7223 <label-do-stmt> = [ <do-construct-name> : ] DO <label> [ <loop-control> ] 7227 use_names = [
"Do_Construct_Name",
"Label",
"Loop_Control"]
7232 :param string: (source of) Fortran string to parse 7233 :type string: str or :py:class:`FortranReaderBase` 7234 :return: 3-tuple containing strings and instances of the classes 7235 determining labeled "DO" statement (optional statement name, 7236 label and loop control expression if present) 7237 :rtype: 3-tuple of objects 7240 if string[:2].upper() !=
"DO":
7242 line = string[2:].lstrip()
7243 mpat = pattern.label.match(line)
7246 label = mpat.group()
7247 line = line[mpat.end() :].lstrip()
7250 return None,
Label(label),
None 7254 :return: string containing Fortran code for the parsed 7255 labeled "DO" statement 7259 name, label, loop_control = self.items
7261 dostmt =
"DO %s" % (label)
7263 dostmt =
"%s: DO %s" % (label)
7264 if loop_control
is not None:
7265 dostmt +=
" %s" % (loop_control)
7268 def get_start_name(self):
7270 :return: optional labeled "DO" statement name 7273 return self.item.name
7275 def get_start_label(self):
7277 :return: label of "DO" statement 7280 return int(self.items[1])
7282 do_construct_name = property(
lambda self: self.items[0])
7283 label = property(
lambda self: self.items[1])
7284 loop_control = property(
lambda self: self.items[2])
7291 <nonlabel-do-stmt> = [ <do-construct-name> : ] DO [ <loop-control> ] 7295 use_names = [
"Do_Construct_Name",
"Loop_Control"]
7300 :param str string: Fortran code to check for a match 7301 :return: code line matching the nonlabeled "DO" statement 7304 return WORDClsBase.match(
"DO", Loop_Control, string)
7306 def get_start_name(self):
7308 :return: optional labeled "DO" statement name 7311 return self.item.name
7318 <loop-control> = [ , ] <do-variable> = scalar-int-expr, 7320 [ , <scalar-int-expr> ] 7321 | [ , ] WHILE ( <scalar-logical-expr> ) 7325 use_names = [
"Do_Variable",
"Scalar_Int_Expr",
"Scalar_Logical_Expr"]
7330 :param str string: Fortran code to check for a match 7331 :return: 3-tuple containing strings and instances of the classes 7332 determining loop control (optional comma delimiter, 7333 optional scalar logical expression describing "WHILE" 7334 condition or optional counter expression containing loop 7335 counter and scalar integer expression) 7336 :rtype: 3-tuple of objects or nothing for an "infinite loop" 7339 optional_delim =
None 7341 if string.startswith(
","):
7342 line, repmap = string_replace_map(string[1:].lstrip())
7343 optional_delim =
", " 7345 line, repmap = string_replace_map(string)
7347 if line[:5].upper() ==
"WHILE" and line[5:].lstrip().startswith(
"("):
7348 lbrak = line[5:].lstrip()
7350 if i != -1
and i == len(lbrak) - 1:
7351 scalar_logical_expr = Scalar_Logical_Expr(repmap(lbrak[1:i].strip()))
7352 return scalar_logical_expr,
None, optional_delim
7355 if line.count(
"=") != 1:
7357 var, rhs = line.split(
"=")
7358 rhs = [s.strip()
for s
in rhs.lstrip().split(
",")]
7360 if not 2 <= len(rhs) <= 3:
7364 list(map(Scalar_Int_Expr, list(map(repmap, rhs)))),
7366 return None, counter_expr, optional_delim
7370 :return: parsed representation of loop control construct 7374 scalar_logical_expr, counter_expr, optional_delim = self.items
7377 if scalar_logical_expr
is not None:
7378 loopctrl =
"WHILE (%s)" % scalar_logical_expr
7381 elif counter_expr[0]
is not None and counter_expr[1]
is not None:
7382 loopctrl =
"%s = %s" % (
7384 ", ".join(map(str, counter_expr[1])),
7387 if optional_delim
is not None:
7388 loopctrl = optional_delim + loopctrl
7396 <do-variable> = <scalar-int-variable> 7399 subclass_names = [
"Scalar_Int_Variable"]
7406 <do-block> = [ <execution-part-construct> ]... 7409 subclass_names = [
"Block"]
7411 use_names = [
"Execution_Part_Construct"]
7416 :param str string: Fortran code to check for a match 7417 :return: code block matching the execution part construct within 7421 return BlockBase.match(
None, [Execution_Part_Construct],
None, string)
7428 <end-do> = <end-do-stmt> 7432 subclass_names = [
"End_Do_Stmt",
"Continue_Stmt"]
7439 <end-do-stmt> = END DO [ <do-construct-name> ] 7443 use_names = [
"Do_Construct_Name"]
7448 :param str string: Fortran code to check for a match 7449 :return: code line matching the "END DO" statement 7452 return EndStmtBase.match(
7453 "DO", Do_Construct_Name, string, require_stmt_type=
True 7461 <nonblock-do-stmt> = <action-term-do-construct> 7462 | <outer-shared-do-construct> 7465 subclass_names = [
"Action_Term_Do_Construct",
"Outer_Shared_Do_Construct"]
7471 <action-term-do-construct> = <label-do-stmt> 7473 <do-term-action-stmt> 7476 <action-term-do-construct> = <label-do-stmt> 7477 [ <execution-part-construct> ]... 7478 <do-term-action-stmt> 7482 use_names = [
"Label_Do_Stmt",
"Execution_Part_Construct",
"Do_Term_Action_Stmt"]
7486 return BlockBase.match(
7488 [Execution_Part_Construct],
7489 Do_Term_Action_Stmt,
7492 enable_do_label_construct_hook=
True,
7495 def tofortran(self, tab="", isfix=None):
7497 Converts this node (and all children) into Fortran. 7499 :param str tab: white space to prefix to output. 7500 :param bool isfix: whether or not to generate fixed-format output. 7502 :returns: Fortran code. 7507 start = self.content[0]
7508 end = self.content[-1]
7510 line.append(start.tofortran(tab=tab, isfix=isfix))
7511 for item
in self.content[1:-1]:
7512 line.append(item.tofortran(tab=tab + extra_tab, isfix=isfix))
7513 if isinstance(item, Label_Do_Stmt):
7515 if len(self.content) > 1:
7516 line.append(end.tofortran(tab=tab, isfix=isfix))
7517 return "\n".join(line)
7522 <do-body> = [ <execution-part-construct> ]... 7526 use_names = [
"Execution_Part_Construct"]
7530 return BlockBase.match(
None, [Execution_Part_Construct],
None, string)
7536 <do-term-action-stmt> = <action-stmt> 7540 C824: <do-term-action-stmt> shall not be <continue-stmt>, <goto-stmt>, 7541 <return-stmt>, <stop-stmt>, <exit-stmt>, <cycle-stmt>, 7542 <end-function-stmt>, <end-subroutine-stmt>, <end-program-stmt>, 7543 <arithmetic-if-stmt> 7546 subclass_names = [
"Action_Stmt_C824"]
7551 <outer-shared-do-construct> = <label-do-stmt> 7553 <shared-term-do-construct> 7557 use_names = [
"Label_Do_Stmt",
"Do_Body",
"Shared_Term_Do_Construct"]
7562 for cls
in [Label_Do_Stmt, Do_Body, Shared_Term_Do_Construct]:
7572 <shared-term-do-construct> = <outer-shared-do-construct> 7573 | <inner-shared-do-construct> 7576 subclass_names = [
"Outer_Shared_Do_Construct",
"Inner_Shared_Do_Construct"]
7581 <inner-shared-do-construct> = <label-do-stmt> 7583 <do-term-shared-stmt> 7587 use_names = [
"Label_Do_Stmt",
"Do_Body",
"Do_Term_Shared_Stmt"]
7592 for cls
in [Label_Do_Stmt, Do_Body, Do_Term_Shared_Stmt]:
7602 <do-term-shared-stmt> = <action-stmt> 7603 C826: see C824 above. 7606 subclass_names = [
"Action_Stmt"]
7611 <cycle-stmt> = CYCLE [ <do-construct-name> ] 7615 use_names = [
"Do_Construct_Name"]
7619 return WORDClsBase.match(
"CYCLE", Do_Construct_Name, string)
7624 <exit-stmt> = EXIT [ <do-construct-name> ] 7628 use_names = [
"Do_Construct_Name"]
7632 return WORDClsBase.match(
"EXIT", Do_Construct_Name, string)
7637 <goto-stmt> = GO TO <label> 7641 use_names = [
"Label"]
7645 if string[:2].upper() !=
"GO":
7647 line = string[2:].lstrip()
7648 if line[:2].upper() !=
"TO":
7650 return (
Label(line[2:].lstrip()),)
7653 return "GO TO %s" % (self.items[0])
7658 <computed-goto-stmt> = GO TO ( <label-list> ) [ , ] <scalar-int-expr> 7662 use_names = [
"Label_List",
"Scalar_Int_Expr"]
7666 if string[:2].upper() !=
"GO":
7668 line = string[2:].lstrip()
7669 if line[:2].upper() !=
"TO":
7671 line = line[2:].lstrip()
7672 if not line.startswith(
"("):
7677 lst = line[1:i].strip()
7680 line = line[i + 1 :].lstrip()
7681 if line.startswith(
","):
7682 line = line[1:].lstrip()
7685 return Label_List(lst), Scalar_Int_Expr(line)
7688 return "GO TO (%s), %s" % self.items
7693 <arithmetic-if-stmt> = IF ( <scalar-numeric-expr> ) <label> , 7698 use_names = [
"Scalar_Numeric_Expr",
"Label"]
7702 if string[:2].upper() !=
"IF":
7704 line = string[2:].lstrip()
7705 if not line.startswith(
"("):
7710 labels = line[i + 1 :].lstrip().split(
",")
7711 if len(labels) != 3:
7713 labels = [
Label(l.strip())
for l
in labels]
7714 return (Scalar_Numeric_Expr(line[1:i].strip()),) + tuple(labels)
7717 return "IF (%s) %s, %s, %s" % self.items
7722 <continue-stmt> = CONTINUE 7729 return STRINGBase.match(
"CONTINUE", string)
7731 def get_end_label(self):
7732 return self.item.label
7737 <stop-stmt> = STOP [ <stop-code> ] 7741 use_names = [
"Stop_Code"]
7745 return WORDClsBase.match(
"STOP", Stop_Code, string)
7750 <stop-code> = <scalar-char-constant> 7751 | <digit> [ <digit> [ <digit> [ <digit> [ <digit> ] ] ] ] 7754 subclass_names = [
"Scalar_Char_Constant"]
7758 return StringBase.match(pattern.abs_label, string)
7768 <io-unit> = <file-unit-number> 7770 | <internal-file-variable> 7773 subclass_names = [
"File_Unit_Number",
"Internal_File_Variable"]
7777 return StringBase.match(
"*", string)
7782 <file-unit-number> = <scalar-int-expr> 7785 subclass_names = [
"Scalar_Int_Expr"]
7790 <internal-file-variable> = <char-variable> 7791 C901: <char-variable> shall not be an array section with a 7795 subclass_names = [
"Char_Variable"]
7800 <open-stmt> = OPEN ( <connect-spec-list> ) 7804 use_names = [
"Connect_Spec_List"]
7810 return CALLBase.match(
"OPEN", Connect_Spec_List, string, require_rhs=
True)
7816 <connect-spec> = [ UNIT = ] <file-unit-number> 7817 | ACCESS = <scalar-default-char-expr> 7818 | ACTION = <scalar-default-char-expr> 7819 | ASYNCHRONOUS = <scalar-default-char-expr> 7820 | BLANK = <scalar-default-char-expr> 7821 | DECIMAL = <scalar-default-char-expr> 7822 | DELIM = <scalar-default-char-expr> 7823 | ENCODING = <scalar-default-char-expr> 7825 | FILE = <file-name-expr> 7826 | FORM = <scalar-default-char-expr> 7827 | IOMSG = <iomsg-variable> 7828 | IOSTAT = <scalar-int-variable> 7829 | PAD = <scalar-default-char-expr> 7830 | POSITION = <scalar-default-char-expr> 7831 | RECL = <scalar-int-expr> 7832 | ROUND = <scalar-default-char-expr> 7833 | SIGN = <scalar-default-char-expr> 7834 | STATUS = <scalar-default-char-expr> 7840 "Scalar_Default_Char_Expr",
7845 "Scalar_Int_Variable",
7851 :param str string: Fortran code to check for a match 7852 :return: 2-tuple containing the keyword and value or None if the 7853 supplied string is not a match 7854 :rtype: 2-tuple containing keyword (e.g. "UNIT") and associated value 7856 if "=" not in string:
7860 for (keyword, value)
in [
7877 Scalar_Default_Char_Expr,
7880 (
"FILE", File_Name_Expr),
7881 (
"IOSTAT", Scalar_Int_Variable),
7882 (
"IOMSG", Iomsg_Variable),
7883 (
"RECL", Scalar_Int_Expr),
7884 (
"UNIT", File_Unit_Number),
7887 obj = KeywordValueBase.match(keyword, value, string, upper_lhs=
True)
7888 except NoMatchError:
7897 <file-name-expr> = <scalar-default-char-expr> 7900 subclass_names = [
"Scalar_Default_Char_Expr"]
7905 <iomsg-variable> = <scalar-default-char-variable> 7908 subclass_names = [
"Scalar_Default_Char_Variable"]
7913 <close-stmt> = CLOSE ( <close-spec-list> ) 7917 use_names = [
"Close_Spec_List"]
7921 return CALLBase.match(
"CLOSE", Close_Spec_List, string, require_rhs=
True)
7926 <close-spec> = [ UNIT = ] <file-unit-number> 7927 | IOSTAT = <scalar-int-variable> 7928 | IOMSG = <iomsg-variable> 7930 | STATUS = <scalar-default-char-expr> 7936 "Scalar_Default_Char_Expr",
7939 "Scalar_Int_Variable",
7946 (
"IOSTAT", Scalar_Int_Variable),
7947 (
"IOMSG", Iomsg_Variable),
7948 (
"STATUS", Scalar_Default_Char_Expr),
7949 (
"UNIT", File_Unit_Number),
7952 obj = KeywordValueBase.match(k, v, string, upper_lhs=
True)
7953 except NoMatchError:
7963 <read-stmt> = READ ( <io-control-spec-list> ) [ <input-item-list> ] 7964 | READ <format> [ , <input-item-list> ] 7968 items : (Io_Control_Spec_List, Format, Input_Item_List) 7972 use_names = [
"Io_Control_Spec_List",
"Input_Item_List",
"Format"]
7976 if string[:4].upper() !=
"READ":
7978 line = string[4:].lstrip()
7979 if line.startswith(
"("):
7980 line, repmap = string_replace_map(line)
7981 idx = line.find(
")")
7984 trimline = line[1:idx].strip()
7987 if idx == len(line) - 1:
7992 Input_Item_List(repmap(line[idx + 1 :].lstrip())),
7996 char = line[0].upper()
7999 if "A" <= char <=
"Z" or char ==
"_":
8001 line, repmap = string_replace_map(line.lstrip())
8004 idx = line.find(
",")
8007 trimline = repmap(line[idx + 1 :].lstrip())
8010 return (
None,
Format(repmap(line[:idx].rstrip())), Output_Item_List(trimline))
8013 if self.items[0]
is not None:
8014 assert self.items[1]
is None, repr(self.items)
8015 if self.items[2]
is None:
8016 return "READ(%s)" % (self.items[0])
8017 return "READ(%s) %s" % (self.items[0], self.items[2])
8018 assert self.items[1]
is not None, repr(self.items)
8019 if self.items[2]
is None:
8020 return "READ %s" % (self.items[1])
8021 return "READ %s, %s" % (self.items[1], self.items[2])
8028 Fortran 2003 rule R911 8029 that specifies syntax of a "WRITE" statement. 8031 <write-stmt> = WRITE ( <io-control-spec-list> ) [ <output-item-list> ] 8035 use_names = [
"Io_Control_Spec_List",
"Output_Item_List"]
8040 :param str string: Fortran code to check for a match 8041 :return: 2-tuple containing strings and instances of the classes 8042 describing "WRITE" statement (mandatory IO control 8043 specification list and optional output item list. 8044 :rtype: 2-tuple of objects (1 mandatory and 1 optional) 8046 if string[:5].upper() !=
"WRITE":
8048 line = string[5:].lstrip()
8051 if not line.startswith(
"("):
8053 line, repmap = string_replace_map(line)
8057 tmp = line[1:i].strip()
8061 if i == len(line) - 1:
8066 Output_Item_List(repmap(line[i + 1 :].lstrip())),
8071 :return: parsed representation of a "WRITE" statement 8074 if self.items[1]
is None:
8075 return "WRITE(%s)" % (self.items[0])
8076 return "WRITE(%s) %s" % tuple(self.items)
8082 <print-stmt> = PRINT <format> [ , <output-item-list> ] 8086 items : (Format, Output_Item_List) 8090 use_names = [
"Format",
"Output_Item_List"]
8094 if string[:5].upper() !=
"PRINT":
8100 if "A" <= c <=
"Z" or c ==
"_" or "0" <= c <=
"9":
8102 line, repmap = string_replace_map(line.lstrip())
8105 return Format(repmap(line)),
None 8106 tmp = repmap(line[i + 1 :].lstrip())
8109 return Format(repmap(line[:i].rstrip())), Output_Item_List(tmp)
8112 if self.items[1]
is None:
8113 return "PRINT %s" % (self.items[0])
8114 return "PRINT %s, %s" % tuple(self.items)
8119 Rule 913 - Control information list. 8121 io-control-spec-list is a list of io-control-spec items. 8123 Subject to the following constraints: 8125 C909 No specifier shall appear more than once in a given 8126 io-control-spec-list. 8127 C910 An io-unit shall be specified; if the optional characters UNIT= are 8128 omitted, the io-unit shall be the first item in the 8129 io-control-spec-list. 8130 C911 A DELIM= or SIGN= specifier shall not appear in a read-stmt. 8131 C912 A BLANK=, PAD=, END=, EOR=, or SIZE=specifier shall not appear in a 8133 C913 The label in the ERR=, EOR=, or END= specifier shall be the statement 8134 label of a branch target statement that appears in the same scoping 8135 unit as the data transfer statement. 8136 C914 A namelist-group-name shall be the name of a namelist group. 8137 C915 A namelist-group-name shall not appear if an input-item-list or an 8138 output-item-list appears in the data transfer statement. 8139 C916 An io-control-spec-list shall not contain both a format and a 8140 namelist-group-name. 8141 C917 If format appears without a preceding FMT=, it shall be the second 8142 item in the iocontrol-spec-list and the first item shall be io-unit. 8143 C918 If namelist-group-name appears without a preceding NML=, it shall be 8144 the second item in the io-control-spec-list and the first item shall 8146 C919 If io-unit is not a file-unit-number, the io-control-spec-list shall 8147 not contain a REC= specifier or a POS= specifier. 8148 C920 If the REC= specifier appears, an END= specifier shall not appear, a 8149 namelist-groupname shall not appear, and the format, if any, shall not 8151 C921 An ADVANCE= specifier may appear only in a formatted sequential or 8152 stream input/output statement with explicit format specification 8153 (10.1) whose control information list does not contain an 8154 internal-file-variable as the io-unit. 8155 C922 If an EOR= specifier appears, an ADVANCE= specifier also shall appear. 8156 C923 If a SIZE= specifier appears, an ADVANCE= specifier also shall appear. 8157 C924 The scalar-char-initialization-expr in an ASYNCHRONOUS= specifier 8158 shall be of type default character and shall have the value YES or NO. 8159 C925 An ASYNCHRONOUS= specifier with a value YES shall not appear unless 8160 io-unit is a file-unit-number. 8161 C926 If an ID= specifier appears, an ASYNCHRONOUS= specifier with the value 8162 YES shall also appear. 8163 C927 If a POS= specifier appears, the io-control-spec-list shall not 8164 contain a REC= specifier. 8165 C928 If a DECIMAL=, BLANK=, PAD=, SIGN=, or ROUND= specifier appears, a 8166 format or namelist-group-name shall also appear. 8167 C929 If a DELIM= specifier appears, either format shall be an asterisk or 8168 namelist-group-name shall appear. 8170 TODO #267. Of these constraints, only C910 & C916-918 are currently 8176 use_names = [
"Io_Control_Spec",
"Namelist_Group_Name",
"Format"]
8181 Attempts to match the supplied string with a list of Io_Control_Spec 8182 items. We have to override the base implementation because the first 8183 two items in the list have specific meanings if they are not explictly 8184 named: the first must be the unit number and the second may be either 8185 a format specifier *or* a namelist-group-name. 8187 :param str string: the string that is checked for a match. 8189 :returns: a tuple of Io_Control_Spec objects if the match is \ 8190 successful, None otherwise. 8191 :rtype: tuple of :py:class:`fparser.two.Fortran2003.Io_Control_Spec` \ 8195 line, repmap = string_replace_map(string)
8196 splitted = line.split(
",")
8202 have_unnamed_nml_or_fmt =
False 8203 spec = splitted.pop(0).strip()
8215 io_spec.items = (
None, io_spec.items[1])
8223 return ",", tuple(lst)
8228 spec = splitted.pop(0).strip()
8230 for cls, name
in [(Namelist_Group_Name,
"nml"), (Format,
"fmt")]:
8238 io_spec.items = (
None, io_spec.items[1])
8240 have_unnamed_nml_or_fmt =
True 8242 except NoMatchError:
8245 raise NoMatchError(
"Not an un-named nml-group-name or fmt")
8247 except NoMatchError:
8254 for spec
in splitted:
8255 mapped_spec = repmap(spec.strip())
8258 except NoMatchError:
8266 if spec.children[0] ==
"UNIT":
8268 elif spec.children[0] ==
"NML":
8270 elif spec.children[0] ==
"FMT":
8277 if have_nml
and have_fmt:
8279 if have_unnamed_nml_or_fmt
and (have_nml
or have_fmt):
8282 return ",", tuple(lst)
8287 This class implements *partial* support for Rule 913: 8289 <io-control-spec> is [UNIT = ] <io-unit> 8290 | [ FMT = ] <format> 8291 | [ NML = ] <namelist-group-name> 8292 | ADVANCE = <scalar-default-char-expr> 8293 | ASYNCHRONOUS = <scalar-char-initialization-expr> 8294 | BLANK = <scalar-default-char-expr> 8295 | DECIMAL = <scalar-default-char-expr> 8296 | DELIM = <scalar-default-char-expr> 8300 | ID = <scalar-int-variable> 8301 | IOMSG = <iomsg-variable> 8302 | IOSTAT = <scalar-int-variable> 8303 | PAD = <scalar-default-char-expr> 8304 | POS = <scalar-int-expr> 8305 | REC = <scalar-int-expr> 8306 | ROUND = <scalar-default-char-expr> 8307 | SIGN = <scalar-default-char-expr> 8308 | SIZE = <scalar-int-variable> 8310 The support is partial because this class requires that every spec be 8311 named. The specs that may not be named are explicitly handled in 8312 Io_Control_Spec_List.match(). 8320 "Namelist_Group_Name",
8321 "Scalar_Default_Char_Expr",
8322 "Scalar_Char_Initialization_Expr",
8324 "Scalar_Int_Variable",
8334 (
"NML", Namelist_Group_Name),
8336 [
"ADVANCE",
"BLANK",
"DECIMAL",
"DELIM",
"PAD",
"ROUND",
"SIGN"],
8337 Scalar_Default_Char_Expr,
8339 (
"ASYNCHRONOUS", Scalar_Char_Initialization_Expr),
8340 ([
"END",
"EOR",
"ERR"], Label),
8341 ([
"ID",
"IOSTAT",
"SIZE"], Scalar_Int_Variable),
8342 (
"IOMSG", Iomsg_Variable),
8343 ([
"POS",
"REC"], Scalar_Int_Expr),
8345 obj = KeywordValueBase.match(k, v, string, upper_lhs=
True)
8353 <format> = <default-char-expr> 8358 subclass_names = [
"Label",
"Default_Char_Expr"]
8362 return StringBase.match(
"*", string)
8367 <input-item> = <variable> 8371 subclass_names = [
"Variable",
"Io_Implied_Do"]
8376 <output-item> = <expr> 8380 subclass_names = [
"Expr",
"Io_Implied_Do"]
8385 <io-implied-do> = ( <io-implied-do-object-list> , <io-implied-do-control> ) 8389 use_names = [
"Io_Implied_Do_Object_List",
"Io_Implied_Do_Control"]
8393 if len(string) <= 9
or string[0] !=
"(" or string[-1] !=
")":
8395 line, repmap = string_replace_map(string[1:-1].strip())
8399 j = line[:i].rfind(
",")
8403 Io_Implied_Do_Object_List(repmap(line[:j].rstrip())),
8408 return "(%s, %s)" % (self.items)
8413 <io-implied-do-object> = <input-item> 8417 subclass_names = [
"Input_Item",
"Output_Item"]
8422 <io-implied-do-control> = <do-variable> = <scalar-int-expr> , 8423 <scalar-int-expr> [ , <scalar-int-expr> ] 8427 use_names = [
"Do_Variable",
"Scalar_Int_Expr"]
8431 line, repmap = string_replace_map(string)
8434 v, exprs = line.split(
"=", 1)
8436 exprs = exprs.lstrip().split(
",")
8437 if len(exprs)
not in [2, 3]:
8439 exprs = tuple([Scalar_Int_Expr(repmap(e.strip()))
for e
in exprs])
8441 return (v,) + exprs + (
None,)
8445 if self.items[3]
is not None:
8446 return "%s = %s, %s, %s" % (self.items)
8447 return "%s = %s, %s" % (self.items[:-1])
8452 <dtv-type-spec> = TYPE ( <derived-type-spec> ) 8453 | CLASS ( <derived-type-spec> ) 8457 use_names = [
"Derived_Type_Spec"]
8461 return CALLBase.match(
8462 [
"TYPE",
"CLASS"], Derived_Type_Spec, string, require_rhs=
True 8468 <wait-stmt> = WAIT ( <wait-spec-list> ) 8472 use_names = [
"Wait_Spec_List"]
8476 return CALLBase.match(
"WAIT", Wait_Spec_List, string, require_rhs=
True)
8481 <wait-spec> = [ UNIT = ] <file-unit-number> 8485 | ID = <scalar-int-expr> 8486 | IOMSG = <iomsg-variable> 8487 | IOSTAT = <scalar-int-variable> 8496 "Scalar_Int_Variable",
8502 ([
"END",
"EOR",
"ERR"], Label),
8503 (
"IOSTAT", Scalar_Int_Variable),
8504 (
"IOMSG", Iomsg_Variable),
8505 (
"ID", Scalar_Int_Expr),
8506 (
"UNIT", File_Unit_Number),
8509 obj = KeywordValueBase.match(k, v, string, upper_lhs=
True)
8510 except NoMatchError:
8520 <backspace-stmt> = BACKSPACE <file-unit-number> 8521 | BACKSPACE ( <position-spec-list> ) 8525 items : (File_Unit_Number, Position_Spec_List) 8529 use_names = [
"File_Unit_Number",
"Position_Spec_List"]
8533 if string[:9].upper() !=
"BACKSPACE":
8535 line = string[9:].lstrip()
8536 if line.startswith(
"("):
8537 if not line.endswith(
")"):
8539 return None, Position_Spec_List(line[1:-1].strip())
8543 if self.items[0]
is not None:
8544 assert self.items[1]
is None, repr(self.items)
8545 return "BACKSPACE %s" % (self.items[0])
8546 return "BACKSPACE(%s)" % (self.items[1])
8552 <endfile-stmt> = ENDFILE <file-unit-number> 8553 | ENDFILE ( <position-spec-list> ) 8557 items : (File_Unit_Number, Position_Spec_List) 8561 use_names = [
"File_Unit_Number",
"Position_Spec_List"]
8565 if string[:7].upper() !=
"ENDFILE":
8567 line = string[7:].lstrip()
8568 if line.startswith(
"("):
8569 if not line.endswith(
")"):
8571 return None, Position_Spec_List(line[1:-1].strip())
8575 if self.items[0]
is not None:
8576 assert self.items[1]
is None, repr(self.items)
8577 return "ENDFILE %s" % (self.items[0])
8578 return "ENDFILE(%s)" % (self.items[1])
8584 <rewind-stmt> = REWIND <file-unit-number> 8585 | REWIND ( <position-spec-list> ) 8589 items : (File_Unit_Number, Position_Spec_List) 8593 use_names = [
"File_Unit_Number",
"Position_Spec_List"]
8597 if string[:6].upper() !=
"REWIND":
8599 line = string[6:].lstrip()
8600 if line.startswith(
"("):
8601 if not line.endswith(
")"):
8603 return None, Position_Spec_List(line[1:-1].strip())
8607 if self.items[0]
is not None:
8608 assert self.items[1]
is None, repr(self.items)
8609 return "REWIND %s" % (self.items[0])
8610 return "REWIND(%s)" % (self.items[1])
8615 <position-spec> = [ UNIT = ] <file-unit-number> 8616 | IOMSG = <iomsg-variable> 8617 | IOSTAT = <scalar-int-variable> 8622 use_names = [
"File_Unit_Number",
"Iomsg_Variable",
"Scalar_Int_Variable",
"Label"]
8628 (
"IOSTAT", Scalar_Int_Variable),
8629 (
"IOMSG", Iomsg_Variable),
8630 (
"UNIT", File_Unit_Number),
8633 obj = KeywordValueBase.match(k, v, string, upper_lhs=
True)
8634 except NoMatchError:
8644 <flush-stmt> = FLUSH <file-unit-number> 8645 | FLUSH ( <position-spec-list> ) 8648 items : (File_Unit_Number, Position_Spec_List) 8652 use_names = [
"File_Unit_Number",
"Position_Spec_List"]
8656 if string[:5].upper() !=
"FLUSH":
8658 line = string[5:].lstrip()
8659 if line.startswith(
"("):
8660 if not line.endswith(
")"):
8662 return None, Position_Spec_List(line[1:-1].strip())
8666 if self.items[0]
is not None:
8667 assert self.items[1]
is None, repr(self.items)
8668 return "FLUSH %s" % (self.items[0])
8669 return "FLUSH(%s)" % (self.items[1])
8675 <flush-spec> = [ UNIT = ] <file-unit-number> 8676 | IOMSG = <iomsg-variable> 8677 | IOSTAT = <scalar-int-variable> 8681 items : ({'UNIT', 'IOMSG', 'IOSTAT', 'ERR'}, {File_Unit_Number, 8682 Iomsg_Variable, Scalar_Int_Variable, Label}) 8686 use_names = [
"File_Unit_Number",
"Iomsg_Variable",
"Scalar_Int_Variable",
"Label"]
8692 (
"IOSTAT", Scalar_Int_Variable),
8693 (
"IOMSG", Iomsg_Variable),
8694 (
"UNIT", File_Unit_Number),
8697 obj = KeywordValueBase.match(k, v, string, upper_lhs=
True)
8698 except NoMatchError:
8708 <inquire-stmt> = INQUIRE ( <inquire-spec-list> ) 8709 | INQUIRE ( IOLENGTH = <scalar-int-variable> ) 8713 items : (Inquire_Spec_List, Scalar_Int_Variable, Output_Item_List) 8717 use_names = [
"Inquire_Spec_List",
"Scalar_Int_Variable",
"Output_Item_List"]
8721 if string[:7].upper() !=
"INQUIRE":
8723 line = string[7:].lstrip()
8724 if not line.startswith(
"("):
8726 if line.endswith(
")"):
8727 return Inquire_Spec_List(line[1:-1].strip()),
None,
None 8728 line, repmap = string_replace_map(line)
8732 tmp = repmap(line[1:i])
8733 if tmp[:8].upper() !=
"IOLENGTH":
8735 tmp = tmp[8:].lstrip()
8736 if not tmp.startswith(
"="):
8738 tmp = tmp[1:].lstrip()
8741 Scalar_Int_Variable(tmp),
8742 Output_Item_List(repmap(line[i + 1 :].lstrip())),
8746 if self.items[0]
is None:
8747 assert None not in self.items[1:], repr(self.items)
8748 return "INQUIRE(IOLENGTH=%s) %s" % (self.items[1:])
8749 return "INQUIRE(%s)" % (self.items[0])
8755 <inquire-spec> = [ UNIT = ] <file-unit-number> 8756 | FILE = <file-name-expr> 8757 | ACCESS = <scalar-default-char-variable> 8758 | ACTION = <scalar-default-char-variable> 8759 | ASYNCHRONOUS = <scalar-default-char-variable> 8760 | BLANK = <scalar-default-char-variable> 8761 | DECIMAL = <scalar-default-char-variable> 8762 | DELIM = <scalar-default-char-variable> 8763 | DIRECT = <scalar-default-char-variable> 8764 | ENCODING = <scalar-default-char-variable> 8766 | EXIST = <scalar-default-logical-variable> 8767 | FORM = <scalar-default-char-variable> 8768 | FORMATTED = <scalar-default-char-variable> 8769 | ID = <scalar-int-expr> 8770 | IOMSG = <iomsg-variable> 8771 | IOSTAT = <scalar-int-variable> 8772 | NAME = <scalar-default-char-variable> 8773 | NAMED = <scalar-default-logical-variable> 8774 | NEXTREC = <scalar-int-variable> 8775 | NUMBER = <scalar-int-variable> 8776 | OPENED = <scalar-default-logical-variable> 8777 | PAD = <scalar-default-char-variable> 8778 | PENDING = <scalar-default-logical-variable> 8779 | POS = <scalar-int-variable> 8780 | POSITION = <scalar-default-char-variable> 8781 | READ = <scalar-default-char-variable> 8782 | READWRITE = <scalar-default-char-variable> 8783 | RECL = <scalar-int-variable> 8784 | ROUND = <scalar-default-char-variable> 8785 | SEQUENTIAL = <scalar-default-char-variable> 8786 | SIGN = <scalar-default-char-variable> 8787 | SIZE = <scalar-int-variable> 8788 | STREAM = <scalar-default-char-variable> 8789 | UNFORMATTED = <scalar-default-char-variable> 8790 | WRITE = <scalar-default-char-variable> 8794 items : (str, instance) 8801 "Scalar_Default_Char_Variable",
8802 "Scalar_Default_Logical_Variable",
8803 "Scalar_Int_Variable",
8812 :param str string: The string to check for conformance with an 8814 :return: 2-tuple of name (e.g. "UNIT") and value or None if 8815 string is not a valid Inquire_Spec 8816 :rtype: 2-tuple where first object represents the name and the 8819 if "=" not in string:
8823 for (keyword, value)
in [
8847 Scalar_Default_Char_Variable,
8850 ([
"EXIST",
"NAMED",
"PENDING",
"OPENED"], Scalar_Default_Logical_Variable),
8851 (
"ID", Scalar_Int_Expr),
8853 [
"IOSTAT",
"NEXTREC",
"NUMBER",
"POS",
"RECL",
"SIZE"],
8854 Scalar_Int_Variable,
8856 (
"IOMSG", Iomsg_Variable),
8857 (
"FILE", File_Name_Expr),
8858 (
"UNIT", File_Unit_Number),
8861 obj = KeywordValueBase.match(keyword, value, string, upper_lhs=
True)
8862 except NoMatchError:
8876 <format-stmt> = FORMAT <format-specification> 8880 use_names = [
"Format_Specification"]
8884 return WORDClsBase.match(
8885 "FORMAT", Format_Specification, string, require_cls=
True 8890 """This class replaces the one generated by fparser. This class is 8891 required as support for hollerith strings makes matching more 8897 subclass_names = [
"Format_Item"]
8901 """Implements the matching for a list of format items. 8903 Supporting Hollerith strings makes it very difficult to 8904 correctly split the input string into items a-priori. The 8905 reason for this can be seen in the following example: 8907 `2H,x,e2.2` is `2H,x` and `e2.2` but when split with commas 8908 incorrectly gives `2H`, `x` and `e2.2`. 8910 Further, hollerith strings could also confuse any code that 8911 tried to determine whether code was inside quotes or not. For 8914 `2H"x,2H"x` does not mean that `x,2H` is part of a string. 8916 The solution chosen is to match one item at a time, first 8917 checking for a valid Hollerith string and then checking for 8918 any other valid input. 8920 :param str string: the string to match as a Format List. 8921 :return: None if there is no match or a tuple of size 2 \ 8922 containing a string with a comma followed by a tuple \ 8923 containing a list which itself contains the matched \ 8926 ([:py:class:`fparser.two.Fortran2003.Format_Item`s])) or `NoneType` 8931 current_string = string.lstrip()
8932 if not current_string:
8935 while current_string:
8937 found, index = skip_digits(current_string)
8938 if found
and current_string[index] ==
"/":
8940 current_string = current_string[index + 1 :].lstrip()
8943 if current_string
and current_string[0] ==
",":
8944 current_string = current_string[1:].lstrip()
8949 if current_string[0]
in ":/":
8951 current_string = current_string[index + 1 :].lstrip()
8954 if current_string
and current_string[0] ==
",":
8955 current_string = current_string[1:].lstrip()
8960 my_pattern = Hollerith_Item.match_pattern
8961 match = re.search(my_pattern, current_string)
8964 match_str = match.group(0)
8965 hol_length_str = match_str[:-1]
8966 hol_length = int(hol_length_str)
8967 num_chars = len(match_str) + hol_length
8968 if len(current_string) < num_chars:
8972 current_string = current_string[num_chars:].lstrip()
8974 if current_string[0] ==
",":
8976 current_string = current_string[1:].lstrip()
8977 elif current_string[0] ==
"/":
8981 elif current_string[0] ==
":":
8990 line, repmap = string_replace_map(current_string)
8991 match = re.search(
"[,/:]", line)
8993 item_list.append(
Format_Item(repmap(line[: match.start()])))
8994 current_string = repmap(line[match.start() :])
8995 if match.group() ==
",":
8997 current_string = current_string[1:].lstrip()
9001 return ",", tuple(item_list)
9006 Fortran 2003 rule R1002 9008 format-specification = ( [ format-item-list ] ) 9010 C1002 is implemented in a separate class Format_Item_C1002 9012 C1002 (R1002) The comma used to separate format-items in a 9013 format-item-list may be omitted 9015 (1) Between a P edit descriptor and an immediately following F, E, 9016 EN, ES, D, or G edit descriptor, possibly preceded by a repeat 9019 (2) Before a slash edit descriptor when the optional repeat 9020 specification is not present, 9022 (3) After a slash edit descriptor, or 9024 (4) Before or after a colon edit descriptor. 9029 use_names = [
"Format_Item_List"]
9033 """Implements the matching for a format specification. 9035 :param str string: The string to check for conformance with a \ 9036 format specification. 9037 :return: `None` if there is no match, otherwise a tuple of \ 9038 size three, the first entry being a string containing a left \ 9039 bracket and the third being a string containing a right \ 9040 bracket. The second entry is either a Format_Item or a \ 9042 :rtype: `NoneType` or ( `str`, \ 9043 :py:class:`fparser.two.Fortran2003.Format_Item` or \ 9044 :py:class:`fparser.two.Fortran2003.Format_Item_List`, `str` ) 9047 return BracketBase.match(
"()", Format_Item_List, string, require_cls=
False)
9050 def skip_digits(string):
9051 """Skips over any potential digits (including spaces) to the next 9052 non-digit character and return its index. If no such character is 9053 found or if the first character in the string is not a digit then 9054 specify that the skip has failed. 9056 :param str string: The string to search 9057 :returns: a 2-tuple with the first entry indicating if a valid \ 9058 character has been found and the second entry indicating the index \ 9059 of this character in the 'string' argument. 9065 for index, char
in enumerate(string):
9066 if not (char.isdigit()
or char ==
" "):
9075 Fortran 2003 constraint C1002 9077 format-item-c1002 is kP [,] (F|D)w.d | (E|EN|ES|G)w.d[Ee] 9078 or [r]/ [,] format-item 9079 or : [,] format-item 9080 or format-item [,] / [[,] format-item] 9081 or format-item [,] : [[,] format-item] 9083 C1002 (R1002) The comma used to separate format-items in a 9084 format-item-list may be omitted 9086 (1) Between a P edit descriptor and an immediately following F, E, 9087 EN, ES, D, or G edit descriptor, possibly preceded by a repeat 9090 (2) Before a slash edit descriptor when the optional repeat 9091 specification is not present (10.7.2), 9093 (3) After a slash edit descriptor, or 9095 (4) Before or after a colon edit descriptor. 9100 use_names = [
"K",
"W",
"D",
"E",
"Format_Item",
"R"] 9104 """Implements the matching for the C1002 Format Item constraint. The 9105 constraints specify certain combinations of format items that 9106 do not need a comma to separate them. Rather than sorting this 9107 out when parsing the list, it was decided to treat these 9108 separately and match them in this class. As a result the 9109 generated class hierarchy is a little more complicated. 9111 :param str string: The string to check for conformance with a \ 9112 C1002 format item constraint. 9113 :return: `None` if there is no match, otherwise a tuple of \ 9114 size 2 containing a mixture of Control_Edit_Descriptor and \ 9115 Format_Item classes depending on what has been matched. 9117 :rtype: `NoneType` or ( \ 9118 :py:class:`fparser.two.Control_Edit_Desc`, \ 9119 :py:class:`fparser.two.Format_Item` ) or \ 9120 (:py:class:`fparser.two.Format_Item`, \ 9121 :py:class:`fparser.two.Control_Edit_Desc`) or \ 9122 (:py:class:`fparser.two.Format_Item`, \ 9123 :py:class:`fparser.two.Format_Item`) 9128 strip_string = string.strip()
9129 if len(strip_string) <= 1:
9131 if strip_string[0]
in ":/":
9138 if strip_string[-1]
in ":/":
9151 found, index = skip_digits(strip_string)
9155 result = strip_string[index].upper()
9174 rhs =
Format_Item(strip_string[index + 1 :].lstrip())
9175 if not isinstance(rhs, Format_Item):
9178 descriptor_object = rhs.items[1]
9180 descriptor_object, (Data_Edit_Desc, Data_Edit_Desc_C1002)
9183 edit_descriptor = descriptor_object.items[0]
9184 if edit_descriptor.upper()
not in [
"F",
"E",
"EN",
"ES",
"D",
"G"]:
9190 line, repmap = string_replace_map(strip_string)
9199 left, right = line.split(option, 1)
9207 :return: Parsed representation of two format items 9210 :raises InternalError: if the length of the internal items \ 9212 :raises InternalError: if the first entry of the internal \ 9213 items list has no content. 9214 :raises InternalError: if the second entry of the internal \ 9215 items list has no content. 9218 if len(self.items) != 2:
9219 raise InternalError(
9220 "Class Format_Item_C1002 method tostr(): internal items list " 9221 "should be length 2 but found '{0}'".format(len(self.items))
9223 if not self.items[0]:
9224 raise InternalError(
9225 "Class Format_Item_C1002 method tostr() items entry 0 should " 9226 "contain a format items object but it is empty or None" 9228 if not self.items[1]:
9229 raise InternalError(
9230 "Class Format_Item_C1002 method tostr() items entry 1 should " 9231 "contain a format items object but it is empty or None" 9233 return "{0}, {1}".format(self.items[0], self.items[1])
9237 """Hollerith strings take the form `nHx`, where `n` is an integer and 9238 `x` is a sequence of characters of length `n`. 9240 Note, the Hollerith format was deprecated in Fortran77 and removed in 9241 Fortran95. However, Fortran compilers still support it. See, for example 9242 https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gfortran/ 9243 Hollerith-constants-support.html 9249 match_pattern =
"^[1-9][0-9 ]*[hH]" 9253 """Implements the matching for a Hollerith string. 9255 :param str string: The string to check for conformance with a \ 9257 :return: String containing the contents of the Hollerith \ 9264 if "hollerith" not in EXTENSIONS:
9270 strip_string = string.lstrip()
9271 match = re.search(Hollerith_Item.match_pattern, strip_string)
9275 match_str = match.group(0)
9276 hol_length_str = match_str[:-1].replace(
" ",
"")
9277 hol_length = int(hol_length_str)
9278 num_chars = len(match_str) + hol_length
9279 if len(strip_string) < num_chars:
9282 if len(strip_string) > num_chars:
9284 if strip_string[num_chars:].strip():
9287 return (strip_string[len(match_str) : num_chars],)
9291 :return: Parsed representation of a Hollerith String. 9294 :raises InternalError: if the length of the internal items \ 9296 :raises InternalError: if the first entry of the internal \ 9297 items list has no content. 9300 if len(self.items) != 1:
9301 raise InternalError(
9302 "Class Hollerith_Item method tostr(): internal items list " 9303 "should be of length 1 but found '{0}'".format(len(self.items))
9305 if not self.items[0]:
9306 raise InternalError(
9307 "Class Hollerith_Item method tostr() items entry 0 should be " 9308 "a valid Hollerith string but it is empty or None" 9310 return "{0}H{1}".format(len(self.items[0]), self.items[0])
9315 Fortran 2003 rule R1003 9316 format-item is [ r ] data-edit-desc 9317 or control-edit-desc 9318 or char-string-edit-desc 9319 or [ r ] ( format-item-list ) 9320 or format-item-c1002 9327 "Control_Edit_Desc",
9328 "Char_String_Edit_Desc",
9329 "Format_Item_C1002",
9331 use_names = [
"R", "Format_Item_List", "Data_Edit_Desc"]
9335 """Implements the matching of a Format Item. This method matches '[ r 9336 ] data-edit-desc' and '[ r ] ( format-item-list )'. The 9337 remaining options are matched via subclasses specified in the 9338 subclass_names variable. 9340 :param str string: A string or the Fortran reader containing the \ 9341 line of code that we are trying to match. 9342 :return: `None` if there is no match or a `tuple` of size 2 \ 9343 containing an instance of the R class followed by an \ 9344 instance of either the Format_Item_List or the Data_Edit_Desc \ 9346 :rtype: `None` or ( :py:class:`fparser.two.Fortran2003.R`, \ 9347 :py:class:`fparser.two.Fortran2003.Format_Item_List` or \ 9348 :py:class:`fparser.two.Fortran2003.Data_Edit_Desc`) 9353 strip_string = string.strip()
9354 if not strip_string:
9358 found, index = skip_digits(strip_string)
9360 my_string = strip_string
9364 rpart =
R(strip_string[:index])
9365 my_string = strip_string[index:].lstrip()
9368 if my_string[0] ==
"(" and my_string[-1] ==
")":
9379 :return: Parsed representation of a Format Item. 9382 :raises InternalError: if the length of the internal items \ 9384 :raises InternalError: if the first entry of the internal \ 9385 items list has no content. 9388 if len(self.items) != 2:
9389 raise InternalError(
9390 "Class Format_Item method tostr(): internal items list " 9391 "should be of length 2 but found '{0}'".format(len(self.items))
9393 if not self.items[1]:
9394 raise InternalError(
9395 "Class Format_Item method tostr(): items list second entry " 9396 "should be a valid descriptor but it is empty or None" 9398 rpart = self.items[0]
9399 rest = self.items[1]
9401 rpart_str = rpart
if rpart
else "" 9402 if isinstance(rest, (Data_Edit_Desc, Data_Edit_Desc_C1002)):
9403 return "{0}{1}".format(rpart_str, rest)
9404 return "{0}({1})".format(rpart_str, rest)
9410 <r> = <int-literal-constant> 9414 C1003, C1004: <r> shall be positive and without kind parameter specified. 9417 subclass_names = [
"Digit_String"]
9421 """This class helps implement the matching for the first part of the 9422 Fortran 2003 Constraint C1002 which constrains rule R1002. In 9423 particular it matches with the subset of edit descriptors that can 9424 follow a P edit descriptor without needing a comma, see below: 9426 C1002 (applied to R1002) The comma used to separate format-items 9427 in a format-item-list may be omitted 9429 (1) Between a P edit descriptor and an immediately following F, E, 9430 EN, ES, D, or G edit descriptor, possibly preceded by a 9433 [Remaining constraint clauses ommitted as they are not relevant 9436 data-edit-desc is F w . d 9446 use_names = [
"W",
"D",
"E"]
9450 """Check whether the input matches the rule. 9452 param str string: contains the Fortran that we are trying to \ 9454 :return: `None` if there is no match, otherwise a `tuple` of \ 9455 size 4, the first entry containing a string with one of ['F', \ 9456 'E', 'EN', 'ES', 'G', 'D'], the second entry containing a W \ 9457 class instance, the third entry containing D class instance \ 9458 and the fourth entry containing either None or an E class \ 9460 :rtype: `NoneType`, (`str`, :py:class:`fparser.two.W`, \ 9461 :py:class:`fparser.two.D`, `NoneType`) or, (`str`, \ 9462 :py:class:`fparser.two.W`, :py:class:`fparser.two.D`, \ 9463 :py:class:`fparser.two.E`) 9468 strip_string = string.strip()
9469 if not strip_string:
9471 char = strip_string[0].upper()
9472 if char
in [
"F",
"D"]:
9474 my_str = strip_string[1:].lstrip().upper()
9476 left, right = my_str.split(
".", 1)
9477 left = left.rstrip()
9478 right = right.lstrip()
9479 return char,
W(left),
D(right),
None 9481 if char
in [
"E",
"G"]:
9484 my_str = strip_string[1:].lstrip().upper()
9486 if char ==
"E" and char2
in [
"S",
"N"]:
9487 my_str = my_str[1:].lstrip()
9490 if "." not in my_str:
9492 left, right = my_str.split(
".", 1)
9493 left = left.rstrip()
9494 right = right.lstrip()
9497 if right.count(
"E") >= 1:
9498 middle, right = right.split(
"E", 1)
9499 middle = middle.rstrip()
9500 right = right.lstrip()
9501 return char + char2,
W(left),
D(middle),
E(right)
9502 return char + char2,
W(left),
D(right),
None 9508 :return: parsed representation of a Data Edit Descriptor \ 9509 conforming to constraint C1002. 9512 :raises InternalError: if the length of the internal items \ 9514 :raises InternalError: if the first, second or third entry of \ 9515 the internal items list has no content. 9516 :raises InternalError: if the value of the first entry is \ 9518 :raises InternalError: if the value of the first entry is 'F' \ 9519 or 'D' and the fourth entry has content. 9520 :raises InternalError: if the value of the first entry is 'E', \ 9521 'EN', 'ES' or 'G' and the fourth entry is empty or None. 9524 if not len(self.items) == 4:
9525 raise InternalError(
9526 "Class Data_Edit_Desc_C1002 method tostr() has '{0}' items, " 9527 "but expecting 4.".format(len(self.items))
9529 if not self.items[0]:
9530 raise InternalError(
9531 "items[0] in Class Data_Edit_Desc_C1002 method tostr() " 9532 "should be a descriptor name but is empty or None" 9534 if not self.items[1]:
9535 raise InternalError(
9536 "items[1] in Class Data_Edit_Desc_C1002 method tostr() " 9537 "should be the w value but is empty or None" 9539 if not self.items[2]:
9540 raise InternalError(
9541 "items[2] in Class Data_Edit_Desc_C1002 method tostr() " 9542 "should be the m value but is empty or None" 9544 descriptor_name = self.items[0]
9545 if descriptor_name
in [
"F",
"D"]:
9547 raise InternalError(
9548 "items[3] in Class Data_Edit_Desc_C1002 method tostr() " 9549 "has an exponent value '{0}' but this is not allowed for " 9550 "'F' and 'D' descriptors and should therefore be " 9551 "None".format(self.items[3])
9553 return "{0}{1}.{2}".format(descriptor_name, self.items[1], self.items[2])
9554 elif descriptor_name
in [
"E",
"EN",
"ES",
"G"]:
9555 if self.items[3]
is None:
9556 return "{0}{1}.{2}".format(
9557 descriptor_name, self.items[1], self.items[2]
9559 return "{0}{1}.{2}E{3}".format(
9560 descriptor_name, self.items[1], self.items[2], self.items[3]
9562 raise InternalError(
9563 "Unexpected descriptor name '{0}' in Class Data_Edit_Desc_C1002 " 9564 "method tostr()".format(descriptor_name)
9571 <data-edit-desc> = I <w> [ . <m> ] 9577 | DT [ <char-literal-constant> ] [ ( <v-list> ) ] 9578 | <data-edit-desc-c1002> 9581 subclass_names = [
"Data_Edit_Desc_C1002"]
9582 use_names = [
"W",
"M",
"Char_Literal_Constant",
"V_List"]
9586 c = string[0].upper()
9587 if c
in [
"I",
"B",
"O",
"Z"]:
9588 line = string[1:].lstrip()
9590 i1, i2 = line.split(
".", 1)
9593 return c,
W(i1),
M(i2),
None, Int_Literal_Constant
9594 return c,
W(line),
None,
None 9596 line = string[1:].lstrip()
9599 return c,
W(line),
None,
None 9601 line = string[1:].lstrip()
9603 return c,
None,
None,
None 9604 return c,
W(line),
None,
None 9605 c = string[:2].upper()
9609 line = string[2:].lstrip()
9611 return c,
None,
None,
None 9613 if line.endswith(
")"):
9617 tmp = line[i + 1 : -1].strip()
9621 line = line[:i].rstrip()
9623 return c,
None, lst,
None 9629 if c
in [
"I",
"B",
"O",
"Z",
"A",
"L"]:
9630 if self.items[2]
is None:
9631 if self.items[1]
is None:
9633 return "%s%s" % (c, self.items[1])
9634 return "%s%s.%s" % (c, self.items[1], self.items[2])
9636 if self.items[1]
is None:
9637 if self.items[2]
is None:
9640 return "%s(%s)" % (c, self.items[2])
9642 if self.items[2]
is None:
9643 return "%s%s" % (c, self.items[1])
9645 return "%s%s(%s)" % (c, self.items[1], self.items[2])
9646 raise NotImplementedError(repr(c))
9652 <w> = <int-literal-constant> == <digit-string> 9656 C1006, C1007: <w> is zero or postive and without kind parameters. 9659 subclass_names = [
"Digit_String"]
9665 <m> = <int-literal-constant> 9669 C1007: <w> is without kind parameters. 9672 subclass_names = [
"Int_Literal_Constant"]
9678 <d> = <int-literal-constant> 9682 C1007: <d> is without kind parameters. 9685 subclass_names = [
"Int_Literal_Constant"]
9691 <e> = <int-literal-constant> 9695 C1005, C1007: <e> is postive and without kind parameters. 9698 subclass_names = [
"Digit_String"]
9704 <v> = <signed-int-literal-constant> 9708 C1007: <w> is without kind parameters. 9711 subclass_names = [
"Signed_Int_Literal_Constant"]
9716 Fortran 2003 rule R1011 9718 control-edit-desc is position-edit-desc 9723 or blank-interp-edit-desc 9725 or decimal-edit-desc 9728 '$' is used to suppress the carriage return on output. Note that 9729 this is an extension to the Fortran standard. 9734 "Position_Edit_Desc",
9736 "Blank_Interp_Edit_Desc",
9738 "Decimal_Edit_Desc",
9740 use_names = [
"R", "K"]
9744 """Check whether the input matches the rule. 9746 param str string: contains the Fortran that we are trying to \ 9748 :return: `None` if there is no match, otherwise a `tuple` of \ 9749 size 2 containing, None and a string with one of '/', ':', or \ 9750 '$', an R class and a string containing '/' or a K class and a \ 9751 string containing 'P'. 9752 :rtype: `NoneType`, (`NoneType`, `str`), \ 9753 (:py:class:`fparser.two.Fortran2003.R`, `str`), or \ 9754 (:py:class:`fparser.two.Fortran2003.K`, `str`) 9759 strip_string = string.strip()
9760 if not strip_string:
9762 if len(strip_string) == 1
and strip_string
in "/:$":
9765 if strip_string ==
"$" and "dollar-descriptor" not in EXTENSIONS:
9767 return None, strip_string
9768 if strip_string[-1] ==
"/":
9769 return R(strip_string[:-1].rstrip()),
"/" 9770 if strip_string[-1].upper() ==
"P":
9771 return K(strip_string[:-1].rstrip()),
"P" 9776 :return: parsed representation of a Control Edit Descriptor 9778 :raises InternalError: if the length of the internal items \ 9780 :raises InternalError: if the second entry of the internal \ 9781 items list has no content. 9784 if len(self.items) != 2:
9785 raise InternalError(
9786 "Class Control_Edit_Desc method tostr() has '{0}' items, " 9787 "but expecting 2.".format(len(self.items))
9789 if not self.items[1]:
9790 raise InternalError(
9791 "items[1] in Class Control_Edit_Desc method tostr() should " 9792 "be an edit descriptor name but is empty or None" 9794 if self.items[0]
is not None:
9795 return "{0}{1}".format(self.items[0], self.items[1])
9796 return "{0}".format(self.items[1])
9802 <k> = <signed-int-literal-constant> 9806 C1009: <k> is without kind parameters. 9809 subclass_names = [
"Signed_Int_Literal_Constant"]
9814 Fortran 2003 rule R1013 9816 position-edit-desc is T n 9821 where n is a positive integer. 9823 If the extensions list includes the string 'x-format' then 'X' 9824 without a preceeding integer is also matched. This is a common 9825 extension in Fortran compilers. 9834 """Check whether the input matches the rule. 9836 param str string: contains the Fortran that we are trying to \ 9838 :return: `None` if there is no match, otherwise a `tuple` of \ 9839 size 2 either containing a `string` which is one of "T", "TL" \ 9840 or "TR", followed by an `N` class, or containing an `N` class, \ 9841 or `None`, followed by an "X". 9842 :rtype: `NoneType`, (`str`, \ 9843 :py:class:`fparser.two.Fortran2003.N`), \ 9844 (:py:class:`fparser.two.Fortran2003.N`, `str`) or (`NoneType`, \ 9850 strip_string_upper = string.strip().upper()
9851 if not strip_string_upper:
9854 if strip_string_upper[0] ==
"T":
9855 if not len(strip_string_upper) > 1:
9858 if strip_string_upper[1]
in "LR":
9861 start = strip_string_upper[:2]
9862 rest = strip_string_upper[2:].lstrip()
9865 start = strip_string_upper[0]
9866 rest = strip_string_upper[1:].lstrip()
9868 number_obj =
N(rest)
9869 return start, number_obj
9870 if strip_string_upper[-1] ==
"X":
9874 if "x-format" in EXTENSIONS
and len(strip_string_upper) == 1:
9880 number_obj =
N(strip_string_upper[:-1].rstrip())
9881 return number_obj,
"X" 9887 :return: parsed representation of a Position Edit Descriptor 9889 :raises InternalError: if the length of the internal items \ 9891 :raises InternalError: if the second entry of the internal \ 9892 items list has no content. 9895 if not len(self.items) == 2:
9896 raise InternalError(
9897 "Class Position_Edit_Desc method tostr() has '{0}' items, " 9898 "but expecting 2.".format(len(self.items))
9900 if not self.items[1]:
9901 raise InternalError(
9902 "items[1] in Class Position_Edit_Desc method tostr() is " 9906 return "{0}{1}".format(self.items[0], self.items[1])
9908 return "{0}".format(self.items[1])
9914 <n> = <int-literal-constant> == <digit-string> 9916 C1010, C1011: <n> is positive and without kind parameter. 9919 subclass_names = [
"Digit_String"]
9924 <sign-edit-desc> = SS 9933 return STRINGBase.match([
"SS",
"SP",
"S"], string)
9938 <blank-interp-edit-desc> = BN 9946 return STRINGBase.match([
"BN",
"BZ"], string)
9951 <round-edit-desc> = RU 9964 return STRINGBase.match([
"RU",
"RD",
"RZ",
"RN",
"RC",
"RP"], string)
9969 <decimal-edit-desc> = DC 9977 return STRINGBase.match([
"DC",
"DP"], string)
9982 <char-string-edit-desc> = <char-literal-constant> 9985 subclass_names = [
"Char_Literal_Constant"]
9994 """Fortran 2003 rule R1101 9996 This class does not cater for the case where there is no 9997 program-stmt. The separate Main_Program0() class matches this 9998 situation. See Class Program() method match() for how this is 10001 main-program is program-stmt 10002 [ specification-part ] 10004 [ internal-subprogram-part ] 10007 C1101 In a main-program, the execution-part shall not contain a 10008 RETURN statement or an ENTRY statement. This is currently not 10009 checked, see issue #140. 10011 C1102 The program-name may be included in the end-program-stmt 10012 only if the optional program-stmt is used and, if included, shall 10013 be identical to the program-name specified in the program-stmt. 10015 C1103 An automatic object shall not appear in the 10016 specification-part (R204) of a main program. This is currently not 10017 checked, see issue #140. 10021 subclass_names = []
10024 "Specification_Part",
10026 "Internal_Subprogram_Part",
10027 "End_Program_Stmt",
10032 """Implements the matching of a main program which has a Program 10033 statement. See class Main_Program0 for matching without a 10034 Program Statement. Matching uses `BlockBase` as it conforms to 10035 the start/end with optional content pattern. `match_names` is 10036 set to `True` so that different names e.g. `program x` and 10037 `end program y` will not match. 10039 :param reader: the Fortran reader containing the line(s) of \ 10040 code that we are trying to match 10041 :type reader: :py:class:`fparser.common.readfortran.FortranReaderBase` 10043 :returns: `None` if there is not match or, if there is a match, \ 10044 a `tuple` containing a single `list`, with minimum \ 10045 size 2 and maximum size 5, which contains instances \ 10046 of the classes that have matched. The first entry in \ 10047 the list will be a `Program_Stmt` and the last entry \ 10048 in the list will be an `End_Program_Stmt`. In-between \ 10049 these two instances will be an optional \ 10050 `Specification_Part` followed by an optional \ 10051 `Execution_Part` followed by an optional \ 10052 `Internal_Subprogram_Part`. 10053 :rtype: `NoneType` or \ 10054 ([:py:class:`fparser.two.Fortran2003.Program_Stmt`, \ 10056 :py:class:`fparser.two.Fortran2003.Specification_Part`, \ 10058 :py:class:`fparser.two.Fortran2003.Execution_Part`, \ 10060 :py:class:`fparser.two.Fortran2003.Internal_Subprogram_Part`, \ 10061 :py:class:`fparser.two.Fortran2003.End_Program_Stmt`]) 10064 return BlockBase.match(
10066 [Specification_Part, Execution_Part, Internal_Subprogram_Part],
10076 Rule 1101 specifies that the opening 'program-stmt' is optional. This 10077 class handles the special case when it is not supplied and thus 10081 [ <specification-part> ] 10082 [ <execution-part> ] 10083 [ <internal-subprogram-part> ] 10086 C1102 The program-name may be included in the end-program-stmt 10087 only if the optional program-stmt is used and, if included, shall 10088 be identical to the program-name specified in the 10091 In this class an end program name is not allowed due to C1102. 10095 subclass_names = []
10098 "Specification_Part",
10100 "Internal_Subprogram_Part",
10101 "End_Program_Stmt",
10107 Attempts to match the content in the reader with a program that is 10108 missing the optional opening program-stmt (R1101). If the match 10109 is successful, a symbol table named "fparser2:main_program" is 10112 :param reader: Content to check for match 10113 :type reader: str or instance of :py:class:`FortranReaderBase` 10115 :return: 2-tuple of (list of matched classes, None) or None \ 10116 if no match is found. 10117 :rtype: (list of matched classes, None) or NoneType 10123 table_name =
"fparser2:main_program" 10124 SYMBOL_TABLES.enter_scope(table_name)
10126 result = BlockBase.match(
10128 [Specification_Part, Execution_Part, Internal_Subprogram_Part],
10133 SYMBOL_TABLES.exit_scope()
10136 SYMBOL_TABLES.remove(table_name)
10143 Fortran 2003 rule R1102 10144 program-stmt is PROGRAM program-name 10148 subclass_names = []
10149 use_names = [
"Program_Name"]
10153 """Implements the matching for a Program Statement. Makes use of 10154 `WORDClsBase`, as the required match is a string followed by a 10155 class. The class is made compulsory for the match as the 10156 PROGRAM keyword is not valid without a program name. 10158 :param str string: Fortran code to check for a match 10159 :returns: `None` if there is no match or, if there is a match, \ 10160 a tuple of size 2 with the first entry being the \ 10161 string 'PROGRAM' and the second entry being a `Name` \ 10162 class containing the name of the program. 10163 :rtype: `NoneType` or ( `str`, \ 10164 :py:class:`fparser.two.Fortran2003.Name` ) 10167 return WORDClsBase.match(
"PROGRAM", Program_Name, string, require_cls=
True)
10169 def get_name(self):
10170 """Provides the program name as an instance of the `Name` class. 10172 :returns: the program name as a :py:class:`Name` class 10173 :rtype: :py:class:`Name` 10176 return self.items[1]
10178 def get_start_name(self):
10179 """Provides the program name as a string. This is used for matching 10180 with the equivalent `end program` name if there is one. 10182 :returns: the program name as a string 10186 return self.get_name().string
10191 <end-program-stmt> = END [ PROGRAM [ <program-name> ] ] 10194 subclass_names = []
10195 use_names = [
"Program_Name"]
10199 return EndStmtBase.match(
"PROGRAM", Program_Name, string)
10204 <module> = <module-stmt> 10205 [ <specification-part> ] 10206 [ <module-subprogram-part> ] 10210 subclass_names = []
10213 "Specification_Part",
10214 "Module_Subprogram_Part",
10220 return BlockBase.match(
10222 [Specification_Part, Module_Subprogram_Part],
10230 <module-stmt> = MODULE <module-name> 10233 subclass_names = []
10234 use_names = [
"Module_Name"]
10238 return WORDClsBase.match(
"MODULE", Module_Name, string, require_cls=
True)
10240 def get_name(self):
10241 return self.items[1]
10246 <end-module-stmt> = END [ MODULE [ <module-name> ] ] 10249 subclass_names = []
10250 use_names = [
"Module_Name"]
10254 return EndStmtBase.match(
"MODULE", Module_Name, string)
10259 <module-subprogram-part> = <contains-stmt> 10260 <module-subprogram> 10261 [ <module-subprogram> ]... 10264 subclass_names = []
10265 use_names = [
"Contains_Stmt",
"Module_Subprogram"]
10269 return BlockBase.match(Contains_Stmt, [Module_Subprogram],
None, reader)
10274 <module-subprogram> = <function-subprogram> 10275 | <subroutine-subprogram> 10278 subclass_names = [
"Function_Subprogram",
"Subroutine_Subprogram"]
10283 Fortran 2003 rule R1109 10285 use-stmt is USE [ [ , module-nature ] :: ] module-name [ , rename-list ] 10286 or USE [ [ , module-nature ] :: ] module-name , 10287 ONLY : [ only-list ] 10291 subclass_names = []
10292 use_names = [
"Module_Nature",
"Module_Name",
"Rename_List",
"Only_List"]
10297 Wrapper for the match method that captures any successfully-matched 10298 use statements in the symbol table associated with the current scope 10301 :param str string: Fortran code to check for a match. 10303 :return: 5-tuple containing strings and instances of the classes 10304 describing a module (optional module nature, optional 10305 double colon delimiter, mandatory module name, optional 10306 "ONLY" specification and optional "Rename" or "Only" list) 10307 or None if the match fails. 10308 :rtype: 5-tuple of objects (module name and 4 optional) or NoneType 10310 :raises InternalError: if an Only_List is found to contain anything \ 10311 other than Name or Rename objects. 10314 result = Use_Stmt._match(string)
10316 table = SYMBOL_TABLES.current_scope
10320 if "only" in result[3].lower():
10322 if isinstance(result[4], Only_List):
10324 for child
in result[4].children:
10325 if isinstance(child, Name):
10326 only_list.append((child.string,
None))
10327 elif isinstance(child, Rename):
10329 (child.children[1].string, child.children[2].string)
10332 raise InternalError(
10333 f
"An Only_List can contain only Name or Rename " 10334 f
"entries but found '{type(child).__name__}' when matching '{string}'" 10336 elif isinstance(result[4], Rename_List):
10337 renames = walk(result[4], Rename)
10340 (rename.children[1].string, rename.children[2].string)
10341 for rename
in renames
10344 table.add_use_symbols(str(result[2]), only_list, rename_list)
10349 def _match(string):
10351 :param str string: Fortran code to check for a match. 10353 :return: 5-tuple containing strings and instances of the classes 10354 describing a module (optional module nature, optional 10355 double colon delimiter, mandatory module name, optional 10356 "ONLY" specification and optional "Rename" or "Only" list). 10357 :rtype: 5-tuple of objects (module name and 4 optional) 10360 line = string.strip()
10362 if line[:3].upper() !=
"USE":
10369 if line[0].isalnum():
10371 line = line.lstrip()
10372 i = line.find(
"::")
10379 if line.startswith(
","):
10380 line_nat = line[1:i].strip()
10385 line = line[i + 2 :].lstrip()
10391 items = re.findall(
r"[\w']+", line)
10395 except NoMatchError:
10398 if nature
is not None:
10401 position = line.find(
",")
10403 return nature, dcolon, Module_Name(line),
"",
None 10404 name = line[:position].rstrip()
10408 name = Module_Name(name)
10409 line = line[position + 1 :].lstrip()
10413 if line[:4].upper() ==
"ONLY":
10414 line = line[4:].lstrip()
10423 line = line[1:].lstrip()
10426 return nature, dcolon, name,
", ONLY:",
None 10427 return nature, dcolon, name,
", ONLY:", Only_List(line)
10428 return nature, dcolon, name,
",", Rename_List(line)
10432 :return: parsed representation of "USE" statement 10434 :raises InternalError: if items array is not the expected size 10435 :raises InternalError: if items array[2] is not a string or is an \ 10437 :raises InternalError: if items array[3] is 'None' as it should be \ 10440 if len(self.items) != 5:
10441 raise InternalError(
10442 "Use_Stmt.tostr(). 'Items' should be of size 5 but found " 10443 "'{0}'.".format(len(self.items))
10445 if not self.items[2]:
10446 raise InternalError(
10447 "Use_Stmt.tostr(). 'Items' entry 2 should " 10448 "be a module name but it is empty" 10450 if self.items[3]
is None:
10451 raise InternalError(
10452 "Use_Stmt.tostr(). 'Items' entry 3 should " 10453 "be a string but found 'None'" 10458 if self.items[0]
and self.items[1]:
10459 usestmt +=
", {0} {1}".format(self.items[0], self.items[1])
10462 elif not self.items[0]
and self.items[1]:
10463 usestmt +=
" {0}".format(self.items[1])
10465 usestmt +=
" {0}{1}".format(self.items[2], self.items[3])
10467 if self.items[4]
is not None:
10468 usestmt +=
" {0}".format(self.items[4])
10476 <module-nature> = INTRINSIC 10480 subclass_names = []
10485 :param str string: Fortran code to check for a match 10486 :return: keyword describing module nature ("INTRINSIC" or 10487 "NON_INTRINSIC") or nothing if no match is found 10490 return STRINGBase.match([
"INTRINSIC",
"NON_INTRINSIC"], string)
10495 <rename> = <local-name> => <use-name> 10496 | OPERATOR(<local-defined-operator>) => 10497 OPERATOR(<use-defined-operator>) 10500 subclass_names = []
10504 "Local_Defined_Operator",
10505 "Use_Defined_Operator",
10510 s = string.split(
"=>", 1)
10513 lhs, rhs = s[0].rstrip(), s[1].lstrip()
10514 if not lhs
or not rhs:
10516 if lhs[:8].upper() ==
"OPERATOR" and rhs[:8].upper() ==
"OPERATOR":
10517 tmp = lhs[8:].lstrip()
10518 r = rhs[8:].lstrip()
10519 if tmp
and r
and tmp[0] + tmp[-1] ==
"()":
10520 if r[0] + r[-1] !=
"()":
10522 tmp = tmp[1:-1].strip()
10523 r = r[1:-1].strip()
10524 if not tmp
or not r:
10527 return None, Local_Name(lhs), Use_Name(rhs)
10530 if not self.items[0]:
10531 return "%s => %s" % self.items[1:]
10532 return "%s(%s) => %s(%s)" % (
10542 <only> = <generic-spec> 10547 subclass_names = [
"Generic_Spec",
"Only_Use_Name",
"Rename"]
10552 <only-use-name> = <name> 10555 subclass_names = [
"Name"]
10560 <local-defined-operator> = <defined-unary-op> 10561 | <defined-binary-op> 10564 subclass_names = [
"Defined_Unary_Op",
"Defined_Binary_Op"]
10569 <use-defined-operator> = <defined-unary-op> 10570 | <defined-binary-op> 10573 subclass_names = [
"Defined_Unary_Op",
"Defined_Binary_Op"]
10579 <block-data> = <block-data-stmt> 10580 [ <specification-part> ] 10581 <end-block-data-stmt> 10584 subclass_names = []
10585 use_names = [
"Block_Data_Stmt",
"Specification_Part",
"End_Block_Data_Stmt"]
10589 return BlockBase.match(
10590 Block_Data_Stmt, [Specification_Part], End_Block_Data_Stmt, reader
10597 <block-data-stmt> = BLOCK DATA [ <block-data-name> ] 10600 subclass_names = []
10601 use_names = [
"Block_Data_Name"]
10605 if string[:5].upper() !=
"BLOCK":
10607 line = string[5:].lstrip()
10608 if line[:4].upper() !=
"DATA":
10610 line = line[4:].lstrip()
10613 return (Block_Data_Name(line),)
10616 if self.items[0]
is None:
10617 return "BLOCK DATA" 10618 return "BLOCK DATA %s" % self.items
10620 def get_name(self):
10621 return self.items[0]
10627 <end-block-data-stmt> = END [ BLOCK DATA [ <block-data-name> ] ] 10630 subclass_names = []
10631 use_names = [
"Block_Data_Name"]
10635 return EndStmtBase.match(
"BLOCK DATA", Block_Data_Name, string)
10646 <interface-block> = <interface-stmt> 10647 [ <interface-specification> ]... 10648 <end-interface-stmt> 10651 subclass_names = []
10652 use_names = [
"Interface_Stmt",
"Interface_Specification",
"End_Interface_Stmt"]
10656 return BlockBase.match(
10657 Interface_Stmt, [Interface_Specification], End_Interface_Stmt, reader
10663 <interface-specification> = <interface-body> 10667 subclass_names = [
"Interface_Body",
"Procedure_Stmt"]
10673 <interface-stmt> = INTERFACE [ <generic-spec> ] 10674 | ABSTRACT INTERFACE 10678 items : ({Generic_Spec, 'ABSTRACT'},) 10681 subclass_names = []
10682 use_names = [
"Generic_Spec"]
10686 if string[:9].upper() ==
"INTERFACE":
10687 line = string[9:].strip()
10691 if string[:8].upper() ==
"ABSTRACT":
10692 line = string[8:].strip()
10693 if line.upper() ==
"INTERFACE":
10694 return (
"ABSTRACT",)
10697 if self.items[0] ==
"ABSTRACT":
10698 return "ABSTRACT INTERFACE" 10699 if self.items[0]
is None:
10701 return "INTERFACE %s" % (self.items[0])
10707 <end-interface-stmt> = END INTERFACE [ <generic-spec> ] 10711 items : (Generic_Spec, ) 10714 subclass_names = []
10715 use_names = [
"Generic_Spec"]
10719 return EndStmtBase.match(
10720 "INTERFACE", Generic_Spec, string, require_stmt_type=
True 10727 <function-body> = <function-stmt> 10728 [ <specification-part> ] 10729 <end-function-stmt> 10732 subclass_names = []
10733 use_names = [
"Function_Stmt",
"Specification_Part",
"End_Function_Stmt"]
10737 return BlockBase.match(
10738 Function_Stmt, [Specification_Part], End_Function_Stmt, reader
10745 <subroutine-body> = <subroutine-stmt> 10746 [ <specification-part> ] 10747 <end-subroutine-stmt> 10750 subclass_names = []
10751 use_names = [
"Subroutine_Stmt",
"Specification_Part",
"End_Subroutine_Stmt"]
10755 return BlockBase.match(
10756 Subroutine_Stmt, [Specification_Part], End_Subroutine_Stmt, reader
10763 <interface-body> = <function-body> | <subroutine-body> 10767 Function_Body, Subroutine_Body 10770 subclass_names = [
"Function_Body",
"Subroutine_Body"]
10777 <procedure-stmt> = [ MODULE ] PROCEDURE <procedure-name-list> 10781 items : (Procedure_Name_List, ) 10784 subclass_names = []
10785 use_names = [
"Procedure_Name_List"]
10789 if string[:6].upper() ==
"MODULE":
10790 line = string[6:].lstrip()
10793 if line[:9].upper() !=
"PROCEDURE":
10795 line = line[9:].lstrip()
10796 return (Procedure_Name_List(line),)
10799 return "MODULE PROCEDURE %s" % (self.items[0])
10805 <generic-spec> = <generic-name> 10806 | OPERATOR ( <defined-operator> ) 10808 | <dtio-generic-spec> 10811 items : ({'OPERATOR', 'ASSIGNMENT'}, {Defined_Operator, '='}) 10814 subclass_names = [
"Generic_Name",
"Dtio_Generic_Spec"]
10815 use_names = [
"Defined_Operator"]
10819 if string[:8].upper() ==
"OPERATOR":
10820 line = string[8:].lstrip()
10821 if not line
or line[0] !=
"(" or line[-1] !=
")":
10824 if string[:10].upper() ==
"ASSIGNMENT":
10825 line = string[10:].lstrip()
10826 if not line
or line[0] !=
"(" or line[-1] !=
")":
10828 if line[1:-1].strip() ==
"=":
10829 return "ASSIGNMENT",
"=" 10832 return "%s(%s)" % (self.items)
10838 <dtio-generic-spec> = READ ( FORMATTED ) 10839 | READ ( UNFORMATTED ) 10840 | WRITE ( FORMATTED ) 10841 | WRITE ( UNFORMATTED ) 10847 subclass_names = []
10851 for rw
in [
"READ",
"WRITE"]:
10852 if string[: len(rw)].upper() == rw:
10853 line = string[len(rw) :].lstrip()
10856 if line[0] !=
"(" or line[-1] !=
")":
10858 line = line[1:-1].strip().upper()
10859 if line
in [
"FORMATTED",
"UNFORMATTED"]:
10860 return (
"%s(%s)" % (rw, line),)
10863 return "%s" % (self.items[0])
10868 Fortran 2003 rule R1209 10869 import-stmt is IMPORT [[ :: ] import-name-list ] 10871 C1210 (R1209) The IMPORT statement is allowed only in an 10872 interface-body. Note, this constraint is not currently enforced. 10874 C1211 (R1209) Each import-name shall be the name of an entity in 10875 the host scoping unit. This constraint is not currently enforced 10876 and can not be generally enforced as the name may come from a use 10877 statement without an only clause. 10881 subclass_names = []
10882 use_names = [
"Import_Name_List"]
10883 tostr = WORDClsBase.tostr_a
10888 Implements the matching for the import-stmt rule. 10890 Makes use of the WORDClsBase base class. 10892 :param str string: the string to match. 10894 :returns: None if there is no match, otherwise a tuple of size \ 10895 2 containing the string `IMPORT` as the first entry and \ 10896 an object of type `Import_Name_List` if names are \ 10897 specified in the string or `None` if not. 10899 :rtype: None, or (str, \ 10900 :py:class:`fparser.two.Fortran2003.Import_Name_List`) or \ 10904 return WORDClsBase.match(
10905 "IMPORT", Import_Name_List, string, colons=
True, require_cls=
False 10911 <external-stmt> = EXTERNAL [ :: ] <external-name-list> 10914 subclass_names = []
10915 use_names = [
"External_Name_List"]
10919 return WORDClsBase.match(
10920 "EXTERNAL", External_Name_List, string, colons=
True, require_cls=
True 10923 tostr = WORDClsBase.tostr_a
10929 <procedure-declaration-stmt> = PROCEDURE ( [ <proc-interface> ] ) 10930 [ [ , <proc-attr-spec> ]... :: ] <proc-decl-list> 10934 items : (Proc_Interface, Proc_Attr_Spec_List, Proc_Decl_List) 10937 subclass_names = []
10938 use_names = [
"Proc_Interface",
"Proc_Attr_Spec_List",
"Proc_Decl_List"]
10942 if string[:9].upper() !=
"PROCEDURE":
10944 line = string[9:].lstrip()
10945 if not line.startswith(
"("):
10947 line, repmap = string_replace_map(line)
10951 tmp = line[1:i].strip()
10953 line = line[i + 1 :].lstrip()
10954 i = line.find(
"::")
10955 proc_attr_spec_list =
None 10957 tmp = line[:i].rstrip()
10958 if tmp
and tmp[0] ==
",":
10959 proc_attr_spec_list = Proc_Attr_Spec_List(repmap(tmp[1:].lstrip()))
10960 line = line[i + 2 :].lstrip()
10961 return proc_interface, proc_attr_spec_list, Proc_Decl_List(repmap(line))
10965 if self.items[0]
is not None:
10966 r +=
"(%s)" % (self.items[0])
10969 if self.items[1]
is not None:
10970 r +=
", %s ::" % (self.items[1])
10971 return "%s %s" % (r, self.items[2])
10976 <proc-interface> = <interface-name> 10977 | <declaration-type-spec> 10980 subclass_names = [
"Interface_Name",
"Declaration_Type_Spec"]
10985 <proc-attr-spec> = <access-spec> 10986 | <proc-language-binding-spec> 10987 | INTENT ( <intent-spec> ) 10995 items : ({'INTENT', 'OPTIONAL', 'POINTER', 'PROTECTED', 'SAVE'}, Intent_Spec) 10998 subclass_names = [
"Access_Spec",
"Proc_Language_Binding_Spec"]
10999 use_names = [
"Intent_Spec"]
11004 Matches procedure arguments. 11006 :param str string: Candidate string. 11007 :return: Discovered arguments. 11008 :rtype: tuple, str or None 11010 if string[:6].upper() ==
"INTENT":
11011 line = string[6:].lstrip()
11014 if line[0] !=
"(" or line[-1] !=
")":
11017 if len(string) == 8
and string.upper() ==
"OPTIONAL":
11018 return "OPTIONAL",
None 11019 if len(string) == 7
and string.upper() ==
"POINTER":
11020 return "POINTER",
None 11021 if len(string) == 9
and string.upper() ==
"PROTECTED":
11022 return "PROTECTED",
None 11023 if len(string) == 4
and string.upper() ==
"SAVE":
11024 return "SAVE",
None 11027 if self.items[1]
is None:
11028 return "%s" % (self.items[0])
11029 return "%s(%s)" % (self.items)
11035 <proc-decl> = <procedure-entity-name> [ => <null-init> ] 11039 items : (Procedure_Entity_Name, Null_Init) 11042 subclass_names = [
"Procedure_Entity_Name"]
11043 use_names = [
"Null_Init"]
11047 return BinaryOpBase.match(Procedure_Entity_Name,
"=>", Null_Init, string)
11052 <interface-name> = <name> 11055 subclass_names = [
"Name"]
11060 <intrinsic-stmt> = INTRINSIC [ :: ] <intrinsic-procedure-name-list> 11063 subclass_names = []
11064 use_names = [
"Intrinsic_Procedure_Name_List"]
11068 return WORDClsBase.match(
11070 Intrinsic_Procedure_Name_List,
11076 tostr = WORDClsBase.tostr_a
11081 <function-reference> = <procedure-designator> 11082 ( [ <actual-arg-spec-list> ] ) 11085 subclass_names = []
11086 use_names = [
"Procedure_Designator",
"Actual_Arg_Spec_List"]
11090 return CallBase.match(Procedure_Designator, Actual_Arg_Spec_List, string)
11094 """Represents the name of a Fortran intrinsic function. 11096 All generic intrinsic names are specified as keys in the 11097 `generic_function_names` dictionary, with their values indicating 11098 the minimum and maximum number of arguments allowed for this 11099 intrinsic function. A `-1` indicates an unlimited number of 11100 arguments. The names are split into the categories specified in 11101 the Fortran2003 specification document. 11103 All specific intrinsic names (which have a different name to their 11104 generic counterpart) are specified as keys in the 11105 `specific_function_names` dictionary, with their values indicating 11106 which generic function they are associated with. 11111 "ABS": {
"min": 1,
"max": 1},
11112 "AIMAG": {
"min": 1,
"max": 1},
11113 "AINT": {
"min": 1,
"max": 2},
11114 "ANINT": {
"min": 1,
"max": 2},
11115 "CEILING": {
"min": 1,
"max": 2},
11116 "CMPLX": {
"min": 1,
"max": 3},
11117 "CONJG": {
"min": 1,
"max": 1},
11118 "DBLE": {
"min": 1,
"max": 1},
11119 "DIM": {
"min": 2,
"max": 2},
11120 "DPROD": {
"min": 2,
"max": 2},
11121 "FLOOR": {
"min": 1,
"max": 2},
11122 "INT": {
"min": 1,
"max": 2},
11123 "MAX": {
"min": 2,
"max":
None},
11124 "MIN": {
"min": 2,
"max":
None},
11125 "MOD": {
"min": 2,
"max": 2},
11126 "MODULO": {
"min": 2,
"max": 2},
11127 "NINT": {
"min": 1,
"max": 2},
11128 "REAL": {
"min": 1,
"max": 2},
11129 "SIGN": {
"min": 2,
"max": 2},
11132 mathematical_names = {
11133 "ACOS": {
"min": 1,
"max": 1},
11134 "ASIN": {
"min": 1,
"max": 1},
11135 "ATAN": {
"min": 1,
"max": 1},
11136 "ATAN2": {
"min": 2,
"max": 2},
11137 "COS": {
"min": 1,
"max": 1},
11138 "COSH": {
"min": 1,
"max": 1},
11139 "EXP": {
"min": 1,
"max": 1},
11140 "LOG": {
"min": 1,
"max": 1},
11141 "LOG10": {
"min": 1,
"max": 1},
11142 "SIN": {
"min": 1,
"max": 1},
11143 "SINH": {
"min": 1,
"max": 1},
11144 "SQRT": {
"min": 1,
"max": 1},
11145 "TAN": {
"min": 1,
"max": 1},
11146 "TANH": {
"min": 1,
"max": 1},
11151 character_names = {
11152 "ACHAR": {
"min": 1,
"max": 2},
11153 "ADJUSTL": {
"min": 1,
"max": 1},
11154 "ADJUSTR": {
"min": 1,
"max": 1},
11155 "CHAR": {
"min": 1,
"max": 2},
11156 "IACHAR": {
"min": 1,
"max": 2},
11157 "ICHAR": {
"min": 1,
"max": 2},
11158 "INDEX": {
"min": 2,
"max": 4},
11159 "LEN_TRIM": {
"min": 1,
"max": 2},
11160 "LGE": {
"min": 2,
"max": 2},
11161 "LGT": {
"min": 2,
"max": 2},
11162 "LLE": {
"min": 2,
"max": 2},
11163 "LLT": {
"min": 2,
"max": 2},
11164 "REPEAT": {
"min": 2,
"max": 2},
11165 "SCAN": {
"min": 2,
"max": 4},
11166 "TRIM": {
"min": 1,
"max": 1},
11167 "VERIFY": {
"min": 2,
"max": 4},
11171 "KIND": {
"min": 1,
"max": 1},
11172 "SELECTED_CHAR_KIND": {
"min": 1,
"max": 1},
11173 "SELECTED_INT_KIND": {
"min": 1,
"max": 1},
11174 "SELECTED_REAL_KIND": {
"min": 1,
"max": 2},
11177 miscellaneous_type_conversion_names = {
11178 "LOGICAL": {
"min": 1,
"max": 2},
11179 "TRANSFER": {
"min": 2,
"max": 3},
11182 numeric_inquiry_names = {
11183 "DIGITS": {
"min": 1,
"max": 1},
11184 "EPSILON": {
"min": 1,
"max": 1},
11185 "HUGE": {
"min": 1,
"max": 1},
11186 "MAXEXPONENT": {
"min": 1,
"max": 1},
11187 "MINEXPONENT": {
"min": 1,
"max": 1},
11188 "PRECISION": {
"min": 1,
"max": 1},
11189 "RADIX": {
"min": 1,
"max": 1},
11190 "RANGE": {
"min": 1,
"max": 1},
11191 "TINY": {
"min": 1,
"max": 1},
11194 array_inquiry_names = {
11195 "LBOUND": {
"min": 1,
"max": 3},
11196 "SHAPE": {
"min": 1,
"max": 2},
11197 "SIZE": {
"min": 1,
"max": 3},
11198 "UBOUND": {
"min": 1,
"max": 3},
11201 other_inquiry_names = {
11202 "ALLOCATED": {
"min": 1,
"max": 1},
11203 "ASSOCIATED": {
"min": 1,
"max": 2},
11204 "BIT_SIZE": {
"min": 1,
"max": 1},
11205 "EXTENDS_TYPE_OF": {
"min": 2,
"max": 2},
11206 "LEN": {
"min": 1,
"max": 2},
11207 "NEW_LINE": {
"min": 1,
"max": 1},
11208 "PRESENT": {
"min": 1,
"max": 1},
11209 "SAME_TYPE_AS": {
"min": 2,
"max": 2},
11212 bit_manipulation_names = {
11213 "BTEST": {
"min": 2,
"max": 2},
11214 "IAND": {
"min": 2,
"max": 2},
11215 "IBCLR": {
"min": 2,
"max": 2},
11216 "IBITS": {
"min": 3,
"max": 3},
11217 "IBSET": {
"min": 2,
"max": 2},
11218 "IEOR": {
"min": 2,
"max": 2},
11219 "IOR": {
"min": 2,
"max": 2},
11220 "ISHFT": {
"min": 2,
"max": 2},
11221 "ISHFTC": {
"min": 2,
"max": 3},
11222 "MVBITS": {
"min": 5,
"max": 5},
11223 "NOT": {
"min": 1,
"max": 1},
11226 floating_point_manipulation_names = {
11227 "EXPONENT": {
"min": 1,
"max": 1},
11228 "FRACTION": {
"min": 1,
"max": 1},
11229 "NEAREST": {
"min": 2,
"max": 2},
11230 "RRSPACING": {
"min": 1,
"max": 1},
11231 "SCALE": {
"min": 2,
"max": 2},
11232 "SET_EXPONENT": {
"min": 2,
"max": 2},
11233 "SPACING": {
"min": 1,
"max": 1},
11236 vector_and_matrix_multiply_names = {
11237 "DOT_PRODUCT": {
"min": 2,
"max": 2},
11238 "MATMUL": {
"min": 2,
"max": 2},
11241 array_reduction_names = {
11242 "ALL": {
"min": 1,
"max": 2},
11243 "ANY": {
"min": 1,
"max": 2},
11244 "COUNT": {
"min": 1,
"max": 3},
11245 "MAXVAL": {
"min": 1,
"max": 3},
11246 "MINVAL": {
"min": 1,
"max": 3},
11247 "PRODUCT": {
"min": 1,
"max": 3},
11248 "SUM": {
"min": 1,
"max": 3},
11251 array_construction_names = {
11252 "CSHIFT": {
"min": 2,
"max": 3},
11253 "EOSHIFT": {
"min": 2,
"max": 4},
11254 "MERGE": {
"min": 3,
"max": 3},
11255 "PACK": {
"min": 2,
"max": 3},
11256 "RESHAPE": {
"min": 2,
"max": 4},
11257 "SPREAD": {
"min": 3,
"max": 3},
11258 "TRANSPOSE": {
"min": 1,
"max": 1},
11259 "UNPACK": {
"min": 3,
"max": 3},
11262 array_location_names = {
11263 "MAXLOC": {
"min": 1,
"max": 4},
11264 "MINLOC": {
"min": 1,
"max": 4},
11267 null_names = {
"NULL": {
"min": 0,
"max": 1}}
11269 allocation_transfer_names = {
"MOVE_ALLOC": {
"min": 2,
"max": 2}}
11271 random_number_names = {
11272 "RANDOM_NUMBER": {
"min": 1,
"max": 1},
11273 "RANDOM_SEED": {
"min": 0,
"max": 3},
11276 system_environment_names = {
11277 "COMMAND_ARGUMENT_COUNT": {
"min": 0,
"max": 0},
11278 "CPU_TIME": {
"min": 1,
"max": 1},
11279 "DATE_AND_TIME": {
"min": 0,
"max": 4},
11280 "GET_COMMAND": {
"min": 0,
"max": 3},
11281 "GET_COMMAND_ARGUMENT": {
"min": 1,
"max": 4},
11282 "GET_ENVIRONMENT_VARIABLE": {
"min": 1,
"max": 5},
11283 "IS_IOSTAT_END": {
"min": 1,
"max": 1},
11284 "IS_IOSTAT_EOR": {
"min": 1,
"max": 1},
11285 "SYSTEM_CLOCK": {
"min": 0,
"max": 3},
11289 specific_function_names = {
11339 generic_function_names = {}
11340 generic_function_names.update(numeric_names)
11341 generic_function_names.update(mathematical_names)
11342 generic_function_names.update(character_names)
11343 generic_function_names.update(kind_names)
11344 generic_function_names.update(miscellaneous_type_conversion_names)
11345 generic_function_names.update(numeric_inquiry_names)
11346 generic_function_names.update(array_inquiry_names)
11347 generic_function_names.update(other_inquiry_names)
11348 generic_function_names.update(bit_manipulation_names)
11349 generic_function_names.update(floating_point_manipulation_names)
11350 generic_function_names.update(vector_and_matrix_multiply_names)
11351 generic_function_names.update(array_reduction_names)
11352 generic_function_names.update(array_construction_names)
11353 generic_function_names.update(array_location_names)
11354 generic_function_names.update(null_names)
11355 generic_function_names.update(allocation_transfer_names)
11356 generic_function_names.update(random_number_names)
11357 generic_function_names.update(system_environment_names)
11360 function_names = list(generic_function_names.keys()) + list(
11361 specific_function_names.keys()
11364 subclass_names = []
11368 """Attempt to match the input `string` with the intrinsic function 11369 names defined in `generic_function_names` or 11370 `specific_function_names`. If there is a match the resultant 11371 string will be converted to upper case. 11373 :param str string: The pattern to be matched. 11375 :returns: A tuple containing the matched string (converted to \ 11376 upper case) if there is a match or None if there is not. 11377 :rtype: (str,) or NoneType 11380 return STRINGBase.match(Intrinsic_Name.function_names, string)
11384 """Represents Fortran intrinsics. 11386 function-reference is intrinsic-name ( [ actual-arg-spec-list ] ) 11390 subclass_names = []
11391 use_names = [
"Intrinsic_Name",
"Actual_Arg_Spec_List"]
11395 """Match the string as an intrinsic function. Also check that the 11396 number of arguments provided matches the number expected by 11399 :param str string: the string to match with the pattern rule. 11401 :return: a tuple of size 2 containing the name of the \ 11402 intrinsic and its arguments if there is a match, or None if \ 11404 :rtype: (:py:class:`fparser.two.Fortran2003.Intrinsic_Name`, \ 11405 :py:class:`fparser.two.Fortran2003.Actual_Arg_Spec_List`) or \ 11408 :raises InternalSyntaxError: If the number of arguments \ 11409 provided does not match the number of arguments expected by \ 11413 result = CallBase.match(Intrinsic_Name, Actual_Arg_Spec_List, string)
11417 function_name = str(result[0])
11418 function_args = result[1]
11422 table = SYMBOL_TABLES.current_scope
11424 table.lookup(function_name)
11427 except (KeyError, AttributeError):
11434 if isinstance(function_args, Actual_Arg_Spec_List):
11435 nargs = len(function_args.items)
11436 elif function_args
is None:
11441 if function_name
in Intrinsic_Name.specific_function_names.keys():
11444 test_name = Intrinsic_Name.specific_function_names[function_name]
11446 test_name = function_name
11448 min_nargs = Intrinsic_Name.generic_function_names[test_name][
"min"]
11449 max_nargs = Intrinsic_Name.generic_function_names[test_name][
"max"]
11451 if max_nargs
is None:
11452 if nargs < min_nargs:
11454 raise InternalSyntaxError(
11455 "Intrinsic '{0}' expects at least {1} args but found " 11456 "{2}.".format(function_name, min_nargs, nargs)
11462 if min_nargs == max_nargs
and nargs != min_nargs:
11463 raise InternalSyntaxError(
11464 "Intrinsic '{0}' expects {1} arg(s) but found {2}." 11465 "".format(function_name, min_nargs, nargs)
11467 if min_nargs < max_nargs
and (nargs < min_nargs
or nargs > max_nargs):
11468 raise InternalSyntaxError(
11469 "Intrinsic '{0}' expects between {1} and {2} args but " 11470 "found {3}.".format(function_name, min_nargs, max_nargs, nargs)
11477 <call-stmt> = CALL <procedure-designator> 11478 [ ( [ <actual-arg-spec-list> ] ) ] 11482 items : (Procedure_Designator, Actual_Arg_Spec_List) 11485 subclass_names = []
11486 use_names = [
"Procedure_Designator",
"Actual_Arg_Spec_List"]
11490 if string[:4].upper() !=
"CALL":
11492 line, repmap = string_replace_map(string[4:].lstrip())
11493 if line.endswith(
")"):
11494 i = line.rfind(
"(")
11497 args = repmap(line[i + 1 : -1].strip())
11501 Actual_Arg_Spec_List(args),
11507 if self.items[1]
is None:
11508 return "CALL %s" % (self.items[0])
11509 return "CALL %s(%s)" % self.items
11514 <procedure-designator> = <procedure-name> 11515 | <proc-component-ref> 11516 | <data-ref> % <binding-name> 11519 subclass_names = [
"Procedure_Name",
"Proc_Component_Ref"]
11520 use_names = [
"Data_Ref",
"Binding_Name"]
11524 return BinaryOpBase.match(
11525 Data_Ref, pattern.percent_op.named(), Binding_Name, string
11531 <actual-arg-spec> = [ <keyword> = ] <actual-arg> 11534 subclass_names = [
"Actual_Arg"]
11535 use_names = [
"Keyword"]
11539 return KeywordValueBase.match(Keyword, Actual_Arg, string)
11544 <actual-arg> = <expr> 11547 | <proc-component-ref> 11548 | <alt-return-spec> 11554 "Proc_Component_Ref",
11562 <alt-return-spec> = * <label> 11565 subclass_names = []
11566 use_names = [
"Label"]
11570 if not string.startswith(
"*"):
11572 line = string[1:].lstrip()
11575 return (
Label(line),)
11578 return "*%s" % (self.items[0])
11583 <function-subprogram> = <function-stmt> 11584 [ <specification-part> ] 11585 [ <execution-part> ] 11586 [ <internal-subprogram-part> ] 11587 <end-function-stmt> 11590 subclass_names = []
11593 "Specification_Part",
11595 "Internal_Subprogram_Part",
11596 "End_Function_Stmt",
11601 return BlockBase.match(
11603 [Specification_Part, Execution_Part, Internal_Subprogram_Part],
11611 <function-stmt> = [ <prefix> ] FUNCTION <function-name> 11612 ( [ <dummy-arg-name-list> ] ) [ <suffix> ] 11614 C1242 (R1227) A prefix shall not specify ELEMENTAL if 11615 proc-language-binding-spec appears in the function-stmt or 11616 subroutine-stmt. The spec associates this constraint with R1227 11617 but it needs to be checked here. 11621 subclass_names = []
11622 use_names = [
"Prefix",
"Function_Name",
"Dummy_Arg_Name_List",
"Suffix"]
11626 line, repmap = string_replace_map(string)
11627 m = pattern.function.search(line)
11630 prefix = line[: m.start()].rstrip()
or None 11631 if prefix
is not None:
11632 prefix =
Prefix(repmap(prefix))
11633 line = line[m.end() :].lstrip()
11634 m = pattern.name.match(line)
11637 name = Function_Name(m.group())
11638 line = line[m.end() :].lstrip()
11639 if not line.startswith(
"("):
11644 dummy_args = line[1:i].strip()
or None 11645 if dummy_args
is not None:
11646 dummy_args = Dummy_Arg_List(repmap(dummy_args))
11647 line = line[i + 1 :].lstrip()
11650 suffix =
Suffix(repmap(line))
11653 binding_spec = walk(suffix, Language_Binding_Spec)
11655 if not c1242_valid(prefix, binding_spec):
11657 return prefix, name, dummy_args, suffix
11660 prefix, name, dummy_args, suffix = self.items
11661 if prefix
is not None:
11662 s =
"%s FUNCTION %s" % (prefix, name)
11664 s =
"FUNCTION %s" % (name)
11665 if dummy_args
is not None:
11666 s +=
"(%s)" % (dummy_args)
11669 if suffix
is not None:
11670 s +=
" %s" % (suffix)
11673 def get_name(self):
11674 """Provides the function name as an instance of the :py:class:`Name` class. 11676 :rtype: :py:class:`Name` 11678 return self.items[1]
11683 <proc-language-binding-spec> = <language-binding-spec> 11686 subclass_names = [
"Language_Binding_Spec"]
11691 <dummy-arg-name> = <name> 11694 subclass_names = [
"Name"]
11698 """Fortran2003 rule R1227 11700 prefix is prefix-spec [ prefix-spec ] ... 11702 C1240 (R1227) A prefix shall contain at most one of each 11703 prefix-spec. Checked below. 11705 C1241 (R1227) A prefix shall not specify both ELEMENTAL and 11706 RECURSIVE. Checked below. 11708 C1242 (R1227) A prefix shall not specify ELEMENTAL if 11709 proc-language-binding-spec appears in the function-stmt or 11710 subroutine-stmt. This constraint can not be checked here, it is 11711 checked in R1224 and R1232. 11715 subclass_names = []
11719 """Match a space separated list of Prefix_Spec objects. Objects may be 11720 separated by 1 or more spaces. 11722 :returns: A tuple of size 2 containing the separator and a \ 11723 tuple containing one or more Prefix_Spec objects if there is a \ 11724 match and None if not. 11726 :rtype: (str, (:class:py:`fparser.two.Fortran2003.Prefix_Spec`,)) \ 11730 start_match_list = []
11731 end_match_list = []
11732 decl_spec_list = []
11734 split = string.split()
11739 while split
and split[0].upper()
in Prefix_Spec.keywords:
11741 keyword_list.append(split[0].upper())
11745 while split
and split[-1].upper()
in Prefix_Spec.keywords:
11747 keyword_list.append(split[-1].upper())
11753 remaining =
" ".join(split)
11756 if len(set(keyword_list)) != len(keyword_list):
11761 if "ELEMENTAL" in keyword_list
and "RECURSIVE" in keyword_list:
11764 result_list = start_match_list + decl_spec_list + end_match_list
11766 return " ", tuple(result_list)
11773 <prefix-spec> = <declaration-type-spec> 11781 subclass_names = [
"Declaration_Type_Spec"]
11783 keywords = [
"ELEMENTAL",
"IMPURE",
"MODULE",
"PURE",
"RECURSIVE"]
11788 Matches procedure prefixes. 11790 :param str string: Candidate string. 11791 :return: Discovered prefix. 11794 return STRINGBase.match(Prefix_Spec.keywords, string)
11799 <suffix> = <proc-language-binding-spec> [ RESULT ( <result-name> ) ] 11800 | RESULT ( <result-name> ) [ <proc-language-binding-spec> ] 11803 subclass_names = [
"Proc_Language_Binding_Spec"]
11804 use_names = [
"Result_Name"]
11808 if string[:6].upper() ==
"RESULT":
11809 line = string[6:].lstrip()
11810 if not line.startswith(
"("):
11815 name = line[1:i].strip()
11818 line = line[i + 1 :].lstrip()
11821 return Result_Name(name),
None 11822 if not string.endswith(
")"):
11824 i = string.rfind(
"(")
11827 name = string[i + 1 : -1].strip()
11830 line = string[:i].rstrip()
11831 if line[-6:].upper() !=
"RESULT":
11833 line = line[:-6].rstrip()
11839 if self.items[1]
is None:
11840 return "RESULT(%s)" % (self.items[0])
11841 return "RESULT(%s) %s" % self.items
11846 <end-function-stmt> = END [ FUNCTION [ <function-name> ] ] 11849 subclass_names = []
11850 use_names = [
"Function_Name"]
11854 return EndStmtBase.match(
"FUNCTION", Function_Name, string)
11859 <subroutine-subprogram> = <subroutine-stmt> 11860 [ <specification-part> ] 11861 [ <execution-part> ] 11862 [ <internal-subprogram-part> ] 11863 <end-subroutine-stmt> 11866 subclass_names = []
11869 "Specification_Part",
11871 "Internal_Subprogram_Part",
11872 "End_Subroutine_Stmt",
11877 return BlockBase.match(
11879 [Specification_Part, Execution_Part, Internal_Subprogram_Part],
11880 End_Subroutine_Stmt,
11885 def c1242_valid(prefix, binding_spec):
11886 """If prefix and binding-spec exist then check whether they conform to 11887 constraint C1242 : "A prefix shall not specify ELEMENTAL if 11888 proc-language-binding-spec appears in the function-stmt or 11891 :param prefix: matching prefix instance if one exists. 11892 :type: :py:class:`fparser.two.Fortran2003.Prefix` or `NoneType` 11893 :param binding_spec: matching binding specification instance if \ 11895 :type binding_spec: \ 11896 :py:class:`fparser.two.Fortran2003.Language_Binding_Spec` or 11898 :returns: False if prefix and binding-spec break constraint C1242, \ 11903 if binding_spec
and prefix:
11906 "ELEMENTAL" in str(child)
for child
in walk(prefix.items, Prefix_Spec)
11917 """<subroutine-stmt> 11918 = [ <prefix> ] SUBROUTINE <subroutine-name> 11919 [ ( [ <dummy-arg-list> ] ) [ <proc-language-binding-spec> ] ] 11921 C1242 (R1227) A prefix shall not specify ELEMENTAL if 11922 proc-language-binding-spec appears in the function-stmt or 11923 subroutine-stmt. The spec associates this constraint with R1227 11924 but it needs to be checked here. 11928 subclass_names = []
11933 "Proc_Language_Binding_Spec",
11938 line, repmap = string_replace_map(string)
11939 m = pattern.subroutine.search(line)
11942 prefix = line[: m.start()].rstrip()
or None 11943 if prefix
is not None:
11944 prefix =
Prefix(repmap(prefix))
11945 line = line[m.end() :].lstrip()
11946 m = pattern.name.match(line)
11949 name = Subroutine_Name(m.group())
11950 line = line[m.end() :].lstrip()
11952 if line.startswith(
"("):
11956 dummy_args = line[1:i].strip()
or None 11957 if dummy_args
is not None:
11958 dummy_args = Dummy_Arg_List(repmap(dummy_args))
11959 line = line[i + 1 :].lstrip()
11960 binding_spec =
None 11963 if not c1242_valid(prefix, binding_spec):
11965 return prefix, name, dummy_args, binding_spec
11967 def get_name(self):
11968 return self.items[1]
11971 if self.items[0]
is not None:
11972 s =
"%s SUBROUTINE %s" % (self.items[0], self.items[1])
11974 s =
"SUBROUTINE %s" % (self.items[1])
11975 if self.items[2]
is not None:
11976 s +=
"(%s)" % (self.items[2])
11977 if self.items[3]
is not None:
11978 s +=
" %s" % (self.items[3])
11984 <dummy-arg> = <dummy-arg-name> 11988 subclass_names = [
"Dummy_Arg_Name"]
11992 return StringBase.match(
"*", string)
11997 <end-subroutine-stmt> = END [ SUBROUTINE [ <subroutine-name> ] ] 12000 subclass_names = []
12001 use_names = [
"Subroutine_Name"]
12005 return EndStmtBase.match(
"SUBROUTINE", Subroutine_Name, string)
12011 <entry-stmt> = ENTRY <entry-name> [ ( [ <dummy-arg-list> ] ) [ <suffix> ] ] 12015 items : (Entry_Name, Dummy_Arg_List, Suffix) 12018 subclass_names = []
12019 use_names = [
"Entry_Name",
"Dummy_Arg_List",
"Suffix"]
12023 if string[:5].upper() !=
"ENTRY":
12025 line = string[5:].lstrip()
12028 return Entry_Name(line),
None,
None 12029 name = Entry_Name(line[:i].rstrip())
12030 line, repmap = string_replace_map(line[i:])
12034 args = line[1:i].strip()
12035 args = Dummy_Arg_List(repmap(args))
if args
else None 12036 line = line[i + 1 :].lstrip()
12038 return name, args,
Suffix(repmap(line))
12039 return name, args,
None 12042 name, args, suffix = self.items
12045 return "ENTRY %s()" % (name)
12046 return "ENTRY %s(%s)" % (name, args)
12048 return "ENTRY %s() %s" % (name, suffix)
12049 return "ENTRY %s(%s) %s" % (name, args, suffix)
12054 <return-stmt> = RETURN [ <scalar-int-expr> ] 12057 subclass_names = []
12058 use_names = [
"Scalar_Int_Expr"]
12062 start = string[:6].upper()
12063 if start !=
"RETURN":
12065 if len(string) == 6:
12067 return (Scalar_Int_Expr(string[6:].lstrip()),)
12070 if self.items[0]
is None:
12072 return "RETURN %s" % self.items
12077 <contains-stmt> = CONTAINS 12080 subclass_names = []
12084 return STRINGBase.match(
"CONTAINS", string)
12089 <stmt-function-stmt> 12090 = <function-name> ( [ <dummy-arg-name-list> ] ) = Scalar_Expr 12093 subclass_names = []
12094 use_names = [
"Function_Name",
"Dummy_Arg_Name_List",
"Scalar_Expr"]
12098 i = string.find(
"=")
12101 expr = string[i + 1 :].lstrip()
12104 line = string[:i].rstrip()
12105 if not line
or not line.endswith(
")"):
12110 name = line[:i].rstrip()
12113 args = line[i + 1 : -1].strip()
12115 return Function_Name(name), Dummy_Arg_Name_List(args), Scalar_Expr(expr)
12116 return Function_Name(name),
None, Scalar_Expr(expr)
12119 if self.items[1]
is None:
12120 return "%s () = %s" % (self.items[0], self.items[2])
12121 return "%s (%s) = %s" % self.items
12129 ClassType = type(Base)
12131 for clsname
in _names:
12132 my_cls = eval(clsname)
12134 isinstance(my_cls, ClassType)
12135 and issubclass(my_cls, Base)
12136 and not my_cls.__name__.endswith(
"Base")
12140 names = getattr(my_cls,
"subclass_names", []) + getattr(my_cls,
"use_names", [])
12144 if n.endswith(
"_List"):
12150 class %s_List(SequenceBase): 12151 subclass_names = [\'%s\'] 12153 def match(string): return SequenceBase.match(r\',\', %s, string) 12158 elif n.endswith(
"_Name"):
12163 class %s_Name(Base): 12164 subclass_names = [\'Name\'] 12168 elif n.startswith(
"Scalar_"):
12173 class Scalar_%s(Base): 12174 subclass_names = [\'%s\'] 12180 DynamicImport().import_now()