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

FPP directives mid statement can cause trouble #429

Open MatthewHambley opened 1 year ago

MatthewHambley commented 1 year ago

I discovered this problem on code like this:

use some_mod, only: &
#ifdef SPECIAL_CASE
    first_mod, &
    second_mod, &
#endif
    third_mod, &
    fourth_mod

So firstly I would like to acknowledge that this is hairy practice and the best solution is not to do it. However developers do do it and it is syntactically valid.

The problem seems to be that the appearance of a preprocessor directive within a statement, rather than between, is causing confusion.

This probably points to a wider problem where it would be true everywhere. For instance if people are using #ifdef to block out arguments in an argument list. Again something they really, really shouldn't but really, really have in the past.

Do preprocessor directives need to be treated like comments which may also appear anywhere?

arporter commented 1 year ago

Thanks for reporting this Matthew. In the fparser docs on FPP/CPP directives (https://fparser.readthedocs.io/en/latest/fparser2.html#preprocessing-directives) I can see there's the explicit limitation that any Fortran with directives in it must still be syntactically correct with them removed, which this code is. I'll do some digging and see whether it's feasible to support this case. I do feel like this might be a Road to Nowhere though as we'll fast end up with a parse tree that doesn't represent any code that is actually compiled which is of limited use?

Could you describe why you need fparser to process this code rather than the code after it has been dealt with by a pre-processor?

arporter commented 1 year ago

Bringing in @reuterbal as he may have some thoughts since he implemented the CPP support (I think?).

arporter commented 1 year ago

(In this particular case, you could do a workaround:

#ifdef SPECIAL_CASE
use my_mod, only: first_mod, second_mod
#else
use my_mod, only: third_mod
end if

)

reuterbal commented 1 year ago

Yes, that's correct and the limitation statement is maybe not phrased perfectly as the limitation is even stricter: The input code must still be correct Fortran if the preprocessor directives were comments. Otherwise there's no alternative to preprocessing the Fortran before feeding it into Fparser (we use pcpp successfully where necessary). I'm wondering what happens if the CPP directives in the example were actual Fortran comments, which should be syntactially valid. Would that be processed correctly by Fparser?