def Analiza(self): ch=leerCaracter if ch==" ": # quitar todos los caracteres blancos #buscar el siguiente componente lexico que sera devuelto ) elif ch== "+": # debe crearse un objeto de la clasee OpAdd que sera devuelto elif #asi con todos los simbolos y operadores del lenguaje return componentes.CorCi() elif ch == "{": #Saltar todos los caracteres del comentario # y encontrar el siguiente componente lexico elif ch == "}": print "ERROR: Comentario no abierto" # tenemos un comentario no abierto return self.Analiza() elif ch==":": #Comprobar con el siguiente caracter si es una definicion de la declaracion o el operador de asignacion elif #Completar los operadores y categorias lexicas que faltan elif ch es un caracter #leer entrada hasta que no sea un caracter valido de un identificador #devolver el ultimo caracter a la entrada # Comprobar si es un identificador o PR y devolver el objeto correspondiente elif ch es numero: #Leer todos los elementos que forman el numero # devolver el ultimo caracter que ya no pertenece al numero a la entrada # Devolver un objeto de la categoria correspondiente elif ch== "\n":
def Analiza(self): ch = self.flujo.siguiente() if ch == " ": # quitar todos los caracteres blancos return self.Analiza() # buscar el siguiente componente lexico que sera devuelto ) elif ch == "+": return componentes.OpAdd("SimSum", self.nlinea) elif ch == "-": return componentes.OpAdd("SimRest", self.nlinea) # debe crearse un objeto de la clasee OpAdd que sera devuelto elif ch == "*": return componentes.OpMult("SimMult", self.nlinea) elif ch == "/": return componentes.OpMult("SimDiv", self.nlinea) elif ch == "[": return componentes.CorAp() elif ch == "]": # asi con todos los simbolos y operadores del lenguaje return componentes.CorCi() elif ch == "{": # Saltar todos los caracteres del comentario while(ch != "}"): ch = self.flujo.siguiente() # Comprobamos que hemos cerrado el comentario if ch != "}": print "ERROR: Comentario no cerrado" # tenemos un comentario no cerrado # y encontrar el siguiente componente lexico return self.Analiza() elif ch == "}": print "ERROR: Comentario no abierto" # tenemos un comentario no abierto return self.Analiza() elif ch == ":": # Comprobar con el siguiente caracter si es una definicion de la declaracion o el operador de asignacion ch = self.flujo.siguiente() if ch == '=': return componentes.OpAsigna() else: self.flujo.devuelve(ch) return componentes.DosPtos() elif ch == '(': return componentes.ParentAp() elif ch == ')': return componentes.ParentCi() elif ch == '.': return componentes.Punto() elif ch == ',': return componentes.Coma() elif ch == ';': return componentes.PtoComa() elif ch == ':': return componentes.DosPtos() elif ch == "=": return componentes.OpRel("SimIgual", self.nlinea) elif ch == "<": ch = self.flujo.siguiente() if ch == ">": return componentes.OpRel("SimDist", self.nlinea) elif ch == "=": return componentes.OpRel("SimMenIgual", self.nlinea) else: self.flujo.devuelve(ch) return componentes.OpRel("SimMenor", self.nlinea) elif ch == ">": ch = self.flujo.siguiente() if ch == "=": return componentes.OpRel("SimMayIgual", self.nlinea) else: self.flujo.devuelve(ch) return componentes.OpRel("SimMayor", self.nlinea) elif ch.isalpha(): # leer entrada hasta que no sea un caracter valido de un identificador cadena = "" + ch ch = self.flujo.siguiente() while ch.isalnum(): cadena = cadena + ch ch = self.flujo.siguiente() # devolver el ultimo caracter a la entrada self.flujo.devuelve(ch) # Comprobar si es un identificador o PR y devolver el objeto correspondiente if(cadena in Analex.PR): return componentes.PR(cadena, self.nlinea) else: return componentes.Identif(cadena, self.nlinea) elif ch.isdigit(): # Leer todos los elementos que forman el numero numero = "" + ch puntoDetectado = 0 ch = self.flujo.siguiente() while ch.isdigit(): numero = numero + ch ch = self.flujo.siguiente() # Es un entero if ch != ".": self.flujo.devuelve(ch) return componentes.Numero(numero, self.nlinea, "ENTERO") # Puede ser un real else: real = numero + ch ch = self.flujo.siguiente() #Guardamos el numero de digitos decimales digitosDecimales = 0 # Comprobamos que lo siguiente del punto sea un digito while ch.isdigit(): digitosDecimales += 1 real = real + ch ch = self.flujo.siguiente() # devolver el ultimo caracter que ya no pertenece al numero a la entrada self.flujo.devuelve(ch) # No es un valor de tipo de real. Devolvemos el tipo entero if digitosDecimales == 0: self.flujo.devuelve(ch) #Devolvemos el caracter decimal al flujo de entrada return componentes.Numero(numero, self.nlinea, "ENTERO") # Es un valor real. Devolvemos el tipo real else: return componentes.Numero(real, self.nlinea, "REAL") elif ch == "\n": # incrementa el numero de linea ya que acabamos de saltar a otra self.nlinea += 1 # devolver el siguiente componente encontrado return self.Analiza() elif ch != "": return self.Analiza() else: if self.eof: return else: self.eof = True return componentes.EOF()
def Analiza(self): ch = self.flujo.siguiente() #print('Caracter: ' + ch) if ch == " ": while ch == " ": ch = self.flujo.siguiente() self.flujo.devuelve(ch) return self.Analiza() elif ch == "+": return componentes.OpAdd("+", self.nlinea) elif ch == "-": return componentes.OpAdd("-", self.nlinea) elif ch == "*": return componentes.OpMult("*", self.nlinea) elif ch == "/": return componentes.OpMult("/", self.nlinea) elif ch == "(": return componentes.ParentAp() elif ch == ")": return componentes.ParentCi() elif ch == "[": return componentes.CorAp() elif ch == "]": return componentes.CorCi() elif ch == ".": return componentes.Punto() elif ch == ",": return componentes.Coma() elif ch == ";": return componentes.PtoComa() elif ch == "{": while ch != "}": ch = self.flujo.siguiente() return self.Analiza() elif ch == "}": print "ERROR: Comentario no abierto" # tenemos un comentario no abierto return self.Analiza() elif ch == ":": newCh = self.flujo.siguiente() if newCh == "=": return componentes.OpAsigna() else: self.flujo.devuelve(newCh) return componentes.DosPtos() elif ch.isalpha(): word = "" while ((ch).isalnum()): word += ch ch = self.flujo.siguiente() self.flujo.devuelve(ch) if word in self.PR: return componentes.PR(word, self.nlinea) else: return componentes.Identif(word, self.nlinea) elif ch.isdigit(): num = "" num += ch ch = self.flujo.siguiente() while (ch.isdigit()): num += ch ch = self.flujo.siguiente() if (ch != '.'): self.flujo.devuelve(ch) return componentes.Numero(num, self.nlinea, 'ENTERO') else: newCh = self.flujo.siguiente() if not (newCh.isdigit()): self.flujo.devuelve(newCh) self.flujo.devuelve(ch) print "ERROR: NUMERO REAL MAL ESPECIFICADO" # tenemos un comentario no abierto return self.Analiza() num += ch num += newCh ch = self.flujo.siguiente() while ((ch).isdigit()): num += ch ch = self.flujo.siguiente() self.flujo.devuelve(ch) return componentes.Numero(num, self.nlinea, 'REAL') elif (ch is not '' and ord(ch) == 13): self.nlinea += 1 return self.Analiza() elif (ch is not '' and ord(ch) == 10): self.nlinea += 1 return self.Analiza() elif (ch is not '' and ord(ch) == 9): return self.Analiza() elif ch == '=': return componentes.OpRel('=', self.nlinea) elif ch == '<': newCh = self.flujo.siguiente() if newCh == '>': return componentes.OpRel('<>', self.nlinea) elif newCh == '=': return componentes.OpRel('<=', self.nlinea) else: self.flujo.devuelve(newCh) return componentes.OpRel('<', self.nlinea) elif ch == '>': newCh = self.flujo.siguiente() if newCh == '=': return componentes.OpRel('>=', self.nlinea) else: self.flujo.devuelve(newCh) return componentes.OpRel('>', self.nlinea) elif len(ch) is not 0: print "ERROR: CARACTER NO DEFINIDO EN LA ESPECIFICACION DEL LENGUAJE" return self.Analiza() else: return componentes.EOF()
def Analiza(self): ch=self.fl.siguiente() if ch==" ": # quitar todos los caracteres blancos #buscar el siguiente componente lexico que sera devuelto ) return self.Analiza() elif ch=='': # cuando ya no encuentre nada acaba return elif ch=="+" or ch=="-": # debe crearse un objeto de la clasee OpAdd que sera devuelto return componentes.OpAdd(ch,self.nlinea) elif ch=="*" or ch=="/": # debe crearse un objeto de la clasee OpMult que sera devuelto return componentes.OpMult(ch,self.nlinea) elif ch=="=": # debe crearse un objeto de la clasee OpRel que sera devuelto return componentes.OpRel(ch,self.nlinea) elif ch=="<": # debe crearse un objeto de la clasee OpRel que sera devuelto ch2=self.fl.siguiente() if ch2==">": return componentes.OpRel(ch+ch2,self.nlinea) elif ch2=="=": return componentes.OpRel(ch+ch2,self.nlinea) else: return componentes.OpRel(ch,self.nlinea) elif ch==">": # debe crearse un objeto de la clasee OpRel que sera devuelto ch2=self.fl.siguiente() if ch2=="=": return componentes.OpRel(ch+ch2,self.nlinea) else: return componentes.OpRel(ch,self.nlinea) #asi con todos los simbolos y operadores del lenguaje elif ch==",": return componentes.Coma() elif ch=="(": return componentes.ParentAp() elif ch==")": return componentes.ParentCi() elif ch=="[": return componentes.CorAp() elif ch=="]": return componentes.CorCi() elif ch==".": return componentes.Punto() elif ch==";": return componentes.PtoComa() elif ch == "{": #Saltar todos los caracteres del comentario # y encontrar el siguiente componente lexico while ch!="}": ch=self.fl.siguiente() return self.Analiza() elif ch == "}": print("ERROR: Comentario no abierto") # tenemos un comentario no abierto return elif ch==":": #Comprobar con el siguiente caracter si es una definicion de la declaracion o el operador de asignacion ch=self.fl.siguiente() if ch=="=": return componentes.OpAsigna() else: self.fl.devuelve(ch) return componentes.DosPtos() # Compruebo si el valor ascii del caracter esta en el rango de las letras posibles elif ord(ch) in self.letra_minus or ord(ch) in self.letra_mayus: cadena=ch ch=self.fl.siguiente() #leer entrada hasta que no sea un caracter valido de un identificador while ord(ch) in self.letra_minus or ord(ch) in self.letra_mayus or ord(ch) in self.numero: cadena += ch ch=self.fl.siguiente() #devolver el ultimo caracter a la entrada self.fl.devuelve(ch) # Comprobar si es un identificador o PR y devolver el objeto correspondiente if cadena in self.PR: return componentes.PR(cadena, self.nlinea) else: return componentes.Identif(cadena, self.nlinea) # Compruebo si el caracter es un numero elif ord(ch) in self.numero: punto=False num=ch ch=self.fl.siguiente() # Leer todos los elementos que forman el numero while ord(ch) in self.numero: num += ch ch=self.fl.siguiente() # Si leo un punto, entonces sera un numero real if ch==".": punto=True num += ch ch=self.fl.siguiente() while ord(ch) in self.numero: num += ch ch=self.fl.siguiente() self.fl.devuelve(ch) # Devolver un objeto de la categoria correspondiente if punto : return componentes.Numero(float(num),self.nlinea,'REAL') else: return componentes.Numero(int(num),self.nlinea,'ENTERO') elif ch== "\n": #incrementa el numero de linea ya que acabamos de saltar a otra # devolver el siguiente componente encontrado self.nlinea+=1 return self.Analiza() else: return self.Analiza()
def Analiza(self): ch = self.flujo.siguiente() ## ESPACIO BLANCO ## if ch == " ": # quitar todos los caracteres blancos # buscar el siguiente componente lexico que sera devuelto ### IMPORTANTE ### # Hacer un bucle que mientras tengamos caracteres en blanco, pase al siguiente # Una vez nos encontremos con un caracter "no en blanco" llamar otra vez a ANALIZA return self.Analiza() ## OPERADORES ARITMETICOS ## elif ch == "+": return componentes.OpAdd(ch, self.nlinea) elif ch == "-": return componentes.OpAdd(ch, self.nlinea) elif ch == "*": return componentes.OpMult(ch, self.nlinea) elif ch == "/": return componentes.OpMult(ch, self.nlinea) ## OPERADOR RELACIONALES ## elif ch == "<": ch = self.flujo.siguiente() if ch == "=": return componentes.OpRel("<=", self.nlinea) elif ch == ">": return componentes.OpRel("<>", self.nlinea) else: self.flujo.devuelve(ch) return componentes.OpRel("<", self.nlinea) elif ch == ">": ch = self.flujo.siguiente() if ch == "=": return componentes.OpRel(">=", self.nlinea) else: self.flujo.devuelve(ch) return componentes.OpRel(">", self.nlinea) elif ch == "=": return componentes.OpRel(ch, self.nlinea) ## COMENTARIOS ## elif ch == "{": # Saltar todos los caracteres del comentario y encontrar el siguiente componente lexico while ch != "}": ch = self.flujo.siguiente() ch = self.flujo.siguiente() elif ch == "}": return errores.ErrorLexico( "Comentario no abierto") # tenemos un comentario no abierto ## ASIGNACION ## elif ch == ":": # Comprobar con el siguiente caracter si es una definicion de la declaracion o el operador de asignacion ch = self.flujo.siguiente() if ch == "=": return componentes.OpAsigna(self.nlinea) else: self.flujo.devuelve(ch) return componentes.DosPtos(self.nlinea) ## OPERADORES Y CATEGORIAS LEXICAS QUE FALTAN ## # Completar los operadores y categorias lexicas que faltan elif ch == "(": return componentes.ParentAp(self.nlinea) elif ch == ")": return componentes.ParentCi(self.nlinea) elif ch == "[": return componentes.CorAp(self.nlinea) elif ch == "]": return componentes.CorCi(self.nlinea) elif ch == ";": return componentes.PtoComa(self.nlinea) elif ch == ",": return componentes.Coma(self.nlinea) ## CARACTERES ## elif ch.lower() in list(string.ascii_lowercase): ident = [] while (ch.lower() in list( string.ascii_lowercase)) or (ch in self.listaNumeros): ident.append(ch) ch = self.flujo.siguiente() self.flujo.devuelve(ch) ## PALABRAS CLAVE ## for x in self.PR: if x == ''.join(ident): return componentes.PR(x, self.nlinea) return componentes.Identif(''.join(ident), self.nlinea) ## NUMEROS ## elif any(ch == x for x in self.listaNumeros): hayPunto = False numero = [] numero.append(ch) ch = self.flujo.siguiente() lista = [] while (ch in self.listaNumeros or ch == "."): if ch in self.listaNumeros: numero.append(ch) ch = self.flujo.siguiente() else: if not hayPunto: numero.append(ch) hayPunto = True ch = self.flujo.siguiente() else: self.flujo.devuelve(ch) return componentes.Numero(''.join(numero), self.nlinea) self.flujo.devuelve(ch) if hayPunto: return componentes.Numero(''.join(numero), "real", self.nlinea) else: return componentes.Numero(''.join(numero), "entero", self.nlinea) # Leer todos los elementos que forman el numero # devolver el ultimo caracter que ya no pertenece al numero a la entrada # Devolver un objeto de la categoria correspondiente ## TABULACION ## elif ch == "\t": # devolver el siguiente componente encontrado return self.Analiza() ## SALTO DE LINEA ## elif ch == "\n": # incrementa el numero de linea ya que acabamos de saltar a otra self.nlinea += 1 # devolver el siguiente componente encontrado return self.Analiza() elif ch == ".": return componentes.Punto(self.nlinea) elif True: return errores.ErrorLexico("Caracter no permitido.")