summaryrefslogtreecommitdiff
path: root/numpy/f2py/lib/block.py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/f2py/lib/block.py')
-rw-r--r--numpy/f2py/lib/block.py114
1 files changed, 78 insertions, 36 deletions
diff --git a/numpy/f2py/lib/block.py b/numpy/f2py/lib/block.py
index f7cdb7dd3..b9bafdcff 100644
--- a/numpy/f2py/lib/block.py
+++ b/numpy/f2py/lib/block.py
@@ -70,7 +70,8 @@ class Block:
'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'))
+ i = Line('program UNDEFINED',(0,0),None,self.reader)
+ p = Program(self,Program.start_re.match(i.get_line()),i)
p.content.extend(self.content)
self.content[:] = [p]
return None
@@ -81,6 +82,7 @@ class Block:
if m.groupdict().has_key('name'):
end_name = m.group('name')
+ if end_name: end_name = end_name.strip()
name = self.get_name()
if end_name and name != end_name:
message = self.reader.format_message(\
@@ -103,12 +105,14 @@ class Block:
return False
def fill(self):
- item = self.get_item()
+ end_flag = self.__class__ is Block
+ item = startitem = 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
+ end_flag = True
break
if flag is None: # fixing the end of undefined start
item = self.get_item()
@@ -117,73 +121,90 @@ class Block:
if self.isblock(item):
item = self.get_item()
continue
-
# line contains something else
self.content.append(item)
item = self.get_item()
+ if not end_flag:
+ message = self.reader.format_message(\
+ 'WARNING',
+ 'failed to find the end of block',
+ self.item.span[0],self.item.span[1])
+ print >> sys.stderr, message
+ sys.stderr.flush()
return
-class Program(Block):
- classes = []
- 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)
+class CodeBlock(Block):
def __init__(self, parent, start_re_match, item):
Block.__init__(self, parent)
self.name = start_re_match.group('name')
+ self.item = item
-class Module(Block):
+class Program(CodeBlock):
+ classes = []
+ 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)
+
+
+class Module(CodeBlock):
classes = []
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):
+ self.item = item
+
+class Interface(CodeBlock):
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', re.I)
- def __init__(self, parent, start_re_match, item):
- Block.__init__(self, parent)
- self.name = start_re_match.group('name')
-
-class PythonModule(Block):
+class PythonModule(CodeBlock):
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', re.I)
- def __init__(self, parent, start_re_match, item):
- Block.__init__(self, parent)
- self.name = start_re_match.group('name')
-class Subroutine(Block):
+class Subroutine(CodeBlock):
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>\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):
+class Function(CodeBlock):
classes = []
- start_re = re.compile(r'\s*function\s*(?P<name>\w+)', re.I)
+ start_re = re.compile(r'\s*(?P<prefix>[\w,\s=()]*)\s*function\s*(?P<name>\w+)', re.I)
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):
+class Type(CodeBlock):
classes = []
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 __init__(self, parent, start_re_match, item):
+ Block.__init__(self, parent)
+ self.item = item
+
+ def isenditem(self, item):
+ line,sline = split2(item.get_line())
+ if sline: return False # end statement never contains strings
+ 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')
+ if end_name: end_name = end_name.strip()
+ 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 fill(self):
item = self.get_item()
while item is not None:
@@ -200,17 +221,38 @@ class StatementBlock(Block):
# line contains something else
self.content.append(item)
item = self.get_item()
+ if item is None:
+ message = self.reader.format_message(\
+ 'WARNING',
+ 'failed to find the end of block',
+ self.item.span[0],self.item.span[1])
+ print >> sys.stderr, message
+ sys.stderr.flush()
return
class DoBlock(StatementBlock):
- start_re = re.compile(r'\s*do\b', re.I)
+ start_re = re.compile(r'\s*do\b\s*(?P<label>\d*)', 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)
+ StatementBlock.__init__(self, parent, start_re_match, item)
+ label = start_re_match.group('label').strip()
+ if label.endswith(':'): label = label[:-1].strip()
+ self.endlabel = label
self.name = item.label
+ def isenditem(self, item):
+ if self.endlabel:
+ if item.label==self.endlabel:
+ # item may contain computational statemets
+ self.content.append(item)
+ # the same item label may be used for different block ends
+ self.put_item(item)
+ return True
+ else:
+ return StatementBlock.isenditem(self, item)
+ return False
+
class IfThenBlock(StatementBlock):
start_re = re.compile(r'\s*if\b.*?\bthen\s*\Z', re.I)
@@ -218,7 +260,7 @@ class IfThenBlock(StatementBlock):
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)
+ StatementBlock.__init__(self, parent, start_re_match, item)
self.name = item.label