예제 #1
0
def main():

    # Se abre el archivo y se guarda su contenido en el string codigo
    file_name = sys.argv[1]
    fp = open(file_name)
    codigo = fp.read()


    # Manejo de gramática y construccion de arbol

    # Definicion del símbolo inicial
    start = 'programa'

    # Precedencia de los operadores
    precedence = (
            ('left','TkDisyuncion'),
            ('left','TkConjuncion'),
            ('left','TkIgual','TkDesigual'),
            ('left','TkMenor','TkMayor','TkMayorIgual','TkMenorIgual'),
            ('left','TkMas','TkResta'),
            ('left','TkMult','TkDiv','TkMod'),
            ('left','TkConcat'),
            ('left','TkAt'),
            ('right','uminus','unot', 'uinspeccion'),                
        )


    # PROGRAMA
    def p_programa(p):
        ''' programa : declaracion TkExecute instlist TkDone
                          |  TkExecute instlist TkDone '''
        if len(p) == 5:
            p[0] = p[3]
        elif len(p) == 4:
            p[0] = p[2]


    # TERMINO UNARIO
    def p_term_num(p):
        ''' term : TkNum '''
        p[0] = numero(p[1])
        str_ = ""
        tabs = (contador+1)*"  "


    # IDENTIFICADOR
    def p_term_ident(p):
        ''' term : TkIdent '''
        p[0] = ident(p[1])
        str_ = ""
        tabs = (contador+1)*"  "


    # EXPRESION UNARIA ARITMETICA
    def p_exp_un(p):
        ''' exp_un : TkResta exp %prec uminus 
                      | TkNegacion exp %prec unot
                      | TkInspeccion exp %prec uinspeccion '''
        p[0] = op_un(p[1],p[2])


    # EXPRESION
    def p_exp(p): 
        ''' exp : term
                | exp_un
                | TkParAbre exp TkParCierra
                | TkCorcheteAbre exp TkCorcheteCierra
                | TkLlaveAbre exp TkLlaveCierra 
                | exp TkMas exp 
                | exp TkMult exp
                | exp TkMod exp
                | exp TkDiv exp
                | exp TkResta exp
                | TkTrue
                | TkFalse
                | exp TkIgual exp
                | exp TkDesigual exp
                | exp TkMenor exp
                | exp TkMayor exp
                | exp TkMenorIgual exp
                | exp TkMayorIgual exp
                | exp TkDisyuncion exp
                | exp TkConjuncion exp 
                | exp TkConcat exp '''

        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 4 and p[1] != '(' and p[1] != '[' and p[1] != '{':
            p[0] = op_bin(p[1],p[3],p[2])
        else:
            p[0] = p[2]
                

    # ASIGNACION
    def p_instruccion_asignacion(p):
        ''' instruccion : TkIdent TkAsignacion exp '''
        p[0] = inst_asig(p[1],p[3])


    # READ
    def p_instruccion_read(p):
        ''' instruccion : TkRead exp '''
        p[0] = inst_read(p[2])


    # WRITE
    def p_instruccion_write(p):
        ''' instruccion : TkWrite exp '''
        p[0] = inst_write(p[2])


    # WHILE
    def p_instruccion_while(p):
        ''' instruccion : TkWhile exp TkDo instlist TkDone '''
        p[0] = inst_while(p[2],p[4])


    # FOR
    def p_instruccion_for(p):
        ''' instruccion : TkFor TkIdent TkFrom exp TkTo exp TkDo instlist TkDone'''
        p[0] = inst_for(p[2],p[4],p[6],p[8])

    # IF
    def p_instruccion_if(p):
        ''' instruccion : TkIf exp TkThen instlist TkDone
                            | TkIf exp TkThen instlist TkElse instlist TkDone '''
        if len(p) == 6:
            p[0] = inst_if(p[2],p[4],None)
        else:
            p[0] = inst_if(p[2],p[4],p[6])


    # BLOQUE DE INSTRUCCIONES
    def p_instruccion_bloque(p):
        ''' instruccion :  declaracion TkExecute instlist TkDone
                            | TkExecute instlist TkDone '''
        if len(p) == 4:
            p[0] = inst_bloque(p[2])
        elif len(p) == 5:
            p[0] = inst_bloque(p[3])


    # BLOQUE DE B-INSTRUCCION (Ej: {lista_tape} At [a] )
    def p_instruccion_b(p):
        ''' instruccion : TkLlaveAbre lista_tape TkLlaveCierra TkAt ident_tape '''
        p[0] = inst_b(p[2], p[5])

    def p_ident_tape(p):
        ''' ident_tape : TkCorcheteAbre exp TkCorcheteCierra
                           | TkIdent '''
        if len(p) == 4:        
            p[0] = p[2]
        elif len(p) == 2:
            p[0] = p[1] 

 
    # LISTA DE SIMBOLOS DE B-INSTRUCCIONES (Ej: ++++--...>>><..)
    def p_lista_tape(p):
        ''' lista_tape : lista_tape simb_tape
                         | simb_tape '''
        if len(p) == 2:
            p[0] = []
            p[0].append(p[1])
        else:
            p[0] = p[1]
            p[0].append(p[2])

    def p_simb_tape(p):
        '''simb_tape : TkPunto
                         | TkMayor
                         | TkMenor
                         | TkMas
                         | TkResta
                         | TkComa '''
        p[0] = p[1]


    # SECUENCIACION DE INSTRUCCIONES
    def p_instlist(p):
        '''  instlist : instlist semicoloninst 
                      | instruccion '''
        if len(p) == 2:
            p[0] = inst_list()
            p[0].lista.append(p[1])
        elif len(p) == 3:
            p[0] = p[1]
            p[0].lista.append(p[2])
                
    def p_commainst(p):
        ''' semicoloninst : TkPuntoYComa instruccion '''
        p[0] = p[2]


    # DECLARACION
    def p_declaracion(p):
        ''' declaracion : TkDeclare declist '''

    def p_declist(p):
        ''' declist : dec TkPuntoYComa declist 
                    | dec '''

    def p_dec(p):
        ''' dec : varlist TkType tipo '''

    def p_varlist(p):
        '''varlist : TkIdent TkComa varlist 
                    | TkIdent '''

    def p_tipo_int(p):
        'tipo : TkInteger'

    def p_tipo_bool(p):
        'tipo : TkBoolean'

    def p_tipo_tape(p):
        'tipo : TkTape'


    #Funcion de error del parser
    def p_error(p):
        c = funciones.hallar_columna(codigo,p)
        print "Error de sintaxis en linea %s, columna %s: token \'%s\' inesperado." % (p.lineno,c,p.value[0])
        sys.exit(0)


    # Se construye la funcion del parser
    parser = yacc.yacc()


    # LOGGER

    # Set up a logging object
    import logging
    logging.basicConfig(
        level = logging.DEBUG,
        filename = "parselog.txt",
        filemode = "w",
        format = "%(filename)10s:%(lineno)4d:%(message)s"
    )
    log = logging.getLogger()

    # Se construye el árbol
    arbol = parser.parse(codigo,debug=log)

    # Se imprime el árbol
    print funciones.print_arbol(arbol)
