docs: def check_sets(self):
          '''
          Check grammar
          '''
          lhs_set         = set()
          rhs_set         = set()
          rhs_rules_set   = {}
          token_set       = set()
          right_recursive = set()
          dup_rhs = {}
          for lhs in self.rules:
              rules_for_lhs = self.rules[lhs]
              lhs_set.add(lhs)
              for rule in rules_for_lhs:
                  rhs = rule[1]
                  if len(rhs) > 0 and rhs in rhs_rules_set:
                      li = dup_rhs.get(rhs, [])
                      li.append(lhs)
                      dup_rhs[rhs] = li
                  else:
                      rhs_rules_set[rhs] = lhs
                  for sym in rhs:
                      # We assume any symbol starting with an uppercase letter is
                      # terminal, and anything else is a nonterminal
                      if re.match("^[A-Z]", sym):
                          token_set.add(sym)
                      else:
                          rhs_set.add(sym)
                  if len(rhs) > 0 and lhs == rhs[-1]:
                      right_recursive.add((lhs, rhs))
                  pass
              pass
  
          lhs_set.remove(self._START)
          rhs_set.remove(self._BOF)
          missing_lhs = lhs_set - rhs_set
          missing_rhs = rhs_set - lhs_set
  
          # dup_rhs is missing first entry found, so add that
          for rhs in dup_rhs:
              dup_rhs[rhs].append(rhs_rules_set[rhs])
              pass
          return (missing_lhs, missing_rhs, token_set, right_recursive, dup_rhs)