Gramatica02

A. Los estados

Para que JFlex sepa de un estado, es necesario anteponer a su nombre el identificador %s. En esta lista se aprecian los estados que contiene el analizador. Estos estados sólo denotan una separación lógica de las transiciones por las que pasa el analizador. En teoría sería posible hacer un analizador léxico sin estados; este acercamiento sería difícil de manejar y de leer.

1. El estado único

Todo analizador léxico construido utilizando JFlex tiene, por lo menos, un estado: YYINITIAL. En este estado el analizador contiene en memoria el elemento (palabra) que se está leyendo actualmente.

Dentro de la definición del estado YYINITIAL se tienen las reglas de transición más simples, en el caso de EXTE a otros estados.

Supongamos que el texto analizado por el analizador es:

Antes del jueves saldrán los presos,... hoy...

Estando dentro de YYINITIAL, el analizador léxico verificará si la palabra que tiene en el búffer (en este caso la primera: "antes") es alguna de las definidas ("algún", "cada", etc.) En caso de serlo, YYINITIAL tiene definidas las transiciones para cada caso. De tal modo que la palabra "antes" sí está definida en el estado YYINITIAL. El analizador léxico busca la transición que este componente léxico tiene y transfiere el control al estado señalado.

Para el caso de EXTE, generalmente la palabra de YYINITIAL indica el nombre del estado. "Antes" irá siempre al estado <ANTES_PREPOSICION>. Esto, forzosamente, tiene una marca //@Antes.0. El analizador léxico ahora lee la siguiente palabra de la frase, "del".

3. Los estados

Cada estado tiene una serie de definiciones para la palabra actual del analizador, de tal modo que si la palabra actualmente analizada coincide con alguna definición del estado (marcada por //@<NombreEstado>.<índice>) se ejecutarán las acciones definidas dentro de esa regla. Si la palabra actual no coincide con ninguna de las reglas dentro del estado, el control se transfiere de regreso a YYINITIAL.

Muchos de los estados tienen dentro de sus reglas una definición para cuando se encuentra la palabra "de". Éste es el caso de <ANTES_PREPOSICIÓN>:

del? {
	//@Antes.1
		actual.addSentence(yytext());
		actual.addRegla(new Regla(Regla.Tipo.ANTES, 1, "Antes"));
		if(yytext().endsWith("del")){
			actual.addRegla(new Regla(Regla.Tipo.DE, 0, "De"));
			actual.addRegla(new Regla(Regla.Tipo.ARTICULO, 0, "Artículo"));
			yybegin(ARTICULO);
		}
		else {
			actual.addRegla(new Regla(Regla.Tipo.DE, 0, "De"));
			yybegin(DE_PREPOSICION);
		}
	}

Aquí la regla #1 de <ANTES_PREPOSICIÓN> define las acciones para el elemento "del?". Es decir, ya sea la palabra "de" o la palabra "del".

La primera sentencia es un comentario, en este caso //@Antes.1 define la primera regla marcada del estado <ANTES_PREPOSICIÓN>.

La segunda sentencia agrega el texto actual del búffer ("de" o "del") a una entidad lógica llamada actual. También para uso interno por EXTE, se agrega el marcado de regla (//@Antes.1) a una entidad lógica encargada de llevar cuenta de las reglas por las que una expresión temporal en potencia puede pasar.

La tercera sentencia, verifica explícitamente si la palabra actual es "de" o "del" y dependiendo del resultado se transfiere el control a otro estado. Si es "del" (que es un apócope de "de el") se transfiere el control al estado <ARTÍCULO> y queda expresado con la sentencia yybegin(ARTICULO). De este modo, el analizador léxico contiene en el búffer la palabra "jueves" y se verificará si hay alguna regla que contenga "jueves" en su definición. Es importante notar que antes de transferir el control al estado <ARTÍCULO> la entidad lógica encargada de rastrear las transiciones, ha agregado la transición a la regla por omisión de Artículo, en este caso //@Artículo.0, que es un sinónimo de la línea actual.addRegla(new Regla(Regla.Tipo.ARTICULO, 0, "Artículo").

Por último, en caso de que la palabra no hubiera sido "del" sino "de", el estado se transfiere al estado <DE_PREPOSICIÓN> siguiendo los mismos pasos que para el otro caso.

Regresar Continuar