MetOffice / MetOffice/fab

Fortran std support

Open
#560 0 comments 0 reactions 0 assignees View on GitHub
Low priority
Dominant language
Python
Stars
9
Forks
9
Avg merge
12d 12h
Merged PRs (30d)
2

Description

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`.

Contributor guide

Open the contributing guide

Research direction

Inspect parse/fortran.py and the fparser standard handling, then reproduce the issue by applying the shown std="f2003" change in tests/system_tests/CFortranInterop/test_CFortranInterop.py. Compare the F2003 and F2008 type and list classes, and use the test to verify that the C/Fortran interoperability case links successfully without missing symbols.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
build-system, compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.