def __init__(self, vocabulary, max_recursion=1, type_grammar="normal"):
    """Defines a grammar of NT -> NT rules and NT -> T rules."""
    if type_grammar not in self.RULES:
      raise ValueError(f"Specified unsupported type grammar {type_grammar}")
    self.type_grammar = type_grammar
    if (type_grammar == "simple_intrans" and
        not vocabulary.get_intransitive_verbs()):
      raise ValueError("Please specify intransitive verbs.")
    elif (type_grammar == "simple_trans" and
          not vocabulary.get_transitive_verbs()):
      raise ValueError("Please specify transitive verbs.")
    self.rule_list = self.RULES[type_grammar] + self.lexical_rules(
        vocabulary.get_intransitive_verbs(), vocabulary.get_transitive_verbs(),
        vocabulary.get_adverbs(), vocabulary.get_nouns(),
        vocabulary.get_color_adjectives(), vocabulary.get_size_adjectives(),
        vocabulary.get_location_preps())
    nonterminals = {rule.lhs for rule in self.rule_list}
    self.rules = {nonterminal: [] for nonterminal in nonterminals}
    self.nonterminals = {nt.name: nt for nt in nonterminals}
    self.terminals = {}

    self.vocabulary = vocabulary
    self.rule_str_to_rules = {}
    for rule in self.rule_list:
      self.rules[rule.lhs].append(rule)
      self.rule_str_to_rules[str(rule)] = rule
    self.expandables = set(
        rule.lhs
        for rule in self.rule_list
        if not isinstance(rule, LexicalRule))
    self.categories = {
        "manner": set(vocabulary.get_adverbs()),
        "shape": set(vocabulary.get_nouns()),
        "color": set(vocabulary.get_color_adjectives()),
        "size": set(vocabulary.get_size_adjectives()),
        "location": set(vocabulary.get_location_preps()),
    }
    self.word_to_category = {}
    for category, words in self.categories.items():
      for word in words:
        self.word_to_category[word] = category

    self.max_recursion = max_recursion
    self.all_templates = []
    self.all_derivations = {}
    self.command_statistics = self.empty_command_statistics()
Defines a grammar of NT -> NT rules and NT -> T rules.
language/gscan/data/grammar.py