code: def visit_rules(self, node, rules_list):
          
          _, rules = rules_list
  
          # Map each rule's name to its Expression. Later rules of the same name
          # override earlier ones. This lets us define rules multiple times and
          # have the last declaration win, so you can extend grammars by
          # concatenation.
          rule_map = OrderedDict((expr.name, expr) for expr in rules)
  
          # And custom rules override string-based rules. This is the least
          # surprising choice when you compare the dict constructor:
          # dict({'x': 5}, x=6).
          rule_map.update(self.custom_rules)
  
          # Resolve references. This tolerates forward references.
          done = set()
          rule_map = OrderedDict((expr.name, self._resolve_refs(rule_map, expr, done))
                                 for expr in itervalues(rule_map))
  
          # isinstance() is a temporary hack around the fact that * rules don't
          # always get transformed into lists by NodeVisitor. We should fix that;
          # it's surprising and requires writing lame branches like this.
          return rule_map, (rule_map[rules[0].name]
                            if isinstance(rules, list) and rules else None)
docs: Collate all the rules into a map. Return (map, default rule).
  
          The default rule is the first one. Or, if you have more than one rule
          of that name, it's the last-occurring rule of that name. (This lets you
          override the default rule when you extend a grammar.) If there are no
          string-based rules, the default rule is None, because the custom rules,
          due to being kwarg-based, are unordered.