pearu / f2py

Automatically exported from code.google.com/p/f2py
Other
54 stars 37 forks source link

fparser fails to parse interface blocks with parentheses in name, e.g. assignment(=) #33

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?

Attempting to parse following Fortran 90 code containing an overloaded 
assignment interface fails:

>>> s = """module foo
... 
... interface assignment(=)
...    module procedure baa
... end interface assignment(=)
...  
... end module foo"""
>>> from fparser import api
>>> print api.parse(s)
WARNING: While processing 'string-4457787584' (mode='free')..
    3:interface assignment(=)
    4:   module procedure baa
    5:end interface assignment(=) <== no parse pattern found for "end interface assignment(F2PY_EXPR_TUPLE_2)" in 'Interface' block.
WARNING: While processing 'string-4457787584' (mode='free')..
    5:end interface assignment(=)
    6:
    7:end module foo <== no parse pattern found for "end module foo" in 'Interface' block.
WARNING: While processing 'string-4457787584' (mode='free')..
    1:module foo
    2:
    3:interface assignment(=) <== failed to find the end of block
    4:   module procedure baa
    5:end interface assignment(=)
WARNING: While processing 'string-4457787584' (mode='free')..
    1:module foo <== failed to find the end of block
    2:
    3:interface assignment(=)
ERROR: While processing 'string-4457787584' (mode='free')..
    1:module foo
    2:
    3:interface assignment(=) <== exception triggered here: <type 'exceptions.Exception'> 'Line' object has no attribute 'analyze'
    4:   module procedure baa
    5:end interface assignment(=)
    6:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jameskermode/lib/python/fparser/api.py", line 157, in parse
    parser.analyze()
  File "/Users/jameskermode/lib/python/fparser/parsefortran.py", line 88, in analyze
    self.block.analyze()
  File "/Users/jameskermode/lib/python/fparser/utils.py", line 204, in new_func
    func(self)
  File "/Users/jameskermode/lib/python/fparser/block_statements.py", line 222, in analyze
    stmt.analyze()
  File "/Users/jameskermode/lib/python/fparser/utils.py", line 204, in new_func
    func(self)
  File "/Users/jameskermode/lib/python/fparser/block_statements.py", line 323, in analyze
    stmt.analyze()
  File "/Users/jameskermode/lib/python/fparser/utils.py", line 204, in new_func
    func(self)
  File "/Users/jameskermode/lib/python/fparser/block_statements.py", line 498, in analyze
    stmt.analyze()
AttributeError: 'Line' object has no attribute 'analyze'

What is the expected output? What do you see instead?

The problem is caused by:

 (i)  regular expression in EndInterface.match not matching parenthesised characters
 (ii) interface name not matching end interface name since bracketed expressions are
      converted to F2PY_EXPR_TUPLE_1 and F2PY_EXPR_TUPLE_2, causing test in 
      base_classes.EndStatement.process_item() to fail.

The attached patch fixes both of these issues. After applying patch, output of 
above commands is:

>>> s = """module foo
... 
... interface assignment(=)
...    module procedure baa
... end interface assignment(=)
...  
... end module foo"""
>>> from fparser import api
>>> print api.parse(s)
!BEGINSOURCE <cStringIO.StringI object at 0x10d33f8d0> mode=free
  MODULE foo
    INTERFACE assignment(=)
      MODULE PROCEDURE baa
    END INTERFACE assignment(=)
  END MODULE foo

What version of the product are you using? On what operating system?

Latest mercurial repository revision (changeset:  83:15a65747d6c6), on Mac OS X 
10.7.

Original issue reported on code.google.com by james.ke...@gmail.com on 25 Jan 2012 at 4:28

Attachments:

GoogleCodeExporter commented 8 years ago
Issue fixed in 22a3f12bd9f9.

Original comment by pearu.peterson on 30 Jan 2012 at 8:47

GoogleCodeExporter commented 8 years ago
Also note that you are using old parser code.

I recommend using fparser.Fortran2003 rules which are much more robust than the 
old rules.

For example:

>>> from fparser.api import get_reader
>>> from fparser.Fortran2003 import Program
>>> s = '''module foo
... interface assignment(=)
... module procedure baa
... end interface assignment(=)
... end module foo
... '''
>>> r = get_reader(s)
>>> p = Program(r)
>>> print p
MODULE foo
  INTERFACE ASSIGNMENT(=)
    MODULE PROCEDURE baa
  END INTERFACE ASSIGNMENT(=)
END MODULE foo
>>> p
Program(Module(Module_Stmt('MODULE', Name('foo')), 
Specification_Part(Interface_Block(Interface_Stmt(Generic_Spec('ASSIGNMENT', 
'=')), Procedure_Stmt(Name('baa')), End_Interface_Stmt('INTERFACE', 
Generic_Spec('ASSIGNMENT', '=')))), End_Module_Stmt('MODULE', Name('foo'))))

Original comment by pearu.peterson on 30 Jan 2012 at 9:00