SlideShare uma empresa Scribd logo
1 de 25
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES



1. COMPILADOR
        Un compilador no es más que un traductor, es decir, un programa que nos permite
pasar información de un lenguaje a otro. Por ejemplo, un compilador de C nos permite
traducir ficheros escritos en lenguaje C a un lenguaje legible para la máquina
(ensambladora).

        En este proceso de compilación no siempre es directo. Esto quiere decir que nos
permite que un lenguaje A lo queremos traducir a un lenguaje B, no siempre será
recomendable traducir directamente de A a B, si no que puede ser conveniente usar un
lenguaje intermedio (que llamaremos X) y entonces diseñaremos un traductor de A a X, y
otro de X a B. En este caso, el primer traductor recibe el nombre de front-end mientras
que el segundo se llama back-end. El lenguaje A es el lenguaje fuente y el lenguaje B es
el lenguaje objeto o destino.
    En el caso de que el lenguaje fuente sea un lenguaje de programación de alto nivel y
el objeto sea un lenguaje de bajo nivel (ensamblador o código de máquina), a dicho
traductor se le denomina compilador. Un ensamblador es un compilador cuyo lenguaje
fuente es el lenguaje ensamblador. Un intérprete no genera un programa equivalente, sino
que toma una sentencia del programa fuente en un lenguaje de alto nivel y la traduce al
código equivalente y al mismo tiempo lo ejecuta, con la escasez de memoria de los
primeros ordenadores, se puso de moda el uso de intérpretes frente a los compiladores,
pues el programa fuente sin traducir y el intérprete juntos daban una ocupación de
memoria menor que la resultante de los compiladores.
    Por ello los primeros ordenadores personales iban siempre acompañados de un
intérprete de BASIC (Spectrum, Commodore VIC-20, PC XT de IBM, etc.). La mejor
información sobre los errores por parte del compilador así como una mayor velocidad de
ejecución del código resultante hizo que poco a poco se impusieran los compiladores. Hoy
en día, y con los problemas de las memorias prácticamente resueltas, se puede hablar de
un gran predominio de los compiladores frente a los intérpretes, aunque intérpretes como
los incluidos a los navegadores de Internet para interpretar el código JVM de Java son la
gran excepción.
    Ventajas de compilar frente a interpretar:
•   Se compila una vez, se ejecutan varias veces.
•   En bucles, la compilación genera código equivalente al bucle, pero interpretándolo se
    traduce tantas veces una línea como veces se repite el bucle.
•   El compilador tiene una visión global del programa, por lo que la información de
    mensajes de error es más detallada.
•   Ventajas del intérprete frente al compilador.
•   Un intérprete necesita menos memoria que un compilador. En principio eran más
    abundantes dado que los ordenadores tenían poca memoria.
•   Permiten una mayor interactividad con el código en tiempo de desarrollo.

   Un compilador no es un programa que funciona de manera aislada, sino que necesita
de otros programas para conseguir su objetivo, para obtener un programa ejecutable a
partir de un programa fuente en un lenguaje de alto nivel. Algunos de esos programas son
preprocesados, el linker, el depurador y el ensamblador. El preprocesado se ocupa
dependiendo del lenguaje de incluir ficheros, expandir macros, eliminar comentarios, y
otras tareas similares.
CISNERO, ADRIAN                                                                        1
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


   Los linker se encargan de construir el fichero ejecutable añadiendo al fichero objeto
generado por el compilador las cabeceras necesarias y las funciones de librería utilizadas
por el programa fuente. Algunos se encargan de depurador permitiendo asi el compilador
ha generado adecuadamente el programa objeto, seguir paso a paso la ejecución de un
programa. Finalmente, muchos compiladores, en vez de generar código objeto, generan
un programa en lenguaje ensamblador que debe después convertirse en un ejecutable
mediante un programa ensamblador.




   1.1. CARACTERÍSTICAS DE LOS COMPILADOR

Generalmente un compilador se divide en dos partes:

* Front End: parte que analiza el código fuente, comprueba su validez, genera el árbol de
derivación y rellena los valores de la tabla de símbolos. Parte que suele ser independiente
de las plataformas sistema operativo para el que funcionará.

* Back End: parte en donde se genera el código máquina exclusivo para una plataforma a
partir de lo analizado en el front end.

       Por lo general el resultado del back end no puede ser ejecutado directamente, se
necesita pasar por un proceso de enlazado (linker).

       Existen varios tipos de compiladores: Compiladores cruzados, Compiladores
optimizadores, Compiladores de una sola pasada, Compiladores de varias pasadas,
Compiladores JIT.

        Para el uso de la informática como herramienta de ayuda a la medicina es una
realidad en auge. Desde hace algún tiempo muchas de las actividades humanas se han
basado en la repetición, en algunos cálculos y del mismo modo que se inventaron
operaciones matemáticas básicas para simplificarlas, surgió la necesidad de mejorar las
limitadas prestaciones que ofrece la mente del hombre para calcular, a medida que las
diversas ciencias se hicieron más complejas.
CISNERO, ADRIAN                                                                          2
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


       Las primeras aplicaciones desarrolladas fueron dirigidas a resolver tareas (task-
oriented) centradas en ciertos servicios o departamentos, siendo sus típicos usuarios
secretarias o técnicos empleados para la introducción de datos, usándose sobre todo con
fines administrativos, análisis financieros, manejo de bases de datos, sistemas de
información de laboratorios o servicios de radiología.

        Estas aplicaciones han tenido un gran impacto desde el punto de vista
administrativo o de organización, pero no están dirigidos a las tareas propiamente
médicas, aunque han contribuido a reducir el tiempo dedicado a acceder a este tipo de
datos.
        Posteriormente el mayor beneficio para las actividades propiamente médica ha
sido la posibilidad de acceder a la bibliografía médica de una forma rápida mediante la
aparición de las bases de datos bibliográficos inicialmente en cederrón y actualmente a
través de INTERNET y en los últimos años, se intenta realizar aplicaciones informáticas
que vayan dirigidas a resolver problemas (problem-based), más cercanas a la práctica
médica, pero encontramos algunos problemas basados fundamentalmente en la ausencia
de comprensión de cual es el proceso que seguimos los médicos para tomar una decisión
y en la forma de representar el conocimiento y el proceso de razonamiento dentro del
ordenador.

        En estos últimos años se han añadido nuevas aplicaciones informáticas a la
medicina, como son las publicaciones electrónicas biomédicas, la telemedicina, impulsada
con un gran auge de INTERNET y su World Wide Web y los registros informáticos de la
historia clínica. Hemos agregado sobre todo en sistemas privados por el pago por
servicio, que obliga a un gran detalle de las actuaciones médicas para identificar el costo
de beneficio, precisando crear registros informáticos de alta calidad.

        La telemedicina es quizá, la que más ventajas aporta y con la que se puede
obtener reducción de costos, al poder establecer comunicación con lugares lejanos del
mundo, gracias a INTERNET y a los satélites de comunicación, evitando desplazamientos
innecesarios y comunicaciones rápidas entre médicos, otros miembros del sistema
sanitario e incluso los propios pacientes.

      En la informática se ha introducido una nueva dimensión en el pensamiento
humano, haciendo reales los sueños. No obstante, las aplicaciones informáticas para el
manejo clínico del paciente siguen estando en el campo de los proyectos, con honrosas
excepciones, existiendo pocos sistemas que sean operativos de una forma generalizada.

        Los avances en esta tecnología y en el desarrollo de redes de información van a
permitir una reducción de costos y un aumento en la calidad del cuidado de nuestros
pacientes. El cambio en la enseñanza de las ciencias médicas permitirá entender al
ordenador como una importante herramienta de trabajo, que además permitirá cambiar la
actual forma memorística e intuitiva de la actuación médica a una forma basada en una

CISNERO, ADRIAN                                                                          3
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


estructura con una mayor base de conocimientos, un proceso analítico de los mismos y
una mayor eficacia en la toma de decisiones.

    El médico no solo quedará apoyado por el ordenador sino que se mantendrá liberado
de sus tareas más repetitivas y tediosas, pasará a ser el eje sobre el que se apoye todo el
soporte informático, al actuar como selector y controlador de los datos de entrada, creador
de los protocolos y algoritmos que éste seguirá, interpretando, además, sus resultados y
por lo tanto siendo el máximo responsable del sistema.


    1.2. FASES DE LOS COMPILADOR

       En el llamado análisis léxico, el compilador revisa y controla que las palabras estén
bien escritas y pertenezcan a algún tipo de token definido dentro del lenguaje, como por
ejemplo que sea algún tipo de palabra reservada, o si es el nombre de una variable que
este escrita de acuerdo a las pautas definidas del lenguaje. En esta etapa se crea la tabla
de símbolos, la cual contiene las variables y el tipo de dato al que pertenece, las
constantes literales, el nombre de funciones y los argumentos que reciben.

        El análisis semántico se encarga de revisar que cada agrupación o conjunto de
token tenga sentido, y no sean muy absurdo. En esta etapa se reúne la información sobre
los tipos para la fase posterior, en la otra etapa se utilizara la estructura jerárquica de la
etapa anterior y así poder determinar los operadores, y operando de expresiones y
preposiciones.

         En el análisis sintáctico como su nombre lo indica se encarga de revisar que los
tokens estén ubicados y agrupados de acuerdo a la definición del lenguaje. Dicho esto de
otra manera, que los tokens pertenezcan a frases gramaticales validas, que el compilador
utiliza para sintetizar la salida. Por lo general las frases gramaticales son representadas
por estructuras jerárquicas, por medio de árboles de análisis sintáctico. En esta se
completa la tabla de símbolos con la dimensión de los identificadores y los atributos
necesarios.

        Generación de código intermedio, aunque algunos compiladores no la tienen, es
bueno saber que existen, en esta etapa se lleva el código del programa fuente a un
código interno para poder trabajar más fácilmente sobre él. Esta representación interna
debe tener dos propiedades, primero debe ser fácil de representar y segundo debe ser
fácil de traducir al código objeto.

        Optimización de código, se busca obtener el código más corto y rápido posible,
utilizando distintos algoritmos de optimización.

        Etapa de generación de código, se lleva el código intermedio final a código
maquina o código objeto, que por lo general consiste en un código maquina re localizable
o código ensamblador. Se selecciona las posiciones de memoria para los datos variables
y se traduce cada una de las instrucciones intermedias a una secuencia de instrucciones
de maquina puro.


CISNERO, ADRIAN                                                                             4
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


         La tabla de símbolos no es una etapa del proceso de compilación, sino que una
tarea, una función que debe realizar el proceso de compilación. En ella se almacenan los
identificadores que aparecen en el código fuente puro, como así también los atributos de
los mismos, su tipo, su ámbito y en el caso de los procedimientos el número de
argumentos el tipo del mismo. En otras palabras una tabla de símbolos es una estructura
de datos, que contiene un registro por cada identificador, y sus atributos. La tabla de
símbolo es accedida tanto para escritura como parar lectura por todas las etapas.

        Los detectores de errores o manejador de errores, al igual que la tabla de símbolos
no es una etapa del proceso de compilación, si no que es una función, muy importante,
pues al ocurrir un error esta función debe tratar de alguna forma el error para así seguir
con el proceso de compilación la mayoría de errores son detectados en las etapas de
análisis léxico, análisis sintáctico, análisis semántico.




                                                                             1.3.
    ESTRUCTURACION DE LOS COMPILADORES
       La estructura de un compilador, está dividida en cuatro grandes módulos, cada
uno independiente del otro, se podría decir que un compilador está formado por cuatros
módulos más a su vez.




       El primero de ellos es el                              preprocesador,   es     el
encargado de transformar el código                            fuente de entrada original
en el código fuente puro. Es decir en                         expandir   las   macros,
CISNERO, ADRIAN                                                                            5
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


incluir las librerías, realizar un preprocesado racional con la capacidad de enriquecer a
un lenguaje antiguo con recursos más modernos, extender el lenguaje y todo aquello
que en el código de entrada sea representativo de una abreviatura para facilitar la
escritura del mismo.




En el segundo modulo encontramos compilación que recibe el código fuente puro, este
es él modulo principal de un compilador, pues si ocurriera algún error en esta etapa el
compilador no podría avanzar. En esta etapa se somete al código fuente puro de
entrada a un análisis léxico gráfico, a un análisis sintáctico, a un análisis semántico, que
construyen la tabla de símbolos, se genera un código intermedio al cual se optimiza
para así poder producir un código de salida generalmente en algún lenguaje
ensamblador.




        Para este tercer modulo es el llamado modulo de ensamblado, este modulo no
es ni más mi menos que otro compilador pues recibe un código fuente de entrada
escrito en ensamblador, y produce otro código de salida, llamado código binario no
enlazado. Si por un momento viéramos a este modulo como un programa
independiente, veríamos que en este caso los términos programa compilador y proceso
de compilación son los mismos.

       Pues este modulo no es mas que un compilador, que en su interior realiza como
su antecesor un análisis léxico gráfico, un análisis sintáctico, un análisis semántico,
crea una tabla de símbolos, genera un código intermedio lo optimiza y produce un
código de salida llamado código binario no enlazado, y a todo este conjunto de tares se
los denomina proceso de compilación.

        Como se puede ver este compilador (llamado ensamblador) a diferencia de los
demás compiladores no realiza una expansión del código fuente original (código fuente
de entrada), tiene solamente un proceso de compilación y por supuesto no enlaza el
código fuente. Es un compilador que carece de los módulos de preprocesado y
enlazado, y donde los módulos de compilación y ensamblado son los mismos.

CISNERO, ADRIAN                                                                                6
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES




El cuarto y ultimo modulo es el encargado de realizar el enlazado del código de fuente
de entrada (código maquina re localizable) con las librerías que necesita, como así
también de proveer al código de las rutinas necesarias para poder ejecutarse y
cargarse a la hora de llamarlo para su ejecución, modifica las direcciones re
localizables y ubica los datos en las posiciones apropiadas de la memoria.

        Este ultimo modulo es el que produce como salida el código binario enlazado.
Ya sea dinámico o estático, al decir dinámico se refiere a que el código producido utiliza
librerías dinámicas (librerías ya cargadas en el sistema), esto implica que se obtendrá
un código más corto y que se actualizara automáticamente si aparece alguna nueva
versión de las librerías, mientras que el estático se refiere al echo que no se realiza
enlace con ninguna librería y por lo tanto se obtendrá un código mas largo con una
copia de las rutinas de librería que necesita.




2. ELEMENTOS DE UN COMPILADOR

Elementos primarios
Elemento                         Descripción

Elemento                         Elemento raíz de cada archivo de configuración usado por las
<configuration>                  aplicaciones de Common Language Runtime y .NET Framework.

