66 """This file provides utilities to create a Fortran parser suitable 67 for a particular standard.""" 75 def get_module_classes(input_module):
76 """Return all classes local to a module. 78 :param module input_module: the module containing the classes. 79 :return: a `list` of tuples each containing a class name and a \ 83 module_cls_members = []
84 module_name = input_module.__name__
87 all_cls_members = inspect.getmembers(sys.modules[module_name], inspect.isclass)
89 for cls_member
in all_cls_members:
90 if cls_member[1].__module__ == module_name:
91 module_cls_members.append(cls_member)
92 return module_cls_members
96 """Creates a parser suitable for the specified Fortran standard.""" 99 """Creates a class hierarchy suitable for the specified Fortran 100 standard. Also sets-up the list of classes that define scoping 101 regions in the global SymbolTables object and clears any existing 102 symbol table information. 104 :param str std: the Fortran standard. Choices are 'f2003' or \ 105 'f2008'. 'f2003' is the default. 106 :return: a Program class (not object) for use with the Fortran reader 107 :rtype: :py:class:`fparser.two.Fortran2003.Program` 109 :raises ValueError: if the supplied value for the std parameter \ 114 >>> from fparser.two.parser import ParserFactory 115 >>> f2003_parser = ParserFactory().create() 116 >>> f2003_parser = ParserFactory().create(std='f2003') 117 >>> f2008_parser = ParserFactory().create(std='f2008') 118 >>> # Assuming that a reader has already been created ... 119 >>> ast = f2008_parser(reader) 124 SYMBOL_TABLES.clear()
131 f2003_cls_members = get_module_classes(Fortran2003)
139 self.
_setup(f2003_cls_members)
143 SYMBOL_TABLES.scoping_unit_classes = [
161 f2008_cls_members = get_module_classes(Fortran2008)
164 f2008_class_names = [i[0]
for i
in f2008_cls_members]
165 for local_cls
in f2003_cls_members:
166 if local_cls[0]
not in f2008_class_names:
167 f2008_cls_members.append(local_cls)
170 self.
_setup(f2008_cls_members)
174 SYMBOL_TABLES.scoping_unit_classes = [
187 raise ValueError(f
"'{std}' is an invalid standard")
189 def _setup(self, input_classes):
190 """Perform some Python magic to create the connections between classes 191 and populate the baseclass with this information. This has 192 been lifted from the original implementation and no attempt 193 has been made to tidy up the code, other than making it 194 conformant to the coding rules. 196 :param list input_classes: a list of tuples each containing a \ 197 class name and a class. 207 class_type = type(fparser.two.Fortran2003.Base)
212 fparser.two.Fortran2003.Base.subclasses = {}
214 for clsinfo
in input_classes:
215 clsname =
"{0}.{1}".format(clsinfo[1].__module__, clsinfo[0])
219 isinstance(cls, class_type)
220 and issubclass(cls, fparser.two.Fortran2003.Base)
221 and not cls.__name__.endswith(
"Base")
223 base_classes[cls.__name__] = cls
224 if len(__autodoc__) < 10:
225 __autodoc__.append(cls.__name__)
233 def _rpl_list(clsname):
234 if clsname
not in base_classes:
235 error_string =
"Not implemented: {0}".format(clsname)
236 logging.getLogger(__name__).debug(error_string)
239 cls = base_classes[clsname]
240 if hasattr(cls,
"match"):
243 for names
in getattr(cls,
"subclass_names", []):
244 list1 = _rpl_list(names)
246 if names1
not in bits:
250 for cls
in list(base_classes.values()):
251 if not hasattr(cls,
"subclass_names"):
253 opt_subclass_names = []
254 for names
in cls.subclass_names:
255 for names1
in _rpl_list(names):
256 if names1
not in opt_subclass_names:
257 opt_subclass_names.append(names1)
258 if not opt_subclass_names == cls.subclass_names:
259 cls.subclass_names[:] = opt_subclass_names
262 for clsname, cls
in list(base_classes.items()):
263 subclass_names = getattr(cls,
"subclass_names",
None)
264 if subclass_names
is None:
265 message =
"%s class is missing subclass_names list" % (clsname)
266 logging.getLogger(__name__).debug(message)
269 bits = fparser.two.Fortran2003.Base.subclasses[clsname]
271 fparser.two.Fortran2003.Base.subclasses[clsname] = bits = []
272 for name
in subclass_names:
273 if name
in base_classes:
274 bits.append(base_classes[name])
276 message =
"{0} not implemented needed by {1}".format(name, clsname)
277 logging.getLogger(__name__).debug(message)
280 for cls
in list(base_classes.values()):
284 subclass_names = getattr(cls,
"subclass_names", [])
285 use_names = getattr(cls,
"use_names", [])
299 for name
in use_names + subclass_names:
300 if name
not in base_classes:
301 message =
"%s not defined used " "by %s" % (name, cls.__name__)
302 logging.getLogger(__name__).debug(message)
def _setup(self, input_classes)
def create(self, std=None)