private ExpressionContext expression(int _p) throws RecognitionException {
    ParserRuleContext _parentctx = _ctx;
    int _parentState = getState();
    ExpressionContext _localctx = new ExpressionContext(_ctx, _parentState);
    ExpressionContext _prevctx = _localctx;
    int _startState = 2;
    enterRecursionRule(_localctx, 2, RULE_expression, _p);
    int _la;
    try {
      int _alt;
      enterOuterAlt(_localctx, 1);
      {
        setState(30);
        switch (_input.LA(1)) {
          case BOOLNOT:
          case BWNOT:
          case ADD:
          case SUB:
            {
              _localctx = new UnaryContext(_localctx);
              _ctx = _localctx;
              _prevctx = _localctx;

              setState(8);
              _la = _input.LA(1);
              if (!((((_la) & ~0x3f) == 0
                  && ((1L << _la) & ((1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB)))
                      != 0))) {
                _errHandler.recoverInline(this);
              } else {
                consume();
              }
              setState(9);
              expression(12);
            }
            break;
          case LP:
            {
              _localctx = new PrecedenceContext(_localctx);
              _ctx = _localctx;
              _prevctx = _localctx;
              setState(10);
              match(LP);
              setState(11);
              expression(0);
              setState(12);
              match(RP);
            }
            break;
          case OCTAL:
          case HEX:
          case DECIMAL:
            {
              _localctx = new NumericContext(_localctx);
              _ctx = _localctx;
              _prevctx = _localctx;
              setState(14);
              _la = _input.LA(1);
              if (!((((_la) & ~0x3f) == 0
                  && ((1L << _la) & ((1L << OCTAL) | (1L << HEX) | (1L << DECIMAL))) != 0))) {
                _errHandler.recoverInline(this);
              } else {
                consume();
              }
            }
            break;
          case VARIABLE:
            {
              _localctx = new ExternalContext(_localctx);
              _ctx = _localctx;
              _prevctx = _localctx;
              setState(15);
              match(VARIABLE);
              setState(28);
              switch (getInterpreter().adaptivePredict(_input, 2, _ctx)) {
                case 1:
                  {
                    setState(16);
                    match(LP);
                    setState(25);
                    _la = _input.LA(1);
                    if ((((_la) & ~0x3f) == 0
                        && ((1L << _la)
                                & ((1L << LP)
                                    | (1L << BOOLNOT)
                                    | (1L << BWNOT)
                                    | (1L << ADD)
                                    | (1L << SUB)
                                    | (1L << VARIABLE)
                                    | (1L << OCTAL)
                                    | (1L << HEX)
                                    | (1L << DECIMAL)))
                            != 0)) {
                      {
                        setState(17);
                        expression(0);
                        setState(22);
                        _errHandler.sync(this);
                        _la = _input.LA(1);
                        while (_la == COMMA) {
                          {
                            {
                              setState(18);
                              match(COMMA);
                              setState(19);
                              expression(0);
                            }
                          }
                          setState(24);
                          _errHandler.sync(this);
                          _la = _input.LA(1);
                        }
                      }
                    }

                    setState(27);
                    match(RP);
                  }
                  break;
              }
            }
            break;
          default:
            throw new NoViableAltException(this);
        }
        _ctx.stop = _input.LT(-1);
        setState(70);
        _errHandler.sync(this);
        _alt = getInterpreter().adaptivePredict(_input, 5, _ctx);
        while (_alt != 2 && _alt != org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER) {
          if (_alt == 1) {
            if (_parseListeners != null) triggerExitRuleEvent();
            _prevctx = _localctx;
            {
              setState(68);
              switch (getInterpreter().adaptivePredict(_input, 4, _ctx)) {
                case 1:
                  {
                    _localctx = new MuldivContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(32);
                    if (!(precpred(_ctx, 11)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 11)");
                    setState(33);
                    _la = _input.LA(1);
                    if (!((((_la) & ~0x3f) == 0
                        && ((1L << _la) & ((1L << MUL) | (1L << DIV) | (1L << REM))) != 0))) {
                      _errHandler.recoverInline(this);
                    } else {
                      consume();
                    }
                    setState(34);
                    expression(12);
                  }
                  break;
                case 2:
                  {
                    _localctx = new AddsubContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(35);
                    if (!(precpred(_ctx, 10)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 10)");
                    setState(36);
                    _la = _input.LA(1);
                    if (!(_la == ADD || _la == SUB)) {
                      _errHandler.recoverInline(this);
                    } else {
                      consume();
                    }
                    setState(37);
                    expression(11);
                  }
                  break;
                case 3:
                  {
                    _localctx = new BwshiftContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(38);
                    if (!(precpred(_ctx, 9)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 9)");
                    setState(39);
                    _la = _input.LA(1);
                    if (!((((_la) & ~0x3f) == 0
                        && ((1L << _la) & ((1L << LSH) | (1L << RSH) | (1L << USH))) != 0))) {
                      _errHandler.recoverInline(this);
                    } else {
                      consume();
                    }
                    setState(40);
                    expression(10);
                  }
                  break;
                case 4:
                  {
                    _localctx =
                        new BoolcompContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(41);
                    if (!(precpred(_ctx, 8)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 8)");
                    setState(42);
                    _la = _input.LA(1);
                    if (!((((_la) & ~0x3f) == 0
                        && ((1L << _la) & ((1L << LT) | (1L << LTE) | (1L << GT) | (1L << GTE)))
                            != 0))) {
                      _errHandler.recoverInline(this);
                    } else {
                      consume();
                    }
                    setState(43);
                    expression(9);
                  }
                  break;
                case 5:
                  {
                    _localctx =
                        new BooleqneContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(44);
                    if (!(precpred(_ctx, 7)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 7)");
                    setState(45);
                    _la = _input.LA(1);
                    if (!(_la == EQ || _la == NE)) {
                      _errHandler.recoverInline(this);
                    } else {
                      consume();
                    }
                    setState(46);
                    expression(8);
                  }
                  break;
                case 6:
                  {
                    _localctx = new BwandContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(47);
                    if (!(precpred(_ctx, 6)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 6)");
                    setState(48);
                    match(BWAND);
                    setState(49);
                    expression(7);
                  }
                  break;
                case 7:
                  {
                    _localctx = new BwxorContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(50);
                    if (!(precpred(_ctx, 5)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 5)");
                    setState(51);
                    match(BWXOR);
                    setState(52);
                    expression(6);
                  }
                  break;
                case 8:
                  {
                    _localctx = new BworContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(53);
                    if (!(precpred(_ctx, 4)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 4)");
                    setState(54);
                    match(BWOR);
                    setState(55);
                    expression(5);
                  }
                  break;
                case 9:
                  {
                    _localctx = new BoolandContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(56);
                    if (!(precpred(_ctx, 3)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 3)");
                    setState(57);
                    match(BOOLAND);
                    setState(58);
                    expression(4);
                  }
                  break;
                case 10:
                  {
                    _localctx = new BoolorContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(59);
                    if (!(precpred(_ctx, 2)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 2)");
                    setState(60);
                    match(BOOLOR);
                    setState(61);
                    expression(3);
                  }
                  break;
                case 11:
                  {
                    _localctx =
                        new ConditionalContext(new ExpressionContext(_parentctx, _parentState));
                    pushNewRecursionContext(_localctx, _startState, RULE_expression);
                    setState(62);
                    if (!(precpred(_ctx, 1)))
                      throw new FailedPredicateException(this, "precpred(_ctx, 1)");
                    setState(63);
                    match(COND);
                    setState(64);
                    expression(0);
                    setState(65);
                    match(COLON);
                    setState(66);
                    expression(1);
                  }
                  break;
              }
            }
          }
          setState(72);
          _errHandler.sync(this);
          _alt = getInterpreter().adaptivePredict(_input, 5, _ctx);
        }
      }
    } catch (RecognitionException re) {
      _localctx.exception = re;
      _errHandler.reportError(this, re);
      _errHandler.recover(this, re);
    } finally {
      unrollRecursionContexts(_parentctx);
    }
    return _localctx;
  }