public final AntlrPilarParser.annotationList_return annotationList()
      throws RecognitionException {
    AntlrPilarParser.annotationList_return retval = new AntlrPilarParser.annotationList_return();
    retval.start = input.LT(1);
    int annotationList_StartIndex = input.index();
    Object root_0 = null;

    AntlrPilarParser.annotation_return annotation25 = null;

    RewriteRuleSubtreeStream stream_annotation = new RewriteRuleSubtreeStream(
        adaptor, "rule annotation");
    try {
      if (state.backtracking > 0 && alreadyParsedRule(input, 12)) {
        return retval;
      }
      // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:213:2: ( -> ^( LIST ) | ( annotation )+ -> ^( LIST ( annotation )+ ) )
      int alt4 = 2;
      int LA4_0 = input.LA(1);

      if ((LA4_0 == EOF || (LA4_0 >= HEX_LIT && LA4_0 <= OCT_LIT)
          || (LA4_0 >= ID && LA4_0 <= ACTION_EXT_OP)
          || (LA4_0 >= ADD_OP && LA4_0 <= RATIONAL_LIT)
          || (LA4_0 >= 168 && LA4_0 <= 170) || (LA4_0 >= 172 && LA4_0 <= 188)
          || (LA4_0 >= 194 && LA4_0 <= 195) || (LA4_0 >= 197 && LA4_0 <= 201)
          || (LA4_0 >= 204 && LA4_0 <= 208) || (LA4_0 >= 210 && LA4_0 <= 211)
          || LA4_0 == 215 || (LA4_0 >= 217 && LA4_0 <= 223) || LA4_0 == 226)) {
        alt4 = 1;
      } else if ((LA4_0 == 171)) {
        int LA4_2 = input.LA(2);

        if ((LA4_2 == 202)) {
          alt4 = 1;
        } else if ((LA4_2 == ID)) {
          alt4 = 2;
        } else {
          if (state.backtracking > 0) {
            state.failed = true;
            return retval;
          }
          NoViableAltException nvae = new NoViableAltException("", 4, 2, input);

          throw nvae;
        }
      } else {
        if (state.backtracking > 0) {
          state.failed = true;
          return retval;
        }
        NoViableAltException nvae = new NoViableAltException("", 4, 0, input);

        throw nvae;
      }
      switch (alt4) {
        case 1:
        // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:213:41: 
        {

          // AST REWRITE
          // elements: 
          // token labels: 
          // rule labels: retval
          // token list labels: 
          // rule list labels: 
          // wildcard labels: 
          if (state.backtracking == 0) {
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(
                adaptor, "rule retval", retval != null ? retval.tree : null);

            root_0 = (Object) adaptor.nil();
            // 213:41: -> ^( LIST )
            {
              // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:213:44: ^( LIST )
              {
                Object root_1 = (Object) adaptor.nil();
                root_1 = (Object) adaptor.becomeRoot(
                    (Object) adaptor.create(LIST, "LIST"),
                    root_1);

                adaptor.addChild(root_0, root_1);
              }

            }

            retval.tree = root_0;
          }
        }
          break;
        case 2:
        // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:214:4: ( annotation )+
        {
          // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:214:4: ( annotation )+
          int cnt3 = 0;
          loop3: do {
            int alt3 = 2;
            int LA3_0 = input.LA(1);

            if ((LA3_0 == 171)) {
              int LA3_2 = input.LA(2);

              if ((LA3_2 == ID)) {
                alt3 = 1;
              }

            }

            switch (alt3) {
              case 1:
              // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:0:0: annotation
              {
                pushFollow(FOLLOW_annotation_in_annotationList1223);
                annotation25 = annotation();

                state._fsp--;
                if (state.failed) return retval;
                if (state.backtracking == 0)
                  stream_annotation.add(annotation25.getTree());

              }
                break;

              default:
                if (cnt3 >= 1) break loop3;
                if (state.backtracking > 0) {
                  state.failed = true;
                  return retval;
                }
                EarlyExitException eee = new EarlyExitException(3, input);
                throw eee;
            }
            cnt3++;
          } while (true);

          // AST REWRITE
          // elements: annotation
          // token labels: 
          // rule labels: retval
          // token list labels: 
          // rule list labels: 
          // wildcard labels: 
          if (state.backtracking == 0) {
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(
                adaptor, "rule retval", retval != null ? retval.tree : null);

            root_0 = (Object) adaptor.nil();
            // 214:41: -> ^( LIST ( annotation )+ )
            {
              // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:214:44: ^( LIST ( annotation )+ )
              {
                Object root_1 = (Object) adaptor.nil();
                root_1 = (Object) adaptor.becomeRoot(
                    (Object) adaptor.create(LIST, "LIST"),
                    root_1);

                if (!(stream_annotation.hasNext())) {
                  throw new RewriteEarlyExitException();
                }
                while (stream_annotation.hasNext()) {
                  adaptor.addChild(root_1, stream_annotation.nextTree());

                }
                stream_annotation.reset();

                adaptor.addChild(root_0, root_1);
              }

            }

            retval.tree = root_0;
          }
        }
          break;

      }
      retval.stop = input.LT(-1);

      if (state.backtracking == 0) {

        retval.tree = (Object) adaptor.rulePostProcessing(root_0);
        adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
      }
    } catch (RecognitionException re) {
      reportError(re);
      recover(input, re);
      retval.tree = (Object) adaptor.errorNode(
          input,
          retval.start,
          input.LT(-1),
          re);

    } finally {
      if (state.backtracking > 0) {
        memoize(input, 12, annotationList_StartIndex);
      }
    }
    return retval;
  }