STxT: El Libro

Un lenguaje para la web

Capítulo 7: Parseo de STxT (*)

Parsear un fichero STxT es mucho más fácil que parsear ficheros de otras tecnologías. Puede parecer paradójico, ya que realmente es un lenguaje muy potente, pero a la vez está basado en principios muy simples.

Yo os explicaré mi forma de parsear un fichero. Es posible que no sea la mejor, ni la más óptima, pero es una forma de hacerlo. De hecho, si queréis ver la implementación que he hecho está disponible en Internet:

Esta implementación se ha hecho en lenguaje Java, ya que es el que mejor conozco.

Espero que STxT tenga éxito, y que muy pronto aparezcan otras implementaciones.

No voy a entrar en todos los detalles, pero sí que me gustaría explicar algunos puntos que requieren más atención.

Si no tenéis intención de implementar un parseador no continuéis leyendo. El siguiente capítulo es mucho más interesante ;-)

Proceso genérico

Parseo por líneas

El proceso de parseo puede hacerse línea a línea, por lo que podemos decir que de forma general tenemos:

mientras no fin de fichero
    leer linea
    procesar linea
fin mientras

Durante el proceso es adecuado tener un listado de los últimos nodos que hemos ido encontrando según el nivel, ya que de esto depende el procesado correcto.

Procesado de línea

El primer paso en el procesado de la línea es la normalización de la línea. Una línea está normalizada cuando está en forma compacta (o semicompacta), por lo que hay que comprobar si lo está, y si no lo está, transformarla. En la normalización también se eliminan las líneas de comentarios.

Hay que tener en cuenta en la normalización que si el nodo anterior era de texto, al superar cierto nivel será parte de ese mismo nodo. Es decir, será texto a continuación. También será parte de él si no llega al nivel pero la línea está completamente en blanco, en cuyo caso se traducirá por texto con un salto de línea ([[chapter_06.html#index_9|Ver tutorial avanzado]]).

Una vez hemos compactada la línea, el procesado sigue independientemente, y ya sólo falta obtener el nivel de la nueva línea y distinguir entre unos pocos casos:

En cada uno de los casos se trata de actualizar el estado de nuestras variables, y proseguir con el proceso.

Nota: Lo más importante aquí es ver que es un proceso que se puede hacer línea a línea, y las decisiones a tomar son relativamente sencillas. Esto nos permite tener un parser muy eficiente, que a su vez puede actuar de validador de la gramática y los nodos.

Validaciones

Las validaciones se hacen en varios puntos del parseo:

¿Cuándo damos por finalizado un nodo? Este punto es interesante, ya que hay dos circunstancias que hacen que un nodo se de por finalizado. Una de ellas es cuando aparece otro nodo con un nivel igual o inferior a este nodo. La otra es cuando se ha procesado todo el fichero y ya no quedan nodos a validar. En estos puntos el nodo se da por finalizado y pueden empezar las validaciones.

Los nodos del lenguaje

En la descripción del lenguaje habíamos dicho que los tipos de datos no tienen limitación ni están ligados a un lenguaje, por lo que las validaciones sólo deberían ser comprobadas mediante expresiones regulares o métodos que aseguren este hecho.

Tenemos los siguientes tipos de nodos:

Por ejemplo, las expresiones regulares que podríamos usar para validar nodos son:

BINARY       = ^(0|1|\s)+$
BOOLEAN      = ^0|1$
HEXADECIMAL  = ^([a-f0-9]|\s)+$
INTEGER      = ^(\-|\+)?\d+$
NATURAL      = ^\d+$
NUMBER       = ^(\-|\+)?\d+\.\d+(e(\-|\+)?\d+)?$
RATIONAL     = ^(\-|\+)?\d+\/\d+$

Gramáticas

Almacenaje

Las gramáticas se obtienen de Internet, pero no es práctico ni eficiente tener que ir a buscar siempre las definiciones de forma remota. La estrategia más eficiente es tener una especie de repositorio de gramáticas, en disco, e ir a buscarlas siempre allí. En caso de no encontrarse se buscaría en Internet, y se actualizaría ese repositorio. También es posible establecer tiempos de comprobación u otras estrategias. La idea es que las gramáticas no cambien con el tiempo, o que al menos sean compatibles de forma retroactiva.

Gramática inicial

Hay que tener en cuenta que no es posible hacer un parser sin tener la gramática previamente. Para parsear una gramática hay que tener la definición de la gramática base ya parseada. Por esta razón habrá una definición de la gramática inicial en el propio código.

Detalles a tener en cuenta

Hay algunos detalles que hay que tener en cuenta en el parseo:

Usamos cookies para mejorar su experiencia de uso y ofrecer contenidos adaptados a sus intereses Entendido! Más información