public final AntlrPilarParser.extParamList_return extParamList()
      throws RecognitionException {
    AntlrPilarParser.extParamList_return retval = new AntlrPilarParser.extParamList_return();
    retval.start = input.LT(1);
    int extParamList_StartIndex = input.index();
    Object root_0 = null;

    Token char_literal201 = null;
    AntlrPilarParser.extParamVariable_return extParamVariable199 = null;

    AntlrPilarParser.extParam_return extParam200 = null;

    AntlrPilarParser.extParam_return extParam202 = null;

    AntlrPilarParser.extParamVariable_return extParamVariable203 = null;

    Object char_literal201_tree = null;
    RewriteRuleTokenStream stream_172 = new RewriteRuleTokenStream(adaptor,
        "token 172");
    RewriteRuleSubtreeStream stream_extParamVariable = new RewriteRuleSubtreeStream(
        adaptor, "rule extParamVariable");
    RewriteRuleSubtreeStream stream_extParam = new RewriteRuleSubtreeStream(
        adaptor, "rule extParam");
    try {
      if (state.backtracking > 0 && alreadyParsedRule(input, 51)) {
        return retval;
      }
      // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:429:2: ( extParamVariable -> ^( LIST ( extParamVariable )? ) | extParam ( ',' extParam )* ( extParamVariable )? -> ^( LIST ( extParam )+ ( extParamVariable )? ) )
      int alt60 = 2;
      alt60 = dfa60.predict(input);
      switch (alt60) {
        case 1:
        // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:429:4: extParamVariable
        {
          pushFollow(FOLLOW_extParamVariable_in_extParamList3699);
          extParamVariable199 = extParamVariable();

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

          // AST REWRITE
          // elements: extParamVariable
          // 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();
            // 429:41: -> ^( LIST ( extParamVariable )? )
            {
              // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:429:44: ^( LIST ( extParamVariable )? )
              {
                Object root_1 = (Object) adaptor.nil();
                root_1 = (Object) adaptor.becomeRoot(
                    (Object) adaptor.create(LIST, "LIST"),
                    root_1);

                // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:429:51: ( extParamVariable )?
                if (stream_extParamVariable.hasNext()) {
                  adaptor.addChild(root_1, stream_extParamVariable.nextTree());

                }
                stream_extParamVariable.reset();

                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:430:4: extParam ( ',' extParam )* ( extParamVariable )?
        {
          pushFollow(FOLLOW_extParam_in_extParamList3733);
          extParam200 = extParam();

          state._fsp--;
          if (state.failed) return retval;
          if (state.backtracking == 0)
            stream_extParam.add(extParam200.getTree());
          // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:430:13: ( ',' extParam )*
          loop58: do {
            int alt58 = 2;
            int LA58_0 = input.LA(1);

            if ((LA58_0 == 172)) {
              alt58 = 1;
            }

            switch (alt58) {
              case 1:
              // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:430:15: ',' extParam
              {
                char_literal201 = (Token) match(
                    input,
                    172,
                    FOLLOW_172_in_extParamList3737);
                if (state.failed) return retval;
                if (state.backtracking == 0) stream_172.add(char_literal201);

                pushFollow(FOLLOW_extParam_in_extParamList3739);
                extParam202 = extParam();

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

              }
                break;

              default:
                break loop58;
            }
          } while (true);

          // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:431:4: ( extParamVariable )?
          int alt59 = 2;
          int LA59_0 = input.LA(1);

          if (((LA59_0 >= ID && LA59_0 <= TYPEVARID) || LA59_0 == 169
              || LA59_0 == 177 || LA59_0 == 185)) {
            alt59 = 1;
          }
          switch (alt59) {
            case 1:
            // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:0:0: extParamVariable
            {
              pushFollow(FOLLOW_extParamVariable_in_extParamList3747);
              extParamVariable203 = extParamVariable();

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

            }
              break;

          }

          // AST REWRITE
          // elements: extParamVariable, extParam
          // 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();
            // 431:41: -> ^( LIST ( extParam )+ ( extParamVariable )? )
            {
              // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:431:44: ^( LIST ( extParam )+ ( extParamVariable )? )
              {
                Object root_1 = (Object) adaptor.nil();
                root_1 = (Object) adaptor.becomeRoot(
                    (Object) adaptor.create(LIST, "LIST"),
                    root_1);

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

                }
                stream_extParam.reset();
                // /Users/robby/Repositories/sireum-parser/sireum-parser/src/main/java/org/sireum/pilar/parser/AntlrPilar.g:431:61: ( extParamVariable )?
                if (stream_extParamVariable.hasNext()) {
                  adaptor.addChild(root_1, stream_extParamVariable.nextTree());

                }
                stream_extParamVariable.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, 51, extParamList_StartIndex);
      }
    }
    return retval;
  }