Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fortran difficulties with case matching and submodules #402

Open
TrippLamb opened this issue Dec 3, 2024 · 2 comments
Open

Fortran difficulties with case matching and submodules #402

TrippLamb opened this issue Dec 3, 2024 · 2 comments

Comments

@TrippLamb
Copy link

TrippLamb commented Dec 3, 2024

It seems there is a parsing error for fortran submodules. I couldn't determine exactly what was going wrong because it didn't seem to be consistent procedure to procedure within a submodule. I suspect the first issue encountered might mess it up for procedures further down by putting the parser into an incorrect state.

When using the syntax Module Subroutine or Module Function there appear to be some parsing difficulties.

Additionally there seem to be some case matching errors. Fortran isn't case sensitive, but in some cases that appears to make the parser miss the subroutines and functions. For some reason the recursive or elemental decorator for the procedures seems to help them be found even with a module decorator.

@terryyin
Copy link
Owner

terryyin commented Dec 4, 2024

I've fixed most of the issues you mentioned. Except this one:

    def xtest_submodule_parsing(self):
        '''Test that submodules are correctly parsed'''
        result = get_fortran_function_list('''
        submodule (parent) child
            module procedure sub1
                integer :: x
            end procedure

            module procedure sub2
                real :: y
            end procedure
        end submodule
        ''')
        self.assertEqual(2, len(result))
        self.assertEqual('submodule::sub1', result[0].name)
        self.assertEqual('submodule::sub2', result[1].name)

Can you confirm if this test case makes sense?

@TrippLamb
Copy link
Author

If I'm understanding correctly, that input string shouldn't return anything, because as far as I'm aware it isn't a valid way to define procedures in Fortran. A subroutine or a function are a procedure, but you cannot use procedure to define a procedure interface. You must use either function or subroutine. There are other invalid syntaxes, but I don't think that missing text would cause issues with this type of parsing.

I'm not sure how the parsing works, but I suspect the current way the parsing is done might cause some misleading results in the case of interface blocks.

interface
    module function fxn1() result(val)
        integer :: val
        !no body because it only defines the procedure interface like a c++ header file
    end function fxn1
end interface

An interface block must be defined above the contains keyword in a module or submodule, the the actual procedure definitions must appear below. So if there is a way to ensure you have hit the contains keyword before parsing you might save yourself a lot of headaches in the future.

Once again I don't know how the parsing currently works, but it seemed to be via regex, so a potentially further issue might be the any ordered-ness of procedure attributes. Keywords like elemental, impure, pure, module, recursive​, and native types can be placed in any order before function or subroutine so while I don't write code this way you could easily come across the following valid string

    submodule (parent) child

    contains

            elemental module subroutine sub1(x)
                integer :: x
            end subroutine 

            module recursive function fxn1() result(y)
                real :: y
            end function 
            
            real impure module elemental function fxn1()
            
            contains
            
                subroutine fxn_sub1()
                    character(20) :: str
                end subroutine
            end function 
        end submodule

I hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants