37 ''' This module provides the PSyIR Fortran front-end.'''
39 from typing
import Optional
40 from fparser.common.readfortran
import FortranStringReader, FortranFileReader
41 from fparser.common.sourceinfo
import FortranFormat
42 from fparser.two
import Fortran2003, pattern_tools
43 from fparser.two.parser
import ParserFactory
44 from fparser.two.symbol_table
import SYMBOL_TABLES
45 from fparser.two.utils
import NoMatchError
53 ''' PSyIR Fortran frontend. This frontend translates Fortran from a string
54 or a file into PSyIR using the fparser2 utilities.
62 self.
_parser_parser = ParserFactory().create(std=
"f2008")
69 Utility method that checks that the supplied name is a valid
72 :param name: the name to check.
74 :raises TypeError: if the name is not a string.
75 :raises ValueError: if this is not a valid name.
78 if not isinstance(name, str):
80 f
"A name should be a string, but found "
81 f
"'{type(name).__name__}'.")
82 if not pattern_tools.abs_name.match(name):
84 f
"Invalid Fortran name '{name}' found.")
87 ''' Generate the PSyIR tree representing the given Fortran source code.
89 :param source_code: text representation of the code to be parsed.
90 :param free_form: If parsing free-form code or not (default True).
92 :returns: PSyIR representing the provided Fortran source code.
93 :rtype: :py:class:`psyclone.psyir.nodes.Node`
97 string_reader = FortranStringReader(source_code)
99 string_reader.set_format(FortranFormat(free_form,
False))
100 parse_tree = self.
_parser_parser(string_reader)
101 psyir = self.
_processor_processor.generate_psyir(parse_tree)
105 symbol_table: Optional[SymbolTable] =
None):
106 '''Generate the PSyIR tree for the supplied Fortran statement. The
107 symbol table is expected to provide all symbols found in the
110 :param source_code: text of the expression to be parsed.
111 :param symbol_table: the SymbolTable in which to search for any
112 symbols that are encountered.
114 :returns: PSyIR representing the provided Fortran expression.
115 :rtype: :py:class:`psyclone.psyir.nodes.Node`
117 :raises TypeError: if no valid SymbolTable is supplied.
118 :raises ValueError: if the supplied source does not represent a
122 if symbol_table
is None:
123 symbol_table = SymbolTable()
124 elif not isinstance(symbol_table, SymbolTable):
125 raise TypeError(f
"Must be supplied with a valid SymbolTable but "
126 f
"got '{type(symbol_table).__name__}'")
129 parse_tree = Fortran2003.Expr(source_code)
130 except NoMatchError
as err:
132 f
"Supplied source does not represent a Fortran "
133 f
"expression: '{source_code}'")
from err
141 fake_parent = Schedule()
143 fake_parent._symbol_table = symbol_table
144 fake_parent.addchild(Assignment())
145 self.
_processor_processor.process_nodes(fake_parent[0], [parse_tree])
146 return fake_parent[0].children[0].detach()
149 symbol_table: Optional[SymbolTable] =
None):
150 '''Generate the PSyIR tree for the supplied Fortran statement. The
151 symbolt table is expected to provide all symbols found in the
154 :param source_code: text of the statement to be parsed.
155 :param symbol_table: the SymbolTable in which to search for any
156 symbols that are encountered.
158 :returns: PSyIR representing the provided Fortran statement.
159 :rtype: :py:class:`psyclone.psyir.nodes.Node`
161 :raises TypeError: if no valid SymbolTable is supplied.
162 :raises ValueError: if the supplied source does not represent a
166 if symbol_table
is None:
167 symbol_table = SymbolTable()
168 elif not isinstance(symbol_table, SymbolTable):
169 raise TypeError(f
"Must be supplied with a valid SymbolTable but "
170 f
"got '{type(symbol_table).__name__}'")
171 string_reader = FortranStringReader(source_code)
173 string_reader.set_format(FortranFormat(
True,
False))
175 exec_part = Fortran2003.Execution_Part(string_reader)
176 except NoMatchError
as err:
177 raise ValueError(f
"Supplied source does not represent a Fortran "
178 f
"statement: '{source_code}'")
from err
184 routine_symbol = symbol_table.lookup_with_tag(
"own_routine_symbol")
185 routine_name = routine_symbol.name
187 routine_name =
"dummy"
188 fake_parent = Routine.create(
189 routine_name, SymbolTable(), [])
191 fake_parent._symbol_table = symbol_table
195 self.
_processor_processor.process_nodes(fake_parent, exec_part.children)
196 return fake_parent[0].detach()
199 ''' Generate the PSyIR tree representing the given Fortran file.
201 :param file_path: path of the file to be read and parsed.
202 :type file_path: str or any Python Path format.
204 :param free_form: If parsing free-form code or not (default True).
205 :type free_form: bool
207 :returns: PSyIR representing the provided Fortran file.
208 :rtype: :py:class:`psyclone.psyir.nodes.Node`
211 SYMBOL_TABLES.clear()
220 reader = FortranFileReader(file_path,
221 include_dirs=Config.get().include_paths)
222 reader.set_format(FortranFormat(free_form,
False))
223 parse_tree = self.
_parser_parser(reader)
224 psyir = self.
_processor_processor.generate_psyir(parse_tree)
229 __all__ = [
'FortranReader']
def validate_name(str name)
def psyir_from_file(self, file_path, free_form=True)
def psyir_from_statement(self, str source_code, Optional[SymbolTable] symbol_table=None)
def psyir_from_expression(self, str source_code, Optional[SymbolTable] symbol_table=None)
def psyir_from_source(self, str source_code, bool free_form=True)