New issue 33 by james.ke...@gmail.com: fparser fails to parse interface
blocks with parentheses in name, e.g. assignment(=)
http://code.google.com/p/f2py/issues/detail?id=33
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.
Attachments:
allow_interfaces_with_parentheses.patch 1.3 KB
Comment #1 on issue 33 by pearu.peterson: fparser fails to parse interface
blocks with parentheses in name, e.g. assignment(=)
http://code.google.com/p/f2py/issues/detail?id=33
Issue fixed in 22a3f12bd9f9.
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'))))