´ nchez Isabel Navarrete Sanchez a ´ rdenas Viedma Mar´ ıa Antonia Cardenas a ´nchez Alvarez Daniel Sanchez a Juan Antonio Bot´ ıa Blaya Roque Mar´ ın Morales ´ Rodrigo Mart´ınez Bejar ejar
´n Departamento de Ingenier´ıa de la Informacion o y las Comunicaciones Universidad de Murcia
´ TEOR´ IA DE AUTOMATAS Y
LENGUAJES FORMALES
Introducci´ on on Aunque no debemos hacer una distinci´on on tajante entre los aspectos pr´ acticos acticos y te´ oricos oricos de la Inform´ atica, es cierto que existen materias que tienen un alto contenido formal, con desarrollos atica, de tipo matem´ atico, al contrario que otros temas m´ atico, as cercanos a la resoluci´ as on on de problemas de tipo pr´actico. actico. La asignatura de Teor´ıa ıa de Au Aut´ t´ omatas y Lenguajes Formales sin duda trata con las materias del primer tipo y los contenidos que se imparten constituyen el eje fundamental de diversas ´areas areas de conocimiento encuadradas dentro de lo que po dr´ dr´ıamos denominar Info In form rm´ ´ atic at ica a aridas” y distanciadas de Te´ orica orica. A veces estas disciplinas resultan para el alumno materias “´aridas” lo que ellos entienden que deber´ deber´ıan estudiar en una carrera de Ingenier´ Ingenier´ıa Inform´ atica. atica. Pero la Inform´ atica, atica, como cualquier cualquier otra ciencia ciencia o ingenier ingenier´´ıa, tiene unos fundamen fundamentos tos te´ oricos sobre los que apoyarse y que cualquier ingeniero en Inform´atica atica debe conocer. As´ As´ı lo entienden diversos organismos internacionales como ACM e IEEE que recomiendan al menos un curso de Aut´ omatas y Lenguajes Formales en los curricula de las carreras relacionadas con la Inform´atiomatas atica. Una motivaci´ on para el estudio de estas materias formales la expuso Millner en un discurso on que dio en 1993 al recoger el prestigioso premio Turing que se otorga a distinguidos cient´ cient´ıficos que trabajan en el ´area area de las Ciencias de la Computaci´ on: on: “Estas [las aplicaciones] son altamente necesarias, pero no queremos que esto ocurra en detrimento del trabajo te´orico...Las orico...Las Ciencias de la Computaci´ Computaci´ on son tan amplias que si s i no tienen una teor´ıa ıa b´ asica, estaremos perdidos. Tantas cosas est´ asica, an an avanzando...¿C´ omo podr´ omo podr´ıa ocurrir esto sin una teor´ teor´ıa? Esta tiene que ir cogida de la mano de la pr´actica.” actica.”
1.
Evol Evoluc uci´ i´ on on hist´ orica oric a de la Teor´ eor´ıa de la Computa Comp utaci´ ci´ on on
La Teor´ alculo abstractos que describen con distintos Teor´ıa de la Comput Com putaci´ aci´on on trata con modelos de c´ grados de precisi´on on las diferentes partes y tipos de computadores. Pero estos modelos no se usan para describir detalles pr´acticos acticos del hardware hardware de un determinado determinado ordenador, ordenador, sino que m´ as as bien se ocupan de cuestiones abstractas sobre la capacidad de los ordenadores, en general. As´ As´ı, en los curricula de Ciencias de la Computaci´ on existen cursos separados para tratar materias on como Arquitectura de Computadores, Teor´ eor´ıa de Circuitos, Algoritmos y Estructuras de Datos, Sistemas Operativos, etc. Todas estas ´areas areas tienen una componente te´orica, orica, pero difieren del estudio de la Teor´ Teor´ıa de la Computaci´ Comput aci´ on fundamentalmente en dos aspectos: on Las primeras tratan con computadores que existen realmente, mientras que los modelos abstractos de c´alculo alculo abarcan todo tipo de computadores que existen, que puedan llegar a existir o simplemente que uno pueda imaginar. En Teor´ eor´ıa de la Computaci´ on, a diferencia de las otras materias, lo importante no es on, buscar la mejor manera de hacer las cosas (optimalidad (optimalidad ) sino estudiar qu´ e puede o no puede hacerse con un ordenador (computabilidad ( computabilidad ). ). 2
La historia de la Teor´ eor´ıa de la Computaci´ on es bastante interesante. Se ha desarrollado gracias on a confluencia, por afortunadas coincidencias, de distintos campos de conocimiento y descubrimientos (fundamentalmente matem´ aticos) realizados a principios del siglo XX. Bajo el nombre aticos) recogen una serie de materias materias que constituyen constituyen hoy en d´ıa los funTeor´ eor´ıa de la Computaci´ Comput aci´on on se recogen damentos te´ oricos oricos de la Inform´ atica: atica: Teor´ Teor´ıa de Aut Aut´ omatas, omatas ´ , Teor´ eor´ıa de los Lenguajes Formales ormale s, Computabilidad y Compleji Comp lejidad dad Algor´ıtmica ıtmi ca . Computabilidad El primer primer tema que cae clarament claramentee dentro dentro del campo de la Teor´ eor´ıa de la Computaci´ Computaci´ on es el odel, Church Church,, Post, Post, Turing uring y Kleene Kleene, tiene sus ra´ de Computabilidad. Iniciada por G¨odel, ra´ıces en la L´ ogica Matem´ atica . Al iniciar el siglo XX, los matem´ aticos estaban a punto de efectuar grandes aticos descubrimientos. Los logros de los siguientes 40 a˜ nos estaban destinados a sacudir las bases de nos las matem´ aticas y tuvieron consecuencias que se extendieron al campo de las Ciencias de la aticas Computaci´ on , a´ un un por nacer. A principios de siglo XX se empez´ o a fraguar un dilema. Georg Cantor (1845(18 45-191 1918), 8), hab´ıa ıa inveni nventado por entonces la Teor´ Teor´ıa ıa de Conjun Con juntos tos,, pero al mismo tiempo descubri´ o algunas paradojas inquietantes. Algunos de sus planteamientos pod´ıan ıan ser comprensibles (como que hay “infinitos” de distinto tama˜ no), pero otros no (por ejemplo, que alg´ no), un conjunto sea mayor que el conjunto un universal). Esto dej´o una nube de duda a los matem´aticos aticos que ellos necesitaban disipar. El punto de partida de fueron las cuestiones fundamentales que David Hilbert (1845-1918) formul´ o en 1928, durante el transcurso de un congreso internacional: 1.
¿Son completas las Matem´ aticas, en el sentido de que pueda probarse o no cada aseveraci´on aticas, on matem´ atica? atica?
2. ¿Son ¿Son las las Mat Matem em´ aticas a´ticas consistentes, consistentes, en el sentido de que no pueda probarse simult´aneaaneamente una aseveraci´on on y su negaci´on? on? 3. ¿Son ¿Son las las Mat Matem em´ aticas a´ticas decidibles, decidibles , en el sentido sentido de que exista un m´ etodo etodo definido que se pueda aplicar a cualquier aseveraci´on on matem´ atica y que determine si dicha aseveraci´on atica on es cierta o falsa? La meta de Hilbert era crear un sistema axiom´atico atico l´ ogico-matem´ ogico-matem´ atico atico completo y consistente, consistente, del cual podr´ıan ıan deducirse todas to das las Matem´ aticas, esto es, cualquier teorema matem´ aticas, atico atico podr´ dr´ıa derivarse de los l os axiomas aplicando una serie finita de reglas, es decir, mediante un proceso algo al gor´ r´ıtmi ıt mico co o computacional . Su idea era encontrar un algoritmo que determinara la verdad o falsedad de cualquier teorema en el sistema formal. A este problema le llam´ o el ‘Entscheidungs‘Entscheidungsproblem ’. ’. Por desgracia para Hilbert, en la d´ecada ecada de 1930 se produjeron una serie de investigaciones investigaciones que mostraron que esto no era posible. Las primeras noticias en contra surgen en 1931 con Kurt G¨ odel odel (1906-1978) y su Teorema de Incompletitud : “Todo sistema de primer orden consistente que contenga los teoremas teoremas de la aritm´ aritm´etica etica y cuyo cuyo conjunto conjunto de axiomas sea recursiv recursivoo no es completo”. completo”. Como consecuenc consecuencia ia no ser´ a posible encontrar el sistema formal deseado por Hilbert en el marco de la l´ogica ogica de primer orden. Una versi´on on posterior y m´as as general del teorema de G¨ odel elimina la posibilidad de considerar sistemas deductivos m´ odel as potentes que los sistemas de as primer orden, demostrando que no pueden ser consistentes y completos a la vez. Los resultados de G¨ odel odel prueban que no s´olo olo no existe un algoritmo que pueda demostrar todos los teoremas en matem´ aticas, aticas, sino que adem´ as, no todos los resultados son demostrables. Entonces cabe as, plantearse las siguientes preguntas: ¿Qu´ e pueden hacer los ordenadores (sin restricciones de ning´ un un tipo)? ¿Cuales son las limitaciones inherentes a los m´etodos etodos autom´ aticos de c´ alculo? alculo? 3
A estas cuestiones cuestiones pretende pretende responder responder la Teor´ eor´ıa de la Computabilid Computabilidad. ad. El primer primer paso en la b´ usqueda de las respuestas a estas preguntas est´a en el estudio de los modelos de computaci´on. usqueda on. Los Modelos nos 30, antes de que existieran nos Modelos Abstrac Abstractos tos de C´ alculo alculo tienen su origen en los a˜ los ordenadores (el primer computador electr´onico onico de prop´osito osito general fue el ENIAC que se desarroll´ o a partir del a˜ no 1943), en el trabajo de los l´ogicos no ogicos Church, G¨ odel, odel, Kleene, Post, y Turing. Estos primeros trabajos han tenido una profunda influencia no s´olo olo en el desarrollo te´ orico de las Ciencias de la Computaci´ orico on, sino que muchos aspectos de la pr´acticos on, acticos de la Inform´ atica fueron presagiados por ellos: incluyendo la existencia de ordenadores de prop´osito atica osito general, la posibilidad de interpretar programas, la dualidad entre software y hardware y la representaci´ on de lenguajes por estructuras formales basados en reglas de producci´on. on on on de funci´ on λ-definible como funci´ funcion o´n efectivamente calculable. Alonzo Church propuso la noci´ La demostraci´ on de teoremas se convierte en una transformaci´on on on de una cadena de s´ımbolos en otra, seg´ un un conjunto de reglas formales, que se conocen como lambda c´ un alculo. alculo. En 1936, Church hace un esquema de la demostraci´on on de la equivalencia entre las funciones λ-definibles y las funciones recursivas de Herbrand-G¨odel odel (esta equivalencia tambi´en en hab´ hab´ıa sido probada por Kleene Kleene ) y conjetura conjetura que ´estas estas iban a ser las unicas u ´nicas funciones calculables por medio de un algoritmo a trav´ es es de la tesis que lleva su nombre (Tesis (Tesis de Church) Church) y utilizando la noci´ on on de funci´on on λ-definible, dio ejemplos de problemas de decisi´on on irresolubles y demostr´o que el Entscheidungsproblem era Entscheidungsproblem era uno de esos problemas. Por otra parte Kleene, pocos meses despu´es, es, demuestra de forma independiente indep endiente la equivalencia equivalencia entre funciones λ-definibles y funciones recursivas de Herbrand-G¨odel, odel, a trav´es es del concepto concept o de funci´ on recursiva y da ejemplos de problemas irresolubles. La tercera noci´on on de funci´on on calculable proviene del matem´ atic at icoo ingl´ in gl´es es Alan Turing (1912-1954). Turing se˜ nal´ nal´o que qu e hab ha b´ıa tenido ´exito exito en caracterizar caracte rizar de un modo matem´ aticamente aticamente preciso, por medio de sus m´aquinas, aquinas, la clase de las funciones calculables mediante un algoritmo ( funciones Turing-computables), Turing-computables ), lo que se conoce hoy como Tesis de Turing (1936). Aunque no se puede dar ninguna prueba formal de que una m´ aquina de Turing pueda tener esa propiedad, Turing dio un elevado n´ umero de argumentos a su favor, en base a lo cual present´o la tesis como un teorema umero demostrado. Adem´ as, as, utiliz´ o su concepto concepto de m´aquina aquina para demostrar que existen problemas que no son calculables por p or un m´etodo etodo definido y en particular, que el Entscheidungsproblem era Entscheidungsproblem era uno de esos problemas. Cuando Turing conoci´ o los trabajos de Church y Kleene, demostr´o que los conceptos de funci´on on λ-definible y funci´on on calculable por medio de una m´ aquina aquina de Turing coinciden. Naturalmente a la luz de esto la Tesis de Turing resulta ser equivalente a la de Church. Posteriormente, Posteriormente, se demostr´ o la equivalencia equi valencia entre lo l o que se pod´ p od´ıa ıa calcular cal cular mediante m ediante una m´ aquina aquina de Turing uring y lo que se pod´ pod´ıa calcul calcular ar median mediante te un sistem sistemaa formal formal en genera general. l. A la vista vista de estos resultados, la Tesis de Church-Turing es aceptada como un axioma a xioma en la Teor´ eor´ıa de la la Computaci´ on y ha servido como punto de partida en la investigaci´ on on de los problemas que se on pueden resolver mediante un algoritmo. Una de las cuestiones m´ as as estudiadas en la Teor´ eor´ıa de la Computabilidad ha sido la posibilidad de construir programas que decidan si un determinado algoritmo posee o no una determinada propiedad. Ser´ Ser´ıa interesante interesante responder de forma autom´ atica a cuestiones como: atica ¿Calculan los algoritmos A y B la misma funci´ on? on? (Problema (Problema de la equivalencia ) ¿Parar´a el algoritmo A para una de sus entradas? (Problema (Problema de la parada ) ¿Parar´a el algoritmo A para todas sus entradas? (Problema (Problema de la totalidad ) ¿Calcula el algoritmo A la funci´ on on f ? on ) f ? (Problema de la verificaci´ Conforme se fueron obteniendo demostraciones individuales de la no computabilidad de cada una de estas cuestiones, fue creciendo la sensaci´on on de que casi cualquier pregunta interesante acerca 4
eorema de Rice, confirma esta sensaci´ de algoritmos era no computable. El Teorema on: on: “Consi “Co nsid´ d´erese eres e cualquier propiedad que no sea trivial acerca de la funci´ on calculada por un algoritmo, entonces on la cuesti´ on on de si la funci´on on calculada por un algoritmo arbitrario verifica dicha propiedad es no computable”.
Comple Com plejid jidad ad Algor Alg or´ ´ıtmica ıtm ica Despu´ es es de que la Teor´ eor´ıa de la Computabilidad fuera desarrollada, era natural preguntarse acerca de la dificultad computacional de las funciones computables. Este es el objetivo de la parte de las Ciencias de la Computaci´on on que se conoce como Comple Com plejid jidad ad Algor Alg or´ ´ıtmica ıtm ica . Rabin fue uno de los primeros en plantear esta cuesti´on on general expl´ expl´ıcitamente: ıcitam ente: ¿Qu´e quiere decir que una funci´ on on f sea m´ as as dif´ dif´ıcil de computar que otra funci´ on on g ? Rabin sugiri´o una axiom´ atica atica que fue la base para el desarrollo del estudio de medidas de complejidad abstracta de Blum y otros (1967). Una segunda aportaci´on on que tuvo una influencia relevante en el desarrollo posterior de esta materia materi a fue el art´ art´ıculo de J. Hartmanis y R. Stearns en 1965, cuyo t´ıtulo On the Complexity of Algorithms dio nombre a este cuerpo de conocimiento. En ´el el se introduce la noci´ on on fundamental de medida de complejidad definida como el tiempo de computaci´ on on sobre una m´aquina aquina de Turing multicinta y se demuestran los teoremas de jerarqu´ jerarqu´ıa. Un tercer hito en los comienzos del tema fue el trabajo de Cobham titulado, The Intrinsic Computational Difficulty of Functions (1964). Cobham enfatiz´ o el t´ermino ermi no “intr “int r´ınseco” ınse co”,, es decir, deci r, ´el el estaba interesado en una teor´ teor´ıa independiente de las m´ aquinas. Esto nos conduce al un conaquinas. cepto importante desarrollado desarrollado en 1965: la identificac identificaci´ i´ on de la clase de problemas que se pueden on resolver resolver en tiempo acotado por un polinomio sobre la longitud longitud de la entrada. La distinci´ on entre algoritmos de tiempo polinomial y algoritmos de tiempo exponencial fue hecha por primera vez en 1953 por Von Neumann. La notaci´ on on de P para la clase de los problemas problemas resolubles resolubles en tiempo polinomial polinomial fue introducida introducida posteriormen posteriormente te por Karp (1972). La teor teo r´ıa de la NP-completitud es NP-completitud es seguramen seguramente te el desarrollo desarrollo m´as as importante de la Complejidad Algor´ıtmica. ıtmica . La clase N P consta de todos los problemas decidibles en tiempo polinomial por una m´ aquina de Turing no determinista. Cook en 1971 introduce la noci´ aquina on on de problema NPcompleto y demuestra que el problema de la satisfacibilidad booleana es NP-completo. La clase N P incluye una gran cantidad de problemas pr´acticos acticos que aparecen en la actividad empresarial e industrial. Demostrar que un problema es NP-completo equivale a demostrar que no tiene una soluci´ on determinista en tiempo polinomial, salvo que todos los problemas de N P est´ on es t´en en en P , P , cuesti´on on que a´ un un no est´a demostrada. Otro area a´rea que actualmente est´ a teniendo cada vez m´as as importancia es la Crip Cr ipto togr graf´ af´ıa, ıa , relacionada con la seguridad de los sistemas inform´aticos aticos y donde se ha aplicado especialmente la teor´ıa ıa de la complejidad comple jidad algor´ıtmica. ıtmic a. Mediante la criptograf cripto graf´´ıa podemos po demos conseguir consegu ir el manejo de informaci´ on confidencial en el ordenador de forma m´as on as o menos segura. M´ aquinas aquina s Secuencial Secu enciales es y Aut´ omatas omatas Finitos La Teor´ engloba tambi´ tambi´ en en al estudio estudio de las M´ aquinas secuenciales, secuenciales, tiene Teor´ıa de Aut´ Aut ´ omatas omatas, que engloba su origen en el campo de la Inge In geni nier´ er´ıa El´ectr ec trica ica . El matem´ atico atico norteameriacano Shanon (que luego se har´ har´ıa famoso por su Teor´ eor´ıa de la Informaci´ Informa ci´ on ) vino a establecer las bases para la aplicaci´ on o n de la L´ogica ogica Matem´ atica a los circuitos combinatorios y posteriormente Huffman atica en 1954 los ampli´ o a circuitos secuenciales y utiliza conceptos como estado de un aut´omata omata y tabla de transici´ on . A lo largo de las d´ ecadas ecadas siguientes, siguientes, las ideas de Shanon Shanon se desarrollar desarrollaron on considerable considerablemen mente, te, dando lugar a la formalizaci´ formalizaci´ on de una Teor´ eor´ıa de las M´ aquinas aquinas Secuenciales y de los Aut´omatas omatas Finitos (1956). Otros trabajos importantes importantes sobre m´ aquinas secuenciales son aquinas debidos a Mealy (1955) y Moore. 5
Desde un frente totalmente distinto, el concepto de aut´ omata finito aparece en 1943 con el art´ıculo ıcul o de de McCulloch y Pitts titulado A Logical Calculus of the Ideas Immanet in Nervous Activity , donde describen los c´alculos alculos l´ ogicos inmersos en un dispositivo (neurona ogicos (neurona artificial ) que hab´ hab´ıan ideado ideado para simular simular la actividad actividad de una neurona neurona biol´ ogica. A partir de entonces, se han desarrollado desarrollado asociaciones asociaciones de neuronas neuronas para constituir constituir redes. Podemos considerar una RNA (Red Neural Artificial ) Artificial ) como una colecci´on on de procesadores elementales (neuronas), conectadas a otras neuronas o entradas externas, y con una salida que permite propagar las se˜nales nales por m´ ultiples caminos. Cada procesador pondera las entradas que recibe y estos pesos pueden ser ultiples modificados en aras de conseguir el objetivo previsto. Es lo que llamaremos funci´ on de aprendizaje. dizaje. Es decir, una RNA puede “aprender” de sus propios errores, por un proceso inductivo a partir de un conjunto de ejemplos de lo que queremos aprender, frente al proceso deductivo, propio de los Sistemas Expertos. Expertos. Las caracter´ caracter´ısticas que hacen interesantes interesantes a las RNAs son su capacidad para aprender (reproducir un sistema o funci´on on a partir de ejemplos), memorizar (almacenar un conjunto de patrones o ejemplos), generalizar y abstraer (que permita recuperaciones a partir de entradas defectuosas o incompletas). Las redes neuronales, dentro del perfil de Teor´ eor´ıa de la Computaci´ on, aportan paradigmas interesantes como son el c´ on, alculo paralelo, paralelo, el aprendizaje inductivo y su capacidad para realizar c´ alculos aproximados por medio de interpolaci´ on. on. En el verano de 1951 Kleene fue invitado por la RAND Corporation para realizar un informe sobre los trabajos de McCulloch-Pitts. En este informe Kleene demuestra la equivalencia entre lo que ´el el llama ll ama “dos formas de definir una misma cosa”: los conjuntos regulares, regulares, los cuales pueden ser descritos a partir de sucesos bases y los operadores uni´on, concatenaci´ on on y clausura, es decir, mediante expresiones regulares y los lenguajes reconocidos por un aut´omata omata finito. Los aut´ omatas finitos son capaces de reconocer solamente un determinado tipo de lenguajes, omatas llamados lenguajes regulares, regulares, que tambi´ ta mbi´en en se caracteri car acterizan zan mediante medi ante un tipo ti po de gram´ aticas aticas llamadas as´ as´ı mismo regulares. Una forma adicional de caracterizar este tipo de lenguajes lengua jes es mediante las citadas expresiones regulares, construidas mediante operadores sobre el alfabeto del lenguaje y otras expresiones regulares, incluyendo el lenguaje vac´ vac´ıo. Es f´acilmente acilmente comprobable que, para un alfabeto concreto, no todos los lenguajes que se pueden construir son regulares. Ni siquiera todos los interesantes desde el punto de vista de la construcci´on on de algoritmos para resolver problemas. Hay entonces muchos problemas que no son calculables con estos lenguajes. Esto pone de manifiesto las limitaciones de los aut´ omatas finitos y las gram´ omatas aticas aticas regulares, y propicia el desarrollo de m´ aquinas reconocedoras de otros tipos de lenguajes y de las gram´aticas aquinas aticas correspondientes asociadas a los mismos, como veremos en el siguiente apartado. Desde su nacimi n acimiento, ento, la Teor´ Teor´ıa de Aut´ A ut´ omatas omatas ha encontrado aplicaci´ on on en campos muy diversos. ¿Qu´e tienen en com´un? un? A primera vista no parece sencillo deducirlo. Sin embargo, podemos vislumbrar la soluci´on on si nos damos cuenta de que en todos ellos se manejan conceptos como el ‘control’, ‘control’, la ‘acci´ on’, la ‘memoria’ y adem´ on’, as, as, los objetos controlados o recordados son s´ımbolos, palabras palabras o frases frases de alg´ un tipo. Algunos de los campos donde ha encontrado aplicaci´on un on la Teor´ıa de Aut´omatas omatas son: Teor´ Teor´ıa de la Comunica Comu nicaci´ ci´ on. on. Teor´ Teor´ıa de Control Cont rol.. L´ ogica ogica de Circuitos Circuitos Secuenciale Secuenciales. s. Reconocimiento de Patrones. Fisiolog Fisiol og´´ıa del Sistema Sistem a Nervioso. Nervioso . Estructura y An´alisis alisis de los Lenguajes de Programaci´on. on. Traducci´on on Autom´ atica atica de Lenguajes. 6
Teor´ eor´ıa Algebraica Algebra ica de Lengua jes. Cuando un aut´ omata se usa para modelar la construcci´on omata on de hardware (ej. circuitos secuenciales) o softwar softwaree (ej. analizadores analizadores l´exicos) exicos) es muy importante examinar examinar el problema problema de encontrar encontrar el aut´ omat om ata a m´ınimo ın imo equivalente a uno dado. Tanto Huffman como Moore se ocuparon de este problema y encontraron algoritmos pr´acticos acticos para minimizar un aut´ omata de estados finitos. omata 2 Para un aut´ omata omata de n estados estado s estos est os algorit a lgoritmos mos requer´ıan ıan n pasos. Bastante m´ as as tarde, en 1971 Hopcroft encontr´ o un m´eto et o do que lo hac ha c´ıa en O(n × log( log (n)) pasos. Existe un punto de vista algebraico sobre la minimizaci´ on on y caracterizaci´on on de aut´omatas omatas finitos, debida a John Myhill y Anil Nerode. Kleene, en su intento de entender los trabajos de McCullock y Pitts, abstrajo el concepto de aut´omata omata finito a partir de las redes de neuronas y el concepto de expresi´on on regular a partir del c´alculo alculo l´ ogico del modelo de McCullock y Pitts. De la misma forma, Myhill ogico a partir de los conceptos de aut´omatas omatas finitos de Kleene obtuvo el de diagrama de transici´ on (deterministas) y a los eventos los redujo a la uni´ on de clases de equivalencia. Siguiendo esta on l´ınea de trabajo, se ha elaborado en las ultimas u´ltima s d´ecadas ecadas una teor´ıa ıa abstracta abstra cta de aut´ omatas omatas con una fuerte base matem´ atica atica que, seg´ un dijo Arbib en 1969, constituye “la matem´ un atica atica pura de la Inform´ atica”. atica”. Gram´ aticas aticas y Lengua Lengu a jes Formales ormale s El desarrollo de los ordenadores en la l a d´ecada ecada de los 40, con la introducci´ on on de los programas en la memoria principal y posteriormente con los lenguajes de programaci´on on de alto nivel, propician la distinci´ on on entre lenguajes lenguajes formales formales,, con reglas sint´acticas acticas y sem´anticas anticas r´ıgidas, ıgida s, concretas concret as y bien definidas, de los lenguajes lenguajes naturales naturales como el ingl´ ingl´es, es, donde la sintaxis sintaxis y la sem´ antica no se pueden controlar f´acilmente. acilmente. Los intentos de formalizar los lenguajes naturales llevan a la construcci´ on o n de gram´ aticas como una forma de describir estos lenguajes, utilizando para ello reglas de producci´on on para construir las frases del lenguaje. Se puede entonces caracterizar un lenguaje mediante las reglas de una gram´ atica atica adecuada. on de lenguajes, que son la base Noam Chomsky Chomsky propone en 1956 tres modelos para la descripci´on de su futura futura jerarqu jerarqu´´ıa de los tipos de lenguajes lenguajes (1959), que ayud´ ayud´ o tambi´ en en en el desarrollo de los lenguajes de programaci´ on. on. Chomsky estableci´o una clasificaci´ on on de gram´ aticas aticas de acuerdo con el formato de sus producciones y distingui´o cuatro clases fundamentales de lenguajes y relaciones relaciones de inclusi´ inclusi´ on on entre ellas. La Teor´ o tener una relaci´on on sorprendente con la Teor´ eor´ıa de eor´ıa de los Lenguajes Lenguaje s Formales result´ Aut´ omatas omatas y la Computabilidad. Paralelamente a la l a jerarqu´ jerarqu´ıa de lenguajes existe otra equivaequivalente de m´ aquinas aquinas abstractas, abstractas, de tal forma que a cada una de las clases de lenguajes definidas en la jerarqu´ jerarqu´ıa de Chomsky a partir de restricciones impuestas a las l as gram´ aticas, aticas, le corresponde corresponde un tipo de m´ aquina aquina abstracta, que no es otra cosa que un m´etodo etodo reconocedor para la descripci´on on de lenguajes. La relaci´on on la podemos observar en la figura 1. Cada uno de estos tipos de m´aquiaquinas es capaz de resolver problemas cada vez m´as as complejos, desde los aut´ omatas omatas finitos (que son los m´ as simples) hasta las m´ as aquinas aquinas de Turing que determinan el l´ımite de los lo s procesos pro cesos computables. putables. Se puede llegar as´ as´ı, de una forma casi natural, a considerar considerar las m´ aquinas de Turing, establecidas casi 20 a˜ nos nos antes, como m´ aquinas reconocedoras de los lenguajes estructurados aquinas por frases frases (tipo 0) e incluso incluso a interpre interpretar tar la Tesis de Turing en t´ erminos erminos de que un sistema sistema computaciona computacionall nunca nunca podr´ a efectuar un an´alisis alisis sint´ actico de aquellos lenguajes que est´ actico an an por encima de los lengua jes estructurados por frases en la jerarqu´ jerarqu´ıa de Chomsky. Chomsky.
2.
Fundamentos undame ntos Matem´ aticos aticos
A continuaci´ on haremos un repaso breve sobre varias ideas matem´aticas on aticas que ser´an an utilizadas en los pr´oximos oximos cap´ cap´ıtulos. Estos conceptos incluyen conjuntos, relaciones, funciones y t´ecnicas ecnicas de 7
LENGUAJES
MAQUINAS
TIPO 0
DE TURING
LENGUAJES
AUTOMATAS
TIPO 1
LINEALMENTE ACOTADOS
LENGUAJES LENGUAJES
AUTOMATAS
TIPO 2
NO ENUMERABLES ENUMERABLES
CON PILA
LENGUAJES
AUTOMATAS
TIPO 3
FINITOS
on Lenguajes-M´ Lenguaj es-M´aquinas aquinas Abstractas Abstract as Figura 1: Relaci´on
demostraci´ on on matem´ aticas. aticas. Conjuntos Un conjunto es una colecci´on on de objetos. Por ejemplo, la colecci´ on de las letras vocales forman un on conjunto que podemos notar como V = {a,e,i,o,u}. Los objetos que forman parte del conjunto se llaman elementos. elementos. Por ejemplo, a es un elemento de V y se escribe a ∈ V ; V ; por otra parte podemos decir que z ∈ / V . V . Dos conjuntos son iguales si y s´olo olo si tienen los mismos elementos. No se tienen en cuenta las repeticiones de elementos ni tampoco t ampoco el orden de ´estos. estos. Hay un conjunto que no tiene ning´ un un elemento llamado conjun conj unto to vac va c´ıo y lo notaremos por ∅. Un conjunto se puede puede especificar especificar enumerando enumerando sus elementos elementos entre entre llaves llaves y separados separados por comas y esto es lo que se llama definici´ on por extensi´ on . Pero a veces esto no es posible hacerlo porque el conjunto es infinito y entonces se usa una definici´ on por comprensi´ on , es decir, haciendo referencia a otros conjuntos (conjuntos (conjuntos referenciales) referenciales ) y a propiedades que los elementos puedan tener. De forma general se definen: B = {x ∈ A | x cumple la propiedad P} Un conjunto A es un subconjunto de otro conjunto B , A ⊆ B , si cada elemento de A es un elmento de B . Tambi´ en en podemos decir que A est´a incluido en B . Cualquier conjunto es un subconjunto subco njunto de s´ı mismo. Si A es un subconjunto de B pero A no es igual a B se dice que A es un subconjunto subconjunto propio de B y se nota como A ⊂ B . Es obvio que ∅ ⊆ A para cualquier conjunto A. Para probar que dos conjuntos A y B son iguales debemos probar que A ⊆ B y B ⊆ A: cada elemento de A debe ser un elemento de B y viceversa. Dos conjuntos se pueden combinar para formar un tercero mediante una serie de operaciones sobre conjuntos: uni´ on on intersecci´ on on diferencia
A ∪ B = {x | (x ∈ A) ∨ (x ∈ B )} A ∩ B = {x | (x ∈ A) ∧ (x ∈ B )} A − B = {x | (x ∈ A) ∧ (x ∈ / B )} 8
Algunas propiedades de las operaciones anteriores se pueden deducir f´acilmente acilmente a partir de sus definiciones: 1. Idempotencia: A ∪ A = A ; A ∩ A = A 2. Conmutatividad: A ∪ B = B ∪ A ; A ∩ B = B ∩ A 3. Asociatividad:
(A ∪ B ) ∪ C = A ∪ (B ∪ C ) (A ∩ B ) ∩ C = A ∩ (B ∩ C )
4. Distributividad:
A ∪ (B ∩ C ) = (A ∪ B ) ∩ (A ∪ C ) A ∩ (B ∪ C ) = (A ∩ B ) ∪ (A ∩ C )
5. Absorci´ on: on: A ∩ (A ∪ B ) = A ; A ∪ (A ∩ B ) = A 6. Leyes de DeMorgan:
A∩B =A∪B A∪B =A∩B
Dos conjuntos son disjuntos si no tienen elementos en com´ u n, o lo que es lo mismo, si su un, intersecci´ on on es el conjunto conjunto vac´ vac´ıo. Es posible formar formar intersec intersecciones ciones y uniones uniones de m´ as a s de dos conjuntos. La colecci´ on de todos los subconjuntos de A es a su vez un conjunto llamado conjunto potencia on de A y lo notamos como 2A . Al conjunto potencia de A tambi´en en se le suele llamar llama r conjunto de las partes de A y se nota como P (A). Ejemplo 0.1 Sea A = {c, d}. Entonces 2A = {∅, {c} , {d} , {c, d}} Una partici´ on on de un conjunto no vac´ vac´ıo A es un subconjunto, Π, de 2A tal que: 1. cada cada elemen elemento to de Π es no vaci vacio; o; 2. los eleme element ntos os de Π son son disjun disjuntos tos;; 3.
Π=A
Ejemplo 0.2 {{a, b} , {c} , {d}} es una partici´ on de {a,b,c,d} pero {{a,b,c} , {c, d}} no lo es. Los conjuntos de n´ umeros pares e impares forman una partici´ on de N. Relaciones y funciones De forma general podemos definir una relaci´ on como un conjunto de elementos , que son en esencia combinaciones de objetos de un determinado tipo que est´ an relacionados de alguna an forma. Llamamos par ordenado a una pareja de objetos escritos entre par´entesis entesis y separados por comas. Por ejemplo, (a, (a, b) es un par ordenado y a, b son los componentes del par ordenado. No es lo mismo (a, (a, b) que {a, b} por varios motivos: el orden influye: no es lo mismo (a, (a, b) que (b, (b, a), sin embargo {a, b} = {b, a} los dos componentes de un par ordenado no tienen porqu´e ser distintos; por ejemplo, (2, (2, 2) es un par v´alido. alido. El producto cartesiano cartesiano de dos conjuntos A y B , que notamos A × B , es el conjunto de todos los pares ordenados (a, (a, b) donde a ∈ A y b ∈ B . Ejemplo 0.3 Dados los conjuntos {1, 3, 9} y {b,c,d} , el producto cartesiano es,
{1, 3, 9} × {b,c,d} = {(1, (1, b), (1, (1, c), (1, (1, d), (3, (3, b), (3, (3, c), (3, (3, d), (9, (9, b), (9, (9, c), (9, (9, d)} 9
on on binaria entre dos conjuntos A y B es un subconjunto de A × B . Una relaci´ Ejemplo 0.4 {(9, (9, b), (1, (1, c), (3, (3, d)} es una relaci´ on binaria entre los conjuntos {1, 3, 9} y {b,c,d} . La relaci´ on ”menor que” entre los n´ umeros naturales es una relaci´ on binaria, <= {(i, j ) | (i, j ∈ N ) ∧ (i < j )} Sea n un n´ umero umero natura natural, l, entonc entonces es (a1 , a2 ,...,an ) es una n-tupla n-tupla ordenada ordenada . Para cada i ∈ esima componente de la n-tupla. Dos n-tuplas (b1 , b2 ,...,bn ) y (a1 , a2 ,...,am ) {1,...,n} , ai es la i-´esima son iguales si y s´olo o lo si m = n y ai = bi para cada i ∈ {1,...,n}. Si A1 ,...,An son conjuntos n
cualesquiera, el producto cartesiano de todos ellos, A1 × . . . × An , es el conjunto de todas las n-tuplas (a (a1 ,...,an ) con ai ∈ Ai para cada i ∈ {1,...,n}. En el caso de que todos los Ai sean n
iguales el producto cartesiano A × . . . × A se puede escribir como An . Una relaci´ on on n-aria n
entre los conjuntos A1 ,...,An es un subconjunto del producto cartesiano A1 × . . . × An . Vamos a tratar ahora con relaciones binarias entre un conjunto y el mismo, es decir, con R ⊆ A × A. Si (a, (a, b) ∈ R podemos escribirlo con una notaci´ on on infija como a R b. Por ejemplo, en la relaci´ on de igualdad se suele decir que a = b, en lugar de (a, on (a, b) ∈=. Sea R una relaci´ on binaria sobre un conjunto A. Decimos que: on R es reflexiva sii ∀ a ∈ A : aRa R es irreflexiva sii ∀ a ∈ A : ¬(aRa) aRa) R es transitiva sii ∀ a,b,c ∈ A : (aRb) aRb) ∧ (bRc) bRc) ⇒ (aRc) aRc) R es sim´ si m´ etric tr ica a sii ∀ a, b ∈ A : aRb ⇒ bRa R es anti antisi sim´ m´ etri et rica ca sii ∀ a, b ∈ A : aRb ⇒ ¬ (bRa) bRa) Una relaci´ on on R ⊆ A × A que cumpla las propiedades reflexiva, sim´etrica etrica y transitiva se dice que es una relaci´ on on de equiv equivale alenci ncia a. Usaremos la notaci´ on on [a]R para indicar la clase de equivalencia de la relaci´on on R representada por el elemento a ∈ A y se define: [a]R = {b ∈ A | (a, b) ∈ R} Al conjunto formado por todas las clases de equivalencia de una relaci´ on on de equivalencia R ⊆ A × A se le denomina conjunto cociente de A modulo R y se nota como A/R: A/R: A/R = {[a] | a ∈ A} Una relaci´ on on R ⊆ A × A que cumpla las propiedades reflexiva, antisim´etrica etrica y transitiva se dice que es una relaci´ on on de orden. orden. Al par (A, (A, R) lo llamaremos conjunto ordenado. Si adem´ as as la relaci´ on on de orden R verifica que todo par de elementos de A son comparables, entonces se dice que R es una relaci´ on de orden total o lineal en A y el par (A, (A, R) es un conjunto totalmente ordenado. ordenado. Un orden no total se llama parcial . Supongamos que P es un conjunto de propiedades sobre relaciones. La P-clausura de R ⊆ A×A es la menor relaci´ on on R′ que incluye todos los pares ordenados de R y cumple las propiedades de P. Por ejemplo, la clausura transitiva de R, que notaremos R+ , se define de la siguiente manera: 10
1.
Si (a, b) ∈ R entonces (a, (a, b) ∈ R+ .
2.
Si (a, b) ∈ R+ y (b, c) ∈ R, entonces (a, (a, c) ∈ R+ .
3.
Solo o´lo est´ an an en R+ los pares introducidos por 1 y 2.
La clausura reflexiva y transitiva de R, que notamos R∗, se define: R∗ = R+ ∪ {(a, a) | a ∈ A} Ejemplo 0.5 Sea R = {(1, (1, 2) , (2, (2, 2) , (2, (2, 3)} una relaci´ on sobre el conjunto {1, 2, 3}. Entonces tenemos que, R+ = {(1, (1, 2) , (2, (2, 2) , (2, (2, 3) , (1, (1, 3)} ∗ R = {(1, (1, 1) , (1, (1, 2) , (1, (1, 3) , (2, (2, 2) , (2, (2, 3) , (3, (3, 3)} Una funci´ on on de un conjunto A en un conjunto B, que notamos como f : A −→ B, es una relaci´ on on binaria f ⊆ A×B con la siguiente propiedad: para cada elemento a ∈ A hay exactamente un par ordenado en f cuya primera componente sea a. Llamamos a A el dominio de la funci´on on f y a B el codominio de f . f . Si a es un elemento cualquiera de A, f ( f (a) ser´a un elemento b ∈ B tal que (a, (a, b) ∈ f y adem´ as as por ser f una funci´on on este b ser´ a unico. u ´nico. Al elemento f ( f (a) lo llamaremos ′ imagen de a bajo f . Si tenemos la funci´on on f anterior y A es un subconjunto de A, definimos:
f A′ = f ( f (a) | a ∈ A′
que es la imagen de A’ bajo f . El rango de una funci´on on f es la imagen de su dominio. Por convenio, si el dominio de una funci´on on es un producto cartesiano, no hace falta que especifiquemos las parejas de par´ pa r´entesis entesis de los l os elementos. elementos . Ejemplo 0.6 Si f : N × N → N est´ a definida de forma que la imagen de un par ordenado (m, n) es la suma de m y n, podemos escribir f ( f (m, n) = m + n, en lugar de f (( f ((m, m, n)) = m + n y adem´ as podemos decir que m, n son los argumentos de f y m + n el correspondiente valor o resultado de f . f . Monoides El par (M, (M, ◦) es un semigrupo si M es un conjunto y ◦ es una operaci´on on interna interna binaria asociativa. Es decir, ◦ es una funci´on on de M × M en M que verifica lo siguiente:
∀ x,y,z ∈ M : x ◦ (y ◦ z) = (x ◦ y) ◦ z Un elemento e ∈ M es la identidad de un semigrupo (M, (M, ◦) si se verifica:
∀ x ∈ M : e ◦ x = x ◦ e = x Un monoide es un semigrupo con identidad. Sea el monoide (M, (M, ◦, e), x ∈ M y un n´ umero umero n natural n. La n-´ esima esi ma poten po tencia cia de x, representada por x , se define inductivamente de la siguiente manera: 1. x0 = e 2. xn = x ◦ xn−1 , para n > 0 Sean A y B subconjuntos del monoide (M, (M, ◦, e). La operaci´on on ◦ induce de forma natural una M operaci´on on binaria ◦ sobre 2 , el conjunto de todos los subconjuntos de M . M . Esta operaci´ on on se define por: ∀ A, B ∈ 2M : A ◦ B = {x ◦ y | (x ∈ A) ∧ (y ∈ B )} 11
Definici´ on on 0.1 Sea (M, ◦, e) un monoide. Entonces 2M , ◦, {e} , donde ◦ es la operaci´ on on inducida, es tambi´ en en un monoide que llamaremos monoide inducido por (M, ◦, e) sobre 2M . Definici´ on on 0.2 Si A es un subconjunto del monoide (M, ◦, e). Entonces: A es cerrado cerrado positivo positivo sii ∀ x, y ∈ A : x ◦ y ∈ A. A es cerrado sii es cerrado positivo y adem´as as contiene a la identidad e. Definici´ on on 0.3 Sea A Sea A un subconjunto cerrado de un monoide. Entonces (A, ◦, e) donde ◦ es la restricci´ on on de la operaci´on on de M para los elementos de A es tambi´ ta mbi´en en un monoide. monoi de. A tal monoide monoi de se le denomina submonoide de (M, ◦, e). Definici´ on on 0.4 Sea A cualquier subconjunto de un monoide (M, ◦, e). El cierre positivo de A, representado por A+ , se define por: ∞
+
A =
An
n=1
El cierre de A, que notaremos como A∗ , se define como: ∞
∗
A =
An
n=0
donde An representa la n-´esima esima potencia de A en el monoide inducido i nducido 2M , ◦, {e} . Un subconjunto B de un monoide M se dice que genera M sii B ∗ = M . M . Al conjunto B se le llama base (o generador) de M . Si B genera M entonces, por definici´on, on, cualquier x ∈ M (distinto de e ) se puede representar como x = x1 ◦ . . . ◦ xn , donde x1 , . . . , xn ∈ B y n > 0. Se dice que B genera libremente a M si la representaci´on on anterior es ´unica unica (salvo el orden, si la operaci´on on ◦ es conmutativa). M se dice que es un monoide libre si contiene un subconjunto B que lo genera libremente. Conjuntos finitos e infinitos Una propiedad b´asica asica de los conjuntos finitos es su tama˜ no o cardinalidad. Algunos aspectos no sobre el tama˜ no de los conjuntos finitos son obvios, como por ejemplo, si A ⊆ B entonces el no cardinal de A es menor o igual que el cardinal de B ; si A es subconjunto propio de B ser´a de menor tama˜ no no que B . Sin embargo esto no es tan simple cuando tenemos conjuntos infinitos. Por ejemplo, ¿hay m´as as n´ umeros naturales que n´ umeros umeros pares? Aunque la intuici´ umeros on on nos dice que s´ı, formalmente formal mente no podemos po demos afirmarlo. afirmar lo. Se dice que dos conjuntos A y B son equinumerables o equipotentes si podemos encontrar una funci´ on on f : A −→ B donde f es biyectiva. Decimos que un conjunto es finito si es equinumerable con {1, 2, . . . , n}, para alg´ un un n ∈ N, y diremos que el cardinal de A es n, esto es, |A| = n. Un conjunto A es infinito si puede establecerse una aplicaci´on on biyectiva entre A y un subcon junto propio de A. No todos los conjuntos infinitos son equinumerables, por ejemplo N y R no tienen la misma cardinalidad. Un conjunto se dice que es infinito numerable si es equinumerable con N y se dice que es numerable si es finito o infinito numerable. En caso contrario se dice que es no numerable, numerable, como por ejemplo el conjunto de los numeros reales R. Teorem eorema a 0.1 0.1 Si A es un conjun conjunto to cualqu cualquier ieraa (inclu (incluso so infinit infinito) o) enton entonces ces |A| < |P (A)| . Adem´ as as si A es infinito numerable entonces P (A) (A) es no numerable. Teorem eorema a 0.2 0.2 La cardinalidad del conjunto de los n´ umeros naturales es menor o igual que umeros la cardinalidad cardinalidad de cualquier cualquier conjunto conjunto infinito. infinito. 12
Principio de inducci´ on on El principio principio de inducci´ inducci´ on matem´ atica afirma lo siguiente, Si A es un subconjunto de numeros naturales, A ⊆ N , y satisface las condiciones: 1.
0∈A
2.
si k ∈ A entonces k + 1 ∈ A entonces debe ser A = N.
En la pr´actica, actica, el principio de inducci´on on es usado para probar afirmaciones del tipo “para todo n´ umero umero natural k la propiedad propiedad P se cumple”. Esto es lo mismo que probar que el conjunto A = {k ∈ N | P ( P (k) se cumpl cumplee} coincide con el conjunto de n´ umeros naturales, esto es, debemos probar que A = N. Esto es lo umeros que se llama demostraci´ on por inducci´ on y el procedimiento a seguir es el siguiente: etapa base Probar que la propiedad P se cumple para 0. ´ n Suponer que la propiedad se sumple para k (hip´ etapa de inducci on o otesis otesis de inducci´on) on)
y probar que esto implica que se cumple para k + 1. 1. ´ n Puesto que hemos probado en la etapa base que 0 ∈ A y en la etapa de conclusion o
inducci´ on o n que si k ∈ A entonces enton ces tambi´ tamb i´en en k + 1 ∈ A, resulta que, por el principio de inducci´ on, podemos deducir que A = N, como quer´ on, quer´ıamos demostrar. demost rar. A veces, interesa demostrar que cierta propiedad se cumple para todo k ≥ m. En este caso debemos demostrar que el conjunto, A = {n ∈ N | P ( P (n + m) se cumple} coincide con el conjunto N. Para Para ello seguimos seguimos el siguiente siguiente razonamiento: razonamiento: etapa base (n = 0) Probar que P ( P (m) se cumple. ´ n (n > 0) Suponer que P (k) se cumple, siendo k ≥ m y probar que etapa de inducci on o
P ( P (k + 1) se cumple. ´ n Por las etapas anteriores y el principio de inducci´ conclusion o on on tenemos que A = N y
por tanto P se cumple para todo k ≥ m. El principio de inducci´on on tambi´ t ambi´ en en se usa para definir conjuntos de objetos donde definimos el primer objeto y el objeto k se define en t´erminos erminos del (k − 1)-´esimo esimo objeto. Esto es lo que se llama definici´ on inductiva . Ejemplo 0.7 El factorial de un n´ umero natural puede ser definido inductivamente como, 1. 0! = 1 2.
k! = k · (k − 1)! para k > 0.
13
14
CAP´ITUL ITULO O 1: ´ LENGUAJES Y GRAMATICAS FORMALES
§ ¤ oricos ¥ ¦Contenidos Te´oricos 1. Alfabet Alfabetos os y palabr palabras as 1.1 Concatenaci´ on on de palabras 1.2 Potencia de una palabra 1.3 Inversi´ on on de palabras 2. Lenguaje Lenguajess formal formales es 2.1 Operaciones del algebra ´algebra de conjuntos 2.2 Concatenaci´ on, on, potencia e inversi´ on on de lenguajes 2.3 Clausura de un lenguaje 3. Gram Gram´ aticas a´ticas formales 3.1 Definiciones b´asicas asicas 3.2 Notaci´ on on BNF 3.3 Clasificaci´ on on de gram´aticas aticas 3.4 Teorema de la jerarqu´ jerarqu´ıa de Chomsky (enunciado) 4. Noc Nocion iones es b´ asicas sobre traductores asicas
1.
Alfa Alfabet betos os y pa pala labr bras as
Un alfabeto es un conjunto c onjunto finito y no vac´ vac´ıo de elementos llamados llama dos s´ımbo mbolos o letras. Una palabra o cadena sobre un alfabeto V es una cadena finita de s´ımbolos ımbolos del alfabeto. La longitud de una cadena w, que notaremos como |w|, es el n´umero umero de letras que aparecen en w . A la cadena que no tiene s´ımbolos, ımbolos, o lo que es lo mismo, que tiene longitud 0, la llamaremos palab pal abra ra vac´ va c´ıa ıa y se nota por λ (o tambi ta mbi´´en en ǫ, seg´ un un los autores). Si V es un alfabeto, llamaremos V n al conjunto de todas las palabras de longitud n sobre V . V . 0 n Un elemento de V ser´ a una cadena del tipo a1 a2 . . . an donde cada ai ∈ V . V . Llamaremos Llamaremos V al 0 conjunto cuyo unico u ´ nico elemento es la palabra vac´ vac´ıa, es decir, V = {λ} . El conjunto de todas las cadenas de cualquier longitud sobre V es: ∞
∗
V =
V n
n=0
Llamamos V + al conjunto de todas las cadenas sobre el alfabeto V excepto la vac´ vac´ıa. Por tanto, + ∗ V = V − {λ}. 15
1.1. 1.1.
Conc Co ncat atena enaci ci´ on o ´n de Palabras
La operaci´ on on de concatenaci´ on, on, que notaremos ‘·’, es una operaci´ on binaria entre palabras sobre on un alfabeto V, esto es: · : V ∗ × V ∗ −→ V ∗ de forma que si tenemos dos palabras x, y ∈ V ∗ donde x = a1 a2 . . . an , y = b1 b2 . . . bm entonces, x concatenado con y ser´ a una palabra w ∈ V ∗ con |w| = |x| + |y|, de forma que: w = x · y = a1 a2 . . . an b1 b2 . . . bm §
¤
Nota
¦
¥
A veces se suele suprimir el ‘ ·’ y se puede escribir directamente w = xy
Algunas propiedades de la concatenaci´ on on son: operaci´on on cerrada
∀ x, y ∈ V ∗ : x · y ∈ V ∗
propiedad asociativa elemento elemento neutro λ
∀ x,y,z ∈ V ∗ : x · (y · z ) = (x · y ) · z ∀ x ∈ V ∗ : λ · x = x · λ = x
Por tener estas propiedades (V (V ∗ , ·, λ) es un monoide. monoide. Adem´ as as cada palabra de V ∗ se representa de forma unica ´ como concatenaci´ on on de s´ımbolo ımb oloss de V , V , por eso es adem´as as un monoide libre. libre. Todo monoide libre cumple la ley de cancelaci´ on izquierda y derecha, on derecha, en este caso, ∀ x,y,z ∈ V se cumple que: (x · y = x · z ) ⇒ (y = z )
(y · x = z · x) ⇒ (y = z )
Decimos que una cadena z es subcadena de otra cadena w si existen cadenas x, y ∈ V ∗ tal que w = x · z · y . Vamos a ver dos conjuntos especiales de subcadenas: Prefijo(w Prefijo(w) = {x ∈ V ∗ | ∃ z ∈ V ∗ : w = x · z } Sufijo(w Sufijo(w) = {x ∈ V ∗ | ∃ z ∈ V ∗ : w = z · x} Diremos que x es un prefijo de w si x ∈ Prefijo(w Prefijo(w) y ser´a un prefijo propio si x = w. Por otra parte, diremos que x es un sufijo de w si x ∈ Sufijo(w Sufijo(w) y ser´a un sufijo propio si x = w. Ejemplo 1.1 Si w = abab es una palabra sobre el alfabeto {a, b}, o lo que es lo mismo, w ∈ {a, b}∗ , tenemos que: ab es un prefijo propio de w abab es un prefijo de w, pero no es propio b es un sufijo de w
1.2. 1.2.
Potenc otencia ia de de una pal palab abra ra
Llamamos potenc pote ncia ia n-´esima es ima de una palabra, a la operaci´on on que consiste en concatenar la palabra ∗ consigo misma n veces. Dada una palabra w ∈ V , se define de fine inducti i nductivamente vamente la potencia pote ncia n-´esima esima n de w, que notaremos w , como: 1. w0 = λ 2. wn = w · wn−1 para n > 0 Ejemplo 1.2 Si w = aba es una palabra sobre el alfabeto {a, b} entonces: w0 = λ w1 = aba w2 = abaaba 16
1.3. 1.3.
Inv Inversi´ ersi´ on on de palabras
Si w = a1 a2 . . . an es una palabra sobre un alfabeto V entonces la palabra inversa o refleja de w se define como: wR = an an−1 . . . a1 Ejemplo 1.3 Si w = aaba es una palabra sobre el alfabeto {a, b}, entonces wR = abaa. abaa.
2.
Leng Lenguaje uajess form formal ales es
Llamamos lenguaje sobre el alfabeto V a cualquier subconjunto de V ∗ . As´ As´ı tenemo ten emoss que, ∗ V , ∅ , y V pueden considerarse como lenguajes. Puesto que un lenguaje es tan s´olo olo una clase especial de conjunto, podemos especificar un lenguaje lenguaje finito por extensi´ extensi´ on on enumerando sus elementos entre llaves. Por ejemplo, {aba,czr,d,f } es un lenguaje sobre el alfabeto {a,b,c,...,z}. Sin embargo, la mayor´ mayor´ıa de los lengua jes de inter´es es son infinitos. infinitos. En este caso podemos especificar un lenguaje por comprensi´on on de la siguiente forma: L = {w ∈ V ∗ | w cumple la propiedad P } En la definici´ on on anterior vemos que V ∗ es el conjunto referencial , que q ue podem p odemos os llamar llama r tambi´ ta mbi´en en lenguaje universal sobre V . V . Ejemplo 1.4 L = {w ∈ { 0, 1}∗ | ceros( ceros(w) = unos( unos(w)}, palabras que tienen el mismo n´ umero de ceros que de unos.
2.1. 2.1.
Operacio Operaciones nes del del algebra algebra de de conjun conjuntos tos
Sean L1 y L2 dos lenguajes definidos sobre el alfabeto V . V . Se define la uni´ on de estos dos lenguajes como el lenguaje L sobre V que se especifica como: L = L1 ∪ L2 = {w ∈ V ∗ | (w ∈ L1 ) ∨ (w ∈ L2 )} La uni´on on de lenguajes sobre el mismo alfabeto es un operaci´on on cerrada y adem´ as as cumple las propiedades asociativa , conmutativa , y existe un elemento neutro que es el lenguaje vac´ vac´ıo ∅ (no es lo mismo ∅ que el lenguaje que contiene contiene la palabra palabra vac´ ac´ıa {λ}). El conjunto P (V ∗ ) (esto es, el conjunto de las partes de V ∗ , tambi´en en llamado llama do 2V ), est´ a formado por todos los lenguajes posibles que se pueden definir sobre el alfabeto V . V . Entonces, por cumplir la uni´on on las ∗ propiedades propiedades anteriores anteriores tenemos tenemos que (P (V ), ∪, ∅) es un monoide abeliano. abeliano. De forma an´aloga aloga a la uni´ union o´n se pueden definir otras operaciones del ´algebra algebra de conjuntos como la intersecci´ on, diferencia, y complementaci´ on de lenguajes. Por ejemplo, el complementario del lenguaje L sobre el alfabeto V ser´ a: a: L = V ∗ − L. ∗
2.2. 2.2.
Conca Co ncate tena naci ci´ o on, ´n, potencia e inversi´ on on de lenguajes
Sean L1 y L2 dos lenguajes definidos sobre el alfabeto V , V , la concatenaci´ on de estos dos lenguajes es otro lenguaje L definido como: L1 · L2 = {x · y ∈ V ∗ | (x ∈ L1 ) ∧ (y ∈ L2 )} La definici´ definici´ on on anterior s´ olo o lo es v´ alida alida si L1 y L2 contienen al menos un elemento. Podemos extender la operaci´on on de concatenaci´on on al lenguaje vac´ vac´ıo de la siguiente manera: ∅
·L= L·∅ = ∅ 17
La concatenaci´ on de lenguajes sobre un alfabeto es una operaci´on on on cerrada , y adem´as as cumple la propiedad asociativa y tiene un elemento neutro que es el lenguaje {λ}. Con lo cual, tenemos que (P (V ∗ ) , ·, {λ}) es el monoide monoide inducido inducido por el monoide (V (V ∗ , ·, λ) sobre P (V ∗ ). Esto es, la operaci´on on de concatenaci´on on de palabras induce la operaci´ on on de concatenaci´on on de lenguajes y ´esta esta conserva conserva las propiedades de la primera. Teorem eorema a 1.1 1.1 Dados los lenguajes A,B,C lenguajes A,B,C sobre sobre un alfabeto V , V , la concatenaci concatenaci´ on o´n de lengua jes es distributiva con respecto a la uni´on, on, esto es, se cumple que: 1. A · (B ∪ C ) = (A · B ) ∪ (A · C ) 2. (B ∪ C ) · A = (B · A) ∪ (C · A) Dem.- La demostr demostraci´ aci´ on se deja como ejercicio. En el primer caso se debe probar que: on A · (B ∪ C ) ⊆ (A · B ) ∪ (A · C ) y (A · B ) ∪ (A · C ) ⊆ A · (B ∪ C ) para demostrar la igualdad y el segundo caso se demuestra de forma an´aloga. aloga.
Una vez definida la concatenaci´on on de lenguajes, podemos definir la potencia poten cia n-´esima esim a de un lenguaje como la operaci´ on que consiste en concatenar el lenguaje consigo mismo n veces. La on definici´ on on inductiva es: 1. L0 = {λ} 2. Ln = L · Ln−1 , ∀ n > 0 Ejemplo 1.5 Si L = {ab,c} es un lenguaje sobre el alfabeto {a,b,c} entonces, L0 L1 L2 L3
= {λ} = L = {ab,c} = L · L1 = {abab abab,, abc, abc, cab, cab, cc} 2 = L · L = {ababab ababab,, ababc, ababc, abcab, abcab, abcc, abcc, cabab, cabab, cabc, cabc, ccab, ccab, ccc}
Las definiciones de prefijo y sufijo de una palabra podemos extenderlas a lenguajes de la siguiente forma: Prefijo(L Prefijo(L) = Prefijo(w Prefijo(w) Sufijo(L Sufijo(L) = Sufijo(w Sufijo(w)
w ∈L
w ∈L
Tambi´en en podemos po demos definir el lenguaje inverso o reflejo de L como:
LR = wR | w ∈ L
2.3. 2.3.
Claus Clausur ura a de un leng lenguaje uaje
Dado un lenguaje L sobre un alfabeto V se define la clausura positiva (o cierre positivo) de L, denotado L+ , como: ∞
+
L =
Ln
n=1
Definimos L∗ como la clausura (o cierre) de L, como: ∞
∗
L =
n=0
18
Ln
En ambos casos, Ln se refiere refiere a la potencia n-´esima esima del lenguaje L en el monoide inducido ∗ (P (V ) , ·, {λ}). El cierre o clausura de un lenguaje, por definici´on, on, contiene contiene cualquier palabra palabra que se obtenga por concatenaci´ on on de palabras de L y adem´ as as la palabr pal abraa vac´ vac´ıa.
3.
Gram´ aticas aticas formales
Hasta ahora hemos descrito los lenguajes formales como se describen los conjuntos: por extensi´on on (si son finitos) o por comprensi´on. on. Aqu´ Aqu´ı vamos a introducir introducir otra forma general y rigurosa rigurosa de describir un lenguaje formal: mediante el uso de gram´ aticas. aticas. Las gram´ aticas aticas son mecanismos generadores de lenguajes, es decir, nos dicen c´omo omo podemos obtener o construir palabras de un determinado lenguaje.
3.1. 3.1.
Defini Definici cion ones es b´ asicas asicas
´ tica es una cuadrupla G = (V N Definici´ on on 1.1 Una gramatica a N , V T T , S , P ) donde:
V T ımbolos ımbolo s termin ter minales ales T es el alfabeto de s´ V N a lfabeto eto de s´ımbolos ımbolo s no terminal te rminales es o variables, variables, de forma que debe ser V ser V N N es el alfab N ∩ V T T = ∅ y denotamos con V al alfabeto total de la gram´ atica, atica, esto es, V = V N N ∪ V T T . ımbo lo inici ini cial al y se cumple que S ∈ V N S es el s´ımbolo N P es un conjunto finito de reglas de producci´ on ´ n es un par ordenado (α, β ) de forma que: Definici´ on on 1.2 Una regla de producci on o ∗ ∗ (α, β ) ∈ (V ∗ · V N N · V ) × V ∗ ∗ Es decir, α = γ 1 Aγ 2 donde γ 1 , γ 2 ∈ (V N on on N ∪ V T T ) , A ∈ V N N y β ∈ (V N N ∪ V T T ) . Una producci´ (α, β ) ∈ P se suele escribir de forma infija como α → β .
Por convenio usaremos letras may´ usculas usculas para los s´ımbolos no terminales; d´ıgitos y las primeras letras min´ usculas usculas del alfabeto para los s´ımbolos terminales; las ultimas ´ letras min´ usculas usculas ∗ del alfabeto para palabras que pertenezcan a V T y letras griegas para cualquier palabra que pertenezca a V ∗ . Usando este convenio, a veces se suele describir una gram´atica atica enumerando unicament u ´ nicamentee sus reglas de producci´ producci´ on y cuando varias reglas tienen la misma parte izquierda, se on suelen agrupar separ´andolas andolas con |. Ejemplo 1.6 Sea la gram´ atica G cuyas producciones son: S → aSa | bSb | a | b | λ Esta gram´ atica tiene una sola variable S que adem´ as es el s´ımbolo inicial. V T T = {a, b} y P contiene 5 reglas de producci´ on. Definici´ on on 1.3 Sea G una gram´ atica y sean las cadenas α, β ∈ V ∗ . Decimos que α deriva atica ´ n directa derivaci on o directa), si y s´ directamente en β , que notamos como α ⇒ β ( derivaci olo olo si existe una ∗ producci´on on δ → σ ∈ P tal que α = γ 1 δγ 2 , β = γ 1 σγ 2 con γ 1 , γ 2 ∈ V . Esto quiere decir que α deriva deriva directamente en β , si β puede obtenerse a partir de α sustituyendo una ocurrencia de la parte izquierda de una producci´on on que aparezca en α por la parte derecha de la regla de producci´on. on. 19
§
¤
Si α → β es una regla de producci´on o n de G, entonces se cumple siempre que α ⇒ β . Cuando sea necesario distinguir entre varias gram´ aticas, aticas, escribiremos α ⇒G β , para referirnos a un derivaci´on on directa en G. Nota
¦
¥
Por la definici´ definici´ on anterior se deduce que ⇒ es una relaci´on on on binaria en el conjunto de cadenas de ∗ ∗ la gram´ atica, atica, esto es: ⇒ ⊆ V × V . Aqu´ Aqu´ı usamos una notaci´ notacion o´n infija para indicar que α ⇒ β en lugar de (α, (α, β ) ∈ ⇒. Definici´ on on 1.4 Decimos que α que α deriva en β , o bien que, β es derivable de α, y lo notamos como ∗ ´ n) si y s´ α ⇒ β ( derivaci olo si se verifica una de las dos condiciones siguientes: olo derivaci on o 1. α = β, (son la misma cadena), o bien, 2. ∃ γ 0 , γ 1 , . . . , γn ∈ V ∗ tal que γ 0 = α, γ n = β y ∀ 0 ≤ i < n se cumple que γ i ⇒ γ i+1 A la secuencia γ secuencia γ 0 ⇒ γ 2 ⇒ . . . ⇒ γ n la llamaremos secuencia llamaremos secuencia de derivaciones directas de longitud n, o simplemente derivaci´ on on de longitud n. §
¤
∗
Por la definici´ on on anterior est´a claro que ⇒ es tambi´en en una relaci´ relaci on o´n binaria ¦ ¥ ∗ en V y adem´ as a s es la clausura reflexiva y transitiva de la relaci´ on on de derivaci´on on ∗ directa ⇒. Esto quiere decir que ⇒ es la menor relaci´ on que cumple lo siguiente: Nota
∗
Si α ⇒ β entonces α ⇒ β . Esto es, si dos cadenas est´an an relacionadas mediante ∗ ⇒ entonces tambi´en en lo est´ an an mediante la relaci´ on on ⇒ ∗
∗
⇒ es reflexiva, ya que ∀ α ∈ V ∗ se cumple que α ⇒ α ∗ ∗ ∗ ∗ ⇒ es transitiva. En efecto, si α ⇒ β y β ⇒ γ , entonces α ⇒ γ ∗ Definici´ on on 1.5 Sea una gram´atica atica G = (V N N , V T T , S , P ). Una palabra α ∈ (V N N ∪ V T T ) se de∗ nomina forma sentencial de la gram´ atica, atica, si y s´olo olo si se cumple que: S ⇒ α. Una forma sentencial w sentencial w tal que w ∈ V T ∗ se dice que es una sentencia.
Ejemplo 1.7 Sea la gram´ atica S → aSa | bSb | a | b | λ , podemos afirmar lo siguiente: aaSb ⇒ aabSbb, aabSbb, aunque ni aaSb ni aabSbb son formas sentenciales de G ∗
aabb ⇒ aabb, aabb, aunque aabb no es una sentencia de G S, aSa, abSba, λ son formas sentenciales de G y adem´ as λ es una sentencia aabaa es una sentencia de G, ya que existe una derivaci´ on de longitud 3 por la que ∗ S ⇒ aabaa. aabaa. En efecto: S ⇒ aSa ⇒ aaSaa ⇒ aabaa Definici´ on on 1.6 Sea una gram´ atica atica G = (V N N , V T T , S , P ) . Se llama lenguaje generado por la gram´ atica atica G al lenguaje L(G) formado por p or todas to das las cadenas de s´ımbolos terminales que son derivables derivables del s´ımbolo inicial de la gram´ atica atica (sentencias):
∗
∗
L(G) = w ∈ V T | S ⇒ w
Ejemplo 1.8 Sea L Sea L = w ∈ { a, b}∗ | w = wR . Este lenguaje est´ a forma fo rmado do por todos los pal´ pal´ındroınd romos sobre el alfabeto {a, b}. Puede probarse que la gram´ atica S → aSa | bSb | a | b | λ genera el lenguaje L. En general general no existe un m´ etodo etodo exacto para para prob probar ar que una gram´ gram´ atica genera un determinado lenguaje. Para este caso tan sencillo podemos probarlo de “manera informal” ∗ haciendo una serie de derivaciones hasta darnos cuenta de que S ⇒ w si y s´ olo si w = wR . Luego veremos una demostraci´ on formal por inducci´ on en la secci´ on de aplicaciones. 20
Definici´ on on 1.7 Dos gram´ aticas aticas G y G′ son equivalentes si y s´olo olo si generan el mismo len′ guaje, es decir, sii L(G) = L(G ).
3.2. 3.2.
Nota Notaci ci´ on o ´n BNF
A veces se utiliza una notaci´ on on especia especiall para para descri describir bir gram´ gram´ aticas aticas llamada notaci´ notacion o´n BN F (Backus-Naus-Form ). ). En la notaci´ on on BN F los s´ımbolos ımbolo s no terminal t erminales es o variables variabl es son encerrado e ncerradoss entre ´angulos angulos y utilizaremos el s´ımbolo ::= para las producciones, en lugar de →. Por ejemplo, la producci´on on S → aSa se representa en BN F como S ::= a S a. Tenemos tambi´en en la notaci´ notacion o´n BNF-extendida que incluye adem´as as los s´ımbolos [ ] y { } para indicar elementos opcionales y repeticiones, respectivamente. Ejemplo 1.9 Supongamos que tenemos un lenguaje de programaci´ on cuyas dos primeras reglas de producci´ on para definir su sintaxis son:
programa ::= [cabecera ] begin sentencias end sentencias ::= sentencia {sentencia } } Esto viene a decir que un programa se compone de una cabecera opcional, seguido de la palabra clave “begin”, a continuaci´ on una lista de sentencias (debe haber al menos una sentencia) y finaliza con la palabra clave “end”. Podemos transformar las producciones anteriores para especificarlas, seg´ un la notaci´ on que nosotros hemos introducido (est´ andar), de la siguiente forma: P → C begin C begin A end | begin A end A → BA|B donde P es el s´ımbolo inicial de la gram´ atica y corresponde a la variable programa , C corresponde a cabecera , A se refiere a la variable sentencias y B a sentencia . La simbolog´ simbolog´ıa utilizada para describir las gram´ aticas aticas en notaci´ on on est´ andar andar y en notaci´ on on BN F nos proporcionan un herramienta para describir los lenguajes y la estructura de las sentencias del lenguaje. Puede considerarse a esta simbolog´ simbolog´ıa como un metalenguaje, metalenguaje, es decir un lenguaje que sirve para describir otros lenguajes.
3.3.
Jerarqu´ Jerarqu´ıa de Chomsky
En 1959 Chomsky clasific´ o las gram´ aticas en cuatro familias, que difieren unas de otras en la aticas forma que pueden tener sus reglas de producci´on. on. Si tenemos una gram´atica atica G = (V N N , V T T , S , P ) clasificaremos las gram´ aticas y los lenguajes generados por ellas, de la siguiente forma: aticas aticas regulares). regulares ). Pueden ser, a su vez, de dos tipos: Tipo 3 (Gram´
• Lineales por la derecha . Todas sus producciones son de la forma: A → bC A→b A→λ donde A, C ∈ V N N y b ∈ V T T . 21
• Lineales por la izquierda . Con producciones del tipo: A → Cb A→b A→λ Los lenguajes generados por estas gram´aticas aticas se llaman lenguajes regulares y el conjunto de todos estos lenguajes es la clase L3 . aticas libres del contexto). contexto ). Las producciones son de la forma: Tipo 2 (Gram´ A→α ∗ donde A ∈ V N aticas aticas se N y α ∈ (V N N ∪ V T T ) . Los lenguajes generados por este tipo de gram´ llaman lenguajes libres del contexto y la clase es L2 .
aticas sensibles al contexto). contexto ). Las producciones son de la forma: Tipo 1 (Gram´ αAβ → αγβ donde α, β ∈ V ∗ y γ ∈ V + Se permite adem´as as la producci´ on on S → λ siempre y cuando S no aparezca en la parte derecha de ninguna regla de producci´ on. on. El sentido de estas reglas de producci´on on es el de especificar que una variable A puede ser reemplazada por γ en una derivaci´on on directa s´ olo olo cuando A aparezca en el “contexto” de α y β, de ah´ ah´ı el nombre nombre “sensibles “sensibles al contexto” contexto”.. Adem´ Ademas, a´s, las producciones de esa forma cumplen siempre que la parte izquierda tiene longitud menor o igual que la parte derecha, pero nunca mayor (excepto para S → λ). Esto quiere decir que la gram´ atica atica es no contr´ actil . Los lenguajes generados por las gram´aticas aticas de tipo 1 se llaman lenguajes sensibles al contexto y su clase es L1 . Tipo 0 (Gram´ aticas con estructura de frase) frase ) Son las gram´ aticas aticas m´ as as generales, que por
ello ell o tambi´ t ambi´en en se s e llama ll aman n gram´ aticas sin restricciones. restricciones. Esto quiere decir que las producciones ∗ pueden pueden ser de cualquier cualquier tipo permitido, permitido, es decir, decir, de la forma α → β con α ∈ (V ∗ · V N N · V ) y β ∈ V ∗ . Los lenguajes generados por estas gram´aticas aticas son los lenguajes con estructura de frase, que se agrupan en la clase L0 . Estos lengua jes tambi´ en en se conocen en el campo de la Teor´ enumerables. eor´ıa de la Computabilida Comput abilidad d como lenguajes recursivamente enumerables. Teorema 1.2 (Jerarqu´ (Jerarqu´ıa de Chomsky) Dado un alfabeto V , V , el conjunto de los lenguajes regulares sobre V est´a incluido propiamente en el conjunto de los lenguajes libres de contexto y este a su vez est´a incluido propiamente en el conjunto de los lenguajes sensibles al contexto, que finalmente est´a incluido propiamente en el conjunto de lenguajes con estructura de frase. Esto es: L3 ⊂ L 2 ⊂ L 1 ⊂ L 0 La demostraci´ on de este teorema la iremos viendo a lo largo del curso. on §
¤
En este tema hemos hecho referencia al termino lenguaje formal para diferenciarlo de lenguaje lenguaje natural natural . En general, un lenguaje natural es aquel que ha evolucionado con el paso del tiempo para fines de la comunicaci´on on humana, por Nota
¦
¥
22
ejemplo el espa˜ nol nol o el ingl´ es. es. Estos lenguajes evolucion evolucionan an sin tener en cuenta cuenta reglas gramaticales gramaticales formales. Las reglas surgen despu´ despu´es es con objeto de explicar, explicar, m´ as as que determinar la estructura de un lenguaje, y la sintaxis sintaxis es dif´ dif´ıcil de determinar determinar con precisi´on. on. Los lenguajes formales, por el contrario, est´an an definidos por reglas de producci´on on preestablecidas y se ajustan con todo rigor o “formalidad” a ellas. Como ejemplo tenemos los lenguajes de programaci´ on on y los lenguajes l´ogicos ogicos y matem´ atiaticos. No es de extra˜ nar, por tanto, que se puedan construir compiladores eficientes nar, para los lenguajes de programaci´ on y que por contra la construcci´on on on de traductores traductores para lenguaje natural sea una tarea compleja e ineficiente, en general. Veremos que las gram´ aticas regulares y libres de contexto, junto con sus m´aquinas aticas aquinas abstractas asociadas tienen especial inter´ es es en la construcci´ on de traductores para lenguajes de on programaci´ on. on.
4.
Nociones b´ asicas asicas sobre traductores
Hace apenas ap enas unas cuantas d´ecadas, ecadas, se utilizaban los llamados lenguajes de primera generaci´ on para hacer que los computadores resolvieran problemas. Estos lenguajes operan a nivel de c´odigo odigo binario de la m´ aquina, que consiste en una secuencia de ceros y unos con los que se instruye aquina, al ordenador para que realice acciones. La programaci´on, on, por tanto, era dif´ dif´ıcil y problem´ atica, atica, aunque pronto se dio un peque˜no no paso con el uso de c´odigo odigo octal o hexadecimal. El c´ odigo odigo de m´ aquina fue reemplazado por los lenguajes de segunda generaci´ aquina on , o lenguajes ensambladores. ensambladores. Estos lenguajes permiten usar abreviaturas nem´ onicas como nombres simb´ onicas olicos, olicos, y la abstracci´ on cambia del nivel de flip-flop al nivel de registro. Se observan ya los primeros pasos on hacia la estructuraci´on on de programas, aunque no puede utilizarse el t´ermino ermino de programaci´ on estructurada al estructurada al hablar de programas en ensamblador. Las desventajas principales del uso de los lenguajes ensambladores son, por un lado, la dependencia de la m´ aquina y, por otro, que son aquina poco legibles. Para sustituir los lenguajes ensambladores, se crearon los lenguajes lenguajes de terce tercerra generaci´ generaci´ on o lenguajes de alto nivel . Con ellos se pueden usar estructuras de control basadas en objetos de datos l´ ogicos: ogicos: variables de un tipo espec´ espec´ıfico. Ofrecen un nivel de abstracci´ on on que permite la especificaci´ on de los datos, funciones o procesos y su control en forma independiente de la on m´ aquina. aquina. El dise˜ no de programas para resolver problemas complejos es mucho m´ no as as sencillo utilizando este tipo de lenguajes, ya que se requieren menos conocimientos sobre la estructura interna del computador, aunque es obvio que el ordenador unicamente u ´nicamente entiende c´odigo odigo m´ aquina. aquina. Por lo tanto, para que un computador pueda ejecutar programas en lenguajes de alto nivel, estos deben ser traducidos a c´odigo odigo m´ aquina. A este proceso se le denomina compilaci´ aquina. on , y la herramien herramienta ta correspondie correspondiente nte se llama compilador . Nosotros Nosotros vamos a entender entender el t´ ermino ermino compilador como compilador como un programa que lee otro, escrito en lenguaje fuente, fuente, y lo traduce a lenguaje objeto, objeto, informando, durante el proceso de traducci´ on, de la presencia de errores en el programa on, fuente. Esto se refleja en la figura 1.1. En la l a d´ecada ecada de 1950, 1 950, se consider´ co nsider´o a los compiladores como programas notablemente dif´ dif´ıciles de escribir. El primer compilador de FORTRAN, por ejemplo, necesit´o para su implementaci´ on, on, 18 a˜ nos nos de trabajo en grupo. Desde entonces, se han descubierto t´ecnicas ecnicas sistem´ aticas aticas para manejar muchas de las importantes tareas que surgen en la compilaci´on. on. Tambi´en en se han desarrollado desarrol lado buenos lenguajes de implementaci´ on, entornos de programaci´ on, on y herramientas de software. on Con estos avances, puede construirse un compilador real incluso como proyecto de estudio en una asignatura sobre dise˜ no no de compiladores. 23
Programa
Programa COMPILADOR
Fuente
Objeto
Mensajes de error
Figura 1.1: Definici´ on on de un compilador 4.1. 4.1.
Traducto raductores res y compi compilad ladores ores
Un traductor es traductor es un programa que acepta cualquier texto expresado en un lenguaje (el lenguaje fuente del traductor) y genera un texto sem´ anticamente equivalente expresado en otro lenguaje anticamente destino). (su lenguaje destino). Un ensamblador traduce un lenguaje ensamblador en su correspondiente c´odigo odigo m´ aquina. aquina. Generalmente, un ensamblador genera una instrucci´ on on de la m´ aquina aquina por cada instrucci´ instrucci´ on on fuente. Un compilador traduce desde un lenguaje de alto nivel a otro lenguaje de bajo nivel. Generalmente, un compilador genera varias instrucciones de la m´aquina aquina por cada comando fuente. Los ensambladores y compiladores son las clases m´ as importantes de traductores de lenguajes de as programaci´ on, on, pero no son las unicas u ´ nicas clases. A veces se utilizan los traductores de alto nivel cuya nivel cuya fuente y destino son lenguajes de alto nivel. Un desensamblador traduce un c´odigo odigo m´ aquina aquina en su correspondiente lenguaje ensamblador. Un descompilador traduce descompilador traduce un lenguaje de bajo nivel en un lenguaje de alto nivel. Nosotros estamos interesados en la traducci´ on de textos que son programas. Antes de realizar on cualquier traducci´on, on, un compilador comprueba que el texto fuente sea un programa correcto del lenguaje fuente. (En caso contrario genera un informe con los errores). Estas comprobaciones tienen en cuenta la sintaxis y las restricciones restricciones contextuales del lenguaje fuente. fuente. Suponiendo Suponiendo que el programa fuente es correcto, el compilador genera un programa objeto que es sem´anticamente anticamente equivalente al programa fuente, es decir, que tiene los efectos deseados cuando se ejecuta. La generaci´ on del programa objeto tiene en cuenta tanto la sem´ on antica del lenguaje fuente como la sem´ antica del lenguaje destino. Los traductores, y otros procesadores de lenguajes, son programas que manipulan programas. Varios lenguajes se ven implicados: no s´olo olo el lenguaje fuente y el lenguaje destino, sino tambi´ bi´en en el lenguaje lenguaje en el cual cual el traduc traductor tor se ha escrit escrito. o. Este Este ultimo u´ltimo es el llamado lenguaje de implementaci´ on .
4.2.
Int´ erpretes erpre tes
Un compilador nos permite preparar un programa para que sea ejecutado en una m´aquina, aquina, traduciendo el programa a c´odigo odigo m´ aquina. El programa entonces se ejecuta a la velocidad de aquina. la m´ aquina. aquina. Este m´ etodo etodo de trabajo no est´ a libre de inconvenientes: todo el programa debe ser traducido antes que pueda ejecutarse y producir resultados. En un entorno interactivo, la interpretaci´ on es un m´etodo etodo de trabajo m´ as as atractivo. Un int´ in t´erpr er pret etee es un programa que acepta otro programa (el programa fuente) fuente) escrito en un determinado lenguaje (el lenguaje fuente), fuente), y ejecuta ej ecuta el programa program a inmediata inme diatamente. mente. Un int´ i nt´erprete erprete trabaja cargando, analizando y ejecutando una a una las instrucciones del programa fuente. El programa fuente comienza a ejecutarse y produce resultados desde el momento en que la primera instrucci´ on on ha sido analizada. El int´erprete erprete no traduce el programa fuente en un c´ odigo odigo objeto. 24
La interpretaci´on on es un buen m´etodo etodo cuando se dan las siguientes circunstancias: El programador est´ a trabajando en forma interactiva, y quiere ver el resultado de cada instrucci´ on antes de entrar la siguiente instrucci´on. on on. El programa se va a utilizar s´olo olo una vez, y por tanto la velocidad de ejecuci´on o n no es importante. Se espera que cada instrucci´on on se ejecute una sola vez. Las instrucciones tiene un formato simple, y por tanto pueden ser analizadas de forma f´acil acil y eficiente. La interpretaci´on on es muy lenta. La interpretaci´ on de un programa fuente, escrito en un lenguaje on de alto nivel, puede ser 100 veces m´as as lenta que la ejecuci´on on del programa equivalente escrito en c´odigo odigo m´ aquina. aquina. Por tanto la interpret interpretaci´ aci´ on no es interesante cuando: on El programa se va a ejecutar en modo de producci´on, on, y por tanto la velocidad es importante. Se espera que las instrucciones se ejecuten frecuentemente. Las instrucciones tienen formatos complicados, y por tanto su an´alisis alisis es costoso en tiempo. Alguno Alg unoss int´ i nt´erpretes erpr etes m´as as o menos conocidos son: (a) Un int´erprete erprete Caml: Caml es un lengua je funcional fun cional.. El int´erprete erprete lee cada c ada cada l´ınea hasta el s´ s´ımbolo ”;;” y la ejecuta produciendo una salida, por lo que el usuario ve el resultado de la misma antes de entrar la siguiente. Existen versiones tanto para Windows como para distintas versiones de Linux. Existen tambi´ en en varios varios compiladores para distintos sistemas operativos. (b) Un int´erprete erprete Lisp: Lisp es un lenguaje lenguaje en el que existe una estructura estructura de datos (´arbol) arbol) tanto para el c´ odigo como para los datos. odigo (c) El int´ i nt´ erprete erprete de comandos de Unix (shell (shell ): ): Una instrucci´on on para el sistema operativo del usuario de Unix se introduce dando el comando de forma textual. El programa shell lee cada comando, lo analiza y extrae un nombre de comando junto con algunos argumentos y ejecuta el comando por medio de un sistema de llamadas. El usuario puede ver el resultado de un comando antes de entrar el siguiente. Los comandos constituyen un lenguaje de comandos, y el shell es un int´erprete erprete para tal lengua je. (d) Un int´erprete erprete SQL: SQL es un lenguaje lengua je de preguntas (query ( query language) language) a una base de datos. El usuario extrae informaci´ on de la base de datos introduciendo una pregunta SQL, que on es analizada y ejecutada inmediatamente. Esto es realizado por el int´erprete erprete SQL que se encuentra dentro del sistema de administraci´ on on de la base de datos.
4.3. 4.3.
Compil Compilador adores es inter interpret pretado adoss
Un compilador puede tardar mucho en traducir un programa fuente a c´odigo odigo m´ aquina, aquina, pero p ero una vez hecho esto, el programa puede correr a la velocidad de la m´aquina. aquina. Un int´erprete erprete permite perm ite que el programa comience a ejecutarse inmediatamente, pero corre muy lento (unas 100 veces m´ as lento que el programa en c´ as odigo odigo m´ aquina). aquina). Un compilador interpretado es una combinaci´ on on de compilador e int´ erprete, erprete, reuniendo algunas de las ventajas de cada uno de ellos. La idea principal es traducir el programa fuente en un lenguaje intermedio, intermedio, dise˜ nado para cumplir los siguiente requisitos: nado 25
tiene un nivel intermedio entre el lenguaje fuente y el c´odigo odigo m´ aquina aquina sus instrucciones tienen formato simple, y por tanto pueden ser analizadas f´ acil acil y r´apidaapidamente. la traducci´ on desde el lenguaje fuente al lenguaje intermedio es f´acil on acil y r´apida. apida. Por tanto un compilador interpretado combina la rapidez de la compilaci´ on on con una velocidad tolerable en la ejecuci´on. on. El c´ odigo odigo de la M´aquina aquina Virtual de Java (el JVM-code) es un lenguaje intermedio orientado a Java. Nos provee de potentes instrucciones que corresponden directamente a las operaciones de Java tales como la creaci´ on on de ob jetos, llamadas de m´etodos etodos e indexaci´ i ndexaci´ on on de matrices. Por ello la traducci´ on desde Java a JVM-code es f´acil on acil y r´ apida. apida. Adem´ as as de ser potente, las instruccion instrucciones es del JVM-code tienen un formato tan sencillo como las instrucciones del c´ odigo odigo m´ aquina aquina con campos de operaci´ on y campos de operandos, y por tanto son f´ on aciles de analizar. Por ello la aciles interpretaci´ on del JVM-code es relativamente r´apida: on apida: alrededor de ’s´ olo’ olo’ diez veces m´ as as lenta que el c´odigo odigo m´ aquina. aquina. JDK consiste en un traductor de Java a JVM-code y un int´ erprete erprete de JVM-code, los cuales se ejecutan sobre alguna m´aquina aquina M.
4.4. 4.4.
Contex Contexto to de un comp compila ilador dor
En el proceso de construcci´on on de un programa escrito en c´ odigo odigo m´ aquina a partir del programa aquina fuente, suelen intervenir, aparte del compilador, otros programas: Preprocesador : Es un traductor cuyo lenguaje fuente es una forma extendida de alg´un un lenguaje de alto nivel, y cuyo lenguaje objeto es la forma est´ andar del mismo lenguaje. andar Realiza la tarea de reunir el programa fuente, que a menudo se divide en m´odulos almacenados en archivos archivos diferentes. Tambi´ Tambi´en en puede expandir abreviaturas, llamadas macros, a proposiciones del lenguaje fuente. El programa objeto producido por un preprocesador puede , entonces, ser traducido y ejecutado por el procesador usual del lenguaje est´andar. andar. Ensamblador : Traduce el programa en lenguaje ensamblador, creado por el compilador, a c´ odigo odigo m´ aquina. aquina. Cargador y linkador : Un cargador es un traductor cuyo lenguaje objeto es el c´odigo odigo de la m´ aquina aquina real y cuyo lengua je fuente es casi id´entico. entico. Este consiste usualmente en programas de lenguaje m´aquina aquina en forma reubicable, junto con tablas de datos que especifican los puntos en d´onde onde el c´odigo odigo reubicable debe modificarse para convertirse en verdaderamente ejecutable. Por otro lado, un linkador es un traductor con los mismos lenguajes fuente y objeto que el cargador. Toma como entrada programas en forma reubicable que se han compilado separadamente, incluyendo subprogramas almacenados al macenados en librer´ librer´ıas. Los une en una sola unidad de c´odigo odigo m´ aquina lista para ejecutarse. En general, un editor de aquina carga y enlace une el c´odigo odigo m´ aquina aquina a rutinas rutinas de librer´ librer´ıa para producir producir el c´ odigo odigo que realmente se ejecuta en la m´ aquina. aquina. En la figura 1.2 aparece resumido el contexto en el que un compilador puede trabajar, aunque es necesario tener en cuenta que no han de cumplirse estos pasos estrictamente. En cualquier caso, depender´a del lenguaje que se est´ est´e traduciend traduciendoo y el entorno entorno en el que se trabaje.
4.5. 4.5.
Fases ases y estruc estructura tura de un compi compilad lador or
Podemos distinguir, en el proceso de compilaci´ on, dos tareas bien diferenciadas: on, 26
Estrctura del programa fuente
PREPROCESADOR
Programa fuente
COMPILADOR
Programa objeto en lenguaje ensamblador
ENSAMBLADOR
Codigo maquina relocalizable
Biblioteca de archivos objeto relocalizables
EDITOR DE CARGA Y ENLACE
Codigo Maquina absoluto
Figura 1.2: Contexto de un compilador An´ alisis: alisis: Se determina la estructura y el significado de un c´odigo odigo fuente. Esta parte del proceso de compilaci´on on divide al programa fuente en sus elementos componentes y crea una representaci´on on intermedia intermedi a de ´el, el, llamada llama da arbol ´ sint´ actico. actico. S´ınte ın tesi siss: Se traduce el c´odigo odigo fuente a un c´odigo odigo de m´ aquina equivalente, a partir de esa aquina representaci´ on on intermedia. inte rmedia. Aqu´ Aqu´ı, es e s necesario nece sario usar t´ecnicas ecnicas mas especializa especi alizadas das que qu e durante dura nte el an´ alisis. alisis. Conceptualmente, un compilador opera en estas dos etapas, que a su vez pueden dividirse en varias fases. Estas pueden verse en la figura 1.3, d´onde onde se muestra la descomposici´ on on t´ıpic ıp icaa de un compilador. En la pr´actica, actica, sin embargo, se pueden agrupar algunas de estas fases, y las representaciones intermedias entre ellas pueden no ser construidas expl´ expl´ıcitamente. 27
programa fuente
analizador lexico
analizador sintactico
manejo de tabla de simbolos
analizador semantico
manejo de errores
generador codigo intermedio
optimizador de codigo
generador de codigo
programa objeto
Figura 1.3: Fases de un compilador Las tres primeras fases de la figura 1.3 conforman la mayor parte de la tarea de an´ alisis en un compilador, mientras que las tres ultimas u ´ ltimas pueden considerarse como constituyentes de la parte de s´ınte ın tesi siss del mismo. Durante el an´ alis al isis is l´exico ex ico,, la cadena de caracteres que constituye el programa fuente, se lee de izquierda a derecha, y se agrupa en componentes l´exicos, exicos, que son secuencias de caracteres con un significado colectivo. En el an´ alisis sint´ actico, actico, los componentes l´exicos exicos se agrupan jer´ arquicamente en colecciones arquicamente anidadas con un significado com´ un. un. En la fase de an´ alisis sem´ antico se realizan ciertas revisiones para asegurar que los componentes de un programa se ajustan de un modo significativo. Las tres ultimas ´ fases suelen variar de un compilador a otro. Existen, por ejemplo, compiladores que no generan c´odigo odigo intermedio, o no lo optimizan y pasan directamente del an´ alisis alisis sem´ antico antico a la generaci´ on on de c´odigo. odigo. De manera informal, tambi´ en en se consideran fases al administrador de d e la tabla de s´ımbolos y al manejador de errores, errores, que est´an an en interacci´on on con todas las dem´ as: as: Administraci´ on de la tabla de s´ımbolos: ımbolos: Una funci´on on esencial de un compilador es registrar los identificadores utilizados en el programa fuente y reunir informaci´on on sobre los distintos atributos de cada identificador. Estos atributos pueden proporcionar informaci´ on on sobre la memoria asignada a un identificador, su tipo, su ambito a´mbito (la parte del programa d´ onde onde 28
tiene validez), y, en el caso de los procedimientos, cosas como el n´ umero u mero y tipo de sus argumentos, el m´etodo etodo por que que cada argumento es pasado (valor, referencia,...) y el tipo que devuelve, si lo hay. Una tabla tab la de s´ımbolos ımbolo s es una estructura de datos que contiene un registro por cada identificador, con campos para los atributos del identificador. La estructura de datos debe permitir encontrar r´apidamente apidamente datos de ese registro. Cuando el analizador l´exico exico detecta un identificador en el programa fuente, este identificador se introduce en la tabla de s´ımbolos. ımbolos. Sin embargo, normalmente los atributos de un identificador no se pueden determinar durante el an´alisis alisis l´exico. exico. Por ejemplo, cuando el analizador anali zador l´exico exico reconoce recono ce los lo s componente com ponentess l´exicos exicos de la l a declaraci dec laraci´ on o´n de PASCAL var x, y, z : real;
no relaciona unos componentes con otros, y, por tanto, no puede establecer el significado de la frase (x (x, y y z son variables reales). Las fases restantes introducen informaci´on on sobre los identificadores en la tabla de s´ımboımbolos, y despu´es es la utilizan de varias formas. Por ejemplo, cuando se est´ a haciendo el an´alisis alisis sem´ antico antico y la generaci´ on on de c´odigo odigo intermedio, se necesita conocer los tipos de los identificadores, para poder comprobar si el programa fuente los usa de una forma v´alid al ida, a, y, as a s´ı, poder generar las operaciones apropiadas con ellos. El generador de c´ odigo, odigo, por lo general, introduce introduce y utiliza informaci´ informacion o´n detallada sobre la memoria asignada a los identificadores. Detecci´ on e informaci´ on de errores: errores: Cada fase dentro de proceso de compilaci´ on, on, puede encontrar encontrar errores. Sin embargo, embargo, despu´es es de detectar detectar un error, error, cada fase debe tratar de alguna forma ese error, para poder continuar la compilaci´on, on, permitiendo la detecci´on on de nuevos errores en el programa fuente. Un compilador que se detiene cuando encuentra el primer error, no resulta tan ´util util como debiera. Las fases de an´ alisis alisis sint´ actico actico y sem´ antico, antico, por lo general, manejan una gran porci´on on de errores detectables por el compilador. La fase de an´ alis al isis is l´exico ex ico puede detectar errores donde los caracteres restantes de la entrada no forman ning´ un un compon co mponente ente l´exico exico del lengua je. Los errores d´onde onde la cadena cadena de componente componentess l´exicos exicos viola las reglas de la estructura estructura del lenguaje (sintaxis) son determinados por la fase de an´ alisis sint´ actico. actico. Durante la fase de an´ alisis sem´ antico, antico, el compilador intenta detectar construcciones que tengan la estructura sint´actica actica correcta, pero que no tengan significado para la operaci´on on implicada. Por ejemplo, se cometer´ cometer´ıa un error sem´antico antico si se intentaran sumar dos identificadores, uno de los cuales fuera el nombre de una matriz, y el otro el nombre de un procedimiento.
4.5.1.
An´ alisis alis is l´ exico exico (o lineal) lin eal)
Es la primera fase de la que consta un compilador. La parte del compilador que realiza el an´ alisis alisis l´exico exic o se llama lla ma analiza ana lizador dor l´exico exi co (AL), scanner o explorador. La tarea b´asica asica que realiza el AL es transformar un flujo de caracteres de entrada en una serie de componentes l´exicos exicos o tokens. tokens. Se encargar´ıa, ıa, por tanto, de reconocer identificadores, palabras clave, constantes, operadores, op eradores, etc. La secuencia de caracteres que forma el token se denomina lexema . No hay que confundir el concepto de token con el de lexema. A un mismo token le pueden corresponder varios lexemas. Por ejemplo, se pueden reconocer como tokens de tipo ID a todos los identificadores. Aunque para analizar sint´ acticamente una expresi´ acticamente on, on, s´ olo olo nos har´ a falta el c´ odigo de token, el lexema odigo 29
debe ser recordado, para usarlo en fases posteriores dentro del proceso de compilaci´on. El AL es el unico u ´ nico componente del compilador que tendr´a acceso al c´odigo odigo fuente. Por tanto, debe de encargarse de almacenar los lexemas para que puedan ser usados posteriormente. Esto se hace en la tabla tab la de s´ımbolos ımbolo s. Por otro lado, debe enviar al analizador sint´actico, actico, aparte del c´ odigo de token reconocido, la informaci´on odigo on del lugar d´onde onde se encuentra almacenado ese lexema (por ejemplo, mediante un apuntador a la posici´on on que ocupa dentro de la tabla de s´ımbolos). Posteriormente, en otras fases del compilador, se ir´a completando la informaci´ on on sobre cada item de la l a tabla t abla de s´ımbolos. ımbolo s. Por ejemplo, ante la sentencia de entrada cost coste e = prec precio io * 0’98 0’98
el AL podr´ podr´ıa devolver devolver una secuencia de parejas, como la siguiente: [ID,1] [ID,1] [=,] [ID,2] [*,] [CONS,3] [CONS,3]
d´ onde onde ID, I D, =, * y CONS C ONS correspo cor responder nder´´ıan a c´ odigos de tokens y los n´umeros odigos umeros a la derecha de cada pareja pare ja ser´ıa ıa ´ındice ınd icess de la tabla tab la de s´ımbolo ımb olos. s. Si durante la fase de an´alisis alisis l´exico, exico, el AL se encuentra con uno o m´as as lexemas que no corresponden a ning´ un un token v´alido, alido, debe dar un mensaje de error er ror l´exico ex ico e intentar recuperarse. Finalmente, puesto que el AL es el ´unico unico componente del compilador que tiene contacto con el c´ odigo odigo fuente, deb e encargarse de eliminar los s´ımbolos ımbolos no significativos del programa, como espacios en blanco, tabuladores, comentarios, etc. Es conveniente siempre separar esta fase de la siguiente (an´alisis alisis sint´ actico), actico), por razones de eficiencia. Adem´as, as, esto permite el uso de representaciones diferentes del programa fuente, sin tener que modificar el compilador completo.
4.5.2.
An´ alisis sint´ actico actico (o jer´ arquico)
Esta es la segunda fase de la que consta un compilador. La parte del compilador que realiza el an´ alisis alisis sint´ actico actico se llama analizador sint´ actico o parser. Su funci´on on es revisar si los tokens del c´ odigo odigo fuente fuente que le proporciona proporciona el analizador analizador l´ exico exico aparecen en el orden correcto (impuesto por la gram´ atica), y los combina para formar unidades gramaticales , d´ atica), andonos andonos como salida el arbol ´ de derivaci´ on o arbol ´ sint´ actico correspondiente a ese c´odigo odigo fuente. De la forma de construir este ´arbol arbol sint´ actico se desprenden los dos tipos de analizadores sint´actiactico acticos existentes: Cuando se parte del axioma de la gram´atica atica y se va descendiendo, utilizando derivaciones m´as as a la izquierda, hasta conseguir la cadena de entrada, se dice que el an´ alisis es descendente Por el contrario, cuando se parte de la cadena de entrada y se va generando el ´arbol hacia arriba mediante reducciones m´ as a la izquierda (derivaciones m´ as as as a la derecha), hasta conseguir la ra´ ra´ız o axioma, se dice que el an´ alisis es ascendente. ascendente. Si el programa no tiene una estructura sint´actica actica correcta, el analizador sint´ actico no podr´ a encontrar el ´arbol arbol de derivaci´ derivaci´ on correspondiente y deber´a dar mensaje de error sint´ on actico. actico. La divisi´ on on entre an´alisis alisi s l´exico exico y sint´ actico es algo arbitraria. Generalmente se elige una diviactico si´on on que simplifique la tarea completa del an´alisis. alisis. Un factor para determinar c´omo omo realizarla es comprobar si una construcci´on on del lenguaje fuente es inherentemente recursiva o no. Las construcciones construc ciones l´exicas exicas no requieren r equieren recursi´on, on, mientras que las sint´ acticas suelen requerirla. acticas 30
Las gram´ aticas libres de contexto (GLC) formalizan la mayor´ mayor´ıa de las reglas recursivas recursivas que pueden usarse para guiar el an´alisis alisis sint´ actico. Es importante destacar, sin embargo, que la mayor actico. parte de los lenguajes de programaci´on on pertenecen realmente al grupo de lenguajes dependientes del contexto. contexto.
4.5.3.
An´ alisis sem´ antico
Para que la definici´on on de un lenguaje de programaci´ on sea completa, aparte de las especificaon ciones de su sintaxis (estructura o forma en que se escribe un programa), necesitamos tambi´en en especificar su sem´antica antica (significado (significado o definici´ definici´ on de lo que realmente hace un programa). on La sintaxis de un lenguaje de programaci´on on se suele dividir en componentes libres de contexto y sensibles al contexto. La sintaxis libre de contexto define secuencias legales de s´ımbolos, independien independientemen temente te de cualquier cualquier noci´ on sobre el contexto o circunstancia particular en que on aparecen dichos s´ımbolos. Por ejemplo, una sintaxis libre de contexto puede informarnos de que A := B + C es una sentencia legal, mientras que A := B ∗ no lo es. Sin embargo, no todos los aspectos de un lenguaje de programaci´on on pueden ser descritos mediante este tipo de sintaxis. Este es el caso, por ejemplo, de las reglas de alcance para variables, de la compatibilidad de tipos, etc. Estos son componentes sensibles al contexto de la sintaxis que define al lenguaje de programaci´ on. on. Por ejemplo, A := B + C podr´ıa ıa no ser legal si las variables no est´an an declaradas, o son de tipos incompatibles. Puesto Puesto que en la may mayor or´´ıa de los casos, casos, como ya apuntamos apuntamos en la secci´ seccion o´n anterior, se utilizan por simplicidad GLC para especificar la sintaxis de los lenguajes de programaci´on, on, tenemos que hacer un tratamiento especial con las restricciones sensibles al contexto. Estas pasar´ an an a formar parte de la sem´antica antica del lenguaje de programaci´on. on. La fase de an´alisis alisis sem´ antico revisa el programa fuente para tratar de encontrar errores sem´ antico anticos, cos, y re´ une une la informaci´on on sobre los tipos para la fase posterior de generaci´ on on de c´odigo. odigo. Para esto se utiliza la estructura jer´arquica arquica que se construye en la fase de an´alisis alisis sint´ actico, actico, para, por ejemplo, identificar operadores y operandos de expresiones y proposiciones. Adem´as, as, accede, completa y actualiza actual iza con frecuencia la tabla de s´ımbolos. ımbolos. Una tarea importante a realizar en esta fase es la verificaci´ on de tipos. tipos. Aqu´ Aqu´ı, el compilador compil ador comprueba si cada operador tiene operandos permitidos por la especificaci´on on del lenguaje fuente. Muy frecuent frecuentemen emente, te, esta especificaci´ especificaci´ on puede permitir ciertas conversi on conversiones ones de tipos tipos en los operandos, por p or ejemplo, cuando un operador aritm´etico etico binario se aplica a un n´ umero umero entero y a otro real. En este caso, el compilador puede requerir la conversi´on on del n´ umero umero entero a real, por ejemplo. Resumiendo, algunas de las comprobaciones que puede realizar, son: Chequeo y conversi´on on de tipos. Comprobaci´ on o n de que el tipo y n´ umero umero de par´ametros ametros en la declaraci´ on on de funciones coincide con los de las llamadas a esa funci´ on. on. Comprobaci´ on on del rango para ´ındices ındices de arrays. Comprobaci´ on on de la declaraci´ on on de variables. Comprobaci´ on de las reglas de alcance de variables. on
4.5.4.
Generaci´ on de c´ odigo
La generaci´ on on de c´odigo odigo constituye la ultima u ´ltima fase dentro del proceso de compilaci´ on. on . Despu´ Des pu´es es de examinar el c´ odigo odigo fuente y comprobar que es correcto desde el punto de vista l´exico, exico, sint´ actico actico 31
y sem´antico, antico, se debe llevar a cabo la traducci´on on del programa fuente al programa objeto. objeto. Este consiste, normalmente, en un programa equivalente escrito en un lenguaje m´aquina aquina o ensamblador. blador. Por equivalen equivalente te queremos decir que tiene el mismo significado, significado, es decir, que produce los mismos resultados que nuestro programa fuente original. El arbol a´rbol de derivaci´on on obtenido como resultado del an´ alisis alisis sint´ actico, junto con la informaci´ actico, on on contenida en la tabla de s´ımbolos, ımbolos, se usa para la construcci´ on del c´odigo odigo ob jeto. Existen varios m´ etodos etodos para conseguir conseguir esto. Uno de ellos, que es particularm particularmente ente efectivo efectivo y elegante, elegante, es el que se conoce como traducci´ on dirigida por la sintaxis. sintaxis. Esta consiste b´asicamente asicamente en asociar a cada nodo del ´arbol arbol de derivaci´ on on una cadena de c´ odigo odigo objeto. El c´ odigo odigo correspondien correspondiente te a un nodo se construye a partir del c´odigo odigo de sus descendientes y del c´odigo odigo que representa acciones propias propias de ese nodo. Por tanto, se puede puede decir que este m´etodo etodo es ascenden ascendente, te, pues parte de las hojas del ´arbol arbol de derivaci´on on y va generando c´odigo odigo hacia arriba, hasta que llegamos a la ra´ız ız del arbol. a´rbol. Esta representa el s´ımbolo inicial de la gram´ atica atica y su c´odigo odigo asociado ser´ a el programa programa objeto deseado. deseado. A veces, el proceso de generaci´on on de c´odigo odigo se puede dividir en las siguientes fases: Generaci´ on o n de c´ odigo odigo intermedio Algunos compiladores generan una representaci´on on intermedia i ntermedia expl´ expl´ıcita del programa p rograma fuente tras la etapa de an´alisis. alisis. Esta representaci´ on intermedia se puede considerar como un on programa para una m´ aquina abstracta, y debe cumplir dos propiedades: aquina
• Debe ser f´acil acil de producir. • Debe ser f´acil acil de traducir a c´odigo odigo objeto. En general, las representaciones intermedias deben hacer algo m´ as que calcular expresioas nes; tambi´en en deben manejar construcciones de flujo de control y llamadas a procedimientos. El c´ odigo generado a partir del intermedio suele ser, por lo general, menos eficiente odigo que el c´odigo odigo m´ aquina generado directamente, debido al nivel de traducci´ aquina on on adicional. adicional. Optimizaci´ on o n del c´ odigo odigo La fase de optimizaci´ on on de c´odigo odigo trata de mejorar el c´ odigo intermedio, de modo que fiodigo nalmente se obtenga un c´odigo odigo m´ aquina aquina m´ as eficiente en tiempo de ejecuci´on. as on. Hay mucha variaci´on on en la cantidad de optimizaci´ on on de c´odigo odigo que ejecutan los distintos compiladores. En los que realizan muchas muchas operaciones operaciones de optimizaci´ optimizaci´ on, on, denominados compiladores optimizadores, mizadores , una parte significativa del tiempo del compilador se ocupa en esta tarea. Sin embargo, hay optimizaciones sencillas que mejoran sensiblemente el tiempo de ejecuci´on on del programa objeto, sin necesidad de retardar demasiado la compilaci´ on. on. A veces, a causa del tiempo requerido en esta fase, hay compiladores que no la llevan a cabo y pasan directamente a la generaci´ on on de c´odigo odigo objeto. De hecho, en muchos casos, tambi´ en en se suele suprimir la fase de generaci´ on o n de c´odigo odigo intermedio, aunque ´esta esta tiene otras utilidades. Suele ser usual que el compilador ofrezca al usuario la posibilidad de desactivar la opci´on on de optimizaci´ on on del generador de c´odigo odigo durante la fase de desarrollo o depuraci´on on de programas. La generaci´ on o n de c´odigo odigo optimo o´ptimo es un problema NP-completo, y, por tanto, incluso los compiladores optimizadores no tienen por qu´e producir c´ odigo odigo optimo. o´ptimo. Es decir, no debemos malinterpre ma linterpretar tar el e l t´ermino ermino optimizaci´ optimi zaci´ on, pues al tratarse de un problema NP-completo, on, s´ olo supone, en general, la obtenci´ olo on on de c´odigo odigo mejorado, pero esto no significa que sea el mejor c´odigo odigo posible p osible.. Generaci´ on o n de c´ odigo odigo objeto 32
La fase final del compilador es la generaci´ on on de c´odigo odigo objeto, que, por lo general, consiste en c´odigo odigo de m´ aquina aquina reubicable o c´odigo odigo ensamblador. Para cada una de las variables usadas usadas por el programa programa se seleccionan seleccionan posiciones de memoria. memoria. Despu´ Despu´es, es, cada una de las instrucciones intermedias se traduce a una secuencia de instrucciones m´aquina aquina que ejecutar´ an la misma tarea. Una aspecto muy importante a tener en cuenta es la asignaci´ an on on de variables a registros. Si durante el proceso de compilaci´on on se ha generado c´odigo odigo intermedio, y se ha pasado por la fase de optimizaci´on, on, s´ olo olo quedar´ıa ıa general el c´ odigo objeto correspondiente al c´odigo odigo odigo intermedio optimizado. En otro caso, podr´ıa ıa generarse directamente c´ odigo odi go ob o b jeto jet o despu´ de spu´es es del an´ alisis alisis sem´ antico. Incluso puede realizarse al mismo tiempo que el an´ antico. alisis alisis sint´ actico actico y sem´antico antico (compiladores (compiladores de una pasada ). ). En cualquier caso, existen varias posibilidades en cuanto al formato que puede tener el c´ odigo odigo objeto:
• Generar directamente c´odigo odigo m´ aquina, aquina, que estar´ estar´ıa, por tanto, listo para ejecutarse en la m´ aquina correspondiente. En este caso, debe resolverse, entre otras cuestiones, aquina la de reservar memoria para los identificadores que aparezcan en el programa. Esto hace necesario construir un mapa de direcciones que asocie a cada identificador su correspondiente direcci´on on en memoria. odigo en lenguaje ensamblador de la m´aquina aquina destino. destino. Posterior Posteriormen mente, te, • Generar c´odigo habr´ habr´ıa que traducirlo, mediante un ensamblador, a c´ odigo objeto reubicable. Este, odigo haciendo haciend o uso del cargador-linkador, cargado r-linkador, se s e transformar´ transf ormar´ıa ıa en c´odigo odigo ejecutable. Esta forma de generar c´odigo odigo es m´ as sencilla, y permite poder compilar por separado distintos as programas program as que qu e pueden pued en interactuar inte ractuar entre s´ı, ı, usando librer´ıas ıas de d e rutinas, ruti nas, etc. De hecho, esta est a t´ecnica ecni ca es e s muy com com´ u´n en compiladores que trabajan bajo entorno UNIX, aunque un en otros casos se evita, por hacer m´as as ineficiente el proceso de compilaci´ on. on. En cualquier caso, la generaci´ on on de c´odigo odigo es una tarea complicada, que requiere profundos conocimientos del hardware de la m´ aquina destino, con objeto de aprovechar al m´aximo aquina aximo los recursos de la misma para que el programa ejecutable resulte lo m´ as as eficiente posible.
4.5.5.
Un ejemplo sencillo
En la figura 1.4 se esquematiza un ejemplo de traducci´on on de la proposici´ on: on: posic posicio ion n := inic inicial ial + velo velocid cidad ad * 60
siguiendo cada una de las fases del proceso de compilaci´on, on, desde el an´ alisis alisis l´exico exico hasta la generaci´ on o n de c´odigo odigo en lenguaje ensamblador. Se supone que las constantes no se almacenan en la tabla de s´ımbolos. ımbolos. Por otro lado, se realiza realiza una conversi´ conversi´ on de tipos (la constante entera 60 se convierte a real), dentro del an´alisis alisis sem´ antico. antico. Asimismo, Asimismo, se genera genera c´ odigo odigo intermedio de tres direcciones, que es optimizado antes de generar el c´odigo odigo en lenguaje ensamblador.
33
posicion := inicial + velocidad * 60 analizador de lexico id1 := Id2 + id3 * 60
analizador sintactico := id1
+ id2
* i d3
60
analizador semantico :=
Tabla de Simbolos posicion
. .
inicial
. .
velocidad
. .
id1
+ id2
* i d3
inttoreal 60
generador codigo intermedio temp1 := inttoreal(60) temp2 := id3 * temp1 temp3 := id2 + temp2 id1 := temp3
optimizador de codigo temp1 := id3 * 60.0 id1 := id2 + temp1
generador de codigo MOVF MULF MOVF ADDF MOVF
id3, R2 #60,0, R2 id2, R1 R2, R1 R1 R1 id1
Figura 1.4: Traducci´ on on de una sentencia
EJERCICIOS RESUELTOS 1.
Sea L = {λ, a}. Obtener Ln para n = 0, 1, 2, 3. ¿Cuantos elementos tiene Ln, en general? Describir por comprensi´on on L+ . L0 = {λ} L2 = L · L 1 = {λ, a} · {λ, a} = {λ,a,aa} 34
L1 = L · L 0 = {λ, a} · {λ} = {λ, a} L3 = L · L 2 = {λ, a} · {λ,a,aa} = {λ,a,aa,aaa}
Para todo n ≥ 0 se tiene que |Ln | = n + 1. Podemos definir la clausura positiva de L como: ∞
+
L =
Ln = {am | m ≥ 0}
n=1
2. Sean Sean los leng lenguaje uajess A = {a} y B = {b}. Describir (AB (AB))∗ y (AB) AB )+ . (AB) AB )∗ = {(ab) ab)n | n ≥ 0} = {λ,ab,abab,ababab,...} (AB) AB )+ = {(ab) ab)n | n > 0} = {ab,abab,ababab,...} 3. Demostrar Demostrar que la concatenaci concatenaci´ o´n de lenguajes no es distributiva respecto de la intersecci´on. on on. No se cumple que para tres lenguajes cualesquiera A · (B ∩ C ) = (A · B ) ∩ (A · C ). ). Lo vamos a demostrar con un contraejemplo. Sean los lenguajes A = {a, λ}, B = {λ}, C = {a}. Tenemos que: A · (B ∩ C ) = {a, λ} · ({λ} ∩ {a}) = ∅ (A · B ) ∩ (A · C ) = {a, λ} ∩ {aa,a} = {a} Como vemos, se obtienen resultados diferentes. Luego la concatenaci´ on on no es distributiva respecto de la intersecci´on. on. 4. Dada Dadass dos dos cade cadena nass x e y sobre V , V , demostrar que |xy | = |x| + |y | (*). Primero definimos por inducci´ on la longitud de una cadena, de forma que: on 1) |λ| = 0, |a| = 1, ∀ a ∈ V 2) |wa| = |w| + 1 Ahora demostramos (*) por inducci´ on. on. Para el caso base cuando y tienen longitud cero o uno, se cumple (*) por la definici´on on inductiva. Por hip´ otesis otesis de inducci´ on on suponemos que (*) se cumple para toda palabra x de cualquier longitud y para toda palabra y de longitud 0 ≤ |y| ≤ n. Ahora consideramos una palabra cualquiera y de longitud n + 1. Entonces y tendr´ a al menos un s´ımbolo, ımbolo , de forma que y = wa y por la definici´on on inductiva tenemos que |y| = |w| + 1. Tambi´ Tambi´en en por definici´ definicion o´n se tiene que |xy| = |xwa| = |xw| + 1. Pero |xw| = |x| + |w| puesto que se cumple la hip´otesis otesis de inducci´on on para w por tener longitud n. En definitiva tenemos que:
|xy | = |xwa| = |xw| + 1 = |x| + |w| + 1 = |x| + |y|, c.q.d.
5. Sea Sea el alfabe alfabeto to V = {0, 1} y los lenguajes: L1 = {w ∈ { 0, 1}∗ | ceros( ceros(w) es par} ∗ L2 = {w ∈ { 0, 1} | w = 01 0 1n , n ≥ 0} Demostrar que la concatenaci´ on on L1 L2 es el lenguaje: L = {w ∈ { 0, 1}∗ | ceros( ceros(w) es impar} Tenemos que demostrar que L1 · L2 ⊆ L y que L ⊆ L1 · L2 L1 · L2 ⊆ L Se cumple ya que la concatenaci´on on de una palabra de L1 con otra de L2 nos da una palabra con un n´umero umero impar de 0’s. En efecto, una palabra de L1 tiene un n´umero umero par de ceros y una palabra de L2 s´olo olo tiene un cero al principio y va seguida de 35