OBJETIVO Y FILOSOFIA DE DISEÑO DE 
LENGUAJES DE PROGRAMACION 

 

 

 


El principal objetivo del lenguaje es, por supuesto, servir de apoyo didáctico en una materia de lenguajes de programación, intérpretes y compiladores. Derivado de la persecución de este objetivo surgen varias metas específicas y objetivos particulares:

En el diseño de Stop se ha tratado de seguir muchos de los principios usados en los modernos lenguajes de programación hasta el punto donde su implementación no sea demasiado complicada para el desarrollo de un proyecto semestral. Principalmente se ha buscado que sea regular, modular y estructurado.

FILOSOFÍA DE DISEÑO DEL LENGUAJE

El lenguaje de programación esta pensado para la programación evolutiva. Esta consiste en un método de programación basado en un ciclo de prueba y error donde se refina un programa hasta conseguir que haga lo que queremos. Esta forma de programar se aplica a problemas donde se desconoce que algoritmo nos llevará a la solución. Esta situación se da en investigación y en la creación de prototipos donde hay que realizar muchas pruebas hasta dar con la solución más apropiada. Para estos casos, es más apropiado el uso de un interprete que un compilador, ya que de esta forma se reduce el tiempo invertido en cada prueba.

Para que un lenguaje sea efectivo en programación evolutiva tiene que facilitar: la interacción, la modificación del programa y aportar instrucciones de alto nivel cercanas al problema. Estos tres punto se consiguen cuando el lenguaje tiene las siguientes características:

Estado de Interacción. Entre prueba y prueba es interesante guardar el estado de ejecución. De esta forma se evita repetir la ejecución de las instrucciones necesarias para llegar al estado de ejecución donde queremos realizar pruebas. Los programas implementa esta característica mediante un ámbito global dinámico que guarda funciones y variables mientras se utiliza el intérprete.

 

Sintaxis Cercana al Problema. Es más efectivo escribir en una notación cercana al problema que adaptarse a la sintaxis de un lenguaje de programación. De esta forma se evita el paso de traducción que tiene que realizar el programador antes de escribir una nueva sentencia del programa.

 

Abstracción. La semántica del lenguaje tiene que ser cercana a la semántica de la notación utilizada en el problema. Como no es cuestión de construir un lenguaje para cada problema, lo que se hace es aportar herramientas para acercar la semántica del lenguaje a la del problema mediante abstracción.

 

Integración. Para la mayoría de campos se encuentran librerías que implementan las operaciones más comunes. Entonces para que un lenguaje sea efectivo tiene que poder integrar estas librerías.

 

Fácil Escritura. En la programación estándar es más importante facilitar la lectura de programas que la escritura (se leen más veces que se escriben). En el caso de lenguajes interactivos es importante que la escritura de sentencias sea fácil.

 

Concisión. Las sentencias ha escribir tienen que ser cortas para agilizar la interacción. aporta generadores, listas por comprensión y una mínima redundancia para reducir el tamaño de los programas sin perder en claridad.

 

Modificación Local. La evolución de un programa se consigue por sucesivas modificaciones que se han de poder realizar rápidamente. Esto se consigue si las modificaciones del programa afectan al menor código posible. Esto supone que la modificación se realizará solo en un lugar del programa y no en dos como se da el C++ donde hay que modificar el fichero de implementación (.cpp) y el fichero de cabecera (.h).

 

 

DISEÑO DEL LENGUAJE

Hasta el momento, lo que se ha visto ha sido una serie de operaciones aritméticas y de manipulación de la pila. Todas éstas indicadas de manera implícita a través de una serie de términos y convenciones que es necesario definir de forma más precisa antes de continuar con otra cosa.

Existen dos formas en las que puede representarse una pila y su funcionamiento; de ésta dependerá la terminología que se emplee. Nosotros hemos venido usando una representación que conceptualiza a la pila como un arreglo que "crece" o es utilizado desde su base (el primer nivel) hacia arriba. Los datos entran y se toman de la base y desplazan o "empujan" a los elementos, que ya pudieran estar introducidos en la pila, hacia arriba. Identificaremos a los diversos elementos involucrados acorde al siguiente diagrama:

