You are on page 1of 29

TEMA 1 LENGUAJES DE PROGRAMACIÓN

Lenguaje Un lenguaje es un instrumento de comunicación. Para que exista una comunicación debe existir comprensión mutua Lenguaje de programación Un lenguaje de programación tiene como fin la comunicación entre el programador y la máquina, comunicación, que resulta difícil por ser elementos de diferente naturaleza. Para superar ésta dificultad se crearon los procesadores de lenguajes, que deben unir el salto semántico entre los distintos lenguajes, el lenguaje del programador y el de la máquina Definición de un lenguaje de programación (desde el punto de vista del usuario) Un lenguaje de programación es una notación que sirve para escribir algoritmos que puedan ser ejecutados en una máquina; una notación precisa, rigurosa y con la pretensión de ausencia de ambigüedades. La anterior definición aporta poca información para su análisis. Ejemplo: Program saludo ; begin writeln (“Bienvenidos a la asignatura de TLP”) end. Definición de un lenguaje de programación (desde el punto de vista del análisis) Un lenguaje de programación es aquél que tiene: un léxico, una sintaxis y una semántica. La anterior definición aporta cierta información para conocer su análisis, que veremos seguidamente. Program ejemplo; var a: integer; x: real; begin read ( a); x:= a*2 ; write (x) end . Un lenguaje tiene un conjunto de componentes elementales e indivisibles: variables, literales, palabras reservadas, símbolos separadores, símbolos aritméticos,..etc que pueden formar parte de un programa fuente escrito en ese lenguaje. Al conjunto de componentes básicos e indivisibles que se pueden usar en el lenguaje, se le llama léxico de ese lenguaje,{ Program, id, ´;´,…}. Los componentes léxicos que forman el léxico de un lenguaje, se pueden asociar para formar estructuras: una asignación, una expresión,…etc. estructuras que pueden formar parte de un programa fuente escrito en ese lenguaje. Ejemplo correcto de una estructura en Pascal: Program ejemplo; var a: integer; x: real; begin read ( a); x:= a*2 ; write (x) end . Al conjunto de estructuras que permite el lenguaje, se denomina sintaxis del lenguaje .Para definir la sintaxis de un lenguaje se utilizan las gramáticas. Una gramáticas es un conjunto finito de reglas a través de las cuales se pueden generar el conjunto(por lo general infinito) de estructuras que forman la sintaxis de un lenguaje. El conjunto de estructuras que se pueden utilizar en un lenguaje deben de cumplir una serie de restricciones y condiciones entre los elementos del lenguaje que la componen: la compatibilidad de tipos en la estructuras de asignación, expresiones,…. El conjunto de condiciones o restricciones que deben cumplir las estructuras se llama semántica estática Program ejemplo; var a: integer; x: real; begin read ( a); x:= a*2 ; write (x) end . En Pascal- una variable debe estar definida antes de usarse, debe existir una compatibilidad de tipos entre los objetos que intervienen en una estructura ( es un lenguaje fuertemente tipado),…. El conjunto de estructuras que se pueden utilizar en un lenguaje, determinan una serie de acciones a realizar, en una asignación: evaluar el valor la parte derecha del operador de la igualdad y asignárselo a la memoria definida por la variable de la parte izquierda, etc…. Las acciones que debe realizar la máquina para acometer el significado de las distintas estructuras se llama semántica dinámica.

1

- Ejemplo anterior: obtener un valor entero de la entrada y ponerlo en la variable a, - El valor que tiene la variable a multiplicado por la constante 2, y el resultado se deja en la variable x - Escribir el contenido de la variable x Cuanto mayor sea la potencia (significación) de las estructuras del lenguaje, mayor será la diferencia de la semántica del lenguaje de programación y el lenguaje de la máquina donde se quiere ejecutar. La forma de representar una sentencia switch del lenguaje C++, es bastante diferente y más simple que la representación en lenguaje máquina. Nivel de un lenguaje El nivel (semántico) de los lenguajes es una medida indicativa de la complejidad del significado de los programas que pueden escribirse con ellos: se refiere al nivel de complejidad de las estructuras (construcciones) del lenguaje; suelen considerarse dos categorías más o menos genéricas: - lenguajes de alto nivel: C++, Java, Ada, Pascal - lenguajes de bajo nivel: lenguajes ensambladores y máquinas de diferentes máquinas Lenguaje máquina – conjunto de instrucciones de una máquina particular que son interpretadas por el hardware o microprogramas de la propia máquina. El conjunto de instrucciones están escritos en notación binaria. Los lenguajes máquina, son los lenguajes de menor nivel semántico. Lenguaje ensamblador- es una versión simbólica del lenguaje máquina. En donde las operaciones, direcciones de memorias, registros.. se dan de forma simbólicas, con ciertas ayudas a la depuración. Lenguajes de alto nivel – Lenguajes que están por cima de máquina y en principio son independientes de la máquina sobre la que se van a ejecutar los programas escritos en la misma. La separación semántica Separación semántica es la diferencia de nivel semántico que se da entre un algoritmo escrito en un lenguaje de programación (de un cierto nivel) y las instrucciones máquina mediante las que ese algoritmo se ejecuta en una máquina (el nivel semántico mínimo para esa máquina). Para que un algoritmo escrito en un lenguaje (de determinado nivel) sea ejecutable en una máquina hay que resolver la separación semántica relativa a dicho lenguaje. Un ejemplo puede ilustrar fácilmente la diferencia: la semántica (el significado) de la sentencia cíclica for de Java es mucho más compleja (de significado más complicado, de mayor semántica, más costosa de ejecutar, más difícil de explicar) que la instrucción máquina que permite almacenar un valor constante en un registro de uso general de la unidad central de proceso. También puede hablarse de lenguajes de nivel intermedio. Hay lenguajes que tienen, a la vez, unas características que pueden considerarse de alto nivel y otras de nivel bajo o intermedio. lenguaje fuente (de cierto nivel) ▫ sentencias del lenguaje ▫ separación semántica algoritmo [ significado común ] nivel de la máquina (física) ▫ instrucciones ejecutables en la máquina ▫ Procesador de lenguajes Se puede definir un procesador de un lenguaje de programación (ya comentado anteriormente) como un sistema que resuelve la separación semántica de los programas escritos en ese lenguaje; un procesador está formado por uno o más programas interrelacionados que hacen posible que un algoritmo (programa) codificado (escrito) en el lenguaje pueda llegar a ejecutarse en una máquina (física). Tipos de procesadores de lenguajes Traductores, Intérpretes. □

2

para la máquina M P [ L ] programa (fuente) escrito en L P [ O ] programa (código) objeto resultante de la traducción (compilación) 3 .Traductor Un traductor entre dos lenguajes de programación. La entrada al traductor se denomina programa fuente y la salida programa destino (o también código generado por el traductor). -.. El proceso de traducción no altera el significado del programa traducido..Traductor entre los lenguajes L y L’ P/L M P programa escrito en L (lenguaje fuente) P' programa escrito en L’ (lenguaje destino) E errores (si existen y son detectados) M máquina donde se ejecuta el traductor Li lenguaje de implementación de T [ P y P' representan idéntico algoritmo ] Lo más frecuente y razonable es que un proceso de traducción disminuya el nivel semántico: el nivel de lenguaje destino es menor que el nivel del lenguaje fuente. el traductor avisa de los errores detectados. La ejecución del programa compilado puede considerarse como un proceso de interpretación del procesador. teniendo un conjunto de datos de entrada y produciendo unos resultados como salida El siguiente esquema ilustra el proceso de ejecución de un programa compilado.) para obtener el código ejecutable. cargador. Compilador Un compilador.compilador del lenguaje T [Li] E P’/L’ C M P[L] P[O] M' P[O] D R C compilador del lenguaje L. el traductor acepta un texto escrito en el lenguaje fuente (representativo de un determinado algoritmo/programa) y emite como salida una representación de ese mismo algoritmo/programa codificada en el lenguaje destino. en caso contrario. no suele darse con frecuencia debido a que tras de una compilación suelen aparecer acciones (enlazador. lenguaje que puede ser máquina o de bajo nivel El resultado de la compilación es un programa ejecutable en una determinada máquina Puede afirmarse que la compilación directa a código máquina directamente ejecutable. conversores. El traductor analiza el programa de entrada verificando que está correctamente codificado según la definición del lenguaje fuente. o también llamado host. La ejecución. -. es un proceso posterior en el que se ejecuta el programa objeto. traduce un programa escrito en un lenguaje fuente de alto nivel a otro semánticamente equivalente escrito en un lenguaje objeto.. es un programa que realiza una transformación (una traducción) entre ellos: el lenguaje de entrada al traductor (lenguaje fuente) y el de salida del traductor (lenguaje destino).. si el programa analizado no tiene errores se puede traducir. ensambladores. con sus dos partes bien diferenciadas: la compilación del programa fuente (ejecución del compilador) y la ejecución del programa resultado de la compilación. Tipos de traductores Compiladores. El traductor está escrito en un lenguaje de implementación Li .

