fparser Reference Guide  0.0.14
Fortran2008.py
1 # Modified work Copyright (c) 2018-2022 Science and Technology
2 # Facilities Council
3 # Original work Copyright (c) 1999-2008 Pearu Peterson
4 
5 # All rights reserved.
6 
7 # Modifications made as part of the fparser project are distributed
8 # under the following license:
9 
10 # Redistribution and use in source and binary forms, with or without
11 # modification, are permitted provided that the following conditions are
12 # met:
13 
14 # 1. Redistributions of source code must retain the above copyright
15 # notice, this list of conditions and the following disclaimer.
16 
17 # 2. Redistributions in binary form must reproduce the above copyright
18 # notice, this list of conditions and the following disclaimer in the
19 # documentation and/or other materials provided with the distribution.
20 
21 # 3. Neither the name of the copyright holder nor the names of its
22 # contributors may be used to endorse or promote products derived from
23 # this software without specific prior written permission.
24 
25 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 
37 # --------------------------------------------------------------------
38 
39 # The original software (in the f2py project) was distributed under
40 # the following license:
41 
42 # Redistribution and use in source and binary forms, with or without
43 # modification, are permitted provided that the following conditions are met:
44 
45 # a. Redistributions of source code must retain the above copyright notice,
46 # this list of conditions and the following disclaimer.
47 # b. Redistributions in binary form must reproduce the above copyright
48 # notice, this list of conditions and the following disclaimer in the
49 # documentation and/or other materials provided with the distribution.
50 # c. Neither the name of the F2PY project nor the names of its
51 # contributors may be used to endorse or promote products derived from
52 # this software without specific prior written permission.
53 
54 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
58 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
60 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
61 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
64 # DAMAGE.
65 
66 """The file implements the Fortran2008 rules as defined in
67  https://j3-fortran.org/doc/year/10/10-007r1.pdf
68 
69 """
70 # pylint: disable=invalid-name
71 # pylint: disable=arguments-differ
72 # pylint: disable=undefined-variable
73 # pylint: disable=eval-used
74 # pylint: disable=exec-used
75 # pylint: disable=unused-import
76 from fparser.common.splitline import string_replace_map
77 from fparser.two import pattern_tools as pattern
78 
79 from fparser.two.utils import (
80  STRINGBase,
81  BracketBase,
82  WORDClsBase,
83  SeparatorBase,
84  Type_Declaration_StmtBase,
85  StmtBase,
86 )
87 from fparser.two.Fortran2003 import (
88  EndStmtBase,
89  BlockBase,
90  SequenceBase,
91  Base,
92  Specification_Part,
93  Stat_Variable,
94  Errmsg_Variable,
95  Source_Expr,
96  KeywordValueBase,
97  Module_Subprogram_Part,
98  Implicit_Part,
99  Implicit_Part_Stmt,
100  Declaration_Construct,
101  Use_Stmt,
102  Import_Stmt,
103  Declaration_Type_Spec,
104  Entity_Decl_List,
105  Component_Decl_List,
106  Stop_Code,
107 )
108 
109 # Import of F2003 classes that are updated in this standard.
110 from fparser.two.Fortran2003 import (
111  Program_Unit as Program_Unit_2003,
112  Attr_Spec as Attr_Spec_2003,
113  Alloc_Opt as Alloc_Opt_2003,
114  Allocate_Stmt as Allocate_Stmt_2003,
115  Type_Declaration_Stmt as Type_Declaration_Stmt_2003,
116  Component_Attr_Spec as Component_Attr_Spec_2003,
117  Data_Component_Def_Stmt as Data_Component_Def_Stmt_2003,
118  Action_Stmt as Action_Stmt_2003,
119  Action_Stmt_C201 as Action_Stmt_C201_2003,
120  Action_Stmt_C802 as Action_Stmt_C802_2003,
121  Action_Stmt_C824 as Action_Stmt_C824_2003,
122  If_Stmt as If_Stmt_2003,
123  Do_Term_Action_Stmt as Do_Term_Action_Stmt_2003,
124  Executable_Construct as Executable_Construct_2003,
125  Executable_Construct_C201 as Executable_Construct_C201_2003,
126 )
127 
128 
129 class Program_Unit(Program_Unit_2003): # R202
130  """
131  Fortran 2008 rule R202
132  program-unit is main-program
133  or external-subprogram
134  or module
135  or submodule
136  or block-data
137 
138  """
139 
140  # Fortran2008 adds the concept of submodules to a program-unit. We
141  # therefore extend the Fortran2003 specification
142  subclass_names = Program_Unit_2003.subclass_names[:]
143  subclass_names.append("Submodule")
144 
145 
146 class Executable_Construct(Executable_Construct_2003): # R213
147  # pylint: disable=invalid-name
148  """
149  Fortran 2003 rule R213
150  executable-construct is action-stmt
151  or associate-construct
152  or block-construct
153  or case-construct
154  or critical-construct
155  or do-construct
156  or forall-construct
157  or if-construct
158  or select-type-construct
159  or where-construct
160 
161  Associated constraints are:
162 
163  "C201 (R208) An execution-part shall not contain an end-function-stmt,
164  end-mp-subprogram-stmt, end-program-stmt, or end-subroutine-stmt."
165 
166  NB: The new block-construct and critical-construct are not yet implemented.
167  TODO: Implement missing F2008 executable-construct (#320)
168 
169  """
170  subclass_names = [
171  "Action_Stmt",
172  "Associate_Construct",
173  "Case_Construct",
174  "Do_Construct",
175  "Forall_Construct",
176  "If_Construct",
177  "Select_Type_Construct",
178  "Where_Construct",
179  ]
180 
181 
182 class Executable_Construct_C201(Executable_Construct_C201_2003):
183  """
184  executable-construct-c201 is executable construct.
185  This applies C201.
186  """
187 
188  subclass_names = Executable_Construct.subclass_names[:]
189  subclass_names[subclass_names.index("Action_Stmt")] = "Action_Stmt_C201"
190 
191 
192 class Action_Stmt(Action_Stmt_2003): # R214
193  """
194  Fortran 2008 rule R214
195  action-stmt is allocate-stmt
196  or assignment-stmt
197  or backspace-stmt
198  or call-stmt
199  or close-stmt
200  or continue-stmt
201  or cycle-stmt
202  or deallocate-stmt
203  or end-function-stmt
204  or end-mp-subprogram-stmt
205  or end-program-stmt
206  or end-subroutine-stmt
207  or endfile-stmt
208  or error-stop-stmt
209  or exit-stmt
210  or flush-stmt
211  or forall-stmt
212  or goto-stmt
213  or if-stmt
214  or inquire-stmt
215  or lock-stmt
216  or nullify-stmt
217  or open-stmt
218  or pointer-assignment-stmt
219  or print-stmt
220  or read-stmt
221  or return-stmt
222  or rewind-stmt
223  or stop-stmt
224  or sync-all-stmt
225  or sync-images-stmt
226  or sync-memory-stmt
227  or unlock-stmt
228  or wait-stmt
229  or where-stmt
230  or write-stmt
231  or arithmetic-if-stmt
232  or computed-goto-stmt
233 
234  The implementation of this rule adds the relevant subclass names
235  for new statements added in Fortran 2008.
236 
237  Associated constraints are:
238 
239  "C201 (R208) An execution-part shall not contain an end-function-stmt,
240  end-mp-subprogram-stmt, end-program-stmt, or end-subroutine-stmt."
241 
242  NB: The following statements are not yet implemented:
243  end-mp-subprogram-stmt, endfile-stmt, lock-stmt, sync-all-stmt,
244  sync-images-stmt, sync-memory-stmt, unlock-stmt.
245 
246  """
247 
248  # Fortran 2008 adds a few additional action-stmt. We therefore
249  # extend the Fortran 2003 specification
250  subclass_names = Action_Stmt_2003.subclass_names[:]
251  subclass_names.append("Error_Stop_Stmt")
252 
253 
254 class Action_Stmt_C201(Action_Stmt_C201_2003):
255  """
256  action-stmt-c201 is action-stmt
257  C201 is applied.
258  """
259 
260  subclass_names = Action_Stmt.subclass_names[:]
261  subclass_names.remove("End_Function_Stmt")
262  subclass_names.remove("End_Subroutine_Stmt")
263 
264 
265 class Action_Stmt_C816(Action_Stmt_C824_2003):
266  """
267  action-stmt-c816 is action-stmt
268  C816 is applied.
269  """
270 
271  subclass_names = Action_Stmt.subclass_names[:]
272  subclass_names.remove("Arithmetic_If_Stmt")
273  subclass_names.remove("Continue_Stmt")
274  subclass_names.remove("Cycle_Stmt")
275  subclass_names.remove("End_Function_Stmt")
276  subclass_names.remove("End_Subroutine_Stmt")
277  subclass_names.remove("Error_Stop_Stmt")
278  subclass_names.remove("Exit_Stmt")
279  subclass_names.remove("Goto_Stmt")
280  subclass_names.remove("Return_Stmt")
281  subclass_names.remove("Stop_Stmt")
282 
283 
284 class Action_Stmt_C828(Action_Stmt_C802_2003):
285  """
286  action-stmt-c828 is action-stmt
287  C828 is applied.
288  """
289 
290  subclass_names = Action_Stmt.subclass_names[:]
291  subclass_names.remove("End_Function_Stmt")
292  subclass_names.remove("End_Subroutine_Stmt")
293  subclass_names.remove("If_Stmt")
294 
295 
296 class Data_Component_Def_Stmt(Data_Component_Def_Stmt_2003): # R436
297  """
298  Fortran 2008 rule 436
299  data-component-def-stmt is declaration-type-spec [
300  [ , component-attr-spec-list ] :: ] component-decl-list
301 
302  The implementation of this rule does not add anything to the Fortran 2003
303  variant but reimplements the match method identical to Fortran 2003 as
304  otherwise the generated Fortran 2008 variant of `Component_Attr_Spec_List`
305  would not be used. Unfortunately, the required `attr_spec_list_cls` can not
306  simply be provided as a class property since the relevant class is only
307  generated at the end of this file using the `use_names` class property of
308  this class.
309 
310  Associated constraints are:
311 
312  "C439 (R436) No component-attr-spec shall appear more than once in a given
313  component-def-stmt."
314  "C440 (R436) If neither the POINTER nor the ALLOCATABLE attribute is
315  specified, the declaration-type-spec in the component-def-stmt shall
316  specify an intrinsic type or a previously defined derived type."
317  "C441 (R436) If the POINTER or ALLOCATABLE attribute is specified, each
318  component-array-spec shall be a deferred-shape-spec-list."
319  "C442 (R436) If a coarray-spec appears, it shall be a
320  deferred-coshape-spec-list and the component shall have the
321  ALLOCATABLE attribute."
322  "C443 (R436) If a coarray-spec appears, the component shall not be of type
323  C_PTR or C_FUNPTR."
324  "C445 (R436) If neither the POINTER nor the ALLOCATABLE attribute is
325  specified, each component-array-spec shall be an
326  explicit-shape-spec-list."
327  "C447 (R436) A component shall not have both the ALLOCATABLE and POINTER
328  attributes."
329  "C448 (R436) If the CONTIGUOUS attribute is specified, the component shall
330  be an array with the POINTER attribute."
331  "C457 (R436) If component-initialization appears, a double-colon separator
332  shall appear before the component-decl-list."
333  "C458 (R436) If component-initialization appears, every type parameter and
334  array bound of the component shall be a colon or constant expression.
335  "C459 (R436) If => appears in component-initialization, POINTER shall
336  appear in the component-attr-spec-list. If = appears in
337  component-initialization, neither POINTER nor ALLOCATABLE shall
338  appear in the component-attr-spec-list."
339 
340  C439-C443, C445, C447-C448, C457-C459 are currently not checked
341  - issue #258.
342 
343  """
344 
345  @staticmethod
346  def match(string):
347  """Implements the matching of a data component definition statement.
348 
349  :param str string: the reader or string to match as a data \
350  component definition statement.
351 
352  :return: a 3-tuple containing declaration type specification, \
353  component attribute specification and component declaration \
354  list if there is a match or None if there is no match.
355  :rtype: `NoneType` or \
356  (:py:class:`fparser.two.Fortran2003.Declaration_Type_Spec`, \
357  :py:class:`fparser.two.Fortran2008.Component_Attr_Spec_List`, \
358  :py:class:`fparser.two.Fortran2003.Component_Decl_List`)
359 
360  """
361  return Type_Declaration_StmtBase.match(
362  Declaration_Type_Spec, Component_Attr_Spec_List, Component_Decl_List, string
363  )
364 
365 
366 class Component_Attr_Spec(Component_Attr_Spec_2003): # R437
367  """
368  Fortran 2008 rule R437
369  component-attr-spec is access-spec
370  or ALLOCATABLE
371  or CODIMENSION lbracket coarray-spec rbracket
372  or CONTIGUOUS
373  or DIMENSION ( component-array-spec )
374  or POINTER
375 
376  In the spec above, lbracket and rbracket are left and right square
377  brackets `[]` but not printed explicitly to avoid misinterpretation
378  as optional parts.
379 
380  This rule adds CODIMENSION and CONTIGUOUS attributes to Fortran2003's R441.
381 
382  """
383 
384  subclass_names = Component_Attr_Spec_2003.subclass_names[:]
385  subclass_names.append("Codimension_Attr_Spec")
386  attributes = Component_Attr_Spec_2003.attributes[:]
387  attributes.append("CONTIGUOUS")
388 
389 
390 class Type_Declaration_Stmt(Type_Declaration_Stmt_2003): # R501
391  """
392  Fortran 2008 rule 501
393  type-declaration-stmt is declaration-type-spec [ [ , attr-spec ] ... :: ]
394  entity-decl-list
395 
396  The implementation of this rule does not add anything to the Fortran 2003
397  variant but overwrites :py:meth:`get_attr_spec_list_cls` to use
398  the Fortran 2008 variant of :py:class:`Attr_Spec_List`.
399 
400  Associated constraints are:
401 
402  "C501 (R501) The same attr-spec shall not appear more than once in a given
403  type-declaration-stmt."
404  "C502 (R501) If a language-binding-spec with a NAME= specifier appears,
405  the entity-decl-list shall consist of a single entity-decl."
406  "C503 (R501) If a language-binding-spec is specified, the entity-decl-list
407  shall not contain any procedure names."
408  "C505 (R501) If initialization appears, a double-colon separator shall
409  appear before the entity-decl-list."
410 
411  C501-C503, C505 are currently not checked - issue #259.
412 
413  """
414 
415  @staticmethod
416  def get_attr_spec_list_cls():
417  """Return the type used to match the attr-spec-list
418 
419  This overwrites the Fortran 2003 type with the Fortran 2008 variant.
420 
421  """
422  return Attr_Spec_List
423 
424 
425 class Codimension_Attr_Spec(WORDClsBase): # R502.d
426  """
427  codimension-attr-spec is CODIMENSION lbracket coarray-spec rbracket
428 
429  In the spec above, lbracket and rbracket are left and right square
430  brackets `[]` but not printed explicitly to avoid misinterpretation
431  as optional parts.
432 
433  """
434 
435  subclass_names = []
436  use_names = ["Coarray_Bracket_Spec"]
437 
438  @staticmethod
439  def match(string):
440  """
441  Implements the matching for the CODIMENSION attribute.
442 
443  :param str string: the string to match as the attribute.
444 
445  :return: `None` if there is no match, otherwise a 2-tuple \
446  containing `CODIMENSION` as a string and the matched \
447  coarray-spec..
448  :rtype: `NoneType` or \
449  (`str`, :py:class:`fparser.two.Fortran2008.Coarray_Bracket_Spec`,)
450 
451  """
452  return WORDClsBase.match(
453  "CODIMENSION", Coarray_Bracket_Spec, string, colons=False, require_cls=True
454  )
455 
456 
457 class Coarray_Bracket_Spec(BracketBase): # R502.d.0
458  """
459  coarray-bracket-spec is lbracket coarray-spec rbracket
460 
461  In the spec above, lbracket and rbracket are left and right square
462  brackets `[]` but not printed explicitly to avoid misinterpretation
463  as optional parts.
464 
465  """
466 
467  subclass_names = []
468  use_names = ["Coarray_Spec"]
469 
470  @staticmethod
471  def match(string):
472  """
473  Implements the matching for the coarray specification
474  including the square brackets.
475 
476  :param str string: the string to match as the specification.
477 
478  :return: `None` if there is no match, otherwise a 3-tuple \
479  containing the left bracket, the matched coarray-spec, \
480  and the right bracket.
481  :rtype: `NoneType` or \
482  (`str`, :py:class:`fparser.two.Fortran2008.Coarray_Spec`, `str`)
483 
484  """
485  return BracketBase.match("[]", Coarray_Spec, string)
486 
487 
488 class Attr_Spec(Attr_Spec_2003): # R502
489  """
490  Fortran 2008 rule R502
491  attr-spec is access-spec
492  or ALLOCATABLE
493  or ASYNCHRONOUS
494  or CODIMENSION lbracket coarray-spec rbracket
495  or CONTIGUOUS
496  or DIMENSION ( array-spec )
497  or EXTERNAL
498  or INTENT ( intent-spec )
499  or INTRINSIC
500  or language-binding-spec
501  or OPTIONAL
502  or PARAMETER
503  or POINTER
504  or PROTECTED
505  or SAVE
506  or TARGET
507  or VALUE
508  or VOLATILE
509 
510  In the spec above, lbracket and rbracket are left and right square
511  brackets `[]` but not printed explicitly to avoid misinterpretation
512  as optional parts.
513 
514  This rule adds CODIMENSION and CONTIGUOUS attributes to Fortran2003's R503.
515 
516  """
517 
518  subclass_names = Attr_Spec_2003.subclass_names[:]
519  subclass_names.append("Codimension_Attr_Spec")
520  use_names = []
521 
522  @staticmethod
523  def match(string):
524  """
525  Implements the matching for attributes of types.
526 
527  :param str string: the string to match as attribute.
528 
529  :return: `None` if there is no match, otherwise a 1-tuple \
530  containing the matched string.
531  :rtype: `NoneType` or (`str`,)
532 
533  """
534  return STRINGBase.match(pattern.abs_attr_spec_f08, string)
535 
536 
537 class Coarray_Spec(Base): # R509
538  """
539  Fortran 2008 rule R509
540  coarray-spec is deferred-coshape-spec-list
541  or explicit-coshape-spec-list
542 
543  """
544 
545  subclass_names = ["Explicit_Coshape_Spec", "Deferred_Coshape_Spec_List"]
546 
547 
548 class Deferred_Coshape_Spec(SeparatorBase): # R510
549  """
550  Fortran 2008 rule R510
551  deferred-coshape-spec is :
552 
553  """
554 
555  subclass_names = []
556 
557  @staticmethod
558  def match(string):
559  """
560  Implements the matching for deferred coarray shape specification.
561 
562  :param str string: the string to match as deferred shape.
563 
564  :return: `None` if there is no match, otherwise a 2-tuple \
565  containing `None`.
566  :rtype: `NoneType` or (`None`, `None`)
567 
568  """
569  if string == ":":
570  return (None, None)
571  return None
572 
573 
574 class Explicit_Coshape_Spec(SeparatorBase): # R511
575  """
576  Fortran 2008 rule R511
577  explicit-coshape-spec is [ coshape-spec-list , ] [ lower-cobound : ] *
578 
579  Associated constraint is:
580 
581  "C529 (R511) A lower-cobound or upper-cobound that is not a constant
582  expression shall appear only in a subprogram, BLOCK construct, or
583  interface body."
584 
585  C529 is currently not checked - issue #259.
586 
587  """
588 
589  subclass_names = []
590  use_names = ["Coshape_Spec_List", "Lower_Cobound"]
591 
592  @staticmethod
593  def match(string):
594  """
595  Implements the matching for explicit coarray shape specification.
596 
597  :param str string: the string to match as deferred shape.
598 
599  :return: `None` if there is no match, otherwise a 2-tuple \
600  containing matched coshape-spec-list or `None` and \
601  matched lower-cobound or `None`.
602  :rtype: `NoneType` or \
603  (:py:class:`fparser.two.Fortran2008.Coshape_Spec_List` or `None`, \
604  :py:class:`fparser.two:Fortran2008.Lower_Cobound` or `None`)
605 
606  """
607  if not string.endswith("*"):
608  return None
609  line = string[:-1].rstrip()
610  if not line:
611  return (None, None)
612  if line.endswith(":"):
613  line, repmap = string_replace_map(line[:-1].rstrip())
614  sep_pos = line.rfind(",")
615  if sep_pos == -1:
616  return (None, Lower_Cobound(repmap(line)))
617  return (
618  Coshape_Spec_List(repmap(line[:sep_pos].rstrip())),
619  Lower_Cobound(repmap(line[sep_pos + 1 :].lstrip())),
620  )
621  if not line.endswith(","):
622  return None
623  line = line[:-1].rstrip()
624  return (Coshape_Spec_List(line), None)
625 
626  def tostr(self):
627  """
628  Converts the explicit coarray shape specification to string.
629 
630  :return: the shape specification as string.
631  :rtype: str
632 
633  """
634  s = ""
635  if self.items[0]:
636  s += str(self.items[0]) + ", "
637  if self.items[1]:
638  s += str(self.items[1]) + " : "
639  s += "*"
640  return s
641 
642 
643 class Coshape_Spec(SeparatorBase): # R511.a
644  """
645  coshape-spec is [ lower-cobound : ] upper-cobound
646 
647  """
648 
649  subclass_names = []
650  use_names = ["Lower_Cobound", "Upper_Cobound"]
651 
652  @staticmethod
653  def match(string):
654  """
655  Implements the matching for a coarray shape.
656 
657  :param str string: the string to match as shape.
658 
659  :return: `None` if there is no match, otherwise a 2-tuple with \
660  lower bound if given or `None`, and upper bound.
661  :rtype: `NoneType` or \
662  (`None`, :py:class:`fparser.two.Fortran2008.Upper_Cobound`) or \
663  (:py:class:`fparser.two.Fortran2008.Lower_Cobound`, \
664  :py:class:`fparser.two.Fortran2008.Upper_Cobound`)
665 
666  """
667  line, repmap = string_replace_map(string)
668  if ":" not in line:
669  return (None, Upper_Cobound(string))
670  lower, upper = line.split(":", 1)
671  lower = lower.rstrip()
672  upper = upper.lstrip()
673  if not upper:
674  return None
675  if not lower:
676  return None
677  return (Lower_Cobound(repmap(lower)), Upper_Cobound(repmap(upper)))
678 
679  def tostr(self):
680  """
681  Converts the Shape specification to string.
682 
683  :return: the shape specification as string.
684  :rtype: str
685 
686  """
687  if self.items[0] is None:
688  return str(self.items[1])
689  return SeparatorBase.tostr(self)
690 
691 
692 class Lower_Cobound(Base): # R512
693  """
694  Fortran 2008 rule R512
695  lower-cobound is specification-expr
696 
697  """
698 
699  subclass_names = ["Specification_Expr"]
700 
701 
702 class Upper_Cobound(Base): # R513
703  """
704  Fortran 2008 rule R513
705  upper-cobound is specification-expr
706 
707  """
708 
709  subclass_names = ["Specification_Expr"]
710 
711 
712 class Do_Term_Action_Stmt(Do_Term_Action_Stmt_2003): # R826
713  """
714  Fortran 2008 rule R826
715  do-term-action-stmt is action-stmt
716 
717  Associated constraints are:
718 
719  "C816 (R826) A do-term-action-stmt shall not be an arithmetic-if-stmt,
720  continue-stmt, cycle-stmt, end-function-stmt, end-mp-subprogram-stmt,
721  end-program-stmt, end-subroutine-stmt, error-stop-stmt, exit-stmt,
722  goto-stmt, return-stmt, or stop-stmt."
723  """
724 
725  subclass_names = ["Action_Stmt_C816"]
726 
727 
728 class Alloc_Opt(Alloc_Opt_2003):
729  """
730  Fortran2008 rule R627
731  alloc-opt is ERRMSG = errmsg-variable
732  or MOLD = source-expr
733  or SOURCE = source-expr
734  or STAT = stat-variable
735 
736  Extends the Fortran2003 version of this class by updating the keyword
737  pairs (used in match) with support for MOLD.
738 
739  """
740 
741  _keyword_pairs = [
742  ("STAT", Stat_Variable),
743  ("ERRMSG", Errmsg_Variable),
744  ("SOURCE", Source_Expr),
745  ("MOLD", Source_Expr),
746  ]
747 
748 
749 class Allocate_Stmt(Allocate_Stmt_2003): # R626
750  """
751  Fortran 2008 rule R626
752  allocate-stmt is ALLOCATE ( [ type-spec :: ] allocation-list
753  [, alloc-opt-list ] )
754 
755  The implementation of this rule simply ensures that the Fortran2008 version
756  of Alloc_Opt is used.
757 
758  """
759 
760  subclass_names = []
761  use_names = ["Type_Spec", "Allocation_List", "Alloc_Opt_List"]
762 
763  @classmethod
764  def alloc_opt_list(cls):
765  """
766  :returns: the Fortran2008 flavour of Alloc_Opt_List.
767  :rtype: type
768  """
769  return Alloc_Opt_List
770 
771 
772 class If_Stmt(If_Stmt_2003): # R837
773  """
774  Fortran 2008 rule R837
775  if-stmt is IF ( scalar-logical-expr ) action-stmt
776 
777  The implementation of this rule only replaces the :py:attr:`use_names` and
778  :py:attr:`action_stmt_class` attributes to use the Fortran 2008 variant
779  :py:class:`Action_Stmt_C828` instead of
780  :py:class:`fparser.two.Fortran2003.Action_Stmt_C802`.
781 
782  Associated constraints are:
783 
784  C828 (R837) The action-stmt in the if-stmt shall not be an end-function-stmt,
785  end-mp-subprogram-stmt, end-program-stmt, end-subroutine-stmt, or if-stmt.
786 
787  """
788 
789  use_names = ["Scalar_Logical_Expr", "Action_Stmt_C828"]
790  action_stmt_cls = Action_Stmt_C828
791 
792 
793 class Error_Stop_Stmt(StmtBase, WORDClsBase): # R856
794  """
795  Fortran 2008 rule R856
796  error-stop-stmt is ERROR STOP [ stop-code ]
797 
798  """
799 
800  subclass_names = []
801  use_names = ["Stop_Code"]
802 
803  @staticmethod
804  def match(string):
805  """Check whether the input matches the rule
806 
807  :param str string: Text that we are trying to match.
808 
809  :returns: None if there is no match or, if there is a match, a \
810  2-tuple containing a string matching 'ERROR STOP' and an \
811  instance of :py:class:`fparser.two.Fortran2003.Stop_Code` \
812  (or None if an instance of 'Stop_Code' is not required and \
813  not provided).
814  :rtype: (str, :py:class:`fparser.two.Fortran2003.Stop_Code` or None) \
815  or NoneType
816 
817  """
818  return WORDClsBase.match("ERROR STOP", Stop_Code, string)
819 
820 
821 class Specification_Part_C1112(Specification_Part): # C1112
822  """Fortran 2008 constraint C1112
823  C1112 A submodule specification-part shall not contain a
824  format-stmt, entry-stmt, or stmt-function-stmt.
825 
826  These statements are found in the following rule hierarchy
827 
828  format-stmt Specification_Part/implicit_part/implicit_part_stmt/format_stmt
829  Specification_Part/declaration_construct/format_stmt
830  entry-stmt Specification_Part/implicit_part/implicit_part_stmt/entry_stmt
831  Specification_Part/declaration_construct/entry_stmt
832  stmt-function-stmt Specification_Part/declaration_construct/
833  stmt-function-stmt
834 
835  Therefore we need to specialise implicit_part, implicit_part_stmt
836  and declaration_construct
837 
838  """
839 
840  use_names = [
841  "Use_Stmt",
842  "Import_Stmt",
843  "Implicit_Part_C1112",
844  "Declaration_Construct_C1112",
845  ]
846 
847  @staticmethod
848  def match(reader):
849  """Check whether the input matches the rule
850 
851  param reader: the fortran file reader containing the line(s)
852  of code that we are trying to match
853  :type reader: :py:class:`fparser.common.readfortran.FortranFileReader`
854  or
855  :py:class:`fparser.common.readfortran.FortranStringReader`
856  :return: `tuple` containing a single `list` which contains
857  instance of the classes that have matched if there is
858  a match or `None` if there is no match
859 
860  """
861  return BlockBase.match(
862  None,
863  [Use_Stmt, Import_Stmt, Implicit_Part_C1112, Declaration_Construct_C1112],
864  None,
865  reader,
866  )
867 
868 
869 class Implicit_Part_C1112(Implicit_Part): # C1112
870  """Fortran 2008 constraint C1112
871  C1112 A submodule specification-part shall not contain a
872  format-stmt, entry-stmt, or stmt-function-stmt.
873 
874  This class specialises 'Implicit_Part' so that the specialised
875  'Implicit_Part_Stmt_C1112' is called rather than the original
876  'Implicit_Part_Stmt'
877 
878  """
879 
880  use_names = ["Implicit_Part_Stmt_C1112", "Implicit_Stmt"]
881 
882  @staticmethod
883  def match(reader):
884  """Check whether the input matches the rule
885 
886  param reader: the fortran file reader containing the line(s)
887  of code that we are trying to match
888  :type reader: :py:class:`fparser.common.readfortran.FortranFileReader`
889  or
890  :py:class:`fparser.common.readfortran.FortranStringReader`
891  :return: `tuple` containing a single `list` which contains
892  instance of the classes that have matched if there is
893  a match or `None` if there is no match
894 
895  """
896  return BlockBase.match(None, [Implicit_Part_Stmt_C1112], None, reader)
897 
898 
899 class Implicit_Part_Stmt_C1112(Implicit_Part_Stmt): # C1112
900  """Fortran 2008 constraint C1112
901  C1112 A submodule specification-part shall not contain a
902  format-stmt, entry-stmt, or stmt-function-stmt.
903 
904  This class specialises 'Implicit_Part_Stmt' to remove
905  'Format_Stmt' and 'Entry_Stmt'
906 
907  """
908 
909  subclass_names = Implicit_Part_Stmt.subclass_names[:]
910  subclass_names.remove("Format_Stmt")
911  subclass_names.remove("Entry_Stmt")
912 
913 
914 class Declaration_Construct_C1112(Declaration_Construct): # C1112
915  """Fortran 2008 constraint C1112
916  C1112 A submodule specification-part shall not contain a
917  format-stmt, entry-stmt, or stmt-function-stmt.
918 
919  This class specialises 'Declaration_Construct' to remove
920  'Format_Stmt', 'Entry_Stmt' and 'Stmt_Function_Stmt'
921 
922  """
923 
924  subclass_names = Declaration_Construct.subclass_names[:]
925  subclass_names.remove("Format_Stmt")
926  subclass_names.remove("Entry_Stmt")
927  # Commented out Stmt_Function_Stmt as it can falsely match an
928  # access to an array or function. Reintroducing statement
929  # functions is captured in issue #202.
930  # subclass_names.remove('Stmt_Function_Stmt')
931 
932 
933 class Submodule(BlockBase): # R1116 [C1112,C1114]
934  """Fortran 2008 rule R1116
935  submodule is submodule-stmt
936  [ specification-part ]
937  [ module-subprogram-part ]
938  end-submodule-stmt
939 
940  C1112 A submodule specification-part shall not contain a
941  format-stmt, entry-stmt, or stmt-function-stmt.
942  This constraint is handled by specialising the Specification_Part
943  class
944 
945  C1114 If a submodule-name appears in the end-submodule-stmt, it
946  shall be identical to the one in the submodule-stmt.
947  This constraint is handled by the Base class with the names being
948  provided by the 'Submodule_Stmt and 'End_Submodule_Stmt' classes
949  via a `get_name` method
950 
951  """
952 
953  subclass_names = []
954  use_names = [
955  "Submodule_Stmt",
956  "Specification_Part_C1112",
957  "Module_Subprogram_Part",
958  "End_Submodule_Stmt",
959  ]
960 
961  @staticmethod
962  def match(reader):
963  """Check whether the input matches the rule
964 
965  param reader: the fortran file reader containing the line(s)
966  of code that we are trying to match
967  :type reader: :py:class:`fparser.common.readfortran.FortranFileReader`
968  or
969  :py:class:`fparser.common.readfortran.FortranStringReader`
970  :return: `tuple` containing a single `list` which contains
971  instance of the classes that have matched if there is
972  a match or `None` if there is no match
973 
974  """
975 
976  result = BlockBase.match(
977  Submodule_Stmt,
978  [Specification_Part_C1112, Module_Subprogram_Part],
979  End_Submodule_Stmt,
980  reader,
981  )
982  return result
983 
984 
985 class Submodule_Stmt(Base): # R1117
986  """
987  Fortran 2008 rule R1117
988  submodule-stmt is SUBMODULE ( parent-identifier ) submodule-name
989 
990  """
991 
992  subclass_names = []
993  use_names = ["Submodule_Name", "Parent_Identifier"]
994 
995  @staticmethod
996  def match(fstring):
997  """Check whether the input matches the rule
998 
999  param string fstring : contains the Fortran that we are trying
1000  to match
1001 
1002  :return: instances of the Classes that have matched if there
1003  is a match or `None` if there is no match
1004 
1005  """
1006  # First look for "SUBMODULE"
1007  name = "SUBMODULE"
1008  if fstring[: len(name)].upper() != name:
1009  # the string does not start with SUBMODULE so does not
1010  # match
1011  return None
1012  # "SUBMODULE is found so strip it out and split the remaining
1013  # line by parenthesis
1014  from fparser.common.splitline import splitparen
1015 
1016  splitline = splitparen(fstring[len(name) :].lstrip())
1017  # We expect 2 entries, the first being parent_identifier with
1018  # brackets and the second submodule_name. However for some
1019  # reason we get an additional empty 1st entry when using
1020  # splitline
1021  if len(splitline) != 3:
1022  # format is not ( parent_identifier ) submodule_name
1023  return None
1024  spurious = splitline[0]
1025  parent_id_brackets = splitline[1]
1026  submodule_name = splitline[2]
1027  if spurious:
1028  # this should be empty
1029  return None
1030  # Make sure the parent identifier contained in splitline[1] is
1031  # enclosed with round brackets
1032  if parent_id_brackets[0] != "(":
1033  return None
1034  if parent_id_brackets[-1] != ")":
1035  return None
1036  parent_id = parent_id_brackets[1:-1].lstrip().rstrip()
1037  # Format is OK from this Class' perspective. Pass on
1038  # parent_identifier and submodule name to appropriate classes
1039  return Parent_Identifier(parent_id), Submodule_Name(submodule_name)
1040 
1041  def tostr(self):
1042  """return the fortran representation of this object"""
1043  # return self.string # this returns the original code
1044  return "SUBMODULE ({0}) {1}".format(self.items[0], self.items[1])
1045 
1046  def get_name(self): # C1114
1047  """Fortran 2008 constraint C1114
1048  return the submodule name. This is used by the base class to check
1049  whether the submodule name matches the name used for the end
1050  submodule statement if one is provided.
1051 
1052  :return: the name of the submodule stored in a Name class
1053  :return type: :py:class:`fparser.two.Fortran2003.Name`
1054  """
1055  return self.items[1]
1056 
1057 
1058 class End_Submodule_Stmt(EndStmtBase): # R1119
1059  """
1060  Fortran 2008 rule R1119
1061  end-submodule-stmt is END [ SUBMODULE [ submodule-name ] ]
1062 
1063  """
1064 
1065  subclass_names = []
1066  use_names = ["Submodule_Name"]
1067 
1068  @staticmethod
1069  def match(fstring):
1070  """Check whether the input matches the rule
1071 
1072  param string fstring : contains the Fortran that we are trying
1073  to match
1074 
1075  :return: instances of the Classes that have matched if there
1076  is a match or `None` if there is no match
1077 
1078  """
1079  return EndStmtBase.match("SUBMODULE", Submodule_Name, fstring)
1080 
1081  def get_name(self): # C1114
1082  """Fortran 2008 constraint C1114 return the submodule name as
1083  specified by the end submodule statement or `None` if one is
1084  not specified. This is used by the base class to check whether
1085  this name matches the submodule name.
1086 
1087  :return: the name of the submodule stored in a Name class
1088  :return type: :py:class:`fparser.two.Fortran2003.Name` or `None`
1089 
1090  """
1091  return self.items[1]
1092 
1093 
1094 class Parent_Identifier(Base): # R1118 (C1113)
1095  """Fortran 2008 rule R1118
1096  parent-identifier is ancestor-module-name [ : parent-submodule-name ]
1097 
1098  C1113 The ancestor-module-name shall be the name of a nonintrinsic
1099  module; the parent-submodule name shall be the name of a
1100  descendant of that module.
1101  This constraint can not be tested by fparser in general as the
1102  module or submodule may be in a different file. We therefore do
1103  not check this constraint in fparser.
1104 
1105  """
1106 
1107  use_names = ["Ancestor_Module_Name", "Parent_SubModule_Name"]
1108 
1109  @staticmethod
1110  def match(fstring):
1111  """Check whether the input matches the rule
1112 
1113  param string fstring : contains the Fortran that we are trying
1114  to match
1115 
1116  :return: instances of the Classes that have matched if there
1117  is a match or `None` if there is no match
1118 
1119  """
1120  split_string = fstring.split(":")
1121  len_split_string = len(split_string)
1122  lhs_name = split_string[0].lstrip().rstrip()
1123  if len_split_string == 1:
1124  return Ancestor_Module_Name(lhs_name), None
1125  elif len_split_string == 2:
1126  rhs_name = split_string[1].lstrip().rstrip()
1127  return Ancestor_Module_Name(lhs_name), Parent_SubModule_Name(rhs_name)
1128  # we expect at most one ':' in our input so the match fails
1129  return None
1130 
1131  def tostr(self):
1132  """return the fortran representation of this object"""
1133  # return self.string # this returns the original code
1134  if self.items[1]:
1135  return "{0}:{1}".format(self.items[0], self.items[1])
1136  return str(self.items[0])
1137 
1138 
1139 #
1140 # GENERATE Scalar_, _List, _Name CLASSES
1141 #
1142 
1143 
1144 ClassType = type(Base)
1145 _names = dir()
1146 for clsname in _names:
1147  cls = eval(clsname)
1148  if not (
1149  isinstance(cls, ClassType)
1150  and issubclass(cls, Base)
1151  and not cls.__name__.endswith("Base")
1152  ):
1153  continue
1154 
1155  names = getattr(cls, "subclass_names", []) + getattr(cls, "use_names", [])
1156  for n in names:
1157  if n in _names:
1158  continue
1159  if n.endswith("_List"):
1160  _names.append(n)
1161  n = n[:-5]
1162  # Generate 'list' class
1163  exec(
1164  """\
1165 class %s_List(SequenceBase):
1166  subclass_names = [\'%s\']
1167  use_names = []
1168  @staticmethod
1169  def match(string): return SequenceBase.match(r\',\', %s, string)
1170 """
1171  % (n, n, n)
1172  )
1173  elif n.endswith("_Name"):
1174  _names.append(n)
1175  n = n[:-5]
1176  exec(
1177  """\
1178 class %s_Name(Base):
1179  subclass_names = [\'Name\']
1180 """
1181  % (n)
1182  )
1183  elif n.startswith("Scalar_"):
1184  _names.append(n)
1185  n = n[7:]
1186  exec(
1187  """\
1188 class Scalar_%s(Base):
1189  subclass_names = [\'%s\']
1190 """
1191  % (n, n)
1192  )