P. 1
Analogia

Analogia

|Views: 2.009|Likes:

More info:

Published by: Lupita Gómez Mercado on Jan 31, 2012
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

06/03/2013

pdf

text

original

Sections

  • 1.1 ¿Qué es y qué estudia la programación de
  • 1.3.1 Lenguajes naturales
  • 1.3.2 Lenguajes artificiales
  • 1.3.3 Proceso de la comunicación
  • 1.4.1 Ensambladores
  • 1.4.2 Compiladores
  • 1.4.3 Intérpretes
  • 2.3 Objetivos y filosofías del diseño de los lenguajes de programación
  • 2.5 Caso de estudio
  • 3.1 Introducción a los Autómatas finitos y expresiones regulares
  • 3.2 Analizador Léxico
  • 3.3 Manejo de localidades temporales de memoria (buffers)
  • 3.5 Manejo de errores léxicos
  • 3.6 Generadores de código léxico:
  • 4.1 Introducción a las Gramáticas libres de contexto y árboles de derivación
  • 4.3 Precedencia de operadores
  • 4.4 Analizador sintáctico
  • 4.6 Manejo de errores sintácticos y su recuperación
  • 4.7 Generadores de código para analizadores sintácticos: Yacc, Bison
  • 5.2 Verificación de tipos en expresiones
  • 5.4 Acciones agregadas en un analizador sintáctico descendente (top-down)
  • 5.5 Pila semántica en un analizador sintáctico ascendente (bottom-up)
  • 5.6 Administración de la tabla de símbolos
  • 5.7 Manejo de errores semánticos
  • 6.2.1 Infija
  • 6.2.2 Postfija
  • 6.2.3 Prefija
  • 6.3.2 Código P
  • 6.3.3 Triplos
  • 6.3.4 Cuádruplos
  • 6.4.1 Expresiones
  • 6.4.2 Declaración de variables, constantes
  • 6.4.3 Estatuto de asignación
  • 6.4.4 Estatuto condicional
  • 6.4.5 Estatuto de ciclos
  • 6.4.6 Arreglos
  • 6.4.7 Funciones
  • 7.1.1 Locales
  • 7.1.2 Bucles
  • 7.1.3 Globales
  • 7.1.4 De mirilla
  • 7.2.3 Herramientas para el análisis del flujo de datos
  • 8.1 Lenguaje máquina
  • 8.2 Lenguaje ensamblador
  • 8.3.1 Distribución
  • 8.3.2 Asignación
  • 8.4 Administración de memoria

TECNOLOGICO DE ESTUDIOS SUPERIORES DE IXTAPALUCA

ING. EN SISTEMAS COMPUTACIONALES

ASIGNATURA: PROGRAMACION DE SISTEMAS

(ANALOGIA DE LOS TEMAS EN CLASE)

PROF.: GARCIA CORTES DAVID

ALUMNA: GOMEZ MERCADO GUADALUPE

GRUPO: 1502

MATRICULA: 200920834

FECHA DE ENTREGA: 30 DE ENERO DE 2012

INDICE
1

Introducción………………………………………………………………… ……………………………….6 Unidad I.- Introducción a la programación de Sistemas…………………………………7 1.1 ¿Qué es y que estudia la programación de sistemas? 1.2 Herramientas desarrolladas con la teoría de P.S. 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.5.3Interpretes 1.5 Generadores de código para compiladores (compilador de compilador) Unidad II Introducción al diseño de los lenguajes de programación…………..12 2.1 Visión del problema 2.2 Consideraciones preliminares 2.3 Objetivos y filosofías del diseño de los lenguajes de programación 2.4 Diseño detallado 2.5 Caso de estudio

2

Unidad III Análisis Léxico………………………………….. …………………………………………15 3.1 Introducción a los Autómatas finitos y expresiones regulares. 3.2 Analizador de léxico. 3.3 Manejo de localidades temporales de memoria (buffers). 3.4 Creación de tablas de símbolos. 3.6 Manejo de errores léxicos. 3.6 Generadores de código léxico: Lex y Flex. Unidad IV Análisis Sintáctico……………………………….. ……………………………………..23 4.1 Introducción a las Gramáticas libres de contexto y árboles de derivación. 4.2 Diagramas de sintaxis. 4.3 Precedencia de operadores. 4.4 Analizador sintáctico. 4.4.1 Analizador descendente (LL). 4.4.2 Analizador ascendente (LR, LALR). 4.5 Administración de tablas de símbolos 4.6 Manejo de errores sintácticos y su recuperación 4.7 Generadores de código para analizadores sintácticos: Yacc, Bison.

3

6.2 Notaciones.1 Analizador semántico 5.3 Conversión de tipos.7 Administración de la tabla de símbolos.4 Esquemas de generación.3 Triplos.2 Verificación de tipos en expresiones.3.3. 6.Unidad V Análisis Semántico ………………………………………………………………………35 5.3 Representación de código intermedio. 4 . 6.4 Acciones agregadas en un analizador sintáctico descendente (top-down).3. 6. 6.2. Unidad VI Generación de Código Intermedio ……………………………………………41 6.5 Pila semántica en un analizador sintáctico ascendente (bottom-up).3 Prefija. 5.3.2.7 Manejo de errores semánticos. 6.1 Lenguajes intermedios.2 Código P.1 Notación Polaca. 5. 5. 5.2 Postfija.1 Infija.4 Cuádruplos. 6. 6.2. 6. 5. 6.

4.4.1 Locales.1. Arreglos. 6.2.1 Lenguaje máquina.4.1 Costo de ejecución. 6.4. 7. 5 .4. 7.2 Criterios para mejorar el código.2 Bucles.1.4.3 Herramientas para el análisis del flujo de datos.3 Globales. Estatuto de asignación.6. Unidad VIII Generación de código intermedio ……………………………………………49 8. 7. Expresiones. Estatuto de ciclos 6.2. constantes 6.1 Tipos de optimización. Funciones. 7. Estatuto condicional.2. 7.1. Declaración de variables.2 Costos.4 De mirilla. 7. 6.1. 7. 6. 7.4. Unidad VII Optimización………………………………………………………………… ……………46 7.

8. 8.1. 8. 8. 8.2 Almacenamiento.2 Direccionamiento.4 Administración de memoria. 8.3.2.1 Características. 8.1 Características. Bibliografía………………………………………………………………… …………………………….53 6 . 8.2 Asignación.2 Lenguaje ensamblador..1.3.3 Registros.1 Distribución.2. 8.

INTRODUCCION En esta antología tenemos un resumen de todo lo visto durante la asignatura de programación de sistemas. Esta asignatura es muy importante para la carrera de ing. En sistemas computacionales ya que tocan temas fundamentales de ella. La programación es un sistema es un conjunto de componentes que se relacionan entre si, para lograr un objetivo común. Las personas se comunican en un lenguaje que es un sistema formado por palabras y símbolos que tienen un significado para quien lo habla y quien loe escucha, lo mismo es para las computadoras. La programación consta de convertir las especificaciones de los sistemas en instrucciones de máquina que producen resultados deseados.

7

Unidad I Introducción a la programación de Sistemas 1.1 ¿Qué es y qué estudia la programación de sistemas? • 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: reales, Hardware equipo, maquinaria, objetos

• Sistemas abstractos: ideas, hipótesis, conceptos, planes, Software • Sistemas abiertos y cerrados dependiendo del ambiente en que se ejecutan. Características de un sistema • 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 1.2 Herramientas desarrolladas con la teoría de programación de sistemas

8

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 Conjunto de palabras y reglas que permiten comunicar información entre dos entidades. El lenguaje que entienden las máquinas (lenguaje formal) es muy diferente del lenguaje que entendemos los humanos • Lenguaje: Son las cadenas que pueden generarse a través de una gramática 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
9

3. 5 • LOAD A.3.• Lenguaje: conjunto de cadenas válidas que se pueden formar a través de un alfabeto 1. 5 10 .2 Lenguajes artificiales 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. 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. 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. por lo que se necesita crear un lenguaje que permita eliminar esas ambigüedades.1 Lenguajes naturales El lenguaje natural es inherentemente ambiguo. • ADD AX.

los humanos escribimos algoritmos en un lenguaje formal que una computadora pueda transformar a un lenguaje entendible por ella.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. 11 . La traducción puede ser sencilla (literal) o compleja (revisar el contexto) dependiendo del tipo de lenguaje de entrada y salida. Clasificación de Chomsky • Lenguajes sin restricciones (gramática 0) • Lenguajes dependientes del contexto (tipo 1) • Lenguajes independientes del contexto (tipo 1. un traductor convierte un lenguaje de entrada (código fuente) a uno de salida (código objeto). los mediadores enmascaran la complejidad y heterogeneidad de los lenguajes. 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.4 Traductor y su estructura Un traductor es un mediador entre dos entidades: emisoras y receptoras. 1.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. En este sentido.

El problema radica en el tiempo y en los recursos para hacerlo 12 . FF 4401FF 1.4.2 Compiladores Es el traductor que se encarga de convertir un lenguaje de alto nivel a código máquina. se necesita de al menos otra revisión (pasada) para hacer una buena traducción. C++. Ejemplo: la traducción de un libro.4.1 Ensambladores Ensamblador es el traductor que se encarga de convertir instrucciones de bajo nivel a instrucciones de una máquina en general. Entre más pasadas se de a un código fuente mayor es la optimización que se puede hacer. //Encabezados 00 MOV AX. Pascal. La característica de este traductor radica en el hecho de que necesita revisar todo el código fuente para poder realizar la traducción. etc.Traducción español a inglés si se hace de manera literal es una mala traducción. discurso. 1. o artículo técnico o de investigación Ejemplos de compiladores: C. 58d 4F0188 03 CMP 0 3A00 05 JMP etiqueta 9918 … Etiqueta: 18 MUL AX.

1. como en el Shell.3 Intérpretes Se ejecutan línea por línea. Por una parte se compila un programa fuente para generar código objeto para una máquina virtual (bytecode o MSIL) para posteriormente ejecutarse de manera interpretada en las diferentes máquinas virtuales de cada plataforma. BASIC En algunas ocasiones se necesita de una traducción rápida de algunas instrucciones. ¿Java es compilado o interpretado? Java al igual que otros lenguajes como C# son lenguajes híbridos.Antes de compilar un programa fuente se sigue una etapa de Pre procesamiento. Preprocesadores: Macros (expansión de funciones) Inclusión de archivos (bibliotecas) Procesadores racionales Extensiones al leguaje (inclusión de ensamblador en C) 1. Lenguajes interpretados: PHP. etc.4.5 Generadores de código para compiladores (compilador de compilador) 13 . instrucciones SQL. instrucción por instrucción. PERL. A este compilador se les llama jitter de JIT (Just in Time).

Los dos primeros lenguajes de alto nivel desarrollado fueron FORTRAN y 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 Herramientas auxiliares para programación de sistemas • Cargadores y editores de enlace • Generadores de analizadores léxico • Generadores de Analizadores sintácticos • Traductores dirigidos por sintaxis • Generadores automáticos de código • Dispositivos para el análisis de flujo de datos 14 .

visualizar información o bien realizar la conversión de un documento. Son lenguajes de programación de propósito general SQL. PROMELA. HTML es lenguaje de representación visual OWL es lenguaje de descripción de elementos 15 . ya que puede ser sólo la estructuración de contenido Web. Pascal. etc. Java. existen para todos los gustos y/o usos. sirven para casi todo Se debe identificar que es lo que se piensa hacer con el lenguaje. Actionscripts son lenguajes específicos ¿Por qué tal diversidad de lenguajes? Los lenguajes de programación son como los carros. ¿Quién cargaría una tonelada de papas en un auto deportivo? Los lenguajes de propósito general son como los autos sedán.1 Visión del problema al diseño de los lenguajes de ¿Cuál es el propósito de un lenguaje? Los lenguajes de computación pueden ser de propósito general o específicos. C++. C.Unidad II Introducción programación 2.

) La tendencia actual implementación es separa la interfaz de la Tratar de hacer lenguajes para múltiples arquitecturas de computadoras (máquinas virtuales) Control de apuntadores Control de tipo de datos robustos 16 . etc. mantenimiento. ya que un programa generalmente se escribe una vez y se lee muchas veces (documentación.C es un lenguaje programación 2. los tipos de datos.2 Consideraciones preliminares Debemos tomar en cuenta las palabras reservadas del lenguaje. si el código desarrollado va a ser mejor. 2. Debemos considerar el objetivo del lenguaje.3 Objetivos y filosofías del diseño de los lenguajes de programación Algunos usos de los lenguajes de programación son: – Comunicación humana – Prevención y Detección de errores – Usabilidad – Portabilidad – Independencia de la máquina Filosofías Es más importante que un programa sea leíble que escribible. los operadores. si es un lenguaje para profesionales. si es un lenguaje de enseñanza.

Simplicidad por eficiencia 2.5 Caso de estudio Explicar el lenguaje que se va a desarrollar en el curso: – ¿Por qué se va a desarrollar (problemática)? – Vocabulario del lenguaje (léxico palabras clases que hacen) – Reglas de estructura (gramática. enlazador) – Inclusión de otros lenguajes 2. sintaxis) – Semántica – Si existe código intermedio – Si se mejora ese código – El código objeto final 17 . APIs. componentes) – Excepciones – Validaciones – Marco de trabajo – Utilerías auxiliares (preprocesador.4 Diseño detallado • Considerar características como: – Patrones de diseño – Paquetes (bibliotecas.

1 Introducción a los Autómatas finitos y expresiones regulares ¿Qué es un autómata? Es un modelo matemático que sirve para determinar si una cadena pertenece a un lenguaje no. 18 .Unidad III Análisis Léxico 3.

M=(Q. &. . F) – Q = conjunto de estados = alfabeto de entrada – & = funciones de transición – F = conjunto de estados de aceptación Autómatas finitos La característica que tienen los autómatas finitos es que solo existe una función de transición definida para un símbolo de entrada. Formato: 19 regular para identificar correos . Esto elimina ambigüedades • Una expresión regular representar lenguajes: es una forma abreviada de • a Representa el lenguaje de las letras a • a* Representa el lenguaje que tiene 0 hasta n a’s Autómatas • Oprel <|>|<=|>=|=|<> • Un solo autómata varios sub_autómatas • Programar un autómata: • Identificador letra (letra|digito|gb)* Expresión Regular Generar la expresión electrónicos válidos.

2 Analizador Léxico • Primera fase de la compilación • Leer caracteres de entrada y generar como salida una secuencia de componentes léxicos • Eliminar espacios en blanco • Eliminar comentarios • Proporcionar información acerca de errores léxicos 20 . Gramática de un if prop _ if expr then prop | if expr then prop else prop |_ expr _ termino oprel termino | termino termino _ id | num oprel _ < |>|=|<=|<>|>=| id _ letra (letra | digito)* num _ digito+ (. Autómatas.mx id@dominio Expresiones Regulares y una gramática Una gramática sirve para generar cadenas de un determinado lenguaje pero también sirve para generarla.jcolivar@itmorelia. Expresiones regulares y gramáticas.edu. Existente una relación uno a uno entre Lenguajes.digito+)?(E(+|-)?digito+)? eb _ delim+ delim _ blanco | tab | linenueva 3.

La devolución de un componente léxico se hace a través de un número entero. Las expresiones regulares dan el nombre al conjunto de cadenas con que concuerdan.Análisis Léxico El análisis lineal. Cada patrón concuerda con una serie de cadenas. Expresiones regulares 21 . tabuladores. Reconocedores de identificadores y palabras clave. se llama léxico o exploración. Especificación de componentes léxicos Expresiones regulares (patrón). Los componentes léxicos se tratan como terminales de la gramática del lenguaje fuente. La tabla de símbolo debe insertar y buscar componentes léxicos. etc. salto de línea. La tabla de símbolos es utilizada por el analizador sintáctico y por otras fases del proceso de traducción Un patrón es una regla que describe el conjunto de lexemas que puede representar a un conjunto léxico. Posicion := inicial + velocidad * 60 Posicion: identificador := símbolo de asignación Inicial: identificador +: signo de suma Velocidad: identificador *: signo de multiplicación 60: numero Se elimina todos los espacios en blancos (espacios.

pero siempre se deberá llevar dos punteros. representa un lenguaje L(r) • Letraaubucu…uz • Dígito1u2u3u…u0 • Identificador letra(letra u dígito)* Abreviaturas • * cero o más casos • + uno o más casos • [a-zA-Z] mayúsculas y minúsculas • [0-9] dígitos • ? Cero o un caso 3.Se construyen a partir de otras expresiones regulares más simples. • La forma más eficiente es realizar una copia a la memoria de todo el código fuente. Para solucionar este problema se sugiere utilizar buffers Manejo de buffers Existen muchas formas de dividir el trabajo.4 Creación de tablas de símbolos 22 . uno al carácter actual y otro al inicial del lexema. cada expresión regular r. Pero esto en la gran mayoría de las ocasiones es impráctico por las dimensiones de los programas.3 Manejo de localidades temporales de memoria (buffers) • La forma más fácil de leer un programa es carácter por carácter pero es ineficiente. El manejo de buffers es esencial para realizar el análisis de grandes programas de mejor manera 3.

el cual se encarga de verificar que no existan caracteres no presentes en el lenguaje. La tabla de símbolos debe estar en memoria para realizar un análisis rápido.En general el proceso de análisis léxico puede describirse simplemente como el reconocimiento de caracteres de un lenguaje para generar una tabla de símbolos. 3.5 Manejo de errores léxicos • Son pocos los errores que se pueden detectar al hacer análisis léxico • fi (a == f(x)) //Error de sintaxis • Pero puede existir algún error si ninguno de los patrones con cuerda con el prefijo de entrada Técnicas de recuperación de errores • Borrar un carácter extraño • Insertar un carácter que falta • Reemplazar un carácter incorrecto por otro correcto • Intercambiar dos caracteres adyacentes Técnicas para realizar analizadores léxicos 23 . la va identificar como un lexema y le va asociar un identificador numérico para posteriormente utilizarlo. El primer paso consiste en crear un escáner. Tabla de símbolos La tabla de símbolos va a guardar cada palabra analizada.

• Utilizar un analizador léxico como FLEX. falla el proceso. genera código C aunque existen otras herramientas que generan código en otros lenguajes • Analizador.yy.6 Generadores de código léxico: Lex y Flex FLEX es la versión de software libre del popular generador de analizadores léxicos LEX para sistemas *NIX. • Realizar análisis léxico de XML en Java o C# 3.lex flex lex. • Si el lenguaje no cumple con las reglas de construcción de documentos XML. El generador se encarga de manejar buffers • Escribir el analizador en un lenguaje de alto nivel haciendo uso de la E/S del lenguaje • Escribir el lenguaje ensamblador y manejar explícitamente la E/S Análisis Léxico en XML • El análisis léxico en documentos XML lo realiza cualquier herramienta o API que utilice XML.c gcc Programa ejecutable analizador • $gcc lex.c –o analizador –lfl Programa Lex %{ Definiciones globales ‘C’ 24 .yy. ya que debemos cerciorarnos que el lenguaje esté bien formado.

] Exp [eE] Signo[\+\-] Digitos {digito}+ 25 expresión .}% Definiciones flex %% Acciones %% Código ‘C’ auxiliar Definiciones regulares en flex %% Separadores de secciones Def Acciones {def} {código ‘C’ asociado} “@” {código ‘C’ asociado} Programa que reconoce flotantes % { #include <stdio.h> Int ocurrencias. }% Digito[0-9] Punto [\.

} Programa para reconocer direcciones IP Digito [0-9] Punto [\. char *argv[]) { FILE *f. } “@” { printf(“Arroba\n”). } . ocurrencias). “r”). F = fopen(argv[1]. { printf(“Inválido: %s\n”. fclose(f). ] 26 .Decimal {punto} {digitos}({exp}{signo}{digitos})? Flotante {digitos}{decimal}? Programa que reconoce flotantes % % {flotante} { printf(“flotante encontrado\n”) ocurrenicas++. printf(“%d flotantes encontrados\n”. yyin = f. yytext). while(yylex()). } %% main(int argc.

} 27 . “.”). i++) { cadnum = strtok(aux. strcat(aux. “. } if(i==4) printf(“Dirección IP: %s\n”. break. yytext).”) . i<4. yytext).IP {digito}+{punto}{digito}+{punto}+{digito} {punto}{digito}+ %% {IP} { strcpy(aux. for(i =0 . if(atoi (cadnum)>255) { printf(“Error\n”).

S. mientras que los terminales el proceso finaliza allí.1 Introducción a las Gramáticas libres de contexto y árboles de derivación Todo lenguaje posee una serie de reglas para describir los programas fuentes (sintaxis). Un analizador sintáctico implementa estas reglas haciendo uso de GICs Gramáticas Son un formalismo matemático que permite decidir si una cadena pertenece a un lenguaje dado. Se define como la cuarteta G= (N. . Reglas de producción • Son las reglas que permiten decidir si la cadena pertenece a un lenguaje y la estructura que lleva: •S A|aB •A aA|bC •S B C e e Genera cadenas del lenguaje a*b u a 28 . S es conjunto de símbolos terminales.Unidad IV Análisis Sintáctico 4. S es el símbolo inicial (S pertenece a N) y P es un cojunto de reglas de producción. Los símbolos no terminales (N) son aquellos que pueden seguir derivando en otros. en donde N es el conjunto de símbolos terminales. P).

Gramáticas Independientes del Contexto Son aquellas G cuya reglas de producción son de la forma: . en donde a pertenece aNy ß pertenece (N u )* Las ventajas de uso de GICs son: •Proporcionan una estructura sintáctica precisa y fácil de comprender • Proporciona al lenguaje fuente una estructura adecuada para la generación del código. No presentan ambiguedades. Las más utilizadas en informáticas son las libres del contexto. Gramáticas Regulares Son las que se forman a través de Autómatas Finitos Deterministas y Expresiones regulares. Desafortunadamente este tipo de gramáticas no permiten expresar todos los lenguajes posibles y en especial los humanos por lo que se necesitan otros tipos de gramáticas. • Por medio de las GICs es fácil construir analizadores sintácticos • Es sencillo añadir funcionalidades a un analizador sintáctico GICs 29 . debido a que no presentan anomalías de ningún tipo.Tipos de gramáticas Las gramáticas más sencillas son las gramáticas regulares.

• Algunas formas de eliminar esa ambigüedad es utilizando técnicas como algoritmos CYK y las formas normales de Chomsky (FNCh) y Greibach (FNG). donde ||<||. GIC tipo 2) son las gramáticas sensible al contexto (tipo 1.• Hay que revisar que la gramática no sea inherentemente ambigua para poder eliminar esa ambigüedad o rediseñar la gramática sin anomalías. (expr) | -expr | expr op expr| VAR | Jerarquía de Chomsky • Las otras dos gramáticas en las cuales clasificó Chomsky (GR tipo 3. Ejemplos de GICs • Expresiones válidas en lenguajes C: Expr NUM • Error sintáctico: cuando la secuencia de componentes léxicos no puede ser generada por la gramática del lenguaje fuente. donde a y ß pertenecen a (u N)* salvo ) y las ramáticas del tipo 0 o sin restricciones. Árboles de Derivación 30 . las cuales sus reglas de producción pueden ser de cualquier tipo.

• La barra vertical | para representar O • La doble flecha • ::= indica indica las derivaciones las producciones • [] indican elementos opcionales • {} indican términos repetitivos 4. BNF La Forma Backus-Naur es una meta-sintaxis. Los paréntesis triangulares < y > sirven para indicar los símbolos no terminales. Si para la misma cadena existen dos o más árboles de derivación la gramática es ambigua. una sintaxis para representar sintaxis. Se crea utilizando el símbolo inicial como la raíz.Es la representación gráfica de la derivación de una cadena. A través de los árboles de derivación se puede verificar la sintaxis de un lenguaje así como comprobar el significado de las palabras.2 Diagramas de sintaxis 31 . Es un estándar para representar lenguajes. es decir. los símbolos N representan nodos del árbol y los símbolos S las hojas del árbol.

• Es otra forma (al igual que los árboles de derivación) de especificar gramáticas del tipo 2.3 Precedencia de operadores • La precedencia de operadores es de vital importancia en el proceso de análisis sintáctico ya que nos representará la forma en que debe construirse el árbol de derivación. () indican la máxima prioridad. Prioridad de operadores • La instrucción a = b + c / 2 en la mayoría de los lenguajes no se evalúa de la forma a = (b + c) /2. • En aritmética existen prioridades. por ejemplo: * y / tienen preferencia sobre + y -. <W>::=<W1> < W2> <W3> <W>::=ab <W> <W>::=< W1> < W2> | <W1>a | ab <W2> 4. • La característica de este esquema es que permite ver las derivaciones al instante de que ocurren. sino de la forma a = b + (c/2) 32 .

postfijo o prefijo. • Las operaciones se realizan de abajo hacia arriba. 33 .• La forma de evaluación depende de cómo se construyan los operadores. ya sea en infijo.

tales y como YACC. viendo un componente léxico a la vez Los analizadores pueden clasificarse dependiendo de la forma en como se construyen los nodos del árbol de derivación sintáctico: ascendentes y descendentes Tipos de analizadores sintácticos • LL (left to left) leen la cadena de izquierda a derecha y derivan por la izquierda • LR (left to right) •S •A •B •C aA aBbC b c 4. cosa que permitió la creación de programas generadores de analizadores sintácticos a partir de una especificación de la sintaxis del lenguaje. detectándose numerosos patrones de funcionamiento en ellos.4.1 Analizador descendente (LL) 34 . Es el proceso de determinar si una cadena dada puede ser generada por una gramática. Los analizadores sintácticos de lenguajes de programación suele hacerse de izquierda a derecha.4 Analizador sintáctico Un analizador sintáctico (Parser) es un programa que reconoce si una o varias cadenas de caracteres forman parte de un determinado lenguaje. Los analizadores sintácticos fueron extensivamente estudiados durante los años 70 del siglo XX. GNU bison y javacc. Los lenguajes habitualmente reconocidos por los analizadores sintácticos son los lenguajes libres de contexto.4.

En un proceso que recorre el árbol de derivación en sentido inverso que se llama reducción. 4. pero en el proceso de análisis sintáctico sufren algunas modificaciones.4.6 Manejo de errores sintácticos y su recuperación. La mayoría caen en una de dos categorías: ascendentes y descendentes. Si los traductores tuvieran que procesar programas correctos el proceso de implantación se simplificaría mucho. 4.Existen diferentes métodos de análisis sintáctico. Generalmente los analizadores sintácticos LR(k) son del tipo “bottom-up”. 35 . Generalmente se agregan valores de tipo y significado para el análisis sintáctico.2 Analizador ascendente (LR. Un analizador ampliamente utilizado se denomina método de análisis predictivo descendente recursivo que es muy sencillo. No sólo es necesaria una gramática que no presente ambigüedades sino que también tenga el valor de k más pequeño. Los ascendentes construyen el árbol desde las hojas hacia la raíz. En algunos casos es más fácil demostrar algo ya existente. 4.5 Administración de tablas de símbolos La tabla de símbolos se crea durante la fase de análisis léxico a través de los componentes léxicos. Los descendentes lo hacen en modo inverso. El analizador trata de reducir la cadena de entrada w al símbolo inicial S. LALR) Algunos problemas no se pueden resolver de forma descendente ya que no están fácil quitar la ambigüedad.

• Sintácticos: como una expresión aritmética con paréntesis no equilibrados. • Lógicos: como una llamada infinitamente recursiva • La mayoría de los errores se centra en la fase de análisis sintáctico. • El manejador de errores debe: Informar la presencia de errores con claridad y exactitud. • Debe indicar informativo la línea del error y algún el mensaje Estrategias de recuperación de errores 36 . palabra clave u operador.¿Cómo debe de responder un compilador de pascal a un código Fortran? Ningún método de recuperación de errores resuelve todos los problemas Tipos de errores • Léxicos: como escribir mal un identificador. • No debe retrasar de manera significativa procesamiento de programas correctos. Administrador de errores • Recuperar de cada error con la suficiente rapidez como para detectar errores posibles. • Semánticos: como un operador aplicado a un operando incompatible.

c. struct c { … . } Recuperación a nivel de frase 37 . int a.• Modo Pánico • Nivel de Frase • Producciones de error • Corrección global Recuperación en modo pánico Es el más sencillo de implantar. El analizador sintáctico desecha componentes léxicos hasta encontrar un carácter de sincronización.) entre otros. } main( ) { int a. Estos caracteres son el punto y como (.b.

Este algoritmo genera menores costos globales para realizar cambios. Desafortunadamente para muchos casos no aplican por lo que no se utilizan demasiados. 4. ya sea por inserción. etc. Producciones de error Se pueden generar gramáticas para generar producciones de error y así de esta forma seguir con el proceso.7 Generadores de código para analizadores sintácticos: Yacc. El problema radica en que el implementar estas estrategias son muy costosas en tiempo y espacio. En algunos casos sería inclusiva más extensa que la gramática del propio lenguaje. Son traductores que corrigen errores. La dificultad radica en el sentido de encontrar esas reglas gramaticales para generar error. junto con el código que será invocado en la medida en que cada una de esas estructuras es reconocida. eliminación o intercambio. El usuario de YACC especifica las estructuras de su entrada. i++) Corrección global Idealmente.. Esta técnica permite sustituir .Esta técnica utiliza una corrección de caracteres adyacentes. por . a<10. sería recomendable que un traductor hiciera el mínimo de cambios para procesar una entrada inválida. Bison YACC (YET ANOTHER COMPILERCOMPILER): provee una herramienta general para describir la entrada de un programa de computación. For (i<3. YACC/BISON 38 .

• Es utilizado para crear parsers para muchos lenguajes. • La subrutina de entrada producida por YACC llama a la rutina provista por el usuario para devolver el próximo ítem básico de la entrada. desde simples calculadoras hasta lenguajes complejos.yy.c”) analizador. • GNU Bison es un generador de parsers de propósito general que convierte una descripción gramatical desde una gramática libre de contexto LALR en un programa en C para hacer el parser. Es necesaria experiencia con C para utilizar Bison.• YACC convierte esa especificación en una subrutina que maneja el proceso de entrada.y (#include “lex.c –o analizador -lfl Estructura de un programa en Bison %{ Declaraciones globales C }% Declaraciones bison 39 bison .tab.c (y. • Cualquier persona que esté familiarizada con Yacc podría utilizar Bison sin problemas. • GNU Bison tiene compatibilidad con Yacc: todas las gramáticas bien escritas para Yacc.c) gcc analizador • $gcc analizador. funcionan en Bison sin necesidad de ser modificadas. YACC • Yet Another Compiler-Compiler • Analizador.

• Reduce/Reduce • Shift/Reduce •S •A •A •A A b a|b|c demasiada profundidad x|y|z S b ambigüedad infinita Analizador. Gramática vacía Gramática: prod1| prod2| . %% Código auxiliar C Tips Todo lexema debe ser un entero #define VAR 200 (256) return (VAR).%% Gramáticas Nombre:prod1|prod2|…|prodn.lex %{ #include “ytab.h” 40 .

41 .}% sp [\n\r\t] If [i][f] %% {if} {return (IF).c” }% %token IF PI PD LLI LLD %token ID NUM OPREL OPLOG %% programa: linea programa | . if: if PI condicion PD LLI campo LLD . return (ERROR).y %{ #include “lex. %% Analizador. } .yy.} “(” {return (PI). Linea: if linea | .

.y $gcc analizador. char *argv[]) { FILE *f = fopen(argv[1]. } Bison $flex analizador. while (yyparse()) . yyin = f. fclose(f) .c –o analizador –lfl • yytext componente léxico • yyin flujo de entrada • yylineno línea de error %% 42 .: {printf(“Error sintáctico”).lex $bison analizador. “r”) .} %% main(int argc.

1 Analizador semántico • Ajuste significativo • Comprobación de tipos: operandos-operadores • Comprobación del flujo de control: 43 . } Unidad V Análisis Semántico 5. yylineno).yyerror() { printf(“Error sintáctico en %d linea”.

uniones. carácter. objetos • Apuntadores: referencias a tipos • Funciones a=suma(). w= a+2. } Analizador semántico • Comprobación de unicidad • int a. real. ) { … break. //una sola vez • Comprobación relacionadas con nombres • Tabla de símbolos: – Estructura en memoria – Almacena información sobre los tipos • Sistemas de tipo: • Tipo básico: entero. lógico • Nombres de tipo • Constructores de tipo: estructuras. 44 .. • char a.for(.

de lo contrario no se pueden realizar los cálculos.2 Verificación de tipos en expresiones • La verificación de los tipos de datos se hace asignando el valor de tipo de cada una de los componentes léxicos. ámbito. 5. } 5. • Estos valores se comparan para verificar que los tipos de datos coincidan y sean congruentes. “abcdefghijk”) . strcpy(a. • Fuertemente tipificado • Débilmente tipificado Símbolo { nombre. tipo.3 Conversión de tipos 45 .• Sistema de tipos: conjunto de reglas que determinan el criterio para asignar expresiones de tipo a las diferentes partes del código fuente • Cada analizador semántico implementa un sistema de tipos • Comprobación dinámica y estática • Estática: compilación • Dinámica: Ejecución char a[5].

lo que se denomina conversión automática. • En Java se puede almacenar un valor byte en una variable int. int b. Ejemplos: 46 . como por ejemplo al pasar un valor flotante a un entero. dado que el tipo más pequeño se ensancha o promociona al tipo compatible más grande. • En algunos tipos es posible almacenar simplemente el valor sin una conversión de tipos. si el compilador reconoce que la variable destino tiene la suficiente precisión para contener el valor origen. dado que se estrecha explícitamente el valor para que quepa en el destino.• Hay situaciones en las cuales se tiene un valor de un tipo dado y se desea almacenar ese valor en una variable de un tipo diferente. a=(byte) b. (tipo) valor. Comprobación de tipos • Existen dos tipos de comprobación: estática y dinámica. • En algunos casos se puede realizar la conversión pero se pueden perder datos. • A esto se le llama estrechamiento. se desea asignar un valor de variable int a una variable byte se necesita realizar una conversión de tipos explícita. • La conversión de un tipo se realiza poniendo delante un nombre de tipo entre paréntesis. • byte a. Si por el contrario. dado que este tipo de datos es de mayor precisión que el primero. por ejemplo. • A esto se le llama ensanchamiento o promoción. • Esto sólo es posible en algún lenguaje de programación. • La comprobación ayuda a evitar la mayoría de los errores de programación.

• Comprobación de unicidad: definir un objeto una sola vez. * enteros que con punteros (aritmética de punteros) • Al conjunto de reglas que se definen para la comprobación de los tipos de datos se denomina sistema de tipos • La mayoría de veces la recuperación de errores se suele omitir ya que el programa no finaliza pero tal vez no obtenga los valores deseados 47 . goto. El mismo nombre debe aparecer dos veces. • + es una función suma(a. • Algunos lenguajes revisan el tamaño de los arreglos (Java) de manera estática otros lo hacen de manera dinámica (en tiempo de ejecución). Las demás comprobaciones son rutinarias. • El operador % ocupa que los dos operandos sean enteros. Variables que se declaran pero no utilizan Comprobación de tipos • La comprobación de tipos es la más complicada. Se debe verificar que las instrucciones que cambia el flujo de un programa sean válidos. • Comprobación relacionadas con nombres. • Diferenciar el uso de +.b) que está sobrecargada para distintos tipos de datos • Siempre se diseñan reglas de tipos como los valores numéricos se convierten al de mayor jerarquía o el tipo de datos punteros sólo apunta al tipo de datos declarado. Para saber si el operador aplicado a los operadores es correcto • Comprobación de flujo de control. Ejemplo: break.• Comprobación de tipos.

4 Acciones agregadas descendente (top-down) en un analizador sintáctico Muchas de las actividades que realiza un analizador semántico no son estándares.• Polimorfismo: una función puede tener el mismo nombre con diferentes elementos. su análisis como sistema y su codificación. • Se debe considerar el ámbito de las variables (locales y globales). El tipo de datos debe ser diferente. • Un ejemplo de polimorfismo son las plantillas en algún lenguaje de programación. 5. dependerán del objetivo del lenguaje de programación. en algunas aplicaciones es interesante conocer que los datos estén en algún rango válido o que ciertos valores se utilicen para uso reservado Acciones agregadas a un analizador semántico • En algunas ocasiones nos interesa conocer el significado de las palabras de algún lenguaje dependiendo del contexto (gramáticas de tipo 1) para diferenciar palabras polisemánticas. o 48 . por ejemplo. • La Web es una base de datos en la mayoría de los casos sin sentidos por lo que la tercera generación de la Web será la llamada Web semántica. 5.5 Pila semántica en un analizador sintáctico ascendente (bottom-up). El diseño ascendente se refiere a la identificación de aquellos procesos que necesitan computarizarse con forme vayan apareciendo.

bien.} | var ID {simbolo=yytext. símbolo. simbolo.} listavar var {inserta(símbolo). Pila semántica • Los problemas de integración entre los subsistemas son sumamente costosos y muchos de ellos no se solucionan hasta que la programación alcanza la fecha limite para la integración total del sistema. Operaciones sobre la tabla de símbolos • Inserta(símbolo) • Existe(nombre) • Tipo(nombre) • Declaración PYC • Listavar {inserta(simbolo).} • Var TIPO {tipo=obtengo(yytext()).} 49 .tipo=tipo.amb=ambito. La tabla de símbolos se mantiene durante todo el proceso de traducción agregando elementos específicos en cada paso.6 Administración de la tabla de símbolos La tabla de símbolos también recibe el nombre de ambiente. • Se necesita una memoria auxiliar que nos permita guardar los datos intermedios para poder hacer la comparación. Un ambiente contiene un conjunto de parámetros que sólo son visibles en ese ambiente. 5. la adquisición de paquetes de software para satisfacer el problema inmediato.

7 Manejo de errores semánticos Los errores semánticos son pocos y los que existen no se pueden detectar tan fácilmente. 50 . al tratar de obtener código existente de algunas funciones/métodos ya implementadas en bibliotecas/APIs.} OPLOG exprlog {A2=A • If(A1==INT && A2==INT) • A=INT. Muchos errores se generan durante la etapa del enlazador.• Exprlog PI exprlog {A=A. Los demás errores ya son muy difíciles de detectar y generalmente se dan en tiempo de ejecución. Hasta esta etapa los errores son mostrados a los usuarios. Algunos problemas se presentan durante la fase de gestión de memoria al pasar argumentos o al crear la pila semántica.} 5.} PD • |NOT exprlog {A=A.} • |exprlog {A1=A. • Else • A=ERROR_TIPO.

• a := b*-c+b*-c • abc -*bc -*+= • x:=yopz • x+y*z • t1:=y*z • t2:=x+t1 6.Unidad VI Generación de Código Intermedio La administración de la memoria se da en esta etapa. y en esta se utilizan generalmente pilas. Los lenguajes intermedios generalmente tienen árboles de derivación más pequeños que su contraparte original. Se puede representar un árbol sintáctico con un Grafo Dirigdo Acíclico (GDA).1 Lenguajes intermedios 51 . Se debe considerar tanto la memoria estática como dinámica. La notación postfija es una manera linealizada de representar un árbol sintáctico.

CORBA y su IDL. Otros lenguajes intermedios famosos son los generados para la máquina virtual de Java el bytecode. Otros lenguajes intermedios sirven de representación parcial de otros procesos.exe En sistemas basados en Unix. Las expresiones aritméticas se pueden expresar de tres formas distintas: infija. base o como Por ejemplo al compilar un programa en C en Windows o DOS. El uso más extendido de las notaciones sirve para expresar operaciones aritméticas.obj para que posteriormente el enlazador cree finalmente el código executable .Los lenguajes intermedios nos sirven para representar la producción final de nuestro lenguaje fuente. La diversidad de notaciones corresponde en que para algunos casos es más sencillo un tipo de notación. el 52 .2 Notaciones Las notaciones sirven de base para expresar sentencias bien definidas. etc.out.NET el MISL para luego ejecutarse en tiempo de ejecución JIT (Just in Time) Otros lenguajes intermedios se utilizan en sistemas distribuidos como RPC.o y el executable a. la mayoría de ellos son una representación más simplificada del código original para facilitar la traducción hacia el código final. En este caso estos lenguajes intermedios se encargan de enmascarar toda la heterogeneidad de las comunicaciones distribuidas en una computadora 6. prefija y postfija. Existen muchos lenguajes intermedios. se produce un código objeto con extensión . y para la máquina virtual de . también ocurre algo similar generándose un archivo . Las notaciones también dependen de cómo se recorrerá el árbol sintáctico.

formales para representar código • Estas notaciones simplifican la traducción de nuestro código fuente a nuestro código objeto ya que ahorran y acotan símbolos de la tabla de símbolos 6.3. preorden o postorden. No existe una estructura simple para representar este tipo de notación en la computadora por esta razón se utilizan otras notaciones.La notación posftfija utiliza una estructura del tipo LIFO (Last In First Out) pila. • Las estructuras FIFO son ampliamente utilizadas pero tienen problemas con el anidamiento aritmético. 6.3 Prefija • La notación prefija pone el operador primero que los dos operandos.2 Postfija La notación postfija pone el operador al final de los dos operandos. Esto se representa con una estructura del tipo FIFO (First In First Out) o cola.2. la cual es la más utilizada para la implementación.1 Notación Polaca 53 . 6. 6. Por ejemplo a+b-5.3 Representación de código intermedio • Existen maneras intermedio.cual puede ser en inorden.1 Infija La notación infija es la más utilizada por los humanos por que es la más comprensible ya que ponen el operador entre los dos operandos. teniendo una relación de uno a uno con la notación de los operadores.2. por lo que la expresión queda: ab+5.2. 6. por lo que la expresión anterior queda: +ab-5.

Las estructuras de control (if.La notación polaca. Con una estructura de tres campos se pueden omitir los valores temporales.3. y todavía puede ser analizada sin ambigüedad. 6. En muchos caso la P se asociado a código portable el cual garantiza que el código compilado en una máquina se pueda ejecutar en otras. Para garantizar la portabilidad del código se necesita que el lenguaje este estandarizado por algún instituto y que dicho código no tenga extensiones particulares. También se recomienda la no utilización de carácterísticas especiales exclusivas de alguna arquitectura de computadoras en particular. El problema de utilizar cuádruplos radica en que se tienen que colocar los valores temporales en la tabla de símbolo. for) son realmente etiquetas goto disfrazadas. Si la aridad de los operadores es fija. es una forma de notación para la lógica.3 Triplos Las proposiciones de tres direcciones se parece mucho al ensamblador. do-while. la aritmética. El lógico polaco Jan Łukasiewicz inventó esta notación alrededor de 1920 para simplificar la lógica proposicional.2 Código P El código P hace referencia a máquinas que utilizan o se auxilian de pilas para generar código objeto. while. también conocida como notación de prefijo o notación prefija.3. el cual es un lenguaje intermedio más entendible para la máquina. switch. 6. y el álgebra. dicha estructura recibe el nombre de triples y tiene los siguientes campos: op. el resultado es una sintaxis que carece de paréntesis u otros signos de agrupación. arg1 y arg2 54 . Su característica distintiva es que coloca los operadores a la izquierda de sus operandos.

3. utilizando para ello expresiones en corto circuito. En este sentido. • * b t1 t2 //cuádruplos • * b (0) //triple Se debe tener en cuenta el proceso de asignación. de declaración. 55 . Cuando se utilizan triples se ocupan punteros a la misma estructura de los triples. Las expresiones lógicas también pueden pasarse a código de tres direcciones. aunque en ocasiones puede variar. en el caso del operador OR si se encuentra una condición verdadera todo será verdadera 6. un compilador es más difícil de implementar ya que tendrá que mantener todas las estructuras generadas que en muchas ocasiones serán cuadrúplos.Generalmente el código que generan los triples recibe el nombre de código de dos direcciones.4. expresiones booleanas.1 Intérpretes Los intérpretes generalmente utilizan este triplos para generar el código intermedio para ejecutarse una vez considerado la instrucción como válido. La evaluación de expresiones en corto circuito implica que se evalúan condiciones revisando valores anteriores. por ejemplo. para el operador AND con una condición que se detecte como falsa toda la expresión es falsa.

4. de tal forma que una expresión sea lo más mínimo posible. Generalmente arg1.4 Esquemas de generación Los esquemas de generación son las estrategias o acciones que se deberán realizarse y tomarse en cuenta en el momento de generar código intermedio.b. arg1.3.1 Expresiones Para generar expresiones estas deben representarse de manera más simple y más literal para que su conversión sea más rápida. Los operadores unarios como x:=-y no utilizan arg2. se descompone a int a. 6.4.6.c. 6. Por ejemplo la traducción de operaciones aritméticas debe especificarse una por una.4. 6. intc.3 Estatuto de asignación Las operaciones de asignación deben quedar expresadas por una expresión sencilla. constantes Las declaraciones de variables y constantes deben separarse de tal manera que queden las expresiones una por una de manera simple. arg2 y resultado son valores de tipo puntero y apuntan a una entrada en la tabla de símbolos. OP tiene un código intermedio. si está es compleja se debe reducir hasta quedar un operador sencillo. Los esquemas de generación dependen de cada lenguaje. 6. respectivamente. arg2 y resultado. int b. Tomaremos algunos esquemas de generación del lenguaje C.2 Declaración de variables.4 Cuádruplos Es una estructura tipo registro con cuatros campos que se llaman: op. Por ejemplo int a. 56 .

En el caso de C.4.5 Estatuto de ciclos Los ciclos se descomponen en un ciclo genérico. debe quedar de la forma y = b/5.4. lo que se hace es expander el código original de la función. Las condiciones lógicas también pueden ser evaluadas en cortocircuito y reducidas. 6. z = a+y. a[4]=‘\0’. así por ejemplo: char *a=“Hola”.4.4.6 Arreglos Los arreglos se descomponen en estructuras básicas de manejo de manera simple. a[3]=‘a’. a[2]=‘l’. for y dowhile tienen la misma representación interna. 57 .7 Funciones Las funciones pueden reducir a en línea. todo queda en forma de while. a[1]=‘o’. se reduce a: a[0]=‘H’. 6. Las funciones se descomponen simplificando los parámetros de manera individual al igual que el valor de retorno.• Por ejemplo: x = a+b/5. if (y) • Las instrucciones de decisión compleja como switch se reducen a una versión complejas de if’s 6. Por ejemplo una instrucción como: if (a == b && f!=5 && f %3==0) se evalúa primero x = (a==b && f!=5) y = x && f %3==0. x=z. por lo que ciclos while. 6.4 Estatuto condicional Las condiciones deben expresarse de manera lo más sencilla posible de tal forma que puedan evaluarse en cortocircuito.

1 Tipos de optimización Las optimizaciones pueden realizarse de diferentes formas. procesador. Desafortunamente no existen optimizador que hagan un programa más rápido y que ocupe menor espacio. generalmente tiempo. espacio. Algunos editores ofrecen una versión de depuración y otra de entrega o final. La mayoría de los compiladores tienen una 58 . etc. La optimización va a depender del lenguaje de programación y es directamente proporcional al tiempo de compilación. es decir. entre más optimización mayor tiempo de compilación. La optimización se realiza reestructurando el código de tal forma que el nuevo código generado tenga mayores beneficios. La optimización es un proceso que tiene a minimizar o maximizar alguna variable de rendimiento.Unidad VII Optimización 7. Las optimizaciones se realizan en base al alcance ofrecido por el compilador. Tipos de optimización Como el tiempo de optimización es gran consumidor de tiempo (dado que tiene que recorrer todo el árbol de posibles soluciones para el proceso de optimización) la optimización se deja hasta la fase de prueba final.

el problema se hace N veces más grandes.1. La característica de las optimizaciones locales es que sólo se ven reflejados en dichas secciones.….optimización baja. La optimización local sirve cuando un bloque de programa o sección es crítico por ejemplo: la E/S. c=5. la rapidez y confiabilidad de un conjunto de instrucciones. se necesita de compiladores especiales para realmente optimizar el código. y si dichas acciones están mal realizadas.1 Locales La optimización local se realiza sobre módulos del programa. Como el espacio de soluciones optimización local es más rápida 7. procedimientos. 7. clases.2 Bucles Los ciclos son una de las partes más esenciales en el rendimiento de un programa dado que realizan acciones repetitivas. la concurrencia. Ciclos while(a == b) { intc=a. En la mayoría de las ocasiones a través de funciones. métodos. } es más pequeño la 59 .1. etc. La mayoría de las optimizaciones sobre ciclos tratan de encontrar elementos que no deben repetirse en un ciclo.

utilizar instrucciones en ensamblador. Este tipo de optimización es más lenta pero mejora el desempeño general de todo programa. sobre todo en instrucciones de bifurcación como son las decisiones.2 Costos Los costos son el factor más importante a tomar en cuenta a la hora de optimizar ya que en ocasiones la mejora obtenida puede verse no reflejada en el programa final pero si ser perjudicial para el equipo de desarrollo. El problema de la optimización en ciclos y en general radica es que muy difícil saber el uso exacto de algunas instrucciones. Así que no todo código de proceso puede ser optimizado.1. La optimización de una pequeña mejora tal vez tenga una pequeña ganancia en 60 .4 De mirilla La optimización de mirilla trata de estructurar de manera eficiente el flujo del programa. E/S.1. fuera del ciclo de ser posible.3 Globales La optimización global se da con respecto a todo el código. Otros uso de la optimización pueden ser el mejoramiento de consultas en SQL o en aplicaciones remotas (sockets. etc. siendo el salto lo más pequeño posible 7. 7. En algunos casos es mejor mantener variables globales para agilizar los procesos (el proceso de declarar variables y eliminarlas toma su tiempo) pero consume más memoria. Algunas optimizaciones incluyen utilizar como variables registros del CPU. ciclos y saltos de rutinas. La idea es tener los saltos lo más cerca de las llamadas.En este caso es mejor pasar el int c =a.) 7. Las optimizaciones globales pueden depender de la arquitectura de la máquina.

Los costos de ejecución son aquellos que vienen implícitos al ejecutar el programa. Los dispositivos móviles tiene recursos más limitados que un dispositivo de cómputo convencional razón por la cual.2 Criterios para mejorar el código 61 . i++). i < 10000.2.1 Costo de ejecución.2. la mejora obtenida puede ser N veces mayor por lo cual el costo se minimiza y es benéfico la mejora. tarjetas de video) o de mucha memoria. Por ejemplo: for(int i=0.tiempo o en espacio pero sale muy costosa en tiempo en generarla. el mejor uso de memoria y otros recursos de hardware tiene mayor rendimiento. por lo que el espacio y la velocidad del microprocesadores son elementos que se deben optimizar para tener un mercado potencial más amplio. si la ganancia es de 30 ms 300s 7. Costos de ejecución Las aplicaciones multimedias como los videojuegos tienen un costo de ejecución alto por lo cual la optimización de su desempeño es crítico. En algunos programas se tiene un mínimo para ejecutar el programa. 7.g. Otro tipo de aplicaciones que deben optimizarse son las aplicaciones para dispositivos móviles. la gran mayoría de las veces requieren de procesadores rápidos (e. En algunos casos es preferible tener la lógica del negocio más fuerte en otros dispositivos y hacer uso de arquitecturas descentralizadas como cliente/servidor o P2P. Pero en cambio si esa optimización se hace por ejemplo en un ciclo.

2. entre ellas tenemos los depuradores y desambladores. Se basa en una lógica binaria de 0 y 1.1. 7. La optimización al igual que la programación es un arte y no se ha podido sistematizar del todo. Unidad VIII Generación de código intermedio 8.La mejor manera de optimizar el código es hacer ver a los programadores que optimicen su código desde el inicio. el problema radica en que el costo podría ser muy grande ya que tendría que codificar más y/o hacer su código más legible. En general el lenguaje máquina es difícil de entender para los humanos por este motivo hacemos uso de lenguajes más parecidos a los lenguajes naturales.1 Lenguaje máquina El lenguaje máquina sólo es entendible por las computadoras.3 Herramientas para el análisis del flujo de datos Existen algunas herramientas que permiten el análisis de los flujos de datos. 8. generalmente implementada por mecanismos eléctricos. Criterios de optimización Muchos de estos criterios pueden modificarse con directivas del compilador desde el código o de manera externa.1 Características 62 . Este proceso lo realizan algunas herramientas del sistema como los ofuscadores para código móvil y código para dispositivos móviles. Los criterios de optimización siempre están definidos por el compilador.

generalmente el inicio del programa. posteriormente aparecieron los compiladores.1 Características 63 . repetitiva) El lenguaje máquina es dependiente del tipo de arquitectura.2 Lenguaje ensamblador El ensamblador (del inglés assembler) es un traductor de un código de bajo nivel a un código. pero en general existen dos tipos de direccionamiento: directo e indirecto. sólo realizan operaciones del tipo aritmética (+. OR. /).2. 8. La forma de acceder a la memoria depende del microprocesador. ejecutable directamente por la máquina para la que se ha generado. NOT) y de control (secuencial. Recordar que un programa no puede ejecutarse sino se encuentra en memoria principal. Así un programa máquina para una arquitectura intel x86 no se ejecutará en una arquitectura Power PC de IBM (al menos de manera nativa). El direccionamiento indirecto también recibe el nombre de direccionamiento relativo y se basa a partir de una dirección genérica. El direccionamiento directo también recibe el nombre de direccionamiento absoluto y el acceso a las direcciones se hace de manera directa. Fue la primera abstracción de un lenguaje de programación.-. decisión. lógicas (AND.El lenguaje máquina realiza un conjunto de operaciones predeterminadas llamadas micro operaciones. Algunos microprocesadores implementan más funcionalidades llamado CISC. 8. pero son más lentos que los RISC ya que estos tienen registros más grandes.1.*. 8.2 Direccionamiento Es la forma en como se accede a la memoria.

o macro ensambladores.2. Algunos registros de propósito general son utilizados para cierto tipo de funciones. antes de la generalización de los lenguajes de alto nivel. Los programas se hacen fácilmente portables de máquina a máquina y el cálculo de bifurcaciones se hace de manera fácil.El programa lee un archivo escrito en lenguaje ensamblador y sustituye cada uno de los códigos mnemotécnicos por su equivalente código máquina. Existen diversos registros de propósito general y otros de uso exclusivo. Descendientes de los ensambladores básicos. Son de muy bajo nivel.3 Registros Los registros son la memoria principal de la computadora. 8. 64 . y su tarea consiste básicamente en ofrecer nombres simbólicos a las distintas instrucciones. Clasificación ensambladores Ensambladores básicos. Además nos permite acceder directamente a los recursos de la máquina para un mejor desempeño. las bifurcaciones y el paso de parámetros. Un macroinstrucción es el equivalente a una función en un lenguaje de alto nivel. parámetros y cosas tales como los modos de direccionamiento. Ensambladores modulares. es que se encarga de administrar de manera transparente para el usuario la creación de memoria. fueron muy populares en las décadas de los 50 y los 60. 8.2 Almacenamiento Una de las principales ventajas del uso del ensamblador.

si son dinámicas no pero el programa es más pequeño. 8. si son estáticas se incluyen en el ejecutable por lo que el programa se hace gráfico. Cuando se trata de memoria dinámica se debe seguir el rastro de los datos 65 . pero nunca de memoria a memoria.3. 8.Existen registros acumuladores. o de registro a memoria.1 Distribución La distribución es el proceso en el que el programa generado puede ejecutarse en otras máquinas. etc. de pila.3. Con respecto al ensamblador. puntero de instrucción.2 Asignación La asignación de valores a variables se hace a través de un proceso de mover el contenido de memoria a registro. la mayoría del direccionamiento se hace relativo para que el programa sea relocalizable por un programa llamado cargador En el caso de programas compilados se necesitan de las librerías.

4 Administración de memoria La administración de la memoria es un proceso hoy en día muy importante. Administración de memoria En la mayoría de los lenguajes de programación el uso de punteros no estaba vigilado por lo que se tienen muchos problemas con el uso de memoria. En general un ensamblador tiene un administrador de memoria más limitado que un compilador. 66 .8. de tal modo que su mal o buen uso tiene una acción directa sobre el desempeño de memoria. • Los lenguajes más recientes controlan el uso de punteros y tienen un programa denominado recolector de basura que se encarga de limpiar la memoria no utilizada mejorando el desempeño.

mitecnologico..BIBLIOGRAFIA www./Programacion%20de%20sistemas_ISC.pdf 67 ..sistemas.itmorelia.edu.pdf antares.ith.mx/~jcolivar/courses/ps207a/ps2_u1.mx/.com/Main/ProgramacionDeSistemas www.

You're Reading a Free Preview

Descarga
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->