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_uptakedeclaration type specification (or simply type specification):
real(8)attribute specifications:
dimension(3), pointertype attribute declaration:
real(8), dimension(3), pointerentity 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_calculatordeclaration 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:
objectDimension 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:
objectA fortran data type including its attributes
See the docstring of
fgen.fortran_parsingfor 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_parsingfor further details.
- classmethod from_str(fortran_type_attribute_declaration)[source]#
Create
FortranDataTypefrom 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_parsingfor 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:
Trueif self represents a type with a deferred size,Falseotherwise.
- property is_array: bool#
Whether this instance represents an array or not.
- Returns:
Trueif self represents an array,Falseotherwise.
- property is_array_of_derived_type: bool#
Whether this instance represents an array of a derived type or not.
- Returns:
Trueif self represents an array of a derived type,Falseotherwise.
- property is_array_of_float_double: bool#
Whether this instance represents an array of floating double-point type.
- Returns:
Trueif self represents a typewhich is an of floating double-point type,
Falseotherwise.
- property is_character: bool#
Whether this instance represents a character type
- Returns:
Trueif self represents a character type,Falseotherwise.
- property is_deferred_array: bool#
Whether this instance represents a deferred size array
- Returns:
Trueif self represents a type which is a deferred size arrayFalseotherwise.
- property is_deferred_array_of_derived_type: bool#
Whether this instance represents a deferred size array of a derived type
- Returns:
Trueif self represents a typewhich is a deferred size array of a derived type,
Falseotherwise.
- property is_derived_type: bool#
Whether this instance represents a type which is a derived type
- Returns:
Trueif self represents a type which is a derived typeFalseotherwise.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:
Trueif self represents a type which is an enum.Falseotherwise.
- property is_logical: bool#
Whether this instance represents a logical type
- Returns:
Trueif self represents a logical type,Falseotherwise.
- property is_pointer: bool#
Whether this instance represents a type which is a pointer
- Returns:
Trueif self represents a type which is a pointerFalseotherwise.
-
attribute_specifications: