예제 #1
0
파일: gen.py 프로젝트: stfc/fgenerator
    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)
예제 #2
0
파일: gen.py 프로젝트: stfc/fgenerator
    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)
예제 #3
0
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__))
예제 #4
0
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
예제 #5
0
파일: gen.py 프로젝트: stfc/fgenerator
    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)
예제 #6
0
파일: gen.py 프로젝트: stfc/fgenerator
    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)
예제 #7
0
파일: gen.py 프로젝트: stfc/fgenerator
 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)
예제 #8
0
파일: gen.py 프로젝트: stfc/fgenerator
 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)
예제 #9
0
파일: gen.py 프로젝트: stfc/fgenerator
    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)
예제 #10
0
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__))
예제 #11
0
파일: gen.py 프로젝트: stfc/fgenerator
    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)
예제 #12
0
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__)
예제 #13
0
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
예제 #14
0
파일: gen.py 프로젝트: stfc/fgenerator
 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)
예제 #15
0
파일: gen.py 프로젝트: stfc/fgenerator
 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)
예제 #16
0
파일: gen.py 프로젝트: stfc/fgenerator
    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)
예제 #17
0
파일: gen.py 프로젝트: stfc/fgenerator
    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)
예제 #18
0
파일: gen.py 프로젝트: stfc/fgenerator
    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))