Niveles

 

...

^
|
Tope
|
v
Base

5

4

3

2

1

 

 

 

 

Objeto

 

 

^
|
Ingreso

 

Llamaremos nivel a cada una de las localidades con que cuente la pila y los enumeraremos a partir de 1. La base es el primer nivel. El tope de la pila lo identificaremos como el nivel en el que se encuentre el elemento con ingreso más antiguo. Representaremos con una elipsis (...) el resto de las localidades o elementos en la pila. Por último, mientras que nos hemos limitado a usar números en la representación de elementos que pueden ser introducidos en la pila, no estamos restringidos a esto. Dependiendo de su implementación una pila puede albergar más que números. De forma genérica nos referiremos a estos elementos como objetos.

Los diagramas que se han usado para ilustrar el contenido de la pila antes y después de la aplicación de una instrucción (que aparece como una operación, función, operador o nombre en el código del programa) serán identificados como diagramas de pila. En estos diagramas la elipsis se incluirá sólo cuando sea necesario recalcar la existencia del resto de la pila o su contenido; mientras no se indique lo contrario, siempre debe considerarse a la pila de Stop como infinita y factible de tener un contenido.

Adicionalmente, en la presente descripción:

Las palabras clave de Stop se escriben en mayúsculas, aunque el lenguaje no es sensible a altas o bajas (lo que en otros ambientes es lo que se denomina case insensitive). Palabras clave de Stop se escriben usando un font no proporcional.

·        Elementos a substituir por otro valor se ilustran en itálicas.

·        Conceptos y acciones a resaltar se subrayan.

·        En las descripciones sintácticas, elementos repetitivos se denotan  por el seguimiento de una elipsis.

·        Salidas en pantalla se muestran en negritas.

 

 

COMUNICACIÓN HUMANA

 

Las teorías de la comunicación representan un punto de partida indispensable no sólo para el estudio y la investigación de la comunicación, sino para el quehacer profesional práctico. El curso discute las aportaciones conceptuales de las perspectivas teóricas más recientes para el análisis de la comunicación masiva contemporánea.

 

Comunicación interpersonal e intercultural, así como las habilidades interactivas necesarias para gerentes.

  Análisis de las capacidades de transmisión de información de fibras ópticas, tomando en cuenta los sistemas transmisores, los sistemas receptores y los requerimientos de acoplamiento óptico. Comportamiento de ondas electromagnéticas en el interior de las fibras ópticas. Receptores óptimos, transmisión coherente, amplificación óptica, multicanalización por división de longitud de onda, redes ópticas, SONET, ATM.

 

La computadora, a diferencia de otras herramientas que en general apoyan el esfuerzo físico de los humanos, fue inventada para facilitar el trabajo intelectual. Si el hombre tiene algún problema, por ejemplo "sumar dos y dos", el diseñador define el algoritmo que resuelve el problema, el programador lo codifica en un lenguaje de programación, el cual la computadora es capaz de "entender", luego la computadora ejecuta el algorítmo expresado como programa en el lenguaje de programación en cuestión, y listo. La máquina le entrega al hombre la respuesta "4", sin que éste tuviera que esforzar sus neuronas.

 

Un programa se escribe una vez, pero se lee muchas durante su depuración, documentación y mantenimiento.

Tendencia actual a separar la interfaz de la implementación de un módulo.

Reducir las manipulaciones implícitas.

Coerciones (coerciones de PL/I o C).

ON de BASIC para eventos o excepciones.

Constructores y destructores de C++ (necesarios, pero complican el seguimiento del flujo de ejecución).

 

un conjunto de instrucciones de la máquina

facilitar la compilación (forth).

Evitar incluso la posibilidad de escribirlas

