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

Parse error in a function declaration #219

Closed rupertford closed 4 years ago

rupertford commented 4 years ago

The following code causes fparser to raise an error but compiles with gfortran:

module test
type :: field_proxy_type
end type
contains
type(field_proxy_type ) function get_proxy(self)
end function get_proxy
end module test

Syntax error: at line 5
>>>type(field_proxy_type ) function get_proxy(self)

parsing 'tmp.f90' failed at line #5'type(field_proxy_type ) function get_proxy(self)'
started at line #1'module test'

If the space after field_proxy_type is removed then it compiles OK.

rupertford commented 4 years ago

Fortran2003 Rule R1224 is function-stmt is [ <prefix> ] FUNCTION <function-name> ... Fortran2003 Rule R1227 is prefix is prefix-spec [ prefix-spec ] Fortran2003 Rule R1226 is prefix-spec is <declaration-type-spec> | ELEMENTAL | IMPURE ...

The problem is that Rule R1227 sees type(field_proxy_type ) as being two prefix-specs due to the space. In general any space between type and ) will cause the match to fail.

This problem did not use to happen and this code has been simplified between 0.0.8 and 0.0.9 so I suspect it has been oversimplified. It is not yet clear to me what the most appropriate fix is.

rupertford commented 4 years ago

R1227 makes use of SequenceBase to match multiple prefix-spec rules and it was SequenceBase that was splitting the line incorrectly. The two options were to rewrite the Prefix class and stop using SequenceBase or to make SequenceBase more robust.

I've gone for the latter as it may help in other contexts (as SequenceBase is also used by other classes).

The approach I've taken is to split the line and then try to match the first entry. If this succeeds then I add the match to a list, remove the current entry and start again. If this fails then I concatenate the first and second entries and try again. The concatenation is repeated until there is a match or there are no more entries. This means that if a line is split into too many parts, it can still be matched.

rupertford commented 4 years ago

Created branch 219_prefix_error

rupertford commented 4 years ago

The reviewer quite rightly pointed out that the sequencebase fix was a bit of a hack. I have therefore changed to modifying the Prefix rule itself, rather than the SequenceBase base class. This is simpler as it is specific to the particular class so specialised logic can be used. As the Prefix rule is the only one that uses SequenceBase with a space separator I've removed support for a space separator from SequenceBase. I've also updated the code to support the Prefix constraints and added associated tests. I've also created a new issue (#221) that captures the fact that Prefix_Spec has some Fortran2008 keywords in it.

arporter commented 4 years ago

220 is merged. Closing issue.