<filename>decafAlejandroV2Parser.py
# Generated from decafAlejandroV2.g4 by ANTLR 4.9.2
# encoding: utf-8
from antlr4 import *
from io import StringIO
import sys
if sys.version_info[1] > 5:
	from typing import TextIO
else:
	from typing.io import TextIO


def serializedATN():
    with StringIO() as buf:
        buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3:")
        buf.write("\u0125\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\4\32\t\32\4\33\t\33\3\2\3\2\3\2\3\2\7\2;\n\2\f\2")
        buf.write("\16\2>\13\2\3\2\3\2\3\3\3\3\3\3\3\3\5\3F\n\3\3\4\3\4\3")
        buf.write("\4\3\4\3\5\3\5\3\5\3\5\7\5P\n\5\f\5\16\5S\13\5\3\5\3\5")
        buf.write("\3\6\3\6\3\6\3\6\5\6[\n\6\3\6\3\6\3\6\5\6`\n\6\3\7\3\7")
        buf.write("\5\7d\n\7\3\b\3\b\3\b\5\bi\n\b\3\t\3\t\3\t\3\t\7\to\n")
        buf.write("\t\f\t\16\tr\13\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n")
        buf.write("\3\n\5\n~\n\n\3\n\3\n\3\n\3\n\7\n\u0084\n\n\f\n\16\n\u0087")
        buf.write("\13\n\5\n\u0089\n\n\3\n\3\n\3\n\3\13\3\13\5\13\u0090\n")
        buf.write("\13\3\f\3\f\7\f\u0094\n\f\f\f\16\f\u0097\13\f\3\f\7\f")
        buf.write("\u009a\n\f\f\f\16\f\u009d\13\f\3\f\3\f\3\r\3\r\3\r\3\r")
        buf.write("\5\r\u00a5\n\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\5\r\u00af")
        buf.write("\n\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3")
        buf.write("\r\3\r\5\r\u00bf\n\r\3\r\3\r\3\r\3\r\5\r\u00c5\n\r\3\r")
        buf.write("\5\r\u00c8\n\r\3\r\3\r\3\r\3\r\5\r\u00ce\n\r\3\16\3\16")
        buf.write("\3\16\3\16\3\16\7\16\u00d5\n\16\f\16\16\16\u00d8\13\16")
        buf.write("\5\16\u00da\n\16\3\16\3\16\5\16\u00de\n\16\3\17\3\17\3")
        buf.write("\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\5\17")
        buf.write("\u00ec\n\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3")
        buf.write("\17\3\17\3\17\5\17\u00f9\n\17\3\17\3\17\7\17\u00fd\n\17")
        buf.write("\f\17\16\17\u0100\13\17\3\20\3\20\5\20\u0104\n\20\3\21")
        buf.write("\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26")
        buf.write("\3\27\3\27\3\27\5\27\u0115\n\27\3\30\3\30\3\31\3\31\3")
        buf.write("\31\3\31\3\31\3\31\5\31\u011f\n\31\3\32\3\32\3\33\3\33")
        buf.write("\3\33\2\3\34\34\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36")
        buf.write(" \"$&(*,.\60\62\64\2\n\3\2 \"\3\2\36\37\3\2\17\20\3\2")
        buf.write("&)\3\2-.\3\2#$\3\2\36\"\3\2*,\2\u013a\2\66\3\2\2\2\4E")
        buf.write("\3\2\2\2\6G\3\2\2\2\bK\3\2\2\2\nV\3\2\2\2\fc\3\2\2\2\16")
        buf.write("e\3\2\2\2\20j\3\2\2\2\22v\3\2\2\2\24\u008f\3\2\2\2\26")
        buf.write("\u0091\3\2\2\2\30\u00cd\3\2\2\2\32\u00cf\3\2\2\2\34\u00eb")
        buf.write("\3\2\2\2\36\u0103\3\2\2\2 \u0105\3\2\2\2\"\u0107\3\2\2")
        buf.write("\2$\u0109\3\2\2\2&\u010b\3\2\2\2(\u010d\3\2\2\2*\u010f")
        buf.write("\3\2\2\2,\u0114\3\2\2\2.\u0116\3\2\2\2\60\u011e\3\2\2")
        buf.write("\2\62\u0120\3\2\2\2\64\u0122\3\2\2\2\66\67\7\3\2\2\67")
        buf.write("8\7\4\2\28<\7\25\2\29;\5\4\3\2:9\3\2\2\2;>\3\2\2\2<:\3")
        buf.write("\2\2\2<=\3\2\2\2=?\3\2\2\2><\3\2\2\2?@\7\26\2\2@\3\3\2")
        buf.write("\2\2AF\5\20\t\2BF\5\6\4\2CF\5\22\n\2DF\5\b\5\2EA\3\2\2")
        buf.write("\2EB\3\2\2\2EC\3\2\2\2ED\3\2\2\2F\5\3\2\2\2GH\5\60\31")
        buf.write("\2HI\5\f\7\2IJ\7\24\2\2J\7\3\2\2\2KL\5\60\31\2LQ\5\f\7")
        buf.write("\2MN\7\33\2\2NP\5\f\7\2OM\3\2\2\2PS\3\2\2\2QO\3\2\2\2")
        buf.write("QR\3\2\2\2RT\3\2\2\2SQ\3\2\2\2TU\7\24\2\2U\t\3\2\2\2V")
        buf.write("W\7\60\2\2WZ\7\27\2\2X[\5 \21\2Y[\5\16\b\2ZX\3\2\2\2Z")
        buf.write("Y\3\2\2\2[\\\3\2\2\2\\_\7\30\2\2]^\7/\2\2^`\5\36\20\2")
        buf.write("_]\3\2\2\2_`\3\2\2\2`\13\3\2\2\2ad\5\16\b\2bd\5\n\6\2")
        buf.write("ca\3\2\2\2cb\3\2\2\2d\r\3\2\2\2eh\7\60\2\2fg\7/\2\2gi")
        buf.write("\5\36\20\2hf\3\2\2\2hi\3\2\2\2i\17\3\2\2\2jk\7\22\2\2")
        buf.write("kl\7\60\2\2lp\7\25\2\2mo\5\6\4\2nm\3\2\2\2or\3\2\2\2p")
        buf.write("n\3\2\2\2pq\3\2\2\2qs\3\2\2\2rp\3\2\2\2st\7\26\2\2tu\7")
        buf.write("\24\2\2u\21\3\2\2\2vw\5\24\13\2wx\5\64\33\2x\u0088\7\31")
        buf.write("\2\2yz\5\60\31\2z{\5\16\b\2{~\3\2\2\2|~\7\21\2\2}y\3\2")
        buf.write("\2\2}|\3\2\2\2~\u0085\3\2\2\2\177\u0080\7\33\2\2\u0080")
        buf.write("\u0081\5\60\31\2\u0081\u0082\5\16\b\2\u0082\u0084\3\2")
        buf.write("\2\2\u0083\177\3\2\2\2\u0084\u0087\3\2\2\2\u0085\u0083")
        buf.write("\3\2\2\2\u0085\u0086\3\2\2\2\u0086\u0089\3\2\2\2\u0087")
        buf.write("\u0085\3\2\2\2\u0088}\3\2\2\2\u0088\u0089\3\2\2\2\u0089")
        buf.write("\u008a\3\2\2\2\u008a\u008b\7\32\2\2\u008b\u008c\5\26\f")
        buf.write("\2\u008c\23\3\2\2\2\u008d\u0090\5\60\31\2\u008e\u0090")
        buf.write("\7\21\2\2\u008f\u008d\3\2\2\2\u008f\u008e\3\2\2\2\u0090")
        buf.write("\25\3\2\2\2\u0091\u0095\7\25\2\2\u0092\u0094\5\6\4\2\u0093")
        buf.write("\u0092\3\2\2\2\u0094\u0097\3\2\2\2\u0095\u0093\3\2\2\2")
        buf.write("\u0095\u0096\3\2\2\2\u0096\u009b\3\2\2\2\u0097\u0095\3")
        buf.write("\2\2\2\u0098\u009a\5\30\r\2\u0099\u0098\3\2\2\2\u009a")
        buf.write("\u009d\3\2\2\2\u009b\u0099\3\2\2\2\u009b\u009c\3\2\2\2")
        buf.write("\u009c\u009e\3\2\2\2\u009d\u009b\3\2\2\2\u009e\u009f\7")
        buf.write("\26\2\2\u009f\27\3\2\2\2\u00a0\u00a1\5\36\20\2\u00a1\u00a2")
        buf.write("\5\62\32\2\u00a2\u00a4\5\34\17\2\u00a3\u00a5\7\24\2\2")
        buf.write("\u00a4\u00a3\3\2\2\2\u00a4\u00a5\3\2\2\2\u00a5\u00ce\3")
        buf.write("\2\2\2\u00a6\u00ce\5\32\16\2\u00a7\u00a8\7\5\2\2\u00a8")
        buf.write("\u00a9\7\31\2\2\u00a9\u00aa\5\34\17\2\u00aa\u00ab\7\32")
        buf.write("\2\2\u00ab\u00ae\5\26\f\2\u00ac\u00ad\7\6\2\2\u00ad\u00af")
        buf.write("\5\26\f\2\u00ae\u00ac\3\2\2\2\u00ae\u00af\3\2\2\2\u00af")
        buf.write("\u00ce\3\2\2\2\u00b0\u00b1\7\b\2\2\u00b1\u00b2\7\31\2")
        buf.write("\2\u00b2\u00b3\5\34\17\2\u00b3\u00b4\7\32\2\2\u00b4\u00b5")
        buf.write("\5\26\f\2\u00b5\u00ce\3\2\2\2\u00b6\u00b7\7\t\2\2\u00b7")
        buf.write("\u00b8\5\34\17\2\u00b8\u00b9\7\24\2\2\u00b9\u00ce\3\2")
        buf.write("\2\2\u00ba\u00bb\7\7\2\2\u00bb\u00be\5\16\b\2\u00bc\u00bd")
        buf.write("\7*\2\2\u00bd\u00bf\5 \21\2\u00be\u00bc\3\2\2\2\u00be")
        buf.write("\u00bf\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\u00c7\7\33\2")
        buf.write("\2\u00c1\u00c4\5\16\b\2\u00c2\u00c3\7*\2\2\u00c3\u00c5")
        buf.write("\5 \21\2\u00c4\u00c2\3\2\2\2\u00c4\u00c5\3\2\2\2\u00c5")
        buf.write("\u00c8\3\2\2\2\u00c6\u00c8\5 \21\2\u00c7\u00c1\3\2\2\2")
        buf.write("\u00c7\u00c6\3\2\2\2\u00c8\u00c9\3\2\2\2\u00c9\u00ca\5")
        buf.write("\26\f\2\u00ca\u00ce\3\2\2\2\u00cb\u00cc\7\n\2\2\u00cc")
        buf.write("\u00ce\7\24\2\2\u00cd\u00a0\3\2\2\2\u00cd\u00a6\3\2\2")
        buf.write("\2\u00cd\u00a7\3\2\2\2\u00cd\u00b0\3\2\2\2\u00cd\u00b6")
        buf.write("\3\2\2\2\u00cd\u00ba\3\2\2\2\u00cd\u00cb\3\2\2\2\u00ce")
        buf.write("\31\3\2\2\2\u00cf\u00d0\5\64\33\2\u00d0\u00d9\7\31\2\2")
        buf.write("\u00d1\u00d6\5\34\17\2\u00d2\u00d3\7\33\2\2\u00d3\u00d5")
        buf.write("\5\34\17\2\u00d4\u00d2\3\2\2\2\u00d5\u00d8\3\2\2\2\u00d6")
        buf.write("\u00d4\3\2\2\2\u00d6\u00d7\3\2\2\2\u00d7\u00da\3\2\2\2")
        buf.write("\u00d8\u00d6\3\2\2\2\u00d9\u00d1\3\2\2\2\u00d9\u00da\3")
        buf.write("\2\2\2\u00da\u00db\3\2\2\2\u00db\u00dd\7\32\2\2\u00dc")
        buf.write("\u00de\7\24\2\2\u00dd\u00dc\3\2\2\2\u00dd\u00de\3\2\2")
        buf.write("\2\u00de\33\3\2\2\2\u00df\u00e0\b\17\1\2\u00e0\u00ec\5")
        buf.write(",\27\2\u00e1\u00ec\5\36\20\2\u00e2\u00ec\5\32\16\2\u00e3")
        buf.write("\u00e4\7\37\2\2\u00e4\u00ec\5\34\17\5\u00e5\u00e6\7%\2")
        buf.write("\2\u00e6\u00ec\5\34\17\4\u00e7\u00e8\7\31\2\2\u00e8\u00e9")
        buf.write("\5\34\17\2\u00e9\u00ea\7\32\2\2\u00ea\u00ec\3\2\2\2\u00eb")
        buf.write("\u00df\3\2\2\2\u00eb\u00e1\3\2\2\2\u00eb\u00e2\3\2\2\2")
        buf.write("\u00eb\u00e3\3\2\2\2\u00eb\u00e5\3\2\2\2\u00eb\u00e7\3")
        buf.write("\2\2\2\u00ec\u00fe\3\2\2\2\u00ed\u00ee\f\b\2\2\u00ee\u00ef")
        buf.write("\t\2\2\2\u00ef\u00fd\5\34\17\t\u00f0\u00f1\f\7\2\2\u00f1")
        buf.write("\u00f2\t\3\2\2\u00f2\u00fd\5\34\17\b\u00f3\u00f8\f\6\2")
        buf.write("\2\u00f4\u00f9\5.\30\2\u00f5\u00f9\5&\24\2\u00f6\u00f9")
        buf.write("\5(\25\2\u00f7\u00f9\5*\26\2\u00f8\u00f4\3\2\2\2\u00f8")
        buf.write("\u00f5\3\2\2\2\u00f8\u00f6\3\2\2\2\u00f8\u00f7\3\2\2\2")
        buf.write("\u00f9\u00fa\3\2\2\2\u00fa\u00fb\5\34\17\7\u00fb\u00fd")
        buf.write("\3\2\2\2\u00fc\u00ed\3\2\2\2\u00fc\u00f0\3\2\2\2\u00fc")
        buf.write("\u00f3\3\2\2\2\u00fd\u0100\3\2\2\2\u00fe\u00fc\3\2\2\2")
        buf.write("\u00fe\u00ff\3\2\2\2\u00ff\35\3\2\2\2\u0100\u00fe\3\2")
        buf.write("\2\2\u0101\u0104\5\16\b\2\u0102\u0104\5\n\6\2\u0103\u0101")
        buf.write("\3\2\2\2\u0103\u0102\3\2\2\2\u0104\37\3\2\2\2\u0105\u0106")
        buf.write("\7\62\2\2\u0106!\3\2\2\2\u0107\u0108\7\64\2\2\u0108#\3")
        buf.write("\2\2\2\u0109\u010a\t\4\2\2\u010a%\3\2\2\2\u010b\u010c")
        buf.write("\t\5\2\2\u010c\'\3\2\2\2\u010d\u010e\t\6\2\2\u010e)\3")
        buf.write("\2\2\2\u010f\u0110\t\7\2\2\u0110+\3\2\2\2\u0111\u0115")
        buf.write("\5 \21\2\u0112\u0115\5\"\22\2\u0113\u0115\5$\23\2\u0114")
        buf.write("\u0111\3\2\2\2\u0114\u0112\3\2\2\2\u0114\u0113\3\2\2\2")
        buf.write("\u0115-\3\2\2\2\u0116\u0117\t\b\2\2\u0117/\3\2\2\2\u0118")
        buf.write("\u011f\7\16\2\2\u0119\u011f\7\r\2\2\u011a\u011f\7\f\2")
        buf.write("\2\u011b\u011c\7\22\2\2\u011c\u011f\7\60\2\2\u011d\u011f")
        buf.write("\5\20\t\2\u011e\u0118\3\2\2\2\u011e\u0119\3\2\2\2\u011e")
        buf.write("\u011a\3\2\2\2\u011e\u011b\3\2\2\2\u011e\u011d\3\2\2\2")
        buf.write("\u011f\61\3\2\2\2\u0120\u0121\t\t\2\2\u0121\63\3\2\2\2")
        buf.write("\u0122\u0123\7\60\2\2\u0123\65\3\2\2\2 <EQZ_chp}\u0085")
        buf.write("\u0088\u008f\u0095\u009b\u00a4\u00ae\u00be\u00c4\u00c7")
        buf.write("\u00cd\u00d6\u00d9\u00dd\u00eb\u00f8\u00fc\u00fe\u0103")
        buf.write("\u0114\u011e")
        return buf.getvalue()


