Source code for cfpq_data.grammars.generators.nested_parentheses_grammar
"""Returns a Nested Parentheses grammar that generates a language of the strings with nested parentheses of different
types. """
import logging
from typing import List, Tuple
from pyformlang.cfg import CFG, Production, Variable, Terminal
__all__ = ["nested_parentheses_grammar"]
[docs]
def nested_parentheses_grammar(
types: List[Tuple[str, str]],
*,
eps: bool = True,
start_symbol: Variable = Variable("S"),
) -> CFG:
"""Returns a Nested Parentheses grammar that generates a language of the strings with nested parentheses of given types.
Parameters
----------
types : List[Tuple[str, str]]
List of pairs $(op_i, cp_i)$ with opening and closing parentheses for each type.
eps : bool
Whether the empty string belongs to the language generated by the grammar.
start_symbol : Variable
Start symbol of the grammar.
Examples
--------
>>> from cfpq_data import *
>>> cfg = nested_parentheses_grammar([("a", "b"), ("c", "d")])
>>> cfg_to_text(cfg)
'S -> \\nS -> a S b\\nS -> c S d'
Returns
-------
cfg : CFG
A Nested Parentheses context-free grammar.
"""
variables = {start_symbol}
productions = set()
terminals = set()
if eps:
productions.add(Production(start_symbol, []))
else:
for op, cp in types:
productions.add(Production(start_symbol, [Terminal(op), Terminal(cp)]))
for op, cp in types:
terminals.update([Terminal(op), Terminal(cp)])
productions.add(
Production(start_symbol, [Terminal(op), start_symbol, Terminal(cp)])
)
cfg = CFG(
variables=variables,
terminals=terminals,
productions=productions,
start_symbol=start_symbol,
)
logging.info(f"Create a Nested Parentheses {cfg=} with {types=}, {eps=}")
return cfg