Ejemplo n.º 1
0
def test_get_type_by_name(monkeypatch):
    ''' Tests for HasImplicitStmt.get_type_by_name(). '''
    from fparser.common.utils import AnalyzeError
    from fparser.common.readfortran import FortranStringReader
    from fparser.common.sourceinfo import FortranFormat
    from fparser.one.typedecl_statements import Real, Integer
    from fparser.one.parsefortran import FortranParser
    # We can't just create a HasImplicitStmt object so we get the parser
    # to create a module object as that sub-classes HasImplicitStmt (amongst
    # other things).
    string = '''\
module some_block
end module some_block
'''
    reader = FortranStringReader(string)
    reader.set_format(FortranFormat(True, False))
    parser = FortranParser(reader)
    parser.parse()
    mod = parser.block.content[0]
    # Now we have a Module object, we can call get_type_by_name()...
    rtype = mod.get_type_by_name("a_real")
    assert isinstance(rtype, Real)
    itype = mod.get_type_by_name("i_int")
    assert isinstance(itype, Integer)
    # Check that we raise the correct error if we don't have any implicit
    # rules set
    monkeypatch.setattr(mod.a, "implicit_rules", None)
    with pytest.raises(AnalyzeError) as err:
        _ = mod.get_type_by_name("i_int")
    assert "Implicit rules mapping is null" in str(err)
Ejemplo n.º 2
0
def test_get_type_by_name_implicit():
    ''' Tests for HasImplicitStmt.get_type_by_name() when the source code
    contains IMPLICIT statements. '''
    from fparser.common.readfortran import FortranStringReader
    from fparser.common.sourceinfo import FortranFormat
    from fparser.one.typedecl_statements import Real, Integer
    from fparser.one.parsefortran import FortranParser
    # We can't just create a HasImplicitStmt object so we get the parser
    # to create a module object as that sub-classes HasImplicitStmt (amongst
    # other things).
    string = '''\
module some_block
  implicit real (a-e)
  implicit integer (f-z)
end module some_block
'''
    reader = FortranStringReader(string)
    reader.set_format(FortranFormat(True, False))
    parser = FortranParser(reader)
    parser.parse()
    # Get the module object
    mod = parser.block.content[0]
    # We have to run the analyze method on the Implicit objects
    # produced by the parser in order to populate the implicit_rules
    # of the module.
    mod.content[0].analyze()
    mod.content[1].analyze()
    # Now we can call get_type_by_name()...
    rtype = mod.get_type_by_name("a_real")
    assert isinstance(rtype, Real)
    itype = mod.get_type_by_name("f_int")
    assert isinstance(itype, Integer)
Ejemplo n.º 3
0
def test_implicit_topyf(monkeypatch):
    ''' Tests for the topyf() method of HasImplicitStmt. '''
    from fparser.common.readfortran import FortranStringReader
    from fparser.common.sourceinfo import FortranFormat
    from fparser.one.parsefortran import FortranParser
    # We can't just create a HasImplicitStmt object so we get the parser
    # to create a module object as that sub-classes HasImplicitStmt (amongst
    # other things).
    string = '''\
module some_block
  implicit real (a-e)
  implicit integer (f-z)
end module some_block
'''
    reader = FortranStringReader(string)
    reader.set_format(FortranFormat(True, False))
    parser = FortranParser(reader)
    parser.parse()
    # Get the module object
    mod = parser.block.content[0]
    code = mod.topyf()
    assert "! default IMPLICIT rules apply" in code
    mod.content[0].analyze()
    mod.content[1].analyze()
    code = mod.topyf()
    assert "REAL (a, b, c, d, e)" in code
    assert "INTEGER (f, g, h" in code
    monkeypatch.setattr(mod.a, "implicit_rules", None)
    code = mod.topyf()
    assert "IMPLICIT NONE" in code
Ejemplo n.º 4
0
def parse(source,
          isfree=None,
          isstrict=None,
          include_dirs=None,
          source_only=None,
          ignore_comments=True,
          analyze=True,
          clear_cache=True):
    """
    Parse input and return Statement tree. Raises an AnalyzeError if the
    parser can not parse the Fortran code.

    :param str source: Specify a string or filename containing Fortran code.
    :param bool isfree: Whether the Fortran source is free-format.
    :param bool isstrict: Whether we are to strictly enforce the `isfree`
                          setting.
    :param list include_dirs: Specify a list of include directories. The
                              default list (when include_dirs=None) contains
                              the current working directory and the directory
                              of ``filename``.
    :param list source_only: A list of Fortran file names that are searched
                             when the ``USE`` statement is encountered.
    :param bool ignore_comments: When True then discard all comment lines in
                                 the Fortran code.
    :param bool analyze: When True then apply analyze() method on the Fortran
                         code tree.
    :param bool clear_cache: Whether or not to wipe the parser cache prior
                             to parsing. Necessary when a new tree object
                             is required, even if the Fortran to be parsed has
                             been seen before.

    :returns: Abstract Syntax Tree of Fortran source.
    :rtype: :py:class:`fparser.api.BeginSource`
    """
    from fparser.one.parsefortran import FortranParser

    if clear_cache:
        # Wipe the parser cache if requested
        FortranParser.cache.clear()

    reader = get_reader(source,
                        isfree,
                        isstrict,
                        include_dirs,
                        source_only,
                        ignore_comments=ignore_comments)
    parser = FortranParser(reader, ignore_comments=ignore_comments)
    try:
        parser.parse()
    except AnalyzeError:
        raise
    if analyze:
        parser.analyze()

    return parser.block
Ejemplo n.º 5
0
def test_analyze_errors():
    ''' Tests that AnalyzeErrors are raised as expected. It also tests
    for various calling-sequence issues, e.g. parsing or analyzing twice,
    or calling analyze() without calling parse() first.'''
    from fparser import api
    source_str = """none subroutine test()
      end
    """
    with pytest.raises(AnalyzeError) as error:
        _ = api.parse(source_str, isfree=True, isstrict=False)
    assert "no parse pattern found" in str(error.value)

    source_str = """subroutine test()
        incorrect :: c
      end
    """
    with pytest.raises(AnalyzeError) as error:
        _ = api.parse(source_str, isfree=False, isstrict=False)
    assert "no parse pattern found" in str(error.value)

    source_str = """subroutine test()
      end
    """
    from fparser.one.parsefortran import FortranParser
    reader = api.get_reader(source_str)
    parser = FortranParser(reader)

    # Handle analyze before parsing (does not raise an exception atm)
    parser.analyze()
    # Cover case that parsing is called twice
    parser.parse()
    parser.parse()

    # Check if analyse is called twice
    parser.analyze()
    parser.analyze()
Ejemplo n.º 6
0
def test_do(name, label, control_comma, terminal_expression, end_name,
            end_label):
    # pylint: disable=redefined-outer-name, too-many-arguments, too-many-locals
    '''
    Checks that the "do" loop parser understands the "for-next" variant of
    the syntax. This is defined in BS ISO/IEC 1539-1:2010 with R814-R822.

    TODO: Only the terminal expression is tested. This is a short-cut and
          relies on expression handling being applied identically across
          all expressions. This was true at the time of writing the test.
    '''
    name_snippet = name + ': ' if name else None
    label_snippet = label + ' ' if label else None
    comma_snippet = ', ' if control_comma else None
    # TODO: Although the Fortran standard allows for "continue" to be used in
    # place of "end do" fparser does not support it.
    end_snippet = 'continue' if end_name == 'continue' \
                  else get_end_do(end_name)
    do_code = '''{name}do {label}{comma}variable = 1, {term}, 1
  write (6, '(I0)') variable
{endlabel} {end}
'''.format(name=name_snippet or '',
           label=label_snippet or '',
           comma=comma_snippet or '',
           term=terminal_expression,
           endlabel=end_label or '',
           end=end_snippet)
    do_expected = '''  {name}DO {label}variable = 1, {term}, 1
    WRITE (6, '(I0)') variable
{endlabel} {endstmt}
'''.format(name=name_snippet or '',
           label=label_snippet or '',
           term=terminal_expression,
           endlabel=end_label or ' ',
           endstmt=get_end_do(end_name))
    do_reader = FortranStringReader(do_code)
    do_reader.set_format(FortranFormat(True, False))
    do_parser = FortranParser(do_reader)
    if (name != end_name) or (label and (label != end_label)):
        with pytest.raises(AnalyzeError):
            do_parser.parse()
    else:
        do_parser.parse()
        loop = do_parser.block.content[0]
        assert str(loop).splitlines() == do_expected.splitlines()