Reducir el conocimiento contextual.

El programador no funciona con una pila como el programa compilado.

 

 

PREVENCIÓN Y DETECCION DE ERRORES

 

Tener una serie de defensas tal que si un error no es detectado por uno, este probablemente sea detectado por otro.

Los errores deben ser detectados  por el compilador, si un mecanismo no es capaz de detectar un error es necesario implementar otro que lo detecte, pero nunca ignorarlo.

 

A continuación se presentan prevencion y tolerancia de errores y fallos

Prevencion de errores

Ejecutar datos -> control de flujo limitado

Errores en el uso de datos -> Tipado fuerte

Apuntadores erróneos -> Gestión de memoria implícita (LISP, PROLOG, ML, etc).

Hay que facilitar su detección, identificación y corrección. Tener que declarar antes de utilizar. Evitar coerciones inductoras de errores.

 

Prevención y tolerancia de fallos

 

 

Prevención de fallos: Se trata de evitar que se introduzcan fallos en el sistema antes de que entre en funcionamiento

 

      Prevención de fallos

Se realiza en dos etapas:

 

        Se trata de impedir que se introduzcan fallos durante la construcción del sistema

 

        Consiste en encontrar y eliminar los fallos que se producen en el sistema una vez construido

 

Tolerancia de fallos: Se trata de conseguir que el sistema continúe funcionando aunque se                                                                    produzcan fallos        

 

En ambos casos el objetivo es desarrollar sistemas con modos de fallo bien definidos.

 

Detección de errores

         hardware (p.ej.. instrucción ilegal)

ºnúcleo o sistema operativo (p.ej. puntero nulo)

 

Duplicación (redundancia con dos versiones)

Comprobaciones de tiempo

Inversión de funciones

Códigos detectores de error

Validación de estado

Validación estructural

 

EFICIENCIA DE LOS LENGUAJES DE PROGRAMACION

 

Compilación rápida del código fuente y ejecución rápida del código objeto.

 

Los factores fundamentales en la calidad del software son: la eficiencia, la portabilidad, la  verificabilidad, la integridad, la facilidad de uso, la exactitud, la robustez, la extensibilidad, la compatibilidad y la reutilización. En términos generales, estos factores pueden describirse de la siguiente forma: 

 

La eficiencia: capacidad para el aprovechamiento óptimo de los recursos que emplea.

Los lenguajes OOP arrastraron en un principio la reputación de ser ineficaces. Esto se debía en gran medida a que los primeros lenguajes (como Smalltalk) eran interpretados y no compilados. La existencia de compiladores permite a los desarrolladores ganar rapidez. Actualmente, usando un buen lenguaje orientado a objetos como C++, Java, etc. Junto con las librerías apropiadas para la realización de un programa, puede que se ejecute más rápidamente que el mismo programa compilado con un lenguaje procedural

La portabilidad: facilidad para ser ejecutados en distintos entornos lógicos o físicos .

La verificabilidad: capacidad para soportar procedimientos de pruebas, test o ensayos.

La integridad: nivel de protección frente a procesos que traten de alterarlo. 

La facilidad de uso: comodidad y claridad en la interacción con el usuario. 

La exactitud: nivel de precisión que alcanzan los resultados obtenidos.

La robustez: capacidad para funcionar correctamente en situaciones extremas.

La extensibilidad: capacidad para adaptar su funcionamiento al incremento en sus objetivos.

La compatibilidad: facilidad de poder ser aplicados en conjunción con otros programas.

La reutilización: posibilidad de utilizarlos (total o parcialmente) en nuevos contextos.

 

INDEPENDENCIA DE LA MÁQUINA

 

Independencia de la máquina: Puesto que diferentes usuarios utilizan diferentes ordenadores, el sistema debe ser accesible por todos ellos sin merma de prestaciones, especialmente por las plataformas mayoritarias: Windows, MacOS y Unix.