<system.codedom>                 Especifica las opciones de configuración del compilador para los
(Elemento)                       proveedores de lenguaje disponibles.

Elemento <compilers>             Contenedor de elementos de configuración del compilador; contiene

CISNERO, ADRIAN                                                                                 7
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES



                                 el cero o más elementos <compiler>.

Elementos secundarios
Elemento                          Descripción

<providerOption>                  Especifica los atributos de versión del compilador para un proveedor
(Elemento)                        de lenguaje.




    2.1.     TIPOS DE COMPILADORES

      Esta taxonomía de los tipos de compiladores no es excluyente, por lo que puede
haber compiladores que se adscriban a varias categorías:

Compiladores cruzados: generan código para un sistema distinto del que están
funcionando.

Compiladores optimizadores: realizan cambios en el código para mejorar su eficiencia,
pero manteniendo la funcionalidad del programa original.

Compiladores de una sola pasada: generan el código máquina a partir de una única
lectura del código fuente.

Compiladores de varias pasadas: necesitan leer el código fuente varias veces antes de
poder producir el código máquina.

Compiladores JIT (Just In Time): forman parte de un intérprete y compilan partes del
código según se necesitan.

       Pauta de creación de un compilador: En las primeras épocas de la informática, el
software de los compiladores era considerado como uno de los más complejos existentes.

       Los primeros compiladores se realizaron programándolos directamente en
lenguaje máquina o en ensamblador. Una vez que se dispone de un compilador, se
pueden escribir nuevas versiones del compilador (u otros compiladores distintos) en el
lenguaje que compila ese compilador.

        Actualmente existen herramientas que facilitan la tarea de escribir compiladores ó
intérpretes informáticos. Estas herramientas permiten generar el esqueleto del analizador
sintáctico a partir de una definición formal del lenguaje de partida, especificada
normalmente mediante una gramática formal y barata, dejando únicamente al
programador del compilador la tarea de programar las acciones semánticas asociadas


3. EMSAMBLADOR



CISNERO, ADRIAN                                                                                8
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


        El ensamblador se refiere a un tipo de programa, informático que se encarga de
traducir un fichero fuente escrito en un lenguaje ensamblador, a un fichero objeto que
contiene código máquina ejecutable directamente por la máquina para la que se ha
generado.

       Los lenguajes ensambladores fueron desarrollados hace muchos años atrás,
cuando fueron referidos como lenguajes de programación de segunda generación. Por
ejemplo, el SOAP (Symbolic Optimal Assembly Program) era un lenguaje ensamblador
para el computador IBM 650. Los lenguajes ensambladores eliminaron mucha de la
propensión a errores y del consumo de tiempo de la programación de los lenguajes de
primera generación que se necesitaban con los primeros computadores, liberando a los
programadores como recordar códigos numéricos y cálculo de direcciones.

         Una vez fueron ampliamente usados para todo tipo de programación. Sin
embargo, los microcomputadores se usaban en gran parte suplantado por los lenguajes
de alto nivel, en la búsqueda de una mejorada productividad en programación. Hoy en
día, aunque el lenguaje ensamblador es casi siempre manejado y generado por los
compiladores, todavía se usa para la manipulación directa del hardware, acceso a
instrucciones especializadas del procesador, o para resolver problemas de desempeño
crítico. Los usos típicos son drivers de dispositivo, sistemas embebidos de bajo nivel, y
sistemas de tiempo real.

        Un gran número de programas han sido escritos enteramente en lenguaje
ensamblador. Los sistemas operativos fueron casi exclusivamente escritos en lenguaje
ensamblador hasta la aceptación amplia del lenguaje de programación C. También,
muchas aplicaciones comerciales fueron escritas en lenguaje ensamblador, incluyendo
una gran cantidad del software escrito por grandes corporaciones para mainframes de
IBM. Los lenguajes COBOL y FORTRAN eventualmente desplazaron mucho de este
trabajo, aunque un número de organizaciones grandes conservaran las infraestructuras
de aplicaciones en lenguaje ensamblador.

         La mayoría de los primeros microcomputadores confiaron en el lenguaje
ensamblador codificado a mano, incluyendo la mayoría de los sistemas operativos y de
las aplicaciones grandes. Esto era porque estos sistemas tenían limitaciones severas
de recursos, impusieron idiosincráticas arquitecturas de memoria y de pantalla que
proporcionaron servicios de sistema limitados con errores. Quizás más importante era
la falta de compiladores de primera clase de lenguajes de alto nivel adecuados para el
uso en el microcomputador.

       En un contexto más comercial, las más grandes razones para usar el lenguaje
ensamblador era hacer programas con mínimo tamaño, mínima sobrecarga, mayor
velocidad y confiabilidad.

        Los típicos ejemplos de programas grandes en lenguaje ensamblador de ese
tiempo son los sistemas operativos IBM PC DOS y aplicaciones tempranas tales como
la hoja de cálculo Lotus 1-2-3, y casi todos los juegos populares para la familia Atari
800 de computadores personales. La mayoría de los videojuegos de consola fueron
escritos en ensamblador, incluyendo la mayoría de los juegos para la Mega
Drive/Genesis y el Super Nintendo Entertainment System.

CISNERO, ADRIAN                                                                             9
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


       Según algunos insiders de la industria, el lenguaje ensamblador era el mejor
lenguaje de programación a usar para obtener el mejor desempeño del Sega Saturn,
una consola para la cual era notoriamente desafiante desarrollar y programar juegos. El
popular juego de arcade NBA Jam es otro ejemplo. El ensamblador ha sido por largo
trecho, el lenguaje de desarrollo primario en los computadores hogareños Commodore
64, Atari ST, así como el ZX Spectrum.

        Esto fue así en gran parte porque los dialectos del BASIC en estos sistemas
ofrecieron insuficiente velocidad de ejecución, así como insuficientes características
para aprovechar completamente el hardware disponible. Algunos sistemas, más
notablemente el Amigo, incluso tienen IDEs con características de depuración y macros
altamente avanzados, tales como el freeware ASM-One assembler, comparable a las
del Microsoft Visual Studio (el ASM-Uno precede al Microsoft Visual Studio).

       El ensamblador para el VIC-20 fue escrito por Don French y publicado por
French Silk. Con 1639 bytes de longitud, se cree que es el más pequeño ensamblador
simbólico jamás escrito. El ensamblador soportaba el direccionamiento simbólico usual
y la definición de cadenas de caracteres o cadenas hexadecimales. También permitía
expresiones de direcciones que podían combinarse con las operaciones de adición,
substracción, multiplicación, división, AND lógico, OR lógico, y exponenciación.

       Han habido siempre debates sobre la utilidad y el desempeño del lenguaje
ensamblador relativo a lenguajes de alto nivel. El lenguaje ensamblador tiene algunas
especificaciones donde son importante. Pero, en general, los modernos compiladores
de optimización para traducir lenguajes de alto nivel en el código que puede correr tan
rápidamente como el lenguaje ensamblador escrito a mano, a pesar de los contra
ejemplos que pueden ser encontrados. La complejidad de los procesadores modernos y
del subsistema de memoria hace la optimización efectiva cada vez más difícil para los
compiladores, así como para los programadores en ensamblador. Adicionalmente, y
para la consternación de los amantes de la eficiencia, el desempeño cada vez mayor
del procesador ha significado que la mayoría de los CPU estén desocupados la mayor
parte del tiempo, con retardos causados por embotellamientos predecibles tales como
operaciones de entrada/salida y paginación de memoria. Esto ha hecho la velocidad de
ejecución cruda del código un problema para muchos programadores.

       Hay algunas situaciones en las cuales los profesionales pudieran elegir utilizar el
lenguaje ensamblador. Por ejemplo cuando:

    •    es requerido un ejecutable binario independiente (stand-alone), es decir uno que
         deba ejecutarse sin recursos a componentes de tiempo de ejecución o a
         bibliotecas asociadas con un lenguaje de alto nivel; ésta es quizás la situación más
         común. Son programas empotrados que solo almacenan una pequeña cantidad de
         memoria y el dispositivo está dirigido para hacer tareas para un simple propósito.
         Ejemplos consisten en teléfonos, sistemas de combustible e ignición para
         automóviles, sistemas de control del aire acondicionado, sistemas de seguridad, y
         sensores.
    •    interactuando directamente con el hardware, por ejemplo en drivers de dispositivo
         y manejadores de interrupción.



CISNERO, ADRIAN                                                                           10
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


    •    usando instrucciones específicas del procesador no explotadas o disponibles por
         el compilador. Un ejemplo común es la instrucción de rotación bit wise en el núcleo
         de muchos algoritmos de cifrado.
    •    creando funciones vectorizadas para programas en lenguajes de alto nivel como
         C. En el lenguaje de alto nivel esto es a veces ayudado por funciones intrínsecas
         del compilador que mapean directamente a los mnemónicos del SIMD, pero sin
         embargo resulta en una conversión de ensamblador de uno a uno para un
         procesador de vector asociado.
    •    es requerida la optimización extrema, en un bucle interno en un algoritmo intensivo
         en el uso del procesador. Los programadores de juegos toman ventaja de las
         habilidades de las características del hardware en los sistemas, permitiendo a los
         juegos correr más rápidamente. También las grandes simulaciones científicas
         requieren algoritmos altamente optimizados, ej, álgebra lineal con BLAS o la
         transformada de coseno discreta la versión SIMD en ensamblador del x264, una
         biblioteca para codificar streams de video.
    •    un sistema con severas limitaciones de recursos un sistema empotrado debe ser
         codificado a mano para maximizar el uso de los limitados recursos; pero esto está
         llegando a ser menos común a medida que el precio del procesador decrece y el
         desempeño mejora.
    •    no existe ningún lenguaje de alto nivel, en un procesador nuevo o especializado.
    •    escribiendo programas de tiempo real que necesitan sincronización y respuestas
         precisas, tales como sistemas de navegación de vuelo, y equipo médico. En un
         sistema fly-by-wire, vuelo por mandos eléctricos, la telemetría debe ser
         interpretada y hay que actuar dentro de limitaciones estrictas de tiempo. Tales
         sistemas deben eliminar fuentes de retrasos impredecibles, que pueden ser
         creados para algunos lenguajes interpretados, recolección de basura automática,
         operaciones de paginación, o multitarea preventiva. Sin embargo, algunos
         lenguajes de alto nivel incorporan componentes de tiempo de ejecución e
         interfaces de sistema operativo que pueden introducir tales retrasos. Elegir el
         ensamblador o lenguajes de bajo nivel para tales sistemas da a los programadores
         mayor visibilidad y control sobre el proceso de los detalles.
    •    es requerido control total sobre el ambiente, en situaciones de seguridad
         extremadamente alta donde nada puede darse por sentado.
    •    se escriben virus de computadora, bootloaders, ciertos drivers de dispositivo, u
         otros elementos muy cerca del hardware o al sistema operativo de bajo nivel
    •    se escriben simuladores del conjunto de instrucciones para monitoreo, trazado y
         depuración de errores donde la sobrecarga adicional es mantenida al mínimo
    •    se hace ingeniería inversa en binarios existentes que pueden o no haber sido
         escritos originalmente en un lenguaje de alto nivel, por ejemplo al crackear la
         protección anticopia del software propietario.
    •    se hace ingeniería inversa y modificación de video juegos, también denominado
         ROM hacking, que es posible por medio de varios métodos. El más ampliamente
         implementado es alterando el código del programa a nivel de lenguaje
         ensamblador
    •    se escribe código automodificable, algo para lo que el lenguaje ensamblador se
         presta bien
    •    se escriben juegos y otros softwares para calculadoras gráficas
    •    se escribe software compilador que genera código ensamblador, y por lo tanto los
         desarrolladores deben ser programadores de lenguaje ensamblador.
    •    se escriben algoritmos criptográficos que siempre deben tomar estrictamente el
         mismo tiempo para ejecutar, previniendo ataques de tiempo.
CISNERO, ADRIAN                                                                          11
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


      Sin embargo, el lenguaje ensamblador es todavía enseñado en la mayoría de los
programas de ciencias de la computación e ingeniería electrónica. Aunque hoy en día,
pocos programadores trabajan regularmente con el lenguaje ensamblador como una
herramienta, los conceptos fundamentales continúan siendo muy importantes.

        Tales tópicos fundamentales, como aritmética binaria, asignación de memoria,
procesamiento del stack, codificación de conjunto de caracteres, procesamiento de
interrupciones, y diseño de compiladores, serían duros de estudiar en detalle sin la
comprensión de cómo el computador opera a nivel del hardware. Puesto que el
comportamiento del computador es fundamentalmente definido por su conjunto de
instrucciones, la manera lógica de aprender tales conceptos es estudiar un lenguaje
ensamblador.

        La mayoría de los computadores modernos tienen un conjunto de instrucciones
similares. Por lo tanto, estudiar un solo lenguaje ensamblador es suficiente para aprender:
i) los conceptos básicos; ii) reconocer situaciones donde el uso de lenguaje ensamblador
puede ser apropiado; y iii) ver cómo el código ejecutable eficiente puede ser creado por
los lenguajes de alto nivel18

        El lenguaje ensamblador hard-coded es típicamente usado en el ROM de arranque
del sistema (BIOS en los sistemas compatible IBM PC). Este código de bajo nivel es
usado, entre otras cosas, para inicializar y probar el hardware del sistema antes de cargar
el sistema operativo, y está almacenado en el ROM. Una vez que ha tomado lugar un
cierto nivel de inicialización del hardware, la ejecución se transfiere a otro código,
típicamente escrito en lenguajes de alto nivel; pero el código corriendo inmediatamente
después de que es aplicada la energía usualmente está escrito en lenguaje ensamblador.
Lo mismo es cierto para los boot loaders.

        Muchos compiladores traducen lenguajes de alto nivel a lenguaje ensamblador
primero, antes de la compilación completa, permitiendo que el código en ensamblador sea
visto para propósitos de depuración y optimización. Lenguajes de relativo bajo nivel, como
C, con frecuencia proveen sintaxis especial para empotrar lenguaje ensamblador en cada
plataforma de hardware. El código portable del sistema entonces puede usar estos
componentes específicos a un procesador a través de una interface uniforme.

       El lenguaje ensamblador también es valioso en ingeniería inversa, puesto que
muchos programas solamente son distribuidos en una forma de código de máquina. El
código de máquina es usualmente fácil de trasladar hacia lenguaje ensamblador para
luego ser cuidadosamente examinado en esta forma, pero es muy difícil de trasladar hacia
un lenguaje de alto nivel. Herramientas como Interactive Disassembler, hacen uso
extenso del desensamblador para tales propósitos.

       Un nicho que hace uso del lenguaje ensamblador es el demoscene. Ciertas
