from .. import data_structures as _data_structures
[docs]def create_empty_terminal():
"""Create a terminal that represents the empty string ε."""
return _data_structures.TerminalSymbol("")
[docs]def is_empty_terminal(symbol):
"""Check if a symbol is a terminal and represents the empty string."""
return symbol.text == "" and isinstance(symbol, _data_structures.TerminalSymbol)
[docs]def create_new_nonterminal(grammar, prefix):
"""Create a new nonterminal that is not yet part of the grammar.
To ensure the nonterminal can be easily recognized as being
autogenerated and to ensure that it is a new symbol,
a combination of a prefix and an increment is used.
Caution: This function assumes that the grammar's nonterminal set
is up to date with the production rules.
"""
template = str(prefix) + "{}"
for i in range(1_000_000_000_000_000):
text = template.format(i)
symbol = _data_structures.NonterminalSymbol(text)
if symbol not in grammar.nonterminal_symbols:
grammar.nonterminal_symbols.add(symbol)
break
return symbol
[docs]def update_grammar_parts(grammar):
"""Repair the grammar after rule modifications so all parts fit.
Process:
- The grammar is reset.
- The old production rules are inserted again.
- The nonterminals and terminals are deduced from the content
of the production rules.
- The start symbol is assumed to be the first nonterminal.
"""
# Remember the original rules and reset the grammar
remembered_rules = grammar.production_rules
grammar._set_empty_state()
# Restore a consistent state
# - Production rules
grammar.production_rules = remembered_rules
# - Sets of nonterminals and terminals
for lhs in grammar.production_rules.keys():
grammar.nonterminal_symbols.add(
lhs
) # order of nonterminals is that of appearance in lhs
for rhs_multiple in grammar.production_rules.values():
for rhs in rhs_multiple:
for sym in rhs:
if isinstance(sym, _data_structures.NonterminalSymbol):
grammar.nonterminal_symbols.add(sym)
else:
grammar.terminal_symbols.add(sym)
# - Start symbol
grammar.start_symbol = grammar.nonterminal_symbols[0]
return grammar