Los programas Windows son independientes de la máquina en la que se ejecutan (o al menos deberían serlo), el acceso a los dispositivos físicos se hace a través de interfaces, y nunca se accede directamente a ellos. Esta es una de las principales ventajas para el programador, ya que no hay que preocuparse por el modelo de tarjeta gráfica o de impresora, la aplicación funcionará con todas, y será el sistema operativo el que se encargue de que así sea.

A la hora de explotar un gran número de bases de datos de diferentes editores nos encontramos ante un doble problema. Por una parte, la citada falta de homogeneidad de los sistemas informáticos de los usuarios; por otra parte, cada una de las bases de datos suele tener su propio programa de consulta, de modo que nos encontramos multitud de programas diferentes que deberán conocer los usuarios. Dichos programas están en su mayor parte diseñados para ordenadores tipo PC con sistema operativo Windows. Teniendo en cuenta todo lo anterior, podemos ver que el sistema ha de permitir acceder a multitud de máquinas diferentes a una serie de programas en muchos casos incompatibles con ellas.

Los servidores de aplicaciones son la base de programas informáticos diseñados para ser ejecutados desde ordenadores personales a través de Navegadores de Internet convencionales.
Con ello se consigue independencia de la máquina (los programas funcionan en cualquier ordenador), independencia de ubicación (es posible utilizar los programas desde cualquier lugar) y una administración ligera y centralizada (mantenimiento cero de los programas de los ordenadores de los usuarios al residir éstos en el servidor).

SIMPLICIDAD

 

Un lenguaje debe ser tan simple como sea posible. Debe haber un número mínimo de conceptos con reglas simples para su combinación. Un lenguaje de programación debe esforzarse  en la simplicidad sintáctica y semántica. Simplicidad en la semántica implica que el lenguaje contiene un mínimo número de conceptos y estructuras. Estos conceptos deben ser naturales, rápidamente aprendidos, y fácilmente entendidos. with little danger of misinterpretation.

 

        

La simplicidad requiere que un idioma incorpore tan pocos conceptos como sean posibles. El lenguaje debe ser una ayuda para el programador antes de que alcance el estado real de codificación en programación. Debe darle un conjunto de conceptos claro, simple y unificado para que pueda usarlos como primarios en el desarrollo de lenguajes. Para ello es deseable tener un número mínimo de conceptos diferentes, con las reglas de su combinación lo más simples y regulares posibles. Esta claridad semántica y de conceptos es el factor determinante del valor de un lenguaje.

 

La simplicidad sintáctica requiere que la sintaxis represente cada concepto en una y una única forma y que ésta interpretación es tan legible como sea posible.  Esto no necesariamente implica que la sintaxis es tan concisa como sea posible, desde que la concisión es a menudo contraproducente a la legibilidad. Excluye múltiples representaciones de la misma semántica conceptual y representaciones sintácticas que son fácilmente confusas.

 

UNIFORMIDAD

Ya que la representación de los objetos lleva implica tanto el análisis como el diseño y la codificación de los mismos.

 

 

La estructura lógica de la BD definida mediante el LDD debe ser uniforme y acorde al modelo de datos del SGBD, para facilitar la manipulación de esta estructura.

En el caso específico del LDD, el lenguaje del SGBD debe ser capaz de definir la estructura lógica de la BD, sin entrar en detalles de implementación ni mecanismos en que se accede a los datos de la BD.

 

La forma idónea de realizar lo anterior es mediante un lenguaje declarativo, el cual permite declarar la estructura del modelo de acuerdo al modelo de datos que utiliza el SGBD.

 

Para el caso del LMD, el lenguaje del SGBD debe incluir formas de especificar qué se desea hacer con los datos (insertar, recuperar, modificar o borrar datos), sin entrar en detalles acerca de cómo se realizan estas operaciones.

Igual que en el caso anterior, la mejor manera de realizar esto es mediante un lenguaje declarativo que permita especificar la estructura de la operación a realizar, de acuerdo siempre con el modelo de datos utilizado por el SGBD.

 

