def p_dimension(p):
    'dimension  :   CORIZQ valor CORDER'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("dimension-> CORIZQ valor CORDER")
    gramatical.add("dimension.val = valor.val")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = p[2]
def p_init(p):
    'init : instrucciones'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("initi-> instrucciones")
    gramatical.add("init.val=instrucciones.val")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = p[1]
def p_punset(p):
    'punset  :   UNSET PARIZQ VARIABLE PARDER PYCOMA'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("punset-> UNSET PARIZQ VARIABLE PARDER PYCOMA")
    gramatical.add("punset.val = unset({0})".format(p[3]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = UnSet(p[3], p.lineno(1), find_column(p.slice[1]))
def p_main(p):
    'main   :   MAIN DOSPUNTOS sentencias'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("pmain-> MAIN DOSPUNTOS sentencias")
    gramatical.add("pmain.val = Main(sentencias.val)")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Main(p[3], p.lineno(1), find_column(p.slice[1]))
def p_dimensionesP2(p):
    'dimensionesP     :   '
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("dimensionesP->empty")
    gramatical.add("dimensionesP.val = new list[]")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = []
def p_psalir(p):
    'pexit  :   EXIT PYCOMA'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("pexit-> EXIT PYCOMA")
    gramatical.add("pexit.val = Exit()")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Exit(p.lineno(1), find_column(p.slice[1]))
def p_etiqueta2(p):
    'etiqueta : ID DOSPUNTOS '
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("petiqueta-> ID DOSPUNTOS epsilon")
    gramatical.add("petiqueta.val = Etiqueta({0},epsilon)".format(p[1]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Etiqueta(p[1], Vacio(), p.lineno(1), find_column(p.slice[1]))
def p_etiqueta(p):
    'etiqueta   :   ID DOSPUNTOS sentencias'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("petiqueta-> ID DOSPUNTOS sentencias")
    gramatical.add("petiqueta.val = Etiqueta({0},sentencias.val)".format(p[1]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Etiqueta(p[1], p[3], p.lineno(1), find_column(p.slice[1]))
def p_pgoto(p):
    'pgoto  :   GOTO ID PYCOMA'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("pgoto-> GOTO ID PYCOMA")
    gramatical.add("pgoto.val = Goto({0})".format(p[2]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Goto(p[2], p.lineno(1), find_column(p.slice[1]))
def p_operaciones6(p):
    'operacion  :   ABS PARIZQ MENOS valor PARDER'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("operacion-> ABS PARIZQ MENOS valor PARDER")
    gramatical.add("operacion.val = OperacionUnaria(valor.val,ABSOLUTO)")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = OperacionUnaria(p[4], OPERACION_NUMERICA.ABSOLUTO, p.lineno(1),
                           find_column(p.slice[1]))
def p_array(p):
    'parray :   VARIABLE IGUAL ARRAY PARIZQ PARDER PYCOMA'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical(
        "parray-> VARIABLE IGUAL ARRAY PARIZQ PARDER PYCOMA")
    gramatical.add("parray.val = DeclararArreglo({0})".format(p[1]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = DeclararArreglo(p[1], p.lineno(1), find_column(p.slice[1]))
def p_operacion2(p):
    '''operacion    :   valor operacionP
    '''
    #Parte para Reglas Gramaticales
    gramatical = NodoGramatical("operacion    ->   valor operacionP")
    gramatical.add("operacion.valor = operacionP.valor")
    lstGrmaticales.insert(0, gramatical)
    #Parte para instrucciones
    p[0] = p[2]
def p_sentenciasP(p):
    '''sentenciasP      :
    '''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("sentenciasP->empty")
    gramatical.add("sentenciasP.val = new list[]")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = []
def p_main2(p):
    '''main    :   MAIN DOSPUNTOS
    '''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("pmain-> MAIN DOSPUNTOS epsilon")
    gramatical.add("pmain.val = Main(epsilon)")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Main(Vacio(), p.lineno(1), find_column(p.slice[1]))
def p_operacion7(p):
    'operacion  :   VARIABLE dimensiones'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("operacion-> VARIABLE dimensiones")
    gramatical.add(
        "operacion.val = OperacionArreglo(dimensiones.val,dimensiones.val)")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = OperacionArreglo(p[1], p[2], p.lineno(1), find_column(p.slice[1]))
def p_instrucciones(p):
    'instrucciones  :   instruccion instruccionesP'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("instrucciones->instruccion sentenciasP")
    gramatical.add("instruccionesP.val.append(instruccion)")
    gramatical.add("instrucciones.val = instruccionesP.val")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[2].insert(0, p[1])
    p[0] = p[2]
def p_pvariable(p):
    'pvariable : VARIABLE IGUAL operacion PYCOMA'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("pvariable-> VARIABLE IGUAL operacion PYCOMA")
    gramatical.add("pvariable.val = Asignacion({0},operacion.val)".format(
        p[1]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Asignacion(p[1], p[3], Tipo_Etiqueta.VARIABLE, p.lineno(1),
                      find_column(p.slice[1]))
def p_instruccion(p):
    '''instruccion  :   main
                    |   etiqueta          
    '''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("instruccion-> {0}".format(p.slice[1].type))
    gramatical.add("instrucion.val = {0}.val".format(p.slice[1].type))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = p[1]
def p_pprint3(p):
    'pprint :  PRINT PARIZQ VARIABLE dimensiones PARDER PYCOMA'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("pprint-> PRINT PARIZQ valor PARDER PYCOMA")
    gramatical.add("pprint.val = Print_(Nueva linea)")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Print_(
        OperacionArreglo(p[3], p[4], p.lineno(3), find_column(p.slice[3])),
        p.lineno(3), find_column(p.slice[3]))
def p_pif(p):
    'pif    :   IF PARIZQ operacion PARDER GOTO ID PYCOMA '
    #Parte para reporte Gramatical
    gramatical = NodoGramatical(
        "pif-> IF PARIZQ operacion PARDER GOTO ID PYCOMA")
    gramatical.add("pif.val = If_(operacion.val,goto({0}))".format(p[6]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = If_(p[3], Goto(p[6], p.lineno(1), find_column(p.slice[1])),
               p.lineno(1), find_column(p.slice[1]))
def p_sentenciasP2(p):
    '''sentenciasP      :   sentencia sentenciasP
    '''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("sentenciasP->sentencia sentenciasP")
    gramatical.add("sentenciasP2.val.append(sentencia)")
    gramatical.add("sentenciasP.val = sentenciasP2.val")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[2].insert(0, p[1])
    p[0] = p[2]
def p_arreglo(p):
    'parreglo   :   VARIABLE dimensiones IGUAL operacion PYCOMA'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical(
        "parreglo-> VARIABLE dimensiones IGUAL operacion PYCOMA")
    gramatical.add("pvariable.val = Asignacion({0},operacion.val)".format(
        p[1]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = AsignacionArreglo(p[1], p[2], p[4], p.lineno(1),
                             find_column(p.slice[1]))
def p_pread(p):
    'pread  :   VARIABLE IGUAL READ PARIZQ PARDER PYCOMA'
    #Parte para reporte Gramatical
    gramatical = NodoGramatical(
        "pread-> VARIABLE IGUAL READ PARIZQ PARDER PYCOMA")
    gramatical.add("pread.val = Read(Asignacion({0}))".format(p[1]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Read(
        Asignacion(p[1], None, Tipo_Etiqueta.VARIABLE, p.lineno(1),
                   find_column(p.slice[1])), p.lineno(1),
        find_column(p.slice[1]))
def p_pprint(p):
    '''pprint   :   PRINT PARIZQ valor PARDER PYCOMA
    '''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical(
        "pprint-> PRINT PARIZQ VARIABLE dimensiones PARDER PYCOMA")
    gramatical.add(
        "pprint.val = Print_(OperacionArreglo({0},dimensiones.val))".format(
            p.slice[3].type))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Print_(p[3], p.lineno(1), find_column(p.slice[1]))
def p_prefencia(p):
    'preferencia    :  VARIABLE IGUAL ANDBIT VARIABLE PYCOMA ' ''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical(
        "preferencia-> VARIABLE IGUAL ANDBIT VARIABLE PYCOMA ")
    gramatical.add(
        "preferencia.val = Referencia({0},OperacionVariable({1}))".format(
            p[1], p[4]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = Referencia(
        p[1], OperacionVariable(p[4], p.lineno(4), find_column(p.slice[4])),
        Tipo_Etiqueta.VARIABLE, p.lineno(1), find_column(p.slice[1]))
def p_operacion8(p):
    '''operacion    :   PARIZQ INTEGER PARDER valor
                    |   PARIZQ FLOAT PARDER valor
                    |   PARIZQ CHAR PARDER valor
    '''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("operacion-> PARIZQ {0} PARDER valor".format(
        p.slice[2].type))
    gramatical.add("operacion.val = OperacionCasteo({0},valor.val)".format(
        p[2]))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = OperacionCasteo(p[2], p[4], p.lineno(1), find_column(p.slice[1]))
def p_valor(p):
    '''valor    :   ENTERO
                |   DECIMAL
                |   CADENA
                |   CADENA2
                |   VARIABLE 
    '''
    #Nodo para Reporte Gramatical
    gramatical = NodoGramatical("operacion-> {0}".format(p.slice[1].type))
    #retorno de instruccion
    if p.slice[1].type == 'ENTERO' or p.slice[1].type == 'DECIMAL':
        #Nodo para Reporte Gramatical
        gramatical.add("operacion.val = OperacionNumero({0})".format(p[1]))
        #retorno de instruccion
        p[0] = OperacionNumero(p[1], p.lineno(1), find_column(p.slice[1]))
    elif p.slice[1].type == 'CADENA' or p.slice[1].type == 'CADENA2':
        #Nodo para Reporte Gramatical
        gramatical.add("operacion.val = OperacionCadena({0})".format(p[1]))
        #retorno de instruccion
        p[0] = OperacionCadena(p[1], p.lineno(1), find_column(p.slice[1]))
    else:
        #Nodo para Reporte Gramatical
        gramatical.add("operacion.val = OperacionCopiaVariable({0})".format(
            p[1]))
        #retorno de instruccion
        p[0] = OperacionCopiaVariable(p[1], p.lineno(1),
                                      find_column(p.slice[1]))
    #Nodo para Reporte Gramatical
    lstGrmaticales.insert(0, gramatical)
    #Agregamos el valor al stack para poder manejarlo en la siguiente operacion
    stack.append(p[0])
def p_operacion(p):
    '''operacion    :   NOT valor
                    |   NOTBIT valor
                    |   MENOS valor
    '''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("operacion-> {0} valor".format(
        p.slice[1].type))
    #Parte para AST
    if p[1] == '!':
        #Parte para reporte Gramatical
        gramatical.add("operacion.val = OperacionUnaria(valor.val,NOT)")
        #Parte para AST
        p[0] = OperacionUnaria(p[2], OPERACION_LOGICA.NOT, p.lineno(1),
                               find_column(p.slice[1]))
    elif p[1] == '~':
        #Parte para reporte Gramatical
        gramatical.add("operacion.val = OperacionUnaria(valor.val,NOTBIT)")
        #Parte para AST
        p[0] = OperacionUnaria(p[2], OPERACION_BIT.NOT, p.lineno(1),
                               find_column(p.slice[1]))
    elif p[1] == '-':
        #Parte para reporte Gramatical
        gramatical.add("operacion.val = OperacionUnaria(valor.val,RESTA)")
        #Parte para AST
        p[0] = OperacionUnaria(p[2], OPERACION_NUMERICA.RESTA, p.lineno(1),
                               find_column(p.slice[1]))
    #Parte para reporte Gramatical
    lstGrmaticales.insert(0, gramatical)
def p_sentencia(p):
    '''sentencia    : pvariable
                    | preferencia
                    | pgoto
                    | pexit
                    | punset
                    | pif
                    | pprint
                    | pread
                    | parreglo
                    | parray
    '''
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("sentencia-> {0}".format(p.slice[1].type))
    gramatical.add("sentencia.val = {0}.val".format(p.slice[1].type))
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[0] = p[1]
def p_dimensionesP(p):
    'dimensionesP     :   dimension dimensionesP '
    #Parte para reporte Gramatical
    gramatical = NodoGramatical("dimensionesP->dimension dimensionesP")
    gramatical.add("dimensionesP2.val.append(dimension)")
    gramatical.add("dimensionesP.val = dimensionesP2.val")
    lstGrmaticales.insert(0, gramatical)
    #Parte para AST
    p[2].insert(0, p[1])
    p[0] = p[2]