competiciones requieren a los concursantes restringir sus creaciones a un muy pequeño
tamaño 256 bytes, 1 KB, 4 KB ó 64 KB, y el lenguaje ensamblador es el lenguaje de
preferencia para alcanzar este objetivo.

       Cuando los recursos son una preocupación, es una necesidad la codificación en
ensamblador, especialmente en sistemas constreñidos por el procesamiento del CPU,
como los primeros modelos del Amiga, y el Commodore 64. El código optimizado en
CISNERO, ADRIAN                                                                         12
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


ensamblador es escrito "a mano" por los programadores en un intento de minimizar el
número de ciclos de CPU usados. Las limitaciones del CPU son tan grandes que cada
ciclo cuenta. Usar tales métodos ha habilitado, a sistemas como el Commodore 64, para
producir gráficos en 3D en tiempo real con efectos avanzados, una hazaña que puede ser
considerada improbable o incluso imposible para un sistema con un procesador de 0.99
MHz.



4. ÁRBOLES PARTE SEMANTICAS.

       Hemos visto que las deducciones pueden hacerse atendiendo a los problemas de
derivación, realizándose esta última a través de la aplicación de las reglas básicas o
derivadas.

       Pero también podemos utilizar otro criterio: el semántico, según el cual, y
suponiendo que la deducción sea correcta, no podemos obtener una conclusión falsa de
premisas verdaderas. La semántica atiende por una parte al hecho al que se refiere la
proposición y, por otra parte, a su valor de verdad.

        El método de las tablas semánticas supone una búsqueda de contraejemplos que
invaliden el argumento. Es una especie de reducción al absurdo, en la que se supone la
verdad de la negación de la conclusión y, a partir de ella, se llega a una contradicción.




CISNERO, ADRIAN                                                                        13
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES




CISNERO, ADRIAN                                               14
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


    4.1.     COMO SE IDENTIFICAN

      El analizador semántico verificara que en este caso cada operador tenga los
operadores permitidos.

=
/
id1 +
/
id2 +
/
id3 tipo_ent
|
10


5. GRAMATICA BNF

Una especificación de BNF es un sistema de reglas de derivación, escrito como:

<simbolo> ::= <expresión con símbolos>

donde <símbolo> es un no terminal, y la expresión consiste en secuencias de símbolos o
secuencias separadas por la barra vertical, '|', indicando una opción, el conjunto es una
posible substitución para el símbolo a la izquierda. Los símbolos que nunca aparecen en
un lado izquierdo son terminales.

Ejemplo

Como ejemplo, considere este BNF para una dirección postal de los EE.UU.

<dirección postal> ::= <nombre> <dirección> <apartado postal>
<personal> ::= <primer nombre> | <inicial> "."
<nombre> ::= <personal> <apellido> [<trato>] <EOL>
        | <personal> <nombre>
<dirección> ::= [<dpto>] <número de la casa> <nombre de la calle> <EOL>
<apartado postal> ::= <ciudad> "," <código estado> <código postal> <EOL>

Esto se traduce a español como:

    •    Una dirección postal consiste en un nombre, seguido por una dirección, seguida
         por un apartado postal.
    •    Una parte "personal" consiste en un nombre o una inicial seguido(a) por un punto.
    •    Un nombre consiste de: una parte personal seguida por un apellido seguido
         opcionalmente por una jerarquía o el trato que se la da a la persona (Jr., Sr., o
         número dinástico) y un salto de línea (end-of-line), o bien una parte personal
         seguida por un nombre (esta regla ilustra el uso de la repetición en BNFs,
         cubriendo el caso de la gente que utiliza múltiples nombres y los nombres medios
         o las iniciales).

CISNERO, ADRIAN                                                                        15
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


    •    Una dirección consiste de una especificación opcional del departamento, seguido
         de un número de casa, seguido por el nombre de la calle, seguido por un salto de
         línea (end-of-line).
    •    Un apartado postal consiste de una ciudad, seguida por una coma, seguida por un
         código del estado (recuerde que es un ejemplo que ocurre en EE.UU.), seguido
         por un código postal y este seguido por un salto de línea (end-of-line).

   Observe que muchas cosas (tales como el formato de una parte personal, de una
especificación del apartamento, o código postal) están dejadas sin especificar aquí. Si es
necesario, pueden ser descritas usando reglas adicionales de BNF, o dejadas como
abstracción si es inaplicable para el propósito actual.

Otros ejemplos

Bastante interesante, la sintaxis de BNF se puede representar en BNF como sigue:

<syntax> ::= <rule> [<syntax>]
<rule> ::= <whitespace> "<" <rule-name> ">" <whitespace> "::="
  <expression> <whitespace> <line-end>
<expression> ::= <whitespace> <or-expression>
<or-expression> ::= <whitespace> <list-expression> [ "|"
  <or-expression> ]
<list-expression> ::= <whitespace> ("<" <rule-name> ">"
  | <QUOTE> <text> <QUOTE> | "(" <expression> ")" | "[" <expression>
  "]") [<list-expression>]
<whitespace> ::= [" " <whitespace>]
<line-end> ::= [<whitespace>] <EOL> [<line-end>]

        Esto asume que no hay Whitespace necesario para la interpretación apropiada de
la regla. El <QUOTE> se presume para ser el carácter ", y el <EOL> para ser el fin de
línea apropiado especificado (en ASCII, retorno de carro o línea nueva, dependiendo del
sistema operativo). El <rule-name> y el <text> deben ser substituidos con nombre/etiqueta
o el texto literal de una regla declarada, respectivamente.

       Hay muchas variantes y extensiones de BNF, posiblemente conteniendo algunos o
todos los comodines de expresiones regulares como un "*" o "+". El Extended Backus-
Naur form (EBNF) es una variante común. De hecho el ejemplo anterior no es la forma
pura inventada para el informe del ALGOL 60. La notación de los corchetes "[ ]" fue
introducida algunos años más tarde en la definición de PL/I de la IBM pero ahora se
reconoce universal. La ABNF es otra extensión usada comúnmente para describir
protocolos del IETF.

       Las expresiones gramaticales de analizadores sintácticos construidas en BNF y las
notaciones de expresión regular para formar una clase alternativa de la gramática formal,
que es esencialmente analítica más que generativa en carácter.

    Muchas especificaciones de BNF disponibles en línea tienen como propósito ser
legibles a simple vista y no son especificaciones formales. Estas incluyen con frecuencia
algunas de estas reglas sintácticas y extensiones:

CISNERO, ADRIAN                                                                        16
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


    •    Elementos opcionales son presentados entre paréntesis cuadrados. Por ejemplo
         [<elemento-x>]
    •    Los elementos que se repiten 0 o más veces son presentados entre paréntesis de
         llave o terminados con un asterisco. Por ejemplo <palabra> ::= <letra> {<letra>}
    •    Los elementos que se repiten 1 o más veces son terminados con un '+'
    •    Los terminales pueden aparecer en negrillas y los no-terminales en texto normal
         en lugar de utilizar itálicas o paréntesis de ángulo
    •    Alternativas opcionales son separadas por el símbolo '|'

Cuando se requiere agrupar varios elementos, se hace con paréntesis simple


    5.1.          SU DEFINICION

       La notación de Backus-Naur, también conocida por sus denominaciones inglesas
Backus-Naur form (BNF), Backus-Naur formalism o Backus normal form, es una
metasintaxis usada para expresar gramáticas libres de contexto: es decir, una manera
formal de describir lenguajes formales.

       El BNF se utiliza extensamente como notación para las gramáticas de los
lenguajes de programación de la computadora, de los sistemas de comando y de los
protocolos de comunicación, así como una notación para representar partes de las
gramáticas de la lengua natural (por ejemplo, el metro en la poesía de Venpa). La mayoría
de los libros de textos para la teoría o la semántica del lenguaje de programación
documentan el lenguaje de programación en BNF.

      Algunas variantes, tales como la Augmented Backus-Naur form (ABNF) y la
Extended Backus–Naur Form (EBNF), tienen su propia documentación.

        Con la aparición de la notación BNF - desarrollada en primer lugar por Backus
en 1960 cuando trabajaba en un borrador del ALGOL 60, modificada en 1963 por Naur
y formalizada por Knuth en 1964 - se tiene una guía para el desarrollo del análisis
sintáctico. Los diversos métodos de parsers ascendentes y descendentes se
desarrollan durante la década de los 60. En 1959, Sheridan describe un método de
parsing de FORTRAN que introducía paréntesis adicionales alrededor de los operandos
para ser capaz de analizar las expresiones. Más adelante, Floyd introduce la técnica de
la precedencia de operador y el uso de las funciones de precedencia.

       A mitad de la década de los 60, Knuth define las gramáticas LR y describe la
construcción de una tabla canónica de parser LR. Por otra parte, el uso por primera vez
de un parsing descendente recursivo tuvo lugar en el año 1961. En el año 1968 se
estudian y definen las gramáticas LL así como los parsers predictivos. También se
estudia la eliminación de la recursión a la izquierda de producciones que contienen
acciones semánticas sin afectar a los valores de los atributos.

       En los primeros años de la década de los 70, se describen los métodos SLR y
LALR de parser LR. Debido a su sencillez y a su capacidad de análisis para una gran
variedad de lenguajes, la técnica de parsing LR va a ser la elegida para los
generadores automáticos de parsers. A mediados de los 70, Johnson crea el generador

CISNERO, ADRIAN                                                                       17
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


de analizadores sintácticos YACC para funcionar bajo un entorno UNIX . Junto al
análisis sintáctico, también se fue desarrollando el análisis semántico.

         La idea de transcribir la estructura del lenguaje con reglas de reescritura se
remontan cuando menos al trabajo del gramático indio Panini (hacia el 460 a. C.), que la
utilizó en su descripción de la estructura de palabras del idioma sánscrito (algunos incluso
han sugerido renombrar BNF a Forma Panini-Backus). Lingüïstas estadounidenses como
Leonard Bloomfield y Zellig Harris llevaron esta idea un paso más adelante al tratar de
formalizar el lenguaje y su estudio en términos de definiciones formales y procedimientos
(1920-1960).

        Noam Chomsky, maestro de lingüística de alumnos de teoría de la información del
MIT, combinó la lingüística y las matemáticas, tomando esencialmente el formalismo de
Axel Thue como la base de su descripción de la sintaxis del lenguaje natural. También
introdujo una clara distinción entre reglas generativas (de la gramática libre de contexto) y
reglas transformativas (1956).

       John Backus, un diseñanor de lenguajes de programación de IBM, adoptó las
reglas generativas de Chomsky para describir la sintaxis del nuevo lenguaje de
programación IAL, conocido en la actualidad como ALGOL 58 (1959), presentando en el
primer Congreso de Computación Mundial (World Computer Congress) el artículo "The
syntax and semantics of the proposed international algebraic language of the Zurich ACM-
GAMM Conference".

       Peter Naur, en su reporte sobre ALGOL 60 de 1963, identificó la notación de
Backus como la Forma Normal de Backus (Backus Normal Form), y la simplificó para
usar un conjunto de símbolos menor, pero a sugerencia de Donald Knuth, su apellido fue
agregado en reconocimiento a su contribución, reemplazando la palabra "Normal" por
Naur, dado que no se trata de una forma normal en ningún sentido, a diferencia, por
ejemplo de la Forma Normal de Chomsky.

6. LAS MAQUINAS DE TURING


        Una máquina de Turing (MT) es un modelo computacional que realiza una lectura/
escritura de manera automática sobre una entrada llamada cinta, generando una salida
en esta misma.

       Este modelo está formado por un alfabeto de entrada y uno de salida, un símbolo
especial llamado blanco (normalmente b, Δ o 0), un conjunto de estados finitos y un
conjunto de transiciones entre dichos estados. Su funcionamiento se basa en una función
de transición, que recibe un estado inicial y una cadena de caracteres (la cinta, la cual
puede ser infinita) pertenecientes al alfabeto de entrada.

         La máquina va leyendo una celda de la cinta en cada paso, borrando el símbolo
en el que se encuentra posicionado su cabezal y escribiendo un nuevo símbolo
perteneciente al alfabeto de salida, para luego desplazar el cabezal a la izquierda o a la
derecha (solo una celda a la vez). Esto se repite según se indique en la función de
transición, para finalmente detenerse en un estado final o de aceptación, representando
así la salida.
CISNERO, ADRIAN                                                                           18
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES




        La entrada de una máquina de Turing viene determinada por el estado actual y el
símbolo leído, un par (estado, símbolo), siendo el cambio de estado, la escritura de un
nuevo símbolo y el movimiento del cabezal, las acciones a tomar en función de una
entrada. En el caso de que para cada par (estado, símbolo) posible exista a lo sumo una
posibilidad de ejecución, se dirá que es una máquina de Turing determinista, mientras que
en el caso de que exista al menos un par (estado, símbolo) con más de una posible
combinación de actuaciones se dirá que se trata de una máquina de Turing no
determinista.

La función de transición δ en el caso no determinista, queda definida como sigue:




       ¿Cómo sabe una máquina no determinista qué acción tomar de las varias
posibles? Hay dos formas de verlo: una es decir que la máquina es "el mejor adivino
posible", esto es, que siempre elige la transición que finalmente la llevará a un estado final
de aceptación. La otra es imaginarse que la máquina se "clona", bifurcándose en varias
copias, cada una de las cuales sigue una de las posibles transiciones. Mientras que una
máquina determinista sigue un único "camino computacional", una máquina no
determinista tiene un "árbol computacional". Si cualquiera de las ramas del árbol finaliza
en un estado de aceptación, se dice que la máquina acepta la entrada.

      La capacidad de cómputo de ambas versiones es equivalente; se puede demostrar
que dada una máquina de Turing no determinista existe otra máquina de Turing
determinista equivalente, en el sentido de que reconoce el mismo lenguaje, y viceversa.
No obstante, la velocidad de ejecución de ambos formalismos no es la misma, pues si una
máquina no determinista M reconoce una cierta palabra de tamaño

n en un tiempo                  , la máquina determinista equivalente reconocerá la palabra en
un tiempo            . Es decir, el no determinismo permitirá reducir la complejidad de la
solución de los problemas, permitiendo resolver, por ejemplo, problemas de complejidad
exponencial en un tiempo polinómico.

Una máquina de Turing con una sola cinta puede definirse como una 7-tupla




donde:
CISNERO, ADRIAN                                                                            19
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES



    •       es un conjunto finito de estados.
    •      es un conjunto finito de símbolos distinto del espacio en blanco, denominado
         alfabeto de máquina o de entrada.
    •      es un conjunto finito de símbolos de cinta, denominado alfabeto de cinta (
                  ).
    •            es el estado inicial.
    •            es un símbolo denominado blanco, y es el único símbolo que se puede
         repetir un número infinito de veces.
    •              es el conjunto de estados finales de aceptación.
    •                                           es una función parcial denominada función de
         transición, donde        es un movimiento a la izquierda y es el movimiento a la
         derecha.

    Existen en la literatura un abundante número de definiciones alternativas, pero todas