Generalización y especialización

        La generalización dice que algo similar también es correcto, pero es difícil de implementar.

        Hay que especializar para facilitar la implementación sin perder la utilidad del lenguaje.

 

 

 
 
DISEÑO DETALLADO

 
 
 

 


(Microestructuras, estructuras de expresión, estructura de datos, estructuras  de control,  estructuras  de  compilador  y  estructuras  de  E/S.)

 

El diseño detallado tiene que ver con la especificación de detalles algorítmicos, representaciones concretas de datos, interconexiones entre funciones y estructuras de datos, y empaque del producto de programación. El diseño detallado está fuertemente influenciado por el lenguaje de instrumentación, pero no es lo mismo que la instrumentación; el diseño detallado tiene que ver más con aspectos semánticos y menos con detalles sintácticos que es la instrumentación.
     El punto de inicio para el diseño detallado es una estructura arquitectónica a la que se le van a proporcionar los detalles algorítmicos y las representaciones concretas de datos. Mientras que hay una fuerte tentación para proceder directamente de la estructura arquitectónica a la instrumentación, hay varias ventajas que pueden lograrse en el nivel intermedio de detalle proporcionado por el diseño detallado. La instrumentación comunica los aspectos de la sintaxis del lenguaje de programación, el estilo de codificación la documentación interna, y la inserción de pruebas y depuraciones al código. Las dificultades que se encuentran durante la instrumentación casi siempre se deben al hecho de que el instrumentador simultáneamente está realizando análisis, diseño y actividades de codificación mientras intenta expresar el resultado final en un lenguaje de instrumentación. El diseño detallado permite el diseño de algoritmos y representaciones de datos en un nivel más alto de abstracción y notación que el que proporciona el lenguaje de instrumentación .     El diseño detallado separa la actividad de diseño a bajo nivel de la instrumentación, igual que las actividades de análisis y diseño aíslan las consideraciones de lo que se desea de la estructura que logrará los resultados deseados. Una especificación adecuada de diseño detallado minimiza el número de sorpresas durante la instrumentación del producto.
   Las actividades de diseño detallado inevitablemente exponen los defectos en la estructura arquitectónica y las modificaciones resultantes se verán facilitadas por tener menos detalles por manipular que los que estarían presentes en el lenguaje de instrumentación. El diseño detallado también proporciona un vehículo para inspecciones de diseño, recorridos estructurados y la revisión crítica del diseño. Las notaciones para el diseño detallado incluyen a los diagramas HIPO, el seudocódigo, el inglés estructurado, los diagramas de flujo estructurados, los diagramas de estructuras de datos, y las distribuciones físicas para las representaciones de datos. La representación del diseño detallado puede utilizar palabras clave del lenguaje de instrumentación para especificar el flujo de control, y proposiciones de declaración del lenguaje para especificar la representación de datos. El empaque tiene que ver con la manera en que los datos elementales globales son compartidos selectivamente entre las unidades del programa, la especificación de áreas de datos estáticos, el agrupamiento de unidades del programa como funciones y subrutinas, la especificación de los mecanismos para el paso de parámetros, las estructuras de archivos y las técnicas para su acceso, y la estructura de las unidades de compilación y módulos de carga. El diseño detallado debe llevarse hasta un nivel donde cada proposición en la notación del diseño resulte en unas cuantas (menos de 10) proposiciones en el lenguaje de instrumentación. Dadas las especificaciones arquitectónicas y de diseño detallado, cualquier programador familiar con el lenguaje de instrumentación debe ser capaz de implantar el producto de la programación.

 

ESTRUCTURAS DE DATOS

 

Las Estructuras de Datos se pueden definir como la organización de la información que permite un determinado lenguaje de programación. Cada estructura posee sus propias características de almacenamiento y recuperación de los datos.
Los Algoritmos constituyen la resolución de problemas computacionales mediante un lenguaje de programación.