예제 #2
0
def main():

    # Se abre el archivo y se guarda su contenido en el string codigo
    file_name = sys.argv[1]
    fp = open(file_name)
    codigo = fp.read()


    # Manejo de gramática y construccion de arbol

    # Definicion del símbolo inicial
    start = 'programa'

    # Precedencia de los operadores
    precedence = (
            ('left','TkDisyuncion'),
            ('left','TkConjuncion'),
            ('left','TkIgual','TkDesigual'),
            ('left','TkMenor','TkMayor','TkMayorIgual','TkMenorIgual'),
            ('left','TkMas','TkResta'),
            ('left','TkMult','TkDiv','TkMod'),
            ('left','TkConcat'),
            ('left','TkAt'),
            ('right','uminus','unot', 'uinspeccion'),                
        )


    # PROGRAMA
    def p_programa(p):
        ''' programa : declaracion TkExecute instlist TkDone
                          |  TkExecute instlist TkDone '''
        if len(p) == 5:
            p[0] = bloque(p[3], p[1])
        elif len(p) == 4:
            p[0] = bloque(p[2], None)


    # NUMERO
    def p_term_num(p):
        ''' term : TkNum '''
        p[0] = numero(p[1],p.lineno(1),funciones.find_column_parser(codigo,p.lexpos(1)))
        str_ = ""
        tabs = (contador+1)*"  "
        
    # TERMINO BOOLEANO
    def p_term_bool(p):
        ''' term : TkTrue
                | TkFalse '''
        p[0] = booleano(p[1],p.lineno(1),funciones.find_column_parser(codigo,p.lexpos(1)))

        
    # IDENTIFICADOR
    def p_term_ident(p):
        ''' term : TkIdent '''
        p[0] = ident(p[1],p.lineno(1),funciones.find_column_parser(codigo,p.lexpos(1)))
        str_ = ""
        tabs = (contador+1)*"  "


    # EXPRESION UNARIA
    def p_exp_un(p):
        ''' exp_un : TkResta exp %prec uminus 
                      | TkNegacion exp %prec unot
                      | TkInspeccion exp %prec uinspeccion '''
        p[0] = op_un(p[1],p[2],p.lineno(1),funciones.find_column_parser(codigo,p.lexpos(1)))


    # EXPRESION
    def p_exp(p): 
        ''' exp : term
                | exp_un
                | TkParAbre exp TkParCierra
                | TkCorcheteAbre exp TkCorcheteCierra
                | TkLlaveAbre exp TkLlaveCierra 
                | exp TkMas exp 
                | exp TkMult exp
                | exp TkMod exp
                | exp TkDiv exp
                | exp TkResta exp
                | exp TkIgual exp
                | exp TkDesigual exp
                | exp TkMenor exp
                | exp TkMayor exp
                | exp TkMenorIgual exp
                | exp TkMayorIgual exp
                | exp TkDisyuncion exp
                | exp TkConjuncion exp 
                | exp TkConcat exp '''

        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 4 and p[1] != '(' and p[1] != '[' and p[1] != '{':
            p[0] = op_bin(p[1],p[3],p[2])
        else:
            p[0] = p[2]
                

    # ASIGNACION
    def p_instruccion_asignacion(p):
        ''' instruccion : TkIdent TkAsignacion exp '''
        p[0] = inst_asig(p[1],p[3],p.lineno(1),funciones.find_column_parser(codigo,p.lexpos(1)))
        p[0].checktype()


    # READ
    def p_instruccion_read(p):
        ''' instruccion : TkRead exp '''
        p[0] = inst_read(p[2],p.lineno(2),funciones.find_column_parser(codigo,p.lexpos(1)))
        p[0].checktype()


    # WRITE
    def p_instruccion_write(p):
        ''' instruccion : TkWrite exp '''
        p[0] = inst_write(p[2])


    # WHILE
    def p_instruccion_while(p):
        ''' instruccion : TkWhile exp TkDo instlist TkDone '''
        p[0] = inst_while(p[2],p[4])
        p[0].checktype()


    # FOR
    def p_instruccion_for(p):
        ''' instruccion : TkFor TkIdent TkFrom exp TkTo exp TkDo instlist TkDone'''
        p[0] = inst_for(p[2],p[4],p[6],p[8],p.lineno(2),p.lexpos(2))
        p[0].checktype()


    # IF
    def p_instruccion_if(p):
        ''' instruccion : TkIf exp TkThen instlist TkDone
                            | TkIf exp TkThen instlist TkElse instlist TkDone '''
        if len(p) == 6:
            p[0] = inst_if(p[2],p[4],None)
        else:
            p[0] = inst_if(p[2],p[4],p[6])
        p[0].checktype()


    # BLOQUE DE INSTRUCCIONES
    def p_instruccion_bloque(p):
        ''' instruccion :  declaracion TkExecute instlist TkDone
                            | TkExecute instlist TkDone '''
        if len(p) == 4:
            p[0] = bloque(p[2], None)
        elif len(p) == 5:
            p[0] = bloque(p[3], p[1])
            stack.pop()


    # BLOQUE DE B-INSTRUCCION (Ej: {lista_tape} At [a] )
    def p_instruccion_b(p):
        ''' instruccion : TkLlaveAbre lista_tape TkLlaveCierra TkAt ident_tape '''
        p[0] = inst_b(p[2], p[5])

    def p_ident_tape(p):
        ''' ident_tape : TkCorcheteAbre exp TkCorcheteCierra
                           | TkIdent '''
        if len(p) == 4:        
            p[0] = p[2]
        elif len(p) == 2:
            p[0] = p[1] 

 
    # LISTA DE SIMBOLOS DE B-INSTRUCCIONES (Ej: ++++--...>>><..)
    def p_lista_tape(p):
        ''' lista_tape : lista_tape simb_tape
                         | simb_tape '''
        if len(p) == 2:
            p[0] = []
            p[0].append(p[1])
        else:
            p[0] = p[1]
            p[0].append(p[2])

    def p_simb_tape(p):
        '''simb_tape : TkPunto
                         | TkMayor
                         | TkMenor
                         | TkMas
                         | TkResta
                         | TkComa '''
        p[0] = p[1]


    # SECUENCIACION DE INSTRUCCIONES
    def p_instlist(p):
        '''  instlist : instlist semicoloninst 
                      | instruccion '''
        if len(p) == 2:
            p[0] = inst_list()
            p[0].lista.append(p[1])
        elif len(p) == 3:
            p[0] = p[1]
            p[0].lista.append(p[2])
                
    def p_commainst(p):
        ''' semicoloninst : TkPuntoYComa instruccion '''
        p[0] = p[2]


    # DECLARACION
    def p_declaracion(p):
        ''' declaracion : TkDeclare declist '''
        p[0] = declare(p[2],p.lineno(1),funciones.find_column_parser(codigo,p.lexpos(1)))

    def p_declist(p):
        ''' declist : dec TkPuntoYComa declist 
                    | dec '''
        if len(p) == 2:
            p[0] = []
            p[0].append(p[1])
        else:
            p[0] = p[3]
            p[0].append(p[1])

    def p_dec(p):
        ''' dec : varlist TkType tipo '''
        p[0] = dec(p[1],p[3])

    def p_varlist(p):
        ''' varlist : TkIdent TkComa varlist 
                    | TkIdent '''
        if len(p) == 2:
            p[0] = []
            p[0].append(p[1])
        else:
            p[0] = p[3]
            p[0].append(p[1])

    def p_tipo(p):
        ''' tipo : TkInteger
                | TkBoolean
                | TkTape '''
        p[0] = p[1]


    #Funcion de error del parser
    def p_error(p):
        c = funciones.print_column(codigo,p)
        str = "Error de sintaxis en linea %s, columna %s: token %s inesperado. \n" %(p.lineno, c, p.value[0])
        print str
        sys.exit(0)
        
        
    # Se construye la funcion del parser
    parser = yacc.yacc()


    # LOGGER

    # Set up a logging object
    import logging
    logging.basicConfig(
        level = logging.DEBUG,
        filename = "parselog.txt",
        filemode = "w",
        format = "%(filename)10s:%(lineno)4d:%(message)s"
    )
    log = logging.getLogger()

    # Se construye el árbol
    arbol = parser.parse(codigo,debug=log)

    # Se imprime el árbol
    if Analisis == '':
        print funciones.print_arbol(arbol)
    else:
        print Analisis	