Ejemplo n.º 7
0
def runner(parser, options, args):
    from fparser.common.readfortran import FortranFileReader
    from fparser.one.parsefortran import FortranParser
    for filename in args:
        reader = FortranFileReader(filename)
        if options.mode != 'auto':
            mode = fparser.common.sourceinfo\
                   .FortranFormat.from_mode(options.mode)
            reader.format.set_mode(mode)
        parser = FortranParser(reader)
        parser.parse()
        parser.analyze()
        if options.task == 'show':
            print(parser.block.torepr(4))
        elif options.task == 'none':
            pass
        else:
            raise NotImplementedError(repr(options.task))
Ejemplo n.º 8
0
def test_do_while(name, label, control_comma, terminal_expression, end_name,
                  end_label):
    # pylint: disable=redefined-outer-name, too-many-arguments
    '''
    Checks that the "do" loop parser understands the "do-while" variant of
    the syntax. This is defined in BS ISO/IEC 1539-1:2010 with R814-R822.
    '''
    name_snippet = name + ': ' if name else None
    label_snippet = label + ' ' if label else None
    comma_snippet = ', ' if control_comma else None
    code = '''{name}do {label}{comma}while ({term})
  write (6, '(I0)') variable
{endlabel} {endstmt}
'''.format(name=name_snippet or '',
           label=label_snippet or '',
           comma=comma_snippet or '',
           term=terminal_expression,
           endlabel=end_label or '',
           endstmt=get_end_do(end_name))
    expected = '''  {name}DO {label}while ({term})
    WRITE (6, '(I0)') variable
{endlabel} {endstmt}
'''.format(name=name_snippet or '',
           label=label_snippet or '',
           term=terminal_expression,
           endlabel=end_label or ' ',
           endstmt=get_end_do(end_name))
    print(code)
    reader = FortranStringReader(code)
    reader.set_format(FortranFormat(True, False))
    parser = FortranParser(reader)
    if (name != end_name) or (label and (label != end_label)):
        with pytest.raises(AnalyzeError):
            parser.parse()
    else:
        parser.parse()
        loop = parser.block.content[0]
        assert str(loop).splitlines() == expected.splitlines()
Ejemplo n.º 9
0
  if not os.path.exists(directory_path+"/instrumented"):
    os.makedirs(directory_path+"/instrumented")
  f=open(file_name)
  f2 = open(directory_path+"/instrumented/"+source_name, "w")
  line_num=1
  for line in f:
    if (line_num in start_line_nums):
      f2.write("call DLKHunter_startEventEpoch()\n")
    f2.write(line)
    if (line_num in end_line_nums):
      f2.write("call DLKHunter_stopEventEpoch(__FILE__, __LINE__)\n")
    if (line_num == import_line):
      f2.write("use dlkhunter_mod\n")
    line_num+=1
  f.close()
  f2.close()

file_name=sys.argv[1]
file_ending=file_name.split(".")[1].strip()
free_form = file_ending != "f"
reader=FortranFileReader(file_name)
reader.set_format(FortranFormat(free_form, False))
parser = FortranParser(reader)
parser.parse()
parser.analyze()
parseForFunctionSubroutineNames(parser.block)
parse(parser.block)
start_line_nums, end_line_nums=processIdentifiedLoopsForInstrumentation(all_loops, True)
createInstrumentedFile(file_name, start_line_nums, end_line_nums)