ellas tienen el mismo poder computacional, por ejemplo se puede añadir el símbolo
como símbolo de "no movimiento" en un paso de cómputo.



7. ANALISIS SINTACTICO.

         Como ya sabemos la sintaxis en lógica es la forma correcta de escribir una fórmula
y la semántica es lo que significa. Como en lógica solamente tenemos dos valores una
fórmula solamente puede ser verdadera o falsa. Para determinar su valor seguimos las
reglas simples que dimos en las definiciones básicas de acuerdo a su tabla de verdad.
Esto lo hacemos mediante interpretaciones. Una interpretación de una fórmula es un
conjunto de valores que se les asignan a sus proposiciones atómicas.

         Al interpretar una fórmula lo que finalmente vamos a obtener es un valor de
verdad, bien sea verdadero o falso. Pero para poder encontrarlo muchas veces el proceso
en laborioso porque puede estar formada por varias proposiciones atómicas.
Primeramente se le asignan valores de verdad a los átomos y se puede encontrar el valor
de la expresión.

         Si deseamos hacerlo en general, debemos analizar todas las posibilidades, esto se
puede hacer construyendo una tabla de verdad. Para fines prácticos cuando se tienen
varios átomos las tablas de verdad no resultan prácticas por lo que analizaremos
solamente expresiones con tres átomos como máximo.

         Por supuesto que se puede construir una tabla para un número mayor de átomos,
pero notemos que por cada átomo que se aumente el número de renglones se duplica.

CISNERO, ADRIAN                                                                          20
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES



Esto es, para un átomos son dos renglones, para dos átomos son cuatro, para tres
átomos son ocho, para cuatro dieciséis, etc.

         Algoritmo para construir una tabla de verdad de una fórmula en lógica de
proposiciones.

         Escribir la fórmula con un número arriba de cada operador que indique su
jerarquía. Se escriben los enteros positivos en orden, donde el número 1 corresponde al
operador de mayor jerarquía. Cuando dos operadores tengan la misma jerarquía, se le
asigna el número menor al de la izquierda.

         Construir el árbol sintáctico empezando con la fórmula en la raíz y utilizando en
cada caso el operador de menor jerarquía. O sea, del número mayor al menor.

         Numerar las ramas del árbol en forma secuencial empezando por las hojas hacia
la raíz, con la única condición de que una rama se puede numerar hasta que estén
numerados los hijos. Para empezar con la numeración de las hojas es buena idea hacerlo
en orden alfabético, así todos obtienen los renglones de la tabla en el mismo orden para
poder comparar resultados.

         Escribir los encabezados de la tabla las fórmulas siguiendo la numeración que se
le dió a las ramas en el árbol sintáctico.

         Al asignarle a los átomos, las hojas del árbol, todos los posibles valores de verdad
de acuerdo al orden establecido. Por supuesto que el orden es arbitrario, pero como el
número de permutaciones es n!, conviene establecer un orden para poder comparar
resultados fácilmente.

         Asignar valor de verdad a cada una de las columnas restantes de acuerdo al
operador indicado en el árbol sintáctico utilizando la tabla de verdad correspondiente,
conviene aprenderse de memoria las tablas de los operadores, al principio pueden tener
un resumen con todas las tablas mientras se memorizan.

          La última columna, correspondiente a la fórmula original, es la que indica los
valores de verdad posibles de la fórmula para cada caso.

Ejemplo. Construya la tabla de verdad de las siguientes expresiones lógicas:
i) (p → ¬q) v (¬p v r)
ii) p → (q ^ r)
CISNERO, ADRIAN                                                                           21
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES



iii) (p → ¬ r) ↔ (q v p)
iv) ¬(p ¬ q) → ¬ r
v) (¬p ^ q) → ¬(q v ¬r)


Solución:

i) Seguimos los pasos del algoritmo con la fórmula (p → ¬q) v (¬p v r)

1. Vemos que los operadores de los paréntesis tienen mayor jerarquía, empezamos por el
paréntesis izquierdo por lo que la fórmula con jerarquías marcadas sería:



    7.1.     LIMITACION

El análisis semántico toma su nombre por requerir información relativa al significado del
lenguaje, fuera del alcance del análisis sintáctico.

Mediante el empleo de gramáticas sensibles al contexto tipo 1 se podrían comprobar
características del lenguaje. Ejemplo: la utilización de una variable requiere que esté
declarada previamente.

Un autómata de tipo 1 es complejo de implementar e ineficiente.

Solución: Análisis semántico a partir de gramáticas y autómatas de tipo 2 sintáctico e
implementación de reglas semánticas del lenguaje.

Se emplean estructuras de datos auxiliares como las tablas de símbolos.

El análisis semántico realiza todas las comprobaciones del lenguaje necesarias y no
llevadas a cabo por el sintáctico



    7.2.     COMO SE UTILIZA

       El analizador sintáctico impone una estructura jerárquica a la cadena de
componentes léxicos, generada por el analizador léxico, que es representada en forma de
un árbol sintáctico.

=
/
id1 +
/
id2 +
/
id3 10

CISNERO, ADRIAN                                                                             22
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES




    7.3.     DESCENDENTE Y ASCENDENTE

El estudio de gramáticas atribuidas se basa en la distinción de atributos heredados y
sintetizados.

Determinará cómo podremos implementarlas.

Sintetizados: se calculan ascendentemente en el árbol sintáctico.
Heredados: cálculo descendente.




8. ANALISIS LEXICO

       Analizador léxico (scanner): lee la secuencia de caracteres del programa fuente,
carácter a carácter, y los agrupa para formar unidades con significado propio, los
componentes léxicos (tokens en ingles). Estos componentes léxicos representan:
palabras reservadas: if, while, do, . . .identificadores: asociados a variables, nombres de
funciones, tipos definidos por el usuario, etiquetas,... Por ejemplo: posición, velocidad,
tiempo, . . . operadores: = * + - / == > < & ! = . . . símbolos especiales: ; ( ) [ ] f g ...
constantes numéricas: literales que representan valores enteros, en coma dotante, etc,
982, 0xF678, -83.2E+2,... constantes de caracteres: literales que representan cadenas
concretas de caracteres, hola mundo",...

       El analizador léxico opera bajo petición del analizador sintáctico devolviendo un
componente léxico conforme el analizador sintáctico lo va necesitando para avanzar en la
gramática. Los componentes léxicos son los símbolos terminales de la gramática.

       Suele implementarse como una subrutina del analizador sintáctico. Cuando recibe
la orden obtiene el siguiente componente léxico, el analizador léxico lee los caracteres de
entrada hasta identificar el siguiente componente lexico.analizador

       El analizador léxico lee los caracteres del programa fuente, y verifica que
correspondan a una secuencia lógica (identificador, palabra reservada etc.). Esta
CISNERO, ADRIAN                                                                           23
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


secuencia de caracteres recibe el nombre componente léxico o lexema. En este caso el
analizador léxico verifica si el identificador id1 (nombre interno para "suma") encontrado
se halla en la tabla de símbolos, si no esta produce un error porque todavía no fue
declarado, si la preposición hubiese sido la declaración del identificador "suma" en
lenguajes C, C++ (int suma;) el analizador léxico agregaría un identificador en la tabla de
símbolos, y así sucesivamente con todos los componentes léxicos que aparezcan.
id1= id2+ id3 * 10


    8.1.     BUFFER DE ENTRADA

       El proceso de lectura de los caracteres de la entrada y formar los componentes
léxicos es lo mas costoso en tiempo en el proceso de traducción. Es importante
implementarlo eficientemente.

         Se utiliza un buffer dividido en dos mitades de tamaño N caracteres, donde N es
un bloque de disco (1024, 4096). Se leen N caracteres de la entrada en cada mitad del
buffer con una única orden de lectura. Se mantienen dos apuntadores. Uno marca el inicio
del lexema y el otro el carácter actual que se mueve hasta encontrar una subcadena que
corresponde con un patrón. Una vez reconocido un componente léxico ambos
apuntadores se colocan en la misma posición y justo detrás del lexema reconocido.
buffer de entrada
if avanza est´a final primera mitad then
     recargar segunda mitad;
     avanza = avanza+1;
else if avanza est´a final segunda mitad then
     recargar primera mitad;
     pasar avanza a principio primera mitad;
else avanza = avanza+1;


    8.2.     LAS EXPRESIONES REGULARES

Expresiones Regulares:

Los componentes léxicos se especifican haciendo uso de expresiones regulares. Además
de las tres operaciones básicas: concatenación, repetición (*) y alternativas (j) vamos a
usar los siguientes meta símbolos:

Una o mas repeticiones +
r+ indica una o mas repeticiones de r
(0j1)+ = (0j1)(0j1)*
Cualquier carácter.
.*b.* indica cualquier cadena que contiene una letra b
Un rango de caracteres [ ] (clase)
[a-z] indica cualquier carácter entre la a y z minúsculas
[a-zA-Z] indica cualquier letra del abecedario minúscula o mayúscula
[0-9] indica cualquier digito de 0 a 9
[abc] indica ajbjc

Cualquier caracter excepto un conjunto dado ~
CISNERO, ADRIAN                                                                         24
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO
NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA
MATERIA: COMPILADORES


~ (ajb) indica cualquier caracter que no sea una a o b
Opcionalidad ?
r? indica que la expresion r puede aparecer o no. En el caso de
que aparezca solo lo haria una vez.
Cuando queremos usar estos simbolos con su significado ten-
emos que usar la barra de escape, [an-z] significar a cualquier letra
que sea a, guion o z.
Algunos ejemplos:
Numeros
nat = [0-9]+
signedNat = ( + j -)? nat
number = signedNat(‘‘.’’nat)? (E signedNat)?
Identi¯cadores
letter = [a-zA-Z]
digit = [0-9]


8.3. LAS EXPRESIONES DE MAQUINAS FINITAS.

Los AFD se pueden utilizar para reconocer las expresiones regulares asociadas a los
componentes léxicos.

Identificadores

identifier = letter (letter j digit)*
Números naturales y reales
nat = [0-9]+
signedNat = (-)? nat
number = signedNat(‘‘.’’nat)? (E signedNat)?




CISNERO, ADRIAN                                                                       25
JUSTINIANI, ALIKI
REINA DAVID
VON CHONG, ROLANDO

Mais conteúdo relacionado

Mais procurados

Programación
ProgramaciónProgramación
Programacióndahir84
 
Libro 1: introduccion a la programacion y su lenguaje
Libro 1: introduccion a la programacion y su lenguajeLibro 1: introduccion a la programacion y su lenguaje
Libro 1: introduccion a la programacion y su lenguajesocrates12854
 
47356113 lenguaje-tecnico-utilizado-en-los-ambitos-de-sistemas-informatica-ti...
47356113 lenguaje-tecnico-utilizado-en-los-ambitos-de-sistemas-informatica-ti...47356113 lenguaje-tecnico-utilizado-en-los-ambitos-de-sistemas-informatica-ti...
47356113 lenguaje-tecnico-utilizado-en-los-ambitos-de-sistemas-informatica-ti...johanna marquez
 
Lenguaje técnico de informática
Lenguaje técnico de informáticaLenguaje técnico de informática
Lenguaje técnico de informática993431901jaz
 
Programa informático
Programa informáticoPrograma informático
Programa informáticotomorrowland
 
01. lenguajes de programación autor virtuniversidad
01. lenguajes de programación autor virtuniversidad01. lenguajes de programación autor virtuniversidad
01. lenguajes de programación autor virtuniversidadLuisBeltrnAlvinoAlva
 
Diseño e Implementación de una Plataforma E-Learning para la Materia de Tecno...
Diseño e Implementación de una Plataforma E-Learning para la Materia de Tecno...Diseño e Implementación de una Plataforma E-Learning para la Materia de Tecno...
Diseño e Implementación de una Plataforma E-Learning para la Materia de Tecno...Alex Carrión
 
Introducccion programacion
Introducccion programacionIntroducccion programacion
Introducccion programacionAnaisMar22
 
Lenguajes de Programación
Lenguajes de Programación Lenguajes de Programación
Lenguajes de Programación lobi7o
 
Historia Y EvolucióN De Los Lenguajes De ProgramacióN
Historia Y EvolucióN De Los Lenguajes De ProgramacióNHistoria Y EvolucióN De Los Lenguajes De ProgramacióN
Historia Y EvolucióN De Los Lenguajes De ProgramacióNda4
 
Lenguajes de programacion
Lenguajes de programacionLenguajes de programacion
Lenguajes de programacionKarol
 
Introobjetos
IntroobjetosIntroobjetos
Introobjetosayreonmx
 
TIPOS DE LENGUAJES DE PROGRAMACION
TIPOS DE LENGUAJES DE PROGRAMACIONTIPOS DE LENGUAJES DE PROGRAMACION
TIPOS DE LENGUAJES DE PROGRAMACIONPEDRO Borja
 
Cuestinario1
Cuestinario1Cuestinario1
Cuestinario1hoppii
 

Mais procurados (19)

Programación
ProgramaciónProgramación
Programación
 
Linea del tiempo
Linea del tiempoLinea del tiempo
Linea del tiempo
 
Libro 1: introduccion a la programacion y su lenguaje
Libro 1: introduccion a la programacion y su lenguajeLibro 1: introduccion a la programacion y su lenguaje
Libro 1: introduccion a la programacion y su lenguaje
 
47356113 lenguaje-tecnico-utilizado-en-los-ambitos-de-sistemas-informatica-ti...
47356113 lenguaje-tecnico-utilizado-en-los-ambitos-de-sistemas-informatica-ti...47356113 lenguaje-tecnico-utilizado-en-los-ambitos-de-sistemas-informatica-ti...
47356113 lenguaje-tecnico-utilizado-en-los-ambitos-de-sistemas-informatica-ti...
 
Historia Lenguajes y sus Tipos
Historia Lenguajes y sus TiposHistoria Lenguajes y sus Tipos
Historia Lenguajes y sus Tipos
 
Lenguaje técnico de informática
Lenguaje técnico de informáticaLenguaje técnico de informática
Lenguaje técnico de informática
 
Programa informático
Programa informáticoPrograma informático
Programa informático
 
Smith
SmithSmith
Smith
 
01. lenguajes de programación autor virtuniversidad
01. lenguajes de programación autor virtuniversidad01. lenguajes de programación autor virtuniversidad
01. lenguajes de programación autor virtuniversidad
 
Diseño e Implementación de una Plataforma E-Learning para la Materia de Tecno...
Diseño e Implementación de una Plataforma E-Learning para la Materia de Tecno...Diseño e Implementación de una Plataforma E-Learning para la Materia de Tecno...
Diseño e Implementación de una Plataforma E-Learning para la Materia de Tecno...
 
