1. INTRODUCCIÓN 1 Generalidades Sobre los Lenguajes 2 Justificación del Estudio Disponer de opciones de elección de lenguajes alternativos Facilitar el aprendizaje de nuevos lenguajes Permitir el diseño adecuado de un lenguaje (p. e. una API) 3 Importancia de un Lenguaje Provee una notación de alto nivel para implementar algoritmos Provee una abstracción de una máquina difícil de programar 4 Características Deseables Rapidez de aprendizaje Integridad conceptual (pocos conceptos) Ortogonalidad (composición de abstracciones, pocos casos especiales) Expresividad Rapidez de programación Legibilidad 5 Evolución de conceptos ABSTRACCIÓN DE DATOS Tipos simples Tipos compuestos Tipos abstractos 6 Evolución de conceptos ABSTRACCIÓN DEL CONTROL Sentencias Unidades de Programas 7 Sentencias • Asignación • Selección (simple, doble y múltiple) • Repetición(con expresión booleana y con variable de control) • Entrada-Salida • Invocación 8 Unidades de programas • Favorecen la programación modular • Generalizan la noción de operador • Permiten encapsular parte de un algoritmo • Tienen una única definición • Posibilitan múltiples activaciones 9 Paradigmas de Programación 10 Clasificación de los Lenguajes 11 Clasificación de Lenguajes LENGUAJES Naturales De Programación De Máquina Simbólicos De Bajo Nivel De alto Nivel 12 Clasificación de Lenguajes LENGUAJES DE ALTO NIVEL Descriptivos de Hardware Imperativos Declarativos Orientados a Objetos Orientados a la Web Concurrentes Reactivos Reflexivos 13 Niveles de abstracción C++ Delphi Pascal Mayor nivel de abstracción C Ensambladores Máquina C# VHDL Java Ruby 14 Lenguajes Descriptivos de Hardware Destinados a definir la estructura, el diseño y la operación de circuitos electrónicos digitales Posibilitan el manejo explícito del tiempo Proveen mecanismos para la implementación de concurrencia Permiten tanto la simulación como el análisis automático de circuitos Algunos de ellos: VHDL, Verilog, ABEL 15 Lenguajes Imperativos Surgen como los primeros lenguajes de alto nivel: Fortran, COBOL, Pascal, C, Ada Se denominan también procedurales Se caracterizan por cambiar el estado de las variables mediante asignación Según Wirth Programa = Algoritmos + Estructuras de Datos Es imprescindible conocer la naturaleza (tipo) de los datos 16 Lenguajes Declarativos Declaran condiciones, proposiciones, afirmaciones, restricciones, ecuaciones o transformaciones Describen qué hacer y no cómo hacer Se basan en el cálculo o en la lógica de primer orden Las variables están dotadas de transparencia referencial No contemplan la asignación ni la tipificación La estructura básica de control es la recursión 17 Lenguajes Declarativos Se subclasifican en: Funcionales, por ejemplo Lógicos, por ejemplo Lisp Haskell Prolog Gödel Algebraicos, por ejemplo SQL Maude 18 Lenguajes Lógicos Se basan en la lógica de primer orden Especifican conocimiento mediante reglas y hechos Regla: mecanismo de inferencia lógica que deduce nuevo conocimiento Hecho: cláusula relacional verdadera o falsa Según Kowalski Algoritmo = Lógica + Control 19 Lenguajes Funcionales Funcionales puros: Haskell, Miranda Funcionales híbridos: ML, Lisp, Scheme Funcionales tácitos: J, Apl Se basan en la lógica ecuacional Su fundamento es el cálculo Un programa se concibe como una composición de expresiones evaluadas como funciones 20 Lenguajes Funcionales Ejemplo en Scheme: Función f(x) = (x + 1)2 + (2x)2 (define (cuad x) (* x x)) (define (sum x y) (+ x y)) (define (mult x y) (* x y)) (define (f x) (sum (cuad (sum x 1)) (cuad (mult 2 x)))) (f 2) 25 21 Lenguajes Orientados a Objetos Representan un modelo de interacción entre objetos, cada uno de los cuales actúa en función de un estado y un comportamiento Se construyen objetos complejos a partir de objetos simples, bajo el principio de la reutilización de código (herencia) Algunos de ellos son Smalltalk, C++, Java, C#, Python 22 Lenguajes Orientados a Objetos Fundamentos Tipo abstracto de datos (TAD) es un modelo conceptual representativo de un conjunto de objetos cuyas características sólo se pueden establecer a través de una colección de operaciones Encapsulamiento es la propiedad que permite reunir datos y operaciones al interior de una estructura única, restringir su acceso y ocultar información 23 Lenguajes Orientados a Objetos Fundamentos Jerarquía es la propiedad que permite ordenar estructuralmente las abstracciones; se presenta en las formas de especialización (herencia: relación esun) y agregación (composición: relación tiene-un) Polimorfismo es la propiedad que permite a una entidad adoptar múltiples formas; se presenta en calidad de polimorfismo paramétrico (o genérico), ad-hoc (o de sobrecarga) y de inclusión (o de sobreescritura) 24 Lenguajes Orientados a Objetos Caracterización Un objeto es un modelo de una entidad concreta o abstracta Objetos de una misma categoría constituyen una clase Un objeto es un ejemplar (instancia) de una clase Los objetos interactúan mediante mensajes 25 Lenguajes Orientados a Objetos Caracterización Un método (operación) se activa mediante un mensaje enviado al objeto Un atributo (dato) es una mantenida por un ejemplar variable interna Los atributos de un objeto representan su estado Los métodos de comportamiento un objeto determinan su 26 Lenguajes Orientados a la Web Presentación: SGML, HTML, XML Desarrollo: JavaScript, PHP, Ruby, Dart, Haxe Destinados a la programación de aplicaciones soportadas por los navegadores web Orientados a satisfacer la dinámica de la interacción entre clientes y servidores en internet 27 Lenguajes Concurrentes Destinados a la programación de aplicaciones que interactúan simultáneamente Las aplicaciones son subprocesos denominados tareas (tasks), hilos (threads) o actores (actors) Dado que los subprocesos comparten recursos, los lenguajes concurrentes deben facilitar tanto la exclusión mutua como la sincronización Algunos de ellos: Java, Scala, Erlang 28 Lenguajes Reactivos Orientados al flujo de datos bajo el principio de causalidad (propagación de cambios) Características: Responsividad (eficiencia en respuestas) Resiliencia (tolerancia a fallas) Elasticidad (adaptación a variaciones de carga) Orientación a mensajes (interacción a través de mensajería asíncrona) Algunos de ellos: R, Oz, Elm 29 Lenguajes Reactivos Por ejemplo, el código reactivo A = 8; B = A + 1; print B; A = 2; print B; genera la salida 9 3 30 Lenguajes Reflexivos Orientados al auto-análisis y la auto-adaptación de programas en tiempo de ejecución Características: Tratamiento de las instrucciones como datos Clasificables como lenguajes débilmente tipados Identificables con los lenguajes basados en máquina virtuales 31 Lenguajes Reflexivos Niveles de reflexión de un programa: 1. Capacidad de capturar información de sí mismo en tiempo de ejecución 2. Capacidad de vincular y utilizar códigos en tiempo de ejecución 3. Capacidad de modificar el propio código en tiempo de ejecución Algunos de ellos: Smalltalk, Racket, C# 32 Homoiconicidad Propiedad de un lenguaje de programación cuya representación primaria es también una estructura de datos de tipo primitivo en él Permite extender conceptualmente el lenguaje de manera simple y entender un programa como un valor en el propio lenguaje (el código también es un dato) La estructura primaria en Lisp es la lista y en Lisp un programa es una lista 33 Factorial en diversos Lenguajes Ada Ruby function Fact(n : integer) return integer is i, prod : integer; begin prod := 1; for i in 2..n loop prod := prod*i; end loop; return prod; end Fact; def fact(n) prod = 1 for i in 2..n do prod = prod*i end return prod end 34 Factorial en diversos Lenguajes Fortran 90 C INTEGER FUNCTION FACT (N) INTEGER :: I, N, PROD PROD = 1 DO I = 2, N PROD = PROD * I END DO FACT = PROD END int fact(int n) { int i, prod=1; for(i=2; i<=n; i++) prod = prod*i: return prod; } 35 Factorial en diversos Lenguajes Pascal Python function fact(n : integer) : integer; var i, prod : integer; begin prod := 1; for i:=2 to n do prod := prod*i; fact := prod; end; def fact(n) : prod = 1 for i in range(2, n+1) : prod = prod*i return prod 36 Factorial en diversos Lenguajes Java Go public int fact(int n) { int prod = 1; for (int i = 1; i <= n; i++) { prod = prod*i; } return prod; } func fact(n int) int { prod := 1 for i:=2; i<=n; i++ { prod = prod*i } return prod } 37 Factorial en diversos Lenguajes Swift Scala func fact(n : Int) -> Int { var prod = 1 for var i=2; i<=n; i++ { prod = prod*i } return prod } def fact(n : Int) : Int = { var prod = Int(1) for (i <- 2 to n) prod = prod*i prod } 38 Ranking de Lenguajes El índice TIOBE (The Importance Of Being Earnest) se basa en el número de páginas web indexadas por los más usados motores de búsqueda que referencian lenguajes de programación http://www.tiobe.com/index.php/content/ paperinfo/tpci/index.html 39 Ranking de Lenguajes El índice PYPL (PopularitY of Programming Languages Index) mide la frecuencia con la que los desarrolladores de software buscan tutoriales de lenguajes de programación http://pypl.github.io/PYPL.html 40 Sintaxis 41 Análisis léxico La primera fase de un compilador consiste en disgregar el código fuente en sus componentes más elementales, es decir, en tokens (palabras del lenguaje) Usualmente, la estructura de un token se define como una expresión regular Una expresión regular es un patrón utilizado para reconocer una determinada combinación de caracteres dentro de un texto 42 Análisis léxico Los tokens se describen, por ejemplo, mediante: "+" "*" "(" ")" "while“ "final" -> -> -> -> -> -> PLUS TIMES LPAR RPAR WHILE FINAL 43 Análisis sintáctico La segunda fase de un compilador consiste en aceptar como entrada la salida del analizador léxico, aplicar las reglas de producción de una gramática libre de contexto (reconocida por un autómata de pila) y generar como salida un árbol sintáctico La salida de un analizador sintáctico constituye la entrada de un analizador semántico 44 Análisis sintáctico 45 Análisis sintáctico 46 Elementos Sintácticos Set de caracteres Identificadores Símbolos para operadores Palabras claves y reservadas Comentarios Delimitadores Expresiones Sentencias Unidades de programas 47 Gramática Representa la definición formal de la sintaxis de un lenguaje Provee un conjunto de reglas de producción correcta de los elementos sintácticos de un lenguaje 48 Metalenguaje Gramática formal destinada a la descripción de la sintaxis de un lenguaje El máximo exponente de los metalenguajes es BNF (Backus-Naur-Form), a partir del cual derivan EBNF (Extended BNF), CBL (COBOL-Like) y los Diagramas sintácticos 49 BNF Notación desarrollada por los especialistas Backus y Naur para definir lenguaje Algol 60 Metasímbolos: • < >: indica símbolo NO-TERMINAL o meta variable • ::= : "Se define como" • |: "o" • identificador: Palabra reservada, constante o símbolo TERMINAL 50 BNF Número entero sin signo <entero sin signo> ::= <dígito> | <dígito> <entero sin signo> <dígito> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 Número real sin signo <real sin signo> ::= <secuencia> . <secuencia> <secuencia> ::= <dígito> | <dígito> <secuencia> <dígito> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 51 BNF Sentencia if <s-if> ::= if ( <expresión booleana> ) <sentencia> | if ( <expresión booleana> ) <sentencia> else <sentencia> Sentencia while <s-while> ::= while ( <expresión booleana> ) <sentencia> Sentencia do-while <s-do-while> ::= do <sentencia> while (<expresión booleana> ) 52 BNF <identificador> ::= <letra> | <letra> <secuencia> <secuencia> ::= <carácter> | <carácter> <secuencia> <carácter> ::= <letra> | <dígito> | _ <letra> ::= A | B | … | Z | a | b | … | z Multilista: (1 2 (3 4 (5) 6) 7 8) <mlista> ::= () | (<lista>) <lista> ::= <elemento> | <elemento> <lista> <elemento> ::= <átomo> | <mlista> 53 BNF Sentencia <sentencia> ::= <simple> | <compuesta> <simple> ::= <asignación> | <invocación> | <selección> | <repetición> <compuesta> ::= {<sentencias>} <sentencias> ::= <simple>; | <simple>; <sentencias> 54 BNF Expresión aritmética x término a*b c/d término término a * b factor factor <ea> ::= <término> | <st> <término> | <ea> <st> <término> <término> ::= <factor> | <factor> <sf> <término> <factor> ::= <id> | <constante> | (<ea>) <st> ::= + | <sf> ::= * | / 55 ÁRBOL DE DERIVACIÓN Una estructura sintáctica es válida si existe un árbol de derivación en el cual la lectura secuencial de las hojas es el programa inicial, la raíz es el símbolo no terminal inicial y cada nodo interno representa una producción de la gramática Ejemplo 3 * (5 + 2) ; NUMBER(3) TIMES LPAR NUMBER(5) PLUS NUMBER(2) RPAR SEMI 56 ÁRBOL DE DERIVACIÓN expre expre NUMBER(3) TIMES expre LPAR expre expre NUMBER(5) PLUS NUMBER(2) expre RPAR SEMI 57 ÁRBOL DE DERIVACIÓN Una gramática es no ambigua si para toda estructura sintáctica existe, a lo más, un árbol de derivación. Pero, esto puede causar problemas semánticos como, por ejemplo, en la expresión 3 - 2 - 1 expre expre NUMBER(3) MINUS expre expre NUMBER(2) MINUS expre NUMBER(1) Con este árbol, al evaluar esa expresión resulta 2 y no 0 58 Azúcar Sintáctico Término acuñado por Peter J. Landin para referirse a las formas complementarias alternativas que un lenguaje de programación provee para hacer más compactas o comprensibles ciertas construcciones sintácticas Esto significa que cualquier forma en calidad de azúcar sintáctico puede ser eliminada sin afectar la expresividad de los programas escritos en el lenguaje 59 Azúcar Sintáctico Ejemplos v[i] x += y; int max = (a > b) ? a : b; *(v + i) x = x + y; int max; if (a > b) max = a; else max = b; En ocasiones, los traductores convierten estas formas complementarias alternativas en las formas básicas provistas por la definición sintáctica del lenguaje 60 Semántica Sintaxis ¡Cómo se expresa un concepto! Semántica ¡Qué significa ese concepto! Semántica se define como el conjunto de reglas que establecen el significado de las expresiones sintácticas Es decir, el conjunto de reglas que determinan el comportamiento de un lenguaje en tiempo de ejecución 61 Semántica Existen cuatro modelos de especificación del significado de los constructores sintácticos: Semántica descriptiva Notación usada por los diccionarios enciclopédicos Semántica operacional (Plotkin) Orientada a la implementación del lenguaje, el significado se define mediante una máquina abstracta (con estados) y secuencias de cómputos sobre dicha máquina 62 Semántica Semántica denotacional (Scott-Strachey) Orientada al diseño del lenguaje, el significado se modela como entidad matemática (en general una función), estando presente aún la noción de estado Semántica axiomática (Floyd-Hoare) Orientada al uso del lenguaje, el significado se establece mediante sentencias lógicas sobre el efecto de la ejecución de un programa 63 Procesadores de Lenguajes 64 Procesador DEFINICIÓN Un procesador es una máquina capaz de ejecutar acciones expresadas en algún lenguaje concreto Actualmente, el único lenguaje concreto que existe es el lenguaje de máquina 65 Traductor Es un decodificador que acepta programas escritos en algún lenguaje fuente y genera programas, funcionalmente equivalentes, en algún lenguaje objeto Programa en Lenguaje Fuente Traductor Programa en Lenguaje Objeto Preprocesador Compilador Ensamblador Ligador Cargador 66 Pre-procesador Es un traductor cuyo lenguaje fuente es una extensión de un lenguaje de alto nivel lenguaje objeto es el estándar del lenguaje de alto nivel Por ejemplo, C y C++ Programa en extensión de LAN Pre-procesador C++ Preprocesador Compilador C Ensamblador Leng. Ensam. Programa en LAN estándar Cargador Código Reubicable Código Ejecutable 67 Pre-procesador #define entero int #define si if #define mientras while #define retornar return entero prod(entero x, entero y){ entero z=0; mientras(y){ si(y%2) z += x; x *= 2; y /= 2; } retornar z; } 68 Compilador Es un traductor cuyo lenguaje fuente es un lenguaje de alto nivel lenguaje objeto es un lenguaje orientado a la máquina Programa en lenguaje de alto nivel Código Fuente Compilador Fases de Compilación Programa en lenguaje orientado a la máquina Código Objeto Análisis léxico Análisis sintáctico Análisis semántico Generación de código intermedio Generación de código ejecutable 69 Compilador Análisis léxico Reconocimiento y clasificación de tokens básicos: Constantes Identificadores Palabras reservadas, etc. Construcción de la tabla de símbolos Lista de todos los símbolos y sus atributos usados en un programa (variables, etiquetas, rutinas, etc) 70 Compilador Generador de analizador léxico Es un programa que, a partir de una especificación del léxico de un lenguaje, genera un analizador léxico (scanner), es decir, un programa que entrega uno a uno los tokens de un código fuente Generadores de analizadores léxicos son, por ejemplo, Lex para C, Flex para C++ y JLex para Java 71 Compilador Análisis sintáctico Generación del árbol sintáctico del programa fuente, en el cual: Las hojas corresponden a los tokens Los nodos internos representan reducciones gramaticales La raíz constituye el nodo inicial de la gramática del lenguaje 72 Compilador Análisis sintáctico Expresión a + b*c Término Expresión + Término Factor Identificador Factor a * Término Identificador Factor b Identificador c 73 Compilador Generador de analizador sintáctico Es un programa que a partir de la especificación de la sintaxis de un lenguaje genera un analizador sintáctico (parser), es decir, un programa que comprueba el cumplimiento de esa especificación en la estructura de un código fuente Generadores de analizadores sintácticos son, por ejemplo, Yacc, Bison y Gold 74 Compilador Análisis semántico Análisis de tipos Aplicación de reglas de inferencia para determinar el tipo de las expresiones Consistencia semántica del árbol sintáctico Coherencia entre operadores y operandos 75 Compilador Generación de código intermedio Convierte el programa en un código de máquina abstracto (independiente de la arquitectura del procesador de destino) Transforma el árbol sintáctico en una lista equivalente de instrucciones de bajo nivel 76 Compilador Generación de código intermedio while((a>b) && (a<=2*b 4)) a = a + b; L1: if(a>b) goto L2; goto L3; L2: t1 = 2*b; t2 = t1 4; if(a <= t2) goto L4; goto L3; L4: a = a + b; goto L1; L3: … 77 Compilador Optimización de código intermedio Objetivo: obtener un código ejecutable eficiente según los criterios de optimización tanto temporal como espacial Funcionamiento: revisa el código generado según los niveles de abstracción fijados y aplica las optimizaciones que correspondan Condiciones: el código optimizado debe demandar menos tiempo y espacio que la versión previa; las transformaciones aplicadas deben preservar la semántica de los programas 78 Compilador Optimización de código intermedio L1: if(a<=b) goto L3; t1 = 2*b; t2 = t1 4; if(a > t2) goto L3; a = a + b; goto L1; L3: … 79 Compilador Optimización de código intermedio a = b + c + d; e = b + c + f; t1 = b + c; a = t1 + d; e = t1 + f; 80 Compilador Optimización de código intermedio do { b = 1; a = a b; } while(a ! = 0); b = 1; do { a = a b; } while(a ! = 0); 81 Compilador Generación del código ejecutable Existen dos enfoques: Archivos binarios Compilación JIT (Just In Time), es decir, compilación en tiempo de ejecución, conocida también como traducción dinámica 82 Compilador Archivos Binarios 1. A partir del código intermedio, el compilador genera un programa en lenguaje ensamblador 2. Luego, el ensamblador genera un archivo binario del programa, el cual es directamente ejecutable (código reubicable, es decir, código con direcciones de memoria relativas) 3. Finalmente, el núcleo del sistema operativo carga el archivo binario, creando un proceso con su espacio de direcciones (código con direcciones de memoria absolutas) 83 Compilador Compilador Autocontenido Compilador escrito en el mismo lenguaje que pretende compilar el cual, evidentemente, no se puede ejecutar la primera vez Sirve para extender el lenguaje o mejorar el código generado Genera el problema conocido como bootstrapping, es decir, el primer compilador creado para un lenguaje tiene que ser compilado por un compilador escrito en otro lenguaje o bien compilado al ejecutar el compilador en un intérprete 84 Ensamblador Es un traductor cuyo Lenguaje fuente es un lenguaje ensamblador (representación simbólica del lenguaje de máquina) Lenguaje objeto es el lenguaje de máquina del computador Programa en Leng. Ensam. Ensamblador Programa en LM 85 Ligador Es un traductor cuyo Lenguaje fuente es el lenguaje de máquina Integra, en un único módulo de carga, el código compilado de la aplicación con el código compilado preexistente correspondiente a las librerías utilizadas Lenguaje objeto es el lenguaje máquina, pero en la versión denominada código reubicable Programa en lenguaje de máquina Linker Programa en leng. de máquina código reubicable 86 Cargador Es un traductor cuyo Lenguaje fuente es el código reubicable (lenguaje de máquina con direcciones relativas) Carga el programa en la RAM, actualizando las tablas de datos, es decir, transformado direcciones relativa en absolutas Lenguaje objeto es el código real (lenguaje de máquina con direcciones absolutas) Programa Ejecutable Programa como código reubicable Loader Programa como código real 87 Ejercicio La séptima instrucción de un código reubicable P se sitúa a partir de la dirección 100000 en la RAM de un computador de 64 bits. Determinar la dirección base de P. Instrucciones antes de la séptima: 6 Tamaño de la instrucción: 8 Luego, el desplazamiento para la séptima instrucción es 6*8 bytes 0 8 16 24 32 40 48 99952 99960 99968 99976 99984 99992 100000 1 2 3 4 5 6 7 8 … 88 Transpilador Es un traductor cuyo lenguaje fuente es un lenguaje de alto nivel lenguaje objeto es un también lenguaje, generalmente, de alto pero menor nivel Ejemplos de transpiladores: Nombre Lenguaje fuente Lenguaje objeto Cfront C++ C HipHop for PHP (HPHPc) PHP C++ Babel JavaScript ES6 JavaScript ES5 ClojureScript Clojure JavaScript JSweet Java TypeScript Swiftify Objective-C Swift J2ObjC Java Objective-C 89 Intérprete Es un procesador cuyo lenguaje concreto es un lenguaje simbólico Hoy, ningún computador es capaz de ejecutar código distinto al de máquina Se debe simular mediante software la existencia de un computador (máquina virtual) cuyo lenguaje de máquina es un lenguaje simbólico 90 Intérprete Interpretación del código fuente El lenguaje fuente es un lenguaje de alto nivel Cada vez que se ejecuta el programa, el intérprete realiza las fases de compilación desde el análisis léxico hasta la generación de código intermedio Seguidamente, el intérprete decodifica y ejecuta ese código intermedio 91 Intérprete Interpretación del código intermedio El lenguaje simbólico es un lenguaje de bajo nivel El código intermedio (por ejemplo byte code) se guarda en un archivo F independiente de la plataforma y distribuible prescindiendo del código fuente El archivo F constituye una versión ejecutable por el intérprete La ejecución del programa es realizada por el intérprete, leyendo y decodificando cada una de las instrucciones del archivo F 92 Compilador en Intérprete Compilador JIT (Just-In-Time) El compilador JIT traduce código intermedio (byte code o CIL (Common Intermediate Language)) a código nativo (binario ejecutable), por lo cual es dependiente de la plataforma 1. El código intermedio se guarda en un archivo F independiente de la plataforma y distribuible prescindiendo del código fuente 2. La ejecución de F implica la compilación JIT de un método ante el envío del respectivo primer mensaje 93 Compilador en Intérprete 94 Intérprete Interprete meta-circular Intérprete de un lenguaje de programación L desarrollado en L Primero se crean unas pocas primitivas de L en otro lenguaje, por ejemplo en C, y luego se completa el desarrollo de L utilizando L L es independiente de la plataforma (sólo requiere el intérprete base en C para las primitivas usadas en su creación) Por ejemplo, PyPy para Python y Rubinius para Ruby 95 Compilador-Intérprete Diferencias Compilador Intérprete Sólo traduce Decodifica y ejecuta Traduce sólo una vez cada sentencia Puede procesar varias veces algunas e ignorar completamente otras instrucciones Acepta las instrucciones de acuerdo a su secuencialidad física Acepta las instrucciones según su secuencialidad lógica 96