Source code for nltk.parse.generate2

# Natural Language Toolkit: Generating from a CFG
#
# Copyright (C) 2001-2013 NLTK Project
# Author: Steven Bird <stevenbird1@gmail.com>
# URL: <http://www.nltk.org/>
# For license information, see LICENSE.TXT
#
from __future__ import print_function

from functools import reduce
from nltk.compat import xrange
from nltk.grammar import Nonterminal, parse_cfg

[docs]def all_combsi(lol): lens = [len(x) for x in lol] num_combs = reduce(lambda x, y: x*y, lens, 1) for i in xrange(num_combs): tmp = [0]*len(lol) for j in xrange(len(tmp)): tmp[j] = lol[j][i % lens[j]] i = i / lens[j] yield tmp
[docs]def expand_nonterm(symbol, grammar): if isinstance(symbol, Nonterminal): return list(map(lambda prod: list(prod.rhs()), grammar.productions(lhs=symbol))) else: return symbol
[docs]def tree_traverse(root, get_children, isleaf, maxdepth): if isleaf(root): yield root elif maxdepth > 0: for child in get_children(root): for x in tree_traverse(child, get_children, isleaf, maxdepth - 1): yield x
[docs]def flatten(lst): val = [] for x in lst: if isinstance(x, list): val = val + x else: val.append(x) return val
[docs]def generate(grammar, start=None, depth=10): def is_terminal(lofs): return all(not isinstance(x, Nonterminal) for x in lofs) def get_children(l_of_symbols): x = [expand_nonterm(x, grammar) for x in l_of_symbols] make_list = lambda x: x if isinstance(x, list) else [x] x = list(map(make_list, x)) for comb in all_combsi(x): yield flatten(comb) if not start: start = grammar.start() return [x for x in tree_traverse([start], get_children, is_terminal, depth)]
def _generate_demo(): g = parse_cfg(""" S -> NP VP NP -> Det N VP -> V NP Det -> 'the' Det -> 'a' N -> 'man' | 'park' | 'dog' | 'telescope' V -> 'saw' | 'walked' P -> 'in' | 'with' """) for s in generate(g): print(' '.join(s)) if __name__ == "__main__": _generate_demo()