# Generated from Jack.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\60")
        buf.write("\u0101\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\7")
        buf.write("\2=\n\2\f\2\16\2@\13\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\7\3")
        buf.write("I\n\3\f\3\16\3L\13\3\3\3\3\3\3\4\3\4\3\4\3\4\5\4T\n\4")
        buf.write("\3\5\3\5\3\5\5\5Y\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6")
        buf.write("\3\6\3\6\3\6\3\6\3\6\7\6h\n\6\f\6\16\6k\13\6\5\6m\n\6")
        buf.write("\3\7\3\7\7\7q\n\7\f\7\16\7t\13\7\3\7\3\7\3\7\3\b\3\b\3")
        buf.write("\b\3\b\3\b\7\b~\n\b\f\b\16\b\u0081\13\b\3\b\3\b\3\t\3")
        buf.write("\t\3\n\3\n\3\13\3\13\3\f\7\f\u008c\n\f\f\f\16\f\u008f")
        buf.write("\13\f\3\r\3\r\3\r\3\r\3\r\5\r\u0096\n\r\3\16\3\16\3\16")
        buf.write("\3\16\3\16\3\16\5\16\u009e\n\16\3\16\3\16\3\16\3\16\3")
        buf.write("\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17")
        buf.write("\3\17\5\17\u00b0\n\17\3\20\3\20\3\20\3\20\3\20\3\20\3")
        buf.write("\20\3\20\3\21\3\21\3\21\3\21\3\22\3\22\5\22\u00c0\n\22")
        buf.write("\3\22\3\22\3\23\3\23\3\23\3\23\7\23\u00c8\n\23\f\23\16")
        buf.write("\23\u00cb\13\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24")
        buf.write("\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\5\24\u00de")
        buf.write("\n\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25\5\25\u00e7\n")
        buf.write("\25\3\25\3\25\3\25\3\25\3\25\3\25\5\25\u00ef\n\25\3\26")
        buf.write("\3\26\3\26\7\26\u00f4\n\26\f\26\16\26\u00f7\13\26\5\26")
        buf.write("\u00f9\n\26\3\27\3\27\3\30\3\30\3\31\3\31\3\31\2\2\32")
        buf.write("\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\2")
        buf.write("\7\3\2\6\7\3\2\r\17\4\2\27\27\36%\4\2\37\37&&\3\2\'*\2")
        buf.write("\u0107\2\62\3\2\2\2\4C\3\2\2\2\6S\3\2\2\2\bU\3\2\2\2\n")
        buf.write("l\3\2\2\2\fn\3\2\2\2\16x\3\2\2\2\20\u0084\3\2\2\2\22\u0086")
        buf.write("\3\2\2\2\24\u0088\3\2\2\2\26\u008d\3\2\2\2\30\u0095\3")
        buf.write("\2\2\2\32\u0097\3\2\2\2\34\u00a3\3\2\2\2\36\u00b1\3\2")
        buf.write("\2\2 \u00b9\3\2\2\2\"\u00bd\3\2\2\2$\u00c3\3\2\2\2&\u00dd")
        buf.write("\3\2\2\2(\u00ee\3\2\2\2*\u00f8\3\2\2\2,\u00fa\3\2\2\2")
        buf.write(".\u00fc\3\2\2\2\60\u00fe\3\2\2\2\62\63\7\3\2\2\63\64\5")
        buf.write("\20\t\2\648\7\4\2\2\65\67\5\4\3\2\66\65\3\2\2\2\67:\3")
        buf.write("\2\2\28\66\3\2\2\289\3\2\2\29>\3\2\2\2:8\3\2\2\2;=\5\b")
        buf.write("\5\2<;\3\2\2\2=@\3\2\2\2><\3\2\2\2>?\3\2\2\2?A\3\2\2\2")
        buf.write("@>\3\2\2\2AB\7\5\2\2B\3\3\2\2\2CD\t\2\2\2DE\5\6\4\2EJ")
        buf.write("\5\24\13\2FG\7\b\2\2GI\5\24\13\2HF\3\2\2\2IL\3\2\2\2J")
        buf.write("H\3\2\2\2JK\3\2\2\2KM\3\2\2\2LJ\3\2\2\2MN\7\t\2\2N\5\3")
        buf.write("\2\2\2OT\7\n\2\2PT\7\13\2\2QT\7\f\2\2RT\5\20\t\2SO\3\2")
        buf.write("\2\2SP\3\2\2\2SQ\3\2\2\2SR\3\2\2\2T\7\3\2\2\2UX\t\3\2")
        buf.write("\2VY\7\20\2\2WY\5\6\4\2XV\3\2\2\2XW\3\2\2\2YZ\3\2\2\2")
        buf.write("Z[\5\22\n\2[\\\7\21\2\2\\]\5\n\6\2]^\7\22\2\2^_\5\f\7")
        buf.write("\2_\t\3\2\2\2`a\5\6\4\2ab\5\24\13\2bi\3\2\2\2cd\7\b\2")
        buf.write("\2de\5\6\4\2ef\5\24\13\2fh\3\2\2\2gc\3\2\2\2hk\3\2\2\2")
        buf.write("ig\3\2\2\2ij\3\2\2\2jm\3\2\2\2ki\3\2\2\2l`\3\2\2\2lm\3")
        buf.write("\2\2\2m\13\3\2\2\2nr\7\4\2\2oq\5\16\b\2po\3\2\2\2qt\3")
        buf.write("\2\2\2rp\3\2\2\2rs\3\2\2\2su\3\2\2\2tr\3\2\2\2uv\5\26")
        buf.write("\f\2vw\7\5\2\2w\r\3\2\2\2xy\7\23\2\2yz\5\6\4\2z\177\5")
        buf.write("\24\13\2{|\7\b\2\2|~\5\24\13\2}{\3\2\2\2~\u0081\3\2\2")
        buf.write("\2\177}\3\2\2\2\177\u0080\3\2\2\2\u0080\u0082\3\2\2\2")
        buf.write("\u0081\177\3\2\2\2\u0082\u0083\7\t\2\2\u0083\17\3\2\2")
        buf.write("\2\u0084\u0085\7-\2\2\u0085\21\3\2\2\2\u0086\u0087\7-")
        buf.write("\2\2\u0087\23\3\2\2\2\u0088\u0089\7-\2\2\u0089\25\3\2")
        buf.write("\2\2\u008a\u008c\5\30\r\2\u008b\u008a\3\2\2\2\u008c\u008f")
        buf.write("\3\2\2\2\u008d\u008b\3\2\2\2\u008d\u008e\3\2\2\2\u008e")
        buf.write("\27\3\2\2\2\u008f\u008d\3\2\2\2\u0090\u0096\5\32\16\2")
        buf.write("\u0091\u0096\5\34\17\2\u0092\u0096\5\36\20\2\u0093\u0096")
        buf.write("\5 \21\2\u0094\u0096\5\"\22\2\u0095\u0090\3\2\2\2\u0095")
        buf.write("\u0091\3\2\2\2\u0095\u0092\3\2\2\2\u0095\u0093\3\2\2\2")
        buf.write("\u0095\u0094\3\2\2\2\u0096\31\3\2\2\2\u0097\u0098\7\24")
        buf.write("\2\2\u0098\u009d\5\24\13\2\u0099\u009a\7\25\2\2\u009a")
        buf.write("\u009b\5$\23\2\u009b\u009c\7\26\2\2\u009c\u009e\3\2\2")
        buf.write("\2\u009d\u0099\3\2\2\2\u009d\u009e\3\2\2\2\u009e\u009f")
        buf.write("\3\2\2\2\u009f\u00a0\7\27\2\2\u00a0\u00a1\5$\23\2\u00a1")
        buf.write("\u00a2\7\t\2\2\u00a2\33\3\2\2\2\u00a3\u00a4\7\30\2\2\u00a4")
        buf.write("\u00a5\7\21\2\2\u00a5\u00a6\5$\23\2\u00a6\u00a7\7\22\2")
        buf.write("\2\u00a7\u00a8\7\4\2\2\u00a8\u00a9\5\26\f\2\u00a9\u00af")
        buf.write("\7\5\2\2\u00aa\u00ab\7\31\2\2\u00ab\u00ac\7\4\2\2\u00ac")
        buf.write("\u00ad\5\26\f\2\u00ad\u00ae\7\5\2\2\u00ae\u00b0\3\2\2")
        buf.write("\2\u00af\u00aa\3\2\2\2\u00af\u00b0\3\2\2\2\u00b0\35\3")
        buf.write("\2\2\2\u00b1\u00b2\7\32\2\2\u00b2\u00b3\7\21\2\2\u00b3")
        buf.write("\u00b4\5$\23\2\u00b4\u00b5\7\22\2\2\u00b5\u00b6\7\4\2")
        buf.write("\2\u00b6\u00b7\5\26\f\2\u00b7\u00b8\7\5\2\2\u00b8\37\3")
        buf.write("\2\2\2\u00b9\u00ba\7\33\2\2\u00ba\u00bb\5(\25\2\u00bb")
        buf.write("\u00bc\7\t\2\2\u00bc!\3\2\2\2\u00bd\u00bf\7\34\2\2\u00be")
        buf.write("\u00c0\5$\23\2\u00bf\u00be\3\2\2\2\u00bf\u00c0\3\2\2\2")
        buf.write("\u00c0\u00c1\3\2\2\2\u00c1\u00c2\7\t\2\2\u00c2#\3\2\2")
        buf.write("\2\u00c3\u00c9\5&\24\2\u00c4\u00c5\5,\27\2\u00c5\u00c6")
        buf.write("\5&\24\2\u00c6\u00c8\3\2\2\2\u00c7\u00c4\3\2\2\2\u00c8")
        buf.write("\u00cb\3\2\2\2\u00c9\u00c7\3\2\2\2\u00c9\u00ca\3\2\2\2")
        buf.write("\u00ca%\3\2\2\2\u00cb\u00c9\3\2\2\2\u00cc\u00de\7+\2\2")
        buf.write("\u00cd\u00de\7,\2\2\u00ce\u00de\5\60\31\2\u00cf\u00de")
        buf.write("\5\24\13\2\u00d0\u00d1\5\24\13\2\u00d1\u00d2\7\25\2\2")
        buf.write("\u00d2\u00d3\5$\23\2\u00d3\u00d4\7\26\2\2\u00d4\u00de")
        buf.write("\3\2\2\2\u00d5\u00de\5(\25\2\u00d6\u00d7\7\21\2\2\u00d7")
        buf.write("\u00d8\5$\23\2\u00d8\u00d9\7\22\2\2\u00d9\u00de\3\2\2")
        buf.write("\2\u00da\u00db\5.\30\2\u00db\u00dc\5&\24\2\u00dc\u00de")
        buf.write("\3\2\2\2\u00dd\u00cc\3\2\2\2\u00dd\u00cd\3\2\2\2\u00dd")
        buf.write("\u00ce\3\2\2\2\u00dd\u00cf\3\2\2\2\u00dd\u00d0\3\2\2\2")
        buf.write("\u00dd\u00d5\3\2\2\2\u00dd\u00d6\3\2\2\2\u00dd\u00da\3")
        buf.write("\2\2\2\u00de\'\3\2\2\2\u00df\u00e0\5\22\n\2\u00e0\u00e1")
        buf.write("\7\21\2\2\u00e1\u00e2\5*\26\2\u00e2\u00e3\7\22\2\2\u00e3")
        buf.write("\u00ef\3\2\2\2\u00e4\u00e7\5\20\t\2\u00e5\u00e7\5\24\13")
        buf.write("\2\u00e6\u00e4\3\2\2\2\u00e6\u00e5\3\2\2\2\u00e7\u00e8")
        buf.write("\3\2\2\2\u00e8\u00e9\7\35\2\2\u00e9\u00ea\5\22\n\2\u00ea")
        buf.write("\u00eb\7\21\2\2\u00eb\u00ec\5*\26\2\u00ec\u00ed\7\22\2")
        buf.write("\2\u00ed\u00ef\3\2\2\2\u00ee\u00df\3\2\2\2\u00ee\u00e6")
        buf.write("\3\2\2\2\u00ef)\3\2\2\2\u00f0\u00f5\5$\23\2\u00f1\u00f2")
        buf.write("\7\b\2\2\u00f2\u00f4\5$\23\2\u00f3\u00f1\3\2\2\2\u00f4")
        buf.write("\u00f7\3\2\2\2\u00f5\u00f3\3\2\2\2\u00f5\u00f6\3\2\2\2")
        buf.write("\u00f6\u00f9\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f8\u00f0\3")
        buf.write("\2\2\2\u00f8\u00f9\3\2\2\2\u00f9+\3\2\2\2\u00fa\u00fb")
        buf.write("\t\4\2\2\u00fb-\3\2\2\2\u00fc\u00fd\t\5\2\2\u00fd/\3\2")
        buf.write("\2\2\u00fe\u00ff\t\6\2\2\u00ff\61\3\2\2\2\268>JSXilr\177")
        buf.write("\u008d\u0095\u009d\u00af\u00bf\u00c9\u00dd\u00e6\u00ee")
        buf.write("\u00f5\u00f8")
        return buf.getvalue()


class JackParser ( Parser ):

    grammarFileName = "Jack.g4"

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

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

    sharedContextCache = PredictionContextCache()

    literalNames = [ "<INVALID>", "'class'", "'{'", "'}'", "'static'", "'field'", 
                     "','", "';'", "'int'", "'char'", "'boolean'", "'constructor'", 
                     "'function'", "'method'", "'void'", "'('", "')'", "'var'", 
                     "'let'", "'['", "']'", "'='", "'if'", "'else'", "'while'", 
                     "'do'", "'return'", "'.'", "'+'", "'-'", "'*'", "'/'", 
                     "'&'", "'|'", "'<'", "'>'", "'~'", "'true'", "'false'", 
                     "'null'", "'this'" ]

    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>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "INTEGERCONSTANT", "STRINGCONSTANT", 
                      "IDENTIFIER", "WHITESPACE", "INLINECOMENT", "DOCCOMENT" ]

    RULE_classNT = 0
    RULE_classVarDecNT = 1
    RULE_typeNT = 2
    RULE_subroutineDecNT = 3
    RULE_parameterListNT = 4
    RULE_subroutineBodyNT = 5
    RULE_varDecNT = 6
    RULE_classNameNT = 7
    RULE_subroutineNameNT = 8
    RULE_varNameNT = 9
    RULE_statementsNT = 10
    RULE_statementNT = 11
    RULE_letStatementNT = 12
    RULE_ifStatementNT = 13
    RULE_whileStatementNT = 14
    RULE_doStatementNT = 15
    RULE_returnStatementNT = 16
    RULE_expressionNT = 17
    RULE_termNT = 18
    RULE_subroutineCallNT = 19
    RULE_expressionListNT = 20
    RULE_opNT = 21
    RULE_unaryOpNT = 22
    RULE_keywordConstantNT = 23

    ruleNames =  [ "classNT", "classVarDecNT", "typeNT", "subroutineDecNT", 
                   "parameterListNT", "subroutineBodyNT", "varDecNT", "classNameNT", 
                   "subroutineNameNT", "varNameNT", "statementsNT", "statementNT", 
                   "letStatementNT", "ifStatementNT", "whileStatementNT", 
                   "doStatementNT", "returnStatementNT", "expressionNT", 
                   "termNT", "subroutineCallNT", "expressionListNT", "opNT", 
                   "unaryOpNT", "keywordConstantNT" ]

    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
    T__36=37
    T__37=38
    T__38=39
    T__39=40
    INTEGERCONSTANT=41
    STRINGCONSTANT=42
    IDENTIFIER=43
    WHITESPACE=44
    INLINECOMENT=45
    DOCCOMENT=46

    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 ClassNTContext(ParserRuleContext):

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

        def classNameNT(self):
            return self.getTypedRuleContext(JackParser.ClassNameNTContext,0)


        def classVarDecNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.ClassVarDecNTContext)
            else:
                return self.getTypedRuleContext(JackParser.ClassVarDecNTContext,i)


        def subroutineDecNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.SubroutineDecNTContext)
            else:
                return self.getTypedRuleContext(JackParser.SubroutineDecNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_classNT

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

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




    def classNT(self):

        localctx = JackParser.ClassNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 0, self.RULE_classNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 48
            self.match(JackParser.T__0)
            self.state = 49
            self.classNameNT()
            self.state = 50
            self.match(JackParser.T__1)
            self.state = 54
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while _la==JackParser.T__3 or _la==JackParser.T__4:
                self.state = 51
                self.classVarDecNT()
                self.state = 56
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 60
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__10) | (1 << JackParser.T__11) | (1 << JackParser.T__12))) != 0):
                self.state = 57
                self.subroutineDecNT()
                self.state = 62
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 63
            self.match(JackParser.T__2)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class ClassVarDecNTContext(ParserRuleContext):

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

        def typeNT(self):
            return self.getTypedRuleContext(JackParser.TypeNTContext,0)


        def varNameNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.VarNameNTContext)
            else:
                return self.getTypedRuleContext(JackParser.VarNameNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_classVarDecNT

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

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




    def classVarDecNT(self):

        localctx = JackParser.ClassVarDecNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 2, self.RULE_classVarDecNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 65
            _la = self._input.LA(1)
            if not(_la==JackParser.T__3 or _la==JackParser.T__4):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
            self.state = 66
            self.typeNT()
            self.state = 67
            self.varNameNT()
            self.state = 72
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while _la==JackParser.T__5:
                self.state = 68
                self.match(JackParser.T__5)
                self.state = 69
                self.varNameNT()
                self.state = 74
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 75
            self.match(JackParser.T__6)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class TypeNTContext(ParserRuleContext):

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

        def classNameNT(self):
            return self.getTypedRuleContext(JackParser.ClassNameNTContext,0)


        def getRuleIndex(self):
            return JackParser.RULE_typeNT

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

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




    def typeNT(self):

        localctx = JackParser.TypeNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 4, self.RULE_typeNT)
        try:
            self.state = 81
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [JackParser.T__7]:
                self.enterOuterAlt(localctx, 1)
                self.state = 77
                self.match(JackParser.T__7)
                pass
            elif token in [JackParser.T__8]:
                self.enterOuterAlt(localctx, 2)
                self.state = 78
                self.match(JackParser.T__8)
                pass
            elif token in [JackParser.T__9]:
                self.enterOuterAlt(localctx, 3)
                self.state = 79
                self.match(JackParser.T__9)
                pass
            elif token in [JackParser.IDENTIFIER]:
                self.enterOuterAlt(localctx, 4)
                self.state = 80
                self.classNameNT()
                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 SubroutineDecNTContext(ParserRuleContext):

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

        def subroutineNameNT(self):
            return self.getTypedRuleContext(JackParser.SubroutineNameNTContext,0)


        def parameterListNT(self):
            return self.getTypedRuleContext(JackParser.ParameterListNTContext,0)


        def subroutineBodyNT(self):
            return self.getTypedRuleContext(JackParser.SubroutineBodyNTContext,0)


        def typeNT(self):
            return self.getTypedRuleContext(JackParser.TypeNTContext,0)


        def getRuleIndex(self):
            return JackParser.RULE_subroutineDecNT

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

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




    def subroutineDecNT(self):

        localctx = JackParser.SubroutineDecNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 6, self.RULE_subroutineDecNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 83
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__10) | (1 << JackParser.T__11) | (1 << JackParser.T__12))) != 0)):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
            self.state = 86
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [JackParser.T__13]:
                self.state = 84
                self.match(JackParser.T__13)
                pass
            elif token in [JackParser.T__7, JackParser.T__8, JackParser.T__9, JackParser.IDENTIFIER]:
                self.state = 85
                self.typeNT()
                pass
            else:
                raise NoViableAltException(self)

            self.state = 88
            self.subroutineNameNT()
            self.state = 89
            self.match(JackParser.T__14)
            self.state = 90
            self.parameterListNT()
            self.state = 91
            self.match(JackParser.T__15)
            self.state = 92
            self.subroutineBodyNT()
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class ParameterListNTContext(ParserRuleContext):

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

        def typeNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.TypeNTContext)
            else:
                return self.getTypedRuleContext(JackParser.TypeNTContext,i)


        def varNameNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.VarNameNTContext)
            else:
                return self.getTypedRuleContext(JackParser.VarNameNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_parameterListNT

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

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




    def parameterListNT(self):

        localctx = JackParser.ParameterListNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 8, self.RULE_parameterListNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 106
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__7) | (1 << JackParser.T__8) | (1 << JackParser.T__9) | (1 << JackParser.IDENTIFIER))) != 0):
                self.state = 94
                self.typeNT()
                self.state = 95
                self.varNameNT()
                self.state = 103
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==JackParser.T__5:
                    self.state = 97
                    self.match(JackParser.T__5)
                    self.state = 98
                    self.typeNT()
                    self.state = 99
                    self.varNameNT()
                    self.state = 105
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)



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


    class SubroutineBodyNTContext(ParserRuleContext):

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

        def statementsNT(self):
            return self.getTypedRuleContext(JackParser.StatementsNTContext,0)


        def varDecNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.VarDecNTContext)
            else:
                return self.getTypedRuleContext(JackParser.VarDecNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_subroutineBodyNT

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

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




    def subroutineBodyNT(self):

        localctx = JackParser.SubroutineBodyNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 10, self.RULE_subroutineBodyNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 108
            self.match(JackParser.T__1)
            self.state = 112
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while _la==JackParser.T__16:
                self.state = 109
                self.varDecNT()
                self.state = 114
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 115
            self.statementsNT()
            self.state = 116
            self.match(JackParser.T__2)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class VarDecNTContext(ParserRuleContext):

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

        def typeNT(self):
            return self.getTypedRuleContext(JackParser.TypeNTContext,0)


        def varNameNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.VarNameNTContext)
            else:
                return self.getTypedRuleContext(JackParser.VarNameNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_varDecNT

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

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




    def varDecNT(self):

        localctx = JackParser.VarDecNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 12, self.RULE_varDecNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 118
            self.match(JackParser.T__16)
            self.state = 119
            self.typeNT()
            self.state = 120
            self.varNameNT()
            self.state = 125
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while _la==JackParser.T__5:
                self.state = 121
                self.match(JackParser.T__5)
                self.state = 122
                self.varNameNT()
                self.state = 127
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 128
            self.match(JackParser.T__6)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class ClassNameNTContext(ParserRuleContext):

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

        def IDENTIFIER(self):
            return self.getToken(JackParser.IDENTIFIER, 0)

        def getRuleIndex(self):
            return JackParser.RULE_classNameNT

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

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




    def classNameNT(self):

        localctx = JackParser.ClassNameNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 14, self.RULE_classNameNT)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 130
            self.match(JackParser.IDENTIFIER)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class SubroutineNameNTContext(ParserRuleContext):

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

        def IDENTIFIER(self):
            return self.getToken(JackParser.IDENTIFIER, 0)

        def getRuleIndex(self):
            return JackParser.RULE_subroutineNameNT

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

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




    def subroutineNameNT(self):

        localctx = JackParser.SubroutineNameNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 16, self.RULE_subroutineNameNT)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 132
            self.match(JackParser.IDENTIFIER)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class VarNameNTContext(ParserRuleContext):

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

        def IDENTIFIER(self):
            return self.getToken(JackParser.IDENTIFIER, 0)

        def getRuleIndex(self):
            return JackParser.RULE_varNameNT

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

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




    def varNameNT(self):

        localctx = JackParser.VarNameNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 18, self.RULE_varNameNT)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 134
            self.match(JackParser.IDENTIFIER)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class StatementsNTContext(ParserRuleContext):

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

        def statementNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.StatementNTContext)
            else:
                return self.getTypedRuleContext(JackParser.StatementNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_statementsNT

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

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




    def statementsNT(self):

        localctx = JackParser.StatementsNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 20, self.RULE_statementsNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 139
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__17) | (1 << JackParser.T__21) | (1 << JackParser.T__23) | (1 << JackParser.T__24) | (1 << JackParser.T__25))) != 0):
                self.state = 136
                self.statementNT()
                self.state = 141
                self._errHandler.sync(self)
                _la = self._input.LA(1)

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


    class StatementNTContext(ParserRuleContext):

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

        def letStatementNT(self):
            return self.getTypedRuleContext(JackParser.LetStatementNTContext,0)


        def ifStatementNT(self):
            return self.getTypedRuleContext(JackParser.IfStatementNTContext,0)


        def whileStatementNT(self):
            return self.getTypedRuleContext(JackParser.WhileStatementNTContext,0)


        def doStatementNT(self):
            return self.getTypedRuleContext(JackParser.DoStatementNTContext,0)


        def returnStatementNT(self):
            return self.getTypedRuleContext(JackParser.ReturnStatementNTContext,0)


        def getRuleIndex(self):
            return JackParser.RULE_statementNT

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

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




    def statementNT(self):

        localctx = JackParser.StatementNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 22, self.RULE_statementNT)
        try:
            self.state = 147
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [JackParser.T__17]:
                self.enterOuterAlt(localctx, 1)
                self.state = 142
                self.letStatementNT()
                pass
            elif token in [JackParser.T__21]:
                self.enterOuterAlt(localctx, 2)
                self.state = 143
                self.ifStatementNT()
                pass
            elif token in [JackParser.T__23]:
                self.enterOuterAlt(localctx, 3)
                self.state = 144
                self.whileStatementNT()
                pass
            elif token in [JackParser.T__24]:
                self.enterOuterAlt(localctx, 4)
                self.state = 145
                self.doStatementNT()
                pass
            elif token in [JackParser.T__25]:
                self.enterOuterAlt(localctx, 5)
                self.state = 146
                self.returnStatementNT()
                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 LetStatementNTContext(ParserRuleContext):

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

        def varNameNT(self):
            return self.getTypedRuleContext(JackParser.VarNameNTContext,0)


        def expressionNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.ExpressionNTContext)
            else:
                return self.getTypedRuleContext(JackParser.ExpressionNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_letStatementNT

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

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




    def letStatementNT(self):

        localctx = JackParser.LetStatementNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 24, self.RULE_letStatementNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 149
            self.match(JackParser.T__17)
            self.state = 150
            self.varNameNT()
            self.state = 155
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==JackParser.T__18:
                self.state = 151
                self.match(JackParser.T__18)
                self.state = 152
                self.expressionNT()
                self.state = 153
                self.match(JackParser.T__19)


            self.state = 157
            self.match(JackParser.T__20)
            self.state = 158
            self.expressionNT()
            self.state = 159
            self.match(JackParser.T__6)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class IfStatementNTContext(ParserRuleContext):

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

        def expressionNT(self):
            return self.getTypedRuleContext(JackParser.ExpressionNTContext,0)


        def statementsNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.StatementsNTContext)
            else:
                return self.getTypedRuleContext(JackParser.StatementsNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_ifStatementNT

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

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




    def ifStatementNT(self):

        localctx = JackParser.IfStatementNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 26, self.RULE_ifStatementNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 161
            self.match(JackParser.T__21)
            self.state = 162
            self.match(JackParser.T__14)
            self.state = 163
            self.expressionNT()
            self.state = 164
            self.match(JackParser.T__15)
            self.state = 165
            self.match(JackParser.T__1)
            self.state = 166
            self.statementsNT()
            self.state = 167
            self.match(JackParser.T__2)
            self.state = 173
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==JackParser.T__22:
                self.state = 168
                self.match(JackParser.T__22)
                self.state = 169
                self.match(JackParser.T__1)
                self.state = 170
                self.statementsNT()
                self.state = 171
                self.match(JackParser.T__2)


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


    class WhileStatementNTContext(ParserRuleContext):

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

        def expressionNT(self):
            return self.getTypedRuleContext(JackParser.ExpressionNTContext,0)


        def statementsNT(self):
            return self.getTypedRuleContext(JackParser.StatementsNTContext,0)


        def getRuleIndex(self):
            return JackParser.RULE_whileStatementNT

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

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




    def whileStatementNT(self):

        localctx = JackParser.WhileStatementNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 28, self.RULE_whileStatementNT)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 175
            self.match(JackParser.T__23)
            self.state = 176
            self.match(JackParser.T__14)
            self.state = 177
            self.expressionNT()
            self.state = 178
            self.match(JackParser.T__15)
            self.state = 179
            self.match(JackParser.T__1)
            self.state = 180
            self.statementsNT()
            self.state = 181
            self.match(JackParser.T__2)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class DoStatementNTContext(ParserRuleContext):

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

        def subroutineCallNT(self):
            return self.getTypedRuleContext(JackParser.SubroutineCallNTContext,0)


        def getRuleIndex(self):
            return JackParser.RULE_doStatementNT

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

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




    def doStatementNT(self):

        localctx = JackParser.DoStatementNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 30, self.RULE_doStatementNT)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 183
            self.match(JackParser.T__24)
            self.state = 184
            self.subroutineCallNT()
            self.state = 185
            self.match(JackParser.T__6)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class ReturnStatementNTContext(ParserRuleContext):

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

        def expressionNT(self):
            return self.getTypedRuleContext(JackParser.ExpressionNTContext,0)


        def getRuleIndex(self):
            return JackParser.RULE_returnStatementNT

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

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




    def returnStatementNT(self):

        localctx = JackParser.ReturnStatementNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 32, self.RULE_returnStatementNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 187
            self.match(JackParser.T__25)
            self.state = 189
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__14) | (1 << JackParser.T__28) | (1 << JackParser.T__35) | (1 << JackParser.T__36) | (1 << JackParser.T__37) | (1 << JackParser.T__38) | (1 << JackParser.T__39) | (1 << JackParser.INTEGERCONSTANT) | (1 << JackParser.STRINGCONSTANT) | (1 << JackParser.IDENTIFIER))) != 0):
                self.state = 188
                self.expressionNT()


            self.state = 191
            self.match(JackParser.T__6)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class ExpressionNTContext(ParserRuleContext):

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

        def termNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.TermNTContext)
            else:
                return self.getTypedRuleContext(JackParser.TermNTContext,i)


        def opNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.OpNTContext)
            else:
                return self.getTypedRuleContext(JackParser.OpNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_expressionNT

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

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




    def expressionNT(self):

        localctx = JackParser.ExpressionNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 34, self.RULE_expressionNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 193
            self.termNT()
            self.state = 199
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__20) | (1 << JackParser.T__27) | (1 << JackParser.T__28) | (1 << JackParser.T__29) | (1 << JackParser.T__30) | (1 << JackParser.T__31) | (1 << JackParser.T__32) | (1 << JackParser.T__33) | (1 << JackParser.T__34))) != 0):
                self.state = 194
                self.opNT()
                self.state = 195
                self.termNT()
                self.state = 201
                self._errHandler.sync(self)
                _la = self._input.LA(1)

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


    class TermNTContext(ParserRuleContext):

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

        def INTEGERCONSTANT(self):
            return self.getToken(JackParser.INTEGERCONSTANT, 0)

        def STRINGCONSTANT(self):
            return self.getToken(JackParser.STRINGCONSTANT, 0)

        def keywordConstantNT(self):
            return self.getTypedRuleContext(JackParser.KeywordConstantNTContext,0)


        def varNameNT(self):
            return self.getTypedRuleContext(JackParser.VarNameNTContext,0)


        def expressionNT(self):
            return self.getTypedRuleContext(JackParser.ExpressionNTContext,0)


        def subroutineCallNT(self):
            return self.getTypedRuleContext(JackParser.SubroutineCallNTContext,0)


        def unaryOpNT(self):
            return self.getTypedRuleContext(JackParser.UnaryOpNTContext,0)


        def termNT(self):
            return self.getTypedRuleContext(JackParser.TermNTContext,0)


        def getRuleIndex(self):
            return JackParser.RULE_termNT

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

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




    def termNT(self):

        localctx = JackParser.TermNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 36, self.RULE_termNT)
        try:
            self.state = 219
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,15,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 202
                self.match(JackParser.INTEGERCONSTANT)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 203
                self.match(JackParser.STRINGCONSTANT)
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 204
                self.keywordConstantNT()
                pass

            elif la_ == 4:
                self.enterOuterAlt(localctx, 4)
                self.state = 205
                self.varNameNT()
                pass

            elif la_ == 5:
                self.enterOuterAlt(localctx, 5)
                self.state = 206
                self.varNameNT()
                self.state = 207
                self.match(JackParser.T__18)
                self.state = 208
                self.expressionNT()
                self.state = 209
                self.match(JackParser.T__19)
                pass

            elif la_ == 6:
                self.enterOuterAlt(localctx, 6)
                self.state = 211
                self.subroutineCallNT()
                pass

            elif la_ == 7:
                self.enterOuterAlt(localctx, 7)
                self.state = 212
                self.match(JackParser.T__14)
                self.state = 213
                self.expressionNT()
                self.state = 214
                self.match(JackParser.T__15)
                pass

            elif la_ == 8:
                self.enterOuterAlt(localctx, 8)
                self.state = 216
                self.unaryOpNT()
                self.state = 217
                self.termNT()
                pass


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


    class SubroutineCallNTContext(ParserRuleContext):

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

        def subroutineNameNT(self):
            return self.getTypedRuleContext(JackParser.SubroutineNameNTContext,0)


        def expressionListNT(self):
            return self.getTypedRuleContext(JackParser.ExpressionListNTContext,0)


        def classNameNT(self):
            return self.getTypedRuleContext(JackParser.ClassNameNTContext,0)


        def varNameNT(self):
            return self.getTypedRuleContext(JackParser.VarNameNTContext,0)


        def getRuleIndex(self):
            return JackParser.RULE_subroutineCallNT

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

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




    def subroutineCallNT(self):

        localctx = JackParser.SubroutineCallNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 38, self.RULE_subroutineCallNT)
        try:
            self.state = 236
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,17,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 221
                self.subroutineNameNT()
                self.state = 222
                self.match(JackParser.T__14)
                self.state = 223
                self.expressionListNT()
                self.state = 224
                self.match(JackParser.T__15)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 228
                self._errHandler.sync(self)
                la_ = self._interp.adaptivePredict(self._input,16,self._ctx)
                if la_ == 1:
                    self.state = 226
                    self.classNameNT()
                    pass

                elif la_ == 2:
                    self.state = 227
                    self.varNameNT()
                    pass


                self.state = 230
                self.match(JackParser.T__26)
                self.state = 231
                self.subroutineNameNT()
                self.state = 232
                self.match(JackParser.T__14)
                self.state = 233
                self.expressionListNT()
                self.state = 234
                self.match(JackParser.T__15)
                pass


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


    class ExpressionListNTContext(ParserRuleContext):

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

        def expressionNT(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(JackParser.ExpressionNTContext)
            else:
                return self.getTypedRuleContext(JackParser.ExpressionNTContext,i)


        def getRuleIndex(self):
            return JackParser.RULE_expressionListNT

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

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




    def expressionListNT(self):

        localctx = JackParser.ExpressionListNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 40, self.RULE_expressionListNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 246
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__14) | (1 << JackParser.T__28) | (1 << JackParser.T__35) | (1 << JackParser.T__36) | (1 << JackParser.T__37) | (1 << JackParser.T__38) | (1 << JackParser.T__39) | (1 << JackParser.INTEGERCONSTANT) | (1 << JackParser.STRINGCONSTANT) | (1 << JackParser.IDENTIFIER))) != 0):
                self.state = 238
                self.expressionNT()
                self.state = 243
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==JackParser.T__5:
                    self.state = 239
                    self.match(JackParser.T__5)
                    self.state = 240
                    self.expressionNT()
                    self.state = 245
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)



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


    class OpNTContext(ParserRuleContext):

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


        def getRuleIndex(self):
            return JackParser.RULE_opNT

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

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




    def opNT(self):

        localctx = JackParser.OpNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 42, self.RULE_opNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 248
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__20) | (1 << JackParser.T__27) | (1 << JackParser.T__28) | (1 << JackParser.T__29) | (1 << JackParser.T__30) | (1 << JackParser.T__31) | (1 << JackParser.T__32) | (1 << JackParser.T__33) | (1 << JackParser.T__34))) != 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 UnaryOpNTContext(ParserRuleContext):

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


        def getRuleIndex(self):
            return JackParser.RULE_unaryOpNT

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

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




    def unaryOpNT(self):

        localctx = JackParser.UnaryOpNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 44, self.RULE_unaryOpNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 250
            _la = self._input.LA(1)
            if not(_la==JackParser.T__28 or _la==JackParser.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


    class KeywordConstantNTContext(ParserRuleContext):

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


        def getRuleIndex(self):
            return JackParser.RULE_keywordConstantNT

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

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




    def keywordConstantNT(self):

        localctx = JackParser.KeywordConstantNTContext(self, self._ctx, self.state)
        self.enterRule(localctx, 46, self.RULE_keywordConstantNT)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 252
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << JackParser.T__36) | (1 << JackParser.T__37) | (1 << JackParser.T__38) | (1 << JackParser.T__39))) != 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





