docs: public RuleDescr rule(PackageDescrBuilder pkg) throws RecognitionException {
          RuleDescrBuilder rule = null;
          try {
              rule = helper.start(pkg,
                      RuleDescrBuilder.class,
                      null);
  
              setAnnotationsOn(rule);
  
              // 'rule'
              match(input,
                    DRL6Lexer.ID,
                    DroolsSoftKeywords.RULE,
                    null,
                    DroolsEditorType.KEYWORD);
              if (state.failed)
                  return null;
  
              if (helper.validateIdentifierKey(DroolsSoftKeywords.WHEN) ||
                      helper.validateIdentifierKey(DroolsSoftKeywords.THEN) ||
                      helper.validateIdentifierKey(DroolsSoftKeywords.END)) {
                  failMissingTokenException();
                  return null; // in case it is backtracking
              }
  
              String name = stringId();
              if (state.failed)
                  return null;
              if (state.backtracking == 0) {
                  rule.name(name);
                  helper.setParaphrasesValue(DroolsParaphraseTypes.RULE,
                          "\"" + name + "\"");
                  helper.emit(Location.LOCATION_RULE_HEADER);
              }
  
              if (helper.validateIdentifierKey(DroolsSoftKeywords.EXTENDS)) {
                  // 'extends'
                  match(input,
                          DRL6Lexer.ID,
                          DroolsSoftKeywords.EXTENDS,
                          null,
                          DroolsEditorType.KEYWORD);
                  if (state.failed)
                      return null;
  
                  String parent = stringId();
                  if (state.backtracking == 0)
                      rule.extendsRule(parent);
                  if (state.failed)
                      return null;
              }
  
              if (state.backtracking == 0 && input.LA(1) != DRL6Lexer.EOF) {
                  helper.emit(Location.LOCATION_RULE_HEADER);
              }
  
              attributes(rule);
  
              if (helper.validateIdentifierKey(DroolsSoftKeywords.WHEN)) {
                  lhs(rule);
              } else {
                  // creates an empty LHS
                  rule.lhs();
              }
  
              rhs(rule);
  
              match(input,
                      DRL6Lexer.ID,
                      DroolsSoftKeywords.END,
                      null,
                      DroolsEditorType.KEYWORD);
              if (state.failed)
                  return null;
  
          } catch (RecognitionException re) {
              reportError(re);
          } finally {
              helper.end(RuleDescrBuilder.class,
                      rule);
          }
          return (rule != null) ? rule.getDescr() : null;
      }