a su vez. En cualquiera de la fases de análisis pueden encontrarse errores: lexicográficos. . generan y optimizan el código. Fases de un compilador. Para separar claramente estas dos fases conviene desde un punto de vista conceptual considerar que. dependiendo ahora de la máquina en la que se ejecutará En una segunda aproximación. como resultado de la fase de análisis se obtiene una representación intermedia del programa analizado que refleja las operaciones que el programa ha de realizar y el orden en que deben de llevarse a cabo. puesto que un compilador puede generar código objeto directamente (compilador puro). en el momento en que se encuentra un error se decide que ya no es necesaria la generación de código: el programa analizado es incorrecto. la naturaleza de esta representación intermedia depende del método empleado para la implementación del compilador Fase de análisis Representación intermedia P[I] Fase de Síntesis P[F] P[O] P[ F ] programa P escrito en el lenguaje fuente P[ O ] programa P escrito en el lenguaje destino P[ I ] representación intermedia del programa P La representación de lenguaje intermedio es el lenguaje de una máquina abstracta ( comentada mas adelante )usado como interfaz entre el análisis y la generación de código.el análisis sintáctico dedicado a verificar la estructura sintáctica de la secuencia de componentes léxicos que les pasa el análisis anterior. Un compilador es un programa que traduce un único lenguaje fuente. . En una primera aproximación se diferencian dos fases: análisis y síntesis. la fase de análisis se considera. produciendo código para una única máquina destino.D datos para una ejecución del programa P R resultados de una ejecución del programa P Máquina anfitriona . Análisis: la fase de análisis debería ser independiente de la máquina. y que constituyen el programa. descompuesta en tres fases cada una de ellas encargada de examinar las diferentes características del programa analizado: . semánticos. 4 . Se considera una descomposición funcional del compilador en diferentes fases. La representación intermedia no es obligatoria en las fases de un compilador.el análisis lexicográfico encargado de comprobar las características lexicográficas (la forma en que están codificados los componentes elementales del texto). La tarea realizada por un compilador es muy compleja y por ello conviene considerarla descompuesta en diferentes partes. sintácticos. El tiempo que tarda en ejecutarse el texto de un lenguaje se llama tiempo de ejecución. Síntesis: A partir del código intermedio generado en la fase de análisis.máquina donde se ejecuta el compilador ( M ) Máquina destino. Representaciones intermedias. en la fase de análisis se comprueba que el programa está bien codificado de acuerdo con la definición del lenguaje fuente y se extrae el significado del texto analizado. generando el código máquina que representa el mismo algoritmo que el programa fuente. mientras que la de síntesis depende de la máquina en la que se ejecutará. Un enfoque tradicional (y bastante provechoso) en el análisis del problema de compilar un programa escrito en un lenguaje de alto nivel es el denominado modelo analítico-sintético. en la fase de síntesis se transcribe ese significado empleando la notación del lenguaje destino.máquina para la que genera código el compilador ( M' ) El tiempo que se tarda en traducir un texto de un lenguaje se llama tiempo de compilación.el análisis semántico que realiza las comprobaciones de las restricciones de semántica estática que han de cumplirse para que el programa analizado tenga un significado correcto.

esta tarea puede hacerse directamente en un único paso o bien considerar que primero se obtiene el programa escrito en un lenguaje intermedio y después se transforma el lenguaje intermedio al código máquina. Para generar código se tiene en cuenta la semántica dinámica del lenguaje que es la que establece lo que la máquina ha de realizar para ejecutar lo indicado por el programa fuente. de manera que pueda ser compilado por todas esas máquinas diferentes. Traduce un programa fuente en un lenguaje de bajo nivel a otro objeto de nivel superior. y dé como resultado un compilador más potente de ese mismo lenguaje. estas optimizaciones pueden hacerse en diferentes momentos: sobre la representación intermedia. Metacompilador Es sinónimo de compilador de compiladores. Cuando se extiende entre muchas máquinas diferentes el uso de un compilador. Autocompilador Es un compilador escrito en el mismo lenguaje que compila. para después trasladarla a otra. En la fase de síntesis se realiza la tarea de generar el código destino. Tipos de compiladores Compilador cruzado Se genera código en lenguaje objeto para una máquina diferente a la que se está utilizando para compilar. sobre el código destino o sobre el lenguaje intermedio (si se ha producido la generación en dos etapas). y éste se desea mejorar. precisamente uno de los motivos que justifica la generación del código en dos o más etapas es la posibilidad de hacer diferentes optimizaciones.Durante el análisis de un programa. el compilador recopila una gran cantidad de información que es necesario tener organizada y fácilmente accesible (para hacer las comprobaciones semánticas y para generar el código). Fase de Análisis Código fuente Análisis léxico Componentes léxicos Análisis sintáctico árbol sintáctico Análisis semántico Árbol anotado Fase de Síntesis Generación de cód. En la mayoría de los casos traducen un lenguaje máquina a un lenguaje ensamblador. la principal estructura de datos donde el compilador almacena la información que obtiene del programa analizado se denomina tabla de símbolos. el nuevo compilador se escribe con el antiguo. intermedio Código intermedio Optimización de cód. intermedio Código intermedio Generación de código Código objeto Optimización de código Código objeto A veces también se considera como una fase dentro de la síntesis la tarea de optimización. Se refiere a un programa que recibe como entrada las especificaciones del lenguaje para el que se desea obtener un compilador y genera como salida el compilador para ese lenguaje Decompiladores Realizan la tarea inversa a la de los compiladores. Uno de los problemas que se encuentra en un nueva máquina es que alguien tiene que escribir el primer compilador. también llamados desensambladores 5 . un compilador puede efectuar intentos de mejora (optimización) en el código generado para que ocupe menos espacio o para que se ejecute con mayor rapidez. La tarea será más cómoda de hacer en la máquina que se dispongan herramientas software.

Sin embargo esto es muy difícil. Sobre los trozos de programa resultantes de las compilaciones hay dos tareas pendientes de realizar: . en este caso el montador puede incorporar el código de esas librerías para formar un todo con el programa previamente compilado en el que se ha hecho uso de ellas. de esta forma se han obtenido n trozos de programa traducido que no son todavía programas ejecutables. hay que diseñar una manera de hacer la implementación. En el siguiente esquema se muestra un programa completo que está dividido en n partes y cada una de ellas ha sido compilada en un proceso separado de compilación. 6 . Una de las características que diferencian a unos compiladores de otros es si tienen o no la posibilidad de traducir una parte de un programa de manera independiente y separada de la traducción de las otras partes que conforman el programa completo. C P O [1] Montador (Cargador) P F [1] P O[reu] Prog ecutable en memoria P O[eje] C P F [2] ···· P F [n] C compilador ···· P O [2] P O [n] montaje ejecución Estas tareas las resuelve un programa auxiliar que se denomina montador o montador-cargador tal y como se ilustra en el anterior esquema. esto es. una vez que se hayan juntado las distintas partes traducidas por separado. procesamiento y almacenamiento de la información obtenida. Pasadas de un compilador La descomposición en fases de un compilador se refiere al análisis del problema que se plantea al desarrollar un compilador para un lenguaje.Compilador incremental Es aquel que compila un programa en el que si después se descubren errores. Pasadas – son el número de veces que se procesa una representación del programa fuente. Compilador con montador y cargador Compilador de distintos módulos de forma independiente y después los enlaza. para formar un único programa ejecutable hay que unir las n partes obtenidas en los procesos de compilación. en vez de corregir el programa fuente y compilarlo por completo. el resultado de cada pasada es el punto de partida para la pasada siguiente.la resolución de las referencias: es posible que en alguna de las partes separadas del programa se haga referencia (se use) una entidad que ha sido definida (declarada) en otra parte distinta. se compilan solo las modificaciones. . A la salida del montador se obtiene un programa completo que ya está preparado para su ejecución. Una vez analizado el problema y descompuesto en tareas más sencillas. Hay lenguajes para los que se dispone de una serie de librerías (trozos de programa) que realizan determinadas tareas (más o menos especializadas).la obtención de las direcciones definitivas para los componentes del programa considerado como un todo. cada pasada se acerca más al resultado pretendido por el compilador. Desde el punto de vista de la implementación se fija la cantidad de pasadas que el compilador hace sobre el programa analizado. Lo ideal es que solo se recompilen aquellas partes que contenían los errores. Cada pasada requiere: lectura del código fuente. y que el código generado se reinserte con cuidado en el lenguaje objeto generado cuando se encontraron los errores. en cada pasada se hace un tratamiento del programa completo y se realiza sobre él alguna parte del trabajo de la compilación.

para conseguir mayor portabilidad. El método empleado para implementar el compilador también influye en el número de pasadas requeridas. traducen de código máquina a ensamblador. el intérprete controlará su realización.Intérprete del lenguaje D (datos) P/L M E I R (resultados) 7 .Si todas las fases de la compilación se realizan examinando una única vez el texto de entrada. A sintáctico. entonces se trata de un compilador de una única pasada. s -. Es un caso más fácil puesto que hay una correspondencia directa entre las instrucciones ensamblador y el código máquina. Las pasadas suelen agruparse: 1ª pasada – A léxico. pero aumenta el tiempo de ejecución al realizar más operaciones de entrada salida. en particular. Un conversor C –> PASCAL nos solucionaría el problema Intérprete Un intérprete es un programa que analiza y ejecuta simultáneamente un programa escrito en un lenguaje fuente. semántico y generación de código intermedio 2ª “ – Generación y optimización de código Un compilador con un número grande de pasadas hace que se necesite menos memoria para la ejecución. si en el programa se indican operaciones de entrada/salida. Desensambladores Caso inverso a los ensambladores. Típicamente una pasada para realizar el análisis léxico y sintáctico. Por ejemplo en un ordenador sólo hay un compilador de PASCAL. Si el lenguaje tiene una semántica compleja puede requerir que cualquier implementación de un compilador requiera más de una pasada. para cada una de ellas. A. subprograma. y queremos ejecutar un programa escrito en C. El intérprete va considerando una tras otra las instrucciones del programa interpretado y. Por ejemplo. antes de pasar a la siguiente instrucción. los lenguajes que permiten que el uso de una entidad (variable. método…) pueda preceder a su declaración (como ocurre en Java) requieren compiladores diseñados con más de una pasada. Existen ensambladores con macroinstrucciones: Macroensambladores. se facilita la detección de errores Compilador de una o varias pasadas Número de veces que hay que analizar el código fuente. Conversores Traducen un lenguaje de alto nivel a otro lenguaje de alto nivel. otra pasada para el análisis semántico y optimización dependiendo del lenguaje fuente y una tercera pasada para la generación de código y optimización dependiente de la máquina C y Pascal son lenguajes de una pasada mientras que el lenguaje modula realiza 2 pasadas Ensambladores Ensamblador Un traductor cuyo lenguaje fuente es un ensamblador y el lenguaje objeto es el lenguaje máquina. Un intérprete hace una simulación de la ejecución del programa de entrada en la máquina donde se está ejecutando el intérprete. analiza su significado y procede de inmediato a realizar las tareas correspondientes.

La interpretación pura en los lenguajes de alto nivel no suelen contruirse puesto que el proceso es bastante ineficaz. pueden considerarse intérpretes puros los intérpretes de comandos de la mayoría de los sistemas operativos. es más fácil de depurar. puede emplearse una descomposición del problema apoyada en la utilización de un lenguaje intermedio.P D R E M programa escrito en L datos para una ejecución de P resultados de una ejecución de P errores (si existen y son detectados) máquina donde se ejecuta el intérprete Tipos de interpretes: (según la estructura interna del intérprete) Intérpretes puros Los lenguajes no necesitan de pseudocompilación. la dificultad y coste de programación son menores( no necesitan fase de generación de código. Un intérprete puede relacionarse a nivel de software o hardware Lenguajes intermedios Para acercar la separación semántica de un programa escrito en un lenguaje de alto nivel a lenguaje máquina. programas que trabajan en modo producción y la velocidad es importante e instrucciones son ejecutadas con frecuencia. potencian el uso de los sistemas interactivos. de modalidades de separación semántica) : la primera agiliza la fase de producción debido al desarrollo de técnicas y herramientas de construcción de compiladores. En la actualidad suelen mezclarse ambas técnicas (apdo. entre las más significativas están: • una traducción siempre produce como salida una representación del programa analizado (el código destino). dicha ejecución es controlada por el intérprete. en una interpretación no se produce código destino En relación a un intérprete no existe el lenguaje destino (no se genera código). mientras que la segunda facilita la ejecución y depuración Se puede decir que un ordenador es un intérprete de su propio lenguaje máquina. Un intérprete necesita menos memoria. montaje y reubicación). sin embargo los conceptos de traducción y de interpretación son esencialmente distintos. Intérpretes avanzados (o normales) Incorporan un paso previo de análisis de todo programa fuente a pseudocompilación generando posteriormente un lenguaje intermedio que es ejecutado por el mismo. es decir siempre se produce un proceso de interpretación. también puede decirse que el lenguaje para el que se construye el intérprete es su “lenguaje fuente”. Pueden enunciarse abundantes diferencias entre los procesos de traducción y de interpretación. tiene una mayor flexibilidad a la hora de modificar las características del lenguaje fuente. tienen una mayor portabilidad. prolog. No son útiles con estructuras complejas. optimización. su ejecución habría de realizarse en otro momento (distinto del de la propia traducción) • una interpretación simula la ejecución de un programa. smaltalk) Comparación entre un traductor y un intérprete Aunque a simple vista pudiera apreciarse que las funciones de un traductor y de un intérprete son similares (ambos aceptan como entrada un programa escrito en un determinado lenguaje de programación y con ambos se pretende conseguir la ejecución de ese programa). si ese código fuera ejecutable en alguna máquina. aunque el concepto de lenguaje fuente es más propio de los traductores. existen objetos que no son conocidos en tiempo de compilación ( Lisp. analizan y ejecutan sentencia a sentencia todo el programa fuente. 8 . Intérpretes incrementales Lenguajes que no se pueden compilar directamente.

por ejemplo el código P definido para favorecer la implementación del lenguaje Pascal. aunque el programa resultante de esa traducción todavía no es directamente ejecutable en una máquina. Son dependientes del lenguaje fuente e independiente de la arquitectura destino. se ha conseguido disminuir la separación semántica entre el lenguaje fuente y la máquina destino. de tres direcciones(tercetos). Las tareas de dicho lenguajes – comprobación de tipos. válidos para representar un conjunto extenso de arquitecturas hardware.Un lenguaje intermedio es una notación que permite representar algoritmos (secuencias de operaciones) y que recibe ese nombre por tener un nivel semántico medio situado entre el alto nivel del lenguaje fuente y el bajo nivel del lenguaje destino (máquina).lenguajes diseñados para actuar en las primeras fases de traducción (análisis) o incluso de procesado. de una misma arquitectura (dependientes de ésta). generación de código y optimización de código con independencia de la plataforma. de cuatro direcciones (cuartetos) y notación polaca inversa (recorrido post orden) . Las representaciones de lenguajes intermedios de alto nivel mas empleados son: árboles de sintaxis abstracta AST. se basan en lenguajes con registros simbólicos Influidos por la máquina destino. Representaciones mas empleadas: máquinas de pila (representación más empleada de código intermedio) . Facilitan la traducción del lenguaje fuente. Intermedio Separación semántica entre lenguaje intermedio y máquina Leng. Diseño de los lenguajes intermedios: .Lenguajes de medio nivel válidos para representar un conjunto amplio de lenguajes fuente ( no siendo dependientes de uno concreto). sus características están “próximas” al lenguaje fuente. máquina Los lenguajes intermedio no son lenguajes de programación de ninguna máquina real. Leng. Fuente Separación semántica entre lenguaje fuente e intermedio Leng. sino que corresponde a una máquina abstracta.leguajes intermedios de bajo nivel – permiten traducir a distintos micros. están “próximos” al lenguaje máquina. el primer paso en la resolución de la separación semántica consiste en la traducción del programa escrito en el lenguaje fuente (alto nivel) al lenguaje intermedio. grafos dirigidos aciclicos GADs y grafos de dependencia.Lenguajes intermedios de alto nivel . Puede decirse que un lenguaje intermedio es una representación más abstracta y uniforme que un lenguaje máquina concreto. Con el uso de un lenguaje intermedio. . Lenguaje1 Lenguaje2 Lenguajen n lenguajes Traducción directa n*m Plataforma1 Plataforma2 P Plataforma O [1] m m Plataformas Traducciones de n lenguajes a m plataformas m*n 9 .

un intérprete del lenguaje de la máquina virtual que se ejecute en la máquina física. El empleo de una misma maquina abstracta evita tener que traducirlos Inconvenientes Introduce en el compilador una nueva fase de traducción. Una máquina virtual es una máquina abstracta para la que existe un intérprete. 10 .(conjunto de instrucciones que pueden ejecutarse. Portabilidad Lenguaje1 C Compilación a máquina abstracta Lenguaje intermedio Traducción a máquina real n+m Lenguaje2 PASCAL Lenguajen JAVA n Lenguajes Plataforma1 Intel Plataforma2 Motorola Plataforman Dec-Alpha m Plataformas En la anterior representación puede verse.En la anterior representación puede verse que para n lenguajes sobre m plataformas se necesitan n*m traducciones Ventajas del lenguaje intermedio Portabilidad de las aplicaciones: El código intermedio. intermedio Intercomunicación de aplicaciones: La representación binaria de datos en distintas plataformas varía.…) . para ello ha de tenerse: . Máquina diseñada sin la intención de ser implementada a nivel de hardware Máquinas virtuales Una máquina abstracta puede definirse como un modelo teórico para ejecutar un conjunto de instrucciones en algún lenguaje formal (no requiere implementación hardware.una estructura de datos que soporte la arquitectura de la máquina virtual. en tal caso se estaría hablando de una máquina concreta). una máquina virtual es una implementación software de la especificación de una máquina abstracta El lenguaje de la máquina virtual suele tener la función de lenguaje intermedio. organización de memoria (pila. son traducidos a código intermedio Distribución de aplicaciones por internet: Los módulos de aplicaciones web se pueden distribuir a través de un servidor. registros. Cualquier módulo de Internet dispone de una máquina virtual para cod. que con un lenguaje intermedio las traducciones se reducen de m*n a n+m El código intermedio de un compilador suele ser código del lenguaje de una máquina abstracta. al ser independiente de la plataforma puede ser ejecutado en cualquiera que tenga disponible una maquina virtual Adecuación de paradigmas complejos: Determinados paradigmas de programación son complicados de traducir a código binario dado su bajo nivel de abstracción. Perdida de eficiencia no permite una compilación de una pasada Dificultad para definir un lenguaje intermedio adecuado en el compromiso entre lenguaje fuente y lenguaje máquina. Una máquina virtual se puede implementar sobre una máquina física. También puede decirse que.

las fases se agrupan en una etapa inicial (Front-End) y una etapa final (Back.….Hay una gran variedad de máquinas virtuales: unas basadas en pila. . se encuentran aspectos de la fase de optimización de código además de la generación de código. junto con el manejo de errores necesario y las operaciones con la tabla de símbolos. La etapa final incluye aquellas partes del compilador que dependen de la máquina objeto y. otras en registros o una combinación de ambas. Por ejemplo. sino sólo del lenguaje intermedio. diseñadas para facilitar la implementación de lenguajes y para favorecer su portabilidad a distintas máquinas físicas. La etapa inicial comprende aquellas fases.máquina P para Pascal. . El código bytecode se está convirtiendo en un código intermedio universal. . ya existen intérpretess de JVM (máquina virtual de java) para todos los sistemas operativos Lenguaje1 Compilación a máquina abstracta Lenguaje2 PLenguajen O [1] N lenguajes Lenguaje intermedio Traducción a máquina real N+m Intérprete LI para P1 Plataforma1 Intérprete LI para P2 Plataforma2 P Intérprete O [1] LI para P2 Plataforman Máquinas Virtuales M Plataformas En lugar de traducir el código intermedio a código objeto de la plataforma destino. por ejemplo: . Ahí normalmente se introducen los análisis léxicos y sintácticos.máquina virtual de java. 11 .máquina EM. Los lenguajes intermedios facilitan la portabilidad de diferentes lenguajes de programación de alto nivel a distintas máquinas (físicas). el lenguaje de la máquina virtual de Java (bytecode) facilita la implementación del lenguaje Java en diferentes máquinas físicas: se tiene un único traductor (compilador) de Java al lenguaje de bytecodes y una colección de intérpretes de bytecode (un intérprete por cada máquina física en la que se quieran ejecutar). . podemos utilizar una máquina virtual para cada plataforma El principal objetivo es reducir el numero de programas necesarios para construir un traductor portable que permita generar código sobre una gran variedad de plataformas Arquitectura front-end/back-end Con frecuencia. se puede desarrollar un único traductor del lenguaje fuente a un lenguaje intermedio y varios traductores (o intérpretes) del lenguaje intermedio a cada uno de los lenguajes máquina de las distintas máquinas (físicas). Si se quiere implementar un lenguaje de alto nivel en diferentes máquinas..máquina A para Ada. el análisis semántico y la generación de código intermedio. en general. La etapa inicial también puede hacer cierta optimización de código e incluye además.End). En la etapa final. la creación de la tabla de símbolos. esas partes no dependen del lenguaje fuente. el manejo de errores correspondiente a cada una de esas fases. o partes de fases que dependen principalmente del lenguaje fuente y que son en gran parte independientes de la máquina objeto.

end Código fuente Análisis léxico Comp. int Back-end Generación de código Optimización de código Código objeto Arquitectura Front. léxicos Análisis sintáctico Árbol sintáctico Análisis semántico Análisis sintáctico Árbol anotado Generación de cód. maq – Intel Tres compiladores ( pascal. maq – Motorola Cod. Front. maq – Intel Compilador C para tres máquinas diferentes.end Para el lenguaje C Lenguaje intermedio Back-end – Dec-Alpha Back-end – Motorola Back-end – Intel Cod. Código intermedio Optimización de cód.end / Back-end Se ha convertido en rutina el tomar la etapa inicial de un compilador y rehacer su etapa final asociada para producir un compilador para el mismo lenguaje fuente en una máquina distinta. java y C) para una misma máquina 12 . obteniéndose así varios compiladores para una máquina. Otro motivo que justifica la división de la generación de código en dos etapas (intermedio y objeto) es la portabilidad: se puede construir una única parte frontal que sirva para traducir el lenguaje fuente a un determinado lenguaje intermedio y varias partes terminales que generen código traduciendo ese lenguaje intermedio a los lenguajes máquinas de distintas máquinas. int.End Java Front -End Front C End Back End Cod.Front . Pascal Front . También resulta tentador compilar varios lenguajes distintos en el mismo lenguaje intermedio y usar una etapa final común para las distintas etapas iniciales. maq – Dec-Alpha Cod.

por sí mismo constituye un procesador de un lenguaje de alto nivel. en el proceso de compilación se obtiene el código directamente ejecutable en la máquina ( Pascal. n1 Intérprete n2 n1 n2 nivel de L (lenguaje de alto nivel) nivel de la máquina (física) n1 n2 n3 nivel de L (lenguaje de alto nivel) nivel del lenguaje intermedio nivel de la máquina (física) 13 . basta con desarrollar un traductor del lenguaje intermedio a esa máquina Modalidades de procesadores. Cada máquina física requiere de un código específico lenguaje objeto (x 86) Para resolver el problema de la separación semántica pueden desarrollarse distintas modalidades de procesadores de lenguajes. ADA). en este caso el propio intérprete constituiría un procesador para el lenguaje de alto nivel. C.Si se cambia el lenguaje fuente. puede considerarse un proceso de interpretación directa (pura) de un lenguaje de alto nivel. . dándose primero la traducción del fuente a una representación intermedia. a la cual se le aplica el proceso de interpretación.Si aparece una nueva arquitectura.La representación intermedia actúa como medio de comunicación entre el front-end y back-end. Todo lenguaje de programación necesita de uno o más procesadores de lenguajes. en la mayoría de los casos coexisten. n1 Traductor n2 Traductor n3 * Un intérprete Aunque no es habitual su utilización (por cuestiones de eficacia). * Un compilador Un copilador. . entonces se reescribe el back-end . Rara vez se realiza el proceso de traducción o interpretación (pura) para resolver el problema de separación semántica. se reescribe el front-end.Si se cambia la máquina objeto. n1 Compilador n2 n1 n2 nivel de L (lenguaje de alto nivel) nivel de la máquina (física) * Dos traductores Un traductor del lenguaje fuente a un lenguaje intermedio y otro traductor del lenguaje intermedio al lenguaje máquina.

Perl. perfiladores. El generador de nuestro estudio es JavaCC que genera código en java. Entorno de desarrollo integrado Conjunto de aplicaciones que permiten la escritura de los procesadores: editor. depurador. El generador es un autómata finito. 14 . Conversores de formato Utilizan las técnicas de los traductores para convertir una descripción de ficheros en otra. Generadores automáticos de código Trabajan con un conjunto de reglas que permiten la traducción del código escrito en lenguaje intermedio al lenguaje objeto. PHP). depuradores. verifican si es de un determinado tipo o no. Las reglas suelen remplazar instrucciones de código intermedio por patrones que contienen las instrucciones equivalentes de la máquina objeto. n1 Traductor n2 Intérprete n3 n1 n2 n3 nivel de L (lenguaje de alto nivel) nivel del lenguaje intermedio nivel de la máquina (física) Herramientas para la construcción de procesadores de lenguajes A parte de las herramientas de desarrollo de software convencionales como: editores. Actualmente es muy común editores con sintaxis resaltada con colores. para la construcción de procesadores de lenguajes. Asocian una o más traducciones a cada nodo sintáctico. generan automáticamente el código fuente para el análisis léxico a partir de una especificación de los tokens. Máquinas de traducción dirigida por sintaxis Producen un conjunto de rutinas que recorren el árbol sintáctico y generan código intermedio. El generador de nuestro estudio es JavaCC que genera código en java. compilador. enlazador… Herramientas relacionadas con los procesadores de lenguajes Las técnicas empleadas en la construcción de traductores. compiladores e intérpretes pueden aplicarse en la construcción de otras herramientas: Editores sensibles al contexto Avisan al programador de posibles errores sintácticos cuando está escribiendo un programa fuente. Analizadores de flujo Suministran la información necesaria para realizar las optimizaciones de código. Normalmente se utilizan para verificar las gramáticas LL(k) y LR(k).* Un traductor y un intérprete Un traductor del lenguaje fuente a un lenguaje intermedio y un intérprete del lenguaje intermedio (java. existen otras herramientas especializadas y cada vez más. entre los que podemos destacar los siguientes: Generadores de analizadores léxicos Generación basada en el uso de expresiones regulares. Analizadores de gramáticas Dada una gramática especificada formalmente.…. Generadores de analizadores sintácticos Construyen el código fuente del analizador sintáctico a partir de la especificación de la gramática del lenguaje fuente. que ayudan a la construcción de procesadores.

Reconocimiento del habla Se realiza un análisis de los sonidos para construir palabras (redes neuronales) Tipos de lenguajes de programación Los lenguajes de programación se pueden clasificar desde diferentes puntos de vista: Según el grado de independencia de la máquina(nivel): Lenguaje máquina Representa la forma más baja de un lenguaje de programación. Intérpretes para consultar base de datos: reciben las consultas. utilización de bloques. música. permitiendo el análisis comprensión y traducción (inteligencia artificial). Compiladores de silicio Utilizan las mismas técnicas de construcción de compiladores e intérpretes pero implantadas en hardware.. las analizan y las ejecutan (EJ. Lenguaje ensamblador Representa una versión simbólica de un lenguaje máquina.. que pueden ser tratadas como un lenguaje de aplicación. Un caso particular son los generadores de pantallas. escrita en la notación que entiende directamente un ordenador binario o hexadecimal. Formateadores de texto Reciben como entrada un texto con indicaciones de cómo se desea la salida y generan dicho texto formateado en un fichero.Asignaciones de memoria se dan con nombre simbólicos Lenguaje de nivel intermedio (caso del lenguaje C) Al ser un nivel intermedio dispone de características de los de bajo y alto nivel Características de los lenguajes máquina: Acceso directo a posiciones memoria. MUL. estructuras de pueden ser datos complejas. Almacenan variables en registros del procesador. SPSS) 15 .. Ada. C++. XBASE. procedimientos o subrutinas.. Pueden estar especializados para fórmulas matemáticas.COM de MSDOS). (smalltalk.: SQL). turbo Pascal…) Lenguajes orientados a problemas concretos Resolución de problemas en un campo específico (SQL. Cada código de operación se indica por un código simbólico: ADD. etc. Construcción de entornos operativos Caso particular del anterior en el cual las órdenes suelen recibirse de forma gráfica ( Ej. PostScript. o para una determinada impresora. Formateadores de código fuente Toman como entrada un código fuente y obtienen a la salida el mismo mostrado de manera que se pueda seguir la estructura del programa.: COMMAND. Generadores de código Permiten desarrollar aplicaciones a partir de unas especificaciones muy compactas. Manejo de datos Lenguaje de alto nivel Características superiores a los lenguajes ensambladores No tienen acceso directo al sistema. Verificación estática de programas Leen el código fuente y lo analizan para descubrir errores potenciales sin ejecutar dicho programa. químicas. Java. Intérpretes de comandos de un sistema operativo Reciben órdenes del sistema operativo. Características de lenguajes de alto nivel: Manejo de estructuras de control.Preprocesadores Toman como entrada un conjunto de instrucciones y generan código en un lenguaje de alto o medio nivel. WINDOWS). Procesamiento de lenguajes naturales Aplican las técnicas de construcción de traductores a los lenguajes naturales. las analizan y las ejecutan ( Ej. Se basa en la arquitectura de la máquina de Von Neumann.

VRML) Otros lenguajes En informática también se utilizan otros lenguajes que no son de programación y que tienen otras aplicaciones. Programación estructurada ( Pascal. No manejan recursividad ni estructuras dinámicas de datos en los años 60. DBT. Pueden ser una característica propia del lenguaje o el resultado de ampliar las instrucciones de un lenguaje no concurrente: Ada. PASCAL. XMN. HTML. 16 . Lenguajes concurrentes: Dos o más tareas simultaneas o paralelas. Delphi) Generación Internet: Necesidad de manejar aplicaciones en diferentes plataformas dentro de internet (Java. Según la generación: Primera generación: Lenguajes máquina y ensamblador en los años 50 Segunda generación: Lenguajes con asignación estática de memoria ( en tiempo de compilación)..Lógicos: instrucciones se forman siguiendo un tipo de lógica. variables locales.. maneja relaciones (predicados) entre objetos (datos). De formatos de ayuda: HLP de Windows.. gráficos..Funcionales: sus construcciones son llamadas a funciones. Tercera generación: Programación estructurada en los años 70.. Lenguajes orientados a objetos: Basados en la teoría de los objetos que permitiendo: la encapsulación.. Concurrent C. surgen primero las reglas gramaticales y se ajustan con todo rigor a ellas. COBOL.. True Page.... BMP. De formatos gráficos vectoriales: DXF. recursividad y estructuras dinámicas.. No hay instrucciones.. etc. herramientas CASE Quinta generación: Inteligencia artificial (LISP PROLOG) Generación orientada a objetos: Con la proliferación de las interfaces gráficas de usuarios en los años 90 Generación visual: Exigencia de los usuarios de interfaces amigables en los años 90 (Visual Basic. concurrent Pascal. C++. Gracias a ello se pueden construir procesadores ( término genérico que hace referencia al proceso de transformación) Tipos de lenguajes que no son de programación: De descripción de páginas: Postcript. hacen uso masivo de variables. MIDI... Están Influidos por la máquina de Von Neumann. MP3. de sonido.. MOV. La ejecución consiste en demostraciones de hechos sobre las relaciones mediante preguntas (PROLOG).. Base de datos. De formatos de archivos de vídeo: AVI.. (FORTRAN. De gestión electrónica de documentos e hipertexto: pdf de Acrobat.. JPEG.. Lenguajes declarativos: lógicos y funcionales Lenguajes de muy alto nivel con notación muy próxima al problema real del algoritmo que resuelven. HLP de Turbo Visión. .. PCX. todos los lenguajes no naturales son formales.. GIF.. Word..(Algol.. MDX. CGM.). De formatos gráficos no vectoriales: TIFF.. C++. En la ejecución se aplica la función a datos de entrada (argumentos) y se obtiene el resultado calculado por la función (LISP). incorporación de mecanismos de bloques. De formatos de texto: RTF. Cuarta generación: De muy alto nivel para tareas específicas a primero de los años 80. Uso de subprogramas o módulos. COBOL).Según la forma de las instrucciones (características intrínsecas al lenguaje: Lenguajes imperativos o procedurales Orientados a instrucciones o sentencias. La relaciones se especifican con reglas y hechos.. MODULA). . WordPerfect. ASCII. Todo el programa es una función y todas las operaciones son funciones más simples. PL/I. De formatos de bases de datos: DBF. De formatos de archivos de sonido: WAV.. HTML.. XML. como pueden ser para describir formatos de texto. En cualquier caso. herencia y polimorfismo ( java. smalltalk…).

. Lenguaje formal . Sean x.1}. x=ε . Σ* es el conjunto de todas las palabras que se pueden formar con Σ. a. b}.y es sufijo propio de x si ∃ z ∈ Σ+ . se representa por |x| x =aaaabb . b. Se representan por (Σ).1. Σ = {a. si ∃ z ∈ Σ+ .. A. Las palabras se representan por los últimos símbolos del alfabeto castellano en minúsculas x. b}. Σ ⊆ Σ* Sea el alfabeto Σ. Ejemplos de alfabetos: Σ1 ={a. b} . Un alfabeto se define por la enumeración de los símbolos que lo contiene. subpalabra de x es una nueva palabra y.Conceptos básicos sobre palabras. ΣASCII ={A. ba.Una palabra es a una secuencia finita de símbolos de un alfabeto.. bb. sufijo de (x) = {ε...Sea una palabra x definida sobre Σ. subpalabras de (x) = {ε. no vacío de símbolos.…. y es prefijo de x si ∃ z ∈ Σ* | x = y·z Sea x=aab.. Σ* se denomina lenguaje universal definido sobre Σ. Un símbolo es una entidad abstracta que no tiene definición. aaa. aab} Sufijo propio . b}. es una subpalabra entresacada desde el final de dicha palabra. x(∑1)=abab ∀ a ∈ Σ.. |x|=0. b.TEMA 2 LENGUAJES FORMALES 2. donde Σ={a. y es sufijo de x si ∃ z ∈ Σ* | x =z · y Sea x=aab. es una combinación de símbolos de dicha palabra en orden.Un símbolo es un componente mínimo e indivisible que puede formar parte de una palabra. nunca tiene el símbolo vacío ε. z ∈ Σ*.. y. Σ1 ∪ Σ2 es un nuevo alfabeto. aa. se representa por ε (épsilon).. z∉ε | x = z. %. Los símbolos pueden estar formados por más de un componente.e en Pascal) será una cadena sobre el alfabeto de caracteres ASCII Longitud de una palabra x . −. Σ*={ε.z. Σmorse ={. donde Σ={a..y. v ∈ Σ*. Sea x=abab. pero no tienen que ser consecutivos. aab} Prefijo propio .}. |x| = 6 Palabra vacía . a .}. Sean x... Un alfabeto Σ. subsecuencias de (x) = {ε. Σ1 ∩ Σ2 es un nuevo alfabeto. es una subpalabra entresacada desde el inicio de dicha palabra.La longitud de una palabra es el conjunto de símbolos que tiene esa palabra.. Cualquier programa (p. Si Σ1 y Σ2 son alfabetos.Un lenguaje formal es un conjunto de palabras definidas sobre un alfabeto. ab.es una palabra que no tiene símbolos.y Cualquier palabra x incluyendo la palabra vacía.. …} ΣHTML ={<HTML>. siempre que Σ1 ∩ Σ2 ≠φ Símbolo . y. bb. ab. son prefijo y sufijo de sí misma Subsecuencia de una palabra x.− ∈ Σmorse. prefijos(x) = {ε. ab.z. aab} Subpalabra propia .. Subpalabra .. Sean x.. <BODY>.. y su longitud es 0. a es una palabra definida sobre Σ .}. a. a. Alfabeto . b}. z∈ Σ*. z∉ε | x = y·z Sufijo de una palabra.y es prefijo propio de x si x =y · z.Z.-. aa..Se llama alfabeto a un conjunto finito. z. palabra . . aa. v ∈ Σ* | x = v·y·z Sea x=aab. b. Σ* es infinito.v siendo alguna de ellas no vacía tales que vxz=y Prefijo de una palabra. Σ=Conjunto de palabras de un diccionario Si Σ1 y Σ2 son alfabetos. donde Σ={a.x es una subpalabra propia de y ⇔ existen z.} 17 .b}. definida sobre el mismo alfabeto. a ∈ Σ1.. donde Σ={a. Σ2={0. y es subpalabra de x si ∃ z. <HTML>∈ΣΗΤΜΛ Cadena. ab. y. formada por símbolos de x entrescados de forma consecutiva de ésta. Sobre cualquier alfabeto Σ .

|x|+|y|=|z| Propiedades de la concatenación ∀ x.) cumple las siguientes propiedades: Operación cerrada x.y (xy) es una nueva palabra z.y =z P. formada por los símbolos x seguidos de los símbolos de y. xy=z=abaa .. y=aa . Las operaciones a destacar con palabras son las siguientes: Concatenación de palabras (.Conceptos básicos de lenguajes formales Un lenguaje formal L definido sobre un alfabeto ∑. es una nueva palabra definida sobre el mismo alfabeto. tiene una definición formalizada L(∑) ⊆ ∑* L(∑)={x∈∑* | x cumple con la definición formal del lenguaje} 18 . se puede concatenar consigo misma un número determinado n de veces. conjunto de palabras con una significación propia (lógica común) y. su inversa o refleja x-1 (xi ).) Sean dos palabras x. formada por los mismos símbolos que tiene x pero situados en orden inverso. la operación concatenación (. transpuesta) Dada una palabra x definida sobre un alfabeto Σ.y definidas sobre el mismo alfabeto Σ. x=aab . x(∑). una palabra x. x3=aabaabaab Propiedades de la potencia ∀ x ∈ Σ* ⇒ ∃ xn∈ Σ* xn = ε si n=0 xn-1x si n>0 |xn|=n |x| Palabra inversa (refleja. serán operaciones con palabras.2. x0=ε . y ∈ Σ*. la concatenación de ambas x. dando lugar a la potencia n-ésima de esa palabra xn x=aab. x-1=baa Propiedades de la inversión ∀ x ∈ Σ* ⇒ ∃ x-1∈ Σ* x-1 = -1 ε -1 si x= ε y a si x=ay |x|=|x | La operación inversa cumple la propiedad de idempotencia ( x-1 ) -1 = x Una palabra es igual a otra sí tienen la misma longitud y los símbolos en la misma posición. las operaciones de lenguajes formales. neutro xε = εx=x Potencia de una palabra Dado que la concatenación permite la propiedad asociativa.3. 2. es cualquier subconjunto de ∑*.y(∑)=x(∑)y(∑)=z (∑) x=ab. Al estar los lenguajes formales compuestos de palabras. asociativa x(yz) = (xy)z E.Operaciones con palabras..2.

Concatenación o yuxtaposición Dado dos lenguajes L1 y L2 definidos sobre un mismo alfabeto Σ. ab. Al ser un lenguaje formal un conjunto de palabras. bab. a. aaba. lenguaje vacío Cardinal ({})=0 L2 = { ε }. aabbb.}= {εε. ab.…}={ ε. se puede aplicar toda la teoría de conjuntos sobre ellos. el lenguaje coincide con el alfabeto L4 = {a. a. aabaabb } Propiedades que cumple la operación (. a. bb. L2 ={b. L2 ⊆ Σ* L1 ={ε. L1. aabb} Propiedades que cumple la operación (|) unión de lenguajes ∀ L ⊆ Σ* se cumplen las siguientes propiedades: Operación cerrada L1| L2 = L3 P. a2. En éste texto vamos a estudiar las siguientes operaciones con lenguajes formales: Sean L1 y L2. aabb} L1 | L2 ={ ε. a.…} lenguaje formado por palabras que contienen cero o más aes . a0b1. aa. Lenguaje.L1=L1 19 . bb. aab}. aa. asociativa L1 (L2L3) = (L1L2)L3 E. b}.b}: L1 = {}= ∅. la unión de ambos es un nuevo lenguaje L3 . εaabb. εaa. b. definido sobre el mismo alfabeto Σ y formado por las palabras de L1 y L2 L1 | L2 = L1 ∪L2 = {x∈ Σ * | x∈L1 ∨ x∈L2 } L1 ={ε. aabb. εb. L2 ={b. aab} .… .4. aa. n≥0}= {a0. abb. aa. m≥0}={a0b0. bb.) concatenación de lenguajes ∀ L ⊆ Σ* se cumplen las siguientes propiedades: Operación cerrada L1 L2 = L3 P. aabb} .ε = ε. ba. aa. definido por una notación matemática L7 ={palabras formadas por un número impar de aes}={ a. aa. aabaa. 2. aab. a. formado de todas las palabras que se pueden construir con los símbolos {a. aa. aaabb. idempotente L1| L1 = L1 P.…} lenguaje formado por palabras formadas por (0 o más) aes seguidas de (0 o más) bes. neutro L1|φ = L1 . a1. aab} . conmutativa L1| L2 = L2|L1 P. neutro L1.Ejemplos de lenguajes formales definidos sobre el alfabetos Σ = {a. ab. definido sobre el mismo alfabeto Σ y formado por las palabras de L1 concatenadas con las palabras de L2 L1L2=L1· L2 = { xy ∈ Σ*| x∈L1 ∧ y∈L2 } L1 ={ε.Operaciones con lenguajes. L2 ={ εb. o cierre de Σ . incluyendo la palabra vacía. ε} el lenguaje contiene la palabra vacía L5 = {an.b} sin limitación de orden y longitud. aaa. aa. la concatenación de ambos es un nuevo lenguaje L3.…}={ ε.Alternativa o unión de lenguajes Dado dos lenguajes L1 y L2 definidos sobre un mismo alfabeto Σ. aabb} L1.. definido por una notación matemática L6 ={anbm | n. εbb. bb. b.…} Σ*=lenguaje universal de Σ. asociativa L1| (L2|L3) = (L1|L2)|L3 E. lenguaje no vacío Cardinal ({ ε })=1 L3 = {a. L2 ={b. lenguajes definidos sobre Σ.

aabε.a.aa..Ln…=L+= U Li i=1 L1+ ={ε. aaa.aa. εaab. aaaab. aa. un número determinado n de veces.L …= U Li Sea L1 ={ε. incluyendo la palabra vacía. aaab.aa. aaε. aaa. εaab.aab} | {εε. εaa . a. aε. cierre de Kleene) L* es el conjunto de palabras que se pueden formar al concatenar en cualquier orden y cantidad las palabras de L.aab} | {εε. aaba. aaaab.aab} L1L1=L12 ={εε.La operación concatenación de lenguajes formales cumple con la propiedad distributiva con respecto a la operación unión P. incluyendo la palabra vacía. aaab. cierre positivo de L) L+ es el conjunto de palabras que se pueden formar al concatenar en cualquier orden y cantidad las palabras de L ∞ Sea L1 ={ε. a. lenguaje universal sobre Σ) Σ* es el conjunto de palabras que se pueden formar al concatenar en cualquier orden y cantidad los símbolos de Σ . aaaa. aaaa. L*= L+| {ε} .L+ (L mas . aabaab} | {…. aabaa.= U Σ i 0 1 2 Σ*=L* sii Σ⊆L .L* (L estrella.a. ∞ Σ*= Σ |Σ |Σ …. aabaab} | {…. L+=L*. aaa. Σ*=L+ sii Σ⊆L y ε∈L i=0 20 . εa. aabε.} |… . aaa. φ0= ε . aa. aabaab} Propiedades de la potencia de lenguajes ∀ L ⊆ Σ* ∃ Ln ⊆ Σ* Operación cerrada L⊆ Σ * . εaa . aaε. aabaa. aa. aab} i=0 0 1 n L1* ={ ε } | {ε.Potencia de lenguajes Dado que la concatenación de lenguajes formales permite la propiedad asociativa. aaba.a. εa. aab} L+=L1| L2…. aaa. aε.. aa. aabaa. ∞ L*=L |L | ….n veces L L1 ={ε. aabε. aaa. aaba.L = L. εaab. aa. aaaab. εaa . Ln⊆ Σ * Li ..} L*= L+| L0 .L . L+= L* sii ε ∈ L . aaab.Σ * ( sigma estrella. aε. un lenguaje formal L1 se puede concatenar consigo mismo. aaaa. aaε. dando lugar a la potencia n-ésima de ese lenguaje Ln Ln=LLL. εa. distributiva L1 (L2|L3) = (L1 L2|( L1L3) (L1|L2)L3 = (L1 L3)| ( L2L3) .Li=Li+1 Cualquier lenguaje L0= ε Ln = ε n-1 si n=0 L L si n>0 En la definición anterior existe una incongruencia para el lenguaje L= φ .

aa. aabb} L1-L2={ε. bb.φ= L1 21 .Intersección de lenguajes Dado dos lenguajes L1 y L2 definidos sobre un mismo alfabeto Σ .) intersección de lenguajes ∀ L ⊆ Σ* se cumplen las siguientes propiedades: Operación cerrada L1∩ L2 = L3 P. neutro L1 . b.…. a. aa. aa. idempotente L1∩ L1 = L1 P. ab.Sublenguaje de otro Sean dos lenguajes definidos sobre un alfabeto: L1 ={ε.. a.Diferencia de lenguajes formales Dado dos lenguajes L1 y L2 definidos sobre un mismo alfabeto Σ. L1⊆ Σ * L1={ε. idempotente E. a.. aab. aa. Σ +≠ Σ* + + + . aab} . la intersección de ambos L1∩L2 es un nuevo lenguaje L3 definido sobre el mismo alfabeto Σ y formado por las palabras que pertenecen a L1 y a L2 L1 ∩L2 = {x∈ ∑ * | x∈L1 ∧ x∈L2 } L1 ={ε. ∞ Σ+= Σ1|Σ2…. aab. Σ ≠L* .L2 = L3 P. bb.= U Σ i i=0 Σ =L sii Σ⊆L y ε∉L . bb. L2 ={b. es un sublenguaje del lenguaje universal Σ *. L2 ={ ε. a. aab} . aab}.} Dos lenguajes son iguales si todos sus elementos son iguales . aa. a. neutro L1∩ Σ *= L1 P. es un nuevo lenguaje L3 definido sobre el mismo alfabeto Σ y formado por las palabras que pertenecen a L1 y no pertenecen a L2 L1-L2 = {x∈ ∑ * | x∈L1 ∧ x∉L2 } L1 ={ε. b. L2 ={b. conmutativa L1∩ L2 = L2∩L1 P. ba. aa. distributiva L1∪ (L2∩L3) = (L1∪ L2) ∩(L1∪ L3) L1∩ (L2∪L3) = (L1∩L2) ∪ (L1∩ L3) .Σ + (sigma mas) Σ+ es el conjunto de palabras que se pueden formar al concatenar en cualquier orden y cantidad los símbolos de Σ . aab} ⊆ { ε.L1 = L1 L1. bb. a. aabb} L1∩L2 ={aa} Propiedades de la operación (. a. asociativa L1∩ (L2∩L3) = (L1∩L2) ∩L3 E. la diferencia de ambos L1-L2. aab} Propiedades de la operación (-) diferencia de lenguajes ∀ L ⊆ Σ* se cumplen las siguientes propiedades: Operación cerrada L1. aabb} L1 es sublenguaje de L2 si L1 ⊆L 2 Todo lenguaje L1 definido por un alfabeto Σ. aa. aa.

habrá que buscar un medio finito y preciso para su definición.…b. .…aaaaabbbb.……. a. aaa} – lenguaje cuyas palabras están formadas por: una.L L =L L ∩L=φ L U L = ∑* . y dicha definición no aporta información para su tratamiento Para evitar los anteriores problemas de indefinición y tratamiento. . a. compuesto de todas las palabras que se pueden formar con los símbolos de Σ (∑* lenguaje universal) menos las palabras del propio L. para su definición basta con su enumeración. Si el lenguaje es finito.} {palabras que tienen un número impar de aes. baa } 2.Mecanismos formales Un lenguaje formal se define por las propiedades que cumplen las palabras que lo componen. pero dicha definición no aporta información para su tratamiento L= { a. se crearon los mecanismos formales: expresiones regulares.m≥0} Tiene una definición en notación matemática.. autómatas y gramáticas: Las expresiones regulares son mecanismos que sirven para describir un tipo de lenguaje formal (lenguajes regulares). abbaa. aba. Las propiedades que cumplen las palabras del lenguaje deben permitir representarlas de una manera formalizada. conocer su representación L= { a. L ⊆ Σ* L = ∑* . L= ∑* . Pero ocurre que no todos los lenguajes formales pueden definirse de una forma finita y precisa L={ε.5. su complementario L.Lenguaje inverso Dado un lenguaje L definido sobre el alfabeto Σ. empiezan por el símbolo a y tienen una a más que bes} La definición no es precisa. aab. es un nuevo lenguaje formal definido sobre el mismo alfabeto. Los autómatas son mecanismos que permiten especificar de manera finita y precisa cualquier lenguaje formal.aa. abbaa.. dos o tres aes Si es infinito no puede ser enumerado.Otras propiedades: leyes de Morgan L1∩ L2 = L1 U L2 L1 U L2 = L1 ∩ L2 . . aaabb. aba.Complemento de un lenguaje: Dado un lenguaje L definido sobre un alfabeto Σ.ab. aa. aabab. con las palabras anteriormente representadas. su inverso L-1 es un nuevo lenguaje definido sobre el mismo alfabeto Σ y. ababa. L-1 ={ ε.… abb…. mecanismos que permiten simular el reconocimiento del lenguaje para dicha especificación 22 .L __ L = { x∈ ∑ * | x∈ ∑ * ∧ x∉L} Propiedades: ∀ L ⊆ Σ* se cumplen las siguientes propiedades: Operación cerrada L ⊆ Σ* . aab} .} = L={anbm | n. a.. bb. formado por las palabras inversas de L L-1 = { x-1 ∈ Σ * | x∈L } L ={ε.

b} L4={(ab)n | 0<= n < 2 } L5={ambl | m. aaba. están definidos por reglas de producción preestablecidas y se ajustan con todo rigor y formalidad a ellas.L1 . L1*=Σ* . L1=L2 complementario 23 .Sea ∑ un alfabeto cualquiera y L un lenguaje cualquiera definido sobre el alfabeto anterior. L1.Sea L1 un lenguaje definido sobre un alfabeto Σ ={a.Alfabeto de entrada para los lenguajes. aabbabbaba Justificar si se cumplen o no las siguientes igualdades: L1 | L2=Σ* . aabbba. aaaba. L7n ∩ L5n. aaabbaaba.ε ∑*=(∑*)-1 Φ *= ε=Φ+ L1-L2 = L1 ∩ L2 = L1∪L2 (L*)*=(L+)*=(L*)+=L*=(L+)+ (L*)I=(LI)* L1. sufijos. L3 y L* 5. Mientras que los lenguajes formales.. abbabbaba Sea L2 un lenguaje definido sobre un alfabeto Σ ={a. Ejercicios sobre lenguajes formales 1 .Demostrar que (xy)-1= y-1. bb. Pascal 2 . En este tema se ha hecho referencia a la definición lenguaje formal para diferenciarlo de lenguaje natural. Determinar qué lenguajes definen suponiendo que n = 3 3.. Determinar qué lenguajes definen suponiendo que n = 0. L0n| L1n.L = L*-L ∑+=L+ L+=L*-ε ∑+=∑*. aabbbaa.java . Ejemplos válidos: a. justificar si siempre son ciertas o no. L3n| L0n.b} formado por las palabras que tienen un número par de símbolos a (el 0 se considera un número par) y como máximo dos símbolos b consecutivos. b}: • • • • • • • • L0={} L1={ε} L2={a} L3={a. aaabbaba.y ∈Σ*. L7n| L5n . 2.Sean las siguientes operaciones con los anteriores lenguajes formales: L0n L1n.L2=L2. 3. L*=L+ ∑*=L+ L =∑*.b} formado por las palabras que tienen un número impar de símbolos a y como máximo dos símbolos b consecutivos. Ejemplos válidos: ε.(∑*-L1)=L1 L1-∑*-L1= Φ L1-L2 = L1 ∩ L2 = L1∪L2 7 .Las gramáticas son mecanismos que permiten especificar de manera finita y precisa cualquier lenguaje formal. Para cada una de las siguientes igualdades. C. prefijos propios. L3n. L3n L1n. L0n . mecanismos permiten simular la generación de las palabras del lenguaje especificado.l >= 0 } L6={anbn | n>=0 } L7 ={lenguaje formado por las palabras que tienen un número impar de aes} Determinar para cada uno de ellos L0. L3n L0n.En una palabra de longitud n – cuantas subpalabras hay en las definiciones: Prefijos. L7n 1. baabbabbab. al contrario que los naturales. babbabbab Ejemplos no válidos: ε. 4 . L3n | L1n. un lenguaje natural es aquel que ha evolucionado con el paso del tiempo para fines de la comunicación humana. Determinar qué lenguajes definen suponiendo que n = * 6. En general. aa.x-1 ∀ x. bb Ejemplos no válidos: a.Dados los siguientes lenguajes formales definidos sobre el alfabeto ∑= {a. . evolucionan sin tener en cuenta reglas gramaticales estrictas que puede resolver situaciones ambiguas.

α2→β2….Definición formal Una gramática es un mecanismo formal compuesto por cuatro elementos G = (Σ.…. alfabeto auxiliar que determina la complejidad de la estructura de las palabras a generar por la gramática Σ ∩ N=Φ S . N. se dice que se deriva en cero pasos. Una gramática que genera dicho lenguaje es la siguiente: G = (Σ ={a. o bien que la palabra ω2 deriva de la palabra ω1.6.es el alfabeto no terminal.δ2∈ ( N | Σ)* Es decir δ1α1δ2→δ1β1δ2 .} .b}. αi ∈ ( N | Σ)* N ( N | Σ)*. P) en donde: Σ .es un conjunto finito de reglas de producción a través de las cuales se obtienen todas las palabras del lenguaje que genera la gramática. N={S.es el símbolo inicial a partir del cual se obtienen todas las palabras del lenguaje a generar por la gramática S∈N P . a1b0. aunque dicha producción u otras de la gramática se puedan aplicar sobre la misma palabra ω. alfabeto de las palabras del lenguaje que genera la gramática N .es el alfabeto terminal.es un proceso enfocado en la obtención de las palabras del lenguaje que genera dicha gramática Sea una gramática G = (Σ. P) P: S → AB A → Aa |ε B → Bb |ε . β i ∈ ( N | Σ)* Ejemplo Sea un lenguaje formal compuesto por las palabras que se ajustan a la siguiente definición: L(Σ )={anbm | n. Una gramática está formada por un conjunto finito no vacío de reglas (producciones) a través de las cuales se obtiene (genera) un lenguaje. } α ∈ (N | Σ)*N( N| Σ)*. δ1. 24 . Una palabra se deriva o se produce así misma sin aplicar el proceso de derivación. es un proceso no determinista que sólo se aplica a una producción..Derivación en el entorno de una gramática Derivación en el entorno de una gramática . P) P: { α1→β1.β1. a1b1. P: { α1→β1.B}.Gramáticas Formales Una gramática es un mecanismo formal generador de lenguajes formales..S. En un proceso de derivación de un paso o producción directa. ω1→ω2 Por lo que puede decirse que la palabra ω1 produce la palabra ω2 (de ahí el nombre de producción en la definición de gramáticas). α2→β2. S. .2. m≥0}={a0b0.A. Sea la palabra ω1 = δ1α1δ2 . una producción α1→β1 de la propia gramática G.δ2∈ ( N | Σ)* y α1 ∈ (N | Σ)* N (N | Σ)* Aplicando la producciónα 1→β1 de la gramática G sobre dicha palabra ω1.Derivación directa (derivación de un paso) Consiste en aplicar sobre una palabra ω ∈ ( N | Σ)* N ( N | Σ)* obtenida de la gramática G. β ∈ ( N|Σ)* L(G)={ x∈ Σ* | xδG ( x deriva de G) } . a0b1. que especifica de una manera finita y precisa el conjunto de palabras que componen el lenguaje al que se quiere definir. la palabra ω1 se transforma en δ1β1δ2= ω2 en donde δ1. . N. S..

b}. m≥0} AbB A . S. A. bm |m≥0 … anbm | n≥0. Ejemplo: G1 = (Σ ={a.aaabb A partir de la anterior definición. S. a . ωi→ωj . aa.…ωm ∈ (N | Σ)* N (N | Σ)* se dice que están en relación de derivación en la gramática G. P) P: S → AB A → Aa |ε B →Bb |ε 25 . se puede decir que. B}. .Gramáticas equivalentes Una gramática genera un solo lenguaje. se llama sentencia .. N={S.. el lenguaje generado por una gramática es el conjunto de sentencias que pueden obtenerse desde el símbolo inicial en un proceso de derivación. A. En el ejemplo anterior son sentencias: ε.. AB. an | n≥0 Forma sentencial – cualquier palabra obtenida de un proceso de derivación.Relación de derivación Sean las palabras ωi. S→*x} Lenguaje generado por la siguiente gramática: G = (Σ ={a. si generan el mismo lenguaje. m≥1 L(G)= {anbm | n≥0. b}. b.aaabb. que se obtienen desde el símbolo inicial en un proceso de derivación de cero o más pasos.→ x = x∈ Σ* L(G)={x | x∈ Σ* . Dos o más gramáticas se dice que son equivalentes.Lenguaje generado por una gramática Conjunto de palabras definidas sobre el alfabeto Σ. ωj→ωk . B}. P) P: S → AB A → Aa |ε B →Bb |ε AaB AaaB aB Aa AaBb Bb ε AabB bB AbBb Ab Aa ε …anbm | n≥1. ε…. de la misma manera para representar un proceso de una o más derivaciones es la siguiente: ωi→+ωm . si la palabra (ωi produce la palabra ωm) o ωm deriva de la palabra ωi en cero o más derivaciones directas. m≥0 S→AB B ….…. en el anterior ejemplo cualquier palabra derivada desde S: S . N={S. S→ α1 → α2 → α3….. pero un lenguaje puede ser generados por muchas gramáticas. ωk→ωm La representación de un proceso de cero o más derivaciones se representa de la siguiente forma: ωi→*ωm . son formas sentenciales Si la forma sentencial está compuesta únicamente por símbolos terminales de la gramática.

26 .Gramáticas de Tipo 3 (Gramáticas regulares). P) P: S → aA| bB |ε A → Aa |ε |bB B →Bb |ε Las gramáticas G1 y G2 son equivalentes. b}. β ∈ ( N | Σ)* |α|≤|β| Se permite además la producción S →ε ¸ siempre y cuando no aparezca el símbolo no terminal S en la parte derecha de ninguna regla de producción. a ∈ Σ Los lenguajes generados por estas gramáticas se llaman lenguajes regulares o lenguajes de tipo 3 y. .Clasificación de las gramáticas Noam Chomsky en 1959 clasificó las gramáticas en cuatro familias (Jerarquía de Chomsky) de gramáticas.Gramáticas de Tipo 2 (Gramáticas libres del contexto). α ∈ ( N | Σ)* Los lenguajes generados por este tipo de gramáticas se llaman lenguajes libres del contexto o lenguajes de tipo 2 y. Todas sus producciones son de la forma: A → Ba A→a A →ε ¸ en donde A. B∈ N .…. A→a y S→ ε (siempre que el lenguaje tenga la palabra vac ía) En nuestro caso hemos cogido la más simple ya que permite una mayor flexibilidad en el tratamiento y transformación entre los mecanismos regulares. Todas sus producciones son de la forma: A → aB A→a A →ε ¸ en donde A. a1b0. Las producciones son de la forma: A →α donde A ∈ N . P) P: { α→β. .7. A. * Existen otras definiciones sobre las gramáticas de tipo 3.} 2. Las producciones son de la forma: α →β en donde α ∈ ( N | Σ)* N ( N | Σ)*. en los siguientes cuatro tipos: .. en una derivación directa sólo cuando A aparezca en el “contexto" de δAγ . que difieren. todos forman la clase de lenguajes L2. como aquellas que permiten las producciones de la forma: A→aB.} α ∈ ( N | Σ)* N ( N | Σ)*..m≥0}={a0b0.Gramáticas de Tipo 1 (Gramáticas sensibles al contexto). Pueden ser a su vez. a0b1. de dos tipos: Lineales por la derecha.. B}. S. N. . S. atendiendo a la forma que pueden tener sus reglas de producción.G2 = (Σ ={a. B ∈ N . entre otras. N={S. Ambas generan el mismo lenguaje: L={anbm | n. β ∈ ( N | Σ)* clasificaremos las gramáticas. a1b1. todos forman la clase de lenguajes L3. El sentido de estas reglas de producción δAγ→δβγ es el de especificar que el símbolo A puede ser reemplazado por β. Sea una gramática G = (Σ. a ∈ Σ Lineales por la izquierda.

forman el conjunto de lenguajes de tipo L1 . P) P: S → AB . S.1.2. la gramática G es de tipo 2 2.8. Dado que un lenguaje. si existe una gramática con un tipo N que lo genera y no otra de un tipo N superior.. gramáticas equivalentes que pueden ser de tipo diferente. a1b0.3).Determinación del tipo de una gramática Para determinar el tipo de una gramática G. Los lenguajes generados por las gramáticas de tipo 1 se llaman lenguajes sensibles al contexto y. B →Bb |ε}∈tipo 2.Las producciones de este tipo de gramáticas cumplen siempre que la parte izquierda tiene longitud menor o igual que la parte derecha.B}. empezando por las producciones de tipo superior.Tipos de lenguajes formales De los tipos de familias de gramáticas creados por Noam Chomsky (Jerarquía de Chomsky) se obtiene una clasificación en los lenguajes que generan. B}. a0b1.A.Gramáticas de Tipo 0 (Gramáticas con estructura de frase..9. P) P: S → AB A → Aa |ε B →Bb |ε La producción S → AB ∉ tipo 3 la gramática G no es de tipo 3 Todas las producciones: {S → AB. Relación de inclusión de las gramáticas: Tipo 3⊆ Tipo 2⊆ Tipo 1⊆ Tipo 0 Tipo 0 Tipo 1 Tipo 2 Tipo 3 2. lenguaje que puede ser generado entre otras por las gramáticas G1 y G2 Ejemplo: G1 = (Σ ={a. que por ello también se llaman gramáticas sin restricciones. A. m≥0}={a0b0. de no ser así se baja de tipo hasta encontrar un tipo que coincida con la dada. pero nunca mayor (excepto para S →ε ). α є ( N | Σ)*N ( N | Σ)* β є ( N | Σ)* Los lenguajes generados por estas gramáticas son los lenguajes con estructura de frase. Esto quiere decir que la gramática es no contráctil. A → Aa |ε .}. a1b1. que tipo de gramática asociar al lenguaje. A → Aa |ε . existe un problema a la hora de relacionar lenguajes con gramáticas. de la forma: α→β . Esto quiere decir que las producciones pueden ser de cualquier tipo permitido. dada la siguiente gramática determinar el tipo de la misma. basta por equiparar las producciones de dicha gramática a las producciones de las familias de los tipos de gramáticas. que se agrupan en la clase de lenguajes de tipo de L0. N={S.b}. b}. no restringidas) Son las gramáticas más generales. N={S. Para solucionar la anterior indecisión. es decir.…. Estos lenguajes también se conocen como lenguajes recursivamente enumerables.S. Ejemplo. podemos aplicar el siguiente axioma a la hora de determinar el tipo del lenguaje generado por la gramática: un lenguaje es de tipo N (N=0. B →Bb |ε G1 es una gramática de tipo 2 27 . puede ser generado por varias gramáticas. G = (Σ ={a. Sea el lenguaje L(Σ)={anbm | n.

A. no existe una gramática de un tipo superior que lo genere. b. A → Aa |ε |bB . b. n. para este caso el tipo del lenguaje L(Σ)={anbm | n.S. P) P: S → aA| bB |ε . m >0} 2. El conjunto de los lenguajes de tipo 3 (regulares) definidos sobre un alfabeto Σ.Construir una gramática que especifique el siguiente lenguaje: L = { w ∈ {0.B}. 2}* | w contiene exactamente dos o tres símbolos 0 en cualquier posición}. G = (Σ ={a. c}. S. Relación de inclusión de los tipos de lenguajes: L3⊆ L2 ⊆ L1⊆ L0 L0 L1 L2 L3 Ejercicios de gramáticas 1. L = { anbm | m <= n <= 2m . n. L = {an bm | n > m >= 0} f) ∑ = {a. b. 1. éste a su vez. b}. B →Bb |ε G2 es una gramática de tipo 3 Para determinar el tipo al que pertenece el lenguaje. L = { anbm | n <>m . está incluido propiamente en el conjunto de los lenguajes tipo 2 ( libres de contexto) y.b}. L = {an bm | n >= m >= 1} e) ∑= {a. c}. b}. m >= 1} c) ∑= {a. L = {am bn ck | m > n + k .A.G2 = (Σ ={a.Para las gramáticas que se proponen a continuación. b}. ¿Sería posible obtener una gramática regular o de tipo 3? 3. N={S. a3b3. b}. L = {an bn+m cm | n >= 1. m≥0 } será de Tipo 3 (no existe una gramática de un tipo superior que lo genere). N={S. a) S → 0S | A A → 0B | 0 B → 1A b) S→ abA | bbB A → bC B→a C → cS | ε 28 . está incluido propiamente en el conjunto de los lenguajes de tipo 1 (sensibles al contexto). c}.…. determinar el tipo de las mismas y el lenguaje generado. L = {an bm cn+2m | n >=0. m >=0} h) ∑ = {a. B}. Sea el lenguaje L(Σ )={anbn | n≥0}={a0b0. que lógicamente está incluido en el conjunto de lenguajes tipo 0 (con estructura de frase). b}. m >= 0} d) ∑= {a.Obtener una gramática para cada uno de los siguientes lenguajes: a) ∑= {a. a1b1. m >= 1} b) ∑= {a. L = {an bm cn | n. a2b2. k >=0} g) ∑ = {a. c}. será el tipo de la gramática con el tipo superior que lo genere. P) P: S → aSb |ε El lenguaje anterior es de tipo 2. b. n.

