Analizador de programación: ¿por qué devolvemos los datos restantes (no consumidos) mientras escribimos un analizador?

Una limitación común de las secuencias de entrada es que solo puede leer de ellas secuencialmente, no puede regresar o leer desde una posición aleatoria, y cuando lee algo, ya no está presente en la secuencia. Entonces, digamos que queremos analizar strim “1b” para verificar si es un número. Leemos “1”, y creemos que podría ser. Luego leemos “b” y nos damos cuenta de que no es un número, pero podría ser algo más que podríamos analizar. Consumimos dos personajes de la secuencia, y no podemos volver a ponerlos allí. Tampoco podemos dejarlos en la corriente: se los quitaron leyendo. Entonces tenemos que volver (Falso, “1b”). Uno podría preguntarse “por qué las transmisiones tienen esta limitación” y hay varias razones. Una es que ahorramos memoria de esta manera, al no almacenar cosas en la secuencia que ya no se necesitan allí. Otra es que detrás del flujo hay un código que produce más contenido, se pausó cuando hay contenido en el flujo y se reanudó para producir más datos cuando sea necesario, por lo que las operaciones de lectura / escritura se utilizan como señales para iniciar / detener esto. código. Una solución común es crear un contenedor para la secuencia que combine la secuencia y el búfer y permita avanzar según sea necesario, pero debajo del capó aún tendrá el concepto de datos restantes.

Se trata de composición. Desea escribir un analizador más grande componiendo analizadores más pequeños. Por ejemplo, para analizar una fecha en el formato mm.dd.yy, escribe un analizador mensual, un analizador diario y un analizador anual. Luego agrega un carácter de punto literal ‘.’ analizador y combinarlos en el orden correcto.

Si la entrada es “01.21.16”, el analizador de mes consume “01”. Devuelve el token de enero y la entrada restante, que es “.21.16”. El analizador de puntos obtiene esta nueva entrada, consume un punto y devuelve el resto “21.16”. Eso es lo que obtiene el analizador diario, y así sucesivamente … Cada paso de análisis, si tiene éxito, consume parte de la entrada y pasa el resto al siguiente paso de análisis.