Source code for alogos._grammar.normalization._shared

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