From 145d85af8e610243024aa715d5470922b0450308 Mon Sep 17 00:00:00 2001 From: Rupert Ford Date: Thu, 28 Mar 2019 11:26:16 +0000 Subject: [PATCH 1/7] issue #171. Hack to remove statement function matching. --- src/fparser/scripts/fparser2.py | 1 + src/fparser/sergi_example.f90 | 4 ++++ src/fparser/two/Fortran2003.py | 6 +++++- src/fparser/two/Fortran2008.py | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 src/fparser/sergi_example.f90 diff --git a/src/fparser/scripts/fparser2.py b/src/fparser/scripts/fparser2.py index d04e2f5b..355ce6f2 100755 --- a/src/fparser/scripts/fparser2.py +++ b/src/fparser/scripts/fparser2.py @@ -98,6 +98,7 @@ def runner(_, options, args): f2003_parser = ParserFactory().create() program = f2003_parser(reader) print (program) + print (repr(program)) except FortranSyntaxError as msg: print ("Syntax error: {0}".format(str(msg))) try: diff --git a/src/fparser/sergi_example.f90 b/src/fparser/sergi_example.f90 new file mode 100644 index 00000000..5300597c --- /dev/null +++ b/src/fparser/sergi_example.f90 @@ -0,0 +1,4 @@ + subroutine field_copy_code() + output(ji,jj) = input(ji,jj) + end subroutine field_copy_code + diff --git a/src/fparser/two/Fortran2003.py b/src/fparser/two/Fortran2003.py index 4ecde5bb..c9af013e 100644 --- a/src/fparser/two/Fortran2003.py +++ b/src/fparser/two/Fortran2003.py @@ -425,10 +425,14 @@ class Declaration_Construct(Base): # R207 | | """ + #subclass_names = ['Comment', 'Derived_Type_Def', 'Entry_Stmt', 'Enum_Def', + # 'Format_Stmt', 'Interface_Block', 'Parameter_Stmt', + # 'Procedure_Declaration_Stmt', 'Specification_Stmt', + # 'Type_Declaration_Stmt', 'Stmt_Function_Stmt'] subclass_names = ['Comment', 'Derived_Type_Def', 'Entry_Stmt', 'Enum_Def', 'Format_Stmt', 'Interface_Block', 'Parameter_Stmt', 'Procedure_Declaration_Stmt', 'Specification_Stmt', - 'Type_Declaration_Stmt', 'Stmt_Function_Stmt'] + 'Type_Declaration_Stmt'] class Execution_Part(BlockBase): # R208 diff --git a/src/fparser/two/Fortran2008.py b/src/fparser/two/Fortran2008.py index e1c14c47..ad1cb8b4 100644 --- a/src/fparser/two/Fortran2008.py +++ b/src/fparser/two/Fortran2008.py @@ -192,7 +192,7 @@ class Declaration_Construct_C1112(Declaration_Construct): # C1112 subclass_names = Declaration_Construct.subclass_names[:] subclass_names.remove('Format_Stmt') subclass_names.remove('Entry_Stmt') - subclass_names.remove('Stmt_Function_Stmt') + #subclass_names.remove('Stmt_Function_Stmt') class Submodule(BlockBase): # R1116 [C1112,C1114] From 8eeadd1fc7c6c2354b3b87629fd9a9242d06a387 Mon Sep 17 00:00:00 2001 From: Rupert Ford Date: Fri, 31 May 2019 01:08:43 +0100 Subject: [PATCH 2/7] pr #200. Adding fparser2 repr support. --- src/fparser/scripts/fparser2.py | 6 +- src/fparser/scripts/script_options.py | 2 +- src/fparser/two/tests/test_scripts.py | 160 ++++++++++++++++++++++++-- 3 files changed, 155 insertions(+), 13 deletions(-) diff --git a/src/fparser/scripts/fparser2.py b/src/fparser/scripts/fparser2.py index 355ce6f2..0912b399 100755 --- a/src/fparser/scripts/fparser2.py +++ b/src/fparser/scripts/fparser2.py @@ -97,8 +97,10 @@ def runner(_, options, args): try: f2003_parser = ParserFactory().create() program = f2003_parser(reader) - print (program) - print (repr(program)) + if options.task == "show": + print (program) + if options.task == "repr": + print (repr(program)) except FortranSyntaxError as msg: print ("Syntax error: {0}".format(str(msg))) try: diff --git a/src/fparser/scripts/script_options.py b/src/fparser/scripts/script_options.py index 8ccf7840..d38a26d9 100644 --- a/src/fparser/scripts/script_options.py +++ b/src/fparser/scripts/script_options.py @@ -100,7 +100,7 @@ def set_fparser_options(parser): %prog parses Fortran code.''') parser.add_option('--task', default = 'show', - choices = ['show', 'none'], + choices = ['show', 'repr', 'none'], help = 'Specify parsing result task. Default: %default.' ) parser.add_option('--std', diff --git a/src/fparser/two/tests/test_scripts.py b/src/fparser/two/tests/test_scripts.py index 3818110f..5f7d8b94 100644 --- a/src/fparser/two/tests/test_scripts.py +++ b/src/fparser/two/tests/test_scripts.py @@ -50,6 +50,7 @@ class DummyArgs(object): ''' dummy object pretending to be the argument options ''' mode = "auto" + task = "show" def test_runner_no_files(capsys): @@ -86,6 +87,7 @@ def test_runner_set_mode(tmpdir, capsys): class DummyArgsFree(object): ''' dummy object pretending to be the argument options ''' mode = "free" + task = "show" # run the relevant script method (runner()) fparser2.runner(None, DummyArgsFree(), [my_file.strpath]) # capture the output and check that the code has been output @@ -155,18 +157,71 @@ def dummy_parser(_): assert "Internal error in fparser: '{0}'".format(error_string) in stdout -def test_runner_output(tmpdir, capsys): - '''Test that the script outputs the code it has parsed ''' - # Create a temporary file containing Fortran code to pass into runner() +def test_runner_output_task_show(tmpdir, capsys): + '''Test that the script outputs the code it has parsed with the + 'task' option set to "show". + + ''' + class DummyArgsTask(object): + ''' dummy object pretending to be the argument options ''' + mode = "free" + task = "show" + + # Create a temporary file containing Fortran code to pass into + # runner(). my_file = tmpdir.mkdir("sub").join("hello.f90") my_file.write("program hello\nend program hello\n") - # run the relevant script method (runner()) - fparser2.runner(None, DummyArgs(), [my_file.strpath]) - # capture the output and check that the code has been output + # Run the relevant script method (runner()). + fparser2.runner(None, DummyArgsTask(), [my_file.strpath]) + # Capture the output and check that the code has been output. stdout, _ = capsys.readouterr() assert "PROGRAM hello\nEND PROGRAM hello\n" in stdout +def test_runner_output_task_repr(tmpdir, capsys): + '''Test that the script outputs the repr representation of the code it + has parsed with the 'task' option set to "repr". + + ''' + class DummyArgsTask(object): + ''' dummy object pretending to be the argument options ''' + mode = "free" + task = "repr" + + # Create a temporary file containing Fortran code to pass into + # runner(). + my_file = tmpdir.mkdir("sub").join("hello.f90") + my_file.write("program hello\nend program hello\n") + # Run the relevant script method (runner()). + fparser2.runner(None, DummyArgsTask(), [my_file.strpath]) + # Capture the output and check that the repr of the code has been + # produced. + stdout, _ = capsys.readouterr() + assert (stdout == "Program(Main_Program(Program_Stmt('PROGRAM'," + " Name('hello')), End_Program_Stmt('PROGRAM', Name('hello'))))\n") + + +def test_runner_output_task_none(tmpdir, capsys): + '''Test that the script outputs nothing when the 'task' option is set + to "none". + + ''' + class DummyArgsTask(object): + ''' dummy object pretending to be the argument options ''' + mode = "free" + task = "none" + + # Create a temporary file containing Fortran code to pass into + # runner(). + my_file = tmpdir.mkdir("sub").join("hello.f90") + my_file.write("program hello\nend program hello\n") + # Run the relevant script method (runner()). + fparser2.runner(None, DummyArgsTask(), [my_file.strpath]) + # Capture the output and check that nothig has been produced. + stdout, _ = capsys.readouterr() + assert stdout == "" + + def test_runner_multi_output(tmpdir, capsys): '''Test that the script outputs the code it has parsed when there are multiple files specified @@ -184,9 +239,9 @@ def test_runner_multi_output(tmpdir, capsys): # fparser2.py script function main() - -def test_main_output(tmpdir, capsys, monkeypatch): - '''Test that the script main() function outputs the code it has parsed''' +def test_main_output_task_default(tmpdir, capsys, monkeypatch): + '''Test that the script main() function outputs the code it has parsed + by default.''' import sys # Create a temporary file containing Fortran code to pass into runner() my_file = tmpdir.mkdir("sub").join("hello.f90") @@ -197,7 +252,92 @@ def test_main_output(tmpdir, capsys, monkeypatch): fparser2.main() # capture the output and check that the code has been output stdout, _ = capsys.readouterr() - assert "PROGRAM hello\nEND PROGRAM hello\n" in stdout + assert stdout == "PROGRAM hello\nEND PROGRAM hello\n" + + +def test_main_output_task_show(tmpdir, capsys, monkeypatch): + '''Test that the script main() function outputs the code it has parsed + when --task=show. + + ''' + import sys + # Create a temporary file containing Fortran code to pass into + # runner(). + my_file = tmpdir.mkdir("sub").join("hello.f90") + my_file.write("program hello\nend program hello\n") + # Use monkeypatch to spoof the command-line argument. + monkeypatch.setattr(sys, "argv", ["fparser2", "--task=show", + my_file.strpath]) + # Run the relevant script method (main()). + fparser2.main() + # Capture the output and check that the code has been output. + stdout, _ = capsys.readouterr() + assert stdout == "PROGRAM hello\nEND PROGRAM hello\n" + + +def test_main_output_task_repr(tmpdir, capsys, monkeypatch): + '''Test that the script main() function outputs the 'repr' of the code + it has parsed when --task=repr. + + ''' + import sys + # Create a temporary file containing Fortran code to pass into + # runner(). + my_file = tmpdir.mkdir("sub").join("hello.f90") + my_file.write("program hello\nend program hello\n") + # Use monkeypatch to spoof the command-line argument. + monkeypatch.setattr(sys, "argv", ["fparser2", "--task=repr", + my_file.strpath]) + # Run the relevant script method (main()). + fparser2.main() + # Capture the output and check that the code has been output. + stdout, _ = capsys.readouterr() + assert stdout == ("Program(Main_Program(Program_Stmt('PROGRAM'," + " Name('hello')), End_Program_Stmt('PROGRAM'," + " Name('hello'))))\n") + + +def test_main_output_task_none(tmpdir, capsys, monkeypatch): + '''Test that the script main() function outputs nothing when + --task=none. + + ''' + import sys + # Create a temporary file containing Fortran code to pass into + # runner(). + my_file = tmpdir.mkdir("sub").join("hello.f90") + my_file.write("program hello\nend program hello\n") + # Use monkeypatch to spoof the command-line argument. + monkeypatch.setattr(sys, "argv", ["fparser2", "--task=none", + my_file.strpath]) + # Run the relevant script method (main()). + fparser2.main() + # Capture the output and check that the code has been output. + stdout, _ = capsys.readouterr() + assert stdout == "" + + +def test_main_output_task_invalid(tmpdir, capsys, monkeypatch): + '''Test that the script main() function prints an error when an + invalid task option is provided. + + ''' + import sys + # Create a temporary file containing Fortran code to pass into + # runner(). + my_file = tmpdir.mkdir("sub").join("hello.f90") + my_file.write("program hello\nend program hello\n") + # Use monkeypatch to spoof the command-line argument. + monkeypatch.setattr(sys, "argv", ["fparser2", "--task=invalid", + my_file.strpath]) + with pytest.raises(SystemExit): + # Run the relevant script method (main()). + fparser2.main() + # Capture the output and check that the appropriate error has been + # written. + _, stderr = capsys.readouterr() + assert ("fparser2: error: option --task: invalid choice: 'invalid'" + "" in stderr) # read.py script function runner() From 21ca5b81873876b8643b0ec478698f786dd3c828 Mon Sep 17 00:00:00 2001 From: Rupert Ford Date: Sun, 2 Jun 2019 21:57:22 +0100 Subject: [PATCH 3/7] pr #200. Completed tests. --- src/fparser/sergi_example.f90 | 4 - src/fparser/two/Fortran2003.py | 40 ++-- src/fparser/two/Fortran2008.py | 5 +- .../test_declaration_construct_r207.py | 173 ++++++++++++++++++ 4 files changed, 199 insertions(+), 23 deletions(-) delete mode 100644 src/fparser/sergi_example.f90 create mode 100644 src/fparser/two/tests/fortran2003/test_declaration_construct_r207.py diff --git a/src/fparser/sergi_example.f90 b/src/fparser/sergi_example.f90 deleted file mode 100644 index 5300597c..00000000 --- a/src/fparser/sergi_example.f90 +++ /dev/null @@ -1,4 +0,0 @@ - subroutine field_copy_code() - output(ji,jj) = input(ji,jj) - end subroutine field_copy_code - diff --git a/src/fparser/two/Fortran2003.py b/src/fparser/two/Fortran2003.py index c9af013e..e34993fa 100644 --- a/src/fparser/two/Fortran2003.py +++ b/src/fparser/two/Fortran2003.py @@ -412,24 +412,28 @@ class Implicit_Part_Stmt(Base): # R206 class Declaration_Construct(Base): # R207 - """ -:F03R:`207`:: - = - | - | - | - | - | - | - | - | - | - """ - #subclass_names = ['Comment', 'Derived_Type_Def', 'Entry_Stmt', 'Enum_Def', - # 'Format_Stmt', 'Interface_Block', 'Parameter_Stmt', - # 'Procedure_Declaration_Stmt', 'Specification_Stmt', - # 'Type_Declaration_Stmt', 'Stmt_Function_Stmt'] - subclass_names = ['Comment', 'Derived_Type_Def', 'Entry_Stmt', 'Enum_Def', + '''Fortran 2003 rule R207 + + declaration-construct is derived-type-def + or entry-stmt + or enum-def + or format-stmt + or interface-block + or parameter-stmt + or procedure-declaration-stmt + or specification-stmt + or type-declaration-stmt + or stmt-function-stmt + + Note, stmt-function-stmt is not currently matched. + + ''' + # Commented out Stmt_Function_Stmt as it can falsely match an + # access to an array or function. Reintroducing statement + # functions is captured in issue #202. + + # 'Type_Declaration_Stmt', 'Stmt_Function_Stmt'] + subclass_names = ['Derived_Type_Def', 'Entry_Stmt', 'Enum_Def', 'Format_Stmt', 'Interface_Block', 'Parameter_Stmt', 'Procedure_Declaration_Stmt', 'Specification_Stmt', 'Type_Declaration_Stmt'] diff --git a/src/fparser/two/Fortran2008.py b/src/fparser/two/Fortran2008.py index ad1cb8b4..917c1fa8 100644 --- a/src/fparser/two/Fortran2008.py +++ b/src/fparser/two/Fortran2008.py @@ -192,7 +192,10 @@ class Declaration_Construct_C1112(Declaration_Construct): # C1112 subclass_names = Declaration_Construct.subclass_names[:] subclass_names.remove('Format_Stmt') subclass_names.remove('Entry_Stmt') - #subclass_names.remove('Stmt_Function_Stmt') + # Commented out Stmt_Function_Stmt as it can falsely match an + # access to an array or function. Reintroducing statement + # functions is captured in issue #202. + # subclass_names.remove('Stmt_Function_Stmt') class Submodule(BlockBase): # R1116 [C1112,C1114] diff --git a/src/fparser/two/tests/fortran2003/test_declaration_construct_r207.py b/src/fparser/two/tests/fortran2003/test_declaration_construct_r207.py new file mode 100644 index 00000000..c86ed12f --- /dev/null +++ b/src/fparser/two/tests/fortran2003/test_declaration_construct_r207.py @@ -0,0 +1,173 @@ +# Copyright (c) 2019 Science and Technology Facilities Council + +# All rights reserved. + +# Modifications made as part of the fparser project are distributed +# under the following license: + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: + +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. + +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +'''Test Fortran 2003 rule R207 : This file tests support for the +Declaration_Construct class. + +As this class just uses Base to match with a choice of subclasses we +test that an instance of each subclass can be succesfully +parsed. Detailed checking of the subclass rules are performed by the +subclass tests. + +''' + +import pytest +from fparser.two.Fortran2003 import Declaration_Construct +from fparser.api import get_reader + + +def test_derived_type_def(f2003_create): + '''Test a derived type definition statement is supported by the + declaration construct class. + + ''' + code = ("TYPE :: my_type\n" + "END TYPE my_type") + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Derived_Type_Def" in repr(result) + + +def test_entry_stmt(f2003_create): + '''Test an entry statement is supported by the declaration construct + class. + + ''' + code = "ENTRY my_function()" + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Entry_Stmt" in repr(result) + + +def test_enum_def(f2003_create): + '''Test an enum definition is supported by the declaration construct + class. + + ''' + code = ("ENUM, BIND(C)\n" + " ENUMERATOR :: a = 1\n" + "END ENUM") + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Enum_Def" in repr(result) + + +def test_format_statement(f2003_create): + '''Test a format statement is supported by the declaration construct + class. + + ''' + code = "FORMAT('(x)')" + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Format_Stmt" in repr(result) + + +def test_interface_block(f2003_create): + '''Test an interface block statement is supported by the declaration + construct class. + + ''' + code = ("INTERFACE\n" + "END INTERFACE") + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Interface_Block" in repr(result) + + +def test_parameter_stmt(f2003_create): + '''Test a parameter statement is supported by the declaration + construct class. + + ''' + code = "PARAMETER(A = 2)" + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Parameter_Stmt" in repr(result) + + +def test_procedure_declaration_stmt(f2003_create): + '''Test a procedure declaration statement is supported by the + declaration construct class. + + ''' + code = "PROCEDURE(REAL) FUNC" + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Procedure_Declaration_Stmt" in repr(result) + + +def test_specification_stmt(f2003_create): + '''Test a specification statement is supported by the declaration + construct class. An access statement is a specification statement, + so check for this. + + ''' + code = "PUBLIC :: A" + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Access_Stmt" in repr(result) + + +def test_type_declaration_stmt(f2003_create): + '''Test a type declarations statement is supported by the declaration + construct class. + + ''' + code = "INTEGER :: X" + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Type_Declaration_Stmt" in repr(result) + + +@pytest.mark.xfail(reason="#202. Statement Function support removed.") +def test_stmt_function_stmt(f2003_create): + '''Test a type declarations statement is supported by the declaration + construct class. + + ''' + code = "C(F) = 5.0*(F - 32.0)/9.0" + reader = get_reader(code) + result = Declaration_Construct(reader) + assert str(result) == code + assert "Stmt_Function_Stmt" in repr(result) From e31334511d7ca4245f488a66d257349abf82ccbb Mon Sep 17 00:00:00 2001 From: Rupert Ford Date: Sun, 2 Jun 2019 22:59:52 +0100 Subject: [PATCH 4/7] pr #200 Tidying for code conformance. --- src/fparser/scripts/fparser2.py | 15 ++++++++------- src/fparser/scripts/script_options.py | 13 ++++++++++--- src/fparser/two/tests/test_scripts.py | 1 + 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/fparser/scripts/fparser2.py b/src/fparser/scripts/fparser2.py index 0912b399..ac9b0621 100755 --- a/src/fparser/scripts/fparser2.py +++ b/src/fparser/scripts/fparser2.py @@ -83,14 +83,14 @@ def runner(_, options, args): from fparser.two.Fortran2003 import FortranSyntaxError, InternalError from fparser.common.readfortran import FortranFileReader if not args: - print ("Error: No fortran files specified") + print("Error: No fortran files specified") raise SystemExit(1) for filename in args: try: reader = FortranFileReader(filename, ignore_comments=False) except IOError as error: - print (error) + print(error) return if options.mode != 'auto': reader.format.from_mode(options.mode) @@ -98,21 +98,22 @@ def runner(_, options, args): f2003_parser = ParserFactory().create() program = f2003_parser(reader) if options.task == "show": - print (program) + print(program) if options.task == "repr": - print (repr(program)) + print(repr(program)) except FortranSyntaxError as msg: - print ("Syntax error: {0}".format(str(msg))) + print("Syntax error: {0}".format(str(msg))) try: # protect the access to fifo_item[-1] in case the fifo # buffer is empty - print('parsing %r failed at %s' % (filename, reader.fifo_item[-1])) + print('parsing %r failed at %s' % (filename, + reader.fifo_item[-1])) print('started at %s' % (reader.fifo_item[0])) except IndexError: pass raise SystemExit(1) except InternalError as msg: - print ("Internal error in fparser: {0}".format(str(msg))) + print("Internal error in fparser: {0}".format(str(msg))) raise SystemExit(1) diff --git a/src/fparser/scripts/script_options.py b/src/fparser/scripts/script_options.py index d38a26d9..2093db69 100644 --- a/src/fparser/scripts/script_options.py +++ b/src/fparser/scripts/script_options.py @@ -93,15 +93,22 @@ def set_parse_options(parser): parser.add_option_group(get_fortran_code_group(parser)) def set_fparser_options(parser): + ''' Command line options used by the fparser2 script. + + :param parser: The OptionParser object. + :type parser: :py:class:`optparse.OptionParser` + + ''' + parser.set_usage('''\ %prog [options] Description: %prog parses Fortran code.''') parser.add_option('--task', - default = 'show', - choices = ['show', 'repr', 'none'], - help = 'Specify parsing result task. Default: %default.' + default='show', + choices=['show', 'repr', 'none'], + help='Specify parsing result task. Default: %default.' ) parser.add_option('--std', default = 'f2003', diff --git a/src/fparser/two/tests/test_scripts.py b/src/fparser/two/tests/test_scripts.py index 5f7d8b94..ea1d417a 100644 --- a/src/fparser/two/tests/test_scripts.py +++ b/src/fparser/two/tests/test_scripts.py @@ -239,6 +239,7 @@ def test_runner_multi_output(tmpdir, capsys): # fparser2.py script function main() + def test_main_output_task_default(tmpdir, capsys, monkeypatch): '''Test that the script main() function outputs the code it has parsed by default.''' From 7a07d974d2feeaa5a2a69770026f9abb4be36e83 Mon Sep 17 00:00:00 2001 From: Rupert Ford Date: Wed, 26 Jun 2019 11:36:50 +0100 Subject: [PATCH 5/7] pr #200. Addressed reviewers comments. --- src/fparser/scripts/fparser2.py | 3 +-- .../two/tests/fortran2003/test_declaration_construct_r207.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/fparser/scripts/fparser2.py b/src/fparser/scripts/fparser2.py index ac9b0621..613557e0 100755 --- a/src/fparser/scripts/fparser2.py +++ b/src/fparser/scripts/fparser2.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Modified work Copyright (c) 2017-2018 Science and Technology +# Modified work Copyright (c) 2017-2019 Science and Technology # Facilities Council # Original work Copyright (c) 1999-2008 Pearu Peterson @@ -123,7 +123,6 @@ def main(): set_fparser_options(parser) options, args = parser.parse_args() runner(parser, options, args) - return if __name__ == "__main__": diff --git a/src/fparser/two/tests/fortran2003/test_declaration_construct_r207.py b/src/fparser/two/tests/fortran2003/test_declaration_construct_r207.py index c86ed12f..e25fb8d0 100644 --- a/src/fparser/two/tests/fortran2003/test_declaration_construct_r207.py +++ b/src/fparser/two/tests/fortran2003/test_declaration_construct_r207.py @@ -149,7 +149,7 @@ def test_specification_stmt(f2003_create): def test_type_declaration_stmt(f2003_create): - '''Test a type declarations statement is supported by the declaration + '''Test a type declaration statement is supported by the declaration construct class. ''' @@ -162,7 +162,7 @@ def test_type_declaration_stmt(f2003_create): @pytest.mark.xfail(reason="#202. Statement Function support removed.") def test_stmt_function_stmt(f2003_create): - '''Test a type declarations statement is supported by the declaration + '''Test a statement function statement is supported by the declaration construct class. ''' From 030d7de49536dd98231b7417d3552a93e02107d7 Mon Sep 17 00:00:00 2001 From: Rupert Ford Date: Tue, 2 Jul 2019 22:42:46 +0100 Subject: [PATCH 6/7] pr #200. Added documentation. --- doc/fparser2.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/fparser2.rst b/doc/fparser2.rst index d8705ec6..7bfe9ed3 100644 --- a/doc/fparser2.rst +++ b/doc/fparser2.rst @@ -160,6 +160,27 @@ number. For example: fparser.two.Fortran2003.FortranSyntaxError: at line 2 >>>en +Unsupported Features +-------------------- + +Statement Functions ++++++++++++++++++++ + +Fparser2 is currently not able to distinguish between statement +functions and array assignments when one or more array assignment +statements are the first statements after a declaration section. This +limitation leads to these particular array assignments being +incorrectly parsed as statement functions. + +To avoid this incorrect behaviour, support for statement functions has +been temporarily removed from fparser2. However, with this change, +statement functions will be incorrectly parsed as array assignments +when one or more statement function statements are the last statements +in a declaration section. + +Whilst any incorrect behaviour should be avoided, the behaviour of +this temporary change is considered preferable to the former case, as +array assigments are more common than statement functions. Extensions ---------- From 28044b00a05e7300b55e9f7dedfc9faf031487c7 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Wed, 3 Jul 2019 09:34:33 +0100 Subject: [PATCH 7/7] #200 update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4771430c..e8182f0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ Modifications by (in alphabetical order): * A. R. Porter, Science & Technology Facilities Council, UK * P. Vitt, University of Siegen, Germany +03/07/2019 PR #200 for #171. Disable Statement Function support + in fparser2. + 02/07/2019 PR #205 for #204. Corrects the minimum number of arguments for the SELECTED_REAL_KIND intrinsic.