예제 #3
0
def main():

    # Se abre el archivo y se guarda su contenido en el string codigo
    file_name = sys.argv[1]
    fp = open(file_name)
    codigo = fp.read()

    ####################################################
    #                    Manejo de gramática y construccion de arbol                                  #
    ####################################################

    # Definicion del símbolo inicial
    start = 'programa'

    # Precedencia de los operadores
    precedence = (
        ('left', 'TkDisyuncion'),
        ('left', 'TkConjuncion'),
        ('left', 'TkIgual', 'TkDesigual'),
        ('left', 'TkMenor', 'TkMayor', 'TkMayorIgual', 'TkMenorIgual'),
        ('left', 'TkMas', 'TkResta'),
        ('left', 'TkMult', 'TkDiv', 'TkMod'),
        ('left', 'TkConcat'),
        ('left', 'TkInspeccion'),
        ('left', 'TkAt'),
        ('right', 'uminus', 'unot'),
    )

    # PROGRAMA
    def p_programa(p):
        ''' programa : declaracion TkExecute instlist TkDone
                          |  TkExecute instlist TkDone '''
        if len(p) == 5:
            p[0] = p[3]
        elif len(p) == 4:
            p[0] = p[2]

    # TERMINO UNARIO
    def p_term_num(p):
        ''' term : TkNum '''
        p[0] = clases.numero(p[1])
        str_ = ""
        tabs = (contador + 1) * "  "

    # IDENTIFICADOR
    def p_term_ident(p):
        ''' term : TkIdent '''
        p[0] = clases.ident(p[1])
        str_ = ""
        tabs = (contador + 1) * "  "

    # EXPRESION UNARIA
    def p_exp_un(p):
        ''' exp_un : TkResta exp %prec uminus
                      | TkNegacion exp %prec unot '''
        p[0] = clases.op_un(p[1], p[2])

    # EXPRESION
    def p_exp(p):
        ''' exp : term
                | TkTrue
                | TkFalse
                | exp_un
                | TkParAbre exp TkParCierra
                | TkCorcheteAbre exp TkCorcheteCierra
                | TkLlaveAbre exp TkLlaveCierra
                | exp TkMas exp 
                | exp TkMult exp
                | exp TkMod exp
                | exp TkDiv exp
                | exp TkResta exp
                | exp TkIgual exp
                | exp TkDesigual exp
                | exp TkMenor exp
                | exp TkMayor exp
                | exp TkMenorIgual exp
                | exp TkMayorIgual exp
                | exp TkConcat exp
                | exp TkInspeccion exp
                | exp TkDisyuncion exp
                | exp TkConjuncion exp
                | exp TkAt exp '''
        #TkPunto
        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 4 and p[1] != '(' and p[1] != '[' and p[1] != '{':
            p[0] = clases.op_bin(p[1], p[3], p[2])
        else:
            p[0] = p[2]

    # ASIGNACION
    def p_instruccion_asignacion(p):
        ''' instruccion : TkIdent TkAsignacion exp '''
        p[0] = clases.inst_asig(p[1], p[3])

    # READ
    def p_instruccion_read(p):
        ''' instruccion : TkRead exp '''
        p[0] = clases.inst_read(p[2])

    # WRITE
    def p_instruccion_write(p):
        ''' instruccion : TkWrite exp '''
        p[0] = clases.inst_write(p[2])

    # WHILE
    def p_instruccion_while(p):
        ''' instruccion : TkWhile exp TkDo instlist TkDone '''
        p[0] = clases.inst_while(p[2], p[4])

    # FOR
    def p_instruccion_for(p):
        ''' instruccion : TkFor TkIdent TkFrom exp TkTo exp TkDo instlist TkDone'''
        p[0] = clases.inst_for(p[2], p[4], p[6], p[8])

    # IF
    def p_instruccion_if(p):
        ''' instruccion : TkIf exp TkThen instlist TkDone
			                | TkIf exp TkThen instlist TkElse instlist TkDone '''
        if len(p) == 6:
            p[0] = clases.inst_if(p[2], p[4], None)
        else:
            p[0] = clases.inst_if(p[2], p[4], p[6])

    # Gramatica del bloque de instrucciones
    def p_instruccion_bloque(p):
        ''' instruccion :  declaracion TkExecute instlist TkDone
                            | TkExecute instlist TkDone '''
        if len(p) == 4:
            p[0] = clases.inst_bloque(p[2])
        elif len(p) == 5:
            p[0] = clases.inst_bloque(p[3])

    # SECUENCIACION DE INSTRUCCIONES
    def p_instlist(p):
        '''  instlist : instlist semicoloninst 
                      | instruccion '''
        if len(p) == 2:
            p[0] = clases.inst_list()
            p[0].lista.append(p[1])
        elif len(p) == 3:
            p[0] = p[1]
            p[0].lista.append(p[2])

    def p_commainst(p):
        ''' semicoloninst : TkPuntoYComa instruccion '''
        p[0] = p[2]

    # DECLARACION
    def p_declaracion(p):
        ''' declaracion : TkDeclare declist '''

    def p_declist(p):
        ''' declist : dec TkPuntoYComa declist 
                    | dec '''

    def p_dec(p):
        ''' dec : varlist TkType tipo '''

    def p_varlist(p):
        '''varlist : TkIdent TkComa varlist 
                    | TkIdent '''

    def p_tipo_int(p):
        'tipo : TkInteger'

    def p_tipo_bool(p):
        'tipo : TkBoolean'

    def p_tipo_tape(p):
        'tipo : TkTape'

    #Funcion de error del parser
    def p_error(p):
        c = lexer.hallar_columna(codigo, p)
        print "Error de sintaxis en linea %s, columna %s: token \'%s\' inesperado." % (
            p.lineno, c, p.value)
        sys.exit(0)

    # Se construye la funcion del parser
    parser = yacc.yacc()

    # LOGGER

    # Set up a logging object
    import logging
    logging.basicConfig(level=logging.DEBUG,
                        filename="parselog.txt",
                        filemode="w",
                        format="%(filename)10s:%(lineno)4d:%(message)s")
    log = logging.getLogger()

    # Se construye el árbol.
    arbol = parser.parse(codigo, debug=log)

    # Se imprime el árbol.
    print funciones.print_arbol(arbol)
