fgen.fortran_parsing#
Support for parsing Fortran type declarations
We just want to make this as helpful as possible when auto-generating our wrappers while keeping the implemenation here as minimal as possible because duplicating the Fortran implementation logic is not the point of this module. The fortran compiler will catch any odd type declarations at compile-time.
To understand what is going on, we start with the syntax for declaring fortran types as defined in Section 5.1 of the Fortran 2003 standard. It looks like the below:
R501 type-declaration-stmt is declaration-type-spec [ [ , attr-spec ] ... :: ] entity-decl-list
R502 declaration-type-spec is intrinsic-type-spec
or TYPE ( derived-type-spec )
or CLASS ( derived-type-spec )
or CLASS ( * )
In short, a type declaration statement is composed of a declaration type specification,
a collection of one or more attribute specifications
and then an entity declaration list.
The declaration type specification can be either an intrinsic type
that has been defined by the language,
or a derived type which has been declared using a type
block elsewhere.
We focus on the combination of the declaration type specification (which we typically shorten to type specification) and the attribute specifications i.e. we largely ignore the entity declarations. In the absence of a defined term in the Fortran standard, we call this combination the type attribute declaration throughout.
To illustrate, consider the following example
real(8), dimension(3), pointer :: heat_uptake
Here is how we would refer to the parts of this example:
type declaration statement:
real(8), dimension(3), pointer :: heat_uptake
declaration type specification (or simply type specification):
real(8)
attribute specifications:
dimension(3), pointer
type attribute declaration:
real(8), dimension(3), pointer
entity declaration (largely ignored by this module, we treat the double colon
::
as part of the entity declaration)::: heat_uptake
One other example using a derived type
type(my_calculator) :: heat_uptake_calculator
Here is how we would refer to the parts of this example:
type declaration statement:
type(my_calculator) :: heat_uptake_calculator
declaration type specification (or simply type specification):
type(my_calculator)
attribute specifications: none
type attribute declaration (same as type specification in this case):
type(my_calculator)
entity declaration (largely ignored by this module, we treat the double colon
::
as part of the entity declaration)::: heat_uptake_calculator
Notes
Fortran type declaration statements (and Fortran in general) are case-insensitive
This module relies heavily on regular expressions. If needed, use an online tool like regex101.com to help you understand them.
SUPPORTED_TYPE_SPECIFICATIONS#
- SUPPORTED_TYPE_SPECIFICATIONS: tuple[str, ...] = ('^INTEGER(\\(.*\\)|)$', '^REAL(\\(.*\\)|)$', '^COMPLEX(\\(.*\\)|)$', '^CHARACTER(\\(.*\\)|)$', '^LOGICAL(\\(.*\\)|)$', 'type\\(\\s?(?P<derived_type_name>[a-z0-9]+)\\s?\\)', 'integer\\(\\s?kind\\s?\\(\\s?(?P<enum_name>[a-z0-9]+)\\s?\\)\\s?\\)')#
The collection of valid type specifications that are supported
This covers both intrinsic type specifications and derived type specifications.
SUPPORTED_ATTRIBUTE_SPECIFICATIONS#
- SUPPORTED_ATTRIBUTE_SPECIFICATIONS: tuple[Union[str, re.Pattern[str]], ...] = ('ALLOCATABLE', 'DIMENSION\\((?P<dimension>(\\*|:|[a-z0-9]+)(,\\s*(\\*|:|[a-z0-9]+))*)\\)', 'POINTER', 'TARGET')#
The collection of valid attribute specifications that are supported
In the type declaration, “type(my_calculator), pointer”, the attribute specification is “pointer” (the other part, “type(my_calculator)”, is simply the type specification (or declaration type specification if you’re being very precise))
Note that only a subset of valid attributes can be specified. The more esoteric attributes have been excluded until the use case for these attributes is better understood.
DimensionAttributeSpecification#
- class DimensionAttributeSpecification(dimensions)[source]#
Bases:
object
Dimension attribute specification
Defines the shape of a data type. See Section 5.1.2.5 of the Fortran 2003 standard for a description of the dimension attribute specification.
Currently, we only support explicit dimensions where the size of the dimension is explicitly declared at compile-time with an integer or execution-time using a variable provided to a procedure (e.g. using “n” which is a variable that is also provided to a procedure). The later form is an automatic explicit dimension and will rely upon the Fortran compiler to validate the attribute declaration since additional context is required about where the attribute is used.
Assumed-sized dimensions (“*”) are not currently supported.
-
dimensions:
tuple
[typing.Union
[str
,int
],...
]# Collection of dimensions of the attribute specification
Can include explicit dimensions (e.g. 5) or automatic explicit dimensions (e.g. “n”). Deferred dimensions (e.g. “:”) are allowed.
- classmethod from_dimension_info(dimension_info)[source]#
Create a DimensionAttributeSpecification from the dimension information
The dimension information describes the shape and dimensionality of a variable.
- Parameters:
dimension_info (
str
) –The dimension information is the content between the () for a dimension attribute. For example, for an attribute “dimension(8, n)” the dimension_info would be “8, n”.
Static dimensions are converted to integers before initialising.
- Returns:
fgen.fortran_parsing.DimensionAttributeSpecification
– New DimensionAttributeSpecification
-
dimensions:
FortranDataType#
- class FortranDataType(type_specification, attribute_specifications)[source]#
Bases:
object
A fortran data type including its attributes
See the docstring of
fgen.fortran_parsing
for further details on Fortran type declaration statements and how we handle and describe them.We are only interested in the type attribute declaration so anything including and after a “::” should be stripped before initialising this class.
-
attribute_specifications:
tuple
[typing.Union
[str
,fgen.fortran_parsing.DimensionAttributeSpecification
],...
]# List of attribute specifications that apply to the Fortran data type
These are our internal representation of attribute specifications e.g. “pointer”, “target”, “dimension(3, 3)”
- property base_python_type: str#
Determine the “base” Python type that represents the Fortran type declaration
This focuses on the base type (float, int, DerivedType etc.) and ignores the modification of this type from attributes such as “dimension” (which mean the ‘full’ python type is some sort of array or iterable). Such dimension handling is done in
equivalent_python_type
.- Returns:
The string representation of the python type
that is equivalent to the base type
(i.e. ignoring any array or other container) of
self
- property dimension_attribute_specification: Optional[DimensionAttributeSpecification]#
Get the dimension attribute of the type if it exists
- Returns:
The dimension attribute if it is present otherwise None
- property equivalent_python_type: str#
Python type-hint for the data type
The “base” type of the equivalent Python type will be:
If the Fortran type has a “dimension” attribute specification, this modifies the “base” type to a tuple that respects the intended shape of the value. n-dimensional variables are supported. TODO: remove this behaviour, doesn’t scale well to long arrays and doesn’t help with deferred shape arrays.
- property fortran_type_attribute_declaration: str#
Fortran type attribute declaration, including attribute specifications.
Attribute specifications are only included if they are applicable.
See the docstring of
fgen.fortran_parsing
for further details.
- classmethod from_str(fortran_type_attribute_declaration)[source]#
Create
FortranDataType
from type declaration statementParses and validates a type declaration statement
- Parameters:
fortran_type_attribute_declaration (
str
) –Fortran type declaration statement
For example, “real(8), dimension(2) :: heat_uptake_sensitivity”
The entity declaration component (including and after “::”) is ignored hence is optional.
See the docstring of
fgen.fortran_parsing
for further details.- Raises:
ValueError – The type declaration statement is invalid
- Return type:
- property has_deferred_size: bool#
Whether this instance represents a type with a deferred size or not.
- Returns:
True
if self represents a type with a deferred size,False
otherwise.
- property is_array: bool#
Whether this instance represents an array or not.
- Returns:
True
if self represents an array,False
otherwise.
- property is_array_of_derived_type: bool#
Whether this instance represents an array of a derived type or not.
- Returns:
True
if self represents an array of a derived type,False
otherwise.
- property is_array_of_float_double: bool#
Whether this instance represents an array of floating double-point type.
- Returns:
True
if self represents a typewhich is an of floating double-point type,
False
otherwise.
- property is_character: bool#
Whether this instance represents a character type
- Returns:
True
if self represents a character type,False
otherwise.
- property is_deferred_array: bool#
Whether this instance represents a deferred size array
- Returns:
True
if self represents a type which is a deferred size arrayFalse
otherwise.
- property is_deferred_array_of_derived_type: bool#
Whether this instance represents a deferred size array of a derived type
- Returns:
True
if self represents a typewhich is a deferred size array of a derived type,
False
otherwise.
- property is_derived_type: bool#
Whether this instance represents a type which is a derived type
- Returns:
True
if self represents a type which is a derived typeFalse
otherwise.True if a type is a derived type, False if it is an intrinsic type
- property is_enum: bool#
Whether this instance represents a type which is an enum.
- Returns:
True
if self represents a type which is an enum.False
otherwise.
- property is_logical: bool#
Whether this instance represents a logical type
- Returns:
True
if self represents a logical type,False
otherwise.
- property is_pointer: bool#
Whether this instance represents a type which is a pointer
- Returns:
True
if self represents a type which is a pointerFalse
otherwise.
-
attribute_specifications: