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

Walk function is not visiting tuples #367

Closed antoine-morvan closed 1 year ago

antoine-morvan commented 1 year ago

Hello,

I'm implementing a pass that visits all Names in do loops. Currently I am relying on walk(doloop, Name) to list all of them. However for such a loop:

do iterator = 0,size
  A(iterator) = B(iterator) * C(iterator)
enddo

walk() is not returning the size name.

The following sample can be used to reproduce:

program test
    integer :: iterator, size
    integer, dimension(0:10) :: A, B, C
    size = 10
    do iterator = 0,size
      A(iterator) = B(iterator) * C(iterator)
    enddo
end program test

The following script is used to highlight the missing name:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

ARG_FORTRAN_FILE_INPUT_PATH = "test_fail.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 Name, Block_Nonlabel_Do_Construct

print("## Parsing input")
reader = FortranFileReader("{0}".format(ARG_FORTRAN_FILE_INPUT_PATH), ignore_comments=False)
f_parser = ParserFactory().create(std=ARG_FORTRAN_STANDARD)
parse_tree = f_parser(reader)
print("## Visiting AST")
doloops = walk(parse_tree, Block_Nonlabel_Do_Construct)
for doloop in doloops:
    allNames = walk(doloop, Name, 0, True)
    for name in allNames:
        print(name)

That gives me the following output with fparser2 version 0.0.16:

## Parsing input
## Visiting AST
child type =  <class 'fparser.two.Fortran2003.Block_Nonlabel_Do_Construct'>
  child type =  <class 'fparser.two.Fortran2003.Nonlabel_Do_Stmt'>
    child type =  <class 'str'> 'DO'
    child type =  <class 'fparser.two.Fortran2003.Loop_Control'>
      child type =  <class 'NoneType'>
      child type =  <class 'tuple'>
      child type =  <class 'NoneType'>
  child type =  <class 'fparser.two.Fortran2003.Assignment_Stmt'>
    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.Name'>
    child type =  <class 'str'> '='
    child type =  <class 'fparser.two.Fortran2003.Add_Operand'>
      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.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.Name'>
  child type =  <class 'fparser.two.Fortran2003.End_Do_Stmt'>
    child type =  <class 'str'> 'DO'
    child type =  <class 'NoneType'>
A
iterator
B
iterator
C
iterator

We can observe that in the Loop_Control, the walk is pruning the tuple type.

I will submit a PR for this.

Best.

arporter commented 1 year ago

368 is on master.