No difference between function call and array reference
Hi,
In the AST, I did not find a way to differenciate function calls and array references.
My sample program is the following:
function mytestfunc(i) result(x)
integer, intent(in) :: i
integer :: x
x = 1337 * i
end function mytestfunc
program test
integer :: myvar
integer, dimension(1:10) :: myArray
myArray = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
!! function call
myvar = mytestfunc(3)
write(*,*) myvar
!! array reference
myvar = myArray(3)
write(*,*) myvar
end program test
and my script is the following:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
ARG_FORTRAN_FILE_INPUT_PATH = "input.f90"
ARG_FORTRAN_STANDARD = 'f2008'
from fparser.common.readfortran import FortranFileReader
from fparser.two.parser import ParserFactory
from fparser.common.readfortran import FortranFileReader
from fparser.two.utils import walk
from fparser.two.Fortran2003 import Main_Program, Assignment_Stmt
print("## Parsing input")
reader = FortranFileReader("{0}".format(ARG_FORTRAN_FILE_INPUT_PATH), ignore_comments=True)
f_parser = ParserFactory().create(std=ARG_FORTRAN_STANDARD)
parse_tree = f_parser(reader)
print("## Visiting AST")
programs = walk(parse_tree,Main_Program)
for program in programs:
execParts = walk(program,Assignment_Stmt)
for execPart in execParts[1:3]:
walk(execPart, debug=True)
The debug print for the 2 assignments to myvar is the following:
child type = <class 'fparser.two.Fortran2003.Assignment_Stmt'>
child type = <class 'fparser.two.Fortran2003.Name'>
child type = <class 'str'> '='
child type = <class 'fparser.two.Fortran2003.Part_Ref'>
child type = <class 'fparser.two.Fortran2003.Name'>
child type = <class 'fparser.two.Fortran2003.Section_Subscript_List'>
child type = <class 'fparser.two.Fortran2003.Int_Literal_Constant'>
child type = <class 'str'> '3'
child type = <class 'NoneType'>
child type = <class 'fparser.two.Fortran2003.Assignment_Stmt'>
child type = <class 'fparser.two.Fortran2003.Name'>
child type = <class 'str'> '='
child type = <class 'fparser.two.Fortran2003.Part_Ref'>
child type = <class 'fparser.two.Fortran2003.Name'>
child type = <class 'fparser.two.Fortran2003.Section_Subscript_List'>
child type = <class 'fparser.two.Fortran2003.Int_Literal_Constant'>
child type = <class 'str'> '3'
child type = <class 'NoneType'>
We can observe that woth assignements RHS are a Part_Ref / Name / Subscript / Const.
Is there any way to differenciate the two cases ?
Best.
In general there is a problem in distinguishing between arrays and functions in Fortran unless you are able to fully link the program and in general we are only parsing part of a full program. What fparser2 currently does is match with the first thing it can which I guess is an assignment here. I think in your particular case we could determine that it is a function as we could add mytestfunc to the symbol table. However, we don't do that at the moment.