Skip to content

Fortran std support #560

Description

@hiker

While the analyse step supports specifying the Fortran standard to be used by fparser. But parse/fortran.py does hard-code some classes Fortran 2008, and so de-facto the standard does not work (admittedly in rather rare circumstances like mixing C and Fortran).

Test:

git diff     CFortranInterop/test_CFortranInterop.py 
diff --git a/tests/system_tests/CFortranInterop/test_CFortranInterop.py b/tests/system_tests/CFortranInterop/test_CFortranInterop.py
index 1231c37..ccff586 100644
--- a/tests/system_tests/CFortranInterop/test_CFortranInterop.py
+++ b/tests/system_tests/CFortranInterop/test_CFortranInterop.py
@@ -35,7 +35,8 @@ def test_CFortranInterop(tmp_path):
         c_pragma_injector(config)
         preprocess_c(config)
         preprocess_fortran(config)
-        analyse(config, root_symbol='main')
+        analyse(config, root_symbol='main',
+                std="f2003")
         compile_c(config, common_flags=['-c', '-std=c99'])
         with warns(UserWarning, match="Removing managed flag"):
             compile_fortran(config, common_flags=['-c'])

Results in linking errors due to missing symbols.

Most cases can be fixed by e.g.:


<                 elif obj_type == Type_Declaration_Stmt:
---
>                 elif isinstance(obj, Type_Declaration_Stmt):

and importing Type_Declaration_Stmt from fparser.two.fortran2003, NOT fparser.two.fortran2008 (since f2008's class is derived from the 2003 class).

Main issue is that the above inheritance does NOT apply for *_List, esp. Attr_Spec_List (all *_List classes are programmatically created in fparser), meaning:

                    specs = _typed_child(obj, Attr_Spec_List)

does not work (since Attr_Spec_list is either F2003 or 2008).

Possible solutions: either import both types and check for a tuple:

...
from f2008  Type_Declaration_Stmt as Type_Declaration_Stmt_2008...
...
                    specs = _typed_child(obj, (Attr_Spec_List, Type_Declaration_Stmt_2008))

Or, using knowledge about fparser's implementation (which avoids importing anything from Fortran2008)

                         if isinstance(child, SequenceBase) and child.subclass_names == ["Attr_Spec"]:
                             specs = child
                             break
                     else:
                         specs = None

Ideally, fparser would provide an API to use this (or maybe the implementation can be changed that F2008.*_List inherits from F2003.*_List.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions