INSTITUTO TECNOLOGICO SUPERIOR DE SAN MARTIN TEXMELUCAN PROGRAMACION DE SISTEMAS 5° “A” TAREAS ABILENNE CORTES CONTRERAS YESENIA PEREZ REYES INGENIERIA EN SISTEMAS COMPUTACIONALES PORTAFOLIO DE EVIDENCIAS CONTENIDO 1.1 ¿Qué es y que estudia la programación de sistemas? 1.2 Herramientas desarrolladas con la teoría de programación de sistemas 1.3 Lenguajes 1.3.1 Lenguajes naturales. 1.3.2 Lenguajes artificiales. 1.3.3 Proceso de la comunicación. 1.4 Traductor y su estructura. 1.4.1 Ensambladores. 1.4.2 Compiladores. 1.4.3 Interpretes. 1.5 Generadores de código para compiladores (compilador de compilador). 1.1 ¿Qué es y qué estudia la programación de sistemas? Son los programas que residen en un sistema de computación. Su función es proporcionar al usuario o programador una interface más eficiente y practica con relación al hardware de la máquina. La P. de S. estudia cómo están implementados cada uno de los programas de un Sistema. PROGRAMACIÓN DE SISTEMAS: Conjunto de reglas para crear soluciones a problemas computables. Conjunto de herramientas que nos permiten crear software de base que son de utilidad para interactuar con la máquina. SOFTWARE DE BASE: Compilador, Querys, Sistema Operativo, Cargador. AUTÓMATA: Son las cadenas posibles que aceptan un lenguaje. EXPRESIONES REGULARES: Conjunto de símbolos que aceptan una palabra reservada. Programa: conjunto de instrucciones que ejecuta una computadora para realizar una actividad. Sistema: conjunto de elementos autónomos que trabajan en armonía para alcanzar un objetivo en común. Tipos de sistemas • Sistemas físicos: equipo, maquinaria, objetos reales, Hardware • Sistemas abstractos: ideas, hipótesis, conceptos, planes, Software • Sistemas abiertos y cerrados dependiendo del ambiente en que se ejecutan Características de un sistema • Están bien delimitados, por lo tanto se conocen sus fronteras. • Un sistema puede interactuar con su medio ambiente a través de una interfaz de entradas y salidas que recibe el nombre de parámetros del sistema. • Un sistema puede ser componente de otro sistema Clasificación del software • Software de sistemas: software que ayuda (sirve de base) a otro software. • Procesan estructuras de datos complejas • Tienen una fuerte dependencia con el hardware • Utilizan una fuerte gestión de procesos (concurrencia, planificación, etc.) Clasificación del software • Software de aplicación (gestión) • Software de tiempo real • Software empotrado • Software de ingeniería y científico • Software basado en Web • Software de inteligencia artificial Áreas afines a la programación de sistemas • Teoría de la computación (lenguajes y autómatas). • Lenguajes de programación • Arquitecturas de computadoras • Algorítmica • Ingeniería del software 1.2 Herramientas desarrolladas con la teoría de programación de sistemas • El caso más sencillo de programación de sistemas es la construcción de compiladores para ejecutar lenguajes de programación. • Pero no sólo se aplica en lenguajes de programación, sino también se aplica en cualquier programa que se tenga que hacer un análisis o extracción de información Software de sistemas • Editores de texto inteligentes (IDEs con autocompletar, revisores ortográficos, etc.) • Impresoras estéticas (impresión de gran calidad sin un editor visual, Latex, etc.) • Intérpretes (Shells de sistemas operativos o de alguna aplicación como un SMBD) • Búsqueda de información que no es tan común en base a patrones, etc. 1.3 Lenguajes Es la notación formal para la descripción de algoritmos, basada en un conjunto de instrucciones en alto nivel, que finalmente pasarán a bajo nivel para interactuar con el hardware y generar herramientas de trabajo. Los lenguajes son sistemas de comunicación. Un lenguaje de programación consiste en todos los símbolos, caracteres y reglas de uso que permiten a las personas "comunicarse" con las computadoras. • Conjunto de palabras y reglas que permiten comunicar información entre dos entidades. • Lenguaje son las cadenas que pueden generarse a través de una gramática • El lenguaje que entienden las máquinas (lenguaje formal) es muy diferente del lenguaje que entendemos los humanos Repaso de lenguajes y autómatas • Símbolo: representación abstracta de alguna entidad • Alfabeto: conjunto finito de símbolos • Cadena: yuxtaposición de símbolos de un alfabeto que representan a un objeto • Lenguaje: conjunto de cadenas válidas que se pueden formar a través de un alfabeto 1.3.1 Lenguajes naturales Este tipo de lenguaje es el que nos permite el designar las cosas actuales y razonar a cerca de ellas, fue desarrollado y organizado a partir de la experiencia humana y puede ser utilizado para analizar situaciones altamente complejas y razonar muy sutilmente. La riqueza de sus componentes semánticos da a los lenguajes naturales su gran poder expresivo y su valor como una herramienta para razonamiento sutil. En un primer resumen, los lenguajes naturales se caracterizan por las siguientes propiedades: Desarrollados por enriquecimiento progresivo antes de cualquier intento de formación de una teoría. La importancia de su carácter expresivo debido grandemente a la riqueza del componente semántico (poli semántica). Dificultad o imposibilidad de una formalización completa. • El lenguaje natural es inherentemente ambiguo, por lo que se necesita crear un lenguaje que permita eliminar esas ambigüedades. • Es mejor crear otro lenguaje, denominado de alto nivel que es el encargado de mediar entre la abstracción humana y la abstracción de lenguaje de máquina 1.3.2 Lenguajes artificiales Podemos distinguir tres grandes estilos o subfamilias de los lenguajes de inteligencia artificial. Los tres estilos de programación son los siguientes: programación funcional, programación relacional y programación por objetos. El lenguaje más representativo del estilo funcional es el LISP, LOGO por su identificación con LSIP, cae de lleno dentro de este estilo. El lenguaje más representativo del estilo relacional PROLOG. El lenguaje más representativo del estilo de programación por objetos es el SMALLTALK, pero existen varios dialectos de LISP que permite programar en esta forma. • Los lenguajes artificiales son aquellos que los humanos hemos creado para comunicarnos • Las computadoras sólo saben 0 y 1 • Un lenguaje artificial permite implementar un algoritmo en una computadora para resolver un problema. Lenguajes de bajo nivel • Una abstracción más entendible del lenguaje máquina es el uso de lenguajes ensambladores en donde cada instrucción o mnemónico es traducido a una instrucción máquina. • ADD AX, 5 • LOAD A, 5 Lenguajes máquina • El lenguaje máquina es dependiente de cada tipo de arquitectura de computadoras por lo que el código no es fácilmente portable a otras arquitecturas. • Los lenguajes de alto nivel son más portables en lo que respecta al código fuente pudiendo llevarse a otras arquitecturas de computadoras sin mayor problema. Clasificación de Chomsky • Lenguajes sin restricciones (gramática 0) • Lenguajes dependientes del contexto (tipo 1) • Lenguajes independientes del contexto (tipo 2) • Lenguajes regulares (tipo 0 no presentan ambigüedades, lo ideal para representarlas en una computadora) 1.3.3 Proceso de la comunicación • Para entablar una comunicación se necesita que tanto el emisor como el receptor conozcan el mismo lenguaje o en su defecto tengan un traductor. • En este sentido, los humanos escribimos algoritmos en un lenguaje formal que una computadora pueda transformar a un lenguaje entendible por ella. 1.4.- traductor y estructura Traductor: En un sentido orientado hacia la computación, un traductor, de manera general, es un software que toma como entrada un programa escrito en un código llamado fuente y genera como salida otro programa en un código llamado objeto. Algunos ejemplos de traductores son los compiladores (toma como entrada código en alto nivel y genera como salida código en bajo nivel), los interpretes (toma como entrada código en alto nivel y genera como salida un código intermedio), los preprocesadores (toma como entrada código en alto nivel y genera como salida código en alto nivel) y el ensamblador (toma como entrada código en ensamblador y genera como salida código en bajo nivel). Su estructura podria ser expresada de la siguiente manera: código fuente -→>> traductor -→> código objeto Definición. Un intérprete es un programa que ejecuta un programa escrito en un determinado lenguaje examinando y ejecutando cada sentencia del programa una a una, por separado y sin realizar un proceso de compilación previo. Algunas de las ventajas de compilar frente a interpretar son: • Se compila una vez; se ejecuta muchas veces • La ejecución del programa objeto es mucho más rápida que si se interpreta el programa fuente. • El compilador tiene una visión global del programa, por lo que la información de mensajes de error es más detallada. Por otro lado, algunas de las ventajas de interpretar frente a compilar son: • Un intérprete necesita menos memoria que un compilador. • Permiten una mayor interactividad con el código en tiempo de desarrollo. • En algunos lenguajes (Smalltalk, Prolog, LISP, Java) está permitido y es frecuente añadir código según se ejecuta otro código, y esta característica solamente es posible implementarla en un intérprete. 1.4.1.- ensambladores Podemos distinguir entre tres tipos de ensambladores: Ensambladores básicos. Son de muy bajo nivel, y su tarea consiste básicamente en ofrecer nombres simbólicos a las distintas instrucciones, parámetros y cosas tales como los modos de direccionamiento. Además, reconoce una serie de directivas (o meta instrucciones) que indican ciertos parámetros de funcionamiento del ensamblador. Ensambladores modulares, o macro ensambladores. Descendientes de los ensambladores básicos, fueron muy populares en las décadas de los 50 y los 60, antes de la generalización de los lenguajes de alto nivel. Hacen todo lo que puede hacer un ensamblador, y además proporcionan una serie de directivas para definir e invocar macroinstrucciones (o simplemente, macros). Véase X86. Ensambladores modulares 32-bits o de alto nivel. Son ensambladores que aparecieron como respuesta a una nueva arquitectura de procesadores de 32 bits, muchos de ellos teniendo compatibilidad hacia atrás pudiendo trabajar con programas con estructuras de 16 bits. Además de realizar la misma tarea que los anteriores, permitiendo también el uso de macros, permiten utilizar estructuras de programación más complejas propias de los lenguajes de alto nivel. 1.4.2.- compiladores Los compiladores pueden ser de: Una sola pasada: examina el código fuente una vez, generando el código o programa objeto. Pasadas múltiples: requieren pasos intermedios para producir un código en otro lenguaje, y una pasada final para producir y optimizar el código producido durante los pasos anteriores. Optimación: lee un código fuente, lo analiza y descubre errores potenciales sin ejecutar el programa. Compiladores incrementales: generan un código objeto instrucción por instrucción (en vez de hacerlo para todo el programa) cuando el usuario teclea cada orden individual. El otro tipo de compiladores requiere que todos los enunciados o instrucciones se compilen conjuntamente. Ensamblador: el lenguaje fuente es lenguaje ensamblador y posee una estructura sencilla. Compilador cruzado: se genera código en lenguaje objeto para una máquina diferente de la que se está utilizando para compilar. Es perfectamente normal construir un compilador de Pascal que genere código para MS-DOS y que el compilador funcione en Linux y se haya escrito en C++. Compilador con montador: compilador que compila distintos módulos de forma independiente y después es capaz de enlazarlos. Auto compilador: compilador que está escrito en el mismo lenguaje que va a compilar. Evidentemente, no se puede ejecutar la primera vez. Sirve para hacer ampliaciones al lenguaje, mejorar el código generado, etc. Meta compilador: es sinónimo de compilador de compiladores y se refiere a un programa que recibe como entrada las especificaciones del lenguaje para el que se desea obtener un compilador y genera como salida el compilador para ese lenguaje. El desarrollo de los meta compiladores se encuentra con la dificultad de unir la generación de código con la parte de análisis. Lo que sí se han desarrollado son generadores de analizadores léxicos y sintácticos. Por ejemplo, los conocidos: LEX: generador de analizadores léxicos YACC: generador de analizadores sintácticos desarrollados para UNIX. Los inconvenientes que tienen son que los analizadores que generan no son muy eficientes. Descompilador: es un programa que acepta como entrada código máquina y lo traduce a un lenguaje de alto nivel, realizando el proceso inverso a la compilación. 1.4.3.- interpretes Un intérprete es un programa que analiza y ejecuta simultáneamente un programa escrito en un lenguaje fuente. En la Figura 1 se presenta el esquema general de un intérprete visto como una caja negra. Cualquier intérprete tiene dos entradas: un programa P escrito en un lenguaje fuente LF (en lo sucesivo, se denotará P/LF) junto con los datos de entrada; a partir de dichas entradas, mediante un proceso de interpretación va produciendo unos resultados. Se ejecutan línea por línea, instrucción por instrucción. • Lenguajes interpretados: PHP, PERL, BASIC • En algunas ocasiones se necesita de una traducción rápida de algunas instrucciones, como en el Shell, instrucciones SQL, etc. Estructura de un intérprete A la hora de construir un intérprete es conveniente utilizar una Representación Interna (RI) del Lenguaje fuente a analizar. De esta forma, la organización interna de la mayoría de los intérpretes se Descompone en los módulos: Traductor a Representación Interna: Toma como entrada el código del programa P en Lenguaje Fuente, lo analiza y lo transforma a la representación interna correspondiente a dicho programa P. Representación Interna (P/RI): La representación interna debe ser consistente con el programa original. Entre los tipos de representación interna, los árboles sintácticos son los más utilizados y, si las características del lenguaje lo permiten, pueden utilizarse estructuras de pila para una mayor eficiencia. Tabla de símbolos: Durante el proceso de traducción, es conveniente ir creando una tabla con información relativa a los símbolos que aparecen. La información a almacenar en dicha tabla de símbolos depende de la complejidad del lenguaje fuente. Se pueden almacenar etiquetas para instrucciones de salto, información sobre identificadores (nombre, tipo, línea en la que aparecen, etc.) o cualquier otro tipo de información que se necesite en la etapa de evaluación. Evaluador de Representación Interna: A partir de la Representación Interna anterior y de los datos de entrada, se llevan a cabo las acciones indicadas para obtener los resultados. Durante el proceso de evaluación es necesario contemplar la aparición de errores. Tratamiento de errores: Durante el proceso de evaluación pueden aparecer diversos errores como desbordamiento de la pila, divisiones por cero, etc. que el intérprete debe contemplar. 1.5.- generador de códigos Aquí se hablará de las herramientas generadoras automáticas de código para un compilador. Estas herramientas trabajan basadas en un conjunto de reglas; estas reglas definen la traducción de las instrucciones del lenguaje intermedio al lenguaje de máquina. Para la generación de código, se busca en las reglas establecidas la proposición que coincida con la entrada actual; la entrada actual proviene de un árbol. Un ejemplo de esto seria Entonces el compilador recibe una entrada de caracteres, por lo general escrita por el programador; el compilador realiza los análisis: léxico, sintáctico y semántico, para generar seguidamente el código intermedio, el código intermedio se genera con principios de búsqueda de patrones y aplicación de reglas. Después se hace la optimización del código intermedio; seguidamente se realiza la generación de código objeto en lenguaje de máquina. En síntesis para crear un generador de código se deben hacer muchas de las tareas que realizan los compiladores; algunas de estas tareas son: la búsqueda de patrones, la escritura de código, el análisis sintáctico, el análisis léxico y la optimización de código. Estas tareas las realiza el desarrollador una vez para una arquitectura específica. METACOMPILADOR: Es Sinónimo De compilador de compiladores y se refiere a un programa que recibe como entrada las especificaciones del lenguaje para el que se desea obtener un compilador y genera como salida el compilador para ese lenguaje. El desarrollo de los meta compiladores se encuentra con la dificultad de unir la generación de código con la parte de análisis. Lo que sí se han desarrollado son generadores de analizadores léxicos y sintácticos. Por ejemplo, los conocidos: • generador de analizadores léxicosLEX. • generador deYACC: analizadores sintácticos desarrollados para UNIX. Los inconvenientes que tienen son que los analizadores que generan no son muy eficientes. *Los dos primeros lenguajes de alto nivel desarrollado fueron FORTRAN y ALFONSO COBOL. * Desarrollar FORTRAN tardó alrededor de 14 años. Desarrollar nuestro compilador tardará menos de 6 meses *Son herramientas que auxilian algún aspecto del proceso de traducción.