Danelly
DanellyDanelly
Danelly
 
Introducccion programacion
Introducccion programacionIntroducccion programacion
Introducccion programacion
 
Lenguajes de Programación
Lenguajes de Programación Lenguajes de Programación
Lenguajes de Programación
 
Historia Y EvolucióN De Los Lenguajes De ProgramacióN
Historia Y EvolucióN De Los Lenguajes De ProgramacióNHistoria Y EvolucióN De Los Lenguajes De ProgramacióN
Historia Y EvolucióN De Los Lenguajes De ProgramacióN
 
Lenguajes de programacion
Lenguajes de programacionLenguajes de programacion
Lenguajes de programacion
 
Introobjetos
IntroobjetosIntroobjetos
Introobjetos
 
TIPOS DE LENGUAJES DE PROGRAMACION
TIPOS DE LENGUAJES DE PROGRAMACIONTIPOS DE LENGUAJES DE PROGRAMACION
TIPOS DE LENGUAJES DE PROGRAMACION
 
Cuestinario1
Cuestinario1Cuestinario1
Cuestinario1
 
Michael guti
Michael gutiMichael guti
Michael guti
 

Destaque (9)

Anexo
AnexoAnexo
Anexo
 
Indice
IndiceIndice
Indice
 
Infografia
InfografiaInfografia
Infografia
 
Introduccion
IntroduccionIntroduccion
Introduccion
 
Lenguajes ensambladores
Lenguajes ensambladoresLenguajes ensambladores
Lenguajes ensambladores
 
Glosario
GlosarioGlosario
Glosario
 
Presentacion
PresentacionPresentacion
Presentacion
 
Introducción al Diseño de experimentos
 Introducción al Diseño de experimentos Introducción al Diseño de experimentos
Introducción al Diseño de experimentos
 
Libro analisis y diseño de experimentos de mongomery
Libro analisis y diseño de experimentos de mongomeryLibro analisis y diseño de experimentos de mongomery
Libro analisis y diseño de experimentos de mongomery
 

Semelhante a Compiladores universidad educación ciencia tecnología

Compiladores financieros trabajo 10
Compiladores financieros trabajo 10Compiladores financieros trabajo 10
Compiladores financieros trabajo 10anita andrea
 
Sower avansado para el prosesamiento de informacion escribir,descripsion
Sower avansado para el prosesamiento de informacion escribir,descripsionSower avansado para el prosesamiento de informacion escribir,descripsion
Sower avansado para el prosesamiento de informacion escribir,descripsionYadira_Perez
 
Informe software de base
Informe software de baseInforme software de base
Informe software de basemayra tapia
 
Desarrollo de Software
Desarrollo de SoftwareDesarrollo de Software
Desarrollo de SoftwareTDS SENA
 
Proyecto Software de Base
Proyecto Software de BaseProyecto Software de Base
Proyecto Software de BaseKarina Morales
 
Introduccion a los microprocesadores
Introduccion a los microprocesadoresIntroduccion a los microprocesadores
Introduccion a los microprocesadoresRuderocker Billy
 
Informe de computacion 05.07.2014
Informe de computacion 05.07.2014Informe de computacion 05.07.2014
Informe de computacion 05.07.201421586985
 
LECCION-1-INTRODUCCION-A-LA-PROGRAMACION.pdf
LECCION-1-INTRODUCCION-A-LA-PROGRAMACION.pdfLECCION-1-INTRODUCCION-A-LA-PROGRAMACION.pdf
LECCION-1-INTRODUCCION-A-LA-PROGRAMACION.pdfestanisjhv
 
Introduccion a la informatica
Introduccion a la informaticaIntroduccion a la informatica
Introduccion a la informaticaJuan Silva Villa
 
Presentación de jorge salazar 4arto b
Presentación de jorge salazar 4arto bPresentación de jorge salazar 4arto b
Presentación de jorge salazar 4arto blokonene
 
úLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosúLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosRitzy Peralta Ubillus
 
úLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosúLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosRitzy Peralta Ubillus
 
úLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosúLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosRitzy Peralta Ubillus
 

Semelhante a Compiladores universidad educación ciencia tecnología (20)

Software
SoftwareSoftware
Software
 
Compiladores financieros trabajo 10
Compiladores financieros trabajo 10Compiladores financieros trabajo 10
Compiladores financieros trabajo 10
 
Tic[1] para prezi .com
Tic[1]   para  prezi .comTic[1]   para  prezi .com
Tic[1] para prezi .com
 
Sower avansado para el prosesamiento de informacion escribir,descripsion
Sower avansado para el prosesamiento de informacion escribir,descripsionSower avansado para el prosesamiento de informacion escribir,descripsion
Sower avansado para el prosesamiento de informacion escribir,descripsion
 
El computador
El computadorEl computador
El computador
 
Software de base
Software de baseSoftware de base
Software de base
 
Informe software de base
Informe software de baseInforme software de base
Informe software de base
 
Desarrollo de Software
Desarrollo de SoftwareDesarrollo de Software
Desarrollo de Software
 
Proyecto Software de Base
Proyecto Software de BaseProyecto Software de Base
Proyecto Software de Base
 
Introduccion a los microprocesadores
Introduccion a los microprocesadoresIntroduccion a los microprocesadores
Introduccion a los microprocesadores
 
Informe de computacion 05.07.2014
Informe de computacion 05.07.2014Informe de computacion 05.07.2014
Informe de computacion 05.07.2014
 
So1
So1So1
So1
 
LECCION-1-INTRODUCCION-A-LA-PROGRAMACION.pdf
LECCION-1-INTRODUCCION-A-LA-PROGRAMACION.pdfLECCION-1-INTRODUCCION-A-LA-PROGRAMACION.pdf
LECCION-1-INTRODUCCION-A-LA-PROGRAMACION.pdf
 
Introduccion a la informatica
Introduccion a la informaticaIntroduccion a la informatica
Introduccion a la informatica
 
Presentación de jorge salazar 4arto b
Presentación de jorge salazar 4arto bPresentación de jorge salazar 4arto b
Presentación de jorge salazar 4arto b
 
úLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosúLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentos
 
sistemas operativos
sistemas operativossistemas operativos
sistemas operativos
 
El Software
El  SoftwareEl  Software
El Software
 
úLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosúLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentos
 
úLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentosúLtimas investigaciones tecnológicas en elimentos
úLtimas investigaciones tecnológicas en elimentos
 

Último

Desarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfDesarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfJulian Lamprea
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx241521559
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITMaricarmen Sánchez Ruiz
 
International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)GDGSucre
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíassuserf18419
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...silviayucra2
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricKeyla Dolores Méndez
 
Presentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxPresentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxLolaBunny11
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan JosephBRAYANJOSEPHPEREZGOM
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveFagnerLisboa3
 

Último (10)

Desarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfDesarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdf
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnología
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
 
Presentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxPresentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptx
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Joseph
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
 

