stfc / fparser

This project maintains and develops a Fortran parser called fparser2 written purely in Python which supports Fortran 2003 and some Fortran 2008. A legacy parser fparser1 is also available but is not supported. The parsers were originally part of the f2py project by Pearu Peterson.
https://fparser.readthedocs.io
Other
61 stars 28 forks source link

specific-binding (F2003:R451 / F2008:R448) doesn't match multiple type-bound-proc-decl #308

Open reuterbal opened 2 years ago

reuterbal commented 2 years ago

Hi,

slowly making our way into OOP interfaces and found a new issue today. Type-bound procedure definitions don't match when multiple procedures are provided in the same declaration as in the example below:

>>> print(fcode)

module test_mod
    implicit none

    type some_type
        LOGICAL :: a = .false.
        LOGICAL :: b = .false.
    contains
        procedure, private :: some_type_do_a_i, some_type_do_a_r
        ! generic :: do_a => some_type_do_a_i, some_type_do_a_r
    end type some_type

contains

    subroutine some_type_do_a_i(self, val)
        class(some_type) :: self
        integer, intent(in) :: val
        self%a = val > 0
    end subroutine some_type_do_a_i

    subroutine some_type_do_a_r(self, val)
        class(some_type) :: self
        real, intent(in) :: val
        self%a = val > 0.
    end subroutine some_type_do_a_r

end module test_mod

>>> from fparser.common.readfortran import FortranStringReader
>>> from fparser.two.parser import ParserFactory
>>> reader = FortranStringReader(fcode)
>>> parser = ParserFactory().create(std='f2008')
>>> ast = parser(reader)
Traceback (most recent call last):
  File ".../loki_env/lib/python3.8/site-packages/fparser/two/Fortran2003.py", line 237, in __new__
    return Base.__new__(cls, string)
  File ".../loki_env/lib/python3.8/site-packages/fparser/two/utils.py", line 405, in __new__
    raise NoMatchError(errmsg)
fparser.two.utils.NoMatchError: at line 9
>>>        procedure, private :: some_type_do_a_i, some_type_do_a_r

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../loki_env/lib/python3.8/site-packages/fparser/two/Fortran2003.py", line 241, in __new__
    raise FortranSyntaxError(string, "")
fparser.two.utils.FortranSyntaxError: at line 9
>>>        procedure, private :: some_type_do_a_i, some_type_do_a_r

Two separate procedure, private :: ... declarations with one procedure name each parse fine. Standard expects a proc-decl-list, so multiple names should be allowed (gfortran --pedantic -Wall is fine with it, too).

reuterbal commented 2 years ago

Apologies, just realized that this is not a proc-component-def-stmt but of course a specific-binding, for which multiple declarations per line were only added with Fortran 2008. So it's not actually a bug but a missing feature for F2008 support.

hiker commented 1 week ago

I just ran into the same issue. Since I already looked up the details in the standards, I'll add them here: Fortran 2003:

R450: proc-binding-stmt is specific-binding
                        or generic-binding
                        or final-binding

R451 specific-binding is PROCEDURE [ (interface-name) ]
                         [ [ , binding-attr -list ] :: ]
                        binding-name [ => procedure-name ]

So, a single name only, as @reuterbal pointed out.

In Fortran 2008, this is now:

R447 type-bound-proc-binding is type-bound-procedure-stmt
                             or type-bound-generic-stmt
                             or final-procedure-stmt
R448  type-bound-procedure-stmt is PROCEDURE [ [ , binding-attr -list ] :: ] type-bound-proc-decl -list
                                or PROCEDURE (interface-name), binding-attr -list :: binding-name-list
R449 type-bound-proc-decl is binding-name [ => procedure-name ]