·         Tipos por valor: Son aquellos tipos que contienen los datos, el valor en si. Se almacenan directamente en el disco duro de la computadora y cuando trabajamos con ellos, trabajamos directamente con el valor. No requiere de memoria adicional aparte de la estrictamente necesaria para almacenar el valor. Estos tipos son implementados por el runtime y aumentan considerablemente la velocidad.

·         Tipos por referencia: Son aquellos que hacen referencia a una posición de memoria, están guardados en la pila. Son más lentos que los tipos por valor y ocupan algo más de memoria, a cambio obtienen varias ventajas como por ejemplo que pueden contener métodos, polimorfismo…

Las estructuras de datos que se manejan en el modelo relacional corresponden a los conceptos de relación, entidad, atributo y dominio, los cuales de introducen aquí intencionalmente:

 

 Relación.

Por una relación se entiende una colección o grupo de objetos que tienen en común un conjunto de características o atributos.

 

Entidad.

Es una unidad de datos en una relación con un conjunto finito de atributos. Es también conocido como n-ada, a raíz de que consiste de n-valores, uno por cada atributo.

 

 

 

Atributo.

También llamado característica, cada atributo de una relación tiene asociado un dominio en el cual toma sus valores.

 

 

Dominio.

Es un conjunto de valores que puede tomar un atributo en una relación.

La notación más usual para denotar las relaciones en términos de estos conceptos es:

 

5#5

por ejemplo

 6#6

Y para establecer la conexión entre un atributo y un dominio podemos usar la siguiente notación:

 7#7

por ejemplo

 8#8

 

Una forma de implementar las relaciones en una computadora, es a través de tablas de valores, de forma que se tienen las siguientes equivalencias: un atributo corresponde al encabezado de una columna, una n-ada equivale a un renglón de la tabla y por supuesto una relación equivale a la tabla misma. En capítulos posteriores, suponiendo natural esta equivalencia de términos, se utilizarán de forma indistinta.

 

ESTRUCTURAS DE CONTROL

El desarrollo de un programa viene determinado por el orden en que aparecen las instrucciones. El lenguaje Perl posee controlar un conjunto de instrucciones que permiten controlar el desarrollo de un programa. Estas instrucciones se denominan estructuras de control porque permiten ejecutar un conjunto de instrucciones cuando se verifica una condición o ejecutar iterativamente un bloque de instrucciones mientras una expresión sea válida.

Estructura secuencial

Sentencias simples

Expresión de algún tipo terminada por el carácter ‘;’

i++;

s = v * t;

;

Sentencias compuestas o bloques

Conjunto de declaraciones y sentencias entre llaves {}

{

<declaración>;

...

<sentencia>;

...

}

 

ESTRUCTURAS CONDICIONALES

 

Operador condicional

expresión1 ? expresión2 : expresión3;

 

Sentencia if

 

if (expresión) {

sentencia;

}

if (expresión) {

sentencia1;

} else {

sentencia2;

}

if (expresión1)

sentencia1;

else if (expresion2)

sentencia2;

else if (...)

...

else

sentenciaN;

Sentencia switch

 

switch (expresión) {

case expr_cte1:

sentencia1;

case expr_cte2:

sentencia2;

...

case expr_cteN:

sentenciaN;

default:

sentencia;

}

Estructuras iterativas / repetitivas

Sentencia while

 

while (expr) {

sentencia;

}

Sentencia for

 

for (expr1; expr2; expr3) {

sentencia;

}

Equivale a: expr1;

while (expr2) {

sentencia;

expr3;

}

Sentencia do … while

 

do {

sentencia;

} while (expresión);

Saltos

break Interrumpe la ejecución del bucle

continue Comienza la siguiente iteración del bucle

goto Salto incondicional

return Finaliza la ejecución de una función

(suele utilizarse para devolver un valor)

exit Finaliza la ejecución del programa

(función de la biblioteca estándar)

 

  La instrucción last.

 

