fparser.common.readfortran ========================== .. py:module:: fparser.common.readfortran .. autoapi-nested-parse:: Provides Fortran reader classes. Overview Provides FortranReader classes for reading Fortran codes from files and strings. FortranReader handles comments and line continuations of both fix and free format Fortran codes. Examples:: >> from fparser.common.readfortran import FortranFileReader >>> import os >>> reader = FortranFileReader(os.path.expanduser('~/src/blas/daxpy.f')) >>> print reader.next() line #1 'subroutine daxpy(n,da,dx,incx,dy,incy)' >>> print `reader.next()` Comment('c constant times a vector plus a vector.\n c uses unrolled loops for increments equal to one.\n c jack dongarra, linpack, 3/11/78.\n c modified 12/3/93, array(1) declarations changed to array(*)',(3, 6)) >>> print `reader.next()` Line('double precision dx(*),dy(*),da',(8, 8),'') >>> print `reader.next()` Line('integer i,incx,incy,ix,iy,m,mp1,n',(9, 9),'') Note that the ``.next()`` method may return `Line`, `SyntaxErrorLine`, `Comment`, `MultiLine`, or `SyntaxErrorMultiLine` instance. Let us continue with the above example session to illustrate the `Line` methods and attributes:: >>> item = reader.next() >>> item Line('if (da .eq. 0.0d0) return',(12, 12),'') >>> item.line 'if (da .eq. 0.0d0) return' >>> item.strline 'if (F2PY_EXPR_TUPLE_5) return' >>> item.strlinemap {'F2PY_EXPR_TUPLE_5': 'da .eq. 0.0d0'} >>> item.span (12, 12) >>> item.get_line() 'if (F2PY_EXPR_TUPLE_5) return' To read a Fortran code from a string, use `FortranStringReader` class:: >>> from fparser.common.sourceinfo import FortranFormat >>> from fparser.common.readfortran import FortranStringReader >>> code = ''' ... subroutine foo(a) ... integer a ... print*,"a=",a ... end ... ''' >>> reader = FortranStringReader(code) >>> reader.set_format(FortranFormat(False, True)) >>> reader.next() Line('subroutine foo(a)',(2, 2),'') >>> reader.next() Line('integer a',(3, 3),'') >>> reader.next() Line('print*,"a=",a',(4, 4),'') Exceptions ---------- .. autoapisummary:: fparser.common.readfortran.FortranReaderError fparser.common.readfortran.SyntaxErrorLine fparser.common.readfortran.SyntaxErrorMultiLine Classes ------- .. autoapisummary:: fparser.common.readfortran.Line fparser.common.readfortran.Comment fparser.common.readfortran.MultiLine fparser.common.readfortran.FortranFileReader fparser.common.readfortran.FortranStringReader Module Contents --------------- .. py:exception:: FortranReaderError Bases: :py:obj:`Exception` Thrown when there is an error reading the Fortran source file. .. py:class:: Line(line, linenospan, label, name, reader) Holds a Fortran source line. Attributes:: line : str code line span : 2-tuple starting and ending line numbers label : {int, None} Specify statement label name : {str, None} Specify construct name. reader : FortranReaderBase strline : {None, str} is_f2py_directive : bool the line contains f2py directive .. py:attribute:: line .. py:attribute:: span .. py:attribute:: label .. py:attribute:: name .. py:attribute:: reader .. py:attribute:: strline :value: None .. py:attribute:: is_f2py_directive .. py:attribute:: parse_cache .. py:method:: has_map() Returns true when a substitution map has been registered. .. py:method:: apply_map(line) Substitutes magic strings in a line with values specified in a map. .. py:method:: copy(line=None, apply_map=False) Creates a Line object from a string. If no line argument is specified a copy is made of this Line. If a substitution map is provided it is used while making the copy. .. py:method:: clone(line) This Line has its contents overwitten by the passed string. The incoming string has substitution applied. .. py:method:: __repr__() .. py:method:: __str__() .. py:method:: isempty(ignore_comments=False) .. py:method:: get_line(apply_map=False) .. py:method:: parse_line(cls, parent_cls) .. py:method:: parse_block(reader, cls, parent_cls) .. py:exception:: SyntaxErrorLine(line, linenospan, label, name, reader, message) Bases: :py:obj:`Line`, :py:obj:`FortranReaderError` Indicates a syntax error while processing a line. .. py:class:: Comment(comment, linenospan, reader, inline: bool = False) Holds a Fortran comment. :param str comment: String containing the text of a single or multi-line comment :param linenospan: A 2-tuple containing the start and end line numbers of the comment from the input source. :type linenospan: (int, int) :param reader: The reader object being used to read the input source. :type reader: :py:class:`fparser.common.readfortran.FortranReaderBase` :param inline: whether this was an inline comment. .. py:attribute:: comment .. py:attribute:: span .. py:attribute:: reader .. py:attribute:: line .. py:attribute:: inline :value: False .. py:method:: __repr__() .. py:method:: isempty(ignore_comments=False) Whether or not this comment is in fact empty (or we are ignoring it). Provided for compatibility with Line.isempty() :param bool ignore_comments: whether we ignore comments :return: True if we are ignoring comments, False otherwise :rtype: bool .. py:class:: MultiLine(prefix, block, suffix, linenospan, reader) Holds PYF file multiline. PYF file multiline is represented as follows:: prefix+'''+lines+'''+suffix. :param str prefix: the prefix of the line(s) :param block: list of lines :type block: List[:py:class:`fparser.common.readfortran.Line`] :param str suffix: the suffix of the block of lines :param linenospan: starting and ending line numbers :type linenospan: Tuple[int, int] :param reader: the current reader instance. :type reader: :py:class:`fparser.common.readfortran.FortranReaderBase` .. py:attribute:: prefix .. py:attribute:: block .. py:attribute:: suffix .. py:attribute:: span .. py:attribute:: reader .. py:method:: __repr__() .. py:method:: isempty(ignore_comments=False) Returns true if there is no significant text in this multi-line string. .. py:exception:: SyntaxErrorMultiLine(prefix, block, suffix, linenospan, reader, message) Bases: :py:obj:`MultiLine`, :py:obj:`FortranReaderError` Indicates a syntax error while processing Python multi-line strings. .. py:class:: FortranFileReader(file_candidate, include_dirs=None, source_only=None, ignore_comments=True, ignore_encoding=True, include_omp_conditional_lines=False, process_directives: bool = False) Bases: :py:obj:`FortranReaderBase` Constructs a FortranFileReader object from a file. :param file_candidate: A filename or file-like object. :param list include_dirs: Directories in which to look for inclusions. :param list source_only: Fortran source files to search for modules required by "use" statements. :param bool ignore_comments: whether or not to discard comments. If comments are not ignored, they will be added as special Comment node to the tree, and will therefore also be added to the output Fortran source code. :param Optional[bool] ignore_encoding: whether or not to ignore Python-style encoding information (e.g. "-*- fortran -*-") when attempting to determine the format of the file. Default is True. :param Optional[bool] include_omp_conditional_lines: whether or not the content of a line with an OMP sentinel is parsed or not. Default is False (in which case it is treated as a Comment). :param process_directives: whether or not to process directives as specialised Directive nodes. Default is False (in which case directives are left as comments). This option overrides the ignore_comments input. For example:: >>> from fparser.common.readfortran import FortranFileReader >>> import os >>> reader = FortranFileReader('myfile.f90') .. py:attribute:: _close_on_destruction :value: False .. py:method:: __del__() .. py:method:: close_source() Called when self.source.next() raises StopIteration. .. py:class:: FortranStringReader(string, include_dirs=None, source_only=None, ignore_comments=True, ignore_encoding=True, include_omp_conditional_lines=False, process_directives: bool = False) Bases: :py:obj:`FortranReaderBase` Reads Fortran source code as a string. :param str string: string to read :param list include_dirs: List of dirs to search for include files :param list source_only: Fortran source files to search for modules required by "use" statements. :param bool ignore_comments: whether or not to discard comments. If comments are not ignored, they will be added as special Comment node to the tree, and will therefore also be added to the output Fortran source code. :param Optional[bool] ignore_encoding: whether or not to ignore Python-style encoding information (e.g. "-*- fortran -*-") when attempting to determine the format of the source. Default is True. :param Optional[bool] include_omp_conditional_lines: whether or not the content of a line with an OMP sentinel is parsed or not. Default is False (in which case it is treated as a Comment). :param process_directives: whether or not to process directives as specialised Directive nodes. Default is False (in which case directives are left as comments). This option overrides the ignore_comments input. For example: >>> from fparser.common.readfortran import FortranStringReader >>> code = ''' subroutine foo(a) integer a print*,"a=",a end ''' >>> reader = FortranStringReader(code) .. py:attribute:: id :value: 'string-'