def __init__(self, parent, datatype="", entity_decls=None, intent="", pointer=False, attrspec=None): if entity_decls is None: raise RuntimeError( "Cannot create a declaration of a derived-type variable " "without specifying the name(s) of the variable(s)") # make a copy of entity_decls as we may modify it local_entity_decls = entity_decls[:] if attrspec is None: attrspec = [] my_attrspec = [spec for spec in attrspec] if intent != "": my_attrspec.append("intent({0})".format(intent)) if pointer is not False: my_attrspec.append("pointer") self._names = local_entity_decls reader = FortranStringReader("type(vanillatype) :: vanilla") reader.set_mode(True, False) # free form, strict myline = reader.next() from fparser.typedecl_statements import Type self._typedecl = Type(parent.root, myline) self._typedecl.selector = ('', datatype) self._typedecl.attrspec = my_attrspec self._typedecl.entity_decls = local_entity_decls BaseGen.__init__(self, parent, self._typedecl)
def __init__(self, parent, language, position, directive_type, content): self._supported_languages = ["omp"] self._language = language self._directive_type = directive_type reader = FortranStringReader("! content\n") reader.set_mode(True, True) # free form, strict subline = reader.next() if language == "omp": my_comment = OMPDirective(parent.root, subline, position, directive_type) my_comment.content = "$omp" if position == "end": my_comment.content += " end" my_comment.content += " " + directive_type if content != "": my_comment.content += " " + content else: raise RuntimeError( "Error, unsupported directive language. Expecting one of " "{0} but found '{1}'".format(str(self._supported_languages), language)) BaseGen.__init__(self, parent, my_comment)
def parse(cls, line, label='', isfree=True, isstrict=False): '''Tries to parse a Fortran line using the given class cls. If successful, it then converts the parsed statement back to a string. If isstrict is false, it will then try to parse this string again (recursively calling itself, with isstrict set to true) and make sure that the re-parsed string is identical to the input. It returns the string representation of the parsed input line. ''' if label: line = label + ' : ' + line reader = FortranStringReader(line) reader.set_mode(isfree, isstrict) item = next(reader) if not cls.match(item.get_line()): raise ValueError('%r does not match %s pattern' % (line, cls.__name__)) stmt = cls(item, item) if stmt.isvalid: # Check that we can successfully parse the string representation # of the parsed object stmt_string = str(stmt) if not isstrict: reparsed_stmt_string = parse(cls, stmt_string, isstrict=True) if stmt_string != reparsed_stmt_string: raise ValueError('Failed to parse %r with %s pattern in Pyf ' 'mode, got %r' % (stmt_string, cls.__name__, reparsed_stmt_string)) return stmt_string raise ValueError('parsing %r with %s pattern failed' % (line, cls.__name__))
def adduse(name, parent, only=False, funcnames=None): ''' Adds a use statement with the specified name to the supplied object. This routine is required when modifying an existing AST (e.g. when modifying a kernel). The classes are used when creating an AST from scratch (for the PSy layer). ''' reader = FortranStringReader("use kern,only : func1_kern=>func1") reader.set_mode(True, True) # free form, strict myline = reader.next() from fparser.block_statements import Use # find an appropriate place to add in our use statement import fparser while not (isinstance(parent, fparser.block_statements.Program) or isinstance(parent, fparser.block_statements.Module) or isinstance(parent, fparser.block_statements.Subroutine)): parent = parent.parent use = Use(parent, myline) use.name = name use.isonly = only if funcnames is None: funcnames = [] use.isonly = False use.items = funcnames parent.content.insert(0, use) return use
def __init__(self, parent, content): reader = FortranStringReader("! content\n") reader.set_mode(True, True) # free form, strict subline = reader.next() my_comment = Comment(parent.root, subline) my_comment.content = content BaseGen.__init__(self, parent, my_comment)
def __init__(self, parent, name="", args=None): reader = FortranStringReader("call vanilla(vanilla_arg)") reader.set_mode(True, True) # free form, strict myline = reader.next() from fparser.block_statements import Call self._call = Call(parent.root, myline) self._call.designator = name if args is None: args = [] self._call.items = args BaseGen.__init__(self, parent, self._call)
def __init__(self, parent, content): from fparser.statements import Deallocate reader = FortranStringReader("deallocate(dummy)") reader.set_mode(True, False) # free form, strict myline = reader.next() self._decl = Deallocate(parent.root, myline) if isinstance(content, str): self._decl.items = [content] elif isinstance(content, list): self._decl.items = content else: raise RuntimeError( "DeallocateGen expected the content argument to be a str" " or a list, but found {0}".format(type(content))) BaseGen.__init__(self, parent, self._decl)
def __init__(self, parent, name="", only=False, funcnames=None): reader = FortranStringReader("use kern,only : func1_kern=>func1") reader.set_mode(True, True) # free form, strict myline = reader.next() root = parent.root from fparser.block_statements import Use use = Use(root, myline) use.name = name use.isonly = only if funcnames is None: funcnames = [] use.isonly = False local_funcnames = funcnames[:] use.items = local_funcnames BaseGen.__init__(self, parent, use)
def __init__(self, parent): if not isinstance(parent, ModuleGen) and not isinstance( parent, SubroutineGen): raise Exception( "The parent of ImplicitNoneGen must be a module or a " "subroutine, but found {0}".format(type(parent))) reader = FortranStringReader("IMPLICIT NONE\n") reader.set_mode(True, True) # free form, strict subline = reader.next() from fparser.typedecl_statements import Implicit my_imp_none = Implicit(parent.root, subline) BaseGen.__init__(self, parent, my_imp_none)
def parse(cls, line, label='', isfree=True, isstrict=False): if label: line = label + ' : ' + line reader = FortranStringReader(line) reader.set_mode(isfree, isstrict) item = next(reader) if not cls.match(item.get_line()): raise ValueError('%r does not match %s pattern' % (line, cls.__name__)) stmt = cls(item, item) if stmt.isvalid: r = str(stmt) if not isstrict: r1 = parse(cls, r, isstrict=True) if r != r1: raise ValueError('Failed to parse %r with %s pattern in pyf mode, got %r' % (r, cls.__name__, r1)) return r raise ValueError('parsing %r with %s pattern failed' % (line, cls.__name__))
def __init__(self, parent, datatype="", entity_decls=None, intent="", pointer=False, kind="", dimension="", allocatable=False): if entity_decls is None: raise RuntimeError( "Cannot create a variable declaration without specifying the " "name(s) of the variable(s)") if datatype.lower() == "integer": from fparser.typedecl_statements import Integer reader = FortranStringReader("integer :: vanilla") reader.set_mode(True, False) # free form, strict myline = reader.next() self._decl = Integer(parent.root, myline) elif datatype.lower() == "real": from fparser.typedecl_statements import Real reader = FortranStringReader("real :: vanilla") reader.set_mode(True, False) # free form, strict myline = reader.next() self._decl = Real(parent.root, myline) else: raise RuntimeError( "f2pygen:DeclGen:init: Only integer and real are currently" " supported and you specified '{0}'".format(datatype)) # make a copy of entity_decls as we may modify it local_entity_decls = entity_decls[:] self._decl.entity_decls = local_entity_decls my_attrspec = [] if intent != "": my_attrspec.append("intent({0})".format(intent)) if pointer is not False: my_attrspec.append("pointer") if allocatable is not False: my_attrspec.append("allocatable") self._decl.attrspec = my_attrspec if dimension != "": my_attrspec.append("dimension({0})".format(dimension)) if kind is not "": self._decl.selector = ('', kind) BaseGen.__init__(self, parent, self._decl)
def parse(cls, line, label='', isfree=True, isstrict=False): if label: line = label + ' : ' + line reader = FortranStringReader(line) reader.set_mode(isfree, isstrict) item = reader.next() if not cls.match(item.get_line()): raise ValueError, '%r does not match %s pattern' % (line, cls.__name__) stmt = cls(item, item) if stmt.isvalid: r = str(stmt) if not isstrict: r1 = parse(cls, r, isstrict=True) if r != r1: raise ValueError, 'Failed to parse %r with %s pattern in pyf mode, got %r' % ( r, cls.__name__, r1) return r raise ValueError, 'parsing %r with %s pattern failed' % (line, cls.__name__)
def test_class_internal_error(monkeypatch, capsys): ''' Check that expected errors are raised when invalid CLASS statements are encountered ''' from fparser.block_statements import ClassIs from fparser.readfortran import FortranStringReader reader = FortranStringReader('CLASS IS (yes)') reader.set_mode(True, False) item = next(reader) stmt = ClassIs(item, item) # Monkeypatch our valid Case object so that get_line() now # returns something invalid. We have to do it this way # because if we started with this text then we wouldn't get # past the match() method monkeypatch.setattr(stmt.item, "get_line", lambda: "class invalid") # Monkeypatch the Case object so that a call to self.warning # (which normally results in a call to the logger) gets replaced # with a call to our print_wrapper() function monkeypatch.setattr(stmt, "warning", print_wrapper) stmt.process_item() output, _ = capsys.readouterr() assert "Internal error when parsing CLASS statement" in output
def __init__(self, parent, expr="UNSET", typeselect=False): ''' construct a ... ''' from fparser.block_statements import EndSelect self._typeselect = typeselect reader = FortranStringReader( "SELECT CASE (x)\nCASE (1)\nCASE DEFAULT\nEND SELECT") reader.set_mode(True, True) # free form, strict select_line = reader.next() self._case_line = reader.next() self._case_default_line = reader.next() end_select_line = reader.next() if self._typeselect: select = TypeSelect(parent.root, select_line) else: select = Select(parent.root, select_line) endselect = EndSelect(select, end_select_line) select.expr = expr select.content.append(endselect) BaseGen.__init__(self, parent, select)
def __init__(self, parent, lhs="", rhs="", pointer=False): if pointer: reader = FortranStringReader("lhs=>rhs") else: reader = FortranStringReader("lhs=rhs") reader.set_mode(True, True) # free form, strict myline = reader.next() if pointer: from fparser.statements import PointerAssignment self._assign = PointerAssignment(parent.root, myline) else: from fparser.statements import Assignment self._assign = Assignment(parent.root, myline) self._assign.expr = rhs self._assign.variable = lhs BaseGen.__init__(self, parent, self._assign)
def __init__(self, parent, clause): reader = FortranStringReader("if (dummy) then\nend if") reader.set_mode(True, True) # free form, strict ifthenline = reader.next() endifline = reader.next() from fparser.block_statements import IfThen, EndIfThen my_if = IfThen(parent.root, ifthenline) my_if.expr = clause my_endif = EndIfThen(my_if, endifline) my_if.content.append(my_endif) BaseGen.__init__(self, parent, my_if)
def __init__(self, parent, variable_name, start, end, step=None): reader = FortranStringReader("do i=1,n\nend do") reader.set_mode(True, True) # free form, strict doline = reader.next() enddoline = reader.next() from fparser.block_statements import Do, EndDo dogen = Do(parent.root, doline) dogen.loopcontrol = variable_name + "=" + start + "," + end if step is not None: dogen.loopcontrol = dogen.loopcontrol + "," + step enddo = EndDo(dogen, enddoline) dogen.content.append(enddo) BaseGen.__init__(self, parent, dogen)
def __init__(self, parent, name="", args=None, implicitnone=False): reader = FortranStringReader( "subroutine vanilla(vanilla_arg)\nend subroutine") reader.set_mode(True, True) # free form, strict subline = reader.next() endsubline = reader.next() from fparser.block_statements import Subroutine, EndSubroutine self._sub = Subroutine(parent.root, subline) self._sub.name = name if args is None: args = [] self._sub.args = args endsub = EndSubroutine(self._sub, endsubline) self._sub.content.append(endsub) ProgUnitGen.__init__(self, parent, self._sub) if implicitnone: self.add(ImplicitNoneGen(self))