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

some problem about Cpp_Endif_Stmt and Cpp_If_Stmt #433

Closed PressFforlove closed 10 months ago

PressFforlove commented 1 year ago

as the title says, when i have a code like below and want to gen ast:

program test
!----------Specification_Part
implicit none
    real(kind = 8) :: a, b, c
    !------Implicit_Part.children[0]
    #ifdef SOME_THING
!----------Execution_Part
        a = 1 
        #ifdef OTHER_THING 
            b = 2 
        #endif 
        c = 3 
    !------Block_Nonlabel_Do_Construct
    #endif 
    Do while(condition)
        do something
    Enddo

why will the 2 #def stmts be split to to specification_part, execution_part, and even some tail(the last #endif) in Block_Nonlabel_Do_Construct? this confused me a lot...

PressFforlove commented 1 year ago

i think the first Cpp_If_Stmt should be in Execution_Part

arporter commented 1 year ago

Yes, I can see that that behaviour is not the best. Essentially, if-defs are not part of Fortran and fparser's support for them is very limited. We recommend that, where possible, the code to be parsed is put through a pre-processor first so that it is valid Fortran. Otherwise, I shall bring in @reuterbal as he implemented support for CPP directives and may be able to comment further.

reuterbal commented 1 year ago

Like Andy said: Preprocessor statements are not part of Fortran, and fparser treats them the same way as comments - but makes them available as a separate node type for convenience.

The question of the split between specification-part and execution-part is somewhat arbitrary since comments can be allocated to either. The specific reason why it appears here in the specification-part rather than execution part is due to the fact, that fparser continues to allocate all nodes to the currently active part (i.e. the spec) until the first executable statement is encountered (i.e., the assignment).

If you are certain that all comments (inlcuding preprocessor statements) should always belong to the execution-part instead, you could update the parse tree accordingly afterwards. However, this is certainly not the case in general. An easy example where this assumption breaks down can be constructed, e.g., when using marker apis from profiling tools:

program test
implicit none
    real(kind = 8) :: a, b, c
#ifdef USE_MARKER_API
    integer :: marker

    call start_marker(marker)
#endif

    ....

#ifdef USE_MARKER_API
    call end_marker(marker)
#endif
end program
PressFforlove commented 10 months ago

Sorry, it have been a long time to reply you, because my work about fparser has finished for a while.

Thank you for reply~

My opinion is not that all comment should belong to exec_part. After think about this quesion alone, my conclusion is almost the same as you, and i do some preprocessing before i do some change to AST(my work).