예제 #4
0
def main():

    # Se abre el archivo y se guarda su contenido en el string codigo
    file_name = sys.argv[1]
    fp = open(file_name)
    codigo = fp.read()



    # Identificadores de los tokens del lenguaje Brainiac
    tokens = ['TkComa',
              'TkPuntoYComa',
              'TkParAbre',
              'TkParCierra',
              'TkCorcheteAbre',
              'TkCorcheteCierra',
              'TkLlaveAbre',
              'TkLlaveCierra',
              'TkAsignacion',
              'TkType',
              'TkMas',
              'TkResta',
              'TkMult',
              'TkDiv',
              'TkMod',
              'TkConjuncion',
              'TkDisyuncion',
              'TkNegacion',
              'TkMenor',
              'TkMenorIgual',
              'TkMayor',
              'TkMayorIgual',
              'TkIgual',
              'TkDesigual',
              'TkConcat',
              'TkInspeccion',
              'TkIdent',
              'TkNum',
              'TkPunto'
             ]


    # Declaracion de lista de tokens a imprimir
    tok_lista = []


    # Diccionario con la lista de palabras reservadas del lenguaje Brainiac
    palabras_reservadas = {
             'if' : 'TkIf',
             'then' : 'TkThen',
             'else' : 'TkElse',
             'integer' : 'TkInteger',
             'boolean' : 'TkBoolean',
             'declare' : 'TkDeclare',
             'read' : 'TkRead',
             'write' : 'TkWrite',
             'do' : 'TkDo',
             'for' : 'TkFor',
             'done' : 'TkDone',
             'while' : 'TkWhile',
             'false' : 'TkFalse',
             'true' : 'TkTrue',
             'tape' : 'TkTape',
             'execute' : 'TkExecute',
             'to' : 'TkTo',
             'from' : 'TkFrom',
             'at' : 'TkAt'
    }


    tokens = tokens + list(palabras_reservadas.values())


    # A continuacion, se presentan las expresiones regulares para cada token
    def t_TkComa(t):
      r','
      tok_lista.append(t)
      return t


    def t_TkPunto(t):
      r'\.'
      tok_lista.append(t)
      return t


    def t_TkPuntoYComa(t):
       r';'
       tok_lista.append(t)
       return t


    def t_TkParAbre(t):
      r'\('
      tok_lista.append(t)
      return t


    def t_TkParCierra(t):
      r'\)'
      tok_lista.append(t)
      return t


    def t_TkCorcheteAbre(t):
      r'\['
      tok_lista.append(t)
      return t


    def t_TkCorcheteCierra(t):
      r'\]'
      tok_lista.append(t)
      return t


    def t_TkLlaveAbre(t):
      r'\{'
      tok_lista.append(t)
      return t


    def t_TkLlaveCierra(t):
      r'\}'
      tok_lista.append(t)
      return t


    def t_TkAsignacion(t):
      r':='
      tok_lista.append(t)
      return t


    def t_TkType(t):
      r':{2}'
      tok_lista.append(t)
      return t


    def t_TkMas(t):
      r'\+'
      tok_lista.append(t)
      return t


    def t_TkResta(t):
      r'-'
      tok_lista.append(t)
      return t


    def t_TkMult(t):
      r'\*'
      tok_lista.append(t)
      return t


    def t_TkConjuncion(t):
      r'/\\'
      tok_lista.append(t)
      return t

      
    def t_TkDesigual(t):
      r'/='
      tok_lista.append(t)
      return t

      
    def t_TkDiv(t):
      r'/'
      tok_lista.append(t)
      return t


    def t_TkMod(t):
      r'%'
      tok_lista.append(t)
      return t

      
    def t_TkDisyuncion(t):
      r'\\/'
      tok_lista.append(t)
      return t


    def t_TkMenor(t):
      r'<'
      tok_lista.append(t)
      return t


    def t_TkMenorIgual(t):
      r'<='
      tok_lista.append(t)
      return t


    def t_TkMayor(t):
      r'>'
      tok_lista.append(t)
      return t


    def t_TkMayorIgual(t):
      r'>='
      tok_lista.append(t)
      return t


    def t_TkIgual(t):
      r'='
      tok_lista.append(t)
      return t


    def t_TkNegacion(t):
      r'\~'
      tok_lista.append(t)
      return t


    def t_TkConcat(t):
      r'&'
      tok_lista.append(t)
      return t


    def t_TkInspeccion(t):
      r'\#'
      tok_lista.append(t)
      return t


    def t_TkNum(t):
      r'\d+'
      t.value = int(t.value)
      tok_lista.append(t)
      return t


    def t_TkIdent(t):
       r"[a-zA-Z_][a-zA-Z0-9]*"
       t.type = palabras_reservadas.get(t.value, "TkIdent")
       tok_lista.append(t)
       return t


    def t_SaltoLinea(t):
       r'\n+'
       t.lexer.lineno += len(t.value)


    # Ignorar todos los espacios en blanco, salvo saltos de linea
    t_ignore_EspaciosEnBlanco = r'[ \t\f\r\v]+' 


    # Ignorar los comentarios hasta que se llegue a un salto de linea
    t_ignore_Comentarios = r'\$-(.|\n)*?-\$|\${2}[^\n]*'


    # Funcion para hallar el nro de columna
    def hallar_columna(input, t):
        inicio = input.rfind('\n',0,t.lexpos)
        # Si es el primer token de la primera línea, su posición es 1
        if inicio < 0 and t.lexpos == 0:         
            inicio = 0
            return 1
        column = (t.lexpos - inicio)
        return column


    # Funcion para obtener errores en una lista
    def t_error(t):
        c = hallar_columna(codigo,t)
        print "Error: caracter inesperado \"%s\" en linea %s, columna %s." % (t.value[0],t.lineno,c)
        sys.exit(0)                
        return t



    ####################################################
    #                                                        CLASES                                                     #
    ####################################################

    # Clase para NUMERO
    class numero:
        def __init__(self,value):
            self.type = "Numero"
            self.value = value
        def __str__(self):
            global contador
            contador = contador + 1
            tabs = "  "*contador
            str_ = str(self.value)
            contador = contador - 1
            return str_

    # Clase para IDENTIFICADOR           
    class ident:
        def __init__(self,name):
            self.type = "Identificador: "
            self.name = name
        def __str__(self):
            global contador
            contador = contador + 1
            tabs = "  "*contador
            str_ =  str(self.name)
            contador = contador - 1
            return str_

    # Clase para EXPRESION UNARIA
    class op_un:
        def __init__(self,pre,e):                        
            self.pre = pre
            self.e = e
        def __str__(self):
            global contador
            contador = contador + 1
            tabs = "  "*contador
            str_ = "EXPRESION_UNARIA\n" + tabs + "Operador: " + str(self.pre) + "\n" + tabs +  "Valor: "  + str(self.e)
            contador = contador - 1
            return str_

    # Clase para EXPRESION BINARIA                       
    class op_bin:
        def __init__(self,left,right,op):
            self.left = left
            self.right = right
            self.op = op
            if op == '+':
                self.op = 'Suma'
            elif op == '-':
                self.op = 'Resta'
            elif op == '~':
                self.op = 'Negacion'
            elif op == '*':
                self.op = 'Multiplicacion'
            elif op == '%':
                self.op = 'Modulo'
            elif op == '/':
                self.op = 'Division'
            elif op == '=':
                self.op = 'Igual'
            elif op == '/=':
                self.op = 'Desigual'
            elif op == '<':
                self.op = 'Menor que'
            elif op == '>':
                self.op = 'Mayor que'
            elif op == '>=':
                self.op = 'Mayor o igual que'
            elif op == '<=':
                self.op = 'Menor o igual que'
            elif op == '&':
                self.op = 'Concatenacion'
            elif op == '#':
                self.op = 'Inspeccion'
            elif op == '\/':
                self.op = 'Or'
            #elif op == '/\':
             #   self.op = 'And'
            else:
                self.op = 'And'

        def __str__(self):
            global contador
            contador = contador + 1
            tabs = contador*"  "
            tabs_plus =  "  " + tabs
            str_ = "EXPRESION_BINARIA\n" + tabs  + "Operacion: " + str(self.op) + "\n"  
            str_ = str_ + tabs + "Operador izquierdo: " + str(self.left) + "\n"  + tabs + "Operador derecho: " + str(self.right)  + " "
            contador = contador - 1
            return str_

    # Clase para ITERACION_INDETERMINADA
    class inst_while:
        def __init__(self,cond,inst):
            self.cond = cond
            self.inst = inst

        def __str__(self):
            global contador
            contador = contador + 1
            tabs = "  "*contador
            str_ = "ITERACION_INDETERMINADA\n" + tabs + "Condicion: " 
            str_ = str_+ str(self.cond) + "\n" + tabs + "Instruccion: " + str(self.inst)
            contador = contador - 1
            return str_

    # Clase para ITERACION_DETERMINADA
    class inst_for:
        def __init__(self,ident,inf,sup,inst):
            self.ident = ident
            self.inf = inf
            self.sup = sup
            self.inst = inst

        def __str__(self):
            global contador
            contador = contador + 1
            tabs = "  "*contador
            str_ = "ITERACION_DETERMINADA\n" + tabs + "Identificador: " + str(self.ident) 
            str_ = str_ + "\n" + tabs + "Cota inf: " + str(self.inf) +", Cota sup: " 
            str_ = str_ + str(self.sup) + "\n" + tabs + "Instruccion: " + str(self.inst)
            contador = contador - 1
            return str_

    # Clase para CONDICIONAL
    class inst_if:
        def __init__(self,cond,instr0,instr1):
            self.cond = cond
            self.instr0 = instr0
            self.instr1 = instr1
        def __str__(self):
            global contador
            contador = contador + 1
            tabs = "  "*contador
            aux = ""
            if self.instr1 != None:
                aux = "\n" +tabs + "Else: " + str(self.instr1)
            str_ = "CONDICIONAL\n" + tabs + "Guardia: " + str(self.cond) + "\n" + tabs + "Exito: " + str(self.instr0) + aux  
            contador = contador - 1
            return str_

    # Clase para B-INSTRUCCION
    class inst_b:
        def __init__(self, slist, ident):
            self.slist = slist
            self.ident = ident
        def __pop__(self):
            return self.slist.pop()
        def __len__(self):
            return len(self.slist)
        def __str__(self):
            global contador
            contador = contador +1
            tabs = "  "*contador
            lista_simbolos = ""
            for elem in self.slist:
                lista_simbolos = lista_simbolos + str(elem)
            str_ = "B-INSTRUCCION\n" + tabs + "Lista de simbolos: " + lista_simbolos + "\n" 
            straux = tabs + "Identificador: " + str(self.ident) + " "
            contador = contador - 1
            return str_ + straux

    # Clase para ASIGNACION
    class inst_asig:
        def __init__(self,ident,val):
            self.ident = ident
            self.val = val
        def __str__(self):          
            global contador
            contador = contador + 1
            tabs = "  "*contador
            str_ = "ASIGNACION\n" + tabs + "Identificador: " + str(self.ident) + "\n" + tabs + "Valor: " + str(self.val)
            contador = contador - 1
            return str_

    # Clase para READ
    class inst_read:
        def __init__(self,ident):
            self.ident = ident
        def __str__(self):
            global contador      
            contador = contador + 1
            tabs = "  "*contador
            str_ = "READ\n" + tabs + "Identificador: " +  str(self.ident.name)
            contador = contador - 1
            return str_

    # Clase para WRITE
    class inst_write:
        def __init__(self,expr):
            self.expr = expr
        def __str__(self):
            global contador
            contador += 1
            tabs = contador*"  "
            strw = "WRITE"
            str0 = strw + "\n"
            str1 = ""
            strs = "CADENA\n" + tabs + "  " + "Valor: "
            str1 = tabs + "Elemento: " + strs + str(self.expr) + str1
            contador = contador - 1
            return str0 + str1

    # Clase para SECUENCIACION
    class inst_list:
        def __init__(self):
            self.lista = []
        def __len__(self):
            return len(self.lista)
        def __pop__(self):
            return self.lista.pop()
        def __str__(self):
            global contador
            contador = contador + 1
                        
            self.lista.reverse()
            str_ = "SECUENCIACION\n"
            contador = contador + 1
            tabs = contador*"  "
            if len(self.lista) == 1 :
                str_ = ""
                elemento =  self.lista.pop()
                str_ = str_ +   str(elemento)
                return str_
            while self.lista:
                elemento =  self.lista.pop()
                str_ = str_ + tabs +   str(elemento)
                if len(self.lista) != 0:
                    str_ = str_ +  "\n" + tabs + "\n"
            contador = contador - 1
            return str_

        def print_(self,contador):
            self.lista.reverse()

            while self.lista:
                elemento =  self.lista.pop()
                elemento.print_(contador,0)
                tabs = contador*"  "
                if len(self.lista) != 0:
                    str_ = str_ + ";"
            return str_

    # Clase para BLOQUE
    class bloque:
        def __init__(self,lista):
            self.lista = lista
        def __len__(self):
            return len(self.lista)
        def __str__(self):
            global contador
            contador = contador + 1
            tabs = "  "*contador
            str_ = "BLOQUE\n"
            str_ = str_ + str(self.lista)
            contador = contador - 1
            return str_
                        

    ####################################################
    #                    Manejo de gramática y construccion de arbol                                  #
    ####################################################


    # Definicion del símbolo inicial
    start = 'programa'

    # Precedencia de los operadores
    precedence = (
            ('left','TkDisyuncion'),
            ('left','TkConjuncion'),
            ('left','TkIgual','TkDesigual'),
            ('left','TkMenor','TkMayor','TkMayorIgual','TkMenorIgual'),
            ('left','TkMas','TkResta'),
            ('left','TkMult','TkDiv','TkMod'),
            ('left','TkConcat'),
            ('left','TkAt'),
            ('right','uminus','unot', 'uinspeccion'),                
        )

    # PROGRAMA
    def p_programa(p):
        ''' programa : declaracion TkExecute instlist TkDone
                          |  TkExecute instlist TkDone '''
        if len(p) == 5:
            p[0] = p[3]
        elif len(p) == 4:
            p[0] = p[2]


    # TERMINO UNARIO
    def p_term_num(p):
        ''' term : TkNum '''
        p[0] = numero(p[1])
        str_ = ""
        tabs = (contador+1)*"  "


    # IDENTIFICADOR
    def p_term_ident(p):
        ''' term : TkIdent '''
        p[0] = ident(p[1])
        str_ = ""
        tabs = (contador+1)*"  "


    # EXPRESION UNARIA ARITMETICA
    def p_exp_un(p):
        ''' exp_un : TkResta exp %prec uminus 
                      | TkNegacion exp %prec unot
                      | TkInspeccion exp %prec uinspeccion '''
        p[0] = op_un(p[1],p[2])


    # EXPRESION 
    def p_exp(p): 
        ''' exp : term
                | exp_un
                | TkParAbre exp TkParCierra
                | TkCorcheteAbre exp TkCorcheteCierra
                | TkLlaveAbre exp TkLlaveCierra 
                | exp TkMas exp 
                | exp TkMult exp
                | exp TkMod exp
                | exp TkDiv exp
                | exp TkResta exp
                | TkTrue
                | TkFalse
                | exp TkIgual exp
                | exp TkDesigual exp
                | exp TkMenor exp
                | exp TkMayor exp
                | exp TkMenorIgual exp
                | exp TkMayorIgual exp
                | exp TkDisyuncion exp
                | exp TkConjuncion exp 
                | exp TkConcat exp '''

        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 4 and p[1] != '(' and p[1] != '[' and p[1] != '{':
            p[0] = op_bin(p[1],p[3],p[2])
        else:
			p[0] = p[2]


    # ASIGNACION
    def p_instruccion_asignacion(p):
        ''' instruccion : TkIdent TkAsignacion exp '''
        p[0] = inst_asig(p[1],p[3])


    # READ
    def p_instruccion_read(p):
        ''' instruccion : TkRead exp '''
        p[0] = inst_read(p[2])


    # WRITE
    def p_instruccion_write(p):
        ''' instruccion : TkWrite exp '''
        p[0] = inst_write(p[2])


    # WHILE
    def p_instruccion_while(p):
        ''' instruccion : TkWhile exp TkDo instlist TkDone '''
        p[0] = inst_while(p[2],p[4])


    # FOR
    def p_instruccion_for(p):
        ''' instruccion : TkFor TkIdent TkFrom exp TkTo exp TkDo instlist TkDone'''
        p[0] = inst_for(p[2],p[4],p[6],p[8])


    # IF
    def p_instruccion_if(p):
        ''' instruccion : TkIf exp TkThen instlist TkDone
			                | TkIf exp TkThen instlist TkElse instlist TkDone '''
        if len(p) == 6:
            p[0] = inst_if(p[2],p[4],None)
        else:
            p[0] = inst_if(p[2],p[4],p[6])


    # Gramatica del bloque de instrucciones
    def p_instruccion_bloque(p):
        ''' instruccion :  declaracion TkExecute instlist TkDone
                            | TkExecute instlist TkDone '''
        if len(p) == 4:
            p[0] = inst_bloque(p[2])
        elif len(p) == 5:
            p[0] = inst_bloque(p[3])


    # BLOQUE DE B-INSTRUCCION (Ej: {lista_tape} At [a] )
    def p_instruccion_b(p):
        ''' instruccion : TkLlaveAbre lista_tape TkLlaveCierra TkAt ident_tape '''
        p[0] = inst_b(p[2], p[5])

    def p_ident_tape(p):
        ''' ident_tape : TkCorcheteAbre exp TkCorcheteCierra
                           | TkIdent '''
        if len(p) == 4:        
            p[0] = p[2]
        elif len(p) == 2:
            p[0] = p[1] 

 
    # LISTA DE SIMBOLOS DE B-INSTRUCCIONES (Ej: ++++--...>>><..)
    def p_lista_tape(p):
        ''' lista_tape : lista_tape simb_tape
                         | simb_tape '''
        if len(p) == 2:
            p[0] = []
            p[0].append(p[1])
        else:
            p[0] = p[1]
            p[0].append(p[2])

    def p_simb_tape(p):
        '''simb_tape : TkPunto
                         | TkMayor
                         | TkMenor
                         | TkMas
                         | TkResta
                         | TkComa '''
        p[0] = p[1]

   # SECUENCIACION DE INSTRUCCIONES
    def p_instlist(p):
        '''  instlist : instlist semicoloninst 
                      | instruccion '''
        if len(p) == 2:
            p[0] = inst_list()
            p[0].lista.append(p[1])
        elif len(p) == 3:
            p[0] = p[1]
            p[0].lista.append(p[2])
                
    def p_commainst(p):
        ''' semicoloninst : TkPuntoYComa instruccion '''
        p[0] = p[2]


    # DECLARACION
    def p_declaracion(p):
        ''' declaracion : TkDeclare declist '''

    def p_declist(p):
        ''' declist : dec TkPuntoYComa declist 
                    | dec '''

    def p_dec(p):
        ''' dec : varlist TkType tipo '''

    def p_varlist(p):
        '''varlist : TkIdent TkComa varlist 
                    | TkIdent '''

    def p_tipo_int(p):
        'tipo : TkInteger'

    def p_tipo_bool(p):
        'tipo : TkBoolean'

    def p_tipo_tape(p):
        'tipo : TkTape'


    #Funcion de error del parser
    def p_error(p):
        c = hallar_columna(codigo,p)
        print "Error de sintaxis en linea %s, columna %s: token \'%s\' inesperado." % (p.lineno,c,p.value)
        sys.exit(0)


    # Construccion del lexer 
    lexer = lex.lex()
    lexer.input(codigo)


    errores = False 
    while True:
        tok  = lexer.token()
        if not tok: break
        if tok.type == 'error':
            errores = True
            continue

    # Si hay errores, se imprime el primero y aborta
    if errores:
        sys.exit(0)

    lexer.lineno = 1

    # Se construye la funcion del parser
    parser = yacc.yacc()


    # LOGGER

    # Set up a logging object
    import logging
    logging.basicConfig(
    level = logging.DEBUG,
    filename = "parselog.txt",
    filemode = "w",
    format = "%(filename)10s:%(lineno)4d:%(message)s"
    )
    log = logging.getLogger()

    # Se construye el árbol.
    arbol = parser.parse(codigo,debug=log)

    # Se imprime el árbol.
    print funciones.print_arbol(arbol)