Professional Documents
Culture Documents
NET
CONCEPTOS BÁSICOS, DEFINICION DE ALFABETO Y AUTOMATAS
Inicio X
S F
AF = (K, ∑, Δ, S, F)
int n = 0
Este sería el algoritmo que usaremos para que
char c = getChar() nuestro autómata reconozca la cadena de
while(n <= lenght (inputString)) entrada, ahora, recordemos que F es “el
s = getState(s, c) conjunto de estados de aceptación”, es decir
if( s <> -1) que en nuestro programa no es un entero, sino
c = getChar()
un arreglo de enteros, así que la última parte la
else
break adaptaremos a que busque S en el arreglo F.
if ( f = s ) El comportamiento o funcionamiento de un
return true autómata está definido por la tabla de
else transiciones. Para explicar mejor esto
return false crearemos el autómata finito que reconozca
números con parte decimal.
De acuerdo con esta estructura la expresión regular podría quedar de la siguiente manera:
DIGITO -> 0|1|2|3|4|5|6|7|8|9
Token -> DIGITO+ . DIGITO+
Bien, ya tenemos la expresión regular, ahora procederemos a construir el autómata que reconozca
números con parte decimal.
Alfabeto S Digito .
S 0 1 2 3 4 5 6 7 8 9 . 0 1 -
0 1 1 1 1 1 1 1 1 1 1 - 1 1 -
1 1 1 1 1 1 1 1 1 1 1 2 2 3 2
2 3 3 3 3 3 3 3 3 3 3 - 3 3 -
3 3 3 3 3 3 3 3 3 3 3 -
Los guiones en la tabla quieren decir que con ese símbolo el autómata no cambiara de estado, es
decir que no hará nada. Esto podemos comprobarlo, el diagrama del autómata dice que estando en
el estado cero solo avanzará al estado 1 con un digito (0-9), es decir, que si la cadena de entrada
comenzara con un punto (.), el autómata no cambiaría de estado. Esto es porque el diagrama solo
muestra las condiciones para el cambio de estado del autómata. Podríamos “escribir” de otra forma
el autómata y sería algo como lo siguiente:
Estado 0
o Estando en el estado 0 y leyendo con digito avanzamos al estado 1
Estado 1
o Estando en el estado 1 y leyendo un digito continuamos en el estado 1
o Estando en el estado 1 y leyendo un punto avanzamos al estado 2
Estado 2
o Estando en el estado 2 y leyendo un digito avanzamos al estado 3
Estado 3
o Estando en el estado 3 y leyendo un digito continuamos en el estado 3
Como pueden ver, solo se describen las condiciones de estado actual y símbolo leído que nos
permiten avanzar de un estado S0 a S1. No necesariamente S0 y S1 deben ser estados diferentes, esto
dependerá de la expresión regular con la que construyamos el autómata.
Clase “AbstractChar”
Como sabemos uno de los componentes de un autómata es el alfabeto de entrada, pues ahora
definiremos el alfabeto, pero debemos tomar algo en cuenta, repasemos la definición de alfabeto.
Alfabeto: Es el subconjunto de símbolos tomado a partir del conjunto de símbolos formado
por todos y cada uno de los símbolos que pertenecen a un lenguaje, es finito y no es vacío.
Justificación
Como pudieron notar, existe una clase AbstractChar, ¿Por qué?, pues por que he definido una
clase para cada carácter del alfabeto de entrada. Por ejemplo, si fuera a crear un autómata que
reconociera números binarios tendría que crear una clase para el carácter cero y otra para el
carácter 1, pero ambas heredarían de la clase AbstractChar, esto es porque el alfabeto de entrada
no siempre será el mismo, así que decidí hacerlo de esta forma, así Grammar.NET seria flexible en
el sentido de que podemos especificar el alfabeto de entrada que usaremos.
También si fueron observadores los métodos Recognize y RecognizeAlgorithm reciben una
lista de caracteres (List<AbstractChar>), eso es por que originalmente el tipo de dato string no
existía o no existe como tal, sino que es una lista de caracteres, así que abstraje de eso que nuestra
cadena es una lista de caracteres abstractos, de ahí el por qué un List<AbstractChar>.
Definición del Autómata para un número Real
Como sabemos, a un número con parte decimal se le conoce como número real, así que llamaremos
a nuestro autómata “Real”. Primero que nada les mostraré el diagrama de clases que debemos
respetar para los autómatas que necesitemos crear en Grammar.NET.
protected override int GetState(int s, AbstractChar c) Como pueden ver hacemos uso de un
{
switch (c.Type) enumerado CharType que definí para saber
{ qué tipo de caracter es, si es un Digito o un
case CharType.Digit:
return arrTabla[s, 0]; punto, de hecho, en él definí muchos más tipos,
case CharType.Point: pero el autómata Real solo manejara estos dos,
return arrTabla[s, 1];
default: por eso solo uso estos en el autómata. Así que
return -1; podemos observar que en nuestros autómatas
}
}
solo usaremos los tipos de carácter que valla a
leer nuestro autómata en cuestión.
El default lo que hace es “atrapar” cualquier símbolo que no pertenezca al alfabeto que reconoce el
autómata Real y retorna un -1, ¿Por qué?, pues por que los estados de nuestro autómata son un
número S, tal que, 0 < S < ∞ así que, podemos ver que los números negativos no pueden
representar algún estado del autómata por eso he decidido tomar el -1 para que represente que
las condiciones de estado actual y símbolo leído no pertenecen a la tabla de transiciones.