Skip to content

Commit ae54830

Browse files
committed
Fix parse failures with REGEX frontend due to white space in declarations (#318)
1 parent 77114a9 commit ae54830

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

loki/frontend/regex.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -900,8 +900,8 @@ def __init__(self):
900900
super().__init__(
901901
r'^(((?:type|class)[ \t]*\([ \t]*(?P<typename>\w+)[ \t]*\))|' # TYPE or CLASS keyword with typename
902902
r'^([ \t]*(?P<basic_type>(logical|real|integer|complex|character))'
903-
r'(?P<param>\((kind|len)=[a-z0-9_-]+\))?[ \t]*))'
904-
r'(?:[ \t]*,[ \t]*[a-z]+(?:\((.(\(.*\))?)*?\))?)*' # Optional attributes
903+
r'[ \t]*(?P<param>\([ \t]*(kind|len)[ \t]*=[ \t]*[a-z0-9_-]+[ \t]*\))?[ \t]*))'
904+
r'(?:[ \t]*,[ \t]*[a-z]+(?:[ \t]*\((.(\(.*\))?)*?\))?)*' # Optional attributes
905905
r'(?:[ \t]*::)?' # Optional `::` delimiter
906906
r'[ \t]*' # Some white space
907907
r'(?P<variables>\w+\b.*?)$', # Variable names
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# (C) Copyright 2018- ECMWF.
2+
# This software is licensed under the terms of the Apache Licence Version 2.0
3+
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
4+
# In applying this licence, ECMWF does not waive the privileges and immunities
5+
# granted to it by virtue of its status as an intergovernmental organisation
6+
# nor does it submit to any jurisdiction.
7+
8+
"""
9+
Verify correct parsing behaviour of the REGEX frontend
10+
"""
11+
12+
from loki.frontend import REGEX
13+
from loki.types import BasicType, DerivedType
14+
from loki.subroutine import Subroutine
15+
16+
def test_declaration_whitespace_attributes():
17+
"""
18+
Test correct behaviour with/without white space inside declaration attributes
19+
(reported in #318).
20+
"""
21+
fcode = """
22+
subroutine my_whitespace_declaration_routine(kdim, state_t0, paux)
23+
use type_header, only: dimension_type, STATE_TYPE, aux_type, jprb
24+
implicit none
25+
TYPE( DIMENSION_TYPE) , INTENT (IN) :: KDIM
26+
type (state_type ) , intent ( in ) :: state_t0
27+
TYPE (AUX_TYPE) , InteNT( In) :: PAUX
28+
CHARACTER ( LEN=10) :: STR
29+
REAL( KIND = JPRB ) :: VAR
30+
end subroutine
31+
""".strip()
32+
33+
routine = Subroutine.from_source(fcode, frontend=REGEX)
34+
35+
# Verify that variables and dtype information has been extracted correctly
36+
assert routine.variables == ('kdim', 'state_t0', 'paux', 'str', 'var')
37+
assert isinstance(routine.variable_map['kdim'].type.dtype, DerivedType)
38+
assert routine.variable_map['kdim'].type.dtype.name.lower() == 'dimension_type'
39+
assert isinstance(routine.variable_map['state_t0'].type.dtype, DerivedType)
40+
assert routine.variable_map['state_t0'].type.dtype.name.lower() == 'state_type'
41+
assert isinstance(routine.variable_map['paux'].type.dtype, DerivedType)
42+
assert routine.variable_map['paux'].type.dtype.name.lower() == 'aux_type'
43+
assert routine.variable_map['str'].type.dtype == BasicType.CHARACTER
44+
assert routine.variable_map['var'].type.dtype == BasicType.REAL
45+
46+
routine.make_complete()
47+
48+
# Verify that additional type attributes are correct after full parse
49+
assert routine.variables == ('kdim', 'state_t0', 'paux', 'str', 'var')
50+
assert isinstance(routine.variable_map['kdim'].type.dtype, DerivedType)
51+
assert routine.variable_map['kdim'].type.dtype.name.lower() == 'dimension_type'
52+
assert routine.variable_map['kdim'].type.intent == 'in'
53+
assert isinstance(routine.variable_map['state_t0'].type.dtype, DerivedType)
54+
assert routine.variable_map['state_t0'].type.dtype.name.lower() == 'state_type'
55+
assert routine.variable_map['state_t0'].type.intent == 'in'
56+
assert isinstance(routine.variable_map['paux'].type.dtype, DerivedType)
57+
assert routine.variable_map['paux'].type.dtype.name.lower() == 'aux_type'
58+
assert routine.variable_map['paux'].type.intent == 'in'
59+
assert routine.variable_map['str'].type.dtype == BasicType.CHARACTER
60+
assert routine.variable_map['str'].type.length == 10
61+
assert routine.variable_map['var'].type.dtype == BasicType.REAL
62+
assert routine.variable_map['var'].type.kind == 'jprb'

0 commit comments

Comments
 (0)