he implementado un escáner basado en el generador de Python que tokenizes una cadena en tuplas de la forma (tipo de token, un valor simbólico):El uso de búsqueda hacia delante con los generadores
for token in scan("a(b)"):
print token
imprimiría
("literal", "a")
("l_paren", "(")
...
La siguiente tarea implica analizar el flujo de tokens y, para eso, necesito poder mirar un elemento por delante del actual sin mover también el puntero hacia adelante. El hecho de que los iteradores y generadores no proporcionen la secuencia completa de elementos a la vez pero que cada elemento según sea necesario hace que lookaheads sea un poco más complicado en comparación con las listas, ya que el próximo elemento no se conoce a menos que se llame al __next__()
.
¿Cómo podría ser una implementación sencilla de un lookahead basado en un generador? Actualmente estoy usando una solución que implica hacer una lista del generador:
token_list = [token for token in scan(string)]
La búsqueda hacia delante y luego se implementa fácilmente por algo así:
try:
next_token = token_list[index + 1]
except: IndexError:
next_token = None
Por supuesto, esto sólo funciona bien. Pero pensando en eso, surge mi segunda pregunta: ¿realmente hay un punto de hacer que scan()
sea un generador en primer lugar?
er ... este no es solo sobre cuerdas, ¿verdad? pensando en cosas como '(_ for _ in (None, 'evil', 4, 0))', eso también es un generador. – n611x007