def _get_cfg_nts(nonterminals_to_ids, rhs_nt_rules, parse_node, num_nts):
  """Return tuple of NTs corresponding to parse."""
  ids_to_nonterminals = {v: k for k, v in nonterminals_to_ids.items()}
  lhs_nt = ids_to_nonterminals[parse_node.rule.lhs]
  node_stack = [parse_node]

  rhs_nts = [None] * num_nts
  while node_stack:
    node = node_stack.pop()
    if node.rule.idx in rhs_nt_rules:
      (nt_idx, target_nt) = rhs_nt_rules[node.rule.idx]
      # QCFG NT indexes are 1-indexed.
      rhs_nts[nt_idx - 1] = target_nt
    for child in node.children:
      node_stack.append(child)
  for nt in rhs_nts:
    if not nt:
      raise ValueError("Bad rhs_nts: %s" % rhs_nts)
  return tuple([lhs_nt] + rhs_nts)
Return tuple of NTs corresponding to parse.
language/compgen/csl/augment/joint_sampler.py