# Generated from ./Decaf.g4 by ANTLR 4.7.2
# encoding: utf-8
from antlr4 import *
from io import StringIO
from typing.io import TextIO
import sys

def serializedATN():
    with StringIO() as buf:
        buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3+")
        buf.write("\u00f9\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
        buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16")
        buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23")
        buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31")
        buf.write("\t\31\3\2\3\2\3\2\3\2\7\2\67\n\2\f\2\16\2:\13\2\3\2\3")
        buf.write("\2\3\3\3\3\3\3\5\3A\n\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3")
        buf.write("\4\3\4\3\4\3\4\5\4N\n\4\3\5\3\5\3\5\3\5\7\5T\n\5\f\5\16")
        buf.write("\5W\13\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6b\n\6")
        buf.write("\3\7\3\7\3\7\3\7\7\7h\n\7\f\7\16\7k\13\7\3\7\3\7\3\7\3")
        buf.write("\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\5\tz\n\t\3\n\3")
        buf.write("\n\3\13\3\13\7\13\u0080\n\13\f\13\16\13\u0083\13\13\3")
        buf.write("\13\7\13\u0086\n\13\f\13\16\13\u0089\13\13\3\13\3\13\3")
        buf.write("\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u0094\n\f\3\f\3\f\3\f\3")
        buf.write("\f\3\f\3\f\3\f\3\f\5\f\u009e\n\f\3\f\3\f\3\f\3\f\3\f\3")
        buf.write("\f\3\f\3\f\3\f\3\f\5\f\u00aa\n\f\3\f\5\f\u00ad\n\f\3\r")
        buf.write("\3\r\3\r\3\r\3\r\3\r\5\r\u00b5\n\r\3\r\3\r\5\r\u00b9\n")
        buf.write("\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3")
        buf.write("\16\3\16\5\16\u00c7\n\16\3\16\3\16\3\16\3\16\7\16\u00cd")
        buf.write("\n\16\f\16\16\16\u00d0\13\16\3\17\3\17\3\17\7\17\u00d5")
        buf.write("\n\17\f\17\16\17\u00d8\13\17\3\17\3\17\3\20\3\20\3\21")
        buf.write("\3\21\3\21\3\21\5\21\u00e2\n\21\3\22\3\22\3\23\3\23\3")
        buf.write("\24\3\24\3\25\3\25\3\26\3\26\3\26\5\26\u00ef\n\26\3\27")
        buf.write("\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\2\3\32\32\2\4")
        buf.write("\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\2\t\3")
        buf.write("\2\13\16\3\2\13\r\4\2\27\27\31\34\3\2\35 \3\2!\"\3\2#")
        buf.write("$\3\2%&\2\u0105\2\62\3\2\2\2\4@\3\2\2\2\6M\3\2\2\2\bO")
        buf.write("\3\2\2\2\na\3\2\2\2\fc\3\2\2\2\16o\3\2\2\2\20y\3\2\2\2")
        buf.write("\22{\3\2\2\2\24}\3\2\2\2\26\u00ac\3\2\2\2\30\u00b4\3\2")
        buf.write("\2\2\32\u00c6\3\2\2\2\34\u00d1\3\2\2\2\36\u00db\3\2\2")
        buf.write("\2 \u00e1\3\2\2\2\"\u00e3\3\2\2\2$\u00e5\3\2\2\2&\u00e7")
        buf.write("\3\2\2\2(\u00e9\3\2\2\2*\u00ee\3\2\2\2,\u00f0\3\2\2\2")
        buf.write(".\u00f2\3\2\2\2\60\u00f6\3\2\2\2\62\63\7\3\2\2\63\64\7")
        buf.write("\4\2\2\648\7\5\2\2\65\67\5\4\3\2\66\65\3\2\2\2\67:\3\2")
        buf.write("\2\28\66\3\2\2\289\3\2\2\29;\3\2\2\2:8\3\2\2\2;<\7\6\2")
        buf.write("\2<\3\3\2\2\2=A\5\b\5\2>A\5\6\4\2?A\5\f\7\2@=\3\2\2\2")
        buf.write("@>\3\2\2\2@?\3\2\2\2A\5\3\2\2\2BC\5\n\6\2CD\7\'\2\2DE")
        buf.write("\7\7\2\2EN\3\2\2\2FG\5\n\6\2GH\7\'\2\2HI\7\b\2\2IJ\7(")
        buf.write("\2\2JK\7\t\2\2KL\7\7\2\2LN\3\2\2\2MB\3\2\2\2MF\3\2\2\2")
        buf.write("N\7\3\2\2\2OP\7\n\2\2PQ\7\'\2\2QU\7\5\2\2RT\5\6\4\2SR")
        buf.write("\3\2\2\2TW\3\2\2\2US\3\2\2\2UV\3\2\2\2VX\3\2\2\2WU\3\2")
        buf.write("\2\2XY\7\6\2\2Y\t\3\2\2\2Zb\7\13\2\2[b\7\f\2\2\\b\7\r")
        buf.write("\2\2]^\7\n\2\2^b\7\'\2\2_b\5\b\5\2`b\7\16\2\2aZ\3\2\2")
        buf.write("\2a[\3\2\2\2a\\\3\2\2\2a]\3\2\2\2a_\3\2\2\2a`\3\2\2\2")
        buf.write("b\13\3\2\2\2cd\5\16\b\2de\7\'\2\2ei\7\17\2\2fh\5\20\t")
        buf.write("\2gf\3\2\2\2hk\3\2\2\2ig\3\2\2\2ij\3\2\2\2jl\3\2\2\2k")
        buf.write("i\3\2\2\2lm\7\20\2\2mn\5\24\13\2n\r\3\2\2\2op\t\2\2\2")
        buf.write("p\17\3\2\2\2qr\5\22\n\2rs\7\'\2\2sz\3\2\2\2tu\5\22\n\2")
        buf.write("uv\7\'\2\2vw\7\b\2\2wx\7\t\2\2xz\3\2\2\2yq\3\2\2\2yt\3")
        buf.write("\2\2\2z\21\3\2\2\2{|\t\3\2\2|\23\3\2\2\2}\u0081\7\5\2")
        buf.write("\2~\u0080\5\6\4\2\177~\3\2\2\2\u0080\u0083\3\2\2\2\u0081")
        buf.write("\177\3\2\2\2\u0081\u0082\3\2\2\2\u0082\u0087\3\2\2\2\u0083")
        buf.write("\u0081\3\2\2\2\u0084\u0086\5\26\f\2\u0085\u0084\3\2\2")
        buf.write("\2\u0086\u0089\3\2\2\2\u0087\u0085\3\2\2\2\u0087\u0088")
        buf.write("\3\2\2\2\u0088\u008a\3\2\2\2\u0089\u0087\3\2\2\2\u008a")
        buf.write("\u008b\7\6\2\2\u008b\25\3\2\2\2\u008c\u008d\7\21\2\2\u008d")
        buf.write("\u008e\7\17\2\2\u008e\u008f\5\32\16\2\u008f\u0090\7\20")
        buf.write("\2\2\u0090\u0093\5\24\13\2\u0091\u0092\7\22\2\2\u0092")
        buf.write("\u0094\5\24\13\2\u0093\u0091\3\2\2\2\u0093\u0094\3\2\2")
        buf.write("\2\u0094\u00ad\3\2\2\2\u0095\u0096\7\23\2\2\u0096\u0097")
        buf.write("\7\17\2\2\u0097\u0098\5\32\16\2\u0098\u0099\7\20\2\2\u0099")
        buf.write("\u009a\5\24\13\2\u009a\u00ad\3\2\2\2\u009b\u009d\7\24")
        buf.write("\2\2\u009c\u009e\5\32\16\2\u009d\u009c\3\2\2\2\u009d\u009e")
        buf.write("\3\2\2\2\u009e\u009f\3\2\2\2\u009f\u00ad\7\7\2\2\u00a0")
        buf.write("\u00a1\5\34\17\2\u00a1\u00a2\7\7\2\2\u00a2\u00ad\3\2\2")
        buf.write("\2\u00a3\u00ad\5\24\13\2\u00a4\u00a5\5\30\r\2\u00a5\u00a6")
        buf.write("\7\25\2\2\u00a6\u00a7\5\32\16\2\u00a7\u00ad\3\2\2\2\u00a8")
        buf.write("\u00aa\5\32\16\2\u00a9\u00a8\3\2\2\2\u00a9\u00aa\3\2\2")
        buf.write("\2\u00aa\u00ab\3\2\2\2\u00ab\u00ad\7\7\2\2\u00ac\u008c")
        buf.write("\3\2\2\2\u00ac\u0095\3\2\2\2\u00ac\u009b\3\2\2\2\u00ac")
        buf.write("\u00a0\3\2\2\2\u00ac\u00a3\3\2\2\2\u00ac\u00a4\3\2\2\2")
        buf.write("\u00ac\u00a9\3\2\2\2\u00ad\27\3\2\2\2\u00ae\u00b5\7\'")
        buf.write("\2\2\u00af\u00b0\7\'\2\2\u00b0\u00b1\7\b\2\2\u00b1\u00b2")
        buf.write("\5\32\16\2\u00b2\u00b3\7\t\2\2\u00b3\u00b5\3\2\2\2\u00b4")
        buf.write("\u00ae\3\2\2\2\u00b4\u00af\3\2\2\2\u00b5\u00b8\3\2\2\2")
        buf.write("\u00b6\u00b7\7\26\2\2\u00b7\u00b9\5\30\r\2\u00b8\u00b6")
        buf.write("\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9\31\3\2\2\2\u00ba\u00bb")
        buf.write("\b\16\1\2\u00bb\u00c7\5\30\r\2\u00bc\u00c7\5\34\17\2\u00bd")
        buf.write("\u00c7\5*\26\2\u00be\u00bf\7\27\2\2\u00bf\u00c7\5\32\16")
        buf.write("\5\u00c0\u00c1\7\30\2\2\u00c1\u00c7\5\32\16\4\u00c2\u00c3")
        buf.write("\7\17\2\2\u00c3\u00c4\5\32\16\2\u00c4\u00c5\7\20\2\2\u00c5")
        buf.write("\u00c7\3\2\2\2\u00c6\u00ba\3\2\2\2\u00c6\u00bc\3\2\2\2")
        buf.write("\u00c6\u00bd\3\2\2\2\u00c6\u00be\3\2\2\2\u00c6\u00c0\3")
        buf.write("\2\2\2\u00c6\u00c2\3\2\2\2\u00c7\u00ce\3\2\2\2\u00c8\u00c9")
        buf.write("\f\6\2\2\u00c9\u00ca\5 \21\2\u00ca\u00cb\5\32\16\7\u00cb")
        buf.write("\u00cd\3\2\2\2\u00cc\u00c8\3\2\2\2\u00cd\u00d0\3\2\2\2")
        buf.write("\u00ce\u00cc\3\2\2\2\u00ce\u00cf\3\2\2\2\u00cf\33\3\2")
        buf.write("\2\2\u00d0\u00ce\3\2\2\2\u00d1\u00d2\7\'\2\2\u00d2\u00d6")
        buf.write("\7\17\2\2\u00d3\u00d5\5\36\20\2\u00d4\u00d3\3\2\2\2\u00d5")
        buf.write("\u00d8\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d6\u00d7\3\2\2\2")
        buf.write("\u00d7\u00d9\3\2\2\2\u00d8\u00d6\3\2\2\2\u00d9\u00da\7")
        buf.write("\20\2\2\u00da\35\3\2\2\2\u00db\u00dc\5\32\16\2\u00dc\37")
        buf.write("\3\2\2\2\u00dd\u00e2\5\"\22\2\u00de\u00e2\5$\23\2\u00df")
        buf.write("\u00e2\5&\24\2\u00e0\u00e2\5(\25\2\u00e1\u00dd\3\2\2\2")
        buf.write("\u00e1\u00de\3\2\2\2\u00e1\u00df\3\2\2\2\u00e1\u00e0\3")
        buf.write("\2\2\2\u00e2!\3\2\2\2\u00e3\u00e4\t\4\2\2\u00e4#\3\2\2")
        buf.write("\2\u00e5\u00e6\t\5\2\2\u00e6%\3\2\2\2\u00e7\u00e8\t\6")
        buf.write("\2\2\u00e8\'\3\2\2\2\u00e9\u00ea\t\7\2\2\u00ea)\3\2\2")
        buf.write("\2\u00eb\u00ef\5,\27\2\u00ec\u00ef\5.\30\2\u00ed\u00ef")
        buf.write("\5\60\31\2\u00ee\u00eb\3\2\2\2\u00ee\u00ec\3\2\2\2\u00ee")
        buf.write("\u00ed\3\2\2\2\u00ef+\3\2\2\2\u00f0\u00f1\7(\2\2\u00f1")
        buf.write("-\3\2\2\2\u00f2\u00f3\7)\2\2\u00f3\u00f4\7*\2\2\u00f4")
        buf.write("\u00f5\7)\2\2\u00f5/\3\2\2\2\u00f6\u00f7\t\b\2\2\u00f7")
        buf.write("\61\3\2\2\2\268@MUaiy\u0081\u0087\u0093\u009d\u00a9\u00ac")
        buf.write("\u00b4\u00b8\u00c6\u00ce\u00d6\u00e1\u00ee")
        return buf.getvalue()


class DecafParser ( Parser ):

    grammarFileName = "Decaf.g4"

    atn = ATNDeserializer().deserialize(serializedATN())

    decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]

    sharedContextCache = PredictionContextCache()

    literalNames = [ "<INVALID>", "'class'", "'Program'", "'{'", "'}'", 
                     "';'", "'['", "']'", "'struct'", "'int'", "'char'", 
                     "'boolean'", "'void'", "'('", "')'", "'if'", "'else'", 
                     "'while'", "'return'", "'='", "'.'", "'-'", "'!'", 
                     "'+'", "'*'", "'/'", "'%'", "'<'", "'>'", "'<='", "'>='", 
                     "'=='", "'!='", "'&&'", "'||'", "'true'", "'false'", 
                     "<INVALID>", "<INVALID>", "'''" ]

    symbolicNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "ID", "NUM", "APOSTROPHE", "CHAR_LITERAL", 
                      "WHITESPACE" ]

    RULE_program = 0
    RULE_declaration = 1
    RULE_varDeclaration = 2
    RULE_structDeclaration = 3
    RULE_varType = 4
    RULE_methodDeclaration = 5
    RULE_methodType = 6
    RULE_parameter = 7
    RULE_parameterType = 8
    RULE_block = 9
    RULE_statement = 10
    RULE_location = 11
    RULE_expression = 12
    RULE_methodCall = 13
    RULE_arg = 14
    RULE_op = 15
    RULE_arith_op = 16
    RULE_rel_op = 17
    RULE_eq_op = 18
    RULE_cond_op = 19
    RULE_literal = 20
    RULE_int_literal = 21
    RULE_char_literal = 22
    RULE_bool_literal = 23

    ruleNames =  [ "program", "declaration", "varDeclaration", "structDeclaration", 
                   "varType", "methodDeclaration", "methodType", "parameter", 
                   "parameterType", "block", "statement", "location", "expression", 
                   "methodCall", "arg", "op", "arith_op", "rel_op", "eq_op", 
                   "cond_op", "literal", "int_literal", "char_literal", 
                   "bool_literal" ]

    EOF = Token.EOF
    T__0=1
    T__1=2
    T__2=3
    T__3=4
    T__4=5
    T__5=6
    T__6=7
    T__7=8
    T__8=9
    T__9=10
    T__10=11
    T__11=12
    T__12=13
    T__13=14
    T__14=15
    T__15=16
    T__16=17
    T__17=18
    T__18=19
    T__19=20
    T__20=21
    T__21=22
    T__22=23
    T__23=24
    T__24=25
    T__25=26
    T__26=27
    T__27=28
    T__28=29
    T__29=30
    T__30=31
    T__31=32
    T__32=33
    T__33=34
    T__34=35
    T__35=36
    ID=37
    NUM=38
    APOSTROPHE=39
    CHAR_LITERAL=40
    WHITESPACE=41

    def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
        super().__init__(input, output)
        self.checkVersion("4.7.2")
        self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
        self._predicates = None



    class ProgramContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def declaration(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(DecafParser.DeclarationContext)
            else:
                return self.getTypedRuleContext(DecafParser.DeclarationContext,i)


        def getRuleIndex(self):
            return DecafParser.RULE_program

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterProgram" ):
                listener.enterProgram(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitProgram" ):
                listener.exitProgram(self)




    def program(self):

        localctx = DecafParser.ProgramContext(self, self._ctx, self.state)
        self.enterRule(localctx, 0, self.RULE_program)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 48
            self.match(DecafParser.T__0)
            self.state = 49
            self.match(DecafParser.T__1)
            self.state = 50
            self.match(DecafParser.T__2)
            self.state = 54
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__7) | (1 << DecafParser.T__8) | (1 << DecafParser.T__9) | (1 << DecafParser.T__10) | (1 << DecafParser.T__11))) != 0):
                self.state = 51
                self.declaration()
                self.state = 56
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 57
            self.match(DecafParser.T__3)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class DeclarationContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def structDeclaration(self):
            return self.getTypedRuleContext(DecafParser.StructDeclarationContext,0)


        def varDeclaration(self):
            return self.getTypedRuleContext(DecafParser.VarDeclarationContext,0)


        def methodDeclaration(self):
            return self.getTypedRuleContext(DecafParser.MethodDeclarationContext,0)


        def getRuleIndex(self):
            return DecafParser.RULE_declaration

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterDeclaration" ):
                listener.enterDeclaration(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitDeclaration" ):
                listener.exitDeclaration(self)




    def declaration(self):

        localctx = DecafParser.DeclarationContext(self, self._ctx, self.state)
        self.enterRule(localctx, 2, self.RULE_declaration)
        try:
            self.state = 62
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,1,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 59
                self.structDeclaration()
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 60
                self.varDeclaration()
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 61
                self.methodDeclaration()
                pass


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class VarDeclarationContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def varType(self):
            return self.getTypedRuleContext(DecafParser.VarTypeContext,0)


        def ID(self):
            return self.getToken(DecafParser.ID, 0)

        def NUM(self):
            return self.getToken(DecafParser.NUM, 0)

        def getRuleIndex(self):
            return DecafParser.RULE_varDeclaration

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterVarDeclaration" ):
                listener.enterVarDeclaration(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitVarDeclaration" ):
                listener.exitVarDeclaration(self)




    def varDeclaration(self):

        localctx = DecafParser.VarDeclarationContext(self, self._ctx, self.state)
        self.enterRule(localctx, 4, self.RULE_varDeclaration)
        try:
            self.state = 75
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,2,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 64
                self.varType()
                self.state = 65
                self.match(DecafParser.ID)
                self.state = 66
                self.match(DecafParser.T__4)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 68
                self.varType()
                self.state = 69
                self.match(DecafParser.ID)
                self.state = 70
                self.match(DecafParser.T__5)
                self.state = 71
                self.match(DecafParser.NUM)
                self.state = 72
                self.match(DecafParser.T__6)
                self.state = 73
                self.match(DecafParser.T__4)
                pass


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class StructDeclarationContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def ID(self):
            return self.getToken(DecafParser.ID, 0)

        def varDeclaration(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(DecafParser.VarDeclarationContext)
            else:
                return self.getTypedRuleContext(DecafParser.VarDeclarationContext,i)


        def getRuleIndex(self):
            return DecafParser.RULE_structDeclaration

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterStructDeclaration" ):
                listener.enterStructDeclaration(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitStructDeclaration" ):
                listener.exitStructDeclaration(self)




    def structDeclaration(self):

        localctx = DecafParser.StructDeclarationContext(self, self._ctx, self.state)
        self.enterRule(localctx, 6, self.RULE_structDeclaration)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 77
            self.match(DecafParser.T__7)
            self.state = 78
            self.match(DecafParser.ID)
            self.state = 79
            self.match(DecafParser.T__2)
            self.state = 83
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__7) | (1 << DecafParser.T__8) | (1 << DecafParser.T__9) | (1 << DecafParser.T__10) | (1 << DecafParser.T__11))) != 0):
                self.state = 80
                self.varDeclaration()
                self.state = 85
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 86
            self.match(DecafParser.T__3)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class VarTypeContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def ID(self):
            return self.getToken(DecafParser.ID, 0)

        def structDeclaration(self):
            return self.getTypedRuleContext(DecafParser.StructDeclarationContext,0)


        def getRuleIndex(self):
            return DecafParser.RULE_varType

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterVarType" ):
                listener.enterVarType(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitVarType" ):
                listener.exitVarType(self)




    def varType(self):

        localctx = DecafParser.VarTypeContext(self, self._ctx, self.state)
        self.enterRule(localctx, 8, self.RULE_varType)
        try:
            self.state = 95
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,4,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 88
                self.match(DecafParser.T__8)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 89
                self.match(DecafParser.T__9)
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 90
                self.match(DecafParser.T__10)
                pass

            elif la_ == 4:
                self.enterOuterAlt(localctx, 4)
                self.state = 91
                self.match(DecafParser.T__7)
                self.state = 92
                self.match(DecafParser.ID)
                pass

            elif la_ == 5:
                self.enterOuterAlt(localctx, 5)
                self.state = 93
                self.structDeclaration()
                pass

            elif la_ == 6:
                self.enterOuterAlt(localctx, 6)
                self.state = 94
                self.match(DecafParser.T__11)
                pass


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class MethodDeclarationContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def methodType(self):
            return self.getTypedRuleContext(DecafParser.MethodTypeContext,0)


        def ID(self):
            return self.getToken(DecafParser.ID, 0)

        def block(self):
            return self.getTypedRuleContext(DecafParser.BlockContext,0)


        def parameter(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(DecafParser.ParameterContext)
            else:
                return self.getTypedRuleContext(DecafParser.ParameterContext,i)


        def getRuleIndex(self):
            return DecafParser.RULE_methodDeclaration

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterMethodDeclaration" ):
                listener.enterMethodDeclaration(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitMethodDeclaration" ):
                listener.exitMethodDeclaration(self)




    def methodDeclaration(self):

        localctx = DecafParser.MethodDeclarationContext(self, self._ctx, self.state)
        self.enterRule(localctx, 10, self.RULE_methodDeclaration)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 97
            self.methodType()
            self.state = 98
            self.match(DecafParser.ID)
            self.state = 99
            self.match(DecafParser.T__12)
            self.state = 103
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__8) | (1 << DecafParser.T__9) | (1 << DecafParser.T__10))) != 0):
                self.state = 100
                self.parameter()
                self.state = 105
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 106
            self.match(DecafParser.T__13)
            self.state = 107
            self.block()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class MethodTypeContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser


        def getRuleIndex(self):
            return DecafParser.RULE_methodType

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterMethodType" ):
                listener.enterMethodType(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitMethodType" ):
                listener.exitMethodType(self)




    def methodType(self):

        localctx = DecafParser.MethodTypeContext(self, self._ctx, self.state)
        self.enterRule(localctx, 12, self.RULE_methodType)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 109
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__8) | (1 << DecafParser.T__9) | (1 << DecafParser.T__10) | (1 << DecafParser.T__11))) != 0)):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class ParameterContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def parameterType(self):
            return self.getTypedRuleContext(DecafParser.ParameterTypeContext,0)


        def ID(self):
            return self.getToken(DecafParser.ID, 0)

        def getRuleIndex(self):
            return DecafParser.RULE_parameter

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterParameter" ):
                listener.enterParameter(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitParameter" ):
                listener.exitParameter(self)




    def parameter(self):

        localctx = DecafParser.ParameterContext(self, self._ctx, self.state)
        self.enterRule(localctx, 14, self.RULE_parameter)
        try:
            self.state = 119
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,6,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 111
                self.parameterType()
                self.state = 112
                self.match(DecafParser.ID)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 114
                self.parameterType()
                self.state = 115
                self.match(DecafParser.ID)
                self.state = 116
                self.match(DecafParser.T__5)
                self.state = 117
                self.match(DecafParser.T__6)
                pass


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class ParameterTypeContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser


        def getRuleIndex(self):
            return DecafParser.RULE_parameterType

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterParameterType" ):
                listener.enterParameterType(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitParameterType" ):
                listener.exitParameterType(self)




    def parameterType(self):

        localctx = DecafParser.ParameterTypeContext(self, self._ctx, self.state)
        self.enterRule(localctx, 16, self.RULE_parameterType)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 121
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__8) | (1 << DecafParser.T__9) | (1 << DecafParser.T__10))) != 0)):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class BlockContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def varDeclaration(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(DecafParser.VarDeclarationContext)
            else:
                return self.getTypedRuleContext(DecafParser.VarDeclarationContext,i)


        def statement(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(DecafParser.StatementContext)
            else:
                return self.getTypedRuleContext(DecafParser.StatementContext,i)


        def getRuleIndex(self):
            return DecafParser.RULE_block

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterBlock" ):
                listener.enterBlock(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitBlock" ):
                listener.exitBlock(self)




    def block(self):

        localctx = DecafParser.BlockContext(self, self._ctx, self.state)
        self.enterRule(localctx, 18, self.RULE_block)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 123
            self.match(DecafParser.T__2)
            self.state = 127
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__7) | (1 << DecafParser.T__8) | (1 << DecafParser.T__9) | (1 << DecafParser.T__10) | (1 << DecafParser.T__11))) != 0):
                self.state = 124
                self.varDeclaration()
                self.state = 129
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 133
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__2) | (1 << DecafParser.T__4) | (1 << DecafParser.T__12) | (1 << DecafParser.T__14) | (1 << DecafParser.T__16) | (1 << DecafParser.T__17) | (1 << DecafParser.T__20) | (1 << DecafParser.T__21) | (1 << DecafParser.T__34) | (1 << DecafParser.T__35) | (1 << DecafParser.ID) | (1 << DecafParser.NUM) | (1 << DecafParser.APOSTROPHE))) != 0):
                self.state = 130
                self.statement()
                self.state = 135
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 136
            self.match(DecafParser.T__3)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class StatementContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def expression(self):
            return self.getTypedRuleContext(DecafParser.ExpressionContext,0)


        def block(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(DecafParser.BlockContext)
            else:
                return self.getTypedRuleContext(DecafParser.BlockContext,i)


        def methodCall(self):
            return self.getTypedRuleContext(DecafParser.MethodCallContext,0)


        def location(self):
            return self.getTypedRuleContext(DecafParser.LocationContext,0)


        def getRuleIndex(self):
            return DecafParser.RULE_statement

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterStatement" ):
                listener.enterStatement(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitStatement" ):
                listener.exitStatement(self)




    def statement(self):

        localctx = DecafParser.StatementContext(self, self._ctx, self.state)
        self.enterRule(localctx, 20, self.RULE_statement)
        self._la = 0 # Token type
        try:
            self.state = 170
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,12,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 138
                self.match(DecafParser.T__14)
                self.state = 139
                self.match(DecafParser.T__12)
                self.state = 140
                self.expression(0)
                self.state = 141
                self.match(DecafParser.T__13)
                self.state = 142
                self.block()
                self.state = 145
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if _la==DecafParser.T__15:
                    self.state = 143
                    self.match(DecafParser.T__15)
                    self.state = 144
                    self.block()


                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 147
                self.match(DecafParser.T__16)
                self.state = 148
                self.match(DecafParser.T__12)
                self.state = 149
                self.expression(0)
                self.state = 150
                self.match(DecafParser.T__13)
                self.state = 151
                self.block()
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 153
                self.match(DecafParser.T__17)
                self.state = 155
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__12) | (1 << DecafParser.T__20) | (1 << DecafParser.T__21) | (1 << DecafParser.T__34) | (1 << DecafParser.T__35) | (1 << DecafParser.ID) | (1 << DecafParser.NUM) | (1 << DecafParser.APOSTROPHE))) != 0):
                    self.state = 154
                    self.expression(0)


                self.state = 157
                self.match(DecafParser.T__4)
                pass

            elif la_ == 4:
                self.enterOuterAlt(localctx, 4)
                self.state = 158
                self.methodCall()
                self.state = 159
                self.match(DecafParser.T__4)
                pass

            elif la_ == 5:
                self.enterOuterAlt(localctx, 5)
                self.state = 161
                self.block()
                pass

            elif la_ == 6:
                self.enterOuterAlt(localctx, 6)
                self.state = 162
                self.location()
                self.state = 163
                self.match(DecafParser.T__18)
                self.state = 164
                self.expression(0)
                pass

            elif la_ == 7:
                self.enterOuterAlt(localctx, 7)
                self.state = 167
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__12) | (1 << DecafParser.T__20) | (1 << DecafParser.T__21) | (1 << DecafParser.T__34) | (1 << DecafParser.T__35) | (1 << DecafParser.ID) | (1 << DecafParser.NUM) | (1 << DecafParser.APOSTROPHE))) != 0):
                    self.state = 166
                    self.expression(0)


                self.state = 169
                self.match(DecafParser.T__4)
                pass


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class LocationContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def ID(self):
            return self.getToken(DecafParser.ID, 0)

        def expression(self):
            return self.getTypedRuleContext(DecafParser.ExpressionContext,0)


        def location(self):
            return self.getTypedRuleContext(DecafParser.LocationContext,0)


        def getRuleIndex(self):
            return DecafParser.RULE_location

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterLocation" ):
                listener.enterLocation(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitLocation" ):
                listener.exitLocation(self)




    def location(self):

        localctx = DecafParser.LocationContext(self, self._ctx, self.state)
        self.enterRule(localctx, 22, self.RULE_location)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 178
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,13,self._ctx)
            if la_ == 1:
                self.state = 172
                self.match(DecafParser.ID)
                pass

            elif la_ == 2:
                self.state = 173
                self.match(DecafParser.ID)
                self.state = 174
                self.match(DecafParser.T__5)
                self.state = 175
                self.expression(0)
                self.state = 176
                self.match(DecafParser.T__6)
                pass


            self.state = 182
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,14,self._ctx)
            if la_ == 1:
                self.state = 180
                self.match(DecafParser.T__19)
                self.state = 181
                self.location()


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class ExpressionContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def location(self):
            return self.getTypedRuleContext(DecafParser.LocationContext,0)


        def methodCall(self):
            return self.getTypedRuleContext(DecafParser.MethodCallContext,0)


        def literal(self):
            return self.getTypedRuleContext(DecafParser.LiteralContext,0)


        def expression(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(DecafParser.ExpressionContext)
            else:
                return self.getTypedRuleContext(DecafParser.ExpressionContext,i)


        def op(self):
            return self.getTypedRuleContext(DecafParser.OpContext,0)


        def getRuleIndex(self):
            return DecafParser.RULE_expression

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterExpression" ):
                listener.enterExpression(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitExpression" ):
                listener.exitExpression(self)



    def expression(self, _p:int=0):
        _parentctx = self._ctx
        _parentState = self.state
        localctx = DecafParser.ExpressionContext(self, self._ctx, _parentState)
        _prevctx = localctx
        _startState = 24
        self.enterRecursionRule(localctx, 24, self.RULE_expression, _p)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 196
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,15,self._ctx)
            if la_ == 1:
                self.state = 185
                self.location()
                pass

            elif la_ == 2:
                self.state = 186
                self.methodCall()
                pass

            elif la_ == 3:
                self.state = 187
                self.literal()
                pass

            elif la_ == 4:
                self.state = 188
                self.match(DecafParser.T__20)
                self.state = 189
                self.expression(3)
                pass

            elif la_ == 5:
                self.state = 190
                self.match(DecafParser.T__21)
                self.state = 191
                self.expression(2)
                pass

            elif la_ == 6:
                self.state = 192
                self.match(DecafParser.T__12)
                self.state = 193
                self.expression(0)
                self.state = 194
                self.match(DecafParser.T__13)
                pass


            self._ctx.stop = self._input.LT(-1)
            self.state = 204
            self._errHandler.sync(self)
            _alt = self._interp.adaptivePredict(self._input,16,self._ctx)
            while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt==1:
                    if self._parseListeners is not None:
                        self.triggerExitRuleEvent()
                    _prevctx = localctx
                    localctx = DecafParser.ExpressionContext(self, _parentctx, _parentState)
                    self.pushNewRecursionContext(localctx, _startState, self.RULE_expression)
                    self.state = 198
                    if not self.precpred(self._ctx, 4):
                        from antlr4.error.Errors import FailedPredicateException
                        raise FailedPredicateException(self, "self.precpred(self._ctx, 4)")
                    self.state = 199
                    self.op()
                    self.state = 200
                    self.expression(5) 
                self.state = 206
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,16,self._ctx)

        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.unrollRecursionContexts(_parentctx)
        return localctx

    class MethodCallContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def ID(self):
            return self.getToken(DecafParser.ID, 0)

        def arg(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(DecafParser.ArgContext)
            else:
                return self.getTypedRuleContext(DecafParser.ArgContext,i)


        def getRuleIndex(self):
            return DecafParser.RULE_methodCall

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterMethodCall" ):
                listener.enterMethodCall(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitMethodCall" ):
                listener.exitMethodCall(self)




    def methodCall(self):

        localctx = DecafParser.MethodCallContext(self, self._ctx, self.state)
        self.enterRule(localctx, 26, self.RULE_methodCall)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 207
            self.match(DecafParser.ID)
            self.state = 208
            self.match(DecafParser.T__12)
            self.state = 212
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__12) | (1 << DecafParser.T__20) | (1 << DecafParser.T__21) | (1 << DecafParser.T__34) | (1 << DecafParser.T__35) | (1 << DecafParser.ID) | (1 << DecafParser.NUM) | (1 << DecafParser.APOSTROPHE))) != 0):
                self.state = 209
                self.arg()
                self.state = 214
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 215
            self.match(DecafParser.T__13)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class ArgContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def expression(self):
            return self.getTypedRuleContext(DecafParser.ExpressionContext,0)


        def getRuleIndex(self):
            return DecafParser.RULE_arg

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterArg" ):
                listener.enterArg(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitArg" ):
                listener.exitArg(self)




    def arg(self):

        localctx = DecafParser.ArgContext(self, self._ctx, self.state)
        self.enterRule(localctx, 28, self.RULE_arg)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 217
            self.expression(0)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class OpContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def arith_op(self):
            return self.getTypedRuleContext(DecafParser.Arith_opContext,0)


        def rel_op(self):
            return self.getTypedRuleContext(DecafParser.Rel_opContext,0)


        def eq_op(self):
            return self.getTypedRuleContext(DecafParser.Eq_opContext,0)


        def cond_op(self):
            return self.getTypedRuleContext(DecafParser.Cond_opContext,0)


        def getRuleIndex(self):
            return DecafParser.RULE_op

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterOp" ):
                listener.enterOp(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitOp" ):
                listener.exitOp(self)




    def op(self):

        localctx = DecafParser.OpContext(self, self._ctx, self.state)
        self.enterRule(localctx, 30, self.RULE_op)
        try:
            self.state = 223
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [DecafParser.T__20, DecafParser.T__22, DecafParser.T__23, DecafParser.T__24, DecafParser.T__25]:
                self.enterOuterAlt(localctx, 1)
                self.state = 219
                self.arith_op()
                pass
            elif token in [DecafParser.T__26, DecafParser.T__27, DecafParser.T__28, DecafParser.T__29]:
                self.enterOuterAlt(localctx, 2)
                self.state = 220
                self.rel_op()
                pass
            elif token in [DecafParser.T__30, DecafParser.T__31]:
                self.enterOuterAlt(localctx, 3)
                self.state = 221
                self.eq_op()
                pass
            elif token in [DecafParser.T__32, DecafParser.T__33]:
                self.enterOuterAlt(localctx, 4)
                self.state = 222
                self.cond_op()
                pass
            else:
                raise NoViableAltException(self)

        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class Arith_opContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser


        def getRuleIndex(self):
            return DecafParser.RULE_arith_op

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterArith_op" ):
                listener.enterArith_op(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitArith_op" ):
                listener.exitArith_op(self)




    def arith_op(self):

        localctx = DecafParser.Arith_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 32, self.RULE_arith_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 225
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__20) | (1 << DecafParser.T__22) | (1 << DecafParser.T__23) | (1 << DecafParser.T__24) | (1 << DecafParser.T__25))) != 0)):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class Rel_opContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser


        def getRuleIndex(self):
            return DecafParser.RULE_rel_op

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterRel_op" ):
                listener.enterRel_op(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitRel_op" ):
                listener.exitRel_op(self)




    def rel_op(self):

        localctx = DecafParser.Rel_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 34, self.RULE_rel_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 227
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << DecafParser.T__26) | (1 << DecafParser.T__27) | (1 << DecafParser.T__28) | (1 << DecafParser.T__29))) != 0)):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class Eq_opContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser


        def getRuleIndex(self):
            return DecafParser.RULE_eq_op

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterEq_op" ):
                listener.enterEq_op(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitEq_op" ):
                listener.exitEq_op(self)




    def eq_op(self):

        localctx = DecafParser.Eq_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 36, self.RULE_eq_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 229
            _la = self._input.LA(1)
            if not(_la==DecafParser.T__30 or _la==DecafParser.T__31):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class Cond_opContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser


        def getRuleIndex(self):
            return DecafParser.RULE_cond_op

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterCond_op" ):
                listener.enterCond_op(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitCond_op" ):
                listener.exitCond_op(self)




    def cond_op(self):

        localctx = DecafParser.Cond_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 38, self.RULE_cond_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 231
            _la = self._input.LA(1)
            if not(_la==DecafParser.T__32 or _la==DecafParser.T__33):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class LiteralContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def int_literal(self):
            return self.getTypedRuleContext(DecafParser.Int_literalContext,0)


        def char_literal(self):
            return self.getTypedRuleContext(DecafParser.Char_literalContext,0)


        def bool_literal(self):
            return self.getTypedRuleContext(DecafParser.Bool_literalContext,0)


        def getRuleIndex(self):
            return DecafParser.RULE_literal

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterLiteral" ):
                listener.enterLiteral(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitLiteral" ):
                listener.exitLiteral(self)




    def literal(self):

        localctx = DecafParser.LiteralContext(self, self._ctx, self.state)
        self.enterRule(localctx, 40, self.RULE_literal)
        try:
            self.state = 236
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [DecafParser.NUM]:
                self.enterOuterAlt(localctx, 1)
                self.state = 233
                self.int_literal()
                pass
            elif token in [DecafParser.APOSTROPHE]:
                self.enterOuterAlt(localctx, 2)
                self.state = 234
                self.char_literal()
                pass
            elif token in [DecafParser.T__34, DecafParser.T__35]:
                self.enterOuterAlt(localctx, 3)
                self.state = 235
                self.bool_literal()
                pass
            else:
                raise NoViableAltException(self)

        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class Int_literalContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def NUM(self):
            return self.getToken(DecafParser.NUM, 0)

        def getRuleIndex(self):
            return DecafParser.RULE_int_literal

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterInt_literal" ):
                listener.enterInt_literal(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitInt_literal" ):
                listener.exitInt_literal(self)




    def int_literal(self):

        localctx = DecafParser.Int_literalContext(self, self._ctx, self.state)
        self.enterRule(localctx, 42, self.RULE_int_literal)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 238
            self.match(DecafParser.NUM)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class Char_literalContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def APOSTROPHE(self, i:int=None):
            if i is None:
                return self.getTokens(DecafParser.APOSTROPHE)
            else:
                return self.getToken(DecafParser.APOSTROPHE, i)

        def CHAR_LITERAL(self):
            return self.getToken(DecafParser.CHAR_LITERAL, 0)

        def getRuleIndex(self):
            return DecafParser.RULE_char_literal

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterChar_literal" ):
                listener.enterChar_literal(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitChar_literal" ):
                listener.exitChar_literal(self)




    def char_literal(self):

        localctx = DecafParser.Char_literalContext(self, self._ctx, self.state)
        self.enterRule(localctx, 44, self.RULE_char_literal)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 240
            self.match(DecafParser.APOSTROPHE)
            self.state = 241
            self.match(DecafParser.CHAR_LITERAL)
            self.state = 242
            self.match(DecafParser.APOSTROPHE)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class Bool_literalContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser


        def getRuleIndex(self):
            return DecafParser.RULE_bool_literal

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterBool_literal" ):
                listener.enterBool_literal(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitBool_literal" ):
                listener.exitBool_literal(self)




    def bool_literal(self):

        localctx = DecafParser.Bool_literalContext(self, self._ctx, self.state)
        self.enterRule(localctx, 46, self.RULE_bool_literal)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 244
            _la = self._input.LA(1)
            if not(_la==DecafParser.T__34 or _la==DecafParser.T__35):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx



    def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int):
        if self._predicates == None:
            self._predicates = dict()
        self._predicates[12] = self.expression_sempred
        pred = self._predicates.get(ruleIndex, None)
        if pred is None:
            raise Exception("No predicate with index:" + str(ruleIndex))
        else:
            return pred(localctx, predIndex)

    def expression_sempred(self, localctx:ExpressionContext, predIndex:int):
            if predIndex == 0:
                return self.precpred(self._ctx, 4)
         




