diff options
Diffstat (limited to 'numpy/f2py/lib/block.py')
-rw-r--r-- | numpy/f2py/lib/block.py | 114 |
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 |