global defs record nonterm(name) procedure main() local line defs := table() while line := read() do (define | generate)(line) end procedure define(line) return line ? defs[(="<",tab(find(">::=")))] := (move(4),alts(tab(0))) end procedure alts(defn) local alist alist := [] defn ? while put(alist,syms(tab(many(~'|')))) do move(1) return alist end procedure syms(alt) local slist slist := [] alt ? while put(slist,tab(many(~'<')) | nonterm(2(="<",tab(upto('>')),move(1)))) return slist end procedure generate(line) local goal, count line ? { ="<" & goal := tab(upto('>')) & move(1) & count := tab(0) } every write(gener(goal)) \ count return end procedure gener(goal) local pending, genstr, symbol repeat { pending := [nonterm(goal)] genstr := "" while symbol := get(pending) do if type(symbol) == "string" then genstr ||:= symbol else pending := ?defs[symbol.name] ||| pending suspend genstr } end