import ply.lex as lex # pip install ply
import ply.yacc as yacc
from functools import reduce
tokens = ('WORD',); t_WORD = r'\w+'; literals = (':', ';')
t_ignore = ' \t\r\n'
def t_error(t): raise SyntaxError()
d = {}
def p_1(p): "rules : rule"
def p_2(p): "rules : rule rules"
def p_4(p):
"rule : WORD ':' words ';'"
k = p[1]; v = d.get(k, []); v.append([p[3]])
d[k] = v
def p_5(p): "words : WORD"; p[0] = [p[1]]
def p_6(p): "words : WORD words"; p[0] = [p[1]] + p[2]
lexer = lex.lex()
istr = """
language : sentence ;
language : sentence language;
sentence : subject predicate object ;
sentence : subject predicate object adverbial ;
subject : Tom ;
subject : Jerry ;
predicate : holds ;
object : Tom ;
object : Jerry ;
adverbial : tightly ;
adverbial : loosely ;
"""
try: yacc.yacc().parse(istr)
except SyntaxError: quit()
def gen(s):
if len(s) > 4: return
expanded = False
for i in range(len(s)):
w = s[i]
for r in d.get(w, []):
expanded = True
gen(s[:i] + r[0] + s[i + 1:])
if not expanded: print(reduce(lambda a,b:a+' '+b, s, '')[1:] + '.')
gen(['language'])
# LISP