TEMA 1 LENGUAJES DE PROGRAMACIÓN
|
|
|
- Domingo Martín Quintana
- hace 9 años
- Vistas:
Transcripción
1 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
2 - 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
3 Traductor Un traductor entre dos lenguajes de programación, 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); 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. El traductor está escrito en un lenguaje de implementación Li, o también llamado host. El proceso de traducción no altera el significado del programa traducido. El traductor analiza el programa de entrada verificando que está correctamente codificado según la definición del lenguaje fuente; si el programa analizado no tiene errores se puede traducir; en caso contrario, el traductor avisa de los errores detectados. La entrada al traductor se denomina programa fuente y la salida programa destino (o también código generado por el traductor). -- Traductor entre los lenguajes L y L 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. Tipos de traductores Compiladores, ensambladores, conversores,.. Compilador Un compilador, traduce un programa escrito en un lenguaje fuente de alto nivel a otro semánticamente equivalente escrito en un lenguaje objeto, 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, no suele darse con frecuencia debido a que tras de una compilación suelen aparecer acciones (enlazador, cargador,..) para obtener el código ejecutable. La ejecución del programa compilado puede considerarse como un proceso de interpretación del procesador. La ejecución, es un proceso posterior en el que se ejecuta el programa objeto, 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, 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. -- compilador del lenguaje P/L T [Li] P /L M E C P [ O ] P [ O ] D P [ L ] M M' R C compilador del lenguaje L, 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
4 D datos para una ejecución del programa P R resultados de una ejecución del programa P Máquina anfitriona - máquina donde se ejecuta el compilador ( M ) Máquina 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 tiempo que tarda en ejecutarse el texto de un lenguaje se llama tiempo de ejecución. Un compilador es un programa que traduce un único lenguaje fuente, produciendo código para una única máquina destino. Fases de un compilador. Representaciones intermedias. La tarea realizada por un compilador es muy compleja y por ello conviene considerarla descompuesta en diferentes partes. 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. Se considera una descomposición funcional del compilador en diferentes fases. En una primera aproximación se diferencian dos fases: análisis y síntesis; 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; en la fase de síntesis se transcribe ese significado empleando la notación del lenguaje destino, generando el código máquina que representa el mismo algoritmo que el programa fuente. Para separar claramente estas dos fases conviene desde un punto de vista conceptual considerar que, 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; la naturaleza de esta representación intermedia depende del método empleado para la implementación del compilador Fase de Representación Fase de P [ F ] análisis intermedia Síntesis P [ O ] P [ I ] 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. La representación intermedia no es obligatoria en las fases de un compilador, puesto que un compilador puede generar código objeto directamente (compilador puro). Análisis: la fase de análisis debería ser independiente de la máquina, mientras que la de síntesis depende de la máquina en la que se ejecutará. Síntesis: A partir del código intermedio generado en la fase de análisis, generan y optimizan el código, dependiendo ahora de la máquina en la que se ejecutará En una segunda aproximación, la fase de análisis se considera, a su vez, descompuesta en tres fases cada una de ellas encargada de examinar las diferentes características del programa analizado: - 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), - 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, y que constituyen el programa, - 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. En cualquiera de la fases de análisis pueden encontrarse errores: lexicográficos, sintácticos, semánticos; 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. 4
5 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); la principal estructura de datos donde el compilador almacena la información que obtiene del programa analizado se denomina tabla de símbolos. En la fase de síntesis se realiza la tarea de generar el código destino; 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. Fase de Análisis Fase de Síntesis Código fuente Análisis léxico Componentes léxicos Análisis sintáctico árbol sintáctico Análisis semántico Árbol anotado Generación de cód. 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; 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; estas optimizaciones pueden hacerse en diferentes momentos: sobre la representación intermedia, sobre el código destino o sobre el lenguaje intermedio (si se ha producido la generación en dos etapas); 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. 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. Uno de los problemas que se encuentra en un nueva máquina es que alguien tiene que escribir el primer compilador. La tarea será más cómoda de hacer en la máquina que se dispongan herramientas software, para después trasladarla a otra. Autocompilador Es un compilador escrito en el mismo lenguaje que compila. Cuando se extiende entre muchas máquinas diferentes el uso de un compilador, y éste se desea mejorar, el nuevo compilador se escribe con el antiguo, de manera que pueda ser compilado por todas esas máquinas diferentes, y dé como resultado un compilador más potente de ese mismo lenguaje. Metacompilador Es sinónimo de compilador de compiladores. 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. Traduce un programa fuente en un lenguaje de bajo nivel a otro objeto de nivel superior. En la mayoría de los casos traducen un lenguaje máquina a un lenguaje ensamblador, también llamados desensambladores 5
6 Compilador incremental Es aquel que compila un programa en el que si después se descubren errores, en vez de corregir el programa fuente y compilarlo por completo, se compilan solo las modificaciones. Lo ideal es que solo se recompilen aquellas partes que contenían los errores, y que el código generado se reinserte con cuidado en el lenguaje objeto generado cuando se encontraron los errores. Sin embargo esto es muy difícil. Compilador con montador y cargador Compilador de distintos módulos de forma independiente y después los enlaza. 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. 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; de esta forma se han obtenido n trozos de programa traducido que no son todavía programas ejecutables; para formar un único programa ejecutable hay que unir las n partes obtenidas en los procesos de compilación. Sobre los trozos de programa resultantes de las compilaciones hay dos tareas pendientes de realizar: - 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, - la obtención de las direcciones definitivas para los componentes del programa considerado como un todo, una vez que se hayan juntado las distintas partes traducidas por separado. P F [1] P F [2] C C P O [1] P O [2] Montador (Cargador) P O[reu] Prog ecutable en memoria P O[eje] P F [n] C P O [n] compilador 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. A la salida del montador se obtiene un programa completo que ya está preparado para su ejecución. 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); 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. 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. Una vez analizado el problema y descompuesto en tareas más sencillas, hay que diseñar una manera de hacer la implementación. Desde el punto de vista de la implementación se fija la cantidad de pasadas que el compilador hace sobre el programa analizado; en cada pasada se hace un tratamiento del programa completo y se realiza sobre él alguna parte del trabajo de la compilación; el resultado de cada pasada es el punto de partida para la pasada siguiente, esto es, cada pasada se acerca más al resultado pretendido por el compilador. Pasadas son el número de veces que se procesa una representación del programa fuente. Cada pasada requiere: lectura del código fuente, procesamiento y almacenamiento de la información obtenida. 6
7 Si todas las fases de la compilación se realizan examinando una única vez el texto de entrada, entonces se trata de un compilador de una única pasada. Si el lenguaje tiene una semántica compleja puede requerir que cualquier implementación de un compilador requiera más de una pasada. El método empleado para implementar el compilador también influye en el número de pasadas requeridas. Por ejemplo, los lenguajes que permiten que el uso de una entidad (variable, subprograma, método ) pueda preceder a su declaración (como ocurre en Java) requieren compiladores diseñados con más de una pasada. Las pasadas suelen agruparse: 1ª pasada A léxico, A sintáctico, A. 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, pero aumenta el tiempo de ejecución al realizar más operaciones de entrada salida, 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. Típicamente una pasada para realizar el análisis léxico y sintáctico, 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. Existen ensambladores con macroinstrucciones: Macroensambladores. Desensambladores Caso inverso a los ensambladores, traducen de código máquina a ensamblador. Es un caso más fácil puesto que hay una correspondencia directa entre las instrucciones ensamblador y el código máquina. Conversores Traducen un lenguaje de alto nivel a otro lenguaje de alto nivel, para conseguir mayor portabilidad. Por ejemplo en un ordenador sólo hay un compilador de PASCAL, y queremos ejecutar un programa escrito en C; 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. 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. El intérprete va considerando una tras otra las instrucciones del programa interpretado y, para cada una de ellas, analiza su significado y procede de inmediato a realizar las tareas correspondientes, antes de pasar a la siguiente instrucción; en particular, si en el programa se indican operaciones de entrada/salida, el intérprete controlará su realización. -- Intérprete del lenguaje D (datos) P/L I M E R (resultados) 7
8 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 intérpretes: (según la estructura interna del intérprete) Intérpretes puros Los lenguajes no necesitan de pseudocompilación, analizan y ejecutan sentencia a sentencia todo el programa fuente, pueden considerarse intérpretes puros los intérpretes de comandos de la mayoría de los sistemas operativos. La interpretación pura en los lenguajes de alto nivel no suelen contruirse puesto que el proceso es bastante ineficaz. 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. Intérpretes incrementales Lenguajes que no se pueden compilar directamente, existen objetos que no son conocidos en tiempo de compilación ( Lisp, prolog, 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), sin embargo los conceptos de traducción y de interpretación son esencialmente distintos. Pueden enunciarse abundantes diferencias entre los procesos de traducción y de interpretación, entre las más significativas están: una traducción siempre produce como salida una representación del programa analizado (el código destino); si ese código fuera ejecutable en alguna máquina; 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; 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); aunque el concepto de lenguaje fuente es más propio de los traductores, también puede decirse que el lenguaje para el que se construye el intérprete es su lenguaje fuente. Un intérprete necesita menos memoria, es más fácil de depurar, tiene una mayor flexibilidad a la hora de modificar las características del lenguaje fuente, tienen una mayor portabilidad, potencian el uso de los sistemas interactivos, la dificultad y coste de programación son menores( no necesitan fase de generación de código, optimización, montaje y reubicación). No son útiles con estructuras complejas, programas que trabajan en modo producción y la velocidad es importante e instrucciones son ejecutadas con frecuencia. En la actualidad suelen mezclarse ambas técnicas (apdo. 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, 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, es decir siempre se produce un proceso de interpretación. 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, puede emplearse una descomposición del problema apoyada en la utilización de un lenguaje intermedio. 8
9 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). 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, 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; aunque el programa resultante de esa traducción todavía no es directamente ejecutable en una máquina, se ha conseguido disminuir la separación semántica entre el lenguaje fuente y la máquina destino. Leng. Fuente Separación semántica entre lenguaje fuente e intermedio Leng. Intermedio Separación semántica entre lenguaje intermedio y máquina Leng. máquina Los lenguajes intermedio no son lenguajes de programación de ninguna máquina real, sino que corresponde a una máquina abstracta. Diseño de los lenguajes intermedios: - Lenguajes intermedios de alto nivel - lenguajes diseñados para actuar en las primeras fases de traducción (análisis) o incluso de procesado. Son dependientes del lenguaje fuente e independiente de la arquitectura destino. Las tareas de dicho lenguajes comprobación de tipos, generación de código y optimización de código con independencia de la plataforma. Las representaciones de lenguajes intermedios de alto nivel mas empleados son: árboles de sintaxis abstracta AST, grafos dirigidos acíclicos GADs y grafos de dependencia. Facilitan la traducción del lenguaje fuente; sus características están próximas al lenguaje fuente; por ejemplo el código P definido para favorecer la implementación del lenguaje Pascal, - Lenguajes de medio nivel válidos para representar un conjunto amplio de lenguajes fuente ( no siendo dependientes de uno concreto), válidos para representar un conjunto extenso de arquitecturas hardware. Representaciones mas empleadas: máquinas de pila (representación más empleada de código intermedio), de tres direcciones(tercetos), de cuatro direcciones (cuartetos) y notación polaca inversa (recorrido post orden) - leguajes intermedios de bajo nivel permiten traducir a distintos micros, de una misma arquitectura (dependientes de ésta), se basan en lenguajes con registros simbólicos Influidos por la máquina destino, están próximos al lenguaje máquina. Lenguaje 1 Lenguaje 2 Lenguaje n n lenguajes Traducción directa n*m Plataforma 1 Plataforma 2 P Plataforma O [1] m m Plataformas Traducciones de n lenguajes a m plataformas m*n 9
10 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, 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, 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. Cualquier módulo de Internet dispone de una máquina virtual para cod. intermedio Intercomunicación de aplicaciones: La representación binaria de datos en distintas plataformas varía. El empleo de una misma maquina abstracta evita tener que traducirlos Inconvenientes Introduce en el compilador una nueva fase de traducció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. Portabilidad Compilación a máquina abstracta Lenguaje 1 C Lenguaje 2 PASCAL Lenguaje intermedio Lenguaje n JAVA n Lenguajes n+m Traducción a máquina real Plataforma 1 Intel Plataforma 2 Motorola Plataforma n Dec-Alpha m Plataformas En la anterior representación puede verse, 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. 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, en tal caso se estaría hablando de una máquina concreta). Una máquina virtual es una máquina abstracta para la que existe un intérprete. También puede decirse que, 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. Una máquina virtual se puede implementar sobre una máquina física; para ello ha de tenerse: - una estructura de datos que soporte la arquitectura de la máquina virtual, organización de memoria (pila, registros, ) - un intérprete del lenguaje de la máquina virtual que se ejecute en la máquina física.(conjunto de instrucciones que pueden ejecutarse. 10
11 Hay una gran variedad de máquinas virtuales: unas basadas en pila, otras en registros o una combinación de ambas; diseñadas para facilitar la implementación de lenguajes y para favorecer su portabilidad a distintas máquinas físicas; por ejemplo: - máquina virtual de java JVM (Java Virtual Machine) - máquina P para Pascal, - máquina A para Ada, - máquina EM, -.. Los lenguajes intermedios facilitan la portabilidad de diferentes lenguajes de programación de alto nivel a distintas máquinas (físicas). Si se quiere implementar un lenguaje de alto nivel en diferentes máquinas, 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). Por ejemplo, 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). El código bytecode se está convirtiendo en un código intermedio universal, ya existen intérpretes de JVM (máquina virtual de java) para todos los sistemas operativos. De ahí el famoso axioma que sigue a Java: "escríbelo una vez, ejecútalo en cualquier parte", o "Write once, run anywhere". Lenguaje1 Lenguaje2 P Lenguajen O [1] N lenguajes Compilación a máquina abstracta Lenguaje intermedio N+m Traducción a máquina real 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, podemos utilizar una máquina virtual para cada plataforma El principal objetivo es reducir el número 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, las fases se agrupan en una etapa inicial (Front-End) y una etapa final (Back- End). La etapa inicial comprende aquellas fases, o partes de fases que dependen principalmente del lenguaje fuente y que son en gran parte independientes de la máquina objeto. Ahí normalmente se introducen los análisis léxicos y sintácticos, la creación de la tabla de símbolos, el análisis semántico y la generación de código intermedio. La etapa inicial también puede hacer cierta optimización de código e incluye además, el manejo de errores correspondiente a cada una de esas fases. La etapa final incluye aquellas partes del compilador que dependen de la máquina objeto y, en general, esas partes no dependen del lenguaje fuente, sino sólo del lenguaje intermedio. En la etapa final, 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. 11
12 Front - end Arquitectura Front- end / Back-end Código fuente Análisis léxico Comp. léxicos Análisis sintáctico Árbol sintáctico Análisis semántico Análisis sintáctico Árbol anotado Generación de cód. int. Código intermedio Optimización de cód. int Back-end Generación de código Optimización de código Código objeto 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. 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. Front- end Para el lenguaje C Lenguaje intermedio Back-end Dec-Alpha Back-end Motorola Back-end Intel Cod. maq Dec-Alpha Cod. maq Motorola Cod. maq Intel Compilador C para tres máquinas diferentes. 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, obteniéndose así varios compiladores para una máquina. Pascal Java C Front - End Front -End Front End Back End Cod. maq Intel Tres compiladores ( pascal, java y C) para una misma máquina 12
13 La representación intermedia actúa como medio de comunicación entre el front-end y back-end. - Si se cambia el lenguaje fuente, se reescribe el front-end. - Si se cambia la máquina objeto, entonces se reescribe el back-end - Si aparece una nueva arquitectura, basta con desarrollar un traductor del lenguaje intermedio a esa máquina Modalidades de procesadores. Rara vez se realiza el proceso de traducción o interpretación (pura) para resolver el problema de separación semántica, en la mayoría de los casos coexisten, dándose primero la traducción del fuente a una representación intermedia, a la cual se le aplica el proceso de interpretación. Todo lenguaje de programación necesita de uno o más procesadores de lenguajes. 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. * Un compilador Un copilador, 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, C, ADA). n 1 Compilador n 2 n 1 n 2 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. n 1 Traductor n 2 n 1 n 2 n 3 nivel de L (lenguaje de alto nivel) nivel del lenguaje intermedio nivel de la máquina (física) Traductor n 3 * Un intérprete Aunque no es habitual su utilización (por cuestiones de eficacia), puede considerarse un proceso de interpretación directa (pura) de un lenguaje de alto nivel; en este caso el propio intérprete constituiría un procesador para el lenguaje de alto nivel. n 1 Intérprete n 2 n 1 n 2 nivel de L (lenguaje de alto nivel) nivel de la máquina (física) 13
14 * Un traductor y un intérprete Un traductor del lenguaje fuente a un lenguaje intermedio y un intérprete del lenguaje intermedio (java, Perl, PHP). n 1 Traductor n 2 n 1 n 2 n 3 nivel de L (lenguaje de alto nivel) nivel del lenguaje intermedio nivel de la máquina (física) Intérprete n 3 Herramientas para la construcción de procesadores de lenguajes A parte de las herramientas de desarrollo de software convencionales como: editores, depuradores, perfiladores,, para la construcción de procesadores de lenguajes, existen otras herramientas especializadas y cada vez más, que ayudan a la construcción de procesadores, entre los que podemos destacar los siguientes: Generadores de analizadores léxicos Generación basada en el uso de expresiones regulares, generan automáticamente el código fuente para el análisis léxico a partir de una especificación de los tokens. El generador es un autómata finito. El generador de nuestro estudio es JavaCC que genera código en java. 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. El generador de nuestro estudio es JavaCC que genera código en java. Analizadores de gramáticas Dada una gramática especificada formalmente, verifican si es de un determinado tipo o no. Normalmente se utilizan para verificar las gramáticas LL(k) y LR(k). Máquinas de traducción dirigida por sintaxis Producen un conjunto de rutinas que recorren el árbol sintáctico y generan código intermedio. Asocian una o más traducciones a cada nodo sintáctico. 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. Las reglas suelen remplazar instrucciones de código intermedio por patrones que contienen las instrucciones equivalentes de la máquina objeto. Analizadores de flujo Suministran la información necesaria para realizar las optimizaciones de código. Entorno de desarrollo integrado Conjunto de aplicaciones que permiten la escritura de los procesadores: editor, compilador, depurador, 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. Actualmente es muy común editores con sintaxis resaltada con colores, Conversores de formato Utilizan las técnicas de los traductores para convertir una descripción de ficheros en otra. 14
15 Preprocesadores Toman como entrada un conjunto de instrucciones y generan código en un lenguaje de alto o medio nivel. 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. Generadores de código Permiten desarrollar aplicaciones a partir de unas especificaciones muy compactas, que pueden ser tratadas como un lenguaje de aplicación. Un caso particular son los generadores de pantallas. Verificación estática de programas Leen el código fuente y lo analizan para descubrir errores potenciales sin ejecutar dicho programa. 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, o para una determinada impresora. Pueden estar especializados para fórmulas matemáticas, químicas, música, etc. Intérpretes de comandos de un sistema operativo Reciben órdenes del sistema operativo, las analizan y las ejecutan ( Ej.: COMMAND.COM de MS- DOS). Construcción de entornos operativos Caso particular del anterior en el cual las órdenes suelen recibirse de forma gráfica ( Ej. WINDOWS). Intérpretes para consultar base de datos: reciben las consultas, las analizan y las ejecutan (EJ.: SQL). Compiladores de silicio Utilizan las mismas técnicas de construcción de compiladores e intérpretes pero implantadas en hardware. Procesamiento de lenguajes naturales Aplican las técnicas de construcción de traductores a los lenguajes naturales, permitiendo el análisis comprensión y traducción (inteligencia artificial). 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., escrita en la notación que entiende directamente un ordenador binario o hexadecimal. Se basa en la arquitectura de la máquina de Von Neumann. Lenguaje ensamblador Representa una versión simbólica de un lenguaje máquina. Cada código de operación se indica por un código simbólico: ADD, MUL...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. Almacenan variables en registros del procesador.. Características de lenguajes de alto nivel: Manejo de estructuras de control, Manejo de datos Lenguaje de alto nivel Características superiores a los lenguajes ensambladores No tienen acceso directo al sistema, estructuras de pueden ser datos complejas, utilización de bloques, procedimientos o subrutinas, (smalltalk, C++, Ada, Java, turbo Pascal ) Lenguajes orientados a problemas concretos Resolución de problemas en un campo específico (SQL, XBASE, PostScript, SPSS) 15
16 Según la forma de las instrucciones (características intrínsecas al lenguaje: Lenguajes imperativos o procedurales Orientados a instrucciones o sentencias, hacen uso masivo de variables, incorporación de mecanismos de bloques. Están Influidos por la máquina de Von Neumann. Programación estructurada ( Pascal, C++, COBOL..). Lenguajes declarativos: lógicos y funcionales Lenguajes de muy alto nivel con notación muy próxima al problema real del algoritmo que resuelven. - Funcionales: sus construcciones son llamadas a funciones. No hay instrucciones. Todo el programa es una función y todas las operaciones son funciones más simples. 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). - Lógicos: instrucciones se forman siguiendo un tipo de lógica, maneja relaciones (predicados) entre objetos (datos). La relaciones se especifican con reglas y hechos. La ejecución consiste en demostraciones de hechos sobre las relaciones mediante preguntas (PROLOG). Lenguajes concurrentes: Dos o más tareas simultaneas o paralelas. Pueden ser una característica propia del lenguaje o el resultado de ampliar las instrucciones de un lenguaje no concurrente: Ada, Concurrent C, concurrent Pascal. Lenguajes orientados a objetos: Basados en la teoría de los objetos que permitiendo: la encapsulación, herencia y polimorfismo ( java, C++, smalltalk ). 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). No manejan recursividad ni estructuras dinámicas de datos en los años 60. (FORTRAN, COBOL). Tercera generación: Programación estructurada en los años 70. Uso de subprogramas o módulos, variables locales, recursividad y estructuras dinámicas.(algol, PL/I, PASCAL, MODULA). Cuarta generación: De muy alto nivel para tareas específicas a primero de los años 80. Base de datos, 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, Delphi) Generación Internet: Necesidad de manejar aplicaciones en diferentes plataformas dentro de internet (Java, XMN, HTML, VRML) Otros lenguajes En informática también se utilizan otros lenguajes que no son de programación y que tienen otras aplicaciones, como pueden ser para describir formatos de texto, gráficos, de sonido, etc. En cualquier caso, todos los lenguajes no naturales son formales, surgen primero las reglas gramaticales y se ajustan con todo rigor a ellas. 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, True Page... De formatos gráficos no vectoriales: TIFF, GIF, PCX, BMP, JPEG... De formatos gráficos vectoriales: DXF, CGM... De formatos de bases de datos: DBF, DBT, MDX... De formatos de texto: RTF, ASCII, Word, WordPerfect... De formatos de archivos de sonido: WAV, MIDI, MP3... De formatos de archivos de vídeo: AVI, MOV,... De formatos de ayuda: HLP de Windows, HLP de Turbo Visión... De gestión electrónica de documentos e hipertexto: pdf de Acrobat, HTML, XML... 16
17 TEMA 2 LENGUAJES FORMALES Conceptos básicos sobre palabras. Lenguaje formal - Un lenguaje formal es un conjunto de palabras definidas sobre un alfabeto. Alfabeto - Se llama alfabeto a un conjunto finito, no vacío de símbolos. Se representan por (Σ). Un alfabeto se define por la enumeración de los símbolos que lo contiene. Ejemplos de alfabetos: Σ 1 ={a,b}, Σ 2 ={0,1}, Σ morse ={.-,.--,..}, Σ ASCII ={A, %, } Σ HTML ={<HTML>, <BODY>, A..Z, a..z,.}, Σ=Conjunto de palabras de un diccionario Si Σ 1 y Σ 2 son alfabetos, Σ 1 Σ 2 es un nuevo alfabeto. Si Σ 1 y Σ 2 son alfabetos, Σ 1 Σ 2 es un nuevo alfabeto, siempre que Σ 1 Σ 2 φ Símbolo - Un símbolo es un componente mínimo e indivisible que puede formar parte de una palabra. Un símbolo es una entidad abstracta que no tiene definición. Los símbolos pueden estar formados por más de un componente. a Σ 1,,. Σ morse, <HTML> Σ ΗΤΜΛ Cadena, palabra - Una palabra es a una secuencia finita de símbolos de un alfabeto. Las palabras se representan por los últimos símbolos del alfabeto castellano en minúsculas x.y,z,.. x( 1 )=abab a Σ, a es una palabra definida sobre Σ. Cualquier programa (p.e en Pascal) será una cadena sobre el alfabeto de caracteres ASCII Longitud de una palabra x - La longitud de una palabra es el conjunto de símbolos que tiene esa palabra, se representa por x x =aaaabb ; x = 6 Palabra vacía - es una palabra que no tiene símbolos, se representa por ε (épsilon), y su longitud es 0, x=ε ; x =0. Un alfabeto Σ, nunca tiene el símbolo vacío ε. Σ = {a, b}, Σ*={ε, a, b, ab, ba, aa, bb, aaa...}, Σ Σ* Sea el alfabeto Σ, Σ* es el conjunto de todas las palabras que se pueden formar con Σ. Sobre cualquier alfabeto Σ, Σ* es infinito. Σ* se denomina lenguaje universal definido sobre Σ. Subpalabra - Sea una palabra x definida sobre Σ; subpalabra de x es una nueva palabra y, definida sobre el mismo alfabeto, formada por símbolos de x entrescados de forma consecutiva de ésta. Sean x, y, z, v Σ*, y es subpalabra de x si z, v Σ* x = v y z Sea x=aab, donde Σ={a, b}, subpalabras de (x) = {ε, a, aa, b, ab, aab} Subpalabra propia - x es una subpalabra propia de y existen z,v siendo alguna de ellas no vacía tales que vxz=y Prefijo de una palabra, es una subpalabra entresacada desde el inicio de dicha palabra. Sean x, y, z Σ*, y es prefijo de x si z Σ* x = y z Sea x=aab, donde Σ={a, b}, prefijos(x) = {ε, a, aa, aab} Prefijo propio - y es prefijo propio de x si x =y z, si z Σ +, z ε x = y z Sufijo de una palabra, es una subpalabra entresacada desde el final de dicha palabra. Sean x, y, z Σ*, y es sufijo de x si z Σ* x =z y Sea x=aab, donde Σ={a, b}, sufijo de (x) = {ε, b, ab, aab} Sufijo propio - y es sufijo propio de x si z Σ +, z ε x = z.y Cualquier palabra x incluyendo la palabra vacía, son prefijo y sufijo de sí misma Subsecuencia de una palabra x, es una combinación de símbolos de dicha palabra en orden, pero no tienen que ser consecutivos. Sea x=abab, donde Σ={a, b}, subsecuencias de (x) = {ε, bb, ab,..} 17
18 2.2.- Operaciones con palabras. Al estar los lenguajes formales compuestos de palabras, las operaciones de lenguajes formales, serán operaciones con palabras. Las operaciones a destacar con palabras son las siguientes: Concatenación de palabras (.) Sean dos palabras x,y definidas sobre el mismo alfabeto Σ, la concatenación de ambas x.y (xy) es una nueva palabra z, formada por los símbolos x seguidos de los símbolos de y. x ( ).y ( ) =x ( ) y ( ) =z ( ) x=ab, y=aa ; xy=z=abaa ; x + y = z Propiedades de la concatenación x, y Σ*, la operación concatenación (.) cumple las siguientes propiedades: Operación cerrada x.y =z P. asociativa x(yz) = (xy)z E. neutro xε = εx=x Potencia de una palabra Dado que la concatenación permite la propiedad asociativa, una palabra x, se puede concatenar consigo misma un número determinado n de veces, dando lugar a la potencia n-ésima de esa palabra x n x=aab, x 0 =ε, x 3 =aabaabaab Propiedades de la potencia x Σ* x n Σ* x n =n x x n = Palabra inversa (refleja, transpuesta) Dada una palabra x definida sobre un alfabeto Σ, su inversa o refleja x -1 (x i ), es una nueva palabra definida sobre el mismo alfabeto, formada por los mismos símbolos que tiene x pero situados en orden inverso. x=aab, x -1 =baa ε si n=0 x n-1 x si n>0 Propiedades de la inversión x Σ* x -1 Σ* ε si x= ε x -1 = y -1 a si x=ay x = x -1 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 Conceptos básicos de lenguajes formales Un lenguaje formal L definido sobre un alfabeto, es cualquier subconjunto de *, conjunto de palabras con una significación propia (lógica común) y, tiene una definición formalizada L( ) * L( )={x * x cumple con la definición formal del lenguaje} 18
19 Ejemplos de lenguajes formales definidos sobre el alfabetos Σ = {a,b}: L 1 = {}=, lenguaje vacío Cardinal ({})=0 L 2 = { ε }, lenguaje no vacío Cardinal ({ε })=1 L 3 = {a, b}, el lenguaje coincide con el alfabeto L 4 = {a, ab, ε} el lenguaje contiene la palabra vacía L 5 = {a n, n 0}= {a 0, a 1, a 2, }={ ε, a, aa, } lenguaje formado por palabras que contienen cero o más aes, definido por una notación matemática L 6 ={a n b m n, m 0}={a 0 b 0, a 0 b 1,.}= {εε, εb, }={ ε, b, } lenguaje formado por palabras formadas por (0 o más) aes seguidas de (0 o más) bes, definido por una notación matemática L 7 ={palabras formadas por un número impar de aes}={ a, ba, ab, bab, aaba, } Σ*=lenguaje universal de Σ, o cierre de Σ. Lenguaje, formado de todas las palabras que se pueden construir con los símbolos {a,b} sin limitación de orden y longitud, incluyendo la palabra vacía Operaciones con lenguajes. Al ser un lenguaje formal un conjunto de palabras, se puede aplicar toda la teoría de conjuntos sobre ellos. En éste texto vamos a estudiar las siguientes operaciones con lenguajes formales: Sean L 1 y L 2, lenguajes definidos sobre Σ, L 1, L 2 Σ* L 1 ={ε, a, aa, aab}, L 2 ={b, bb, aa, aabb} - Alternativa o unión de lenguajes Dado dos lenguajes L 1 y L 2 definidos sobre un mismo alfabeto Σ, la unión de ambos es un nuevo lenguaje L 3, definido sobre el mismo alfabeto Σ y formado por las palabras de L 1 y L 2 L 1 L 2 = L 1 L 2 = {x Σ * x L 1 x L 2 } L 1 ={ε, a, aa, aab}, L 2 ={b, bb, aa, aabb} L 1 L 2 ={ ε, a, aa, aab, b, bb, aabb} Propiedades que cumple la operación ( ) unión de lenguajes L Σ* se cumplen las siguientes propiedades: Operación cerrada L 1 L 2 = L 3 P. idempotente L 1 L 1 = L 1 P. conmutativa L 1 L 2 = L 2 L 1 P. asociativa L 1 (L 2 L 3 ) = (L 1 L 2 ) L 3 E. neutro L 1 φ = L 1 - Concatenación o yuxtaposición Dado dos lenguajes L 1 y L 2 definidos sobre un mismo alfabeto Σ, la concatenación de ambos es un nuevo lenguaje L 3, definido sobre el mismo alfabeto Σ y formado por las palabras de L 1 concatenadas con las palabras de L 2 L 1 L 2 =L 1 L 2 = { xy Σ* x L 1 y L 2 } L 1 ={ε, a, aa, aab}, L 2 ={b, bb, aa, aabb} L 1. L 2 ={ εb, εbb, εaa, εaabb, ab, abb, aaa, aaabb, aabb, aabbb, aabaa, aabaabb } Propiedades que cumple la operación (.) concatenación de lenguajes L Σ* se cumplen las siguientes propiedades: Operación cerrada L 1 L 2 = L 3 P. asociativa L 1 (L 2 L 3 ) = (L 1 L 2 )L 3 E. neutro L 1. ε = ε.l 1 =L 1 19
20 La operación concatenación de lenguajes formales cumple con la propiedad distributiva con respecto a la operación unión P. distributiva L 1 (L 2 L 3 ) = (L 1 L 2 ( L 1 L 3 ) (L 1 L 2 )L 3 = (L 1 L 3 ) ( L 2 L 3 ) - Potencia de lenguajes Dado que la concatenación de lenguajes formales permite la propiedad asociativa, un lenguaje formal L 1 se puede concatenar consigo mismo, un número determinado n de veces, dando lugar a la potencia n-ésima de ese lenguaje L n L n =LLL.. n veces L L 1 ={ε,a,aa,aab} 2 L 1 L 1 =L 1 ={εε, εa, εaa, εaab, aε, aa, aaa, aaab, aaε, aaa, aaaa, aaaab, aabε, aaba, aabaa, aabaab} Propiedades de la potencia de lenguajes L Σ* L n Σ* Operación cerrada L Σ *, L n Σ * L i.l = L.L i =L i+1 Cualquier lenguaje L 0 = ε ε si n=0 L n = L n-1 L si n>0 En la definición anterior existe una incongruencia para el lenguaje L= φ, φ 0 = ε - L* (L estrella, cierre de Kleene) L* es el conjunto de palabras que se pueden formar al concatenar en cualquier orden y cantidad las palabras de L, incluyendo la palabra vacía. L*=L 0 L 1..L n = U L i i=0 Sea L 1 ={ε, a, aa, aab} L 1 * ={ ε } {ε,a,aa,aab} {εε, εa, εaa, εaab, aε, aa, aaa, aaab, aaε, aaa, aaaa, aaaab, aabε, aaba, aabaa, aabaab} {.} - L + (L mas, 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 L + =L 1 L 2..L n =L + = U L i Sea L 1 ={ε, a, aa, aab} i=1 L + 1 ={ε,a,aa,aab} {εε, εa, εaa, εaab, aε, aa, aaa, aaab, aaε, aaa, aaaa, aaaab, aabε, aaba, aabaa, aabaab} {.} L*= L + L 0 ; L*= L + {ε} ; L + = L* sii ε L ; L + =L*.L - Σ * ( sigma estrella, lenguaje universal sobre Σ) Σ* es el conjunto de palabras que se pueden formar al concatenar en cualquier orden y cantidad los símbolos de Σ, incluyendo la palabra vacía. Σ*= Σ 0 Σ 1 Σ 2.= U Σ i i=0 Σ*=L* sii Σ L ; Σ*=L + sii Σ L y ε L 20
21 - Σ + (sigma mas) Σ + es el conjunto de palabras que se pueden formar al concatenar en cualquier orden y cantidad los símbolos de Σ, Σ + = Σ 1 Σ 2.= U Σ i Σ + =L + sii Σ L y ε L ; Σ + L* ; Σ + Σ* - Intersección de lenguajes Dado dos lenguajes L 1 y L 2 definidos sobre un mismo alfabeto Σ, la intersección de ambos L 1 L 2 es un nuevo lenguaje L 3 definido sobre el mismo alfabeto Σ y formado por las palabras que pertenecen a L 1 y a L 2 L 1 L 2 = {x * x L 1 x L 2 } L 1 ={ε, a, aa, aab}, L 2 ={b, bb, aa, aabb} L 1 L 2 ={aa} Propiedades de la operación (.) intersección de lenguajes L Σ* se cumplen las siguientes propiedades: Operación cerrada L 1 L 2 = L 3 P. idempotente L 1 L 1 = L 1 P. conmutativa L 1 L 2 = L 2 L 1 P. asociativa L 1 (L 2 L 3 ) = (L 1 L 2 ) L 3 E. neutro L 1 Σ *= L 1 P. distributiva L 1 (L 2 L 3 ) = (L 1 L 2 ) (L 1 L 3 ) L 1 (L 2 L 3 ) = (L 1 L 2 ) (L 1 L 3 ) - Sublenguaje de otro Sean dos lenguajes definidos sobre un alfabeto: L 1 ={ε, a, aa, aab}, L 2 ={ ε, a, aa, aab, b, bb, aabb} L 1 es sublenguaje de L 2 si L 1 L 2 Todo lenguaje L 1 definido por un alfabeto Σ, es un sublenguaje del lenguaje universal Σ *, L 1 Σ * L 1= {ε, a, aa, aab} { ε, a, b, aa, bb, ab, ba, aab,..} Dos lenguajes son iguales si todos sus elementos son iguales - Diferencia de lenguajes formales i=0 Dado dos lenguajes L 1 y L 2 definidos sobre un mismo alfabeto Σ, la diferencia de ambos L 1 -L 2, es un nuevo lenguaje L 3 definido sobre el mismo alfabeto Σ y formado por las palabras que pertenecen a L 1 y no pertenecen a L 2 L 1 -L 2 = {x * x L 1 x L 2 } L 1 ={ε, a, aa, aab}, L 2 ={b, bb, aa, aabb} L 1 -L 2= {ε, a, aab} Propiedades de la operación (-) diferencia de lenguajes L Σ* se cumplen las siguientes propiedades: Operación cerrada L 1 - L 2 = L 3 P. idempotente L 1 - L 1 = L 1 E. neutro L 1 - φ= L 1 21
22 - Complemento de un lenguaje: Dado un lenguaje L definido sobre un alfabeto Σ, su complementario L, es un nuevo lenguaje formal definido sobre el mismo alfabeto, compuesto de todas las palabras que se pueden formar con los símbolos de Σ ( * lenguaje universal) menos las palabras del propio L, L= * - L L = { x * x * x L} Propiedades: L Σ* se cumplen las siguientes propiedades: Operación cerrada L Σ* ; L Σ* L = * - L L = L L L = φ L U L = * - Otras propiedades: leyes de Morgan L 1 L 2 = L 1 U L 2 L 1 U L 2 = L 1 L 2 - Lenguaje inverso Dado un lenguaje L definido sobre el alfabeto Σ, su inverso L -1 el mismo alfabeto Σ y, formado por las palabras inversas de L L -1 = { x -1 Σ * x L } L ={ε, a, aba, aab}, L -1 ={ ε, a, aba, baa } es un nuevo lenguaje definido sobre Mecanismos formales Un lenguaje formal se define por las propiedades que cumplen las palabras que lo componen. Las propiedades que cumplen las palabras del lenguaje deben permitir representarlas de una manera formalizada. Si el lenguaje es finito, para su definición basta con su enumeración, conocer su representación L= { a, aa, aaa} lenguaje cuyas palabras están formadas por: una, dos o tres aes Si es infinito no puede ser enumerado, habrá que buscar un medio finito y preciso para su definición. Pero ocurre que no todos los lenguajes formales pueden definirse de una forma finita y precisa L={ε, a,,aa,..ab, aab, b, bb, abb..} = L={a n b m n,m 0} Tiene una definición en notación matemática, pero dicha definición no aporta información para su tratamiento L= { a, abbaa, aabab, ababa, abbaa, aaabb, aaaaabbbb,.} {palabras que tienen un número impar de aes, empiezan por el símbolo a y tienen una a más que bes} La definición no es precisa, con las palabras anteriormente representadas, y dicha definición no aporta información para su tratamiento Para evitar los anteriores problemas de indefinición y tratamiento, se crearon los mecanismos formales: expresiones regulares, autómatas y gramáticas: Las expresiones regulares son mecanismos que sirven para describir un tipo de lenguaje formal (lenguajes regulares). Los autómatas son mecanismos que permiten especificar de manera finita y precisa cualquier lenguaje formal, mecanismos que permiten simular el reconocimiento del lenguaje para dicha especificación 22
23 Las gramáticas son mecanismos que permiten especificar de manera finita y precisa cualquier lenguaje formal, mecanismos permiten simular la generación de las palabras del lenguaje especificado. En este tema se ha hecho referencia a la definición lenguaje formal para diferenciarlo de lenguaje natural. En general, un lenguaje natural es aquel que ha evolucionado con el paso del tiempo para fines de la comunicación humana, evolucionan sin tener en cuenta reglas gramaticales estrictas que puede resolver situaciones ambiguas. Mientras que los lenguajes formales, al contrario que los naturales, están definidos por reglas de producción preestablecidas y se ajustan con todo rigor y formalidad a ellas. Ejercicios sobre lenguajes formales 1 - Alfabeto de entrada para los lenguajes- java, C, Pascal 2 - En una palabra de longitud n cuantas subpalabras hay en las definiciones: prefijos, sufijos, prefijos propios,.. 3- Demostrar que (xy) -1 = y -1.x -1 x,y Σ*. 4 - Dados los siguientes lenguajes formales definidos sobre el alfabeto = {a, b}: L 0 ={} L 1 ={ε} L 2 ={a} L 3 ={a,b} L 4 ={(ab) n 0<= n < 2 } L 5 ={a m b l m,l >= 0 } L 6 ={a n b n n>=0 } L 7 ={lenguaje formado por las palabras que tienen un número impar de aes} Determinar para cada uno de ellos L 0, L 3 y L * 5- Sean las siguientes operaciones con los anteriores lenguajes formales: L n 0 L n 1, L n 0 L n 1, L n 3 L n n 1, L 3 L n 1, L n 3 L n 0, L n 3 L n 0, L n 7 L n 5, L n n 7 L 5, L n 0, L n, n 3, L 7 1. Determinar qué lenguajes definen suponiendo que n = Determinar qué lenguajes definen suponiendo que n = 3 3. Determinar qué lenguajes definen suponiendo que n = * 6- Sea un alfabeto cualquiera y L un lenguaje cualquiera definido sobre el alfabeto anterior. Para cada una de las siguientes igualdades, justificar si siempre son ciertas o no. L*=L + *=L + + =L + L + =L*-ε + = *- ε *=( *) -1 Φ *= ε=φ + L = * - L = L * -L L 1 -L 2 = L 1 L 2 = L 1 L 2 (L*)*=(L + )*=(L*) + =L*=(L + ) + (L * ) I =(L I ) * L 1 - ( *-L 1 )=L 1 L 1 - *-L 1 = Φ L 1 -L 2 = L 1 L 2 = L 1 L Sea L 1 un lenguaje definido sobre un alfabeto Σ ={a,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: a, aaba, aaabbaba, babbabbab Ejemplos no válidos: ε, aabbba, bb, abbabbaba Sea L 2 un lenguaje definido sobre un alfabeto Σ ={a,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. Ejemplos válidos: ε, aa, aaaba, aaabbaaba, baabbabbab, bb Ejemplos no válidos: a, aabbbaa, aabbabbaba Justificar si se cumplen o no las siguientes igualdades: L 1 L 2 =Σ*, L 1.L 2 =L 2.L 1, L 1 *=Σ*, L 1 =L 2 complementario 23
24 2.6.- Gramáticas Formales Una gramática es un mecanismo formal generador de lenguajes formales, que especifica de una manera finita y precisa el conjunto de palabras que componen el lenguaje al que se quiere definir. 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. - Definición formal Una gramática es un mecanismo formal compuesto por cuatro elementos G = (Σ, N, S, P) en donde: Σ - es el alfabeto terminal, alfabeto de las palabras del lenguaje que genera la gramática N - es el alfabeto no terminal, alfabeto auxiliar que determina la complejidad de la estructura de las palabras a generar por 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 - 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. P: { α 1 β 1, α 2 β 2..}, α i ( N Σ)* N ( N Σ)*, β i ( N Σ)* Ejemplo Sea un lenguaje formal compuesto por las palabras que se ajustan a la siguiente definición: L(Σ )={a n b m n, m 0}={a 0 b 0, a 0 b 1, a 1 b 0, a 1 b 1,. Una gramática que genera dicho lenguaje es la siguiente: G = (Σ ={a,b}, N={S,A,B},S, P) P: S AB A Aa ε B Bb ε - Derivación en el entorno de una gramática Derivación en el entorno de una gramática - es un proceso enfocado en la obtención de las palabras del lenguaje que genera dicha gramática Sea una gramática G = (Σ, N, S, P) P: { α 1 β 1, α 2 β 2,.. } α (N Σ)*N( N Σ)*, β ( N Σ)* L(G)={ x Σ* xδg ( x deriva de G) } - Derivación directa (derivación de un paso) Consiste en aplicar sobre una palabra ω ( N Σ)* N ( N Σ)* obtenida de la gramática G, una producción α 1 β 1 de la propia gramática G. Sea la palabra ω 1 = δ 1 α 1 δ 2 ; δ 1, δ 2 ( N Σ)* y α 1 (N Σ)* N (N Σ)* Aplicando la producción α 1 β 1 de la gramática G sobre dicha palabra ω 1, la palabra ω 1 se transforma en δ 1 β 1 δ 2 = ω 2 en donde δ 1, β 1, δ 2 ( N Σ)* Es decir δ 1 α 1 δ 2 δ 1 β 1 δ 2, ω 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), o bien que la palabra ω 2 deriva de la palabra ω 1. En un proceso de derivación de un paso o producción directa, es un proceso no determinista que sólo se aplica a una producción, aunque dicha producción u otras de la gramática se puedan aplicar sobre la misma palabra ω. Una palabra se deriva o se produce así misma sin aplicar el proceso de derivación, se dice que se deriva en cero pasos. 24
25 Relación de derivación Sean las palabras ω i, ω m (N Σ)* N (N Σ)* se dice que están en relación de derivación en la gramática G, si la palabra (ω i produce la palabra ω m ) o ω m deriva de la palabra ω i en cero o más derivaciones directas. ω i ω j ; ω j ω k ; ω k ω m La representación de un proceso de cero o más derivaciones se representa de la siguiente forma: ω i *ω m, de la misma manera para representar un proceso de una o más derivaciones es la siguiente: ω i + ω m - Lenguaje generado por una gramática Conjunto de palabras definidas sobre el alfabeto Σ, que se obtienen desde el símbolo inicial en un proceso de derivación de cero o más pasos. S α 1 α 2 α 3. x = x Σ* L(G)={x x Σ*, S *x} Lenguaje generado por la siguiente gramática: G = (Σ ={a, b}, N={S, A, B}, S, P) P: S AB A Aa ε B Bb ε AaaB AaB ab a n b m n 1, m 0 Aa AaBb Bb S AB B ε. b m m 0 L(G)= {a n b m n 0, m 0} AabB AbB bb a n b m n 0, m 1 AbBb Ab A Aa... a n n 0 ε Forma sentencial cualquier palabra obtenida de un proceso de derivación; en el anterior ejemplo cualquier palabra derivada desde S: S, AB, ε..aaabb, son formas sentenciales Si la forma sentencial está compuesta únicamente por símbolos terminales de la gramática, se llama sentencia. En el ejemplo anterior son sentencias: ε, a, b, aa,..aaabb A partir de la anterior definición, se puede decir que, 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. - Gramáticas equivalentes Una gramática genera un solo lenguaje, pero un lenguaje puede ser generados por muchas gramáticas. Dos o más gramáticas se dice que son equivalentes, si generan el mismo lenguaje. Ejemplo: G 1 = (Σ ={a, b}, N={S, A, B}, S, P) P: S AB A Aa ε B Bb ε 25
26 G 2 = (Σ ={a, b}, N={S, A, B}, S, P) P: S a A b B ε A A a ε b B B B b ε Las gramáticas G 1 y G 2 son equivalentes. Ambas generan el mismo lenguaje: L={a n b m n,m 0}={a 0 b 0, a 0 b 1, a 1 b 0, a 1 b 1,..} Clasificación de las gramáticas Noam Chomsky en 1959 clasificó las gramáticas en cuatro familias (Jerarquía de Chomsky) de gramáticas, que difieren, atendiendo a la forma que pueden tener sus reglas de producción. Sea una gramática G = (Σ, N, S, P) P: { α β,..} α ( N Σ)* N ( N Σ)*, β ( N Σ)* clasificaremos las gramáticas, en los siguientes cuatro tipos: - Gramáticas de Tipo 3 (Gramáticas regulares). Pueden ser a su vez, de dos tipos: Lineales por la derecha. Todas sus producciones son de la forma: A ab A a A ε en donde A, B N, a Σ Lineales por la izquierda. Todas sus producciones son de la forma: A Ba A a A ε en donde A, B N, a Σ Los lenguajes generados por estas gramáticas se llaman lenguajes regulares o lenguajes de tipo 3 y, todos forman la clase de lenguajes L3. * Existen otras definiciones sobre las gramáticas de tipo 3, entre otras, como aquellas que permiten las producciones de la forma: A ab, 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. - Gramáticas de Tipo 2 (Gramáticas libres del contexto). Las producciones son de la forma: A α donde A N, α ( N Σ)* Los lenguajes generados por este tipo de gramáticas se llaman lenguajes libres del contexto o lenguajes de tipo 2 y, todos forman la clase de lenguajes L2. - Gramáticas de Tipo 1 (Gramáticas sensibles al contexto). Las producciones son de la forma: α β en donde α ( N Σ)* N ( N Σ)*, β ( 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. El sentido de estas reglas de producción δaγ δβγ es el de especificar que el símbolo A puede ser reemplazado por β, en una derivación directa sólo cuando A aparezca en el contexto" de δaγ. 26
27 Las producciones de este tipo de gramáticas 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ática es no contráctil. Los lenguajes generados por las gramáticas de tipo 1 se llaman lenguajes sensibles al contexto y, forman el conjunto de lenguajes de tipo L1 - Gramáticas de Tipo 0 (Gramáticas con estructura de frase, no restringidas) Son las gramáticas más generales, que por ello también se llaman gramáticas sin restricciones. Esto quiere decir que las producciones pueden ser de cualquier tipo permitido, es decir, de la forma: α β, α є ( N Σ)*N ( N Σ)* β є ( N Σ)* Los lenguajes generados por estas gramáticas son los lenguajes con estructura de frase, que se agrupan en la clase de lenguajes de tipo de L0. Estos lenguajes también se conocen como lenguajes recursivamente enumerables. Relación de inclusión de las gramáticas: Tipo 3 Tipo 2 Tipo 1 Tipo 0 Tipo 0 Tipo 1 Tipo 2 Tipo Determinación del tipo de una gramática Para determinar el tipo de una gramática G, basta por equiparar las producciones de dicha gramática a las producciones de las familias de los tipos de gramáticas, empezando por las producciones de tipo superior, de no ser así se baja de tipo hasta encontrar un tipo que coincida con la dada. Ejemplo, dada la siguiente gramática determinar el tipo de la misma. G = (Σ ={a,b}, N={S,A,B},S, P) P: S AB A Aa ε B Bb ε La producción S AB tipo 3 la gramática G no es de tipo 3 La producción S AB tipo 3 pero si a las gramáticas de tipo 2, por lo que la gramática G es una gramática de tipo 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. Dado que un lenguaje, puede ser generado por varias gramáticas, gramáticas equivalentes que pueden ser de tipo diferente, existe un problema a la hora de relacionar lenguajes con gramáticas, que tipo de gramática asociar al lenguaje. Para solucionar la anterior indecisión, 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,1,2,3), si existe una gramática con un tipo N que lo genera y no otra de un tipo N superior. Sea el lenguaje L(Σ)={a n b m n, m 0}={a 0 b 0, a 0 b 1, a 1 b 0, a 1 b 1,.}, lenguaje que puede ser generado entre otras por las gramáticas G 1 y G 2 Ejemplo: G 1 = (Σ ={a, b}, N={S, A, B}, S, P) P: S AB, A Aa ε, B Bb ε G 1 es una gramática de tipo 2 27
28 G 2 = (Σ ={a, b}, N={S, A, B}, S, P) P: S aa bb ε, A Aa ε bb, B Bb ε G 2 es una gramática de tipo 3 Para determinar el tipo al que pertenece el lenguaje, será el tipo de la gramática con el tipo superior que lo genere, para este caso el tipo del lenguaje L(Σ)={a n b m n, m 0 } será de Tipo 3 (no existe una gramática de un tipo superior que lo genere). Sea el lenguaje L(Σ )={a n b n n 0}={a 0 b 0, a 1 b 1, a 2 b 2, a 3 b 3,. G = (Σ ={a,b}, N={S,A,B},S, P) P: S asb ε El lenguaje anterior es de tipo 2, no existe una gramática de un tipo superior que lo genere. El conjunto de los lenguajes de tipo 3 (regulares) definidos sobre un alfabeto Σ, está incluido propiamente en el conjunto de los lenguajes tipo 2 ( libres de contexto) y, éste a su vez, está incluido propiamente en el conjunto de los lenguajes de tipo 1 (sensibles al contexto), que lógicamente está incluido en el conjunto de lenguajes tipo 0 (con estructura de frase). Relación de inclusión de los tipos de lenguajes: L3 L2 L1 L0 L 0 L 1 L 2 L 3 Ejercicios de gramáticas 1- Obtener una gramática para cada uno de los siguientes lenguajes: a) = {a, b, c}, L = {a n b m c n n, m >= 1} b) = {a, b, c}, L = {a n b m c n+2m n >=0, m >= 1} c) = {a, b, c}, L = {a n b n+m c m n >= 1, m >= 0} d) = {a, b}, L = {a n b m n >= m >= 1} e) = {a, b}, L = {a n b m n > m >= 0} f) = {a, b, c}, L = {a m b n c k m > n + k ; n, k >=0} g) = {a, b}, L = { a n b m m <= n <= 2m ; n, m >=0} h) = {a, b}, L = { a n b m n <>m ; n, m >0} 2- Construir una gramática que especifique el siguiente lenguaje: L = { w {0, 1, 2} * w contiene exactamente dos o tres símbolos 0 en cualquier posición}. Sería posible obtener una gramática regular o de tipo 3? 3- Para las gramáticas que se proponen a continuación, determinar el tipo de las mismas y el lenguaje generado. a) S 0S A A 0B 0 B 1A b) S aba bbb A bc B a C cs ε 28
29 4- Sea la siguiente gramática definida sobre el alfabeto = {a, +, = } S BSa asa a+a=aa Ba ab B+ +a Obtener el lenguaje generado por la misma 5 - Dado el alfabeto Σ= {a, +, = } y el siguiente lenguaje: L={a n +a m =a n+m n, m > 0}, construir una gramática de tipo 2 que genere dicho lenguaje. 6- Dado el alfabeto Σ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +,-,*, / }, sea el lenguaje L formado por todas las expresiones aritméticas que se pueden formar con los símbolos de este alfabeto, donde 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 son operandos y, +,-,*, / son los operadores binarios de suma, resta, producto y división respectivamente. Por ejemplo, pertenecen a este lenguaje las palabras 1, 1+0 y 5+3*8/7, y no pertenecen: 11, +1 ó 1*/2. Determinar el tipo del lenguaje L, justificándolo mediante un mecanismo formal del tipo correspondiente. 7- Sea el lenguaje de sumas de números naturales sobre Σ = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + }. Ejemplos de palabras del lenguaje: ó 35 Ejemplos de palabras no válidas: 34+ ó Representar mediante una gramática de tipo 2 los siguientes lenguajes: a) Sea L 1 el lenguaje de sumas en el que los números naturales no pueden tener ceros a la izquierda. El número 0 se representará por un único cero, nunca por una secuencia de ceros. i. Ejemplo:10+0 ii. Ejemplo de palabra no válida: b) Sea L 2 el lenguaje de sumas en el que los números naturales pueden empezar por 0, aunque no sea el número 0, 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). i. Ejemplo: ii. Ejemplos de palabras no válidas: , 1 c) Sea L 3 el lenguaje de sumas en el que los números naturales pueden empezar por 0, aunque no sea el número 0, pero en el que se cumple la condición de que al menos dos números tienen la misma longitud. i. Ejemplo: Dado el alfabeto Σ={a,b,0,1}, sea el lenguaje L={w (0 1) v v,w pertenecen a {a,b} + y w = v }, en el que además se cumplen las siguientes restricciones: Si el dígito central es 0, w deberá empezar por a Pero si el dígito central es 1, entonces es v quien empezará por a. Ejemplos de palabras válidas: aba0bba, a0a, a0b, a1a, b1a, abb1abb Ejemplos de algunas palabras no válidas: b0a, ba0aa, a1b, ba1ba Obtener una gramática independiente del contexto que genere el lenguaje pedido, teniendo en cuenta las restricciones. 9- Con el alfabeto ={a,b,c} se define el lenguaje L = {w c n w pertenece a {a,b} +, n>0} en el que además se cumple que: si w termina en a, entonces la longitud de w es mayor o igual que n si w termina en b, entonces la longitud de w es menor o igual que n Obtener una gramática independiente del contexto que genere el lenguaje pedido, teniendo en cuenta las restricciones pedidas Dado el alfabeto Σ= {a, b} sea el lenguaje: L = { vbbw v, w {a,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, teniendo en cuenta las restricciones pedidas. 29
Lenguaje de programación. COMPILADORES Unidad I: Introducción al proceso de compilación
COMPILADORES Unidad I: Introducción al proceso de compilación Flor Prof. Flor Narciso GIDyC-Departamento de Computación LABSIULA-Escuela de Ingeniería de Sistemas Facultad de Ingeniería Universidad de
Unidad I Introducción a la programación de Sistemas. M.C. Juan Carlos Olivares Rojas
Unidad I Introducción a la programación de Sistemas M.C. Juan Carlos Olivares Rojas Agenda 1.1 Qué es y que estudia la programación de sistemas? 1.2 Herramientas desarrolladas con la teoría de programación
Lenguajes de programación
Introducción Lenguajes de programación Primera generación: lenguajes máquina Los programas se escriben en código binario 000001011010000000000000 Segunda generación: lenguajes simbólicos Cada instrucción
Compiladores e intérpretes Introducción
Introducción Profesor: Eridan Otto Introducción Perspectiva histórica Motivación Definiciones Componentes y fases de un compilador 1 Introducción Definiciónes básicas Traductor: desde un punto de vista
Procesadores de lenguaje Tema 1 Introducción a los compiladores
Procesadores de lenguaje Tema 1 Introducción a los compiladores Salvador Sánchez, Daniel Rodríguez Departamento de Ciencias de la Computación Universidad de Alcalá Resumen del tema Traductores Estructura
FASES DE UN COMPILADOR
FASES DE UN COMPILADOR PROGRAMA FUENTE analizador léxico analizador sintáctico administrador analizador semántico manejador de la tabla generador de código intermedio de errores de símbolos optimizador
Lenguajes de Programación
Lenguajes de ción Bloque 1. Complemento a Tema 1 1. Historia 2. Paradigmas de programación 3. Fases creación de un programa 4. Traducción: compilación e interpretación 1ª Generación Ordenadores sólo entienden
Introducción a la programación: Contenido. Introducción
Introducción a la programación: Contenido Introducción a la programación:... 1 Introducción... 1 1. Procesamiento automatizado de información... 1 2. Concepto de algoritmo.... 2 3. Lenguajes de programación....
Unidad 2. Introducción Lenguajes y Compiladores
Unidad 2 Introducción Lenguajes y Compiladores Principal material bibliográfico utilizado Compiladores Principios, técnicas y herramientas. Aho y Ullman. Addison Wesley. www.jorgesanchez.net www.iqcelaya.itc.mx/~vicente/programacion/tradcomp.pdf
Introducción a la programación
Introducción a la programación PROGRAMACION I Grado en Matematicas Informática Programación I - 2015/2016 Introducción 1 Introducción a la programación Computador: aparato electrónico capaz de interpretar
Un. I. Introducción a la programación de sistemas
Un. I. Introducción a la programación de sistemas 1.1 Qué es la programación de sistemas? La programación de sistemas comprende el desarrollo de aquellos programas de computadora que tienen una fuerte
COLEGIO DE ESTUDIOS DE POSGRADO DE LA CIUDAD DE MÉXICO
COLEGIO DE ESTUDIOS DE POSGRADO DE LA CIUDAD DE MÉXICO ELABORO: ALEJANDRA FUERTES FRANCISCO TEMA: LENGUAJES DE PROGRAMACIÓN INTRODUCCIÓN Un lenguaje de programación es un conjunto de instrucciones que
Lenguajes de Cuarta Generación
Lenguajes de Cuarta Generación Diana Marcela SánchezS http://www.csi.map.es/csi/metrica3/index.html www.csi.map.es/csi/metrica3/ /metrica3/index.htmlindex.html Que es un programa? La unión de una secuencia
Lenguajes y Compiladores Introducción. Compiladores 1
Facultad de Ingeniería de Sistemas Lenguajes y Introducción 1 Objetivos Conocer los fundamentos de construcción de en todas sus fases, presentando los conceptos básicos, definiciones formales, técnicas
Tema 2 Conceptos básicos de programación. Fundamentos de Informática
Tema 2 Conceptos básicos de programación Fundamentos de Informática Índice Metodología de la programación Programación estructurada 2 Pasos a seguir para el desarrollo de un programa (fases): Análisis
Evolución del software y su situación actual
Evolución del software y su situación actual El software es el conjunto de programas que permite emplear la PC, es decir, es el medio de comunicación con la computadora, el control de sus funciones y su
Unidad III: Introducción a la Programación
Unidad III: Introducción a la Programación 3.1 Características del lenguaje de programación Un lenguaje de programación es un idioma artificial diseñado para expresar procesos que pueden ser llevadas a
Concepto de compilador Intérprete Fases de un Compilador Herramientas de construcción de Compiladores
18:55 1 2 Temas Concepto de compilador Intérprete Fases de un Compilador Herramientas de construcción de Compiladores Objetivo Que el estudiante logre conocer, comprender y manejar conceptos y técnicas
CÓMO DESARROLLAR Y PROBAR PROGRAMAS?, COMPRUÉBALO!
CÓMO DESARROLLAR Y PROBAR PROGRAMAS?, COMPRUÉBALO! AUTORÍA MARÍA CATALÁ CARBONERO TEMÁTICA PROGRAMACIÓN ETAPA CICLO MEDIO Y SUPERIOR DE INFORMÁTICA Resumen A la hora de realizar un programa en cualquier
Diseño de Compiladores I. Estructura General de un Compilador
Diseño de Compiladores I Estructura General de un Compilador PROGRAMA FUENTE COMPILADOR SALIDA Mensajes de Error 2 Un compilador es un programa que traduce un programa escrito en lenguaje fuente y produce
Principios de diseño de lenguajes
Capítulo 1 Principios de diseño de lenguajes Objetivo El alumno describirá los procedimientos y gramáticas empleadas en el diseño de los lenguajes de programación. Figura 1.1: Preguntas incómodas 1.1.
Es un conjunto de palabras y símbolos que permiten al usuario generar comandos e instrucciones para que la computadora los ejecute.
Los problemas que se plantean en la vida diaria suelen ser resueltos mediante el uso de la capacidad intelectual y la habilidad manual del ser humano. La utilización de la computadora en la resolución
Introducción al Diseño de Compiladores. Año
Introducción al Diseño de Compiladores Año 2003 1 BIBLIOGRAFÍA [AHO] Compilers. Principles, Techniques, and Tools Aho, Sethi; Adisson-Wesley 1986 [TEU] Compiladores: Conceptos fundamentales. Teufel ; Addison
Introducción a la programación
Introducción a la programación Conceptos Básicos El objetivo fundamental de éste curso es enseñar a resolver problemas mediante una computadora. El programador de computadoras es antes que nada una persona
INTRODUCCIÓN A COMPILADORES Y LENGUAJES FORMALES FUNDAMENTOS DE COMPILADORES
Todos los derechos de propiedad intelectual de esta obra pertenecen en exclusiva a la Universidad Europea de Madrid, S.L.U. Queda terminantemente prohibida la reproducción, puesta a disposición del público
Tema 2 Introducción a la Programación en C.
Tema 2 Introducción a la Programación en C. Contenidos 1. Conceptos Básicos 1.1 Definiciones. 1.2 El Proceso de Desarrollo de Software. 2. Lenguajes de Programación. 2.1 Definición y Tipos de Lenguajes
INTRODUCCIÓN A LOS LENGUAJES
INTRODUCCIÓN A LOS LENGUAJES 1 Definición de lenguaje 2 Lenguajes formales 2.1 Requisitos 2.2 Aplicaciones 2.3 Especificación 2.4 Gramáticas 2.4.1 Definición y Ejemplos 2.4.2 Ambigüedad 2.4.3 Clasificación
INICIACIÓN A LA PROGRAMACIÓN 1ª parte
TEMA 4 INICIACIÓN A LA PROGRAMACIÓN 1ª parte Qué es la programación? La programación es el proceso de diseñar, codificar, depurar y mantener el código fuente de programas computacionales. En la actualidad,
Elementos para el estudio de los compiladores
Ing. Adrian Ulises Mercado Martínez Enero 30, 2015 Ing. Adrian Ulises Mercado Martínez Enero 30, 2015 1 / 51 1 Objetivo 2 Historia 3 Traductor Tipo de Traductores Compilador Intérprete Máquina Virtual
Análisis semántico Tabla de símbolos, chequeo de tipos y representaciones internas
Análisis semántico Tabla de símbolos, chequeo de tipos y representaciones internas Análisis semático c 2001 José Fortes Gálvez p.1 Análisis?... semántico? La semántica corresponde al significado asociado
TEMA 3: El proceso de compilación, del código fuente al código máquina
TEMA 3: El proceso de compilación, del código fuente al código máquina 3.1 Fase de compilación y linkado (link, montado o enlace) Un programa escrito en un lenguaje de alto nivel, no puede ser ejecutado
Metodología de Desarrollo de Programas
Metodología de Desarrollo de Programas Prof. Judith Barrios Albornoz Departamento de Computación Escuela de Ingeniería de Sistemas Facultad de Ingeniería Universidad de Los Andes Semestre A_2013 Este material
INSTITUCIÓN EDUCATIVA SAN CRISTÓBAL
INSTITUCIÓN EDUCATIVA SAN CRISTÓBAL MEDIA TÉCNICA EN PROGRAMACIÓN DE SOFTWARE TEMA: LOS LENGUAJES DE PROGRAMACIÓN Profesora: Beatriz Elena Herrera Legarda Qué es una computadora? Computadora electrónica
1. Computadores y programación
1. Computadores y programación Informática y computadora (RAE) Informática (Ciencia de la computación) Conjunto de conocimientos científicos y técnicos que hacen posible el tratamiento automático de la
Introducción a la Programación en C
Christopher Expósito-Izquierdo [email protected] Airam Expósito-Márquez [email protected] Israel López-Plata [email protected] Belén Melián-Batista [email protected] José Marcos Moreno-Vega [email protected]
Técnicas de Programación
Técnicas de Programación 2.1.- Introducción: unos conceptos previos y primeros conceptos de la API Introducción La resolución de un problema con medios informáticos implica generalmente la siguiente secuencia
Procesadores de lenguaje Tema 5 Comprobación de tipos
Procesadores de lenguaje Tema 5 Comprobación de tipos Departamento de Ciencias de la Computación Universidad de Alcalá Resumen Sistemas de tipos. Expresiones de tipo. Equivalencia de tipos. Sobrecarga,
Generación de Código Intermedio
Generación de Código Intermedio Programación II Margarita Álvarez Generación de código intermedio Con la generación de código intermedio se inicia la tarea de síntesis. Aunque un programa fuente se puede
Diseño de compiladores. Organización de memoria. Organización de memoria. Organización de memoria. Zona de código 04/05/2014 ORGANIZACIÓN DE MEMORIA
Diseño de compiladores Gestión de la memoria / Generación de código ORGANIZACIÓN DE MEMORIA Organización de memoria Depende del tipo de lenguaje (declarativos, imperativos), del compilador y del sistema
Programación de Ordenadores
Programación de Ordenadores Ingeniería Química David Pelta Depto de Ciencias de la Computación e I.A. Universidad de Granada Índice Resolución de Problemas con Ordenadores Algoritmo Metodología de la programación
TEMA 1. PROGRAMACIÓN DE UN COMPUTADOR
Tema 1. Programación de un computador TEMA 1. CIÓN DE UN COMPUTADOR 1. CONCEPTO DE 2. LENGUAJES DE CIÓN 2.1. LENGUAJE MÁQUINA 2.2. LENGUAJE ENSAMBLADOR 2.3. LENGUAJE DE ALTO NIVEL 3. ALGORITMOS. REPRESENTACIÓN
Unidad II: Análisis semántico
Unidad II: Análisis semántico Se compone de un conjunto de rutinas independientes, llamadas por los analizadores morfológico y sintáctico. El análisis semántico utiliza como entrada el árbol sintáctico
Prof. María Alejandra Quintero. Informática Año
Prof. María Alejandra Quintero Informática Año 2014-2015 Es la acción de escribir programas de computación con el objetivo de resolver un determinado problema. Implica escribir instrucciones para indicarle
Análisis semántico Tabla de símbolos, chequeo de tipos y representaciones internas
Análisis semántico Tabla de símbolos, chequeo de tipos y representaciones internas Análisis semático v1.2 c 2005 José Fortes Gálvez p.1 Análisis?... semántico? La semántica corresponde al significado asociado
Capítulo 3 CICLO DE VIDA DE UN PROGRAMA. Presentación resumen del libro: "EMPEZAR DE CERO A PROGRAMAR EN lenguaje C"
Presentación resumen del libro: "EMPEZAR DE CERO A PROGRAMAR EN lenguaje C" Autor: Carlos Javier Pes Rivas ([email protected]) Capítulo 3 CICLO DE VIDA DE UN PROGRAMA 1 OBJETIVOS Saber qué es la Ingeniería
FUNDAMENTOS DE PROGRAMACIÓN. Algoritmos y Programas
FUNDAMENTOS DE PROGRAMACIÓN Algoritmos y Programas Dato La palabra proviene del latín datum, forma del verbo dare dar, que significa Lo que es dado Representación de una información de manera adecuada
Contenidos: Definiciones:
Contenidos: Definiciones. Esquema de un ordenador. Codificación de la información. Parámetros básicos de un ordenador. Programas e instrucciones. Proceso de ejecución de una instrucción. Tipos de instrucciones.
AMBIENTES DE COMPILACION
AMBIENTES DE COMPILACION Los compiladores a menudo producen como resultado del análisis semántico, una forma de representación intermedia del código fuente. Hoy en día, es cada vez más común que, en ambientes
INTRODUCCION A LA PROGRAMACION (C.U.) PROGRAMACION (T.I.G.)
INTRODUCCION A LA PROGRAMACION (C.U.) PROGRAMACION (T.I.G.) PRESENTACION: Lic. Jaquelina Jallés Comisión 1: Lunes 8-10 OBJETIVOS: Martes 10-12 Jueves 8-12 A) Desarrollar el pensamiento lógico y estructurado
C1 INTRODUCCIÓN AL LENGUAJE C. Fundamentos de Informática Departamento de Ingeniería de Sistemas y Automática. EII. Universidad de Valladolid
C1 INTRODUCCIÓN AL LENGUAJE C Fundamentos de Informática Departamento de Ingeniería de Sistemas y Automática. EII. Universidad de Valladolid Índice 1. Lenguajes de Programación 1. Definición. 2. Niveles
Modelos de Desarrollo de Programas Y Programación Concurrente Clase N 3: 3 - Paradigmas de Programación
3 - Paradigmas de Programación En los inicios los lenguajes de programación imitaron y abstrajeron las operaciones de una computadora, lo cual trajo aparejado que el tipo de computadora para el cual fueron
Procesadores de Lenguajes. Análisis sintáctico. Gramáticas libres de contexto
Procesadores de Lenguajes Ingeniería Técnica superior de Ingeniería Informática Departamento de Lenguajes y Sistemas informáticos Análisis sintáctico Gramáticas libres de contexto Javier Vélez Reyes [email protected]
16 Análisis sintáctico I
2 Contenido Recordando la estructura de un compilador Recordando el análisis léxico l análisis sintáctico Comparación con el análisis léxico l Rol del Parser Lenguajes de programación Gramáticas structura
ALGORITMO. Podemos encontrar muchas definiciones de algoritmo en los textos de programación, todas ellas muy similares:
Nuestra herramienta mental más importante para competir con la complejidad es la abstracción. Por tanto, un problema no deberá considerarse inmediatamente en términos de instrucciones de un lenguaje, sino
2.1 METODOLOGÍA PARA LA SOLUCIÓN DE PROBLEMAS
2.1 METODOLOGÍA PARA LA SOLUCIÓN DE PROBLEMAS El proceso de resolución de un problema con una computadora conduce a la escritura de un programa y su ejecución en la misma. Aunque el proceso de diseñar
Contenido. Capítulo 1. Teoría de conjuntos. 1. Capítulo 2. Lenguaje. 39. Capítulo 3. Lenguajes formales. 55
Contenido Capítulo 1. Teoría de conjuntos. 1 1.1 Conjuntos.... 3 1.1.1 Definiciones básicas.... 3 1.1.2 Operaciones sobre conjuntos.... 6 1.1.3 Diagrama de Venn.... 7 1.1.4 Álgebra de conjuntos.... 7 1.2
Métodos para escribir algoritmos: Diagramas de Flujo y pseudocódigo
TEMA 2: CONCEPTOS BÁSICOS DE ALGORÍTMICA 1. Definición de Algoritmo 1.1. Propiedades de los Algoritmos 2. Qué es un Programa? 2.1. Cómo se construye un Programa 3. Definición y uso de herramientas para
Tema III: Introducción al lenguaje de programación
Tema III: Introducción al lenguaje de programación Semestre: U-2014 Profesora: Nelly García Mora Agenda 1. Definición 2. Programación estructurada 3. Programación Modular 4. Tipos de lenguaje de Programación
Algoritmos y Lenguajes de Programación
Introducción y horario Algoritmos y Lenguajes de Programación 543242-2 [email protected] Código: 543242-2 Carrera: Ing. Civil Electrónica Clases 7 de Marzo a 28 de Junio Horario clases Martes, 9:10 a
Lenguajes y Compiladores Aspectos Formales (Parte 1) Compiladores
Facultad de Ingeniería de Sistemas Lenguajes y Aspectos Formales (Parte 1) 1 Aspectos Formales Los compiladores traducen lenguajes que están formalmente definidos a través de reglas que permiten escribir
Lenguajes y Gramáticas
Lenguajes y Gramáticas Teoría de Lenguajes Fernando Naranjo Introduccion Se desarrollan lenguajes de programación basados en el principio de gramática formal. Se crean maquinas cada vez mas sofisticadas
Introducción. El proceso de traducción
Traductores y compiladores bajo + de abstracción 1945 1950 1968 1970 1990 11100110 0001 0110 10101001 1100 0011 11000011 1101 1100 MOVE AX #2 MOVE BX #3 MUL CX AX BX Fact = 1; For i:=0 to 10 fact := fact
ANÁLISIS SEMÁNTICO LA TABLA DE SÍMBOLOS
Todos los derechos de propiedad intelectual de esta obra pertenecen en exclusiva a la Universidad Europea de Madrid, S.L.U. Queda terminantemente prohibida la reproducción, puesta a disposición del público
TEORÍA DE AUTÓMATAS Y LENGUAJES
2010/2011 INGENIERÍA TÉCNICA EN INFORMÁTICA DE SISTEMAS TEORÍA DE AUTÓMATAS Y LENGUAJES FORMALES Enunciado de prácticas Lex y Yacc Enunciado de la práctica El objetivo de la práctica de esta asignatura
Lenguajes. Ciclo de desarrollo. Cód. Máquina Lenguajes alto nivel Lenguaje ensamblador 6-2. Introducción a los microprocesadores IIE FI - UDELAR
6-1 Lenguajes Cód. Máquina Lenguajes alto nivel Lenguaje ensamblador Ciclo de desarrollo 6-2 Nivel de abstracción bajo ceros y unos. Es lo único que entiende el procesador. Objetivo: código de máquina
Unidad I: Conceptos Básicos
Unidad I: Conceptos Básicos 1.1 Clasificación del software de: sistemas y aplicación Varios tipos de software se describen basándose en su método de distribución. Entre estos se encuentran los así llamados
LÓGICA DE PROGRAMACIÓN
LÓGICA DE PROGRAMACIÓN Lógica de la Programación Lenguajes de Programación Ing CIP. Mike Joseph Palacios Juárez Clasificación del Software Sistemas Operativos 1. Multitarea 2. Multiusuario 3. Multiproceso
Lenguajes y paradigmas de programación
Lenguajes y paradigmas de programación Temas Que es un programa? Que es un lenguaje de programación? Características de los lenguajes de programación Paradigmas de programación Que es un programa? La unión
Tema: Introducción a la Programación Estructurada
Tema: Introducción a la Programación Estructurada 1 Objetivos Mostrar el contexto en el que se desarrolla la asignatura. Comprender algunos conceptos como el de algoritmo y programa. Entender las tareas
Enteros. Son los números que no contienen componentes fraccionarios y, por tanto, no contienen punto decimal.
LENGUAJE DE PROGRAMACIÓN TURBO PASCAL El lenguaje de programación de alto nivel Pascal fue diseñado el 1968 por Niklaus Wirth con una finalidad eminentemente pedagógica El 1983, el Pascal fue estandarizado
Fundamentos de programación. Diagramas de flujo, Diagramas N-S, Pseudocódigo y Java
Fundamentos de programación. Diagramas de flujo, Diagramas N-S, Pseudocódigo y Java José Alfredo Jiménez Murillo Eréndira Miriam Jiménez Hernández Laura Nelly Alvarado Zamora Selecciona el libro para continuar
José Luis Alonzo Velázquez
UG Introducción Universidad de Guanajuato Sesión 1 Temario Sobre la clase: Preguntas Sobre la clase: Tareas Objetivo del Curso Inicio de curso Temario: 1 Introducción a la Programación 1 Karel el Robot
Lenguajes de programación Última modificación 2008/10
Lenguajes de programación Última modificación 2008/10 La Torre de Babel (1563) - Pieter Brueghel el Viejo 2008 Güimi (http://guimi.net) Esta obra está bajo una licencia "Reconocimiento-Compartir bajo la
Lógica: Algoritmo: Archivo: Base de datos: Bit:
Lógica: Algoritmo: Archivo: Base de datos: Bit: 1 LÓGICA: Es una secuencia de operaciones realizadas por el hardware o por el software. Lógica del hardware, Son los circuitos y Chips que realizan las operaciones
Tema 5. Soporte lógico de computadoras.
Tema 5. Soporte lógico de computadoras. 5.1 Conceptos generales Como se ha visto previamente, un ordenador consta de dos partes, una la parte física, conocida como "Hardware" y otra, la parte lógica denominada