b. Ejemplos de palabras del lenguaje: 2+67+9870 ó 35 Ejemplos de palabras no válidas: 34+ ó 34++23 Representar mediante una gramática de tipo 2 los siguientes lenguajes: a) Sea L1 el lenguaje de sumas en el que los números naturales no pueden tener ceros a la izquierda. construir una gramática de tipo 2 que defina dicho lenguaje. resta. 7. + }. 1. 9 son operandos y . teniendo en cuenta las restricciones. w ∈ {a. 4. y no pertenecen: 11. producto y división respectivamente.0.Dado el alfabeto Σ= {a.Dado el alfabeto Σ = {0. 7. entonces la longitud de w es mayor o igual que n • si w termina en b.b}+ y |w|=|v|}. teniendo en cuenta las restricciones.*.Sea la siguiente gramática definida sobre el alfabeto ∑ = {a. w deberá empezar por a • Pero si el dígito central es 1. aunque no sea el número 0. Ejemplos de palabras no válidas: 03+129 .b. 3. 4. 5.Dado el alfabeto Σ={a. m > 0}. Ejemplo:10+0 ii. teniendo en cuenta las restricciones. 2. 2..4. justificándolo mediante un mecanismo formal del tipo correspondiente. 7. 3. 5. 1. a1b. Por ejemplo. +1 ó 1*/2. en el que además se cumplen las siguientes restricciones: • Si el dígito central es 0. 1+0 y 5+3*8/7. 1 c) Sea L3 el lenguaje de sumas en el que los números naturales pueden empezar por 0. 9.*. + . 6. 1. a0a. b1a.c} se define el lenguaje L = {w·c n | w pertenece a {a. entonces la longitud de w es menor o igual que n Obtener una gramática independiente del contexto que genere el lenguaje pedido.Con el alfabeto ∑={a. a0b.. sea el lenguaje L={w·(0|1)·v | v. aunque no sea el número 0. Ejemplo: 0503+30+450+89+203+03 8 . / }. Ejemplo de palabra no válida: 03+12 b) Sea L2 el lenguaje de sumas en el que los números naturales pueden empezar por 0. 5. i.. ba1ba Obtener una gramática independiente del contexto que genere el lenguaje pedido.Sea el lenguaje de sumas de números naturales sobre Σ = { 0.b}* y |v| >= |w| (la longitud de v es mayor o igual que la de w) } Obtener una gramática independiente del contexto que genere el lenguaje pedido. pero en cada suma se cumple siempre la condición de que el primer y el último número tienen siempre la misma longitud (al menos habrá dos números). donde 0. 6. 8.. i. 10 . pertenecen a este lenguaje las palabras 1. 6. + . Determinar el tipo del lenguaje L. / son los operadores binarios de suma. pero en el que se cumple la condición de que al menos dos números tienen la misma longitud. 8. n>0} en el que además se cumple que: • si w termina en a. = } S → BSa | aSa | a+a=aa Ba → aB B+ → +a Obtener el lenguaje generado por la misma 5 . +.b}+. abb1abb Ejemplos de algunas palabras no válidas: b0a. 8. 9. a1a. i. b} sea el lenguaje: L = { vbbw | v. 29 .w pertenecen a {a. Ejemplo: 10+1+01 ii. Ejemplos de palabras válidas: aba0bba. 4. entonces es v quien empezará por a. nunca por una secuencia de ceros. = } y el siguiente lenguaje: L={an+am=an+m | n. ba0aa.1}.Dado el alfabeto Σ= {a. +. sea el lenguaje L formado por todas las expresiones aritméticas que se pueden formar con los símbolos de este alfabeto. 6. 2. 7. El número 0 se representará por un único cero. 9. 3.