Check grammar for:
        -  unused left-hand side nonterminals that are neither start symbols
           or listed in ok_start_symbols
        -  unused right-hand side nonterminals, i.e. not tokens
        -  right-recursive rules. These can slow down parsing.

def check_grammar(self, ok_start_symbols = set(),
                      out=sys.stderr):
        '''
        Check grammar for:
        -  unused left-hand side nonterminals that are neither start symbols
           or listed in ok_start_symbols
        -  unused right-hand side nonterminals, i.e. not tokens
        -  right-recursive rules. These can slow down parsing.
        '''
        warnings = 0
        (lhs, rhs, tokens, right_recursive,
         dup_rhs) = self.check_sets()
        if lhs - ok_start_symbols:
            warnings += 1
            out.write("LHS symbols not used on the RHS:\n")
            out.write("  " + (', '.join(sorted(lhs)) + "\n"))
        if rhs:
            warnings += 1
            out.write("RHS symbols not used on the LHS:\n")
            out.write((', '.join(sorted(rhs))) + "\n" )
        if right_recursive:
            warnings += 1
            out.write("Right recursive rules:\n")
            for rule in sorted(right_recursive):
                out.write("  %s ::= %s\n" % (rule[0], ' '.join(rule[1])))
                pass
            pass
        if dup_rhs:
            warnings += 1
            out.write("Nonterminals with the same RHS\n")
            for rhs in sorted(dup_rhs.keys()):
                out.write("  RHS: %s\n" % ' '.join(rhs))
                out.write("  LHS: %s\n" % ', '.join(dup_rhs[rhs]))
                out.write("  ---\n")
                pass
            pass
        return warnings