def parse(tokens, rules, node_fn, postprocess_cell_fn, verbose=False):
  """Run bottom up parser.

  Args:
    tokens: List of strings for input.
    rules: List of QCFGRule instances.
    node_fn: Function with input arguments (span_begin, span_end, rule,
      children) and returns a "node".
    postprocess_cell_fn: Function from a list of "nodes" to "nodes".
    verbose: Print debug output if True.

  Returns:
    A List of "node" objects for completed parses.
  """
  if verbose:
    print("tokens: %s" % (tokens,))
    print("rules:")
    for rule in rules:
      print(str(rule))

  # Convert tokens to integer IDs.
  tokens_to_input_ids = {}
  input_ids_to_tokens = {}
  for idx, token in enumerate(set(tokens)):
    input_ids_to_tokens[idx] = token
    tokens_to_input_ids[token] = idx
  input_ids = [tokens_to_input_ids[token] for token in tokens]

  # Our QCFG grammars always use a single NT symbol.
  nt_idx = 0

  # Convert to ParserRule format.
  idx_to_rule = {}
  parser_rules = []
  rule_idx = 0
  for rule in rules:
    rhs = _convert_rhs(rule, nt_idx, tokens_to_input_ids)
    if rhs is None:
      continue
    parser_rule = cfg_rule.CFGRule(idx=rule_idx, lhs=nt_idx, rhs=rhs)
    parser_rules.append(parser_rule)
    idx_to_rule[rule_idx] = rule
    rule_idx += 1

  # Wrap node_fn to pass original Rule instead of CFGRule.
  def populate_fn(span_begin, span_end, parser_rule, children):
    rule = idx_to_rule[parser_rule.idx]
    return node_fn(span_begin, span_end, rule, children)

  nonterminals = {nt_idx}
  start_idx = nt_idx

  if verbose:
    print("parser_rules: %s" % parser_rules)

  parses = cfg_parser.parse(
      input_ids,
      parser_rules,
      nonterminals,
      start_idx,
      populate_fn,
      postprocess_cell_fn,
      verbose=verbose)

  return parses
Run bottom up parser.

  Args:
    tokens: List of strings for input.
    rules: List of QCFGRule instances.
    node_fn: Function with input arguments (span_begin, span_end, rule,
      children) and returns a "node".
    postprocess_cell_fn: Function from a list of "nodes" to "nodes".
    verbose: Print debug output if True.

  Returns:
    A List of "node" objects for completed parses.
  
language/compgen/nqg/model/qcfg/qcfg_parser.py