code: public void addRule(ExecutableElement reducer, String nonterminal, String document, boolean synthetic, List<String> rhs)
      {
          Grammar.R rule = new Grammar.R(nonterminal, rhs, reducer, document, synthetic);
          if (!ruleSet.contains(rule))
          {
              rule.number = ruleNumber++;
              ruleSet.add(rule);
              lhsMap.add(nonterminal, rule);
              if (!nonterminalMap.containsKey(nonterminal))
              {
                  Grammar.NT nt = new Grammar.NT(nonterminal);
                  nonterminalMap.put(nonterminal, nt);
                  symbolMap.put(nonterminal, nt);
                  numberMap.put(nt.number, nt);
              }
              for (String s : rhs)
              {
                  if (isAnonymousTerminal(s))
                  {
                      String expression = s.substring(1, s.length()-1);
                      addAnonymousTerminal(expression);
                  }
              }
          }
      }
docs: Adds new rule if the same rule doesn't exist already.
  @param reducer Reducer method.
  @param nonterminal Left hand side of the rule.
  @param rhs Strings which are either nonterminal names, terminal names or
  anonymous terminals. Anonymous terminals are regular expressions inside
  apostrophes. E.g '[0-9]+'