La instrucción last interrumpe la ejecución del bucle actual y se ejecuta la instrucción que sigue al bloque. El ejemplo siguiente permite interrumpir el bucle while cuando la variable i toma el valor 3.

$i = 0;
while($i < 6) {
   if($i == 3) {
     last;
   }
   $i++;
}
print "el valor de \$i es $i";

Cuando la instrucción tiene como argumento una etiqueta, la ejecución prosigue en la línea indicada por la etiqueta.

 

 

 La instrucción next.

 

La instrucción next es idéntica a la instrucción continue en C. Interrumpe la ejecución del bloque de instrucción actual y prosigue la ejecución en la iteración siguente. Esta instrucción no interrumpe completamente la ejecución del bucle; la expresión que controla el bucle se evalúa. Si el resultado de la expresión es válido, el bucle se ejecuta de nuevo.

Cuando una instrucción tiene como argumento una etiqueta, la instrucción prosigue en la línea identificada por la etiqueta y no al principio del bloque.

Seguidamente veremos un ejemplo de dicha instrucción:

print "Teclea \"x\" para salir:\n";
print "Si se pulsa la tecla \"s\" no se imprime:\n";
$ristra = "";
while ($ristra ne "x") {
   $ristra = ; chop($ristra);
   if ($ristra eq "s") {
      next;
   }
   print "Has escrito $ristra\n";
}
print "Salida.\n" 

 La instrucción until.

 

La instrucción until al igual que la instrucción while permite ejecutar un conjunto de instrucciones un número repetido de veces. Pero al contrario que la la instrucción while, la intrucción until ejecuta dicho bloque de instrucciones mientras no se verifique la comprobación. La sintaxis es:

until (expresión) {
   instrucción o bloque de instrucciones;
}

He aquí el ejemplo anterior pero utilizando la instrucción until.

print "Teclea \"x\" para salir:\n";
print "Si se pulsa la tecla \"s\" no se imprime:\n";
$ristra = "";
until ($ristra eq "x") {
   $ristra = ; chop($ristra);
   if ($ristra eq "s") {
      next;
   }
   print "Has escrito $ristra\n";
}
print "Salida.\n"

 

La instrucción unless.

 

Esta instrucción es análoga al if, salvo que permite considerar la no verificación de la prueba. Su sintaxis es la siguiente:

unless (expresión) {
   instrucción o bloque de intrucciones 1;
}

Para ver mejor el funcionamiento del unless, modificaremos el ejemplo anterior para adaptarlo a dicha instrucción.

print "Teclea \"x\" para salir:\n";
print "Si se pulsa la tecla \"s\" no se imprime:\n";
$ristra = "";
until ($ristra eq "x") {
   $ristra = ; chop($ristra);
   unless ($ristra eq "s") {
      next;
   }
   print "Has escrito $ristra\n";
}
print "Salida.\n"

 

ESTRUCTURA DE UN COMPILADOR

 

Cualquier compilador debe realizar dos tareas principales: análisis del programa a compilar y síntesis de un programa en lenguaje maquina que, cuando se ejecute, realizara correctamente las actividades descritas en el programa fuente.

Para el estudio de un compilador, es necesario dividir su trabajo en fases. Cada fase representa una transformación al código fuente para obtener el código objeto. La siguiente figura representa los componentes en que se divide un compilador. Las tres primeras fases realizan la tarea de análisis, y las demás la síntesis.

   

En cada una de las fases se utiliza un administrador de la tabla de símbolos y un manejador de errores.

Análisis Léxico.

En la fase de análisis léxico se leen los caracteres del programa fuente y se agrupan en cadenas que representan los componentes léxicos. Cada componente léxico es una secuencia lógicamente coherente de caracteres relativa a un identificador, una palabra reservada, un operador o un carácter de puntuación.

A la secuencia de caracteres que representa un componente léxico se le llama lexema (o con su nombre en inglés token). En el caso de los identificadores creados por el programador no solo se genera un componente léxico, sino que se genera otro lexema en la tabla de símbolos.

