summaryrefslogtreecommitdiff
path: root/numpy/f2py/lib/block.py
diff options
context:
space:
mode:
authorPearu Peterson <pearu.peterson@gmail.com>2006-05-25 10:54:57 +0000
committerPearu Peterson <pearu.peterson@gmail.com>2006-05-25 10:54:57 +0000
commita12cb7b1dab184bae0f1ae9931292778afc93f5d (patch)
treee8a85c422d9352314078f82c55d7996ebe7900a1 /numpy/f2py/lib/block.py
parent4de4ac85272818496e6bd4868b66e1690ee26f65 (diff)
downloadnumpy-a12cb7b1dab184bae0f1ae9931292778afc93f5d.tar.gz
Cont. impl. fortran parser, added do and ifthen blocks.
Diffstat (limited to 'numpy/f2py/lib/block.py')
-rw-r--r--numpy/f2py/lib/block.py174
1 files changed, 133 insertions, 41 deletions
diff --git a/numpy/f2py/lib/block.py b/numpy/f2py/lib/block.py
index cea71a593..f7cdb7dd3 100644
--- a/numpy/f2py/lib/block.py
+++ b/numpy/f2py/lib/block.py
@@ -15,19 +15,25 @@ __all__ = ['Block','Module','PythonModule','Interface',
'Subroutine','Function','Type']
import re
+import sys
from readfortran import Line
+from splitline import split2, string_replace_map
class Block:
classes = []
+ end_re = re.compile(r'\s*end\s*\Z', re.I)
def __init__(self, parent):
self.parent = parent
- self.content = []
-
+ self.isfix77 = parent.isfix77
+ self.reader = parent.reader
self.get_item = parent.get_item
self.put_item = parent.put_item
+ self.lower = not self.reader.ispyf
+
+ self.content = []
self.name = None
def get_name(self):
@@ -48,35 +54,70 @@ class Block:
l.append(tab+'end '+self.__class__.__name__ +' '+ name)
return '\n'.join(l)
- def isendline(self, line):
+ def isenditem(self, item):
+ line,sline = split2(item.get_line())
+ if sline: return False # end statement never contains strings
if self.__class__ is Block:
# MAIN block does not define start/end line conditions,
- # so it never ends.
+ # so it should never end until all lines are read.
+ # However, sometimes F77 programs lack the PROGRAM statement,
+ # and here we fix that:
+ if self.isfix77:
+ m = self.end_re.match(line)
+ if m:
+ message = self.reader.format_message(\
+ 'WARNING',
+ 'assuming the end of undefined PROGRAM statement',
+ item.span[0],item.span[1])
+ print >> sys.stderr, message
+ p = Program(self,Program.start_re.match('program UNDEFINED'))
+ p.content.extend(self.content)
+ self.content[:] = [p]
+ return None
return False
m = self.end_re.match(line)
if not m: return False
+ # check if the block start name matches with the block end name
+
+ if m.groupdict().has_key('name'):
+ end_name = m.group('name')
+ name = self.get_name()
+ if end_name and name != end_name:
+ message = self.reader.format_message(\
+ 'WARNING',
+ 'expected the end of %r block but got end of %r'\
+ % (name, end_name),
+ item.span[0],item.span[1])
+ print >> sys.stderr, message
return True
+ def isblock(self, item):
+ line = item.get_line()
+ for cls in self.classes:
+ m = cls.start_re.match(line)
+ if m:
+ subblock = cls(self, m, item)
+ self.content.append(subblock)
+ subblock.fill()
+ return True
+ return False
+
def fill(self):
item = self.get_item()
while item is not None:
if isinstance(item, Line):
- line = item.line
- if self.isendline(line):
+ # handle end of a block
+ flag = self.isenditem(item)
+ if flag: # end of block
break
- # check if line contains subblock start
- found_block = False
- for cls in self.classes:
- m = cls.start_re.match(line)
- if m:
- found_block = True
- subblock = cls(self, m)
- self.content.append(subblock)
- subblock.fill()
- break
- if found_block:
+ if flag is None: # fixing the end of undefined start
item = self.get_item()
continue
+ # handle subblocks
+ if self.isblock(item):
+ item = self.get_item()
+ continue
+
# line contains something else
self.content.append(item)
item = self.get_item()
@@ -84,63 +125,114 @@ class Block:
class Program(Block):
classes = []
- start_re = re.compile(r'\s*program', re.I)
-
+ start_re = re.compile(r'\s*program\s*((?P<name>\w+)|)', re.I)
+ end_re = re.compile(r'\s*end(\s*program(\s*(?P<name>\w+)|)|)\s*\Z', re.I)
+ def __init__(self, parent, start_re_match, item):
+ Block.__init__(self, parent)
+ self.name = start_re_match.group('name')
class Module(Block):
classes = []
- start_re = re.compile(r'\s*module\s(?P<name>\w+)', re.I)
- end_re = re.compile(r'\s*end(\s*module(\s*(?P<name>\w+)|)|)\s*\Z')
- def __init__(self, parent, start_re_match):
+ start_re = re.compile(r'\s*module\s*(?P<name>\w+)\s*\Z', re.I)
+ end_re = re.compile(r'\s*end(\s*module(\s*(?P<name>\w+)|)|)\s*\Z', re.I)
+ def __init__(self, parent, start_re_match, item):
Block.__init__(self, parent)
self.name = start_re_match.group('name')
class Interface(Block):
classes = []
start_re = re.compile(r'\s*interface(\s*(?P<name>\w+)|)', re.I)
- end_re = re.compile(r'\s*end(\s*interface(\s*(?P<name>\w+)|)|)\s*\Z')
- def __init__(self, parent, start_re_match):
+ end_re = re.compile(r'\s*end(\s*interface(\s*(?P<name>\w+)|)|)\s*\Z', re.I)
+ def __init__(self, parent, start_re_match, item):
Block.__init__(self, parent)
self.name = start_re_match.group('name')
class PythonModule(Block):
classes = []
- start_re = re.compile(r'\s*python\s*module\s(?P<name>\w+)', re.I)
- end_re = re.compile(r'\s*end(\s*python\s*module(\s*(?P<name>\w+)|)|)\s*\Z')
- def __init__(self, parent, start_re_match):
+ start_re = re.compile(r'\s*python\s*module\s*(?P<name>\w+)', re.I)
+ end_re = re.compile(r'\s*end(\s*python\s*module(\s*(?P<name>\w+)|)|)\s*\Z', re.I)
+ def __init__(self, parent, start_re_match, item):
Block.__init__(self, parent)
self.name = start_re_match.group('name')
class Subroutine(Block):
classes = []
start_re = re.compile(r'\s*subroutine\s*(?P<name>\w+)', re.I)
- end_re = re.compile(r'\s*end(\s*subroutine(\s*(?P<name>.*)|)|)\s*\Z')
- def __init__(self, parent, start_re_match):
+ end_re = re.compile(r'\s*end(\s*subroutine(\s*(?P<name>\w+)|)|)\s*\Z', re.I)
+ def __init__(self, parent, start_re_match, item):
Block.__init__(self, parent)
self.name = start_re_match.group('name')
class Function(Block):
classes = []
start_re = re.compile(r'\s*function\s*(?P<name>\w+)', re.I)
- end_re = re.compile(r'\s*end(\s*function(\s*(?P<name>.*)|)|)\s*\Z')
- def __init__(self, parent, start_re_match):
+ end_re = re.compile(r'\s*end(\s*function(\s*(?P<name>\w+)|)|)\s*\Z')
+ def __init__(self, parent, start_re_match, item):
Block.__init__(self, parent)
self.name = start_re_match.group('name')
class Type(Block):
classes = []
- start_re = re.compile(r'\s*type(?!\s*\()', re.I)
- end_re = re.compile(r'\s*end(\s*type(\s*(?P<name>.*)|)|)\s*\Z')
- def __init__(self, parent, start_re_match):
+ start_re = re.compile(r'\s*type(?!\s*\()(.*::|)\s*(?P<name>\w+)\s*\Z', re.I)
+ end_re = re.compile(r'\s*end(\s*type(\s*(?P<name>\w+)|)|)\s*\Z', re.I)
+ def __init__(self, parent, start_re_match, item):
+ Block.__init__(self, parent)
+ self.name = start_re_match.group('name')
+
+
+class StatementBlock(Block):
+ classes = []
+
+ def fill(self):
+ item = self.get_item()
+ while item is not None:
+ if isinstance(item, Line):
+ # handle end of a block
+ flag = self.isenditem(item)
+ if flag: # end of block
+ break
+ # handle subblocks
+ if self.isblock(item):
+ item = self.get_item()
+ continue
+
+ # line contains something else
+ self.content.append(item)
+ item = self.get_item()
+ return
+
+class DoBlock(StatementBlock):
+
+ start_re = re.compile(r'\s*do\b', re.I)
+ end_re = re.compile(r'\s*end\s*do(\s*(?P<name>.*)|)\s*\Z', re.I)
+
+ def __init__(self, parent, start_re_match, item):
+ Block.__init__(self, parent)
+ self.name = item.label
+
+class IfThenBlock(StatementBlock):
+
+ start_re = re.compile(r'\s*if\b.*?\bthen\s*\Z', re.I)
+ #start_re = re.compile(r'\s*if\b', re.I)
+ end_re = re.compile(r'\s*end\s*if(\s*(?P<name>.*)|)\s*\Z', re.I)
+
+ def __init__(self, parent, start_re_match, item):
Block.__init__(self, parent)
- self.name = 'notimpl'#start_re_match.group('name')
+ self.name = item.label
+
# Initialize classes lists
-Block.classes.extend([Program,PythonModule,Module,Interface,Subroutine,Function,Type])
-Module.classes.extend([PythonModule,Interface,Subroutine,Function,Type])
+
+basic_blocks = [Program,PythonModule,Module,Interface,Subroutine,Function,Type]
+stmt_blocks = [DoBlock,IfThenBlock]
+
+Block.classes.extend(basic_blocks + stmt_blocks)
+Module.classes.extend(Block.classes[1:])
PythonModule.classes.extend(Module.classes)
-Interface.classes.extend([PythonModule,Module,Interface,Subroutine,Function,Type])
-Subroutine.classes.extend([PythonModule,Module,Interface,Subroutine,Function,Type])
-Subroutine.classes.extend(Function.classes)
-Type.classes.extend([Type,Function,Subroutine,Interface])
+Interface.classes.extend(Block.classes[1:])
+Subroutine.classes.extend(Block.classes[1:])
+Function.classes.extend(Subroutine.classes)
+Type.classes.extend(Block.classes[3:])
+
+StatementBlock.classes.extend(stmt_blocks)