Skip to content

Commit

Permalink
#426 extend fix to F2008 and refactor Connect_Spec implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
arporter committed Jan 10, 2024
1 parent 3d0b6a0 commit e79199d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 90 deletions.
86 changes: 50 additions & 36 deletions src/fparser/two/Fortran2003.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python

# Modified work Copyright (c) 2017-2023 Science and Technology
# Modified work Copyright (c) 2017-2024 Science and Technology
# Facilities Council.
# Original work Copyright (c) 1999-2008 Pearu Peterson

Expand Down Expand Up @@ -8602,50 +8602,64 @@ class Connect_Spec(KeywordValueBase):
"Scalar_Int_Variable",
]

@staticmethod
def match(string):
"""
@classmethod
def _keyword_value_list(cls):
"""
Defines the valid keywords and corresponding classes to match against.
This has to be a method rather than a class property as those classes
are generated after this class has been created.
:returns: list of keyword, class pairs to match against.
:rtype: list[tuple[str, type]]
"""
result = [
("ACCESS", Scalar_Default_Char_Expr),
("ACTION", Scalar_Default_Char_Expr),
("ASYNCHRONOUS", Scalar_Default_Char_Expr),
("BLANK", Scalar_Default_Char_Expr),
("DECIMAL", Scalar_Default_Char_Expr),
("DELIM", Scalar_Default_Char_Expr),
("ENCODING", Scalar_Default_Char_Expr),
("FORM", Scalar_Default_Char_Expr),
("PAD", Scalar_Default_Char_Expr),
("POSITION", Scalar_Default_Char_Expr),
("ROUND", Scalar_Default_Char_Expr),
("SIGN", Scalar_Default_Char_Expr),
("STATUS", Scalar_Default_Char_Expr),
("ERR", Label),
("FILE", File_Name_Expr),
("IOSTAT", Scalar_Int_Variable),
("IOMSG", Iomsg_Variable),
("RECL", Scalar_Int_Expr),
("UNIT", File_Unit_Number),
]
if "open-convert" in EXTENSIONS():
# The CONVERT keyword is a non-standard extension supported by
# many compilers.
result.append(("CONVERT", Scalar_Default_Char_Expr))
return result

@classmethod
def match(cls, string):
"""Implements the matching for connect-spec.
Note that this is implemented as a `classmethod` (not a
`staticmethod`), using attribute keywords from the list provided
as a class method. This allows expanding this list for
Fortran 2008 without having to reimplement the matching.
:param str string: Fortran code to check for a match
:return: 2-tuple containing the keyword and value or None if the
supplied string is not a match
:rtype: 2-tuple containing keyword (e.g. "UNIT") and associated value
"""
if "=" not in string:
# The only argument which need not be named is the unit number
return "UNIT", File_Unit_Number(string)
# We have a keyword-value pair. Check whether it is valid...
keyword_list = [
"ACCESS",
"ACTION",
"ASYNCHRONOUS",
"BLANK",
"DECIMAL",
"DELIM",
"ENCODING",
"FORM",
"PAD",
"POSITION",
"ROUND",
"SIGN",
"STATUS",
]
if "open-convert" in EXTENSIONS():
# The CONVERT keyword is a non-standard extension supported by
# many compilers.
keyword_list.append("CONVERT")

for keyword, value in [
(
keyword_list,
Scalar_Default_Char_Expr,
),
("ERR", Label),
("FILE", File_Name_Expr),
("IOSTAT", Scalar_Int_Variable),
("IOMSG", Iomsg_Variable),
("RECL", Scalar_Int_Expr),
("UNIT", File_Unit_Number),
]:
for keyword, value in cls._keyword_value_list():
try:
obj = KeywordValueBase.match(keyword, value, string, upper_lhs=True)
except NoMatchError:
Expand Down
66 changes: 12 additions & 54 deletions src/fparser/two/Fortran2008/connect_spec_r905.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -----------------------------------------------------------------------------
# BSD 3-Clause License
#
# Copyright (c) 2023, Science and Technology Facilities Council.
# Copyright (c) 2023-2024, Science and Technology Facilities Council.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -48,7 +48,8 @@

class Connect_Spec(Connect_Spec_2003):
"""
Fortran2008 rule R905.
Fortran2008 rule R905. Extends the Fortran2003 definition with support for
the NEWUNIT specifier.
connect-spec is [ UNIT = ] file-unit-number
or ACCESS = scalar-default-char-expr
Expand Down Expand Up @@ -104,58 +105,15 @@ class Connect_Spec(Connect_Spec_2003):
"Scalar_Int_Variable",
]

@staticmethod
def match(string):
@classmethod
def _keyword_value_list(cls):
"""
:param str string: Fortran code to check for a match
Extends the list of keywords supported in Fortran2003 with NEWUNIT.
:returns: 2-tuple containing the keyword and value or None if the
supplied string is not a match
:rtype: Optional[Tuple[str, Any]]
"""
# Avoid circular dependencies by importing here.
# pylint: disable=import-outside-toplevel
from fparser.two.Fortran2008 import (
Scalar_Default_Char_Expr,
Scalar_Int_Variable,
Scalar_Int_Expr,
)
:returns: list of keyword, class pairs to match against.
:rtype: list[tuple[str, type]]
if "=" not in string:
# The only argument which need not be named is the unit number
return "UNIT", File_Unit_Number(string)
# We have a keyword-value pair. Check whether it is valid...
for keyword, value in [
(
[
"ACCESS",
"ACTION",
"ASYNCHRONOUS",
"BLANK",
"DECIMAL",
"DELIM",
"ENCODING",
"FORM",
"PAD",
"POSITION",
"ROUND",
"SIGN",
"STATUS",
],
Scalar_Default_Char_Expr,
),
("ERR", Label),
("FILE", File_Name_Expr),
("IOSTAT", Scalar_Int_Variable),
("IOMSG", Iomsg_Variable),
("RECL", Scalar_Int_Expr),
("UNIT", File_Unit_Number),
("NEWUNIT", File_Unit_Number),
]:
try:
obj = KeywordValueBase.match(keyword, value, string, upper_lhs=True)
except NoMatchError:
obj = None
if obj is not None:
return obj
return None
"""
result = Connect_Spec_2003._keyword_value_list()
result.append(("NEWUNIT", File_Unit_Number))
return result

0 comments on commit e79199d

Please sign in to comment.