Nociones básicas sobre Lenguajes Gramáticas y Autómatas Lenguajes y Gramáticas En este capítulo vamos a sintetizar los conceptos básicos de gramáticas y lenguajes para la teoría de compiladores Cadenas y Lenguajes La noción más básica en la teoría de lenguajes es la tira o cadena de caracteres formada por la concatenación de caracteres. La cadena mínima es la nula y la denominaremos . Si tenemos un alfabeto o vocabulario { a, b}, algunas cadenas que se pueden formar con él serán: , a, b, ab, aa, ba, bb, aaa, aab, bba,…… El orden es importante, la cadena ab es diferente de la ba. La concatenación de 2 cadenas es otra cadena. Ejemplo la concatenación de ab y aaa es otra cadena : abaaa. Si una de las cadenas es la nula la concatenación de dos cadenas deja inalterada la cadena : .ab es la misma que ab. La longitud de una cadena es el número de caracteres que la forman. Potencia de una cadena es la cadena resultante de concatenar dicha cadena consigo misma tantas veces como indique el exponente: Si x fuera la cadena abc entonces : x0 = ., x1 = abc , x2= abcabc ……. Si se tienen dos conjuntos de cadenas de caracteres A y B, se puede realizar su producto cartesiano AB, considerando los pares de cadenas del producto resultante como concatenados, es decir: Si A = { a, b, cd } y B = { d, g}, entonces el conjunto producto es . AB = { ad, ag, bd, bg, cdd, cdg} Sabiendo realizar el producto de conjuntos de tiras, es fácil calcular potencias” de conjuntos, realizando el producto consigo mismo A0= { . } ; A1= A ; A2= AA , etc. Si A = { a, b} A0= { . } A1= A = {a, b} A2= AA ={aa, ab, ba, bb} A3= AAA = { aaa, aab, aba, abb, baa, bab, bba, bbb} Cierre transitivo de un conjunto A , que denominaremos A+ a la unión de sus potencias crecientes A+ = A1 union A2 union A3 …… union An Cierre transitivo y reflexivo de A , que denominaremos A* , a la union de sus potencias crecientes pero comenzando con la potencia cero A* = A0 union A1 union A2 union A3 …… union An es decir A* se forma añadiendo al A+ Lenguaje: su concepto Un lenguaje está formado por los dos elementos siguientes: Un diccionario, que indica el significado de las palabras del lenguaje Un conjunto de reglas para describir las sentencias válidas del lenguaje. Este conjunto forma la gramática del lenguaje. Semántica : estudio del significado de las frases de un lenguaje y su interpretación. (el fondo). Sintaxis: estudio de la estructura del lenguaje ( la forma). Noción de lenguaje: un conjunto de tiras de caracteres Una tira o sentencia es una secuencia ordenada de los símbolos Un símbolo es un elemento del vocabulario del lenguaje, que se emplea para formar las tiras o cadenas del mismo, que se llaman sentencias Un alfabeto o vocabulario es el conjunto de todos los símbolos que forman las sentencias del lenguaje La operación básica para formar las cadenas del lenguaje es la concatenación de símbolos. Noción de Gramática Una gramática está formada por un cuarteto: ( N, T, P, S) N es el vocabulario No Terminal de símbolos introducidos por nosotros como elementos auxiliares para la definición de la gramática y no figuran en las sentencias del lenguaje. T es el vocabulario Terminal de símbolos que forman las sentencias del lenguaje. P es el conjunto de Reglas de Derivación de las cadenas, que tienen la forma tira1 tira2. Aplicando esta regla la tira1 se transforma en la tira2. S es el elemento más importante del vocabulario N no terminal: el símbolo inicial o axioma, del que se derivan todas los demás aplicando las reglas P. Ejemplo: Sea la gramática G1: N sólo tiene el símbolo no terminal S que es también el axioma T tiene los símbolos terminales a y b P consta de las reglas: S ab S aSb Las tiras formadas aplicando estas reglas constan de varias a concatenadas y del mismo número de b: S aSb aaSbb aaaSbbb aaaaSbbbb aaaaabbbbb | V | V | V aabb aaabbb aaaabbbb Clasificación de CHOMSKY Chomsky es el que definió una gramática como formada por el cuarteto antes mencionado. Introdujo cuatro tipos de gramáticas a base de cambiar sólo las reglas de derivación P. Gramática tipo 0 o con estructura de frase: La parte izquierda de una regla puede ser una tira de símbolos cualesquiera de N y T y la parte derecha lo mismo y además puede ser nula. tira1tira2 estando tira1 en (N U T)+ y tira2 en (N U T )* Gramática tipo 1 o sensible al contexto: tira1 A tira2 tira1 tira3 tira2 estando A en N, tira1 y tira2 en (N U T)* y tira3 en (N U T)+ Se puede cambiar A por tira3 pero siempre dentro del contexto tira1...tira2 Gramática tipo 2 o libre de contexto: A tira estando A en N y tira en (N U T)* Se puede cambiar A por tira independientemente del contexto en que aparezca A Ejemplo: N: S, A, B T: a, b P : SaB | bA A a | aS | bAA B b | bS | aBB Gramática de tipo3 o regulares: A aB o A a Ejemplo: N: S, A, B T: 0, 1 P: S0A | 1B |0 A 0A |0S |1B B 1B | 1 | 0 Cada una de ellas es más restringida que la anterior, comprende un menor número de lenguajes G tipo 0 G tipo 1 G tipo2 G tipo 3 Gramáticas libres de contexto Derivación por la izquierda Derivación por la derecha Tomar el axioma Tomar el axioma Sustituir axioma por parte derecha regla Sustituir axioma por parte derecha regla Tomar el no terminal más a la izquierda Tomar el no terminal más a la derecha Sustituirle por parte derecha de alguna de sus reglas Sustituirle por parte derecha de alguna de sus reglas ¿queda algún no terminal por sustituir? ¿queda algún no terminal por sustituir? si si no no La cadena resultante es una sentencia del lenguaje La cadena resultante es una sentencia del lenguaje Representaciones gráficas: árboles sintácticos Sea la G con las siguientes reglas: S a | aAa A b | bA Representación gráfica de las sentencias aba y abba S aAa aba SaAa abAaabba S S a a A A a a b b A b Recursividad Un mecanismo que nos permite definir formas complicadas de un lenguaje con reglas sucintas. En vez de escribir T L T L V T L V V T L V V V ………….. Se utilizan reglas recursivas: Recursiva por la izquierda T L T T V Ejemplos: Un entero sin signo Entero Dígito Entero Entero Dígito por la derecha TL T VT Un identificador Identificador Letra Identificador Identificador LetraoDígito LetraoDígito Letra | Dígito Ambigüedad Es esencial que una sentencia tenga un único árbol sintáctico. En caso contrario el compilador podría “entender” de varias formas lo escrito por el programador. Diremos que una sentencia es ambigua si el lenguaje definido tiene alguna sentencia que tenga más de un árbol sintáctico Ejemplo: expresiones aritméticas EE + E |E * E | n es una gramática ambigua Sea la cadena n + n * n E E E E n E E + n * E E n n E E + T | T T T * F | F F n No es ambigua E + E n * E E T T T F F n + n F * n n Máquinas Reconocedoras o Autómatas Son dispositivos formales que permiten definir un lenguaje por medio de la vía de aceptación de las cadenas que lo componen. En contraposición de las gramáticas formales, que generan cadenas a partir de unas reglas, los autómatas deciden si una cadena determinada pertenece o no a un lenguaje En general un autómata consta de: Una cinta de entrada dividida en celdas, cada celda es ocupada por cada uno de los símbolos. Puede moverse a la derecha , a la izquierda o permanecer quieta. Un control de estados que determina el comportamiento del mecanismo de reconocimiento representado por un conjunto de estados, que en la práctica debe ser finito. Encontrándose el autómata en un estado y leído un símbolo de la cinta de entrada, la máquina transitará a otro estado, pudiendo ser incluso el mismo. Una memoria, que consta de una función de direccionamiento, una función de búsqueda y un determinado alfabeto. Lo más frecuente , esta memoria , cuando exista, tendrá una estructura de pila. Se entiende por movimiento a la situación que se produce cuando la cabeza de lectura se desplaza ( o permanece inmóvil) por la cinta de entrada, el posible almacenamiento en la memoria de alguna cadena de símbolos y el nuevo estado producido. Se entiende por configuración, un conjunto de elementos que definen la situación en un instante considerado del autómata como son el estado actual, el contenido de la cinta de entrada, y el contenido de la memoria auxiliar en ese instante. Cuando la transición se realiza de un estado a otro exclusivamente se dice que el control es determinista. Por el contrario si partiendo de un estado y con la lectura de un símbolo de la cinta de entrada puede transitarse a dos o más estados diferentes se dice que el control es no-determinista. La máquina se encuentra en una configuración inicial cuando se halla en el estado inicial del reconocimiento, la cabeza de lectura se halla sobre el símbolo más a la izquierda y la memoria contiene el símbolo inicial. Análogamente , la máquina se encuentra en la configuración final cuando la cabeza de lectura se encuentra en el símbolo más a la derecha y la memoria se halla en determinadas condiciones. En general un autómata acepta una cadena si empezando en la configuración inicial y después de una serie de movimientos se llega a una configuración final. Existen varios tipos de máquinas reconocedoras en relación con el tipo de lenguaje que aceptan: 1. Autómatas finitos, reconocen lenguajes regulares (tipo 3). La cinta de entrada sólo se mueve en un sentido (unidireccional) y no posee memoria auxiliar. Utilizados para la construcción de analizadores léxicos. 2. Autómatas con pila, reconocen lenguajes libres de contexto. Son de movimiento unidireccional y la memoria tiene una estructura de pila, con una función de almacenamiento y búsqueda. Utilizados en la construcción de analizadores sintácticos. 3. Autómatas bidireccionales, reconocen lenguajes dependientes del contexto. 4. Máquinas de Turing, reconocen lenguajes tipo 0, o con estructura de frase. Son también bidireccionales. Autómatas Finitos Consta de una cinta de entrada y un control de estados. Reconoce lenguajes Regulares. Cinta de entrada .......... Símbolos alfabeto entrada a b .................................... c ................... Cabeza lectora Control de estados Símbolo leído Estado actual Estado nuevo Un AF puede ser considerado como un sistema que consta: Un conjunto finito de estados que determina la conducta del autómata Un conjunto de símbolos de entrada. La cadena que se quiere reconocer y que se encuentra en la cinta de entrada debe estar formada por caracteres de ete alfabeto. Una función de transición: cada estado actual y el símbolo leído le hace corresponder uno (determinista) o varios estados (no-determinista) que pasan a ser los actuales. Un estado inicial Un subconjunto no vacío de estados llamados finales. Cuando se llega a alguno de ellos se ha llegado a un final lógico en el proceso de aceptación. La configuración de un autómata finito: Estado en el que se encuentra La subcadena que resta por reconocer Luego la configuración inicial será: Estado inicial La cadena de entrada completa La configuración final será: Un estado final La subcadena vacía, no queda nada de la cadena de entrada por reconocer Una tira de entrada es reconocida o aceptada por un autómata finito si puede escribirse una secuencia de movimientos ( o de transiciones) entre las configuraciones inicial y final. Una forma de representar una transición Símbolo leído Estado viejo Estado nuevo Otra notación : expresiones regulares: a* a+ a a a a b ab a a b o b (a+b) Ejemplo: identificador letra (letra | dígito) letra a | b | ..........| z dígito 0 | 1 | ........| 9 identificador = letra (letra +dígito) * letra = a + b + ...... + z gígito= 0 + 1+ ....+ 9 Tabla de transiciones: Estados 0 1 2 Letra 1 1 - letra 0 Dígito 1 - Fin de cadena 2 - $ (fin cadena) 1 Estado inicial Estado final Letra o dígito Si L es un lenguaje regular: L se denota por una expresión regular L puede ser definido por un Autómata Finito No Determinista (AFN ) Cualquier AFN puede ser transformado en uno determinista AFD.