Análisis Sintáctico.

En esta fase, los componentes léxicos se agrupan en frases gramaticales que el compilador utiliza para sintetizar la salida.

 

Análisis Semántico.

La fase de análisis semántico se intenta detectar instrucciones que tengan la estructura sintáctica correcta, pero que no tengan significado para la operación implicada.

 

Generación de código Intermedio.

Algunos compiladores generan una representación intermedia explícita del programa fuente, una vez que se han realizado las fases de análisis. Se puede considerar esta operación intermedia como un subprograma para una máquina abstracta. Esta representación intermedia debe tener dos propiedades importantes: debe ser fácil de producir y fácil de traducir al programa objeto.

Optimización de Código.

En esta fase se trata de mejorar el código intermedio, de modo que resulte un código de máquina más rápido de ejecutar.

Generación de Código.

Esta constituye la fase final de un compilador. En ella se genera el código objeto que por lo general consiste en código en lenguaje máquina (código relocalizable) o código en lenguaje ensamblador.

 

 

 

Administrador de la tabla de símbolos.

Una tabla de símbolos es una estructura de datos que contiene un registro por cada identificador. El registro incluye los campos para los atributos del identificador.

El administrador de la tabla de símbolos se encarga de manejar los accesos a la tabla de símbolos, en cada una de las etapas de compilación de un programa.

Manejador de errores.

En cada fase del proceso de compilación es posibles encontrar errores. Es conveniente que el tratamiento de los errores se haga de manera centralizada a través de un manejador de errores. De esta forma podrán controlarse más eficientemente los errores encontrados en cada una de las fases de la compilación de un programa.

 

 

ESTRUCTURAS DE ENTRADAS Y SALIDAS

 

Diseño de salida. El diseño de un sistema de información basado en computadora es diseñar la salida o resultado que producirá el sistema. Se evoca a la selección de contenido forma y medio para los informes y el resultado que generará el sistema.


*informes

*contenido

*forma

*medio

*formato

*realce


 

2. Diseño de entrada. Se seleccionan los registros de entrada y los métodos de tal manera que conozcamos cuales son los datos que se van a proporcionar cada vez que corra una aplicación en la computadora.

*registros

*medio

*modo

*volumen

 

3. Diseño de procesamiento. Se especifica él computo, manejo de datos y la lógica necesarios para producir el resultado.

*cálculos

*lógica

*frecuencia

*volumen

4. Especificación de datos. Se especifican los datos algunos se marcarán para que se almacenen en los archivos maestros, y otros datos que serán de entrada cada vez que se corra una aplicación.

*contenido del registro.

*diseño del registro

*especificación de los archivos.

*organización de los archivos.

*volumen

5. Especificación de procedimientos. Se desarrollan los programas y el software de computadora así como los archivos y la elaboración de bases de datos. 3

*corridas de computadora

*documentar el proceso

*métodos de control

*procesos manuales

*procedimientos operativos. 3

Tiene 5 etapas fundamentales.

Especificación de procedimientos es donde vamos a recopilar toda nuestra información, identificar el o los problemas es necesario tomar en cuenta la factibilidad de nuestro diseño.

Especificación de datos. aquí es donde tenemos que tomar en cuenta los datos que vamos a utilizar de que tipo son, se diseñara el registro, los archivos.

Diseño de procesamiento. Una vez que ya sabemos los datos que habrán que utilizarse se tendrá que saber la frecuencia de estos datos y en donde se utilizarán, que cálculos habrá de hacerse para que funcione nuestro sistema para poder elegir un lenguaje de programación adecuado para que de el resultado requerido.

Diseño de entrad. Una vez que se sabe que lenguaje se utilizara entonces empezamos a programar cuidando que los datos e intrusiones den como resultado en la pantalla del usuario la información que este desea.

Diseño de salida. Es el resultado final, se realizan las pruebas para corroborar que nuestro sistema funcione adecuadamente para poderlo implantar.