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 29 forks source link

fparser2 fails to parse function with specified type in some circumstances #130

Closed arporter closed 5 years ago

arporter commented 5 years ago

This problem is triggered by the following Fortran:

MODULE sbcrnf
   TYPE(FLD),        ALLOCATABLE, DIMENSION(:) ::   sf_t_rnf
CONTAINS
   integer FUNCTION sbc_rnf_alloc()
   END FUNCTION sbc_rnf_alloc
END MODULE sbcrnf

fparser2 falls over while attempting to match the function statement:

obj = item.parse_line(cls, parent_cls)
File "Projects/GungHo/PSyclone/external/fparser/src/fparser/common/readfortran.py", line 358, in parse_line
obj = cls(self.line, parent_cls=parent_cls)
File "Projects/GungHo/PSyclone/external/fparser/src/fparser/two/utils.py", line 258, in __new__
result = cls.match(string)
File "Projects/GungHo/PSyclone/external/fparser/src/fparser/two/Fortran2003.py", line 1378, in match
Component_Decl_List, string)
File "Projects/GungHo/PSyclone/external/fparser/src/fparser/two/utils.py", line 1259, in match
entity_decls = entity_decl_list_cls(repmap(line))
File "Projects/GungHo/PSyclone/external/fparser/src/fparser/two/utils.py", line 280, in __new__
obj = subcls(string, parent_cls=parent_cls)
File "Projects/GungHo/PSyclone/external/fparser/src/fparser/two/utils.py", line 258, in __new__
result = cls.match(string)
File "Projects/GungHo/PSyclone/external/fparser/src/fparser/two/Fortran2003.py", line 1449, in match
assert newline == '', repr(newline)
AssertionError: 'sbc_rnf_alloc()'

Strangely, if I remove either the TYPE(FLD) declaration or the integer qualifier on the function statement then fparser2 is happy.

rupertford commented 5 years ago

OK, this was a fun one. The following cut down example still failed. However, if I removed the :: in the type declaration then it worked.

   TYPE(FLD) :: sf_t_rnf
CONTAINS
   integer FUNCTION sbc_rnf_alloc()
   END FUNCTION sbc_rnf_alloc

The reason for this is that fparser was matching `type(fld) :: sf_t_rnf as the beginning of a derived_type_definition and then matching subsequent lines i.e.

type :: y
 contains
  integer function x()
  end function x
end type y

and so tried to parse contains and the subsequent function as content to the type declaration. At some point one of the matches failed as it got strange unexpected content.

The first line was matching as the implementation of Derived_Type_Stmt r430 did not check for invalid content between TYPE and :: i.e. (FLD) was ignored.

If we add a check for invalid content in the match method of Derived_Type_Stmt then all is well.

rupertford commented 5 years ago

Created branch derived_type_stmt_error

rupertford commented 5 years ago

pr #133 has been merged to master. Closing this issue.