Compiladores universidad educación ciencia tecnología

  • 1. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES 1. COMPILADOR Un compilador no es más que un traductor, es decir, un programa que nos permite pasar información de un lenguaje a otro. Por ejemplo, un compilador de C nos permite traducir ficheros escritos en lenguaje C a un lenguaje legible para la máquina (ensambladora). En este proceso de compilación no siempre es directo. Esto quiere decir que nos permite que un lenguaje A lo queremos traducir a un lenguaje B, no siempre será recomendable traducir directamente de A a B, si no que puede ser conveniente usar un lenguaje intermedio (que llamaremos X) y entonces diseñaremos un traductor de A a X, y otro de X a B. En este caso, el primer traductor recibe el nombre de front-end mientras que el segundo se llama back-end. El lenguaje A es el lenguaje fuente y el lenguaje B es el lenguaje objeto o destino. En el caso de que el lenguaje fuente sea un lenguaje de programación de alto nivel y el objeto sea un lenguaje de bajo nivel (ensamblador o código de máquina), a dicho traductor se le denomina compilador. Un ensamblador es un compilador cuyo lenguaje fuente es el lenguaje ensamblador. Un intérprete no genera un programa equivalente, sino que toma una sentencia del programa fuente en un lenguaje de alto nivel y la traduce al código equivalente y al mismo tiempo lo ejecuta, con la escasez de memoria de los primeros ordenadores, se puso de moda el uso de intérpretes frente a los compiladores, pues el programa fuente sin traducir y el intérprete juntos daban una ocupación de memoria menor que la resultante de los compiladores. Por ello los primeros ordenadores personales iban siempre acompañados de un intérprete de BASIC (Spectrum, Commodore VIC-20, PC XT de IBM, etc.). La mejor información sobre los errores por parte del compilador así como una mayor velocidad de ejecución del código resultante hizo que poco a poco se impusieran los compiladores. Hoy en día, y con los problemas de las memorias prácticamente resueltas, se puede hablar de un gran predominio de los compiladores frente a los intérpretes, aunque intérpretes como los incluidos a los navegadores de Internet para interpretar el código JVM de Java son la gran excepción. Ventajas de compilar frente a interpretar: • Se compila una vez, se ejecutan varias veces. • En bucles, la compilación genera código equivalente al bucle, pero interpretándolo se traduce tantas veces una línea como veces se repite el bucle. • El compilador tiene una visión global del programa, por lo que la información de mensajes de error es más detallada. • Ventajas del intérprete frente al compilador. • Un intérprete necesita menos memoria que un compilador. En principio eran más abundantes dado que los ordenadores tenían poca memoria. • Permiten una mayor interactividad con el código en tiempo de desarrollo. Un compilador no es un programa que funciona de manera aislada, sino que necesita de otros programas para conseguir su objetivo, para obtener un programa ejecutable a partir de un programa fuente en un lenguaje de alto nivel. Algunos de esos programas son preprocesados, el linker, el depurador y el ensamblador. El preprocesado se ocupa dependiendo del lenguaje de incluir ficheros, expandir macros, eliminar comentarios, y otras tareas similares. CISNERO, ADRIAN 1 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 2. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES Los linker se encargan de construir el fichero ejecutable añadiendo al fichero objeto generado por el compilador las cabeceras necesarias y las funciones de librería utilizadas por el programa fuente. Algunos se encargan de depurador permitiendo asi el compilador ha generado adecuadamente el programa objeto, seguir paso a paso la ejecución de un programa. Finalmente, muchos compiladores, en vez de generar código objeto, generan un programa en lenguaje ensamblador que debe después convertirse en un ejecutable mediante un programa ensamblador. 1.1. CARACTERÍSTICAS DE LOS COMPILADOR Generalmente un compilador se divide en dos partes: * Front End: parte que analiza el código fuente, comprueba su validez, genera el árbol de derivación y rellena los valores de la tabla de símbolos. Parte que suele ser independiente de las plataformas sistema operativo para el que funcionará. * Back End: parte en donde se genera el código máquina exclusivo para una plataforma a partir de lo analizado en el front end. Por lo general el resultado del back end no puede ser ejecutado directamente, se necesita pasar por un proceso de enlazado (linker). Existen varios tipos de compiladores: Compiladores cruzados, Compiladores optimizadores, Compiladores de una sola pasada, Compiladores de varias pasadas, Compiladores JIT. Para el uso de la informática como herramienta de ayuda a la medicina es una realidad en auge. Desde hace algún tiempo muchas de las actividades humanas se han basado en la repetición, en algunos cálculos y del mismo modo que se inventaron operaciones matemáticas básicas para simplificarlas, surgió la necesidad de mejorar las limitadas prestaciones que ofrece la mente del hombre para calcular, a medida que las diversas ciencias se hicieron más complejas. CISNERO, ADRIAN 2 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 3. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES Las primeras aplicaciones desarrolladas fueron dirigidas a resolver tareas (task- oriented) centradas en ciertos servicios o departamentos, siendo sus típicos usuarios secretarias o técnicos empleados para la introducción de datos, usándose sobre todo con fines administrativos, análisis financieros, manejo de bases de datos, sistemas de información de laboratorios o servicios de radiología. Estas aplicaciones han tenido un gran impacto desde el punto de vista administrativo o de organización, pero no están dirigidos a las tareas propiamente médicas, aunque han contribuido a reducir el tiempo dedicado a acceder a este tipo de datos. Posteriormente el mayor beneficio para las actividades propiamente médica ha sido la posibilidad de acceder a la bibliografía médica de una forma rápida mediante la aparición de las bases de datos bibliográficos inicialmente en cederrón y actualmente a través de INTERNET y en los últimos años, se intenta realizar aplicaciones informáticas que vayan dirigidas a resolver problemas (problem-based), más cercanas a la práctica médica, pero encontramos algunos problemas basados fundamentalmente en la ausencia de comprensión de cual es el proceso que seguimos los médicos para tomar una decisión y en la forma de representar el conocimiento y el proceso de razonamiento dentro del ordenador. En estos últimos años se han añadido nuevas aplicaciones informáticas a la medicina, como son las publicaciones electrónicas biomédicas, la telemedicina, impulsada con un gran auge de INTERNET y su World Wide Web y los registros informáticos de la historia clínica. Hemos agregado sobre todo en sistemas privados por el pago por servicio, que obliga a un gran detalle de las actuaciones médicas para identificar el costo de beneficio, precisando crear registros informáticos de alta calidad. La telemedicina es quizá, la que más ventajas aporta y con la que se puede obtener reducción de costos, al poder establecer comunicación con lugares lejanos del mundo, gracias a INTERNET y a los satélites de comunicación, evitando desplazamientos innecesarios y comunicaciones rápidas entre médicos, otros miembros del sistema sanitario e incluso los propios pacientes. En la informática se ha introducido una nueva dimensión en el pensamiento humano, haciendo reales los sueños. No obstante, las aplicaciones informáticas para el manejo clínico del paciente siguen estando en el campo de los proyectos, con honrosas excepciones, existiendo pocos sistemas que sean operativos de una forma generalizada. Los avances en esta tecnología y en el desarrollo de redes de información van a permitir una reducción de costos y un aumento en la calidad del cuidado de nuestros pacientes. El cambio en la enseñanza de las ciencias médicas permitirá entender al ordenador como una importante herramienta de trabajo, que además permitirá cambiar la actual forma memorística e intuitiva de la actuación médica a una forma basada en una CISNERO, ADRIAN 3 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 4. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES estructura con una mayor base de conocimientos, un proceso analítico de los mismos y una mayor eficacia en la toma de decisiones. El médico no solo quedará apoyado por el ordenador sino que se mantendrá liberado de sus tareas más repetitivas y tediosas, pasará a ser el eje sobre el que se apoye todo el soporte informático, al actuar como selector y controlador de los datos de entrada, creador de los protocolos y algoritmos que éste seguirá, interpretando, además, sus resultados y por lo tanto siendo el máximo responsable del sistema. 1.2. FASES DE LOS COMPILADOR En el llamado análisis léxico, el compilador revisa y controla que las palabras estén bien escritas y pertenezcan a algún tipo de token definido dentro del lenguaje, como por ejemplo que sea algún tipo de palabra reservada, o si es el nombre de una variable que este escrita de acuerdo a las pautas definidas del lenguaje. En esta etapa se crea la tabla de símbolos, la cual contiene las variables y el tipo de dato al que pertenece, las constantes literales, el nombre de funciones y los argumentos que reciben. El análisis semántico se encarga de revisar que cada agrupación o conjunto de token tenga sentido, y no sean muy absurdo. En esta etapa se reúne la información sobre los tipos para la fase posterior, en la otra etapa se utilizara la estructura jerárquica de la etapa anterior y así poder determinar los operadores, y operando de expresiones y preposiciones. En el análisis sintáctico como su nombre lo indica se encarga de revisar que los tokens estén ubicados y agrupados de acuerdo a la definición del lenguaje. Dicho esto de otra manera, que los tokens pertenezcan a frases gramaticales validas, que el compilador utiliza para sintetizar la salida. Por lo general las frases gramaticales son representadas por estructuras jerárquicas, por medio de árboles de análisis sintáctico. En esta se completa la tabla de símbolos con la dimensión de los identificadores y los atributos necesarios. Generación de código intermedio, aunque algunos compiladores no la tienen, es bueno saber que existen, en esta etapa se lleva el código del programa fuente a un código interno para poder trabajar más fácilmente sobre él. Esta representación interna debe tener dos propiedades, primero debe ser fácil de representar y segundo debe ser fácil de traducir al código objeto. Optimización de código, se busca obtener el código más corto y rápido posible, utilizando distintos algoritmos de optimización. Etapa de generación de código, se lleva el código intermedio final a código maquina o código objeto, que por lo general consiste en un código maquina re localizable o código ensamblador. Se selecciona las posiciones de memoria para los datos variables y se traduce cada una de las instrucciones intermedias a una secuencia de instrucciones de maquina puro. CISNERO, ADRIAN 4 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 5. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES La tabla de símbolos no es una etapa del proceso de compilación, sino que una tarea, una función que debe realizar el proceso de compilación. En ella se almacenan los identificadores que aparecen en el código fuente puro, como así también los atributos de los mismos, su tipo, su ámbito y en el caso de los procedimientos el número de argumentos el tipo del mismo. En otras palabras una tabla de símbolos es una estructura de datos, que contiene un registro por cada identificador, y sus atributos. La tabla de símbolo es accedida tanto para escritura como parar lectura por todas las etapas. Los detectores de errores o manejador de errores, al igual que la tabla de símbolos no es una etapa del proceso de compilación, si no que es una función, muy importante, pues al ocurrir un error esta función debe tratar de alguna forma el error para así seguir con el proceso de compilación la mayoría de errores son detectados en las etapas de análisis léxico, análisis sintáctico, análisis semántico. 1.3. ESTRUCTURACION DE LOS COMPILADORES La estructura de un compilador, está dividida en cuatro grandes módulos, cada uno independiente del otro, se podría decir que un compilador está formado por cuatros módulos más a su vez. El primero de ellos es el preprocesador, es el encargado de transformar el código fuente de entrada original en el código fuente puro. Es decir en expandir las macros, CISNERO, ADRIAN 5 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 6. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES incluir las librerías, realizar un preprocesado racional con la capacidad de enriquecer a un lenguaje antiguo con recursos más modernos, extender el lenguaje y todo aquello que en el código de entrada sea representativo de una abreviatura para facilitar la escritura del mismo. En el segundo modulo encontramos compilación que recibe el código fuente puro, este es él modulo principal de un compilador, pues si ocurriera algún error en esta etapa el compilador no podría avanzar. En esta etapa se somete al código fuente puro de entrada a un análisis léxico gráfico, a un análisis sintáctico, a un análisis semántico, que construyen la tabla de símbolos, se genera un código intermedio al cual se optimiza para así poder producir un código de salida generalmente en algún lenguaje ensamblador. Para este tercer modulo es el llamado modulo de ensamblado, este modulo no es ni más mi menos que otro compilador pues recibe un código fuente de entrada escrito en ensamblador, y produce otro código de salida, llamado código binario no enlazado. Si por un momento viéramos a este modulo como un programa independiente, veríamos que en este caso los términos programa compilador y proceso de compilación son los mismos. Pues este modulo no es mas que un compilador, que en su interior realiza como su antecesor un análisis léxico gráfico, un análisis sintáctico, un análisis semántico, crea una tabla de símbolos, genera un código intermedio lo optimiza y produce un código de salida llamado código binario no enlazado, y a todo este conjunto de tares se los denomina proceso de compilación. Como se puede ver este compilador (llamado ensamblador) a diferencia de los demás compiladores no realiza una expansión del código fuente original (código fuente de entrada), tiene solamente un proceso de compilación y por supuesto no enlaza el código fuente. Es un compilador que carece de los módulos de preprocesado y enlazado, y donde los módulos de compilación y ensamblado son los mismos. CISNERO, ADRIAN 6 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 7. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES El cuarto y ultimo modulo es el encargado de realizar el enlazado del código de fuente de entrada (código maquina re localizable) con las librerías que necesita, como así también de proveer al código de las rutinas necesarias para poder ejecutarse y cargarse a la hora de llamarlo para su ejecución, modifica las direcciones re localizables y ubica los datos en las posiciones apropiadas de la memoria. Este ultimo modulo es el que produce como salida el código binario enlazado. Ya sea dinámico o estático, al decir dinámico se refiere a que el código producido utiliza librerías dinámicas (librerías ya cargadas en el sistema), esto implica que se obtendrá un código más corto y que se actualizara automáticamente si aparece alguna nueva versión de las librerías, mientras que el estático se refiere al echo que no se realiza enlace con ninguna librería y por lo tanto se obtendrá un código mas largo con una copia de las rutinas de librería que necesita. 2. ELEMENTOS DE UN COMPILADOR Elementos primarios Elemento Descripción Elemento Elemento raíz de cada archivo de configuración usado por las <configuration> aplicaciones de Common Language Runtime y .NET Framework. <system.codedom> Especifica las opciones de configuración del compilador para los (Elemento) proveedores de lenguaje disponibles. Elemento <compilers> Contenedor de elementos de configuración del compilador; contiene CISNERO, ADRIAN 7 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 8. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES el cero o más elementos <compiler>. Elementos secundarios Elemento Descripción <providerOption> Especifica los atributos de versión del compilador para un proveedor (Elemento) de lenguaje. 2.1. TIPOS DE COMPILADORES Esta taxonomía de los tipos de compiladores no es excluyente, por lo que puede haber compiladores que se adscriban a varias categorías: Compiladores cruzados: generan código para un sistema distinto del que están funcionando. Compiladores optimizadores: realizan cambios en el código para mejorar su eficiencia, pero manteniendo la funcionalidad del programa original. Compiladores de una sola pasada: generan el código máquina a partir de una única lectura del código fuente. Compiladores de varias pasadas: necesitan leer el código fuente varias veces antes de poder producir el código máquina. Compiladores JIT (Just In Time): forman parte de un intérprete y compilan partes del código según se necesitan. Pauta de creación de un compilador: En las primeras épocas de la informática, el software de los compiladores era considerado como uno de los más complejos existentes. Los primeros compiladores se realizaron programándolos directamente en lenguaje máquina o en ensamblador. Una vez que se dispone de un compilador, se pueden escribir nuevas versiones del compilador (u otros compiladores distintos) en el lenguaje que compila ese compilador. Actualmente existen herramientas que facilitan la tarea de escribir compiladores ó intérpretes informáticos. Estas herramientas permiten generar el esqueleto del analizador sintáctico a partir de una definición formal del lenguaje de partida, especificada normalmente mediante una gramática formal y barata, dejando únicamente al programador del compilador la tarea de programar las acciones semánticas asociadas 3. EMSAMBLADOR CISNERO, ADRIAN 8 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 9. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES El ensamblador se refiere a un tipo de programa, informático que se encarga de traducir un fichero fuente escrito en un lenguaje ensamblador, a un fichero objeto que contiene código máquina ejecutable directamente por la máquina para la que se ha generado. Los lenguajes ensambladores fueron desarrollados hace muchos años atrás, cuando fueron referidos como lenguajes de programación de segunda generación. Por ejemplo, el SOAP (Symbolic Optimal Assembly Program) era un lenguaje ensamblador para el computador IBM 650. Los lenguajes ensambladores eliminaron mucha de la propensión a errores y del consumo de tiempo de la programación de los lenguajes de primera generación que se necesitaban con los primeros computadores, liberando a los programadores como recordar códigos numéricos y cálculo de direcciones. Una vez fueron ampliamente usados para todo tipo de programación. Sin embargo, los microcomputadores se usaban en gran parte suplantado por los lenguajes de alto nivel, en la búsqueda de una mejorada productividad en programación. Hoy en día, aunque el lenguaje ensamblador es casi siempre manejado y generado por los compiladores, todavía se usa para la manipulación directa del hardware, acceso a instrucciones especializadas del procesador, o para resolver problemas de desempeño crítico. Los usos típicos son drivers de dispositivo, sistemas embebidos de bajo nivel, y sistemas de tiempo real. Un gran número de programas han sido escritos enteramente en lenguaje ensamblador. Los sistemas operativos fueron casi exclusivamente escritos en lenguaje ensamblador hasta la aceptación amplia del lenguaje de programación C. También, muchas aplicaciones comerciales fueron escritas en lenguaje ensamblador, incluyendo una gran cantidad del software escrito por grandes corporaciones para mainframes de IBM. Los lenguajes COBOL y FORTRAN eventualmente desplazaron mucho de este trabajo, aunque un número de organizaciones grandes conservaran las infraestructuras de aplicaciones en lenguaje ensamblador. La mayoría de los primeros microcomputadores confiaron en el lenguaje ensamblador codificado a mano, incluyendo la mayoría de los sistemas operativos y de las aplicaciones grandes. Esto era porque estos sistemas tenían limitaciones severas de recursos, impusieron idiosincráticas arquitecturas de memoria y de pantalla que proporcionaron servicios de sistema limitados con errores. Quizás más importante era la falta de compiladores de primera clase de lenguajes de alto nivel adecuados para el uso en el microcomputador. En un contexto más comercial, las más grandes razones para usar el lenguaje ensamblador era hacer programas con mínimo tamaño, mínima sobrecarga, mayor velocidad y confiabilidad. Los típicos ejemplos de programas grandes en lenguaje ensamblador de ese tiempo son los sistemas operativos IBM PC DOS y aplicaciones tempranas tales como la hoja de cálculo Lotus 1-2-3, y casi todos los juegos populares para la familia Atari 800 de computadores personales. La mayoría de los videojuegos de consola fueron escritos en ensamblador, incluyendo la mayoría de los juegos para la Mega Drive/Genesis y el Super Nintendo Entertainment System. CISNERO, ADRIAN 9 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 10. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES Según algunos insiders de la industria, el lenguaje ensamblador era el mejor lenguaje de programación a usar para obtener el mejor desempeño del Sega Saturn, una consola para la cual era notoriamente desafiante desarrollar y programar juegos. El popular juego de arcade NBA Jam es otro ejemplo. El ensamblador ha sido por largo trecho, el lenguaje de desarrollo primario en los computadores hogareños Commodore 64, Atari ST, así como el ZX Spectrum. Esto fue así en gran parte porque los dialectos del BASIC en estos sistemas ofrecieron insuficiente velocidad de ejecución, así como insuficientes características para aprovechar completamente el hardware disponible. Algunos sistemas, más notablemente el Amigo, incluso tienen IDEs con características de depuración y macros altamente avanzados, tales como el freeware ASM-One assembler, comparable a las del Microsoft Visual Studio (el ASM-Uno precede al Microsoft Visual Studio). El ensamblador para el VIC-20 fue escrito por Don French y publicado por French Silk. Con 1639 bytes de longitud, se cree que es el más pequeño ensamblador simbólico jamás escrito. El ensamblador soportaba el direccionamiento simbólico usual y la definición de cadenas de caracteres o cadenas hexadecimales. También permitía expresiones de direcciones que podían combinarse con las operaciones de adición, substracción, multiplicación, división, AND lógico, OR lógico, y exponenciación. Han habido siempre debates sobre la utilidad y el desempeño del lenguaje ensamblador relativo a lenguajes de alto nivel. El lenguaje ensamblador tiene algunas especificaciones donde son importante. Pero, en general, los modernos compiladores de optimización para traducir lenguajes de alto nivel en el código que puede correr tan rápidamente como el lenguaje ensamblador escrito a mano, a pesar de los contra ejemplos que pueden ser encontrados. La complejidad de los procesadores modernos y del subsistema de memoria hace la optimización efectiva cada vez más difícil para los compiladores, así como para los programadores en ensamblador. Adicionalmente, y para la consternación de los amantes de la eficiencia, el desempeño cada vez mayor del procesador ha significado que la mayoría de los CPU estén desocupados la mayor parte del tiempo, con retardos causados por embotellamientos predecibles tales como operaciones de entrada/salida y paginación de memoria. Esto ha hecho la velocidad de ejecución cruda del código un problema para muchos programadores. Hay algunas situaciones en las cuales los profesionales pudieran elegir utilizar el lenguaje ensamblador. Por ejemplo cuando: • es requerido un ejecutable binario independiente (stand-alone), es decir uno que deba ejecutarse sin recursos a componentes de tiempo de ejecución o a bibliotecas asociadas con un lenguaje de alto nivel; ésta es quizás la situación más común. Son programas empotrados que solo almacenan una pequeña cantidad de memoria y el dispositivo está dirigido para hacer tareas para un simple propósito. Ejemplos consisten en teléfonos, sistemas de combustible e ignición para automóviles, sistemas de control del aire acondicionado, sistemas de seguridad, y sensores. • interactuando directamente con el hardware, por ejemplo en drivers de dispositivo y manejadores de interrupción. CISNERO, ADRIAN 10 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 11. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES • usando instrucciones específicas del procesador no explotadas o disponibles por el compilador. Un ejemplo común es la instrucción de rotación bit wise en el núcleo de muchos algoritmos de cifrado. • creando funciones vectorizadas para programas en lenguajes de alto nivel como C. En el lenguaje de alto nivel esto es a veces ayudado por funciones intrínsecas del compilador que mapean directamente a los mnemónicos del SIMD, pero sin embargo resulta en una conversión de ensamblador de uno a uno para un procesador de vector asociado. • es requerida la optimización extrema, en un bucle interno en un algoritmo intensivo en el uso del procesador. Los programadores de juegos toman ventaja de las habilidades de las características del hardware en los sistemas, permitiendo a los juegos correr más rápidamente. También las grandes simulaciones científicas requieren algoritmos altamente optimizados, ej, álgebra lineal con BLAS o la transformada de coseno discreta la versión SIMD en ensamblador del x264, una biblioteca para codificar streams de video. • un sistema con severas limitaciones de recursos un sistema empotrado debe ser codificado a mano para maximizar el uso de los limitados recursos; pero esto está llegando a ser menos común a medida que el precio del procesador decrece y el desempeño mejora. • no existe ningún lenguaje de alto nivel, en un procesador nuevo o especializado. • escribiendo programas de tiempo real que necesitan sincronización y respuestas precisas, tales como sistemas de navegación de vuelo, y equipo médico. En un sistema fly-by-wire, vuelo por mandos eléctricos, la telemetría debe ser interpretada y hay que actuar dentro de limitaciones estrictas de tiempo. Tales sistemas deben eliminar fuentes de retrasos impredecibles, que pueden ser creados para algunos lenguajes interpretados, recolección de basura automática, operaciones de paginación, o multitarea preventiva. Sin embargo, algunos lenguajes de alto nivel incorporan componentes de tiempo de ejecución e interfaces de sistema operativo que pueden introducir tales retrasos. Elegir el ensamblador o lenguajes de bajo nivel para tales sistemas da a los programadores mayor visibilidad y control sobre el proceso de los detalles. • es requerido control total sobre el ambiente, en situaciones de seguridad extremadamente alta donde nada puede darse por sentado. • se escriben virus de computadora, bootloaders, ciertos drivers de dispositivo, u otros elementos muy cerca del hardware o al sistema operativo de bajo nivel • se escriben simuladores del conjunto de instrucciones para monitoreo, trazado y depuración de errores donde la sobrecarga adicional es mantenida al mínimo • se hace ingeniería inversa en binarios existentes que pueden o no haber sido escritos originalmente en un lenguaje de alto nivel, por ejemplo al crackear la protección anticopia del software propietario. • se hace ingeniería inversa y modificación de video juegos, también denominado ROM hacking, que es posible por medio de varios métodos. El más ampliamente implementado es alterando el código del programa a nivel de lenguaje ensamblador • se escribe código automodificable, algo para lo que el lenguaje ensamblador se presta bien • se escriben juegos y otros softwares para calculadoras gráficas • se escribe software compilador que genera código ensamblador, y por lo tanto los desarrolladores deben ser programadores de lenguaje ensamblador. • se escriben algoritmos criptográficos que siempre deben tomar estrictamente el mismo tiempo para ejecutar, previniendo ataques de tiempo. CISNERO, ADRIAN 11 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 12. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES Sin embargo, el lenguaje ensamblador es todavía enseñado en la mayoría de los programas de ciencias de la computación e ingeniería electrónica. Aunque hoy en día, pocos programadores trabajan regularmente con el lenguaje ensamblador como una herramienta, los conceptos fundamentales continúan siendo muy importantes. Tales tópicos fundamentales, como aritmética binaria, asignación de memoria, procesamiento del stack, codificación de conjunto de caracteres, procesamiento de interrupciones, y diseño de compiladores, serían duros de estudiar en detalle sin la comprensión de cómo el computador opera a nivel del hardware. Puesto que el comportamiento del computador es fundamentalmente definido por su conjunto de instrucciones, la manera lógica de aprender tales conceptos es estudiar un lenguaje ensamblador. La mayoría de los computadores modernos tienen un conjunto de instrucciones similares. Por lo tanto, estudiar un solo lenguaje ensamblador es suficiente para aprender: i) los conceptos básicos; ii) reconocer situaciones donde el uso de lenguaje ensamblador puede ser apropiado; y iii) ver cómo el código ejecutable eficiente puede ser creado por los lenguajes de alto nivel18 El lenguaje ensamblador hard-coded es típicamente usado en el ROM de arranque del sistema (BIOS en los sistemas compatible IBM PC). Este código de bajo nivel es usado, entre otras cosas, para inicializar y probar el hardware del sistema antes de cargar el sistema operativo, y está almacenado en el ROM. Una vez que ha tomado lugar un cierto nivel de inicialización del hardware, la ejecución se transfiere a otro código, típicamente escrito en lenguajes de alto nivel; pero el código corriendo inmediatamente después de que es aplicada la energía usualmente está escrito en lenguaje ensamblador. Lo mismo es cierto para los boot loaders. Muchos compiladores traducen lenguajes de alto nivel a lenguaje ensamblador primero, antes de la compilación completa, permitiendo que el código en ensamblador sea visto para propósitos de depuración y optimización. Lenguajes de relativo bajo nivel, como C, con frecuencia proveen sintaxis especial para empotrar lenguaje ensamblador en cada plataforma de hardware. El código portable del sistema entonces puede usar estos componentes específicos a un procesador a través de una interface uniforme. El lenguaje ensamblador también es valioso en ingeniería inversa, puesto que muchos programas solamente son distribuidos en una forma de código de máquina. El código de máquina es usualmente fácil de trasladar hacia lenguaje ensamblador para luego ser cuidadosamente examinado en esta forma, pero es muy difícil de trasladar hacia un lenguaje de alto nivel. Herramientas como Interactive Disassembler, hacen uso extenso del desensamblador para tales propósitos. Un nicho que hace uso del lenguaje ensamblador es el demoscene. Ciertas competiciones requieren a los concursantes restringir sus creaciones a un muy pequeño tamaño 256 bytes, 1 KB, 4 KB ó 64 KB, y el lenguaje ensamblador es el lenguaje de preferencia para alcanzar este objetivo. Cuando los recursos son una preocupación, es una necesidad la codificación en ensamblador, especialmente en sistemas constreñidos por el procesamiento del CPU, como los primeros modelos del Amiga, y el Commodore 64. El código optimizado en CISNERO, ADRIAN 12 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 13. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES ensamblador es escrito "a mano" por los programadores en un intento de minimizar el número de ciclos de CPU usados. Las limitaciones del CPU son tan grandes que cada ciclo cuenta. Usar tales métodos ha habilitado, a sistemas como el Commodore 64, para producir gráficos en 3D en tiempo real con efectos avanzados, una hazaña que puede ser considerada improbable o incluso imposible para un sistema con un procesador de 0.99 MHz. 4. ÁRBOLES PARTE SEMANTICAS. Hemos visto que las deducciones pueden hacerse atendiendo a los problemas de derivación, realizándose esta última a través de la aplicación de las reglas básicas o derivadas. Pero también podemos utilizar otro criterio: el semántico, según el cual, y suponiendo que la deducción sea correcta, no podemos obtener una conclusión falsa de premisas verdaderas. La semántica atiende por una parte al hecho al que se refiere la proposición y, por otra parte, a su valor de verdad. El método de las tablas semánticas supone una búsqueda de contraejemplos que invaliden el argumento. Es una especie de reducción al absurdo, en la que se supone la verdad de la negación de la conclusión y, a partir de ella, se llega a una contradicción. CISNERO, ADRIAN 13 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 14. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES CISNERO, ADRIAN 14 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 15. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES 4.1. COMO SE IDENTIFICAN El analizador semántico verificara que en este caso cada operador tenga los operadores permitidos. = / id1 + / id2 + / id3 tipo_ent | 10 5. GRAMATICA BNF Una especificación de BNF es un sistema de reglas de derivación, escrito como: <simbolo> ::= <expresión con símbolos> donde <símbolo> es un no terminal, y la expresión consiste en secuencias de símbolos o secuencias separadas por la barra vertical, '|', indicando una opción, el conjunto es una posible substitución para el símbolo a la izquierda. Los símbolos que nunca aparecen en un lado izquierdo son terminales. Ejemplo Como ejemplo, considere este BNF para una dirección postal de los EE.UU. <dirección postal> ::= <nombre> <dirección> <apartado postal> <personal> ::= <primer nombre> | <inicial> "." <nombre> ::= <personal> <apellido> [<trato>] <EOL> | <personal> <nombre> <dirección> ::= [<dpto>] <número de la casa> <nombre de la calle> <EOL> <apartado postal> ::= <ciudad> "," <código estado> <código postal> <EOL> Esto se traduce a español como: • Una dirección postal consiste en un nombre, seguido por una dirección, seguida por un apartado postal. • Una parte "personal" consiste en un nombre o una inicial seguido(a) por un punto. • Un nombre consiste de: una parte personal seguida por un apellido seguido opcionalmente por una jerarquía o el trato que se la da a la persona (Jr., Sr., o número dinástico) y un salto de línea (end-of-line), o bien una parte personal seguida por un nombre (esta regla ilustra el uso de la repetición en BNFs, cubriendo el caso de la gente que utiliza múltiples nombres y los nombres medios o las iniciales). CISNERO, ADRIAN 15 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 16. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES • Una dirección consiste de una especificación opcional del departamento, seguido de un número de casa, seguido por el nombre de la calle, seguido por un salto de línea (end-of-line). • Un apartado postal consiste de una ciudad, seguida por una coma, seguida por un código del estado (recuerde que es un ejemplo que ocurre en EE.UU.), seguido por un código postal y este seguido por un salto de línea (end-of-line). Observe que muchas cosas (tales como el formato de una parte personal, de una especificación del apartamento, o código postal) están dejadas sin especificar aquí. Si es necesario, pueden ser descritas usando reglas adicionales de BNF, o dejadas como abstracción si es inaplicable para el propósito actual. Otros ejemplos Bastante interesante, la sintaxis de BNF se puede representar en BNF como sigue: <syntax> ::= <rule> [<syntax>] <rule> ::= <whitespace> "<" <rule-name> ">" <whitespace> "::=" <expression> <whitespace> <line-end> <expression> ::= <whitespace> <or-expression> <or-expression> ::= <whitespace> <list-expression> [ "|" <or-expression> ] <list-expression> ::= <whitespace> ("<" <rule-name> ">" | <QUOTE> <text> <QUOTE> | "(" <expression> ")" | "[" <expression> "]") [<list-expression>] <whitespace> ::= [" " <whitespace>] <line-end> ::= [<whitespace>] <EOL> [<line-end>] Esto asume que no hay Whitespace necesario para la interpretación apropiada de la regla. El <QUOTE> se presume para ser el carácter ", y el <EOL> para ser el fin de línea apropiado especificado (en ASCII, retorno de carro o línea nueva, dependiendo del sistema operativo). El <rule-name> y el <text> deben ser substituidos con nombre/etiqueta o el texto literal de una regla declarada, respectivamente. Hay muchas variantes y extensiones de BNF, posiblemente conteniendo algunos o todos los comodines de expresiones regulares como un "*" o "+". El Extended Backus- Naur form (EBNF) es una variante común. De hecho el ejemplo anterior no es la forma pura inventada para el informe del ALGOL 60. La notación de los corchetes "[ ]" fue introducida algunos años más tarde en la definición de PL/I de la IBM pero ahora se reconoce universal. La ABNF es otra extensión usada comúnmente para describir protocolos del IETF. Las expresiones gramaticales de analizadores sintácticos construidas en BNF y las notaciones de expresión regular para formar una clase alternativa de la gramática formal, que es esencialmente analítica más que generativa en carácter. Muchas especificaciones de BNF disponibles en línea tienen como propósito ser legibles a simple vista y no son especificaciones formales. Estas incluyen con frecuencia algunas de estas reglas sintácticas y extensiones: CISNERO, ADRIAN 16 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 17. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES • Elementos opcionales son presentados entre paréntesis cuadrados. Por ejemplo [<elemento-x>] • Los elementos que se repiten 0 o más veces son presentados entre paréntesis de llave o terminados con un asterisco. Por ejemplo <palabra> ::= <letra> {<letra>} • Los elementos que se repiten 1 o más veces son terminados con un '+' • Los terminales pueden aparecer en negrillas y los no-terminales en texto normal en lugar de utilizar itálicas o paréntesis de ángulo • Alternativas opcionales son separadas por el símbolo '|' Cuando se requiere agrupar varios elementos, se hace con paréntesis simple 5.1. SU DEFINICION La notación de Backus-Naur, también conocida por sus denominaciones inglesas Backus-Naur form (BNF), Backus-Naur formalism o Backus normal form, es una metasintaxis usada para expresar gramáticas libres de contexto: es decir, una manera formal de describir lenguajes formales. El BNF se utiliza extensamente como notación para las gramáticas de los lenguajes de programación de la computadora, de los sistemas de comando y de los protocolos de comunicación, así como una notación para representar partes de las gramáticas de la lengua natural (por ejemplo, el metro en la poesía de Venpa). La mayoría de los libros de textos para la teoría o la semántica del lenguaje de programación documentan el lenguaje de programación en BNF. Algunas variantes, tales como la Augmented Backus-Naur form (ABNF) y la Extended Backus–Naur Form (EBNF), tienen su propia documentación. Con la aparición de la notación BNF - desarrollada en primer lugar por Backus en 1960 cuando trabajaba en un borrador del ALGOL 60, modificada en 1963 por Naur y formalizada por Knuth en 1964 - se tiene una guía para el desarrollo del análisis sintáctico. Los diversos métodos de parsers ascendentes y descendentes se desarrollan durante la década de los 60. En 1959, Sheridan describe un método de parsing de FORTRAN que introducía paréntesis adicionales alrededor de los operandos para ser capaz de analizar las expresiones. Más adelante, Floyd introduce la técnica de la precedencia de operador y el uso de las funciones de precedencia. A mitad de la década de los 60, Knuth define las gramáticas LR y describe la construcción de una tabla canónica de parser LR. Por otra parte, el uso por primera vez de un parsing descendente recursivo tuvo lugar en el año 1961. En el año 1968 se estudian y definen las gramáticas LL así como los parsers predictivos. También se estudia la eliminación de la recursión a la izquierda de producciones que contienen acciones semánticas sin afectar a los valores de los atributos. En los primeros años de la década de los 70, se describen los métodos SLR y LALR de parser LR. Debido a su sencillez y a su capacidad de análisis para una gran variedad de lenguajes, la técnica de parsing LR va a ser la elegida para los generadores automáticos de parsers. A mediados de los 70, Johnson crea el generador CISNERO, ADRIAN 17 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 18. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES de analizadores sintácticos YACC para funcionar bajo un entorno UNIX . Junto al análisis sintáctico, también se fue desarrollando el análisis semántico. La idea de transcribir la estructura del lenguaje con reglas de reescritura se remontan cuando menos al trabajo del gramático indio Panini (hacia el 460 a. C.), que la utilizó en su descripción de la estructura de palabras del idioma sánscrito (algunos incluso han sugerido renombrar BNF a Forma Panini-Backus). Lingüïstas estadounidenses como Leonard Bloomfield y Zellig Harris llevaron esta idea un paso más adelante al tratar de formalizar el lenguaje y su estudio en términos de definiciones formales y procedimientos (1920-1960). Noam Chomsky, maestro de lingüística de alumnos de teoría de la información del MIT, combinó la lingüística y las matemáticas, tomando esencialmente el formalismo de Axel Thue como la base de su descripción de la sintaxis del lenguaje natural. También introdujo una clara distinción entre reglas generativas (de la gramática libre de contexto) y reglas transformativas (1956). John Backus, un diseñanor de lenguajes de programación de IBM, adoptó las reglas generativas de Chomsky para describir la sintaxis del nuevo lenguaje de programación IAL, conocido en la actualidad como ALGOL 58 (1959), presentando en el primer Congreso de Computación Mundial (World Computer Congress) el artículo "The syntax and semantics of the proposed international algebraic language of the Zurich ACM- GAMM Conference". Peter Naur, en su reporte sobre ALGOL 60 de 1963, identificó la notación de Backus como la Forma Normal de Backus (Backus Normal Form), y la simplificó para usar un conjunto de símbolos menor, pero a sugerencia de Donald Knuth, su apellido fue agregado en reconocimiento a su contribución, reemplazando la palabra "Normal" por Naur, dado que no se trata de una forma normal en ningún sentido, a diferencia, por ejemplo de la Forma Normal de Chomsky. 6. LAS MAQUINAS DE TURING Una máquina de Turing (MT) es un modelo computacional que realiza una lectura/ escritura de manera automática sobre una entrada llamada cinta, generando una salida en esta misma. Este modelo está formado por un alfabeto de entrada y uno de salida, un símbolo especial llamado blanco (normalmente b, Δ o 0), un conjunto de estados finitos y un conjunto de transiciones entre dichos estados. Su funcionamiento se basa en una función de transición, que recibe un estado inicial y una cadena de caracteres (la cinta, la cual puede ser infinita) pertenecientes al alfabeto de entrada. La máquina va leyendo una celda de la cinta en cada paso, borrando el símbolo en el que se encuentra posicionado su cabezal y escribiendo un nuevo símbolo perteneciente al alfabeto de salida, para luego desplazar el cabezal a la izquierda o a la derecha (solo una celda a la vez). Esto se repite según se indique en la función de transición, para finalmente detenerse en un estado final o de aceptación, representando así la salida. CISNERO, ADRIAN 18 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 19. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES La entrada de una máquina de Turing viene determinada por el estado actual y el símbolo leído, un par (estado, símbolo), siendo el cambio de estado, la escritura de un nuevo símbolo y el movimiento del cabezal, las acciones a tomar en función de una entrada. En el caso de que para cada par (estado, símbolo) posible exista a lo sumo una posibilidad de ejecución, se dirá que es una máquina de Turing determinista, mientras que en el caso de que exista al menos un par (estado, símbolo) con más de una posible combinación de actuaciones se dirá que se trata de una máquina de Turing no determinista. La función de transición δ en el caso no determinista, queda definida como sigue: ¿Cómo sabe una máquina no determinista qué acción tomar de las varias posibles? Hay dos formas de verlo: una es decir que la máquina es "el mejor adivino posible", esto es, que siempre elige la transición que finalmente la llevará a un estado final de aceptación. La otra es imaginarse que la máquina se "clona", bifurcándose en varias copias, cada una de las cuales sigue una de las posibles transiciones. Mientras que una máquina determinista sigue un único "camino computacional", una máquina no determinista tiene un "árbol computacional". Si cualquiera de las ramas del árbol finaliza en un estado de aceptación, se dice que la máquina acepta la entrada. La capacidad de cómputo de ambas versiones es equivalente; se puede demostrar que dada una máquina de Turing no determinista existe otra máquina de Turing determinista equivalente, en el sentido de que reconoce el mismo lenguaje, y viceversa. No obstante, la velocidad de ejecución de ambos formalismos no es la misma, pues si una máquina no determinista M reconoce una cierta palabra de tamaño n en un tiempo , la máquina determinista equivalente reconocerá la palabra en un tiempo . Es decir, el no determinismo permitirá reducir la complejidad de la solución de los problemas, permitiendo resolver, por ejemplo, problemas de complejidad exponencial en un tiempo polinómico. Una máquina de Turing con una sola cinta puede definirse como una 7-tupla donde: CISNERO, ADRIAN 19 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 20. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES • es un conjunto finito de estados. • es un conjunto finito de símbolos distinto del espacio en blanco, denominado alfabeto de máquina o de entrada. • es un conjunto finito de símbolos de cinta, denominado alfabeto de cinta ( ). • es el estado inicial. • es un símbolo denominado blanco, y es el único símbolo que se puede repetir un número infinito de veces. • es el conjunto de estados finales de aceptación. • es una función parcial denominada función de transición, donde es un movimiento a la izquierda y es el movimiento a la derecha. Existen en la literatura un abundante número de definiciones alternativas, pero todas ellas tienen el mismo poder computacional, por ejemplo se puede añadir el símbolo como símbolo de "no movimiento" en un paso de cómputo. 7. ANALISIS SINTACTICO. Como ya sabemos la sintaxis en lógica es la forma correcta de escribir una fórmula y la semántica es lo que significa. Como en lógica solamente tenemos dos valores una fórmula solamente puede ser verdadera o falsa. Para determinar su valor seguimos las reglas simples que dimos en las definiciones básicas de acuerdo a su tabla de verdad. Esto lo hacemos mediante interpretaciones. Una interpretación de una fórmula es un conjunto de valores que se les asignan a sus proposiciones atómicas. Al interpretar una fórmula lo que finalmente vamos a obtener es un valor de verdad, bien sea verdadero o falso. Pero para poder encontrarlo muchas veces el proceso en laborioso porque puede estar formada por varias proposiciones atómicas. Primeramente se le asignan valores de verdad a los átomos y se puede encontrar el valor de la expresión. Si deseamos hacerlo en general, debemos analizar todas las posibilidades, esto se puede hacer construyendo una tabla de verdad. Para fines prácticos cuando se tienen varios átomos las tablas de verdad no resultan prácticas por lo que analizaremos solamente expresiones con tres átomos como máximo. Por supuesto que se puede construir una tabla para un número mayor de átomos, pero notemos que por cada átomo que se aumente el número de renglones se duplica. CISNERO, ADRIAN 20 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 21. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES Esto es, para un átomos son dos renglones, para dos átomos son cuatro, para tres átomos son ocho, para cuatro dieciséis, etc. Algoritmo para construir una tabla de verdad de una fórmula en lógica de proposiciones. Escribir la fórmula con un número arriba de cada operador que indique su jerarquía. Se escriben los enteros positivos en orden, donde el número 1 corresponde al operador de mayor jerarquía. Cuando dos operadores tengan la misma jerarquía, se le asigna el número menor al de la izquierda. Construir el árbol sintáctico empezando con la fórmula en la raíz y utilizando en cada caso el operador de menor jerarquía. O sea, del número mayor al menor. Numerar las ramas del árbol en forma secuencial empezando por las hojas hacia la raíz, con la única condición de que una rama se puede numerar hasta que estén numerados los hijos. Para empezar con la numeración de las hojas es buena idea hacerlo en orden alfabético, así todos obtienen los renglones de la tabla en el mismo orden para poder comparar resultados. Escribir los encabezados de la tabla las fórmulas siguiendo la numeración que se le dió a las ramas en el árbol sintáctico. Al asignarle a los átomos, las hojas del árbol, todos los posibles valores de verdad de acuerdo al orden establecido. Por supuesto que el orden es arbitrario, pero como el número de permutaciones es n!, conviene establecer un orden para poder comparar resultados fácilmente. Asignar valor de verdad a cada una de las columnas restantes de acuerdo al operador indicado en el árbol sintáctico utilizando la tabla de verdad correspondiente, conviene aprenderse de memoria las tablas de los operadores, al principio pueden tener un resumen con todas las tablas mientras se memorizan. La última columna, correspondiente a la fórmula original, es la que indica los valores de verdad posibles de la fórmula para cada caso. Ejemplo. Construya la tabla de verdad de las siguientes expresiones lógicas: i) (p → ¬q) v (¬p v r) ii) p → (q ^ r) CISNERO, ADRIAN 21 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 22. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES iii) (p → ¬ r) ↔ (q v p) iv) ¬(p ¬ q) → ¬ r v) (¬p ^ q) → ¬(q v ¬r) Solución: i) Seguimos los pasos del algoritmo con la fórmula (p → ¬q) v (¬p v r) 1. Vemos que los operadores de los paréntesis tienen mayor jerarquía, empezamos por el paréntesis izquierdo por lo que la fórmula con jerarquías marcadas sería: 7.1. LIMITACION El análisis semántico toma su nombre por requerir información relativa al significado del lenguaje, fuera del alcance del análisis sintáctico. Mediante el empleo de gramáticas sensibles al contexto tipo 1 se podrían comprobar características del lenguaje. Ejemplo: la utilización de una variable requiere que esté declarada previamente. Un autómata de tipo 1 es complejo de implementar e ineficiente. Solución: Análisis semántico a partir de gramáticas y autómatas de tipo 2 sintáctico e implementación de reglas semánticas del lenguaje. Se emplean estructuras de datos auxiliares como las tablas de símbolos. El análisis semántico realiza todas las comprobaciones del lenguaje necesarias y no llevadas a cabo por el sintáctico 7.2. COMO SE UTILIZA El analizador sintáctico impone una estructura jerárquica a la cadena de componentes léxicos, generada por el analizador léxico, que es representada en forma de un árbol sintáctico. = / id1 + / id2 + / id3 10 CISNERO, ADRIAN 22 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 23. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES 7.3. DESCENDENTE Y ASCENDENTE El estudio de gramáticas atribuidas se basa en la distinción de atributos heredados y sintetizados. Determinará cómo podremos implementarlas. Sintetizados: se calculan ascendentemente en el árbol sintáctico. Heredados: cálculo descendente. 8. ANALISIS LEXICO Analizador léxico (scanner): lee la secuencia de caracteres del programa fuente, carácter a carácter, y los agrupa para formar unidades con significado propio, los componentes léxicos (tokens en ingles). Estos componentes léxicos representan: palabras reservadas: if, while, do, . . .identificadores: asociados a variables, nombres de funciones, tipos definidos por el usuario, etiquetas,... Por ejemplo: posición, velocidad, tiempo, . . . operadores: = * + - / == > < & ! = . . . símbolos especiales: ; ( ) [ ] f g ... constantes numéricas: literales que representan valores enteros, en coma dotante, etc, 982, 0xF678, -83.2E+2,... constantes de caracteres: literales que representan cadenas concretas de caracteres, hola mundo",... El analizador léxico opera bajo petición del analizador sintáctico devolviendo un componente léxico conforme el analizador sintáctico lo va necesitando para avanzar en la gramática. Los componentes léxicos son los símbolos terminales de la gramática. Suele implementarse como una subrutina del analizador sintáctico. Cuando recibe la orden obtiene el siguiente componente léxico, el analizador léxico lee los caracteres de entrada hasta identificar el siguiente componente lexico.analizador El analizador léxico lee los caracteres del programa fuente, y verifica que correspondan a una secuencia lógica (identificador, palabra reservada etc.). Esta CISNERO, ADRIAN 23 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 24. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES secuencia de caracteres recibe el nombre componente léxico o lexema. En este caso el analizador léxico verifica si el identificador id1 (nombre interno para "suma") encontrado se halla en la tabla de símbolos, si no esta produce un error porque todavía no fue declarado, si la preposición hubiese sido la declaración del identificador "suma" en lenguajes C, C++ (int suma;) el analizador léxico agregaría un identificador en la tabla de símbolos, y así sucesivamente con todos los componentes léxicos que aparezcan. id1= id2+ id3 * 10 8.1. BUFFER DE ENTRADA El proceso de lectura de los caracteres de la entrada y formar los componentes léxicos es lo mas costoso en tiempo en el proceso de traducción. Es importante implementarlo eficientemente. Se utiliza un buffer dividido en dos mitades de tamaño N caracteres, donde N es un bloque de disco (1024, 4096). Se leen N caracteres de la entrada en cada mitad del buffer con una única orden de lectura. Se mantienen dos apuntadores. Uno marca el inicio del lexema y el otro el carácter actual que se mueve hasta encontrar una subcadena que corresponde con un patrón. Una vez reconocido un componente léxico ambos apuntadores se colocan en la misma posición y justo detrás del lexema reconocido. buffer de entrada if avanza est´a final primera mitad then recargar segunda mitad; avanza = avanza+1; else if avanza est´a final segunda mitad then recargar primera mitad; pasar avanza a principio primera mitad; else avanza = avanza+1; 8.2. LAS EXPRESIONES REGULARES Expresiones Regulares: Los componentes léxicos se especifican haciendo uso de expresiones regulares. Además de las tres operaciones básicas: concatenación, repetición (*) y alternativas (j) vamos a usar los siguientes meta símbolos: Una o mas repeticiones + r+ indica una o mas repeticiones de r (0j1)+ = (0j1)(0j1)* Cualquier carácter. .*b.* indica cualquier cadena que contiene una letra b Un rango de caracteres [ ] (clase) [a-z] indica cualquier carácter entre la a y z minúsculas [a-zA-Z] indica cualquier letra del abecedario minúscula o mayúscula [0-9] indica cualquier digito de 0 a 9 [abc] indica ajbjc Cualquier caracter excepto un conjunto dado ~ CISNERO, ADRIAN 24 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO
  • 25. NIVERSIDAD METROPOLITANA DE EDUCACION, CIENCIA Y TECNOLOGÍA MATERIA: COMPILADORES ~ (ajb) indica cualquier caracter que no sea una a o b Opcionalidad ? r? indica que la expresion r puede aparecer o no. En el caso de que aparezca solo lo haria una vez. Cuando queremos usar estos simbolos con su significado ten- emos que usar la barra de escape, [an-z] significar a cualquier letra que sea a, guion o z. Algunos ejemplos: Numeros nat = [0-9]+ signedNat = ( + j -)? nat number = signedNat(‘‘.’’nat)? (E signedNat)? Identi¯cadores letter = [a-zA-Z] digit = [0-9] 8.3. LAS EXPRESIONES DE MAQUINAS FINITAS. Los AFD se pueden utilizar para reconocer las expresiones regulares asociadas a los componentes léxicos. Identificadores identifier = letter (letter j digit)* Números naturales y reales nat = [0-9]+ signedNat = (-)? nat number = signedNat(‘‘.’’nat)? (E signedNat)? CISNERO, ADRIAN 25 JUSTINIANI, ALIKI REINA DAVID VON CHONG, ROLANDO