public Tree produceTree(String state) { Counter<String> terminal = terminals.get(state); if (terminal != null) { // found a terminal production. make a leaf with a randomly // chosen expansion and make a preterminal with that one leaf // as a child. String label = Counters.sample(terminal, random); Tree child = tf.newLeaf(label); List<Tree> children = Collections.singletonList(child); Tree root = tf.newTreeNode(state, children); return root; } Counter<List<String>> nonTerminal = nonTerminals.get(state); if (nonTerminal != null) { // found a nonterminal production. produce a list of // recursive expansions, then attach them all to a node with // the expected state List<String> labels = Counters.sample(nonTerminal, random); List<Tree> children = new ArrayList<>(); for (String childLabel : labels) { children.add(produceTree(childLabel)); } Tree root = tf.newTreeNode(state, children); return root; } throw new RuntimeException("Unknown state " + state); }