class decafAlejandroV2Parser ( Parser ):

    grammarFileName = "decafAlejandroV2.g4"

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

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

    sharedContextCache = PredictionContextCache()

    literalNames = [ "<INVALID>", "'class'", "'Program'", "'if'", "'else'", 
                     "'for'", "'while'", "'return'", "'break'", "'continue'", 
                     "'boolean'", "'char'", "'int'", "'True'", "'False'", 
                     "'void'", "'struct'", "'callout'", "';'", "'{'", "'}'", 
                     "'['", "']'", "'('", "')'", "','", "'\"'", "'''", "'+'", 
                     "'-'", "'*'", "'/'", "'%'", "'&&'", "'||'", "'!'", 
                     "'>'", "'<'", "'>='", "'<='", "'='", "'+='", "'-='", 
                     "'=='", "'!='", "'.'" ]

    symbolicNames = [ "<INVALID>", "CLASS", "PROGRAM", "IF", "ELSE", "FOR", 
                      "WHILE", "RETURN", "BREAK", "CONTINUE", "BOOLEAN", 
                      "CHAR", "INT", "TRUE", "FALSE", "VOID", "STRUCT", 
                      "CALLOUT", "SEMICOLON", "LCURLY", "RCURLY", "LSQUARE", 
                      "RSQUARE", "LROUND", "RROUND", "COMMA", "QUOTES", 
                      "APOSTROPHE", "ADD", "SUB", "MULTIPLY", "DIVIDE", 
                      "REMINDER", "AND", "OR", "NOT", "GREATER_OP", "LESS_OP", 
                      "GREATER_eq_op", "LESS_eq_op", "EQUAL_OP", "ADD_eq_op", 
                      "SUB_eq_op", "EQUALITY_OP", "UNEQUALITY_OP", "POINT", 
                      "ID", "ALPHA", "DECIMAL_LITERAL", "DIGIT", "STRING_LITERAL", 
                      "ALPHA_NUM", "HEX_DIGIT", "LINE_COMMENT", "COMMENT", 
                      "NEWLINE", "WHITESPACE" ]

    RULE_program = 0
    RULE_declaration = 1
    RULE_vardeclr = 2
    RULE_field_declr = 3
    RULE_array_id = 4
    RULE_field_var = 5
    RULE_var_id = 6
    RULE_struct_declr = 7
    RULE_method_declr = 8
    RULE_return_type = 9
    RULE_block = 10
    RULE_statement = 11
    RULE_method_call = 12
    RULE_expr = 13
    RULE_location = 14
    RULE_int_literal = 15
    RULE_string_literal = 16
    RULE_bool_literal = 17
    RULE_rel_op = 18
    RULE_eq_op = 19
    RULE_cond_op = 20
    RULE_literal = 21
    RULE_arith_op = 22
    RULE_var_type = 23
    RULE_assign_op = 24
    RULE_method_name = 25

    ruleNames =  [ "program", "declaration", "vardeclr", "field_declr", 
                   "array_id", "field_var", "var_id", "struct_declr", "method_declr", 
                   "return_type", "block", "statement", "method_call", "expr", 
                   "location", "int_literal", "string_literal", "bool_literal", 
                   "rel_op", "eq_op", "cond_op", "literal", "arith_op", 
                   "var_type", "assign_op", "method_name" ]

    EOF = Token.EOF
    CLASS=1
    PROGRAM=2
    IF=3
    ELSE=4
    FOR=5
    WHILE=6
    RETURN=7
    BREAK=8
    CONTINUE=9
    BOOLEAN=10
    CHAR=11
    INT=12
    TRUE=13
    FALSE=14
    VOID=15
    STRUCT=16
    CALLOUT=17
    SEMICOLON=18
    LCURLY=19
    RCURLY=20
    LSQUARE=21
    RSQUARE=22
    LROUND=23
    RROUND=24
    COMMA=25
    QUOTES=26
    APOSTROPHE=27
    ADD=28
    SUB=29
    MULTIPLY=30
    DIVIDE=31
    REMINDER=32
    AND=33
    OR=34
    NOT=35
    GREATER_OP=36
    LESS_OP=37
    GREATER_eq_op=38
    LESS_eq_op=39
    EQUAL_OP=40
    ADD_eq_op=41
    SUB_eq_op=42
    EQUALITY_OP=43
    UNEQUALITY_OP=44
    POINT=45
    ID=46
    ALPHA=47
    DECIMAL_LITERAL=48
    DIGIT=49
    STRING_LITERAL=50
    ALPHA_NUM=51
    HEX_DIGIT=52
    LINE_COMMENT=53
    COMMENT=54
    NEWLINE=55
    WHITESPACE=56

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




    class ProgramContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def CLASS(self):
            return self.getToken(decafAlejandroV2Parser.CLASS, 0)

        def PROGRAM(self):
            return self.getToken(decafAlejandroV2Parser.PROGRAM, 0)

        def LCURLY(self):
            return self.getToken(decafAlejandroV2Parser.LCURLY, 0)

        def RCURLY(self):
            return self.getToken(decafAlejandroV2Parser.RCURLY, 0)

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


        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.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 = 52
            self.match(decafAlejandroV2Parser.CLASS)
            self.state = 53
            self.match(decafAlejandroV2Parser.PROGRAM)
            self.state = 54
            self.match(decafAlejandroV2Parser.LCURLY)
            self.state = 58
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.BOOLEAN) | (1 << decafAlejandroV2Parser.CHAR) | (1 << decafAlejandroV2Parser.INT) | (1 << decafAlejandroV2Parser.VOID) | (1 << decafAlejandroV2Parser.STRUCT))) != 0):
                self.state = 55
                self.declaration()
                self.state = 60
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 61
            self.match(decafAlejandroV2Parser.RCURLY)
        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):
        __slots__ = 'parser'

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

        def struct_declr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Struct_declrContext,0)


        def vardeclr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.VardeclrContext,0)


        def method_declr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Method_declrContext,0)


        def field_declr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Field_declrContext,0)


        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.DeclarationContext(self, self._ctx, self.state)
        self.enterRule(localctx, 2, self.RULE_declaration)
        try:
            self.state = 67
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,1,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 63
                self.struct_declr()
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 64
                self.vardeclr()
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 65
                self.method_declr()
                pass

            elif la_ == 4:
                self.enterOuterAlt(localctx, 4)
                self.state = 66
                self.field_declr()
                pass


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


    class VardeclrContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def var_type(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Var_typeContext,0)


        def field_var(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Field_varContext,0)


        def SEMICOLON(self):
            return self.getToken(decafAlejandroV2Parser.SEMICOLON, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_vardeclr

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

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




    def vardeclr(self):

        localctx = decafAlejandroV2Parser.VardeclrContext(self, self._ctx, self.state)
        self.enterRule(localctx, 4, self.RULE_vardeclr)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 69
            self.var_type()
            self.state = 70
            self.field_var()
            self.state = 71
            self.match(decafAlejandroV2Parser.SEMICOLON)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class Field_declrContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def var_type(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Var_typeContext,0)


        def field_var(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.Field_varContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.Field_varContext,i)


        def SEMICOLON(self):
            return self.getToken(decafAlejandroV2Parser.SEMICOLON, 0)

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

        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_field_declr

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

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




    def field_declr(self):

        localctx = decafAlejandroV2Parser.Field_declrContext(self, self._ctx, self.state)
        self.enterRule(localctx, 6, self.RULE_field_declr)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 73
            self.var_type()
            self.state = 74
            self.field_var()
            self.state = 79
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while _la==decafAlejandroV2Parser.COMMA:
                self.state = 75
                self.match(decafAlejandroV2Parser.COMMA)
                self.state = 76
                self.field_var()
                self.state = 81
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 82
            self.match(decafAlejandroV2Parser.SEMICOLON)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class Array_idContext(ParserRuleContext):
        __slots__ = 'parser'

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

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

        def LSQUARE(self):
            return self.getToken(decafAlejandroV2Parser.LSQUARE, 0)

        def RSQUARE(self):
            return self.getToken(decafAlejandroV2Parser.RSQUARE, 0)

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


        def var_id(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Var_idContext,0)


        def POINT(self):
            return self.getToken(decafAlejandroV2Parser.POINT, 0)

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


        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_array_id

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

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




    def array_id(self):

        localctx = decafAlejandroV2Parser.Array_idContext(self, self._ctx, self.state)
        self.enterRule(localctx, 8, self.RULE_array_id)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 84
            self.match(decafAlejandroV2Parser.ID)
            self.state = 85
            self.match(decafAlejandroV2Parser.LSQUARE)
            self.state = 88
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [decafAlejandroV2Parser.DECIMAL_LITERAL]:
                self.state = 86
                self.int_literal()
                pass
            elif token in [decafAlejandroV2Parser.ID]:
                self.state = 87
                self.var_id()
                pass
            else:
                raise NoViableAltException(self)

            self.state = 90
            self.match(decafAlejandroV2Parser.RSQUARE)
            self.state = 93
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,4,self._ctx)
            if la_ == 1:
                self.state = 91
                self.match(decafAlejandroV2Parser.POINT)
                self.state = 92
                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 Field_varContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def var_id(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Var_idContext,0)


        def array_id(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Array_idContext,0)


        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_field_var

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

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




    def field_var(self):

        localctx = decafAlejandroV2Parser.Field_varContext(self, self._ctx, self.state)
        self.enterRule(localctx, 10, self.RULE_field_var)
        try:
            self.state = 97
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,5,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 95
                self.var_id()
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 96
                self.array_id()
                pass


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


    class Var_idContext(ParserRuleContext):
        __slots__ = 'parser'

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

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

        def POINT(self):
            return self.getToken(decafAlejandroV2Parser.POINT, 0)

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


        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_var_id

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

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




    def var_id(self):

        localctx = decafAlejandroV2Parser.Var_idContext(self, self._ctx, self.state)
        self.enterRule(localctx, 12, self.RULE_var_id)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 99
            self.match(decafAlejandroV2Parser.ID)
            self.state = 102
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,6,self._ctx)
            if la_ == 1:
                self.state = 100
                self.match(decafAlejandroV2Parser.POINT)
                self.state = 101
                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 Struct_declrContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def STRUCT(self):
            return self.getToken(decafAlejandroV2Parser.STRUCT, 0)

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

        def LCURLY(self):
            return self.getToken(decafAlejandroV2Parser.LCURLY, 0)

        def RCURLY(self):
            return self.getToken(decafAlejandroV2Parser.RCURLY, 0)

        def SEMICOLON(self):
            return self.getToken(decafAlejandroV2Parser.SEMICOLON, 0)

        def vardeclr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.VardeclrContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.VardeclrContext,i)


        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_struct_declr

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

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




    def struct_declr(self):

        localctx = decafAlejandroV2Parser.Struct_declrContext(self, self._ctx, self.state)
        self.enterRule(localctx, 14, self.RULE_struct_declr)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 104
            self.match(decafAlejandroV2Parser.STRUCT)
            self.state = 105
            self.match(decafAlejandroV2Parser.ID)
            self.state = 106
            self.match(decafAlejandroV2Parser.LCURLY)
            self.state = 110
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.BOOLEAN) | (1 << decafAlejandroV2Parser.CHAR) | (1 << decafAlejandroV2Parser.INT) | (1 << decafAlejandroV2Parser.STRUCT))) != 0):
                self.state = 107
                self.vardeclr()
                self.state = 112
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 113
            self.match(decafAlejandroV2Parser.RCURLY)
            self.state = 114
            self.match(decafAlejandroV2Parser.SEMICOLON)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class Method_declrContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def return_type(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Return_typeContext,0)


        def method_name(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Method_nameContext,0)


        def LROUND(self):
            return self.getToken(decafAlejandroV2Parser.LROUND, 0)

        def RROUND(self):
            return self.getToken(decafAlejandroV2Parser.RROUND, 0)

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


        def VOID(self):
            return self.getToken(decafAlejandroV2Parser.VOID, 0)

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

        def var_type(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.Var_typeContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.Var_typeContext,i)


        def var_id(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.Var_idContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.Var_idContext,i)


        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_method_declr

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

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




    def method_declr(self):

        localctx = decafAlejandroV2Parser.Method_declrContext(self, self._ctx, self.state)
        self.enterRule(localctx, 16, self.RULE_method_declr)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 116
            self.return_type()
            self.state = 117
            self.method_name()
            self.state = 118
            self.match(decafAlejandroV2Parser.LROUND)
            self.state = 134
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.BOOLEAN) | (1 << decafAlejandroV2Parser.CHAR) | (1 << decafAlejandroV2Parser.INT) | (1 << decafAlejandroV2Parser.VOID) | (1 << decafAlejandroV2Parser.STRUCT))) != 0):
                self.state = 123
                self._errHandler.sync(self)
                token = self._input.LA(1)
                if token in [decafAlejandroV2Parser.BOOLEAN, decafAlejandroV2Parser.CHAR, decafAlejandroV2Parser.INT, decafAlejandroV2Parser.STRUCT]:
                    self.state = 119
                    self.var_type()
                    self.state = 120
                    self.var_id()
                    pass
                elif token in [decafAlejandroV2Parser.VOID]:
                    self.state = 122
                    self.match(decafAlejandroV2Parser.VOID)
                    pass
                else:
                    raise NoViableAltException(self)

                self.state = 131
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==decafAlejandroV2Parser.COMMA:
                    self.state = 125
                    self.match(decafAlejandroV2Parser.COMMA)
                    self.state = 126
                    self.var_type()
                    self.state = 127
                    self.var_id()
                    self.state = 133
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)



            self.state = 136
            self.match(decafAlejandroV2Parser.RROUND)
            self.state = 137
            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 Return_typeContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def var_type(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Var_typeContext,0)


        def VOID(self):
            return self.getToken(decafAlejandroV2Parser.VOID, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_return_type

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

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




    def return_type(self):

        localctx = decafAlejandroV2Parser.Return_typeContext(self, self._ctx, self.state)
        self.enterRule(localctx, 18, self.RULE_return_type)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 141
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [decafAlejandroV2Parser.BOOLEAN, decafAlejandroV2Parser.CHAR, decafAlejandroV2Parser.INT, decafAlejandroV2Parser.STRUCT]:
                self.state = 139
                self.var_type()
                pass
            elif token in [decafAlejandroV2Parser.VOID]:
                self.state = 140
                self.match(decafAlejandroV2Parser.VOID)
                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 BlockContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def LCURLY(self):
            return self.getToken(decafAlejandroV2Parser.LCURLY, 0)

        def RCURLY(self):
            return self.getToken(decafAlejandroV2Parser.RCURLY, 0)

        def vardeclr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.VardeclrContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.VardeclrContext,i)


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


        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.BlockContext(self, self._ctx, self.state)
        self.enterRule(localctx, 20, self.RULE_block)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 143
            self.match(decafAlejandroV2Parser.LCURLY)
            self.state = 147
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.BOOLEAN) | (1 << decafAlejandroV2Parser.CHAR) | (1 << decafAlejandroV2Parser.INT) | (1 << decafAlejandroV2Parser.STRUCT))) != 0):
                self.state = 144
                self.vardeclr()
                self.state = 149
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 153
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.IF) | (1 << decafAlejandroV2Parser.FOR) | (1 << decafAlejandroV2Parser.WHILE) | (1 << decafAlejandroV2Parser.RETURN) | (1 << decafAlejandroV2Parser.BREAK) | (1 << decafAlejandroV2Parser.ID))) != 0):
                self.state = 150
                self.statement()
                self.state = 155
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 156
            self.match(decafAlejandroV2Parser.RCURLY)
        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):
        __slots__ = 'parser'

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


        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_statement

     
        def copyFrom(self, ctx:ParserRuleContext):
            super().copyFrom(ctx)



    class Statement_breakContext(StatementContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.StatementContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def BREAK(self):
            return self.getToken(decafAlejandroV2Parser.BREAK, 0)
        def SEMICOLON(self):
            return self.getToken(decafAlejandroV2Parser.SEMICOLON, 0)

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

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


    class Statement_whileContext(StatementContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.StatementContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def WHILE(self):
            return self.getToken(decafAlejandroV2Parser.WHILE, 0)
        def LROUND(self):
            return self.getToken(decafAlejandroV2Parser.LROUND, 0)
        def expr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,0)

        def RROUND(self):
            return self.getToken(decafAlejandroV2Parser.RROUND, 0)
        def block(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.BlockContext,0)


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

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


    class Statement_assignContext(StatementContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.StatementContext
            super().__init__(parser)
            self.copyFrom(ctx)

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

        def assign_op(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Assign_opContext,0)

        def expr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,0)

        def SEMICOLON(self):
            return self.getToken(decafAlejandroV2Parser.SEMICOLON, 0)

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

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


    class Statement_methodcallContext(StatementContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.StatementContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def method_call(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Method_callContext,0)


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

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


    class Statement_returnContext(StatementContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.StatementContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def RETURN(self):
            return self.getToken(decafAlejandroV2Parser.RETURN, 0)
        def expr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,0)

        def SEMICOLON(self):
            return self.getToken(decafAlejandroV2Parser.SEMICOLON, 0)

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

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


    class Statement_forContext(StatementContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.StatementContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def FOR(self):
            return self.getToken(decafAlejandroV2Parser.FOR, 0)
        def var_id(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.Var_idContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.Var_idContext,i)

        def COMMA(self):
            return self.getToken(decafAlejandroV2Parser.COMMA, 0)
        def block(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.BlockContext,0)

        def int_literal(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.Int_literalContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.Int_literalContext,i)

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

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

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


    class Statement_ifContext(StatementContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.StatementContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def IF(self):
            return self.getToken(decafAlejandroV2Parser.IF, 0)
        def LROUND(self):
            return self.getToken(decafAlejandroV2Parser.LROUND, 0)
        def expr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,0)

        def RROUND(self):
            return self.getToken(decafAlejandroV2Parser.RROUND, 0)
        def block(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.BlockContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.BlockContext,i)

        def ELSE(self):
            return self.getToken(decafAlejandroV2Parser.ELSE, 0)

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

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



    def statement(self):

        localctx = decafAlejandroV2Parser.StatementContext(self, self._ctx, self.state)
        self.enterRule(localctx, 22, self.RULE_statement)
        self._la = 0 # Token type
        try:
            self.state = 203
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,19,self._ctx)
            if la_ == 1:
                localctx = decafAlejandroV2Parser.Statement_assignContext(self, localctx)
                self.enterOuterAlt(localctx, 1)
                self.state = 158
                self.location()
                self.state = 159
                self.assign_op()
                self.state = 160
                self.expr(0)
                self.state = 162
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if _la==decafAlejandroV2Parser.SEMICOLON:
                    self.state = 161
                    self.match(decafAlejandroV2Parser.SEMICOLON)


                pass

            elif la_ == 2:
                localctx = decafAlejandroV2Parser.Statement_methodcallContext(self, localctx)
                self.enterOuterAlt(localctx, 2)
                self.state = 164
                self.method_call()
                pass

            elif la_ == 3:
                localctx = decafAlejandroV2Parser.Statement_ifContext(self, localctx)
                self.enterOuterAlt(localctx, 3)
                self.state = 165
                self.match(decafAlejandroV2Parser.IF)
                self.state = 166
                self.match(decafAlejandroV2Parser.LROUND)
                self.state = 167
                self.expr(0)
                self.state = 168
                self.match(decafAlejandroV2Parser.RROUND)
                self.state = 169
                self.block()
                self.state = 172
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if _la==decafAlejandroV2Parser.ELSE:
                    self.state = 170
                    self.match(decafAlejandroV2Parser.ELSE)
                    self.state = 171
                    self.block()


                pass

            elif la_ == 4:
                localctx = decafAlejandroV2Parser.Statement_whileContext(self, localctx)
                self.enterOuterAlt(localctx, 4)
                self.state = 174
                self.match(decafAlejandroV2Parser.WHILE)
                self.state = 175
                self.match(decafAlejandroV2Parser.LROUND)
                self.state = 176
                self.expr(0)
                self.state = 177
                self.match(decafAlejandroV2Parser.RROUND)
                self.state = 178
                self.block()
                pass

            elif la_ == 5:
                localctx = decafAlejandroV2Parser.Statement_returnContext(self, localctx)
                self.enterOuterAlt(localctx, 5)
                self.state = 180
                self.match(decafAlejandroV2Parser.RETURN)
                self.state = 181
                self.expr(0)
                self.state = 182
                self.match(decafAlejandroV2Parser.SEMICOLON)
                pass

            elif la_ == 6:
                localctx = decafAlejandroV2Parser.Statement_forContext(self, localctx)
                self.enterOuterAlt(localctx, 6)
                self.state = 184
                self.match(decafAlejandroV2Parser.FOR)
                self.state = 185
                self.var_id()
                self.state = 188
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if _la==decafAlejandroV2Parser.EQUAL_OP:
                    self.state = 186
                    self.match(decafAlejandroV2Parser.EQUAL_OP)
                    self.state = 187
                    self.int_literal()


                self.state = 190
                self.match(decafAlejandroV2Parser.COMMA)
                self.state = 197
                self._errHandler.sync(self)
                token = self._input.LA(1)
                if token in [decafAlejandroV2Parser.ID]:
                    self.state = 191
                    self.var_id()
                    self.state = 194
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)
                    if _la==decafAlejandroV2Parser.EQUAL_OP:
                        self.state = 192
                        self.match(decafAlejandroV2Parser.EQUAL_OP)
                        self.state = 193
                        self.int_literal()


                    pass
                elif token in [decafAlejandroV2Parser.DECIMAL_LITERAL]:
                    self.state = 196
                    self.int_literal()
                    pass
                else:
                    raise NoViableAltException(self)

                self.state = 199
                self.block()
                pass

            elif la_ == 7:
                localctx = decafAlejandroV2Parser.Statement_breakContext(self, localctx)
                self.enterOuterAlt(localctx, 7)
                self.state = 201
                self.match(decafAlejandroV2Parser.BREAK)
                self.state = 202
                self.match(decafAlejandroV2Parser.SEMICOLON)
                pass


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


    class Method_callContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def method_name(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Method_nameContext,0)


        def LROUND(self):
            return self.getToken(decafAlejandroV2Parser.LROUND, 0)

        def RROUND(self):
            return self.getToken(decafAlejandroV2Parser.RROUND, 0)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.ExprContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,i)


        def SEMICOLON(self):
            return self.getToken(decafAlejandroV2Parser.SEMICOLON, 0)

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

        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_method_call

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

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




    def method_call(self):

        localctx = decafAlejandroV2Parser.Method_callContext(self, self._ctx, self.state)
        self.enterRule(localctx, 24, self.RULE_method_call)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 205
            self.method_name()
            self.state = 206
            self.match(decafAlejandroV2Parser.LROUND)
            self.state = 215
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.TRUE) | (1 << decafAlejandroV2Parser.FALSE) | (1 << decafAlejandroV2Parser.LROUND) | (1 << decafAlejandroV2Parser.SUB) | (1 << decafAlejandroV2Parser.NOT) | (1 << decafAlejandroV2Parser.ID) | (1 << decafAlejandroV2Parser.DECIMAL_LITERAL) | (1 << decafAlejandroV2Parser.STRING_LITERAL))) != 0):
                self.state = 207
                self.expr(0)
                self.state = 212
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==decafAlejandroV2Parser.COMMA:
                    self.state = 208
                    self.match(decafAlejandroV2Parser.COMMA)
                    self.state = 209
                    self.expr(0)
                    self.state = 214
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)



            self.state = 217
            self.match(decafAlejandroV2Parser.RROUND)
            self.state = 219
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,22,self._ctx)
            if la_ == 1:
                self.state = 218
                self.match(decafAlejandroV2Parser.SEMICOLON)


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


    class ExprContext(ParserRuleContext):
        __slots__ = 'parser'

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


        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_expr

     
        def copyFrom(self, ctx:ParserRuleContext):
            super().copyFrom(ctx)


    class Expr_literalContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

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


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

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


    class Expr_locationContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

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


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

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


    class Expr_PrecedenciaMaxContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.ExprContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,i)

        def MULTIPLY(self):
            return self.getToken(decafAlejandroV2Parser.MULTIPLY, 0)
        def DIVIDE(self):
            return self.getToken(decafAlejandroV2Parser.DIVIDE, 0)
        def REMINDER(self):
            return self.getToken(decafAlejandroV2Parser.REMINDER, 0)

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

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


    class Expr_menosContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def SUB(self):
            return self.getToken(decafAlejandroV2Parser.SUB, 0)
        def expr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,0)


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

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


    class Expr_normalContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.ExprContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,i)

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

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

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

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


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

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


    class Expr_PrecedenciaMenorContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(decafAlejandroV2Parser.ExprContext)
            else:
                return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,i)

        def ADD(self):
            return self.getToken(decafAlejandroV2Parser.ADD, 0)
        def SUB(self):
            return self.getToken(decafAlejandroV2Parser.SUB, 0)

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

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


    class Expr_parentesisContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def LROUND(self):
            return self.getToken(decafAlejandroV2Parser.LROUND, 0)
        def expr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,0)

        def RROUND(self):
            return self.getToken(decafAlejandroV2Parser.RROUND, 0)

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

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


    class Expr_methodCallContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def method_call(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Method_callContext,0)


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

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


    class Expr_negacionContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a decafAlejandroV2Parser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def NOT(self):
            return self.getToken(decafAlejandroV2Parser.NOT, 0)
        def expr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.ExprContext,0)


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

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



    def expr(self, _p:int=0):
        _parentctx = self._ctx
        _parentState = self.state
        localctx = decafAlejandroV2Parser.ExprContext(self, self._ctx, _parentState)
        _prevctx = localctx
        _startState = 26
        self.enterRecursionRule(localctx, 26, self.RULE_expr, _p)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 233
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,23,self._ctx)
            if la_ == 1:
                localctx = decafAlejandroV2Parser.Expr_literalContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx

                self.state = 222
                self.literal()
                pass

            elif la_ == 2:
                localctx = decafAlejandroV2Parser.Expr_locationContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 223
                self.location()
                pass

            elif la_ == 3:
                localctx = decafAlejandroV2Parser.Expr_methodCallContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 224
                self.method_call()
                pass

            elif la_ == 4:
                localctx = decafAlejandroV2Parser.Expr_menosContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 225
                self.match(decafAlejandroV2Parser.SUB)
                self.state = 226
                self.expr(3)
                pass

            elif la_ == 5:
                localctx = decafAlejandroV2Parser.Expr_negacionContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 227
                self.match(decafAlejandroV2Parser.NOT)
                self.state = 228
                self.expr(2)
                pass

            elif la_ == 6:
                localctx = decafAlejandroV2Parser.Expr_parentesisContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 229
                self.match(decafAlejandroV2Parser.LROUND)
                self.state = 230
                self.expr(0)
                self.state = 231
                self.match(decafAlejandroV2Parser.RROUND)
                pass


            self._ctx.stop = self._input.LT(-1)
            self.state = 252
            self._errHandler.sync(self)
            _alt = self._interp.adaptivePredict(self._input,26,self._ctx)
            while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt==1:
                    if self._parseListeners is not None:
                        self.triggerExitRuleEvent()
                    _prevctx = localctx
                    self.state = 250
                    self._errHandler.sync(self)
                    la_ = self._interp.adaptivePredict(self._input,25,self._ctx)
                    if la_ == 1:
                        localctx = decafAlejandroV2Parser.Expr_PrecedenciaMaxContext(self, decafAlejandroV2Parser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 235
                        if not self.precpred(self._ctx, 6):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 6)")
                        self.state = 236
                        _la = self._input.LA(1)
                        if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.MULTIPLY) | (1 << decafAlejandroV2Parser.DIVIDE) | (1 << decafAlejandroV2Parser.REMINDER))) != 0)):
                            self._errHandler.recoverInline(self)
                        else:
                            self._errHandler.reportMatch(self)
                            self.consume()
                        self.state = 237
                        self.expr(7)
                        pass

                    elif la_ == 2:
                        localctx = decafAlejandroV2Parser.Expr_PrecedenciaMenorContext(self, decafAlejandroV2Parser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 238
                        if not self.precpred(self._ctx, 5):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 5)")
                        self.state = 239
                        _la = self._input.LA(1)
                        if not(_la==decafAlejandroV2Parser.ADD or _la==decafAlejandroV2Parser.SUB):
                            self._errHandler.recoverInline(self)
                        else:
                            self._errHandler.reportMatch(self)
                            self.consume()
                        self.state = 240
                        self.expr(6)
                        pass

                    elif la_ == 3:
                        localctx = decafAlejandroV2Parser.Expr_normalContext(self, decafAlejandroV2Parser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 241
                        if not self.precpred(self._ctx, 4):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 4)")
                        self.state = 246
                        self._errHandler.sync(self)
                        token = self._input.LA(1)
                        if token in [decafAlejandroV2Parser.ADD, decafAlejandroV2Parser.SUB, decafAlejandroV2Parser.MULTIPLY, decafAlejandroV2Parser.DIVIDE, decafAlejandroV2Parser.REMINDER]:
                            self.state = 242
                            self.arith_op()
                            pass
                        elif token in [decafAlejandroV2Parser.GREATER_OP, decafAlejandroV2Parser.LESS_OP, decafAlejandroV2Parser.GREATER_eq_op, decafAlejandroV2Parser.LESS_eq_op]:
                            self.state = 243
                            self.rel_op()
                            pass
                        elif token in [decafAlejandroV2Parser.EQUALITY_OP, decafAlejandroV2Parser.UNEQUALITY_OP]:
                            self.state = 244
                            self.eq_op()
                            pass
                        elif token in [decafAlejandroV2Parser.AND, decafAlejandroV2Parser.OR]:
                            self.state = 245
                            self.cond_op()
                            pass
                        else:
                            raise NoViableAltException(self)

                        self.state = 248
                        self.expr(5)
                        pass

             
                self.state = 254
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,26,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 LocationContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def var_id(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Var_idContext,0)


        def array_id(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Array_idContext,0)


        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.LocationContext(self, self._ctx, self.state)
        self.enterRule(localctx, 28, self.RULE_location)
        try:
            self.state = 257
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,27,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 255
                self.var_id()
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 256
                self.array_id()
                pass


        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):
        __slots__ = 'parser'

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

        def DECIMAL_LITERAL(self):
            return self.getToken(decafAlejandroV2Parser.DECIMAL_LITERAL, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.Int_literalContext(self, self._ctx, self.state)
        self.enterRule(localctx, 30, self.RULE_int_literal)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 259
            self.match(decafAlejandroV2Parser.DECIMAL_LITERAL)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class String_literalContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def STRING_LITERAL(self):
            return self.getToken(decafAlejandroV2Parser.STRING_LITERAL, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_string_literal

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

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




    def string_literal(self):

        localctx = decafAlejandroV2Parser.String_literalContext(self, self._ctx, self.state)
        self.enterRule(localctx, 32, self.RULE_string_literal)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 261
            self.match(decafAlejandroV2Parser.STRING_LITERAL)
        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):
        __slots__ = 'parser'

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

        def TRUE(self):
            return self.getToken(decafAlejandroV2Parser.TRUE, 0)

        def FALSE(self):
            return self.getToken(decafAlejandroV2Parser.FALSE, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.Bool_literalContext(self, self._ctx, self.state)
        self.enterRule(localctx, 34, self.RULE_bool_literal)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 263
            _la = self._input.LA(1)
            if not(_la==decafAlejandroV2Parser.TRUE or _la==decafAlejandroV2Parser.FALSE):
                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):
        __slots__ = 'parser'

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

        def GREATER_OP(self):
            return self.getToken(decafAlejandroV2Parser.GREATER_OP, 0)

        def LESS_OP(self):
            return self.getToken(decafAlejandroV2Parser.LESS_OP, 0)

        def LESS_eq_op(self):
            return self.getToken(decafAlejandroV2Parser.LESS_eq_op, 0)

        def GREATER_eq_op(self):
            return self.getToken(decafAlejandroV2Parser.GREATER_eq_op, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.Rel_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 36, self.RULE_rel_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 265
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.GREATER_OP) | (1 << decafAlejandroV2Parser.LESS_OP) | (1 << decafAlejandroV2Parser.GREATER_eq_op) | (1 << decafAlejandroV2Parser.LESS_eq_op))) != 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):
        __slots__ = 'parser'

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

        def EQUALITY_OP(self):
            return self.getToken(decafAlejandroV2Parser.EQUALITY_OP, 0)

        def UNEQUALITY_OP(self):
            return self.getToken(decafAlejandroV2Parser.UNEQUALITY_OP, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.Eq_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 38, self.RULE_eq_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 267
            _la = self._input.LA(1)
            if not(_la==decafAlejandroV2Parser.EQUALITY_OP or _la==decafAlejandroV2Parser.UNEQUALITY_OP):
                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):
        __slots__ = 'parser'

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

        def AND(self):
            return self.getToken(decafAlejandroV2Parser.AND, 0)

        def OR(self):
            return self.getToken(decafAlejandroV2Parser.OR, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.Cond_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 40, self.RULE_cond_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 269
            _la = self._input.LA(1)
            if not(_la==decafAlejandroV2Parser.AND or _la==decafAlejandroV2Parser.OR):
                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):
        __slots__ = 'parser'

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

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


        def string_literal(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.String_literalContext,0)


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


        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.LiteralContext(self, self._ctx, self.state)
        self.enterRule(localctx, 42, self.RULE_literal)
        try:
            self.state = 274
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [decafAlejandroV2Parser.DECIMAL_LITERAL]:
                self.enterOuterAlt(localctx, 1)
                self.state = 271
                self.int_literal()
                pass
            elif token in [decafAlejandroV2Parser.STRING_LITERAL]:
                self.enterOuterAlt(localctx, 2)
                self.state = 272
                self.string_literal()
                pass
            elif token in [decafAlejandroV2Parser.TRUE, decafAlejandroV2Parser.FALSE]:
                self.enterOuterAlt(localctx, 3)
                self.state = 273
                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 Arith_opContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def ADD(self):
            return self.getToken(decafAlejandroV2Parser.ADD, 0)

        def SUB(self):
            return self.getToken(decafAlejandroV2Parser.SUB, 0)

        def MULTIPLY(self):
            return self.getToken(decafAlejandroV2Parser.MULTIPLY, 0)

        def DIVIDE(self):
            return self.getToken(decafAlejandroV2Parser.DIVIDE, 0)

        def REMINDER(self):
            return self.getToken(decafAlejandroV2Parser.REMINDER, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.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 = decafAlejandroV2Parser.Arith_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 44, self.RULE_arith_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 276
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.ADD) | (1 << decafAlejandroV2Parser.SUB) | (1 << decafAlejandroV2Parser.MULTIPLY) | (1 << decafAlejandroV2Parser.DIVIDE) | (1 << decafAlejandroV2Parser.REMINDER))) != 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 Var_typeContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def INT(self):
            return self.getToken(decafAlejandroV2Parser.INT, 0)

        def CHAR(self):
            return self.getToken(decafAlejandroV2Parser.CHAR, 0)

        def BOOLEAN(self):
            return self.getToken(decafAlejandroV2Parser.BOOLEAN, 0)

        def STRUCT(self):
            return self.getToken(decafAlejandroV2Parser.STRUCT, 0)

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

        def struct_declr(self):
            return self.getTypedRuleContext(decafAlejandroV2Parser.Struct_declrContext,0)


        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_var_type

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

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




    def var_type(self):

        localctx = decafAlejandroV2Parser.Var_typeContext(self, self._ctx, self.state)
        self.enterRule(localctx, 46, self.RULE_var_type)
        try:
            self.state = 284
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,29,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 278
                self.match(decafAlejandroV2Parser.INT)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 279
                self.match(decafAlejandroV2Parser.CHAR)
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 280
                self.match(decafAlejandroV2Parser.BOOLEAN)
                pass

            elif la_ == 4:
                self.enterOuterAlt(localctx, 4)
                self.state = 281
                self.match(decafAlejandroV2Parser.STRUCT)
                self.state = 282
                self.match(decafAlejandroV2Parser.ID)
                pass

            elif la_ == 5:
                self.enterOuterAlt(localctx, 5)
                self.state = 283
                self.struct_declr()
                pass


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


    class Assign_opContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def EQUAL_OP(self):
            return self.getToken(decafAlejandroV2Parser.EQUAL_OP, 0)

        def ADD_eq_op(self):
            return self.getToken(decafAlejandroV2Parser.ADD_eq_op, 0)

        def SUB_eq_op(self):
            return self.getToken(decafAlejandroV2Parser.SUB_eq_op, 0)

        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_assign_op

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

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




    def assign_op(self):

        localctx = decafAlejandroV2Parser.Assign_opContext(self, self._ctx, self.state)
        self.enterRule(localctx, 48, self.RULE_assign_op)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 286
            _la = self._input.LA(1)
            if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << decafAlejandroV2Parser.EQUAL_OP) | (1 << decafAlejandroV2Parser.ADD_eq_op) | (1 << decafAlejandroV2Parser.SUB_eq_op))) != 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 Method_nameContext(ParserRuleContext):
        __slots__ = 'parser'

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

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

        def getRuleIndex(self):
            return decafAlejandroV2Parser.RULE_method_name

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

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




    def method_name(self):

        localctx = decafAlejandroV2Parser.Method_nameContext(self, self._ctx, self.state)
        self.enterRule(localctx, 50, self.RULE_method_name)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 288
            self.match(decafAlejandroV2Parser.ID)
        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[13] = self.expr_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 expr_sempred(self, localctx:ExprContext, predIndex:int):
            if predIndex == 0:
                return self.precpred(self._ctx, 6)
         

            if predIndex == 1:
                return self.precpred(self._ctx, 5)
         

            if predIndex == 2:
                return self.precpred(self._ctx, 4)
         




