fparser Reference Guide  0.0.14
fparser.two.symbol_table.SymbolTables Class Reference

Public Member Functions

def __init__ (self)
 
def __str__ (self)
 
def enable_checks (self, value)
 
def clear (self)
 
def add (self, name)
 
def lookup (self, name)
 
def scoping_unit_classes (self)
 
def scoping_unit_classes (self, value)
 
def current_scope (self)
 
def enter_scope (self, name)
 
def exit_scope (self)
 
def remove (self, name)
 

Detailed Description

Class encapsulating functionality for the global symbol-tables object.
This is a container for all symbol tables constructed while parsing
code. All names are converted to lower case (since Fortran is not
case sensitive).

Definition at line 48 of file symbol_table.py.

Member Function Documentation

◆ add()

def fparser.two.symbol_table.SymbolTables.add (   self,
  name 
)
Add a new symbol table with the supplied name. The name will be
converted to lower case if necessary.

:param str name: the name for the new table.

:returns: the new symbol table.
:rtype: :py:class:`fparser.two.symbol_table.SymbolTable`

:raises SymbolTableError: if there is already an entry with the \
                  supplied name.

Definition at line 93 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._enable_checks, and fparser.two.symbol_table.SymbolTables._symbol_tables.

93  def add(self, name):
94  """
95  Add a new symbol table with the supplied name. The name will be
96  converted to lower case if necessary.
97 
98  :param str name: the name for the new table.
99 
100  :returns: the new symbol table.
101  :rtype: :py:class:`fparser.two.symbol_table.SymbolTable`
102 
103  :raises SymbolTableError: if there is already an entry with the \
104  supplied name.
105  """
106  lower_name = name.lower()
107  if lower_name in self._symbol_tables:
108  raise SymbolTableError(
109  f"The table of top-level (un-nested) symbol tables already "
110  f"contains an entry for '{lower_name}'"
111  )
112  table = SymbolTable(lower_name, checking_enabled=self._enable_checks)
113  self._symbol_tables[lower_name] = table
114  return table
115 
Here is the caller graph for this function:

◆ clear()

def fparser.two.symbol_table.SymbolTables.clear (   self)
Deletes any stored SymbolTables but retains the stored list of
classes that define scoping units.

Definition at line 84 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._current_scope, and fparser.two.symbol_table.SymbolTables._symbol_tables.

84  def clear(self):
85  """
86  Deletes any stored SymbolTables but retains the stored list of
87  classes that define scoping units.
88 
89  """
90  self._symbol_tables = {}
91  self._current_scope = None
92 

◆ current_scope()

def fparser.two.symbol_table.SymbolTables.current_scope (   self)
:returns: the symbol table for the current scoping unit or None.
:rtype: :py:class:`fparser.two.symbol_table.SymbolTable` or NoneType

Definition at line 160 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._current_scope.

160  def current_scope(self):
161  """
162  :returns: the symbol table for the current scoping unit or None.
163  :rtype: :py:class:`fparser.two.symbol_table.SymbolTable` or NoneType
164  """
165  return self._current_scope
166 

◆ enable_checks()

def fparser.two.symbol_table.SymbolTables.enable_checks (   self,
  value 
)
Sets whether or not to enable consistency checks in every symbol
table that is created during a parse.

:param bool value: whether or not checks are enabled.

Definition at line 74 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._enable_checks.

74  def enable_checks(self, value):
75  """
76  Sets whether or not to enable consistency checks in every symbol
77  table that is created during a parse.
78 
79  :param bool value: whether or not checks are enabled.
80 
81  """
82  self._enable_checks = value
83 

◆ enter_scope()

def fparser.two.symbol_table.SymbolTables.enter_scope (   self,
  name 
)
Called when the parser enters a new scoping region (i.e. when it
encounters one of the classes listed in `_scoping_unit_classes`).
Sets the 'current scope' to be the symbol table with the supplied name.
If we are not currently within a tree of scoping regions then a
new entry is created in the internal dict of symbol tables. If there
is an existing tree then a new table is created and added to the
bottom.

:param str name: name of the scoping region.

Definition at line 167 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._current_scope, fparser.two.symbol_table.SymbolTables._enable_checks, fparser.two.symbol_table.SymbolTables.add(), and fparser.two.symbol_table.SymbolTables.lookup().

167  def enter_scope(self, name):
168  """
169  Called when the parser enters a new scoping region (i.e. when it
170  encounters one of the classes listed in `_scoping_unit_classes`).
171  Sets the 'current scope' to be the symbol table with the supplied name.
172  If we are not currently within a tree of scoping regions then a
173  new entry is created in the internal dict of symbol tables. If there
174  is an existing tree then a new table is created and added to the
175  bottom.
176 
177  :param str name: name of the scoping region.
178 
179  """
180  lname = name.lower()
181 
182  if not self._current_scope:
183  # We're not already inside a nested scope.
184  try:
185  table = self.lookup(lname)
186  except KeyError:
187  # Create a new, top-level symbol table with the supplied name.
188  table = self.add(lname)
189  else:
190  # We are already inside a scoping region so create a new table
191  # and setup its parent/child connections.
192  table = SymbolTable(
193  lname, parent=self._current_scope, checking_enabled=self._enable_checks
194  )
195  self._current_scope.add_child(table)
196 
197  # Finally, make this new table the current scope
198  self._current_scope = table
199 
Here is the call graph for this function:

◆ exit_scope()

def fparser.two.symbol_table.SymbolTables.exit_scope (   self)
Marks the end of the processing of the current scoping unit. Since
we are exiting the current scoping region, the new 'current scoping
region' will be its parent.

:raises SymbolTableError: if there is no current scope from which to \
                  exit.

Definition at line 200 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._current_scope.

200  def exit_scope(self):
201  """
202  Marks the end of the processing of the current scoping unit. Since
203  we are exiting the current scoping region, the new 'current scoping
204  region' will be its parent.
205 
206  :raises SymbolTableError: if there is no current scope from which to \
207  exit.
208  """
209  if not self._current_scope:
210  raise SymbolTableError("exit_scope() called but no current scope exists.")
211  self._current_scope = self._current_scope.parent
212 

◆ lookup()

def fparser.two.symbol_table.SymbolTables.lookup (   self,
  name 
)
Find the named symbol table and return it.

:param str name: the name of the required symbol table (not case \
         sensitive).

:returns: the named symbol table.
:rtype: :py:class:`fparser.two.symbol_table.SymbolTable`

Definition at line 116 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._symbol_tables.

116  def lookup(self, name):
117  """
118  Find the named symbol table and return it.
119 
120  :param str name: the name of the required symbol table (not case \
121  sensitive).
122 
123  :returns: the named symbol table.
124  :rtype: :py:class:`fparser.two.symbol_table.SymbolTable`
125 
126  """
127  return self._symbol_tables[name.lower()]
128 
Here is the caller graph for this function:

◆ remove()

def fparser.two.symbol_table.SymbolTables.remove (   self,
  name 
)
Removes the named symbol table and any descendants it may have.
When searching for the named table, the current scope takes priority
followed by the list of top-level symbol tables.

:param str name: the name of the symbol table to remove (not case \
         sensitive).
:raises SymbolTableError: if the named symbol table is not in the \
    current scope or in the list of top-level symbol tables.

Definition at line 213 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._current_scope, and fparser.two.symbol_table.SymbolTables._symbol_tables.

213  def remove(self, name):
214  """
215  Removes the named symbol table and any descendants it may have.
216  When searching for the named table, the current scope takes priority
217  followed by the list of top-level symbol tables.
218 
219  :param str name: the name of the symbol table to remove (not case \
220  sensitive).
221  :raises SymbolTableError: if the named symbol table is not in the \
222  current scope or in the list of top-level symbol tables.
223 
224  """
225  lname = name.lower()
226  if self._current_scope:
227  try:
228  self._current_scope.del_child(lname)
229  # We succeeded in removing it from the current scope so we
230  # are done.
231  return
232  except KeyError:
233  pass
234 
235  if lname not in self._symbol_tables:
236  msg = f"Failed to find a table named '{name}' in "
237  if self._current_scope:
238  msg += (
239  f"either the current scope (which contains "
240  f"{[child.name for child in self._current_scope.children]}) or "
241  )
242  msg += (
243  f"the list of top-level symbol tables "
244  f"({list(self._symbol_tables.keys())})."
245  )
246  raise SymbolTableError(msg)
247 
248  # Check that we're not currently somewhere inside the scope of the
249  # named table.
250  top_table = self._symbol_tables[lname]
251  if self._current_scope:
252  if self._current_scope.root is top_table:
253  raise SymbolTableError(
254  f"Cannot remove top-level symbol table '{name}' because the "
255  f"current scope '{self._current_scope.name}' has it as an ancestor."
256  )
257 
258  del self._symbol_tables[lname]
259 
260 

◆ scoping_unit_classes() [1/2]

def fparser.two.symbol_table.SymbolTables.scoping_unit_classes (   self)
:returns: the fparser2 classes that are taken to mark the start of \
  a new scoping region.
:rtype: list of types

Definition at line 130 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._scoping_unit_classes.

130  def scoping_unit_classes(self):
131  """
132  :returns: the fparser2 classes that are taken to mark the start of \
133  a new scoping region.
134  :rtype: list of types
135 
136  """
137  return self._scoping_unit_classes
138 
Here is the caller graph for this function:

◆ scoping_unit_classes() [2/2]

def fparser.two.symbol_table.SymbolTables.scoping_unit_classes (   self,
  value 
)
Set the list of fparser2 classes that are taken to mark the start of \
a new scoping region.

:param value: the list of fparser2 classes.
:type value: list of types

:raises TypeError: if the supplied value is not a list of types.

Definition at line 140 of file symbol_table.py.

References fparser.two.symbol_table.SymbolTables._scoping_unit_classes, and fparser.two.symbol_table.SymbolTables.scoping_unit_classes().

140  def scoping_unit_classes(self, value):
141  """
142  Set the list of fparser2 classes that are taken to mark the start of \
143  a new scoping region.
144 
145  :param value: the list of fparser2 classes.
146  :type value: list of types
147 
148  :raises TypeError: if the supplied value is not a list of types.
149 
150  """
151  if not isinstance(value, list):
152  raise TypeError(
153  f"Supplied value must be a list but got '{type(value).__name__}'"
154  )
155  if not all(isinstance(item, type) for item in value):
156  raise TypeError(f"Supplied list must contain only classes but got: {value}")
157  self._scoping_unit_classes = value
158 
Here is the call graph for this function:

The documentation for this class was generated from the following file: