Esempio n. 1
0
def cfg_to_text(cfg: CFG) -> str:
    """Turns a context-free grammar [1]_
    into its text representation.

    Parameters
    ----------
    cfg : CFG
        Context-free grammar.

    Examples
    --------
    >>> import cfpq_data
    >>> cfg = cfpq_data.cfg_from_text("S -> a S b S")
    >>> cfpq_data.cfg_to_text(cfg)
    'S -> a S b S\\n'

    Returns
    -------
    text : str
        Context-free grammar
        text representation.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Context-free_grammar#Formal_definitions
    """
    return cfg.to_text()
Esempio n. 2
0
def change_terminals_in_cfg(cfg: CFG, spec: Dict[str, str]) -> CFG:
    """Change terminals of
    a context-free grammar [1]_.

    Parameters
    ----------
    cfg : CFG
        Context-free grammar.

    spec: Dict
        Terminals mapping.

    Examples
    --------
    >>> import cfpq_data
    >>> cfg = cfpq_data.cfg_from_text("S -> a S b S")
    >>> new_cfg = cfpq_data.change_terminals_in_cfg(cfg, {"a": "b", "b": "c"})
    >>> new_cfg.to_text()
    'S -> b S c S\\n'

    Returns
    -------
    cfg : CFG
        Context-free grammar with changed terminals.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Context-free_grammar#Formal_definitions
    """
    regex = re.compile("|".join(map(re.escape, spec.keys())))
    text = regex.sub(lambda match: spec[match.group(0)], cfg.to_text())
    return cfg_from_text(text)
Esempio n. 3
0
    def from_cfg(cls, cfg: CFG):
        """
        Build RSA from a given cfpq_data context-free grammar
        @param cfg: CFG on which RSA is built
        @return: initialized class
        """
        grammar = cfg.to_text()

        productions = dict()
        for line in grammar.split("\n")[:-1]:
            part_line = line.split(" -> ")
            right = part_line[1]
            if right == "":
                right = "epsilon"
            if part_line[0] in productions:
                productions[part_line[0]] += " | " + right
            else:
                productions[part_line[0]] = right

        grammar_new = ""
        for nonterminal in productions:
            grammar_new += nonterminal + " -> " + productions[nonterminal] + "\n"

        grammar_new = grammar_new[:-1]
        return RecursiveAutomaton.from_rsm(rsm_from_text(grammar_new))
Esempio n. 4
0
def cfg_from_cnf(cnf: CFG) -> CFG:
    """Create a context-free grammar [2]_
    from given context-free grammar
    in Chomsky normal form [1]_.

    Parameters
    ----------
    cnf : CFG
        Context free grammar
        in Chomsky normal form.

    Examples
    --------
    >>> import cfpq_data
    >>> cnf = cfpq_data.cnf_from_text("S -> a S b S | epsilon")
    >>> cfg = cfpq_data.cfg_from_cnf(cnf)
    >>> [cfg.contains(word) for word in ["", "ab", "aabb"]]
    [True, True, True]

    Returns
    -------
    cfg : CFG
        Context-free grammar.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Chomsky_normal_form
    .. [2] https://en.wikipedia.org/wiki/Context-free_grammar#Formal_definitions
    """
    return CFG.from_text(cnf.to_text(), cnf.start_symbol)
Esempio n. 5
0
def rsm_from_cnf(cnf: CFG) -> RSM:
    """Create a Recursive State Machine [2]_
    from context-free grammar
    in Chomsky normal form [1]_.

    Parameters
    ----------
    cnf : CFG
        Context-free grammar
        in Chomsky normal form.

    Examples
    --------
    >>> import cfpq_data
    >>> cnf = cfpq_data.cnf_from_text("S -> a S b S | epsilon")
    >>> rsm = cfpq_data.rsm_from_cnf(cnf)
    >>> [rsm.contains(word) for word in ["", "ab", "aabb"]]
    [True, True, True]

    Returns
    -------
    rsm : RSM
        Recursive State Machine.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Chomsky_normal_form
    .. [2] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive State Machines. In: Berry G.,
       Comon H., Finkel A. (eds) Computer Aided Verification. CAV 2001.
       Lecture Notes in Computer Science, vol 2102.
       Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-44585-4_18
    """
    return rsm_from_text(cnf.to_text(), cnf.start_symbol)
Esempio n. 6
0
def cnf_to_text(cnf: CFG) -> str:
    """Turns a context-free grammar
    in Chomsky normal form [1]_
    into its text representation.

    Parameters
    ----------
    cnf : CFG
        Context-free grammar
        in Chomsky normal form.

    Examples
    --------
    >>> import cfpq_data
    >>> cnf = cfpq_data.cnf_from_text("S -> a")
    >>> cfpq_data.cnf_to_text(cnf)
    'S -> a\\n'

    Returns
    -------
    text : str
        Context-free grammar
        in Chomsky normal form
        text representation.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Chomsky_normal_form
    """
    return cnf.to_text()
Esempio n. 7
0
    def from_cfg(cls, cfg: CFG):
        """ Create a recursive automaton from context-free grammar

        Parameters
        -----------
        cfg : :class:`~pyformlang.cfg.CFG`
            The context-free grammar

        Returns
        -----------
        rsa : :class:`~pyformlang.rsa.RecursiveAutomaton`
            The new recursive automaton built from context-free grammar
        """

        initial_label = to_symbol(cfg.start_symbol)
        grammar_in_true_format = remove_repetition_of_nonterminals_from_productions(
            cfg.to_text())

        boxes = set()
        labels = set()
        notation_for_epsilon = Epsilon().to_text()
        for production in grammar_in_true_format.splitlines():
            head, body = production.split(" -> ")
            labels.add(to_symbol(head))

            if body == "":
                body = notation_for_epsilon

            boxes.add(
                Box(Regex(body).to_epsilon_nfa().minimize(), to_symbol(head)))

        return RecursiveAutomaton(labels, initial_label, boxes)
Esempio n. 8
0
def change_terminals_in_cnf(cnf: CFG, spec: Dict[str, str]) -> CFG:
    """Change terminals of
    a context-free grammar [1]_
    in Chomsky normal form.

    Parameters
    ----------
    cnf : CFG
        Context-free grammar
        in Chomsky normal form.

    spec: Dict
        Terminals mapping.

    Examples
    --------
    >>> import cfpq_data
    >>> cnf = cfpq_data.cnf_from_text("S -> a S b S | epsilon")
    >>> new_cnf = cfpq_data.change_terminals_in_cnf(cnf, {"a": "b", "b": "c"})
    >>> [new_cnf.contains(word) for word in ["", "bc", "bbcc"]]
    [True, True, True]

    Returns
    -------
    cnf : CFG
        Context-free grammar
        in Chomsky normal form
        with changed terminals.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Chomsky_normal_form
    """
    regex = re.compile("|".join(map(re.escape, spec.keys())))
    text = regex.sub(lambda match: spec[match.group(0)], cnf.to_text())
    return cnf_from_text(text)