Anda di halaman 1dari 309

UNIVERSIDAD CENTROAMERICANA

JOS SIMEN CAAS








REVISIN DE LENGUAJE PARA LA EJECUCIN DE
ALGORITMOS EN PSEUDO-CDIGO Y CONSTRUCCIN
DE SU COMPILADOR

TRABAJO DE GRADUACIN PREPARADO PARA LA
FACULTAD DE INGENIERA Y ARQUITECTURA


PARA OPTAR AL GRADO DE
LICENCIADO EN CIENCIAS DE LA COMPUTACIN

POR:
BAYRON DANIEL MENESSES RENDEROS
HERBERT IVN AMAYA LVAREZ
JOS ENMANUEL AMAYA ARAUJO


OCTUBRE 2010
ANTIGUO CUSCATLN, EL SALVADOR C.A.
RECTOR
JOS MARA TOJEIRA, S.J.


SECRETARIO GENERAL
REN ALBERTO ZELAYA



DECANO DE LA FACULTAD DE INGENIERA Y ARQUITECTURA
EMILIO JAVIER MORALES QUINTANILLA



COORDINADOR DE LA CARRERA DE LICENCIATURA EN
CIENCIAS DE LA COMPUTACIN
GUILLERMO ERNESTO CORTS VILLEDA



DIRECTOR DEL TRABAJO
GUILLERMO ERNESTO CORTS VILLEDA



LECTOR
ROBERTO ALFONSO ABARCA JUREZ

i
RESUMEN EJECUTIVO

En el ao 2003, en la Universidad Centroamericana Jos Simen Caas, surgi la
iniciativa de construir una herramienta que facilitara el aprendizaje de los principios de la
programacin en los estudiantes de primer ao de la carrera Licenciatura en Ciencias de la
Computacin.

Se defini que dicha herramienta de aprendizaje consistiera en un lenguaje de
programacin sencillo, basado en los principios del pseudo-cdigo y totalmente en
castellano, junto a un entorno de desarrollo que proporcionara herramientas para la
creacin, compilacin y ejecucin de programas escritos en este lenguaje
fundamentalmente pedaggico.

Comenzando en el ao 2003, fueron realizados cuatro intentos de desarrollo de esta
herramienta de software, lastimosamente en ninguna de las cuatro ocasiones fue posible
lograr una adecuada estabilizacin del lenguaje y de su entorno de desarrollo. Este
problema es atribuido a diversidad de factores: debilidades del lenguaje, inestabilidad de la
interfaz grfica, dificultad de mantenimiento del cdigo fuente del compilador de la
aplicacin, entre otros.

El primer intento fue conocido por el nombre de APRENDE v1.0 (Algoritmos en Pseudo-
cdigo Runtime Environment y Desarrollador), nombre que le fue asignado al entorno de
desarrollo de la aplicacin. Esta versin fue construida utilizando metacompiladores y
present inconsistencias entre la definicin establecida del lenguaje y el comportamiento de
los procesos de compilacin.

APRENDE v2.0 fue un intento de correccin de la primera versin, mientras que
APRENDE v3.0 fue un intento de reconstruccin de la totalidad del proyecto, con el
objetivo de eliminar los problemas encontrados. Sin embargo, aunque la mayora de los
problemas existentes hasta ese momento fueron solucionados, surgieron nuevos problemas
de la misma ndole que imposibilitaban una correcta estabilizacin.
ii
El ltimo intento conocido, siempre bajo una estrategia de metacompilacin, fue ORION
v1.0, el cual consisti en un intento de correccin de la tercera versin de APRENDE. La
interfaz grfica del entorno de desarrollo fue mejorada considerablemente y fueron
aadidas diversas funcionalidades al lenguaje. Pero, a pesar de estos esfuerzos, se
obtuvieron los mismos resultados que sus antecesores: inconsistencias en el
comportamiento del compilador que evitaban estabilizar el lenguaje y su entorno de
desarrollo.

En consecuencia, en el ao 2010 se toma la decisin de implementar una vez ms esta
herramienta didctica desde una nueva perspectiva: un enfoque de diseo del lenguaje
fundamentalmente didctico y una construccin manual de su compilador que proporcione
control sobre el cdigo y facilite los procesos de mantenimiento.

El lenguaje de programacin fue reestructurado eliminando sentencias, funciones y tipos de
datos innecesarios en una etapa inicial del aprendizaje de la programacin. Adems, se
procur proporcionar a la sintaxis del lenguaje un carcter intuitivo, es decir, un aspecto
fcil de comprender y utilizar por alumnos que comienzan sus estudios de programacin.

Se modific la sintaxis del lenguaje con el objetivo de mejorar el carcter intuitivo antes
mencionado, as como tambin para incluir algunas funciones matemticas y de
manipulacin de cadenas y caracteres que permitan ampliar la gama de programas que
pueden ser escritos y proporcionar una mayor rea de prctica para los estudiantes.

Una vez definida la sintaxis resultante de todas las modificaciones que implic el proceso
de revisin y rediseo, se procedi, en primer lugar, a nombrar al lenguaje,
proporcionndole as independencia de cualquier tipo de entorno de desarrollo. El nombre
escogido fue AEGOLI.

En segundo lugar, se construy la gramtica formal que genera al lenguaje, de forma que se
le pudiera hacer una evaluacin cuyo objetivo principal era comprobar que la gramtica era
iii
LL1, dado que se buscaba construir un compilador que contara con un analizador sintctico
descendente determinstico, aspecto para el cual la condicin anterior es imprescindible.

Con tan solo unos pocos casos excepcionales y fcilmente resolubles donde la gramtica no
cumpla con ser LL1, se comenz el proceso de desarrollo de su compilador, el cual se
comenta a continuacin:

Se definieron por produccin de la gramtica que genera al lenguaje AEGOLI todas
las reglas semnticas, tanto las correspondientes a tiempo de compilacin como las
correspondientes a tiempo de ejecucin.

Se establecieron las expresiones regulares que definen el comportamiento y
funcionamiento del analizador lexicogrfico del compilador.

Se construy un analizador sintctico descendente dirigido por la sintaxis del
lenguaje.

Se realiz un proceso de tratamiento de los errores sintcticos y semnticos dentro
del compilador.

Se dise e implement la generacin de cdigo intermedio basado en la estructura
utilizada por el cdigo P, el cual es el cdigo intermedio utilizado en algunas
implementaciones antiguas del lenguaje de programacin PASCAL.

Se construy una mquina virtual capaz de ejecutar el cdigo intermedio generado
por el compilador y que le proporcione a la aplicacin caractersticas de portabilidad
y estabilidad.

Despus de realizar lo anterior, se obtiene un producto enteramente dedicado a servir como
apoyo de enseanza de la programacin, listo para ser sometido a procesos de prueba y
depuracin, y capaz de ser acoplado a un entorno grfico que facilitar a los estudiantes el
aprender a programar conociendo y utilizando el lenguaje AEGOLI.

NDICE


RESUMEN EJECUTIVO ...................................................................................................... i

NDICE DE TABLAS ........................................................................................................ viii

NDICE DE FIGURAS .......................................................................................................... x

SIGLAS .............................................................................................................................. xiv

SIMBOLOGA ..................................................................................................................... xv

PRLOGO ......................................................................................................................... xvii

CAPTULO 1: INTRODUCCIN ....................................................................................... 01

1.1 Definicin del problema .................................................................................... 01

CAPTULO 2: ANTECEDENTES ...................................................................................... 03

2.1 APRENDE v1.0 ................................................................................................ 03

2.2 APRENDE v2.0 ................................................................................................ 04

2.3 APRENDE v3.0 ................................................................................................ 05

2.4 ORION v1.0 ...................................................................................................... 07

CAPTULO 3: MARCO TERICO ..................................................................................... 09

3.1 Compiladores e Intrpretes ................................................................................ 09

3.1.1 Compiladores ....................................................................................... 09

3.1.2 Intrpretes ............................................................................................. 13

3.2 Estructura de un compilador .............................................................................. 16

3.2.1 El Anlisis Lexicogrfico ..................................................................... 18

3.2.2 El Anlisis Sintctico ........................................................................... 21

3.2.3 El Anlisis Semntico .......................................................................... 25

3.2.4 Tratamiento de los errores .................................................................... 27

3.2.5 Generacin de cdigo intermedio ........................................................ 32

3.3 La Mquina Virtual ........................................................................................... 37

CAPTULO 4: OBJETIVOS ................................................................................................ 41

4.1 Objetivo General ............................................................................................... 41

4.2 Objetivos Especficos ........................................................................................ 41

CAPTULO 5: PRODUCTOS ENTREGABLES ................................................................ 43

CAPTULO 6: ALCANCES Y LMITES ........................................................................... 45

6.1 Alcances ............................................................................................................ 45

6.2 Lmites ............................................................................................................... 50

CAPTULO 7: METODOLOGA Y HERRAMIENTAS ................................................... 51

7.1 Metodologa ....................................................................................................... 51

7.2 Herramientas ...................................................................................................... 54

CAPTULO 8: REVISIN DEL LENGUAJE PARA LA APLICACIN DE
ALGORITMOS EN PSEUDO-CDIGO. .................................................. 55

8.1 Lenguaje AEGOLI ............................................................................................ 55

8.2 Modificaciones al Lenguaje para la ejecucin de algoritmos
en pseudo-cdigo ............................................................................................... 55

8.3 Definicin de la gramtica libre de contexto que genera
al Lenguaje AEGOLI ........................................................................................ 65

8.4 Evaluacin de la gramtica libre de contexto que genera
al Lenguaje AEGOLI ........................................................................................ 68

8.5 Reglas semnticas por produccin para el Lenguaje AEGOLI ......................... 71

CAPTULO 9: DISEO DE COMPILADOR PARA EL LENGUAJE AEGOLI ............. 77

9.1 Analizador lexicogrfico. .................................................................................. 77

9.1.1 Estrategia de lectura del archivo fuente ............................................... 77

9.1.2 Expresiones regulares del lenguaje AEGOLI ...................................... 77

9.1.3 Estrategia de utilizacin de tokens ....................................................... 79

9.1.4 Cmo se obtienen los identificadores, nmeros,
cadenas y caracteres ............................................................................ 82

9.1.5 Clasificacin de operadores y smbolos especiales. ............................. 84

9.2 Analizador sintctico .......................................................................................... 84

9.2.1 Construccin de analizador sintctico descendente:
Aplicacin de reglas R y R. ................................................................ 84

9.2.2 Presentacin de los errores generados durante el
proceso de compilacin ........................................................................ 86

9.2.3 Definicin de la tabla de smbolos ....................................................... 87

9.2.4 Estrategia de manipulacin de la tabla de smbolos ............................. 91

9.3 Tratamiento de los errores .................................................................................. 95

9.3.1 Diagrama de Dependencias .................................................................. 95

9.3.2 Estrategias utilizadas para la estabilizacin de
errores sintcticos y semnticos. .......................................................... 96

9.4 Diseo del cdigo intermedio ............................................................................ 98

9.4.1 Mnemnicos ......................................................................................... 98

9.4.2 Estructura de una instruccin en cdigo intermedio ............................ 99

9.5 La mquina virtual ........................................................................................... 104

CAPTULO 10: CONCLUSIONES Y RECOMENDACIONES ...................................... 105

10.1 Conclusiones .................................................................................................... 105

10.2 Recomendaciones ............................................................................................ 107

GLOSARIO ........................................................................................................................ 109

BIBLIOGRAFA ................................................................................................................ 113

ANEXOS.

ANEXO A. Descripcin del Lenguaje AEGOLI.

ANEXO B. Definiciones y herramientas matemticas.

ANEXO C. Manual tcnico.

ANEXO D. Manual de usuario.

ANEXO E. Batera de pruebas.
ix
NDICE DE TABLAS


Tabla 1. Comparacin entre compilar e interpretar. ............................................................ 15

Tabla A-1. Tipos de dato existentes en AEGOLI. .......................................................... A-17

Tabla A-2. Operadores aritmticos. ................................................................................ A-17

Tabla A-3. Operadores relacionales. ............................................................................... A-18

Tabla A-4. Operadores Lgicos. ..................................................................................... A-18

Tabla A-5. Otros operadores y caracteres especiales. ..................................................... A-18

Tabla A-6. Funciones numricas. ................................................................................... A-19

Tabla A-7. Funciones para el manejo de datos de tipo cadena o carcter. ..................... A-20

Tabla A-8. Detalle de funciones para el manejo de datos de tipo cadena. ..................... A-21

Tabla A-9. Palabras reservadas. ...................................................................................... A-21

Tabla C-1. Campos de la tabla de smbolos. .................................................................... C-16

Tabla D-1. Operadores aritmticos. ................................................................................ D-11

Tabla D-2. Operadores relacionales. ................................................................................ D-12

Tabla D-3. Operadores Lgicos. ..................................................................................... D-12

Tabla D-4. Operador de asignacin. ............................................................................... D-13

Tabla D-5. Operador de concatenacin. ......................................................................... D-13

Tabla D-6. Tipos de datos existentes en AEGOLI. ......................................................... D-14

Tabla D-7. Funciones numricas. .................................................................................... D-27

Tabla D-8. Funciones de cadena. ..................................................................................... D-28

Tabla D-9. Descripcin de funciones de cadena. ............................................................. D-29

Tabla D-10. Lista de errores detectados por el scanner. .................................................. D-32

Tabla D-11. Lista de errores sintcticos. ......................................................................... D-32
x
Tabla D-12. Lista de errores semnticos. ......................................................................... D-34

Tabla D-13. Lista de errores detectados en tiempo de ejecucin. .................................... D-35

Tabla E-1. Equivalentes de la tabla ASCII extendida para escapar caracteres
del lenguaje castellano en salidas a consola. .................................................... E-3

Tabla E-2. Equivalentes de la tabla ASCII extendida para escapar
los caracteres y en salidas a consola. ................................................... E-14

Tabla E-3. Cambio de valores para LONGSTACK y MAXLONCAD. .......................... E-20


xi
NDICE DE FIGURAS


Figura 1. Compilacin. ........................................................................................................ 10

Figura 2. Sistema para procesamiento de un lenguaje. ........................................................ 11

Figura 3. Ejemplo de rbol sintctico. ................................................................................. 13

Figura 4. Fases de un compilador. ...................................................................................... 18

Figura 5. Interaccin entre el analizador lxico y el analizador sintctico. ......................... 19

Figura 6. Posicin del analizador sintctico en el compilador. ............................................ 22

Figura 7. Ejemplo de rbol de anlisis sintctico. ............................................................... 23

Figura 8. Esquema de construccin de analizadores sintcticos descendentes. .................. 24

Figura 9. Estrategia de generacin y ejecucin de cdigo intermedio. ............................... 34

Figura 10. Traduccin dirigida por la sintaxis. .................................................................... 35

Figura 11. Esquema general de un compilador usando una mquina virtual. ..................... 38

Figura 12. DFA para identificadores y palabras reservadas. ............................................... 82

Figura 13. DFA para nmeros enteros y reales. ................................................................... 82

Figura 14. DFA para cadenas. ............................................................................................. 83

Figura 15. DFA para caracteres. .......................................................................................... 83

Figura 16. Diagrama para la construccin de analizador sintctico descendente. ............... 84

Figura 17. Diagrama de sintaxis para la produccin Cuerpo. .......................................... 85

Figura 18. Diagrama de dependencias. ................................................................................. 95

Figura A-1. Diagrama de sintaxis de la estructura general de un algoritmo ..................... A-1

Figura A-2. Diagrama de sintaxis para la estructura interna de un algoritmo .................. A-2

Figura A-3. Diagrama de sintaxis para la declaracin de una variable ............................ A-2

Figura A-4. Diagrama de sintaxis que muestra los tipos
xii
existentes en el lenguaje AEGOLI. ............................................................... A-2

Figura A-5. Diagrama de sintaxis para estructura de un subalgoritmo
dentro de un programa. .................................................................................. A-3

Figura A-6. Diagrama de sintaxis para la firma de los subalgoritmos
dentro de un programa. .................................................................................. A-3

Figura A-7. Diagrama de sintaxis para los parmetros en las firmas o
encabezados de subalgoritmos. ..................................................................... A-3

Figura A-8. Diagrama de sintaxis que muestra la forma en que puede
utilizarse una variable dependiendo de si es un arreglo,
o matriz o variable sencilla. ........................................................................... A-4

Figura A-9. Diagrama de sintaxis para la estructura interna de un bloque
en el subalgoritmo principal y en los subalgoritmos externos. ..................... A-4

Figura A-10. Diagrama de sintaxis que muestra las diferentes instrucciones
que pueden utilizarse en un algoritmo. ........................................................ A-5

Figura A-11. Diagrama de sintaxis para las distintas instrucciones de entrada
y salida de datos. ......................................................................................... A-6

Figura A-12. Diagrama de sintaxis para la instruccin de llamada a un
subalgoritmo dentro de otro. ....................................................................... A-6

Figura A-13. Diagrama de sintaxis para la instruccin de asignacin de un
valor a una variable. .................................................................................... A-7

Figura A-14. Diagrama de sintaxis para la instruccin si. ................................................ A-7

Figura A-15. Diagrama de sintaxis para la instruccin hacer. .......................................... A-7

Figura A-16. Diagrama de sintaxis para la instruccin mientras. ..................................... A-8

Figura A-17 Diagrama de sintaxis para la instruccin repetir. .......................................... A-8

Figura A-18. Diagrama de sintaxis para la instruccin para. ............................................ A-8

Figura A-19. Diagrama de sintaxis para la instruccin leer. ............................................. A-9

Figura A-20. Diagrama de sintaxis para la instruccin escribir. ....................................... A-9

Figura A-21. Diagrama de sintaxis para la instruccin escribirln. .................................... A-9

Figura A-22. Diagrama de sintaxis para la instruccin abrirArchivo. ............................ A-10
xiii

Figura A-23. Diagrama de sintaxis para la instruccin leerArchivo. ............................. A-10

Figura A-24. Diagrama de sintaxis para la instruccin cerrarArchivo. .......................... A-10

Figura A-25. Diagrama de sintaxis que muestra las diferentes expresiones
que se puede utilizar. ................................................................................. A-11

Figura A-26. Diagrama de sintaxis para una expresin numrica. ................................. A-11

Figura A-27. Diagrama de sintaxis para una expresin de conjuncin. ......................... A-11

Figura A-28. Diagrama de sintaxis para una expresin relacional. ................................. A-12

Figura A-29. Diagrama de sintaxis para la estructura de una expresin aritmtica. ...... A-12

Figura A-30. Diagrama de sintaxis para la estructura de un trmino en una
expresin numrica. .................................................................................. A-12

Figura A-31. Diagrama de sintaxis que muestra los elementos que pueden
conformar un factor en una expresin numrica. ...................................... A-13

Figura A-32. Diagrama de sintaxis que muestra la estructura de las funciones
que devuelven una cadena trabajando con cadenas. ................................. A-13

Figura A-33. Diagrama de sintaxis que muestra la estructura de las funciones
que devuelven un valor numrico trabajando con
expresiones numricas. ............................................................................. A-14

Figura A-34. Diagrama de sintaxis que muestra la estructura de las funciones
que devuelven un valor numrico trabajando
con cadenas o con caracteres. ................................................................... A-15

Figura A-35. Diagrama de sintaxis para los datos de tipo caracter utilizados
como parmetro en subalgoritmos o como valores en expresiones. ......... A-15

Figura A-36. Diagrama de sintaxis para los datos de tipo cadena utilizados
como parmetro en subalgoritmos o como valores en expresiones. ......... A-16

Figura B-1. Ejemplo de diagrama de transicin de estados. .............................................. B-3

Figura C-1. Ejemplo de rbol de parsing para una expresin numrica. .......................... C-31

Figura C-2. Contenido de archivo XML externo para el reporte de errores. .................... C-65

Figura D-1. Instalacin de compilador y mquina virtual. ................................................ D-2

xiv
Figura D-2. Ubicacin de compilador.exe desde consola. ................................................. D-3

Figura D-3. Compilacin de un programa.......................................................................... D-3

Figura D-4. Ejemplo de archivo OB generado. .................................................................. D-4

Figura D-5. Compilacin de un programa con errores encontrados. ................................. D-4

Figura D-6. Compilacin de un programa utilizando el parmetro GUI. .......................... D-5

Figura D-7. Ejemplo de archivo XML externo para el reporte de errores. ........................ D-6

Figura D-8. Contenido de archivo XML externo para el reporte de errores. ..................... D-6

Figura D-9. Ejecucin de un programa. ............................................................................. D-7

Figura D-10. Error durante la ejecucin de un programa................................................... D-7

Figura D-11. Ejemplo de contenido para un archivo txt. ................................................. D-24

Figura E-1. Diagrama de sintaxis para una expresin condicional. ................................... E-7

Figura E-2. Diagrama de sintaxis para los miembros que conforman una
expresin condicional. ..................................................................................... E-8

Figura E-3. Propuesta de modificacin al diagrama de sintaxis para una
expresin condicional. ..................................................................................... E-8

Figura E-4. Diagrama de sintaxis para una expresin aritmtica. .................................... E-10

Figura E-5. Diagrama de sintaxis para una expresin numrica. ..................................... E-10

Figura E-6. Diagrama de sintaxis para una expresin de conjuncin. ............................. E-10

Figura E-7. Diagrama de sintaxis para una expresin relacional. .................................... E-11

Figura E-8. Diagrama de sintaxis para un factor. ............................................................. E-11

Figura E-9. Diagrama de Venn para el ejercicio de la sesin #4
de la batera de pruebas. ................................................................................ E-16

xv
SIGLAS

Significado
APRENDE Algoritmos en Pseudocdigo Runtime
Environment y DEsarrollador
CPU


Central Processing Unit (Unidad Central
de Procesamiento)
DFA Deterministic Finit Automata (Autmata
Finito Determnistico)
DS Diagrama de sintaxis
EBNF Extended Backus Naur Form (Forma
Extendida de Backus Naur)
LL1 La primera L indica anlisis sintctico de
izquierda a derecha, la segunda L indica
derivacin por la izquierda, y el nmero 1,
los smbolos de anticipacin
ORION platafOrma de apRendIzaje de
programacin
UCA Universidad Centroamericana Jos
Simen Caas
xvii
SIMBOLOGA

Diagramas de sintaxis.

1) Representacin grfica de un smbolo no terminal para una gramtica.
X

2) Representacin grfica de un smbolo terminal para una gramtica.
x

3) Representacin grfica de la concatenacin de simbolos (terminales y no terminales).
1
n 2
...


4) Representacin grfica de la existencia de alternativas.





5) Representacin grfica de la cerradura de Kleene.



Notacin EBNF utilizada.

1) A =B representa una produccin, donde el smbolo de = significa produce a.
La produccin A = B se lee A produce a B.

2) Un smbolo terminal es una secuencia de smbolos que se encuentra entre comillas.
As: A = terminal.

1
n
2
.
.
.
xviii
3) Un smbolo no terminal se representa como una secuencia de smbolos. De la
siguiente manera: A = NoTerminal.

4) El smbolo de barra vertical | se utiliza para indicar la existencia de alternativas.

5) La concatenacin de smbolos (terminales y no terminales) simplemente se
representa con un espacio en blanco entre ellos.

6) Los corchetes [ ] indican que es opcional lo que se encierra.

7) Las llaves { } se utilizan para representar la cerradura de Kleene.

8) El smbolo de terminacin es un punto al final de cada produccin.

9) Los parntesis ( ) se utilizan para realizar agrupaciones.

xix
PRLOGO

El presente documento expone el proceso de diseo de un lenguaje de programacin para la
ejecucin de algoritmos en pseudo-cdigo y el proceso de desarrollo y construccin de su
compilador. Todo esto entendido como una aplicacin informtica destinada a ser utilizada
a manera de herramienta didctica en la enseanza de la programacin a estudiantes que
comienzan sus estudios en la carrera de Licenciatura en Ciencias de la Computacin en la
Universidad Centroamericana Jos Simen Caas.

En el primer captulo se expone el contexto sobre el que se desarrolla el proyecto y se
explica la situacin problemtica que se propone solucionar, as como las razones por las
que se debe solucionar.

En el segundo captulo se presenta una breve resea de proyectos antecedentes al tratado a
lo largo del documento, explicando para cada uno de ellos los logros alcanzados y las
dificultades encontradas.

En el tercer captulo se profundiza en los aspectos tericos que se encuentran detrs del
diseo y construccin de compiladores, explicando su estructura, componentes principales,
mecanismos de interaccin, as como posibles estrategias para su elaboracin.

En el cuarto captulo se plantean los objetivos que se pretenden alcanzar con el desarrollo
del proyecto. Se expone brevemente el objetivo general del proyecto, seguido de los
objetivos especficos que lo complementan.

En el quinto captulo se comentan brevemente los productos entregables que sern el
resultado del proceso de desarrollo del proyecto.

En el sexto captulo se listan los alcances del proyecto, las fallas que se proponen
enmendar, las mejoras que se desean implementar y los requerimientos establecidos para el
xx
desarrollo del proyecto. Adems, se listan los lmites del proyecto, especificando lo que no
es tomado en cuenta para el proceso de desarrollo.

En el sptimo captulo se plantean las estrategias metodolgicas utilizadas durante la
totalidad del proceso de desarrollo del proyecto, clasificadas por etapa del proceso para
cada una de las partes de la aplicacin.

En el octavo captulo se explica el proceso de revisin del lenguaje para la ejecucin de
algoritmos en pseudo-cdigo, presentando las modificaciones efectuadas sobre su sintaxis y
semntica, la definicin de la gramtica formal que lo describe y la evaluacin matemtica
de las propiedades de sta ltima.

Por ltimo, en el noveno captulo se detallan los componentes del compilador construidos a
lo largo del desarrollo del proyecto. Para cada uno de ellos se exponen las tcnicas
utilizadas para su construccin, las estrategias escogidas para la implementacin y la
explicacin de sus elementos principales.


1
1
CAPTULO 1. INTRODUCCIN

1.1 Definicin del problema

Actualmente la Universidad Centroamericana Jos Simen Caas (UCA), dentro de su
facultad de Ingeniera y Arquitectura, cuenta con la carrera de Licenciatura en Ciencias de
la Computacin, la cual ofrece una formacin que permite a sus estudiantes evaluar un
conjunto de circunstancias relacionadas con un problema en particular, valorando sus
fortalezas y distinguiendo sus debilidades de manera que se pueda estructurar y poner en
prctica una solucin satisfactoria. Dicha solucin se encuentra fundamentada en el
desarrollo de aplicaciones de software que den tratamiento a los datos; desde su
adquisicin, almacenamiento y transformacin, hasta la generacin de informacin til.

Algunas de las reas de estudio ms importantes en las que se apoya la carrera se
encuentran enfocadas en los fundamentos de la computacin y el desarrollo de programas
computacionales. Estas reas de estudio comprenden asignaturas orientadas a la enseanza
del pensamiento abstracto y del razonamiento lgico-matemtico a sus estudiantes, las
cuales les permitan consolidar las bases sobre las que se fundamentar el conocimiento
terico necesario para el desarrollo de habilidades prcticas en procesos de programacin
en los mbitos acadmico, cientfico y comercial.

El curso de Fundamentos de Programacin adquiere una gran relevancia dentro de la
carrera, ya que tiene como objetivo que sus estudiantes sepan identificar y utilizar las
etapas del diseo de programas, conozcan y distingan los paradigmas de programacin y
adquieran habilidades bsicas para el diseo de programas de computadora. Una
caracterstica muy peculiar de este curso es que no trabaja con ningn lenguaje de
programacin, pero finaliza con el desarrollo de algoritmos en pseudo-cdigo.

Debido a que el pseudo-cdigo es solamente una descripcin de alto nivel de un algoritmo
que emplea una mezcla de lenguaje natural con algunas convenciones sintcticas propias de
los lenguajes de programacin, ste no cumple con los requerimientos necesarios para que
2
2
pueda ser llamado un lenguaje de programacin formal. Es por ello que, a pesar de que
facilita el entendimiento de algoritmos a principiantes en la programacin, se vuelve muy
difcil encontrar herramientas de desarrollo capaces de soportar este sistema de
programacin en pseudo-cdigo. Dicha limitacin de herramientas de desarrollo para
aplicaciones en pseudo-cdigo evita que la enseanza de la programacin pueda hacerse de
manera ms sencilla y eficaz, por lo que la UCA propuso como trabajo de graduacin, en el
ao 2003, la creacin de un entorno de desarrollo que solventara esta necesidad
educacional. El trabajo de graduacin gener como resultado una plataforma de
Algoritmos en Pseudo-cdigo Runtime Environment y Desarrollador conocido por el
acrnimo de APRENDE, que proporciona un entorno para la experimentacin, creacin,
diseo y ejecucin de algoritmos mediante el uso de pseudo-cdigo. APRENDE se utiliz
como herramienta didctica en la materia de Fundamentos de Programacin en el ciclo
02/2004 y 03/2004, sin embargo la aplicacin present ciertas deficiencias que impedan
que siguiera siendo utilizada para la enseanza. Trabajos de graduacin posteriores
retomaron la plataforma con el objetivo de corregir todas las deficiencias encontradas y
aadir nuevas funcionalidades a la plataforma, pero ninguna tuvo el xito que se esperaba.

Desde la creacin de APRENDE versin 1.0, este proyecto ha sido retomado como trabajo
de graduacin en cuatro ocasiones distintas, sin embargo, todas han seguido una
metodologa de desarrollo muy similar y es por ello que algunos errores an persisten, por
lo que no se ha podido crear una aplicacin estable y funcional que solvente las necesidades
educacionales de la materia de Fundamentos de Programacin.

Por lo anterior, es imprescindible crear un nuevo entorno de desarrollo que emplee nuevas
tcnicas de construccin, distintas a las implementadas en proyectos anteriores, y que
presente una mayor portabilidad y estabilidad; adems, es necesario que estas
caractersticas le permitan ser utilizado como herramienta didctica no solo en niveles
bsicos de la carrera, como en la materia de Fundamentos de Programacin, sino que pueda
trascender incluso en la enseanza del curso de Compiladores, perteneciente tambin a la
carrera de Licenciatura en Ciencias de la Computacin.

3
3
CAPTULO 2. ANTECEDENTES

Dentro de la carrera de Licenciatura en Ciencias de la Computacin ha habido cuatro
trabajos de graduacin que han abordado el mismo tema que se tratar en el presente
trabajo. Como resultado final de estos trabajos se obtuvieron las aplicaciones APRENDE
v1.0, APRENDE v2.0, APRENDE v3.0, y la ms reciente versin ORION; cuyas
caractersticas y problemas se detallan en los siguientes prrafos.

2.1 APRENDE v1.0

Fue concebido en la UCA en el ciclo 02/2003 como un trabajo de graduacin de la carrera
Licenciatura en Ciencias de la Computacin, el objetivo era construir una herramienta que
sirviera de apoyo al proceso de enseanza y aprendizaje de la programacin en
computadoras. El nombre de APRENDE son las siglas de Algoritmos en Pseudo-cdigo
Runtime Environment y Desarrollador.

El nombre del trabajo de graduacin fue: PLATAFORMA PARA LA CREACIN Y
EJECUCIN DE ALGORITMOS EN PSEUDO-CDIGO, realizado por: Jaime Alfredo
Castaeda Castillo y Lenin Vladimir Solrzano Garca.

El entorno de desarrollo fue utilizado, luego de su finalizacin, durante dos ciclos de
estudio de la universidad (02/2004 03/2004), en la materia Fundamentos de
Programacin, durante este periodo de utilizacin los usuarios detectaron una serie de
problemas y fallas que presentaba APRENDE, entre algunas de ellas podemos mencionar:

La opcin de ejecucin paso a paso no era clara.

Faltaba informacin en la fase de finalizacin de la ejecucin de un algoritmo.

La forma de informar al programador sobre errores detectados careca de claridad y
algunos no eran detectados.
4
4
No estaban definidas las variables globales, as como su alcance.

El uso correcto de las palabras reservadas INCLUIR y RUTA no quedaba claro.

Los contenidos de la ayuda eran deficientes.

No era posible utilizar caracteres del idioma castellano como: , , , , y .

El uso de variables y/o constantes reales en sentencias condicionales no se permita.


2.2 APRENDE v2.0

En el 2005 con el objetivo de mejorar la versin anterior de APRENDE, se propone como
trabajo de graduacin el tema: SEGUIMIENTO A LA PLATAFORMA PARA LA
CREACIN Y EJECUCIN DE ALGORITMOS EN PSEUDO-CDIGO, proyecto en el
cual formaron parte: Salvador Antonio Barahona Pea, Roxana Evelyn Casco Valeriano y
Jocelyn Vanesa Prez Anaya.

En los alcances se busc solucionar los problemas presentados en la versin anterior,
adems de proponer la inclusin de nuevas caractersticas al lenguaje de programacin en
pseudo-cdigo, algunas de las cuales fueron:

Implementar funcionalidades de lectura directa del valor de un elemento en un
arreglo.

Aadir el tipo de datos Cadena y las operaciones bsicas para el manejo de este
nuevo tipo de datos.

Permitir que los sub-algoritmos reciban arreglos como parmetros de entrada.

5
5
Aadir el tipo de datos Archivo y las operaciones bsicas de lectura y escritura de
archivos.

Varios alcances lograron implementarse con xito, sin embargo, otros no fueron
implementados. Esto se debi a que en APRENDE v1.0 se utiliz un meta-compilador
llamado javaCC en la construccin del compilador, ya que para usarlo de manera
eficiente es necesario poseer cierto nivel de conocimiento y prctica en su utilizacin.
Luego, esto redujo la capacidad para manipular el cdigo generado por javaCC, ya sea
para hacer mejoras o correcciones. Entre los alcances que no lograron implementarse estn:


Aadir el tipo de dato cadena.

Aadir el manejo de archivos.

Permitir el uso de caracteres ajenos al lenguaje ingls como: , , , , y .

Mejorar la presentacin de los errores.


2.3 APRENDE v3.0

Fue el tercer intento por retomar la misma lnea de trabajo dejada por APRENDE v2.0. El
tema de trabajo de graduacin fue: SEGUIMIENTO A LA PLATAFORMA PARA LA
CREACIN Y EJECUCIN DE ALGORITMOS EN PSEUDO-CDIGO. VERSIN
3.0. En este proyecto trabajaron: Felipe Antonio Carranza Flores, David Salvador Sosa
Mendoza y Arturo Eduardo Turcios Rivas.

Entre las mejoras que se propusieron en este trabajo de graduacin se mencionan las
siguientes:

6
6
Reconstruccin del compilador de APRENDE, debido a la dificultad que
presentaba el solventar los problemas generados por el uso del meta-compilador
JavaCC.

Corregir los errores y funcionalidades que hicieron falta en la versin 2.0, entre
los cuales estaban:
o Permitir la lectura directa del valor de un elemento en un arreglo.
o Aadir el uso de variables y/o constantes reales en sentencias
condicionales.
o Realizar la documentacin de operaciones bsicas para la manipulacin
del tipo de dato cadena.
o Mejorar los contenidos de la ayuda.
o Implementar la ejecucin paso a paso para que funcione adecuadamente.
o Permitir el redimensionamiento de la consola de estado.
o Presentar de forma ms clara cuando la ejecucin de un algoritmo
finaliza y mejorar la presentacin de los errores.

Generar una mquina virtual para la ejecucin del cdigo intermedio.

Adaptar el nuevo compilador a la interfaz grfica ya existente.

Luego de haber planteado los alcances anteriormente descritos, el nuevo compilador
comenz a ser desarrollado y se usaron nuevamente meta-compiladores para la
construccin de los componentes del compilador. El Scanner fue creado con el generador
de analizadores lexicogrficos FLEX y el Parser o analizador sintctico fue generado con
un metacompilador llamado BISON. Sin embargo, el trabajo no logr ser completado en
todas las caractersticas que inicialmente fueron propuestas.




7
7
2.4 ORION v1.0

Es la versin ms reciente creada por estudiantes de la carrera de Licenciatura en Ciencias
de la Computacin. El objetivo principal era corregir las fallas y realizar una ampliacin
de APRENDE v3.0, de ah su nombre: AMPLIACIN Y MEJORAS DE UNA
PLATAFORMA DE APRENDIZAJE DE PROGRAMACIN EN PSEUDO-CDIGO.
El trabajo fue realizado y terminado en octubre del 2008 por: Ingrid Margarita Alfaro
Aragn, Ricardo Mauricio Alvarado Carrillo, Patricia Eugenia Melndez Guardado y
lvaro Javier Navarrete Guerrero. El nombre de ORION es el acrnimo de platafOrma de
apRendIzaje deprOgramaciN.

Entre las mejoras ms importantes que se implementaron para esta nueva versin destacan:

La creacin de una funcionalidad que permite al usuario observar la ejecucin de un
programa y con ello el comportamiento del flujo de datos y variables en el
transcurso de la ejecucin. Esta funcionalidad fue importante tambin para ayudar al
programador a encontrar las fallas de un algoritmo escrito en pseudo-cdigo.

El diseo e implementacin de una interfaz grfica ms amigable y moderna.

Correccin de diversas fallas encontradas en APRENDE v3.0.

El compilador, al igual que en versiones anteriores, sigui desarrollndose con las
herramientas para la construccin de compiladores: FLEX y BISON, para la generacin del
Scanner y el Parser respectivamente.

Nuevamente esta metodologa ofreci la ventaja de poder generar cdigo que facilita la
labor del programador, pero ofreciendo a la vez la desventaja de la inflexibilidad del cdigo
generado y la carencia de amplia documentacin.

8
8
Por esto ltimo, surgieron algunos detalles en el nuevo compilador que provocaron que no
funcionase como era esperado, y por ende, se encontraron algunas fallas y/o defectos no
deseados, los cuales son:

Inconsistencia en el uso de la instruccin para durante el manejo y uso de
llamadas a sub-algoritmos.

Deteccin de errores inexistentes a tiempo de compilacin en el manejo de ndices
para los arreglos.

Congelamiento inesperado de la interfaz grfica durante el manejo de archivos.

Congelamiento inesperado de la interfaz grfica durante el proceso de ejecucin
paso a paso.
9
9
CAPTULO 3. MARCO TERICO

3.1 Compiladores e Intrpretes

3.1.1 Compiladores

Los principios y tcnicas de escritura de compiladores son tan amplios que tienen el alcance
de poder ser empleados en muchas otras reas de la computacin. La escritura de
compiladores comprende los lenguajes de programacin, la arquitectura de computadores,
la teora de lenguajes, los algoritmos y la ingeniera de software. Por fortuna, con algunas
tcnicas bsicas de escritura de compiladores se pueden construir traductores para una gran
variedad de lenguajes y mquinas. En este captulo, se introduce el tema de la compilacin
describiendo los componentes de un compilador y el entorno en el que stos trabajan.

Un compilador es un programa reconocedor-traductor, que recibe como entrada un
programa escrito en un lenguaje dotado de estructura y que pasando por una serie de
esquemas de reconocimiento y traduccin, produce otro programa en lenguaje objeto. El
compilador reconoce, aplana, y devasta su entrada, hasta producir una salida
linealizada y entendible para la computadora.

En otras palabras, el objetivo de un compilador es bsicamente traducir un programa (o
texto) escrito en un lenguaje fuente, que llamaremos programa o cdigo fuente, en un
equivalente en otro lenguaje denominado objeto, al que llamaremos programa o cdigo
objeto. Si el programa fuente es correcto (se genera a partir del lenguaje fuente), el
compilador podr realizar tal traduccin sin problemas; de lo contrario, se espera que se
pueda obtener uno o varios mensajes de error que permitan determinar, lo ms claramente
posible, los orgenes de la incorreccin.

La traduccin podr hacerse en dos formas:
Interpretacin: la traduccin se hace frase a frase.
10
10
Compilacin: la traduccin se hace del texto completo. La compilacin consiste en coger
los archivos fuente que conforman un programa y, lnea por lnea, traducir cada instruccin
de alto nivel por varias instrucciones en cdigo mquina que realicen lo que la instruccin
de alto nivel expresa. Si se repite esa traduccin para todas las lneas del cdigo fuente,
obtendremos un conjunto de instrucciones de mquina. Al grabar dichas instrucciones
mquina en un archivo que contiene una estructura interna, que un determinado sistema
operativo es capaz de entender, se obtiene un archivo binario ejecutable (Figura 1).












Es frecuente que, adems del compilador, se utilicen otros programas para crear un cdigo
objeto ejecutable. Un esquema tpico es el que se describe a continuacin.

Una aplicacin para edicin de texto es necesaria para escribir la estructura del programa
fuente. Dicho programa puede incluir texto en lenguaje fuente y algunas rdenes para el
preprocesador, el cual se encarga de realizar algunas tareas tales como la eliminacin de
comentarios, expansin de macros, inclusin de archivos, sustitucin de constantes, o
algunas extensiones del lenguaje fuente.

El compilador traducir el resultado del pre-proceso obteniendo un programa equivalente
en lenguaje ensamblador, que a su vez ser traducido por el ensamblador a cdigo de
Archivo ejecutable
Archivos fuente
Figura 1. Compilacin.
11
11
mquina relocalizable, en el cual las direcciones sern relativas a ciertas posiciones de
origen, y quizs algunas llamadas a rutinas no estn resueltas an.

Finalmente, el editor de carga y enlace (o montador, o linker) resolver las llamadas a
rutinas, incluyndolas a partir de otros objetos de biblioteca si es necesario, y obtendr
direcciones absolutas, de modo que ya se dispondr del cdigo mquina absoluto
ejecutable. El proceso entero se ilustra en la figura 2.


Estructura del programa fuente




Programa fuente

Compilador

Programa objeto en ensamblador

Ensamblador

Cdigo mquina relocalizable

Editor de carga y enlace



Cdigo mquina absoluto





No siempre todo este proceso es necesario, y, an cuando se realice, no siempre ser
observado por el usuario, de forma que una sola orden (cc programa.c, por ejemplo)
puede provocar el proceso completo. Los compiladores suelen incluir opciones que
permiten obtener explcitamente (o conservar) los resultados intermedios.

Cada uno de los componentes es realmente un traductor. La dificultad mxima de
traduccin suele estar en la compilacin propiamente dicha.
Preprocesador
Biblioteca, archivos objeto
relocalizables

Figura 2. Sistema para procesamiento de un lenguaje.




12
12
Preprocesadores.
Un preprocesador es un programa separado del compilador, pero que es invocado por este
mismo antes de que comience el proceso de compilacin. El preprocesado es una fase que
se aplica generalmente sobre el archivo principal que contiene el cdigo fuente.
La funcin principal de los preprocesadores es hacer inteligible, para el compilador, el
cdigo fuente, cambiando las directivas de preprocesamiento por valores para el
compilador. Estas directivas siempre estn sealadas por caracteres especiales, con el
objetivo de que solo sean modificadas por el preprocesador. En el caso del preprocesador
de C estas directivas comienzan con #.
Algunos preprocesadores son capaces de comprobar errores de sintaxis en el cdigo antes
de pasar a la etapa de compilacin, incluso pueden detectar dependencias con otros
archivos para evitar muchos problemas.
Los preprocesadores producen la entrada para un compilador, y pueden realizar las
funciones siguientes:
Procesamiento de macros. Un preprocesador puede permitir a un usuario definir
macros, que son abreviaturas de construcciones ms grandes.
Inclusin de archivos. Un preprocesador puede insertar archivos de
encabezamiento en el texto del programa. Por ejemplo, el preprocesador de C hace
que el contenido del archivo <global.h> reemplace a la proposicin #include
<global.h> cuando procesa un archivo que contenga a esa proposicin.
Preprocesadores "racionales". Estos preprocesadores enriquecen los lenguajes
antiguos con recursos ms modernos de flujo de control y de estructuras de datos.
Por ejemplo, un preprocesador de este tipo podra proporcionar al usuario macros
incorporadas para construcciones, como proposiciones while o if, en un lenguaje de
programacin que no las tenga.
13
13
Extensiones a lenguajes. Estos preprocesadores tratan de crear posibilidades al
lenguaje que equivalen a macros incorporadas. Por ejemplo, el lenguaje Equel es un
lenguaje de consulta de base de datos integrado en C. El preprocesador considera las
proposiciones que empiezan con ## como proposiciones de acceso a la base de
datos, sin relacin con C, y se traducen a llamadas de procedimiento a rutinas que
realizan el acceso a la base de datos.
Los procesadores de macros tratan dos clases de proposiciones: definicin de macros y uso
de macros. Las definiciones normalmente se indican con algn carcter exclusivo o palabra
clave, como define o macro. Constan de un nombre para la macro que se est definiendo y
de un cuerpo, que constituye su definicin.


3.1.2 Intrpretes

Un intrprete es un programa que analiza y ejecuta simultneamente un programa escrito en
un lenguaje fuente.
Los intrpretes en lugar de producir un programa objeto como resultado de una traduccin,
realizan las operaciones que implica el archivo fuente. Para una proposicin de asignacin
en lenguaje Pascal, por ejemplo, un intrprete podra construir un rbol sintctico como el
de la figura 3.


Figura 3. Ejemplo de rbol sintctico.

14
14

Posteriormente a la construccin del rbol, el intrprete efectuara las operaciones de los
nodos conforme recorre el rbol. En la raz descubrira que tiene que realizar una
asignacin, y llamara a una rutina para evaluar la expresin de la derecha y despus
almacenara el valor resultante en la localidad de memoria asociada con el identificador
posicin. En el hijo derecho de la raz, la rutina descubrira que tiene que calcular la suma
de dos expresiones. Se llamara a s misma de manera recursiva para calcular el valor de la
expresin velocidad*60. Despus sumara ese valor al valor de la variable inicial.
Muchas veces los intrpretes se usan para ejecutar lenguajes de rdenes, pues cada
operador que se ejecuta en un lenguaje de rdenes suele ser una invocacin de una rutina
compleja, como un editor o un compilador. Del mismo modo, algunos lenguajes de muy
alto nivel, normalmente son interpretados, porque hay muchas cosas sobre los datos, como
el tamao y la forma de las matrices, que no se pueden deducir en el momento de la
compilacin.
El proceso de interpretacin es bastante diferente al de compilacin, pero su resultado
debera ser similar: la ejecucin de un programa. A diferencia del compilador, el intrprete
no realiza una traduccin a cdigo de mquina. El intrprete intenta realizar "al vuelo" lo
que se expresa en los archivos fuente. El intrprete contiene en su interior miles de
porciones de cdigo de mquina, que combinndolas adecuadamente pueden realizar las
mismas tareas que expresa una orden escrita en el lenguaje de alto nivel.
Cuando un programa es interpretado, el proceso que se sigue es el siguiente: el intrprete
obtiene una instruccin del archivo fuente y la realiza inmediatamente. Para ello, ejecuta en
secuencia varias de esas porciones de cdigo de mquina que se mencionaron
anteriormente, y que residen en el interior del intrprete. Cuando la CPU termina la
ejecucin de esa secuencia, el resultado es que la CPU habr hecho lo que la lnea de
cdigo fuente expresaba.


15
15
Diferencias entre compilar e interpretar.

La opcin de compilar o interpretar no est siempre disponible. Algunos lenguajes
tpicamente se compilan y otros tpicamente se interpretan. En muy pocas ocasiones se
puede optar por una u otra indistintamente.
Por ejemplo, programas escritos en lenguajes como C prcticamente siempre se compilan,
y otros programas escritos en lenguajes como Perl o Python prcticamente siempre se
interpretan.

Por medio del siguiente cuadro comparativo se muestran algunas de las diferencias ms
importantes que existen entre compilar e interpretar:
Compilar Interpretar
-Genera un ejecutable. -No genera un ejecutable.
-El proceso de traduccin se realiza una
sola vez.
-El proceso de traduccin se realiza en
cada ejecucin.
-La ejecucin es muy rpida debido a que
el programa ya ha sido traducido a cdigo
mquina.
-La ejecucin es ms lenta, ya que para
cada lnea del programa es necesario
realizar la traduccin.
-Los programas que se van a compilar
suelen estar muy ligados a la plataforma de
destino.
-Los programas que se van a interpretar no
suelen ser muy dependientes de su
plataforma de destino, siendo ms
portables.
-Los lenguajes compilados suelen
proporcionar al programador mecanismos
ms potentes y flexibles, a costa de una
mayor ligazn a la plataforma.
-Los lenguajes interpretados no suelen ser
muy dependientes de la plataforma de
destino, pero suelen ser menos flexibles y
potentes que los compilados.
-Una vez compilado el programa, el cdigo
fuente no es necesario para ejecutarlo, as
que puede permanecer en secreto si se
desea.
-El cdigo fuente es necesario en cada
ejecucin, as que no puede permanecer en
secreto.
-Los errores sintcticos se detectan durante
la compilacin. Si el cdigo fuente
contiene errores sintcticos, el compilador
no producir un ejecutable.
-Los errores sintcticos se detectan durante
la ejecucin, ya que traduccin y ejecucin
se van haciendo simultneamente.
16
16
Tabla 1. Comparacin entre compilar e interpretar


3.2 Estructura de un compilador

La construccin de un compilador involucra la divisin del proceso en una serie de fases
que variar con su complejidad. Generalmente estas fases se agrupan en dos tareas: el
anlisis del programa fuente y la sntesis del programa objeto. El anlisis divide al
programa fuente en sus componentes y crea una representacin intermedia del programa
fuente. La parte de la sntesis construye el programa objeto deseado a partir de la
representacin intermedia. De las dos, la sntesis es la que requiere tcnicas ms
especializadas.

Durante el anlisis se determinan las operaciones que indica el programa fuente, obteniendo
una representacin del significado, normalmente en una estructura jerrquica de rbol, en la
que cada nodo representa una operacin, y cuyos hijos son los argumentos de dicha
operacin.

De este modo, a partir de la representacin intermedia, diferentes partes de sntesis podran
obtener distintos cdigos, para distintos lenguajes objeto; tambin, a partir de distintos
lenguajes fuente, con partes de anlisis adecuadas, se podra obtener una representacin
intermedia que pueda ser traducida por una sntesis a un nico lenguaje objeto.

El anlisis suele dividirse en tres fases: anlisis lxico, anlisis sintctico y anlisis
semntico; y la sntesis en otras tres: generacin de cdigo intermedio, optimizacin de
cdigo y generacin de cdigo.
-Un programa compilado puede, por error,
afectar seriamente a la estabilidad de la
plataforma, comprometiendo la ejecucin
de los otros procesos, por ejemplo,
acaparando la CPU, la memoria o algn
otro recurso, siendo a veces complicado
para el sistema operativo interrumpir su
ejecucin.
-Un programa interpretado con un
comportamiento torpe normalmente puede
ser interrumpido sin dificultad, ya que su
ejecucin est bajo el control del
intrprete, y no slo del sistema operativo.
17
17
Se consideran por lo tanto 6 fases en el proceso de compilacin, cada una de las cuales
transforma la fuente de entrada, progresivamente, hasta conseguir el objeto final.

Por otra parte, cada una de las fases puede detectar errores, y debe informar adecuadamente
de ellos. Se considerar, por simplificar el esquema, un slo bloque de manipulacin de
errores, que se usa desde cada fase, puesto que la informacin de los errores deber estar
relacionada con el lugar del texto en el que se encuentra, relacin que slo puede establecer
la fase de anlisis lxico.

La mayor parte de los errores se detectan en las dos primeras fases. Adems, las diferentes
fases crean y acceden a una estructura de datos llamada tabla de smbolos, en la que se
anotan a lo largo de las fases, variadas informaciones o atributos que es necesario
intercambiar; por ejemplo, las variables, con sus nombres, tipos, mbito, posicin relativa
de memoria en la generacin de cdigo, etc.
Estos dos ltimos elementos, aunque no sean realmente fases del proceso, tienen suficiente
entidad como para ser consideradas bloques de similar importancia.
Alternativamente, las fases descritas para las tareas de anlisis y sntesis se pueden agrupar
en Front-end y Back-end (Figura 4):
Front-end: es la parte que analiza el cdigo fuente, comprueba su validez, genera el
rbol de derivacin (ver El Anlisis Sintctico) y rellena los valores de la tabla de
smbolos. Esta parte suele ser independiente de la plataforma o sistema para el cual
se vaya a compilar.
Back-end: es la parte que genera el cdigo de mquina, especfico de una
plataforma, a partir de los resultados de la fase de anlisis, realizada por el Front
End.
Esta divisin permite que el mismo Back End se utilice para generar el cdigo mquina de
varios lenguajes de programacin distintos y que el mismo Front End, que sirve para
analizar el cdigo fuente de un lenguaje de programacin concreto, sirva para generar
cdigo mquina en varias plataformas distintas.
18
18














3.2.1 El Anlisis Lexicogrfico

Se considera el anlisis lxicogrfico como la primera fase o etapa de desarrollo de un
compilador. Para entender mejor su funcin principal, es necesario definir el concepto de
lexema y token. El lexema o lexeme, es una secuencia de caracteres en el cdigo fuente,
que poseen en conjunto un significado especial en el lenguaje de programacin. El token es
un smbolo con un significado especial en el lenguaje. Es precisamente el significado que
se le otorga a un lexema.

Una vez definidos los conceptos anteriores es importante distinguir que la funcin principal
del analizador lxico es la de leer los caracteres de entrada de un cdigo fuente, los cuales
agrupa en lexemas, y luego produce como salida un flujo de componentes lxicos (tokens)
que sern utilizados en la fase de anlisis sintctico. La forma en como se realiza esta
interaccin se puede observar en la figura 5.

Figura 4. Fases de un compilador.

19
19
Analizador lxico Cdigo fuente
Componente
lxico
Analizador
sintctico
Obtener el
siguiente
componente
lxico
Tabla de smbolos


Figura 5. Interaccin entre el analizador lxico y el analizador sintctico.

El analizador lxico y el analizador sintctico forman un par productor-consumidor. El
analizador lxico produce componentes lxicos y el analizador sintctico los consume. Los
componentes lxicos producidos se pueden conservar en un buffer hasta ser consumidos.
Por lo general, el buffer contiene slo un componente lxico. En este caso, la interaccin se
puede aplicar simplemente haciendo que el analizador lxico sea un procedimiento llamado
por el analizador sintctico, que devuelva componentes lxicos cuando se lo pidan.

El analizador lexicogrfico o scanner trabaja con los aspectos meramente
representacionales del programa fuente (el lxico).

Debido a que el analizador lxicogrfico es el componente del compilador que lee el cdigo
fuente, tambin puede ser usado para desempear otras funciones. Una de ellas es obviar
los comentarios, espacios en blanco, caracteres de tabulacin y de lnea nueva en el cdigo
fuente. Otra funcin secundaria es relacionar los mensajes de error con el cdigo fuente,
esto es asociando un nmero de lnea con un mensaje de error, a esto tambin se le conoce
con el nombre de referencias cruzadas. Luego, si se necesita hacer un pre-procesamiento
del cdigo fuente, este puede realizarse dentro del anlisis lxico.
El lenguaje de entrada tendr un catlogo de componentes posibles, que se podrn codificar
(por ejemplo mediante constantes enteras). Normalmente habrn componentes como los
siguientes: palabras reservadas, identificadores caracterizados por ser sucesiones de letras y
20
20
dgitos que comiencen por una letra y que no pertenezcan al catlogo de palabras
reservadas, operadores relacionales, operadores aritmticos, entre otros. Cada vez que se
detecta un nuevo identificador en el anlisis lxico, se anota una entrada en la tabla de
smbolos.
La salida del analizador lxico es, entonces, una sucesin de pares: el tipo de componente
lxico de que se trata y cul de ellos es. Llamaremos componente lxico al primer elemento
del par y valor lxico al segundo.

Necesidad del anlisis lxico.

Algunos aspectos muy importantes por los cuales es imprescindible el anlisis lxico en un
compilador se enumeran a continuacin:

1. Diseo sencillo del compilador, debido a que el analizador lxico permite
simplificar al analizador sintctico.
2. Mejora la eficiencia del compilador.
3. Mejora la portabilidad del compilador, esto es alcanzado dado que se limitan al
analizador lxico las peculiaridades del alfabeto de entrada, las cuales dependen del
idioma, as, smbolos especiales del japons o el alemn quedan aislados en el
analizador lxico.
Como la tarea que realiza el analizador lxico es un caso especial de coincidencia de
patrones, se necesitan los mtodos de especificacin y reconocimiento de patrones, y estos
mtodos son principalmente las expresiones regulares y los autmatas finitos. Sin embargo,
un analizador lxico tambin es la parte del traductor que maneja la entrada del cdigo
fuente, y puesto que esta entrada a menudo involucra un importante gasto de tiempo, el
analizador lxico debe funcionar de manera tan eficiente como sea posible.
21
21
La lexicografa de un lenguaje de programacin puede ser descrita por expresiones
regulares, de forma que basta construir un Autmata Finito Determinstico para reconocer
los lexemas.


Errores lxicos.

La cantidad de errores que se pueden encontrar en la fase de anlisis lxico es muy escasa.
Un ejemplo de ello, se observa en la siguiente lnea de cdigo en C:

fi (var = = 2)

Un programador logra detectar que fi se trata de un if mal escrito, pero para el
analizador lxico fi es un identificador. Luego el analizador lxico devolver
identificador como token y entonces ser tarea del analizador sintctico o parser detectar
el error sintctico.



3.2.2 El Anlisis Sintctico

El anlisis sintctico se entiende como el proceso de determinar si una cadena de
componentes lxicos o tokens puede ser generada por una gramtica, y en caso de
conseguirlo, se debe poder descubrir su estructura gramatical, esto es, el camino de
derivacin.

Cuando se habla sobre una gramtica en el anlisis sintctico, especficamente se hace
referencia a las gramticas independientes del contexto (Ver Anexo B), ya que son stas las
que describen de forma natural la estructura jerrquica de muchas construcciones de los
lenguajes de programacin de alto nivel.

22
22
Dentro del compilador, el papel del analizador sintctico es obtener una cadena de
componentes lxicos provenientes del analizador lxico y comprobar si la cadena es
generada por la gramtica del lenguaje fuente. Esto se observa en la figura 6.


Analizador lxico Cdigo fuente
Componente
lxico
Analizador
sintctico
Obtener el
siguiente
componente
lxico
Tabla de smbolos
rbol de
anlisis
sintctico
Resto de la etapa
inicial
Representacin
intermedia


Figura 6. Posicin del analizador sintctico en el compilador.


En una etapa de implementacin, dentro del analizador sintctico se pueden realizar varias
tareas, como recoger informacin sobre distintos componentes lxicos en la tabla de
smbolos, realizar la verificacin de tipo y otras clases de anlisis semntico, y generar
cdigo intermedio por el mtodo llamado traduccin dirigida por la sintaxis. Todas estas
actividades se han agrupado en el cuadro de resto de la etapa inicial que se encuentra en
la figura 6.


rboles de anlisis sintctico.

Una manera de indicar grficamente como se realiza la derivacin de una cadena a partir
del smbolo inicial de una gramtica es por medio de un rbol de anlisis sintctico.
Para el ejemplo anterior, la expresin 8-4+1, el correspondiente rbol de anlisis sintctico
se observa en la figura 7.
23
23










Figura 7. Ejemplo de rbol de anlisis sintctico.



Ambigedad.

Cuando una frase puede ser derivada desde el smbolo inicial de una gramtica en dos
formas o caminos de derivacin diferentes, entonces se dice que la gramtica es ambigua.
Otra manera de determinar la ambigedad de una gramtica es con los rboles de anlisis
sintctico. Luego, si una gramtica produce ms de un rbol de anlisis sintctico para
alguna frase, entonces tambin se dir que es ambigua.

La ambigedad es una caracterstica que no es preferible en la gramtica con la cual se
realizara el anlisis sintctico, ya que si se permitiera no se podra determinar de manera
exclusiva que rbol de anlisis sintctico seleccionar para una frase.

Para solucionar este inconveniente existen reglas que se pueden implementar en el
analizador sintctico para eliminar las ambigedades y, por tanto, dejar de lado rboles de
anlisis sintctico indeseables.



lista
lista dgito +
lista dgito -
dgito
8
4
1
24
24

Mtodos de anlisis sintctico.

Existen dos mtodos de anlisis sintctico. El primero es el mtodo de anlisis descendente
y el segundo es el mtodo de anlisis ascendente. Estos mtodos hacen referencia a la
manera en como se construye el rbol de anlisis sintctico, es decir, los analizadores
sintcticos descendentes construyen rboles de anlisis sintctico desde arriba (la raz)
hasta abajo (las hojas) y los analizadores sintcticos ascendentes comienzan en las hojas y
suben hasta la raz. En ambos casos, se analiza la entrada, frase o cadena de izquierda a
derecha, un smbolo a la vez.

Dentro del texto, solo se abordar como construir un analizador sintctico descendente,
debido a que los analizadores sintcticos ascendentes, aunque pueden ser ms eficientes,
son ms complicados de implementar.


Mtodo de construccin de analizadores sintcticos descendentes.

Los analizadores sintcticos descendentes pueden ser hechos de manera manual, debido a
que poseen un diseo sencillo y por tanto fcil de implementar.


Reglas
R
Reglas
R'
G
(Gramtica independiente
del contexto)
Representacin grfica,
Diagrama de sintaxis (DS)
Algoritmo resultante:
Parser descendente para
G
G
(Gramtica independiente
del contexto y LL1)


Figura 8. Esquema de construccin de analizadores sintcticos descendentes.

El mtodo, como se muestra en la figura 8 consiste bsicamente en primero definir una
gramtica independiente del contexto que genere la sintaxis del lenguaje fuente, a la cual
denotaremos G, luego seguir las reglas R (Ver Anexo B).


25
25
3.2.3 El Anlisis Semntico

Es el encargado de verificar el cumplimiento de las reglas semnticas para un lenguaje
dado. Formalmente se encarga de verificar si el rbol de anlisis sintctico generado es
vlido en cuanto a reglas semnticas. Aunque se aprecie como un componente separado, en
la prctica, el anlisis semntico se da en el mismo momento que el anlisis sintctico
extendindose inclusive hasta la generacin de cdigo.


Especificacin formal de la semntica de un lenguaje.

Una forma de proporcionar una especificacin precisa de los aspectos semnticos de los
lenguajes de programacin es mediante las gramticas con atributos.


Gramticas con atributos.

Como su nombre lo indica, una gramtica con atributos es una gramtica independiente del
contexto a cuyos smbolos gramaticales (terminales o no terminales) se les asocia un
conjunto de atributos, los cuales pueden ser atributos sintetizados y atributos heredados de
dicho smbolo gramatical.

Un atributo puede representar cualquier cosa: una cadena, un nmero, un tipo, una posicin
en memoria, etc. El valor de un atributo en un nodo de un rbol de anlisis sintctico se
define mediante una regla semntica asociada a la produccin utilizada en dicho nodo.

El valor de un atributo sintetizado en un nodo se calcula a partir de los valores de los
atributos de los hijos de dicho nodo en el rbol de anlisis sintctico; luego, el valor de un
atributo heredado se calcula a partir de los valores de los atributos en los hermanos y el
padre de dicho nodo.

26
26
Un rbol de anlisis sintctico que muestre los valores de los atributos en cada nodo se
llamara un rbol de anlisis sintctico con anotaciones. El proceso de calcular los valores
de los atributos en los nodos se denomina anotar o decorar el rbol de anlisis sintctico.


Comprobador o chequeo de tipos.

Una de las tareas ms importantes dentro del analizador semntico es la comprobacin de
tipos, el cual es el proceso de verificar y tomar acciones sobre los tipos, basndose en el
sistema de tipos de un lenguaje de programacin. Un sistema de tipos define como un
lenguaje de programacin clasifica valores y expresiones en tipos, como se manipularn
estos tipos y como interactan entre si.

La comprobacin de tipos puede ser de dos maneras: comprobacin esttica y
comprobacin dinmica. La diferencia entre ambas radica en que la comprobacin esttica
se hace a tiempo de compilacin y la dinmica a tiempo de ejecucin. Por tanto, la
comprobacin esttica ser tarea del analizador semntico.

Dentro de la comprobacin esttica se pueden encontrar las siguientes:

Comprobaciones de tipos. Se refiere a las comprobaciones de compatibilidad entre
operadores y operandos.
Comprobaciones de flujo de control. Como es el caso de la proposicin break en C
que hace que el control abandone la proposicin que la engloba, ya sea sta while,
for o switch; si dicha proposicin englobadora no existe entonces se deber marcar
el error.
Comprobaciones de unicidad. Se refiere a la definicin nica de objetos, es decir,
un objeto slo debe haberse definido exactamente una vez dentro del cdigo.
Comprobaciones relacionadas con nombres. Hay ocasiones en las que es necesario
que un nombre aparezca dos o ms veces dentro de una porcin de cdigo.

27
27

Tabla de smbolos.

Con el fin de facilitar el anlisis semntico, as como, la generacin de cdigo, es necesaria
la construccin de una tabla de smbolos. La tabla de smbolos es una estructura de datos en
el compilador, en la cual se llevar el registro de los objetos declarados o especificados en
el cdigo fuente, esto es, procedimientos, funciones, variables, constantes, etc. Esta
informacin depender, por tanto, de las especificaciones de cada lenguaje a compilar.


Organizacin y eficiencia de la tabla de smbolos.

Es de notar que la eficiencia de una tabla de smbolos estar estrechamente relacionada con
la forma en como sta se implementar en el cdigo, es decir, que estructura de datos y sus
respectivos algoritmos de manipulacin (insercin, eliminacin y bsqueda de un
elemento) se utilicen en la implementacin.

Fundamentalmente, se pueden concebir tres estructuras para implementar una tabla de
smbolos: lineal, indizada unidimensionalmente y basada en algoritmos de hashing.



3.2.4 Tratamiento de los errores

Cada fase puede encontrar errores. Sin embargo, despus de detectar un error, cada fase
debe tratar de alguna forma ese error, para poder continuar la compilacin, permitiendo la
deteccin de ms errores en el programa fuente. Un compilador que se detiene cuando
encuentra el primer error, no resulta tan til como debiera.

Las fases de anlisis sintctico y semntico por lo general manejan una gran porcin de los
errores detectables por el compilador. La fase lxica puede detectar errores donde los
28
28
caracteres restantes de la entrada no forman ningn componente lxico del lenguaje. Los
errores donde la cadena de componentes lxicos viola las reglas de estructura (sintaxis) del
lenguaje son determinados por la fase de anlisis sintctico. Durante el anlisis semntico
el compilador intenta detectar construcciones que tengan la estructura sintctica correcta,
pero que no tengan significado para la operacin implicada, por ejemplo, si se intenta
sumar dos identificadores, uno de los cuales es el nombre de una matriz, y el otro, el
nombre de un procedimiento.

Un compilador es un sistema que en la mayora de casos tiene que manejar una entrada
errnea, por lo tanto, es indispensable que ste pueda cumplir con ciertos requisitos:

El compilador debe detectar todos los errores en la entrada.
El compilador debe recuperarse de los errores sin perder el control y sin perder
demasiada informacin.
El compilador debe producir un mensaje de error que permita al programador
encontrar y corregir fcilmente los elementos incorrectos de su programa.

El mensaje de error debe proporcionar al programador suficiente informacin para intuir
rpidamente la forma correcta que espera el compilador. Por otra parte, no slo ha de poder
informar, sino tambin ser capaz de seguir el anlisis del texto fuente, sin verse afectado
sobremanera por los posibles errores que vaya detectando.

Para poder continuar el anlisis a partir de la deteccin de un error, habr que estimar:
1. La naturaleza del error.
2. La intencin del programador cuando cometi el error.

Estimar la naturaleza del error puede ser algo complejo, y lo es mucho ms estimar la
intencin del programador. La complejidad viene dada porque an no se han podido
formalizar los factores que influyen en una persona a la hora de codificar un programa.
Adems, hay otras consideraciones que se deben de tomar en cuenta en el tratamiento de
29
29
errores, y todas ellas dependen del lenguaje especfico que se tenga, con lo cual no se
pueden generalizar a todos los lenguajes libres de contexto.

A la vista de un error, una solucin rpida (e ineficiente) es saltar el texto fuente hasta
encontrar una nueva sentencia. Pero esta solucin, adems de resultar drstica, depender
siempre de la estructura y sintaxis que tenga el lenguaje en cuestin. Sin embargo, hay
reglas que sirven para ampliar esta solucin. El objetivo de estas reglas es conseguir dotar
al analizador de una lnea de conducta, de unos puntos de referencia, de forma que no
ignore texto fuente en demasa. La experiencia propia con el compilador es muy importante
para esta etapa.


Clasificacin de los errores.

Errores invisibles: son aquellos que no puede detectar el compilador. Por ejemplo,
errores de lgica y todos los que no se producen por el uso incorrecto del lenguaje
de programacin. Sin embargo hay tcnicas formales para verificar la correctitud de
este tipo de errores.
Errores visibles: s pueden ser detectados por el compilador. Pueden ser
lexicogrficos, sintcticos o semnticos.
Errores a tiempo de ejecucin: no son detectados por el compilador, sino por el
mecanismo de ejecucin del programa (divisin entre 0, stack overflow, etc.).


Algunas reacciones del compilador frente a los errores.

Se encuentra un error y el compilador se detiene informando del error.
El compilador encuentra un error, lo seala al usuario, contina la compilacin pero
no se recupera del error y se marcan cascadas de errores falsos o entra en un bucle
infinito. Esto se conoce como Desestabilizacin.
30
30
El compilador detecta un error, lo seala al usuario e intenta recuperarse del error
(saltando texto o tal vez bajo alguna suposicin sobre la intencin del programador).
La compilacin contina generando o no cdigo objeto.


Regla de las palabras clave.

La primera regla (denominada por Niklaus Wirth
1
regla de la palabra clave) dice que,
para poder saltar o ignorar una parte del texto fuente cuando se detecta un error, ser
conveniente que el lenguaje tenga palabras clave o reservadas cuyo uso inadecuado sea
muy improbable. Por tanto, el compilador se estabilizar al llegar a una de estas palabras
clave.

Ejemplo:
x=3; (x+2) @ l*2 If a=2
^error. ^salto hasta esta posicinla compilacin contina con xito


Regla antipnico.

La segunda regla va enfocada a la propia construccin del analizador sintctico. En los
analizadores descendentes, los objetivos se dividen en objetivos parciales y unos
procedimientos llaman a otros para que analicen esos objetivos parciales. La segunda regla
(denominada por Wirth antipnico) especifica que, cuando un analizador sintctico
detecte un error, no slo debe pararse e informar del error, sino que ha de seguir
examinando el texto hasta llegar a un punto estable. Ello supone que no se podr salir de
un analizador sintctico a no ser que sea por su punto de terminacin normal.


1
Niklaus Emil Wirth es un cientfico de la computacin, mejor conocido por el diseo de diversos lenguajes
de programacin, incluyendo Pascal, y por ser pionero en muchos temas de la Ingeniera de Software.
31
31
La aplicacin prctica de esta regla consiste en saltar texto a partir de la deteccin del error,
y no parar hasta encontrar un smbolo que pueda seguir correctamente a la estructura que se
est analizando. Ello implica que cada analizador debe conocer el smbolo o conjunto de
posibles smbolos que puedan seguir a la estructura sintctica que le corresponde analizar.
Por lo anterior, es necesario definir todos los conjuntos de smbolos seguidores (ver
definicin de Sig(X) en el Anexo B) a una sentencia o estructura dada, y pasar a cada
procedimiento analizador un parmetro con los seguidores correspondientes a la estructura
que analiza dicho procedimiento.

No obstante, saltar texto hasta detectar un seguidor puede ser una solucin bastante pobre.
Despus de todo, el programador puede haber omitido un solo smbolo y saltar texto hasta
encontrar un seguidor puede derivar en que se salte una o ms sentencias correctas. Es
preciso, por tanto, ampliar controles de deteccin, esto se puede lograr introduciendo un
nuevo tipo de smbolos, los smbolos de parada, conjunto de smbolos que est compuesto
por las posibles palabras reservadas que expresan explcitamente el comienzo de una
estructura.

Implementando las reglas anteriores se puede lograr recuperar el analizador ignorando uno
o ms smbolos de entrada. Pero esto es insuficiente cuando el error cometido sea por
omisin. Y ocurre que un gran porcentaje de errores son de este tipo. Es muy comn
olvidarse de un ;, pero rara vez se olvida colocar un while al comenzar una estructura de
ese tipo. La experiencia seala tambin que la inmensa mayora de omisiones son con
smbolos cuya funcin es meramente sintctica, que no representan una accin
determinada. Por tanto, es preciso calibrar bien qu smbolos y, sobre todo, qu palabras
clave incluir en los conjuntos de smbolos seguidores o de parada, para que el analizador
deje de ignorar smbolos cuanto antes.

Wirth especifica que el tratamiento de errores de un buen compilador ha de reunir las
siguientes caractersticas:

Ninguna frase debe dar lugar a que el compilador pierda el control.
32
32

Todos los errores que se presenten deben ser detectados y sealados (lo cual no
significa necesariamente corregidos).

Los errores muy frecuentes e imputables a verdaderos fallos de comprensin o
descuido del programador, habrn de ser diagnosticados correctamente y habrn de
evitar tropiezos adicionales del compilador (los llamados mensajes no genuinos o de
rebote). Esta tercera caracterstica es la ms difcil de lograr, ya que incluso
compiladores de gran calidad emiten dos o ms mensajes para un determinado error.



3.2.5 Generacin de cdigo intermedio

En el modelo de anlisis y sntesis de un compilador, la etapa inicial traduce un programa
fuente a una representacin intermedia, a partir de la cual la etapa final genera el cdigo
objeto. Los detalles del lenguaje objeto se confinan en la etapa final, si esto es posible.
Aunque un programa fuente se puede traducir directamente al lenguaje objeto, algunas
ventajas de utilizar una forma intermedia independiente de la mquina son:

1. Se facilita la redestinacin; se puede crear un compilador para una mquina distinta
uniendo una etapa final para la nueva mquina a una etapa inicial ya existente.
2. Se aumenta la portabilidad del compilador de una mquina a otra (en particular si
existe un ejecutor del cdigo intermedio).
3. Un optimizador de cdigo puede ser aplicado al cdigo intermedio antes de generar
el cdigo de mquina.

Se puede pensar en el cdigo intermedio como un cdigo generalizado para una mquina
abstracta. Esta representacin intermedia debe tener dos propiedades importantes: debe ser
fcil de producir y fcil de traducir al programa objeto. Las mquinas abstractas deben
definirse completamente: por una parte se definir su arquitectura y por otra su repertorio
33
33
de instrucciones. Habitualmente las arquitecturas tpicas de mquinas abstractas son:
mquinas basadas en pila, basadas en registros, combinacin de pilas y registros, orientadas
a objetos.

Sin una representacin intermedia bien definida se debe de crear un compilador diferente
para todas las combinaciones entre lenguajes y procesadores que existen, por lo que para m
lenguajes y n procesadores distintos habra que construir m*n compiladores. Sin embargo,
al contar con la generacin de cdigo intermedio se pueden construir para m lenguajes y n
procesadores m+n compiladores.
La fase de generacin de cdigo intermedio es vital para la implementacin de una mquina
virtual. Actualmente lenguajes de la plataforma .NET y Java utilizan mquinas virtuales, y
con ello aportan estabilidad y portabilidad a las aplicaciones.
Un cdigo intermedio reconocido por su fcil utilizacin e implementacin es el que utiliza
el compilador del lenguaje de programacin PASCAL, denominado cdigo-p. A
continuacin se detallan las caractersticas y estrategias de implementacin de este cdigo
intermedio.

Cdigo-p

El cdigo-p (abreviatura de cdigo empaquetado, packed) es un tipo de cdigo intermedio
al cual pueden ser traducidos los programas para luego ser interpretados y ejecutados por
una mquina virtual, que emula el comportamiento de una CPU.

El cdigo-p utiliza operadores postfijos para el manejo de mquinas virtuales de pila. Los
compiladores comerciales de Microsoft utilizan este tipo de cdigo intermedio.


34
34
La estrategia de generacin de cdigo-p y su ejecucin pueden observarse en la figura 9:









A continuacin se describen los mnemnicos del cdigo-p que son interpretados y
ejecutados por la mquina virtual de PASCAL a travs de una instruccin:

1. LIT: cargar una literal numrica a la pila de memoria de la mquina virtual (stack).
2. CAR: cargar una variable al stack.
3. ALM: instruccin de almacenamiento equivalente a la asignacin.
4. LLA: activacin de procedimiento o subrutina.
5. INS: instruccin de asignacin de espacio en el stack en base a incrementar el
apuntador de stack (SP).
6. SAC: salto condicional.
7. SAL: salto incondicional.
8. OPR: referencia a operacin relacional o aritmtica.

La utilizacin del cdigo-p implica el manejo de tcnicas para la gestin de la memoria de
la mquina virtual y la interaccin con otras estructuras de datos.

La traduccin de estructuras de control en cdigo-p se implementa realizando una
desestructuracin de la instruccin en cdigo-p como podemos ver a continuacin:


Figura 9. Estrategia de generacin y ejecucin de cdigo intermedio.

FRONT-END
BACK-END
Generacin de
cdigo
intermedio
Intrprete
de cdigo
intermedio
Intrprete
de cdigo intermedio
desacoplado del
compilador (loader)
Programa
fuente
Ejecucin
sobre el S.O.
Cdigo
objeto
.OBP
35
35
If C then S
cdigo para la condicin C
SAC E1 !si la condicin es falsa, salta a E1
cdigo para la instruccin S !pueden ser varias lneas
E1: continue

While C do S
E1: cdigo para la condicin C
SAC E2 !si la condicin es falsa, salta a E2
cdigo para la instruccin S !pueden ser varias lneas
SAL E1
E2: continue
Traduccin dirigida por la sintaxis

Si teniendo una frase se construye su rbol de anlisis sintctico y asociamos a cada rama
una regla semntica de tal manera que existe una subrutina que ejecuta la regla emitiendo
una traduccin a cdigo objeto, se dice que la traduccin est siendo dirigida por la sintaxis
(Figura 10).









Usualmente la generacin de cdigo objeto con esta tcnica se realiza durante el anlisis
sintctico.


Figura 10. Traduccin dirigida por la sintaxis.
36
36

Tan pronto el compilador conoce los datos de una instruccin como el mnemnico, la
posicin esttica del nivel de la variable en la memoria y su respectivo valor, se genera la
instruccin en cdigo-p, el cual se detallar ms adelante.

Debido a que la generacin de cdigo objeto es secuencial, se necesita generar
instrucciones de salto hacia direcciones que todava no se conocen. Para un compilador de
un paso sobre el cdigo objeto, se usan tcnicas de parcheo (backpatching). Ya que el
cdigo objeto se generar en RAM, se almacenan las posiciones de instrucciones de salto
hacia direcciones que an no se conocen y se parchan en el momento en que se conozca
hacia donde es el salto.


Backpatching

Cuando se genera un cdigo con saltos condicionales y expresiones booleanas se enfrenta
un problema muy comn, en la expresin if (B) S debemos establecer el salto hacia S
cuando se da B, el problema es que no siempre se conoce B a la hora de hacer esta
transformacin.

Backpatching es un enfoque donde al momento de generar un salto el objetivo de este salto
se deja temporalmente indefinido. Cada salto es almacenado en una lista de saltos donde las
etiquetas de sus destinos son establecidas en el momento en que ya pueden ser
determinadas.


Notacin Polaca Inversa

Una forma de manejar la generacin de instrucciones para clculo es por medio de la
Notacin Polaca Inversa (RPN=Reverse Polish Notation), tambin conocida como
Notacin de Lukasciewicz. La notacin RPN es un mtodo algebraico alternativo de
37
37
introduccin de datos. Su principio es el de evaluar los datos directamente cuando se
introducen y manejarlos dentro de una estructura LIFO (Last In First Out, ltimo en Entrar
Primero en Salir), lo que optimiza los procesos a la hora de programar.
Bsicamente las diferencias con el mtodo algebraico o notacin de infijo es que, al evaluar
los datos directamente cuando son introducidos, no es necesario ordenar la evaluacin de
los mismos, y que para ejecutar un comando, primero se deben introducir todos sus
argumentos; as, para hacer una suma 'a+b=c' el RPN lo manejara a b +, dejando el
resultado 'c' directamente.
Obsrvese que la notacin polaca inversa no es literalmente la imagen especular de la
notacin polaca: el orden de los operandos es igual en las tres notaciones (infijo, prefijo o
polaca, y postfijo o polaca inversa), lo que cambia es el lugar donde va el operador. En la
notacin infija, el operador va en medio de los operandos, mientras que en la notacin
polaca va antes y en la notacin polaca inversa va despus.


3.3 La Mquina Virtual

La idea principal de una mquina virtual es la siguiente: el cdigo fuente se compila, el
resultado de esta compilacin genera un archivo ejecutable con un cdigo dirigido a una
CPU imaginaria. A esta tipo de cdigo se le denomina cdigo intermedio.

Como esa CPU imaginaria no existe, para poder ejecutar ese ejecutable, se construye un
intrprete. Este intrprete es capaz de leer cada una de las instrucciones de cdigo mquina
imaginario y ejecutarlas en una CPU real. A este intrprete se le denomina mquina virtual.
El esquema general de un compilador, incluyendo el concepto de mquina virtual se
muestra en la figura 11.



38
38




Figura 11. Esquema general de un compilador usando una mquina virtual.


Este esquema aporta muchas de las ventajas de la compilacin y la interpretacin,
deshacindose de algunos inconvenientes, pero provee de dos ventajas que son de mucha
importancia:


Portabilidad: Si el compilador gener cdigo intermedio entonces ya se encuentra
libre de errores y es un cdigo muy sencillo (al estilo del cdigo mquina). Si existe un
intrprete para este cdigo en distintas plataformas, el mismo cdigo se puede ejecutar en
cada una de ellas. Adems, la construccin de este intrprete ser relativamente sencilla y
su ejecucin ms rpida, ya que no ha de realizar un anlisis de tipo lxico, sintctico y
semntico en busca de errores.


Estabilidad: El cdigo intermedio no es ejecutado por una CPU real directamente,
sino por una CPU virtual, esto es, la mquina virtual. Esto permite un mayor control sobre
este cdigo, facilitando la labor de impedir que un cdigo descontrolado afecte a la
estabilidad de la plataforma real.


39
39
Desde otros puntos de vista tambin podemos encontrar las ventajas de este enfoque. A
continuacin se enuncian algunas de ellas:

Se realiza una sola traduccin a cdigo intermedio, y una interpretacin muy rpida
del cdigo intermedio en cada ejecucin.

Un programa que presente un comportamiento inadecuado, que es ejecutado sobre
la mquina virtual, no suele comprometer la estabilidad de la plataforma real,
debido a que la mquina virtual tiene un control absoluto sobre l.

41
41
CAPTULO 4. OBJETIVOS

4.1 Objetivo General

Desarrollar herramientas que faciliten el aprendizaje de los fundamentos de la
programacin en la carrera de Licenciatura en Ciencias de la Computacin de la
Universidad Centroamericana Jos Simen Caas, analizando y redefiniendo la
estructura sintctica y semntica del lenguaje para la ejecucin de algoritmos en pseudo-
cdigo, diseado en proyectos anteriores dentro de la UCA, junto con la construccin de su
respectivo compilador.


4.2 Objetivos Especficos

a) Analizar la definicin del lenguaje para la ejecucin de algoritmos en pseudo-
cdigo, orientando su utilizacin a un entorno primordialmente didctico, que pueda
ser de ayuda a los programadores principiantes.

b) Reestructurar las reglas sintcticas y semnticas del lenguaje para la ejecucin de
algoritmos en pseudo-cdigo, de tal forma que se fortalezcan en dicho lenguaje
caractersticas como legibilidad y sencillez, reduciendo situaciones excepcionales y
proporcionando tambin un conjunto ms claro y unificado de las instrucciones
bsicas para el desarrollo de algoritmos.

c) Crear un compilador estable y funcional para el lenguaje de programacin para la
ejecucin de algoritmos en pseudo-cdigo, cuyo proceso de desarrollo sea
completamente independiente de cualquier tipo de meta-compilador, facilitando con
ello la escalabilidad y legibilidad del cdigo fuente del compilador y
proporcionando un ambiente propicio para posteriores procesos de depuracin.

42
42
d) Disear e implementar un cdigo intermedio y su respectiva mquina virtual que
proporcionen estabilidad y portabilidad al lenguaje para la ejecucin de algoritmos
en pseudo-cdigo.

e) Proveer al compilador en su fase de implementacin caractersticas de modularidad
que faciliten la incorporacin de este a cualquier entorno de desarrollo.

f) Construir una herramienta de software funcional y til para los docentes de la
Universidad Centroamericana Jos Simen Caas que pueda ser utilizada en su
labor didctica dentro de las materias de Fundamentos de Computacin y
Compiladores.

g) Generar un producto informtico de calidad que cumpla con los requerimientos
necesarios para ser utilizada a nivel nacional en el mbito educativo de la
informtica.

h) Superar las deficiencias y dificultades presentadas en los proyectos precedentes para
evitar que estas interfieran en el aprendizaje de la programacin en pseudo-cdigo.
43
43
CAPTULO 5. PRODUCTOS ENTREGABLES


Al finalizar el trabajo de graduacin se espera contar con los siguientes productos:


1. Un compilador del lenguaje para la ejecucin de algoritmos en pseudo-cdigo con
un cdigo fuente claramente estructurado, con la funcionalidad del tratamiento de
errores y la generacin de cdigo intermedio.


2. Una mquina virtual capaz de interpretar el cdigo intermedio generado por el
compilador.


3. Un manual de usuario que brinde la ayuda necesaria al lector para que pueda utilizar
las aplicaciones construidas y aprovechar sus funcionalidades al mximo.


4. Un manual tcnico que brinde a programadores un mejor entendimiento de la
manera en que sern construidos el compilador y la mquina virtual.


5. El documento final del trabajo de graduacin.

45
45
CAPTULO 6. ALCANCES Y LIMITES

6.1 Alcances

Los alcances planteados en este trabajo de graduacin son:

Rediseo del lenguaje para la ejecucin de algoritmos en pseudo-cdigo de manera
que se puedan solventar ciertas deficiencias en su estructura y mejorar su capacidad
de utilizacin como herramienta didctica.

Nombramiento del lenguaje para la ejecucin de algoritmos en pseudo-cdigo para
su identificacin como lenguaje formal de programacin creado en la Universidad
Centroamericana Jos Simen Caas.

Construccin manual de un compilador que soporte cualquier programa escrito en el
lenguaje para la ejecucin de algoritmos en pseudo-cdigo y que efecte un proceso
de anlisis sintctico descendente.

Diseo de un cdigo intermedio que constituya la salida del compilador.

Construccin manual de una mquina virtual capaz de interpretar el cdigo
intermedio diseado y generado por el compilador del lenguaje para la ejecucin de
algoritmos en pseudo-cdigo.



A continuacin se presentan el conjunto de fallas actualmente existentes que se solventarn,
las mejoras que sern implementadas y el listado de requerimientos solicitados para el
presente trabajo:

Fallas.
Falta de claridad en la especificacin del lenguaje para la ejecucin de algoritmos
en pseudo-cdigo a causa de:
46
46

o Diagramas de sintaxis no implementados de acuerdo a los estndares
planteados para este tipo de diagramas.

o Diagramas de sintaxis incompletos o con entradas y salidas no coherentes
con el contexto en el que se encuentran.

o Escasa documentacin acerca de la implementacin de los mecanismos
evaluativos de la sintaxis y el funcionamiento del lenguaje dentro del
compilador y la interfaz grfica.

Ambigedad en la especificacin del lenguaje para la ejecucin de algoritmos en
pseudo-cdigo a causa de los mismos elementos antes mencionados.

Al traducir sin ningn tratamiento previo los diagramas de sintaxis del lenguaje para
la ejecucin de algoritmos en pseudo-cdigo a una gramtica formal, no cumple con
ser LL1 en algunas producciones, lo que dificulta el construir un compilador que
sea eficiente y que realice un anlisis sintctico descendente.

Poco valor didctico en varios elementos del lenguaje para la ejecucin de
algoritmos en pseudo-cdigo, tales como:

o Declaracin previa de funciones para su posterior definicin.

o Inclusin de archivos y especificacin de rutas.

o Manejo de archivos como tipo de dato formal para la creacin y utilizacin
de variables.
o Pobre delimitacin de elementos en la sintaxis de la instruccin para.


Errores actualmente existentes en tiempo de compilacin:
47
47

o Imposibilidad de compilacin al utilizar una instruccin para que contenga
dentro de su estructura una llamada a un sub-algoritmo.

o Deteccin de errores inexistentes a tiempo de compilacin en el manejo de
ndices para los arreglos. En este caso, si se ha colocado como ndice una
variable, el compilador intenta errneamente evaluar el valor de esta
variable en tiempo de compilacin, lo cual debera suceder en tiempo de
ejecucin.



Mejoras.

Modificar la sintaxis del lenguaje para la ejecucin de algoritmos en pseudo-cdigo
de forma que al traducir su definicin a una gramtica formal sta sea LL1 en todas
sus producciones, o al menos cuente con pocas excepciones fcilmente resolubles.

Modificar la sintaxis del lenguaje para la ejecucin de algoritmos en pseudo-cdigo
de forma que pueda contar con un alto valor pedaggico y pueda as conformar una
herramienta didctica bastante satisfactoria desde la perspectiva del usuario final.

Agregar funciones predefinidas de carcter matemtico que faciliten la construccin
de algoritmos de mayor nivel, tales como:

o Funciones para la evaluacin de logaritmo natural y logaritmo base 10.

o Funcin para aproximar un nmero mediante el mtodo de redondeo.

o Funcin que devuelva el nmero .

o Funcin que devuelve el valor de e elevado a una potencia.

48
48
Modificar la sintaxis del lenguaje para la ejecucin de algoritmos en pseudo-cdigo
de forma que la instruccin para cuente con delimitadores ms claros que faciliten
su evaluacin a tiempo de compilacin y mejoren su apreciacin y comprensin por
parte de los usuarios.

Modificar la sintaxis del lenguaje para la ejecucin de algoritmos en pseudo-cdigo
de forma que cuente con una mayor distincin entre los sub-algoritmos que retornan
un valor (funciones) y los que no lo retornan (procedimientos).

Modificar la sintaxis del lenguaje para la ejecucin de algoritmos en pseudo-cdigo
de forma que la utilizacin de arreglos y matrices pueda llevarse a cabo de manera
ms intuitiva por parte de los usuarios.

Modificar la sintaxis del lenguaje para la ejecucin de algoritmos en pseudo-cdigo
con el fin de permitir la diferenciacin para el envo de parmetros por valor y envo
de parmetros por referencia, as como permitir utilizar cualquiera de estas dos
modalidades.

Agregar mecanismos de tratamiento de los errores durante la construccin del
compilador del lenguaje para la ejecucin de algoritmos en pseudo-cdigo con el
objetivo de aumentar la estabilidad y eficiencia en la deteccin de errores. Estos
mecanismos de tratamiento de los errores se dedicarn a la estabilizacin de errores
sintcticos y semnticos exclusivamente.

Agregar mecanismo de modularizacin en la generacin del reporte de los errores
del compilador de manera que ste pueda ser acoplado a cualquier entorno grfico
sin necesidad de modificar el cdigo fuente del compilador.

Aadirle propiedades de portabilidad y escalabilidad al proyecto a travs de la
implementacin y diseo del cdigo intermedio y la mquina virtual que lo
interpretar. La estrategia de implementacin para la generacin de cdigo
intermedio ser implementada bajo un esquema de traduccin dirigido por la
sintaxis.
49
49

Mejorar y clarificar la documentacin de la estructura del compilador y sus
mecanismos evaluativos mediante su proceso de construccin manual.

Nombrar al lenguaje para la ejecucin de algoritmos en pseudo-cdigo.



Requerimientos.

Redisear y evaluar la sintaxis del lenguaje para la ejecucin de algoritmos en
pseudo-cdigo.

Demostrar que la gramtica formal que describe al lenguaje para la ejecucin de
algoritmos en pseudo-cdigo es LL1 o que cuenta al menos con un nmero mnimo
de excepciones fcilmente resolubles.

Construir manualmente una aplicacin de consola capaz de compilar y ejecutar
programas escritos en el lenguaje para la ejecucin de algoritmos en pseudo-cdigo.

Realizar extensos procesos de control de calidad sobre la aplicacin que compilar y
ejecutar los programas escritos en el lenguaje para la ejecucin de algoritmos en
pseudo-cdigo.


6.2 Lmites

Se consideran los siguientes elementos como lmites del presente trabajo:

El compilador y su mquina virtual sern implementados slo en plataformas
Windows.

50
50
No se utilizar ningn tipo de aplicacin especializada en la generacin de
analizadores lexicogrficos o en la generacin de analizadores sintcticos.

No se crear ningn tipo de interfaz grfica para el compilador del lenguaje para la
ejecucin de algoritmos en pseudo-cdigo.

En relacin con lo anterior, no se solventar ninguna falla actualmente existente de
carcter grfico.

Por las mismas razones, no se efectuar ninguna mejora sobre elementos grficos
del sistema actual.
51
51
CAPTULO 7. METODOLOGA Y HERRAMIENTAS

7.1 Metodologa

Metodologa para la construccin del compilador.

La metodologa a utilizar estar estrechamente relacionada con las fases de la compilacin,
usando una metodologa basada en el ciclo del anlisis estructurado para el desarrollo de
sistemas informticos, el cual consta de un Anlisis, un Diseo y una Implementacin.
Cada fase de compilacin ser dividida en un ciclo de tres etapas que llevarn los mismos
nombres, ya que poseern caractersticas similares a los de la metodologa del anlisis
estructurado, donde al final de cada fase se realizar la documentacin respectiva. Adems,
al final de cada una de estas fases se realizar tambin un proceso de control de calidad, de
forma que puedan identificarse y corregirse errores de manera continua durante todo el
proceso de desarrollo del proyecto.

A continuacin se detalla la forma en que se desarrollar cada una de las fases de
compilacin, desde la perspectiva de los resultados que se esperan obtener al final de cada
una de ellas.

1. Anlisis Lexicogrfico.
a. Anlisis: determinacin de lexemas y expresiones regulares que describen la
lexicografa del lenguaje para la ejecucin de algoritmos en pseudo-cdigo.
b. Diseo: enfocado en el diseo del componente del compilador que se
encargara de identificar los lexemas en el cdigo y traducirlos a tokens,
llamado Scanner.
c. Implementacin y documentacin del Scanner.
d. Ciclo de pruebas de escritorio que determinen la capacidad del Scanner para
reconocer todos los elementos pertenecientes a la lexicografa del lenguaje
para la ejecucin de algoritmos en pseudo-cdigo.

52
52

2. Anlisis Sintctico.
a. Anlisis: identificacin de las reglas sintcticas y la gramtica libre de
contexto del lenguaje para la ejecucin de algoritmos en pseudo-cdigo.
b. Diseo: se trabajara con el diseo de los diagramas de sintaxis y el del
Parser, componente del compilador encargado del anlisis sintctico.
c. Implementacin y documentacin del Parser.
d. Ciclo de pruebas de escritorio que determinen la capacidad del Parser para
evaluar eficiente y correctamente la sintaxis del lenguaje para la ejecucin
de algoritmos en pseudo-cdigo.

3. Anlisis Semntico.
a. Anlisis y diseo: planteamiento de las reglas semnticas del lenguaje para
la ejecucin de algoritmos en pseudo-cdigo.
b. Implementacin y documentacin del Anlisis semntico.
c. Ciclo de pruebas de escritorio que determinen la correctitud de las
evaluaciones semnticas efectuadas durante los procesos de anlisis
sintctico.

4. Generacin de cdigo intermedio.
a. Anlisis: determinacin de las caractersticas y estructura del cdigo
intermedio a utilizar basado en el cdigo P.
b. Diseo: propuesta de incorporacin de mecanismos para la generacin de
cdigo intermedio en el cdigo del compilador.
c. Implementacin y documentacin del Cdigo Intermedio.
d. Ciclo de pruebas de escritorio que determinen la correctitud de las
traducciones efectuadas para la generacin de cdigo intermedio.

5. Construccin de la mquina virtual.
a. Anlisis: planeacin de la estructura y las caractersticas que la mquina
virtual tendr para ejecutar el cdigo intermedio generado por el compilador.
53
53
b. Diseo: tomando en cuenta lo propuesto en el anlisis, se esbozar la
arquitectura de la mquina virtual.
c. Implementacin y documentacin de la Mquina Virtual.


6. Realizacin de una batera de pruebas.
Hacia finales del proceso de desarrollo se efectuar un proceso de control de calidad
que consistir en lo siguiente:

o Registrar un servicio de horas sociales en el que un grupo de 15 a 20
personas realicen una prueba de uso del compilador en sesiones de 3 horas
diarias durante un perodo de 2 semanas.

o Para esto se les impartir a los participantes una capacitacin previa en el
uso del compilador del lenguaje para la ejecucin de algoritmos en pseudo-
cdigo y de su respectiva mquina virtual.

o El grupo de participantes estar conformado por estudiantes de 2 a 5 ao
de la carrera Licenciatura en Ciencias de la Computacin de la Universidad
Centroamericana Jos Simen Caas.

o Paralelamente se llevarn a cabo procesos de depuracin del proyecto
basados en los resultados obtenidos durante la batera de pruebas.


54
54
7.2 Herramientas

Para el desarrollo del trabajo completo se utilizar un conjunto de herramientas las cuales
variarn segn el componente del compilador que se construya. La lista de herramientas por
componente se detalla a continuacin.

Compilador y mquina virtual.

Sistema operativo.
Se utilizar Windows XP y Windows 7, debido a que la mayora de herramientas o
software utilitario se encuentran disponibles slo para estas plataformas.

IDE:
Se considera que el lenguaje C provee una interaccin ms cercana entre
programador y CPU al no tener un alto grado de abstraccin, permitiendo as un
ambiente ideal para el desarrollo de sistemas, es entonces que se opta por utilizarlo
para la construccin de estos elementos.

Se utilizar Dev-C++ como entorno para la programacin en C, debido a que es un
software libre, estable y cuenta con una amplia gama de plugins y soporte en lnea.
55
55
CAPTULO 8. REVISIN DEL LENGUAJE PARA LA APLICACIN DE
ALGORITMOS EN PSEUDO-CDIGO.

Actualmente, en la carrera Licenciatura en Ciencias de la Computacin de la Universidad
Centroamericana Jos Simen Caas, se utiliza como una herramienta de aprendizaje
para los estudiantes, un lenguaje de programacin que basa sus estructuras y palabras
claves en los caractersticas generales empleadas para la construccin de algoritmos en
pseudo-cdigo, denominado de forma genrica Lenguaje para la ejecucin de algoritmos
en pseudo-cdigo.

El Lenguaje para la ejecucin de algoritmos en pseudo-cdigo se basa especficamente en
las caractersticas empleadas para el pseudo-cdigo en el lenguaje castellano, donde han
sido aplicadas las adaptaciones necesarias que brindan al lenguaje la rigurosidad suficiente
para ser considerado un lenguaje de programacin, principalmente respecto a una
definicin estricta de su lexicografa y sintaxis, y a un establecimiento claro de su
semntica.


8.1 Lenguaje AEGOLI

Se denominar Lenguaje AEGOLI al lenguaje resultante luego de aplicar todas las
modificaciones que sean determinadas como necesarias durante el proceso de revisin del
Lenguaje para la ejecucin de algoritmos en pseudo-cdigo.


8.2 Modificaciones al Lenguaje para la ejecucin de algoritmos en pseudo-cdigo

A continuacin se listan todas las modificaciones en la estructura y sintaxis del lenguaje
para la ejecucin de algoritmos en pseudo-cdigo y para cada una de ellas se especifican las
razones para su realizacin:

56
56
Eliminacin de la declaracin previa de sub-algoritmos.
Al momento de especificar la definicin de los sub-algoritmos, se utilizar la firma
del sub-algoritmo para realizar conjuntamente su declaracin y registro en la tabla
de smbolos.

Estado anterior: antes de comenzar la definicin de sub-algoritmos (incluyendo el
sub-algoritmo principal) se deban declarar todos los sub-algoritmos para
posteriormente establecer su definicin luego de haber definido al sub-algoritmo
principal.
Justificacin:
a) Es un mecanismo ms intuitivo para principiantes de la
programacin.
b) Es un mecanismo que cuenta con poca dificultad de implementacin.


Colocacin de definicin de sub-algoritmos antes de la definicin del sub-algoritmo
principal.
Al inicio de un programa escrito en el lenguaje para la ejecucin de algoritmos en
pseudo-cdigo deben ser colocados todos los sub-algoritmos que se utilizarn para
posteriormente definir el sub-algoritmo principal. No se permitir la definicin de
sub-algoritmos despus de haber colocado la definicin del sub-algoritmo principal.

Estado anterior: antes de comenzar la definicin de sub-algoritmos (incluyendo el
sub-algoritmo principal) se deban declarar todos los sub-algoritmos para
posteriormente establecer su definicin luego de haber definido al sub-algoritmo
principal.
Justificacin:
a) Este ordenamiento brinda mayor claridad al momento de escribir o
de leer un programa escrito en el lenguaje para la ejecucin de
algoritmos en pseudo-cdigo.
57
57
b) Este ordenamiento permite implementar las validaciones sintcticas
y semnticas relacionadas con la definicin de sub-algoritmos de una
manera ms sencilla y eficiente.

Adicin de las palabras clave funcin y procedimiento para la definicin de
sub-algoritmos.
Al momento de definir un sub-algoritmo ste podr especificarse de dos maneras:
funcion <tipo> <Nombre Funcin> (<parmetros>)
comienza
<instrucciones>
retornar <valor>
termina
O bien:
procedimiento <Nombre Funcin> (<parmetros>)
comienza
<instrucciones>
termina

Estado anterior: la sintaxis para la definicin de un sub-algoritmo era una sola para
funciones y procedimientos:
[<tipo>] <Nombre Funcin> (<parmetros>)
comienza
<instrucciones>
[retornar <valor>]
Termina

Justificacin: es mucho ms claro e intuitivo para un estudiante de programacin
que los sub-algoritmos se vean diferenciados de esta manera. Adems, facilita el
aprendizaje en cuanto a las diferencias conceptuales y utilitarias entre las funciones
y los procedimientos.

58
58
Eliminacin de las sentencias ruta e incluir.
No se permitir el establecimiento de rutas en disco y de nombres de archivos para
la inclusin de libreras u otros programas escritos en pseudo-cdigo.

Estado anterior: se utilizaba la sentencia ruta para establecer una ubicacin en disco
desde la cual se incluiran archivos y luego se utilizaba la sentencia incluir para
especificar el nombre del archivo que se anexara desde la ubicacin en disco
establecida.
Justificacin: la inclusin de archivos es una herramienta que se considera
innecesaria para que los estudiantes aprendan las bases de la programacin.


Eliminacin del tipo de dato archivo.
Se elimina el tipo de dato archivo pero se mantendr la lectura de datos desde un
archivo, la cual podr ser realizada de la siguiente manera:
a. Se abre un archivo para permitir la extraccin de datos mediante la
instruccin abrirArchivo:
abrirArchivo(<nombre de archivo>)
Es importante hacer notar que no se permitir que ms de un archivo
se encuentre abierto en un momento dado.

b. Se extrae informacin del archivo mediante la instruccin
leerArchivo:
leerArchivo(<variable>)
Esta instruccin extrae el siguiente elemento del contenido del
archivo y lo almacena en la variable especificada. Los elementos a
extraer deben estar separados por espacios en blanco o cambios de
lnea el tipo de dato a extraer depender del tipo de la variable
especificada.

59
59
c. Se cierra el archivo para detener la extraccin de datos mediante la
instruccin cerrarArchivo:
cerrarArchivo()

d. Para determinar si se ha alcanzado el final de un archivo se utiliza la
funcin finalArchivo. Esta funcin se utiliza como si fuera una
variable (siempre y cuando se haya abierto algn archivo
previamente) y retorna un valor de 0 si no se ha alcanzado el final
del archivo y 1 en caso contrario. Un ejemplo de esta funcin podra
ser:
mientras(finalArchivo==0)
leerArchivo(var)
finmientras

Estado anterior: existencia del tipo de dato archivo y existencia de funciones e
instrucciones dedicadas a la lectura y escritura de informacin en archivos.
Justificacin: el tipo de dato archivo es tambin una herramienta que se considera
innecesaria para que los estudiantes aprendan las bases de la programacin; sin
embargo, es importante proveer de un mecanismo que permita facilitar el ingreso de
datos, por lo que es necesario mantener funcionalidades de lectura de archivos.


Adaptacin de indexado para las matrices a un esquema de par ordenado.
Para declarar e indexar una variable de cualquier tipo de datos que sea una matriz se
utilizar la siguiente estructura:
<variable>[<nmero entero>,<nmero entero>]

Estado anterior: la sintaxis para el uso o declaracin de un objeto matricial era la
siguiente:
<variable>[<nmero entero>][<nmero entero>]
60
60
Justificacin: para un estudiante de programacin es mucho ms intuitivo referirse a
una posicin dentro de una matriz utilizando una notacin de par ordenado, ya que
es una notacin fiel a su representacin matemtica formal.


Adicin de ndices representativos en la declaracin de parmetros para los sub-
algoritmos y adicin del carcter # como un smbolo especial del lenguaje para la
ejecucin de algoritmos en pseudo-cdigo.
La sintaxis para la declaracin de un parmetro dentro de la definicin de un sub-
algoritmo si se trata de un arreglo es la siguiente:
<tipo> <nombre> [#]

Y si se trata de una matriz es:
<tipo> <nombre> [#,#]

Estado anterior: la sintaxis para un parmetro dentro de la definicin de un sub-
algoritmo era para el caso de un arreglo:
<tipo> <nombre> []
Y para el caso de una matriz:
<tipo> <nombre> [][]
Justificacin: es mucho ms claro e intuitivo para un estudiante de programacin el
tener siempre en mente la propiedad de dimensionalidad de estructuras como los
arreglos y las matrices, as como la caracterstica de par ordenado para la
dimensionalidad de las matrices especficamente.



Adicin de envo de parmetros por valor o por referencia.
Al enviar un parmetro dentro de una llamada a un sub-algoritmo se podr colocar
de manera opcional la nueva palabra reservada ref de la siguiente manera:
<nombreSubalgoritmo>([ref] <parametro>,.)
61
61
El colocar esta palabra reservada indicar que el parmetro se enva por referencia
mientras que su ausencia indica que el parmetro se enva por valor.

Estado anterior: no exista ningn mecanismo dentro del lenguaje para la ejecucin
de algoritmos en pseudo-cdigo que permitiera establecer esta diferenciacin. Por
defecto todos los parmetros se enviaban por valor.
Justificacin: diferenciar entre envo de parmetros por referencia y envo de
parmetros por valor es un elemento importante para un estudiante de programacin
y se considera esencial asimilar este recurso desde el comienzo del aprendizaje.


Eliminacin de la funcin matemtica predefinida potenciaDiez.
Esta funcin ya no podr ser utilizada. As mismo la secuencia de caracteres
potenciaDiez ya no ser considerada una palabra clave.


Estado anterior: la funcin potenciaDiez cuya sintaxis es:
potenciaDiez(exponente)
reciba como parmetro un nmero real que se consideraba un exponente, la funcin
retornaba el valor de 10 elevado al nmero real proporcionado como parmetro.
Justificacin: lo realizado con esta funcin puede ser realizado utilizando la funcin
potencia cuya sintaxis es la siguiente:
potencia(base, exponente)
colocando en la base un valor de 10.


Adicin de funciones matemticas.
Las funciones matemticas a agregar son las siguientes:
o Una funcin que retorne el valor numrico .
o Una funcin que permita evaluar el logaritmo base 10 de un nmero real.
o Una funcin que permita evaluar el logaritmo natural de un nmero real.
62
62
o Una funcin que permita aproximar un nmero real utilizando un
mecanismo de redondeo.
o Una funcin que permite obtener el valor del nmero e elevado a alguna
potencia.

La sintaxis de estas nuevas funciones son las siguientes:
o Para la funcin que retorne el valor numrico :
pi()
o Para la funcin que permita evaluar el logaritmo base 10 de un nmero real:
log(numero)
o Una funcin que permita evaluar el logaritmo natural de un nmero real:
ln(numero)
o Para la funcin que permita aproximar un nmero real utilizando un
mecanismo de redondeo:
redondear(numero)
o Para la funcin que permita obtener el valor de e elevado a alguna potencia:
exp(numero)

Estado anterior: funciones predefinidas para realizar estas operaciones eran
inexistentes.
Justificacin: poder realizar estas operaciones ampla en gran medida el tipo de
programas que pueden ser escritos con el lenguaje para la ejecucin de algoritmos
en pseudo-cdigo, lo cual se traduce en una ventaja para los estudiantes de
programacin, ya que expande sus posibilidades creativas y mejora sus procesos de
aprendizaje.


Adicin de la funcin predefinida compararCaracteres.
Esta funcin permitir evaluar si dos caracteres son iguales o no y su sintaxis ser la
siguiente:
compararCaracteres(<caracter 1>, <caracter 2>)
63
63

En caso de que <caracter 1> y <caracter 2> sean distintos, la funcin especificar
adems si <caracter 1> es menor o mayor que <caracter 2> por medio de un criterio
de ordenacin alfabtica.

Estado anterior: una funcin que realizara este proceso no exista en el lenguaje para
la ejecucin de algoritmos en pseudo-cdigo.
Justificacin: poder realizar esta operacin tambin permite ampliar en gran medida
el tipo de programas que pueden ser escritos con el lenguaje para la ejecucin de
algoritmos en pseudo-cdigo.


Sustituir los delimitadores de la sintaxis de la instruccin para por palabras
claves.
La nueva sintaxis de la instruccin para ser la siguiente:
para <variable>=<valor 1> hasta <valor 2> paso <valor 3> hacer
<instruccin 1>
<instruccin 2>
..
<instruccin N>
finpara

De esta forma la palabra reservada hasta especificar el lmite superior de la
iteracin realizada por la instruccin, la palabra reservada paso especificar el
incremento o decremento que debe ser efectuado para realizar la iteracin, y la
palabra reservada hacer especificar el inicio de las instrucciones que conforman a
la instruccin para.

Estado anterior: la sintaxis anterior de la instruccin para era:

para <variable>=<valor 1> , <valor 2> ; <valor 3>
64
64
<instruccin 1>
<instruccin 2>
..
<instruccin N>
finpara

Justificacin:
a) La sintaxis anterior era poco intuitiva para un estudiante de
programacin.
b) Usar palabras claves como delimitadores facilita la implementacin
de las evaluaciones sintcticas de la instruccin para.


Adicin de la instruccin terminaPrograma.
Esta instruccin permitir terminar la ejecucin de un programa al momento de ser
evaluada. Un ejemplo sencillo de su uso podra ser:
si (a<10) entonces
escribirln(Este mensaje se imprime en consola)
sino
terminaPrograma
escribirln(Este mensaje no se imprime en consola)
finsi

Estado anterior: una instruccin que realizara esta funcionalidad no exista en el
lenguaje para la ejecucin de algoritmos en pseudo-cdigo.
Justificacin: poder realizar esta operacin permite evitar realizar operaciones
innecesarias y ahorrar recursos de la computadora al abortar el proceso de ejecucin
de un programa en un momento adecuado.

65
65

8.3 Definicin de la gramtica libre de contexto que genera al Lenguaje AEGOLI

La gramtica libre de contexto que genera al lenguaje AEGOLI se presenta a continuacin
descrita en notacin EBNF (Extended Backus Naus Form):



Algoritmo =
"algoritmo" identificador "inicio" Cuerpo "fin".

Cuerpo =
{Declaracion_Variable}{Subalgoritmo} "principal" "(" ")" Bloque.

Declaracion_Variable =
Tipo identificador ["[" entero ["," entero] "]"] {"," identificador ["[" entero ["," entero]"]"]}.

Tipo =
"cadena"|"caracter"|"entero"|"real".

Subalgoritmo =
Firma_Subalgoritmo Bloque.

Firma_Subalgoritmo =
("procedimiento" | "funcion" Tipo) identificador "(" [Parametro {"," Parametro}] ")".

Parametro =
Tipo identificador ["[" "#" ["," "#"] "]"].


Bloque =
"comienza" {Declaracion_Variable} Instruccion "termina".

Instruccion =
{Llamada_Subalgoritmo | Asignacion | Instruccion_Si| Instruccion_Hacer |
Instruccion_Mientras|Instruccion_Repetir | Instruccion_Para | Instruccion_E/S |
"terminaPrograma" | retornar" Expresion}.

66
66
Instruccin_E/S =
Instruccion_Leer| Instruccion_Escribir | Instruccion_Escribirln |
Instruccion_AbrirArchivo| Instruccion_LeerArchivo | Instruccion_CerrarArchivo.

Variable =
Identificador["[" Expresion_Numerica ["," Expresion_Numerica] "]"].


Llamada_Subalgoritmo =
identificador "(" [(["ref"] Variable | Expresion) {"," (["ref"] Variable | Expresion)}] ")".

Asignacion =
Variable "=" Expresion.

Instruccion_Si =
"si" "(" Expresion_Numerica ")" "entonces" Instruccion ["sino" Instruccion] "finsi".

Instruccion_Hacer =
"hacer" Instruccion "mientrasque" "(" Expresion_Numerica ")".

Instruccion_Mientras =
"mientras" "(" Expresion_Numerica ")" Instruccion "finmientras".

Instruccion_Repetir =
"repetir" Instruccion "hasta" "(" Expresion_Numerica ")".

Instruccion_Para =
"para" Variable "=" Expresion_Numerica "hasta" Expresion_Numerica
"paso" Expresion_Numerica "hacer" Instruccion "finpara".

Instruccion_Leer =
"leer" "(" Variable {"," Variable} ")".

Instruccion_Escribir =
"escribir" "(" Expresion {"," Expresion} ")".

Instruccion_Escribirln =
"escribirln" "(" Expresion {"," Expresion} ")".
67
67

Instruccion_AbrirArchivo =
"abrirArchivo" "(" Dato_Cadena ")".

Instruccion_LeerArchivo =
"leerArchivo" "(" Variable ")".

Instruccion_CerrarArchivo =
"cerrarArchivo" "(" ")".

Expresion =
Dato_Caracter | Dato_Cadena | Expresion_Numerica.

Expresion_Numerica =
Expresion_Conjuncion {"|" Expresion_Conjuncion}.

Expresion_Conjuncion =
Expresion_Relacional {"&" Expresion_Relacional}.

Expresion_Relacional =
["!"] Expresion_Aritmetica ["<"|">"|"<="|">="|"=="|"!=" Expresion_Aritmetica].

Expresion_Numerica =
Termino {"+"|"-" Termino}.

Termino =
Factor {"*"|"/" Factor}.

Factor =
["+"|"-"] (entero | real | Variable | Llamada_Subalgoritmo | Funcion_Numerica|
Funcion_Numerica_Cadena_Caracter | "(" Expresion_Numerica ")").

Funcion_Numerica =
("tangente" |"seno" |"coseno" |"arctan"| "arcsen"| "arccos"|
"truncar"| "absoluto" | "raiz" | "redondear"| log"| "ln" | "exp"
"(" Expresion_Numerica ")") | ("pi" "(" ")") | "finalArchivo" |
(("mod" | "potencia" | "div") "(" Expresion_Numerica "," Expresion_Numerica ")").

68
68
Funcion_Cadena =
("concatenar" "(" Dato_Cadena "," Dato_Cadena ")") | ("extraerCadena"
"(" Dato_Cadena "," Expresion_Numerica "," Expresion_Numerica ")")|
("cadenaMayusculas" "(" Dato_Cadena ")")| ("cadenaMinusculas"
"(" Dato_Cadena ")").

Funcion_Numerica_Cadena_Caracter =
("compararCadenas" "(" Dato_Cadena "," Dato_Cadena ")")| ("buscarCadena"
"(" Dato_Cadena "," Dato_Cadena ")")| ("longitudCadena" "(" Dato_Cadena ")") |
("compararCaracteres" "(" Dato_Caracter "," Dato_Caracter ")").

Dato_Caracter =
caracter | Variable | Llamada_Subalgoritmo.

Dato_Cadena =
cadena | Variable | Llamada_Subalgoritmo | Funcion_Cadena.



8.4 Evaluacin de la gramtica libre de contexto que genera al Lenguaje AEGOLI

A continuacin se presenta las evaluaciones matemticas utilizadas para comprobar si la
gramtica que genera al Lenguaje AEGOLI es LL1:


1. En la produccin Instruccion.

Prim(Llamada_Subalgoritmo) = {identificador}
Prim(Asignacion) = {identificador}
Prim(Instruccion_Si) = {si}
Prim(Instruccion_Hacer) = {hacer}
Prim(Instruccion_Mientras) = { mientras }
Prim(Instruccion_Repetir) = { repetir }
Prim(Instruccion_Para) = { para }
Prim(Instrucciones_E/S) = { leer ,escribir ,escribirln , abrirArchivo, leerArchivo, cerrarArchivo}

Siendo A = "terminaPrograma" | retornar Expresion.
69
69
Prim(A)= {terminaPrograma,retornar}
Luego,
Prim(Llamada_Subalgoritmo) Prim(Asignacion Prim(Instruccion_Si) Prim(Instruccion_Hacer)
Prim(Instruccion_Mientras) Prim(Instruccion_Repetir) Prim(Instruccion_Para)
Prim(Instrucciones_E/S) Prim(A) =

Pero:
Prim(Llamada_Subalgoritmo) Prim(Asignacion) = {identificador}

Por tanto, la gramtica no cumple con ser LL1 en la produccin Instruccion.


2. En la produccin Expresion.


Prim(Dato_Cadena)
= {caracter} U Prim(Variable) U Prim(Llamada_Subalgoritmo)
= {carcter, identificador}
Prim(Dato_Cadena)
= {cadena} U Prim(Variable) U Prim(Llamada_Subalgoritmo) U Prim(Funcion_Cadena)
= {cadena, identificador, concatenar, extraerCadena, cadenaMayusculas, cadenaMinusculas }

Prim(Expresion_Numerica)
= Prim(Expresion_Conjuncion)
= Prim(Expresion_Relacional)
= {negacion} U Prim(Expresion_Aritmetica)
= {negacion } U Prim(Termino)
= {negacion } U Prim(Factor)
= {mas, menos, ,negacin, entero, real, (} U Prim(Variable) U Prim(Llamada_Subalgoritmo)
U Prim(Funcion_Numerica) U Prim(Funcion_Numerica_Cadena_Caracter)
= { mas, menos , negacin, entero, real, (, identificador, tangente, seno, coseno, arctan , arcsen,
arccos, truncar, absoluto, raz, redondear, log, ln, pi ,finalArchivo, exp, mod, potencia, div,
compararCadenas, compararCaracteres, buscarCadena, longitudCadena}

Luego,
Prim(Dato_Caracter) Prim(Dato_Cadena) Prim(Expresion_Numerica) = {identificador}

Por tanto, la gramtica no cumple con ser LL1 en la produccin Expresion.
70
70
3. En la produccin Factor


Prim(()= {(}
Prim(entero)= {entero}
Prim(real) = {real}
Prim(Variable) = {identificador}
Prim(Llamada_Subalgoritmo)= {identificador}
Prim(Funcion_Numerica)
= {tangente, seno, coseno, arctan , arcsen, arccos, truncar, absoluto, raz, redondear, log, ln, pi,
finalArchivo, exp, mod, potencia, div}
Prim(Funcion_Numerica_Cadena_Caracter)
= {compararCadenas, compararCaracteres, buscarCadena, longitudCadena}

Luego,
Prim(entero) Prim(real) Prim(Funcion_Numerica) Prim(Variable) Prim(Llamada_Subalgoritmo)
Prim(Funcion_Numerica_Cadena_Caracter) =

Pero:
Prim(Variable) Prim(Llamada_Subalgoritmo) = {identificador}

Por tanto, la gramtica no cumple con ser LL1 en la produccin Factor.



4. En la produccin Dato_Caracter


Prim(caracter)= { caracter }
Prim(Variable) = {identificador}
Prim(Llamada_Subalgoritmo)= {identificador}

Luego,
Prim(caracter) Prim(Variable) Prim(Llamada_Subalgoritmo) =

Pero:
Prim(Variable) Prim(Llamada_Subalgoritmo) = {identificador}

Por tanto, la gramtica no cumple con ser LL1 en la produccin Dato_Caracter.
71
71
5. En la produccin Dato_Cadena


Prim(cadena)= { cadena }
Prim(Variable) = {identificador}
Prim(Llamada_Subalgoritmo)= {identificador}
Prim(Funcion_Cadena)
= {concatenar, extraerCadena, cadenaMayusculas, cadenaMinusculas}
Luego,
Prim(cadena) Prim(Variable) Prim(Llamada_Subalgoritmo) Prim(Funcion_Cadena) =

Pero:
Prim(Variable) Prim(Llamada_Subalgoritmo) = {identificador}

Por tanto, la gramtica no cumple con ser LL1 en la produccin Dato_Cadena.

La construccin de un analizador sintctico descendente para la gramtica que genera al
Lenguaje AEGOLI, necesita solucionar las producciones en donde la gramtica no cumple
con ser LL1. La forma como se corregir este problema para la gramtica presentada ser
aadiendo reglas semnticas para las producciones de Instruccion, Expresin, Factor,
Dato_Caracter y Dato_Cadena.



8.5 Reglas semnticas por produccin para el Lenguaje AEGOLI

1. En la produccin Declaracion_Variable.
No redefinicin de objetos.
El smbolo terminal entero 1.

2. En la produccin Subalgoritmo.
Si se trata de un subalgoritmo de tipo funcin entonces en Bloque deber existir una
instruccin retornar.

72
72

3. En la produccin Firma_Subalgoritmo y Parametro.
No redefinicin de objetos.

4. En la produccin Bloque.
Si el bloque pertenece a un subalgoritmo de tipo funcin debe existir al menos un
retornar con su respectiva expresin.
Si el bloque pertenece a un subalgoritmo de tipo procedimiento no puede existir un
retornar antes de la palabra clave termina.

5. En la produccin Instruccion.
Si se encuentra un identificador, verificar si es un procedimiento o una variable,
para decidir si se trata de una llamada a un procedimiento o una asignacin a una
variable.
Para la instruccin retornar no se permitir devolver una variable que sea arreglo o
matriz, mientras que si se permitir devolver alguna posicin dentro de este tipo de
estructuras.

6. En la produccin Variable.
Verificar si el identificador se encuentra declarado como variable.
Si un identificador fue declarado como una variable de tipo matriz entonces el
acceso a un valor debe estar especificado con un esquema de par ordenado, de la
forma: [numero, numero]; si fue declarado de tipo arreglo entonces comprobar que
el acceso a un valor se especifica con un nmero entre corchetes: [numero].
La nica excepcin a esta regla es en el caso de una llamada a un subalgoritmo
cuando el identificador est siendo enviado como parmetro de manera individual
(sin formar parte de una expresin).
En caso de ser un arreglo o una matriz comprobar que el valor de
Expresin_Numerica se encuentre dentro de los lmites definidos en la declaracin
del arreglo (Validacin realizada en tiempo de ejecucin).

73
73
7. En la produccin Llamada_Subalgoritmo.
Verificar si el identificador se encuentra declarado como un subalgoritmo.
Verificar que la cantidad de parmetros del subalgoritmo sea igual a la definida en
su declaracin
Verificar que el valor de los parmetros correspondan al tipo con el que fueron
declarados.
(Validacin realizada en tiempo de ejecucin).

8. En la produccin Asignacion.
Luego de evaluar Expresin comprobar que exista una compatibilidad de tipos
(Validacin realizada en tiempo de ejecucin).

9. En la produccin Instruccion_Para.
Variable debe ser un variable entera.
El valor de Expresion_Numerica debe ser un entero o al menos que exista
compatibilidad de tipos.
(Validacin realizada en tiempo de ejecucin).
Para
Limite1: Valor de la primera aparicin de Expresion_Numerica.
Limite2: Valor de la segunda aparicin de Expresion_Numerica.
Paso: Valor de la tercera aparicin de Expresion_Numerica.

Se debe cumplir una de las siguientes dos reglas:
a) Si Limite1 < Limite2 entonces Paso > 0.
b) Si Limite1 > Limite2 entonces Paso < 0.

(Validacin realizada en tiempo de ejecucin)

10. En la produccin Instruccin_LeerArchivo:
No se permitir el uso de esta instruccin si no se ha abierto previamente algn
archivo con la instruccin abrirArchivo.
74
74
11. En la produccin Instruccin_CerrarArchivo:
No se permitir el uso de esta instruccin si no se ha abierto previamente algn
archivo con la instruccin abrirArchivo.

12. En la produccin Expresion.
Si se encuentra un identificador la compilacin seguir si se cumple lo siguiente:
a) Si el identificador es una variable entera o real entonces seguir por el
camino de Expresin_Numerica.
b) Si el identificador es una funcin que retorna un valor entero o real
entonces seguir por el camino de Expresin_Numerica.
c) Si el identificador es una variable de tipo carcter o una funcin que
retorna un valor de tipo carcter entonces seguir por el camino de
Dato_Caracter.
d) Si el identificador es una variable de tipo cadena o una funcin que retorna
un valor de tipo cadena entonces seguir por el camino de Dato_Cadena.
e) Si el identificador es cualquier otra cosa entonces se emitir un error.

13. En la produccin Factor.
Si se encuentra un identificador la compilacin seguir si se cumple lo siguiente:
a) Si el identificador es una variable entera o real entonces seguir por el
camino de Variable.
b) Si el identificador es una funcin que retorna un valor entero o real
entonces seguir por el camino de Llamada_Subalgoritmo.
c) Si el identificador es cualquier otra cosa entonces se emitir un error.

14. En la produccin Funcion_Numerica.
(Validaciones realizadas en tiempo de ejecucin)
Si es la funcin tangente entonces el valor de Expresion_Numerica no tiene ser
igual a 90 ni igual a 270.
Si es la funcin raiz entonces el valor de Expresion_Numerica tiene que ser mayor o
igual a cero.
75
75
Si es la funcin ln o log entonces el valor de Expresion_Numerica tiene que ser
mayor que cero.
Si es la funcin mod o div entonces el valor de ambas apariciones de
Expresion_Numerica deben ser nmeros enteros.
Si la funcin es finalArchivo, no se permitir su uso si no se ha abierto algn
archivo de texto previamente con la instruccin abrirArchivo.

15. En la produccin Funcion_Cadena.
(Validacin realizada en tiempo de ejecucin)
Si es la funcin extraerCadena entonces el valor de ambas apariciones de
Expresion_Numerica deben ser nmeros enteros, adems de cumplir con ser ndices
vlidos para la cadena fuente (0 Exp_Num < longitud(cadena)) y que el valor de
la segunda Expresion_Numerica sea mayor que la primera.

16. En la produccin Dato_Caracter.
Si se encuentra un identificador la compilacin seguir si se cumple lo siguiente:
a) Si el identificador es una variable de tipo caracter entonces seguir por el
camino de Variable.
b) Si el identificador es una funcin que retorna un carcter entonces seguir
por el camino de Llamada_Subalgoritmo.
c) Si el identificador es cualquier otra cosa entonces se emitir un error.

17. En la produccin Dato_Cadena.
Si se encuentra un identificador la compilacin seguir si se cumple lo siguiente:
a) Si el identificador es una variable de tipo cadena entonces seguir por el
camino de Variable.
b) Si el identificador es una funcin que retorna una cadena entonces seguir
por el camino de Llamada_Subalgoritmo.
c) Si el identificador es cualquier otra cosa entonces se emitir un error.


77
CAPTULO 9. DISEO DEL COMPILADOR PARA EL LENGUAJE AEGOLI

9.1 Analizador lexicogrfico.

9.1.1 Estrategia de lectura del archivo fuente

Definicin de elementos a utilizar para el proceso de lectura del archivo fuente.

Se ha determinado que para la lectura del archivo fuente que contiene el programa escrito
en el lenguaje AEGOLI se utilizar una tcnica de buffering con un buffer de entrada. La
estrategia de aplicacin de esta tcnica contar con los siguientes elementos:

Una funcin encargada de la extraccin de caracteres lnea por lnea desde el
archivo fuente que contiene el programa escrito en el lenguaje AEGOLI para su
almacenamiento en el buffer de entrada.
Esta funcin ser invocada cada vez que se determine que el buffer de entrada de
datos ha sido vaciado.

Una funcin encargada de la extraccin uno a uno de los caracteres almacenados en
el buffer de entrada.
Esta funcin ser invocada continuamente durante el proceso de anlisis
lexicogrfico del archivo fuente, de forma que, por medio de los caracteres
extrados se vayan formando los tokens que se utilizarn en el anlisis sintctico.


9.1.2 Expresiones regulares del lenguaje AEGOLI


i. Identificadores


identificador = letra(letra+digito+simbolo)*


78
Donde,
letra = {a, b,, , , z, A, B, ,, ..., Z, , , , , } y
digito={0,1,2,,9}
simbolo={ _ } (guin bajo)

ii. Nmeros enteros

entero = digito(digito)*
digito={0,1,2,3,4,5,6,7,8,9}


iii. Nmeros reales

real = entero.entero



iv. Cadena

cadena = (letra+digito+simbolo)*
Donde,
letra = {a, b,, ,, z, A, B, ,, ..., Z, , , , , }
digito={0,1,2,,9}
simbolo={x / x es cualquier carcter imprimible distinto de letra, dgito o }


v. Carcter

caracter = (letra+digito+simbolo)
Donde,
letra = {a, b,, ,, z, A, B, ,, ..., Z, , , , , }
digito={0,1,2,,9}
simbolo={x / x es cualquier carcter imprimible distinto de letra, dgito o }




79
9.1.3 Estrategia de utilizacin de tokens

Uno de los objetivos principales del compilador, en la lectura del archivo fuente, es poder
identificar dentro de l todos los tokens definidos para el lenguaje AEGOLI. Los tokens de
un lenguaje son precisamente los significados que se le otorgan a los lexemas que lo
conforman. Dichos lexemas son secuencias de caracteres en el cdigo fuente que definen
las palabras reservadas, operadores y smbolos que tienen un significado especial para
cierto lenguaje de programacin.

Las palabras reservadas del lenguaje AEGOLI pueden verse en la Tabla A-9 del Anexo A y
la definicin de sus respectivos lexemas en el cdigo fuente del compilador se colocarn
dentro de un arreglo de caracteres, este arreglo se denominar lexpal y tendr una longitud
igual al total de palabras reservadas con las que cuenta el lenguaje.

La definicin de dicho arreglo se muestra a continuacin:
char
*lexpal[MAXPAL]={"abrirArchivo","absoluto","algoritmo",
"arccos","arcsen","arctan","buscarCadena","cadena",
"cadenaMayusculas", cadenaMinusculas","caracter",
"cerrarArchivo","comienza",compararCadenas",
"compararCaracteres","concatenar",coseno","div",
"entero","entonces","escribir","escribirln","exp",
"extraerCadena","fin","finalArchivo","finmientras",
"finpara",finsi","funcion","hacer","hasta","inicio",
"leer","leerArchivo","ln","log","longitudCadena",
"mientras","mientrasque","mod","para","paso","pi",
"potencia","principal","procedimiento","raiz","real",
"redondear","ref","repetir","retornar",seno","si",
"sino","tangente","termina","terminaPrograma",
"truncar"};



80
Una vez definidas los lexemas de las palabras reservadas, se utiliza un tipo de dato especial
para representar la lista de todos sus tokens. Esta lista ser representada por medio de una
enumeracin denominada simbolo.
Dicha enumeracin ser definida en el cdigo fuente de la siguiente manera:

enum simbolo {nulo,abrirArchivoTok,absolutoTok,algoritmoTok,
arccosTok,arcsenTok,arctanTok,buscarCadenaTok,cadenaTok,
cadenaMayusculasTok,cadenaMinusculasTok,caracterTok,
cerrarArchivoTok,comienzaTok,compararCadenasTok,
compararCaracteresTok,concatenarTok,cosenoTok,divTok,
enteroTok,entoncesTok,escribirTok,escribirlnTok,expTok,
extraerCadenaTok,finTok,finalArchivoTok,finmientrasTok,
finparaTok,finsiTok,funcionTok,hacerTok,hastaTok,
inicioTok,leerTok,leerArchivoTok,lnTok,logTok,
longitudCadenaTok,mientrasTok,mientrasqueTok,modTok,
paraTok,pasoTok,piTok,potenciaTok,principalTok,
procedimientoTok,raizTok,realTok,redondearTok,refTok,
repetirTok,retornarTok,senoTok,siTok,sinoTok,
tangenteTok,terminaTok,terminaProgramaTok,truncarTok,
mas,menos,por,barra,menor,menoroigual,mayor,mayoroigual,igual,diferente,
conjuncion,disyuncion,negacion,asignador,coma,parena,parenc,punto,entero,real,
identificador,cadena,caracter,puntoycoma,corchea,
corchec,numeral};

Luego de definir la enumeracin simbolo, se declara la variable token que podr tomar
cualquier valor que se encuentre dentro de dicha enumeracin. A continuacin se puede
apreciar la declaracin de la variable token:

enum simbolo token;

Para que el compilador pueda diferenciar las palabras reservadas con respecto a los
smbolos y operadores especiales del lenguaje, se utilizar la enumeracin simbolo para
declarar un arreglo nombrado tokpal que tendr una longitud igual al total de palabras

81
reservadas del lenguaje y que se inicializar con los tokens correspondientes a dichas
palabras.


A continuacin se presenta la definicin de este arreglo:


enum simbolo tokpal[MAXPAL]={abrirArchivoTok,absolutoTok,
algoritmoTok,arccosTok,arcsenTok,arctanTok,
buscarCadenaTok,cadenaTok,cadenaMayusculasTok,
cadenaMinusculasTok,caracterTok,cerrarArchivoTok,
comienzaTok,compararCadenasTok,compararCaracteresTok,
concatenarTok,cosenoTok,divTok,enteroTok,entoncesTok,
escribirTok,escribirlnTok,expTok,extraerCadenaTok,
finTok,finalArchivoTok,finmientrasTok,finparaTok,
finsiTok,funcionTok,hacerTok,hastaTok,inicioTok,leerTok,leerArchivoTok,lnTok,
logTok,longitudCadenaTok,mientrasTok,mientrasqueTok,modTok,paraTok,
pasoTok,piTok,potenciaTok,principalTok,procedimientoTok,raizTok,realTok,
redondearTok,refTok,repetirTok,retornarTok,
senoTok,siTok,sinoTok,tangenteTok,terminaTok,
terminaProgramaTok,truncarTok};


Es muy importante tener en cuenta que el orden de los tokens en tokpal, debe corresponder
perfectamente con el orden de los lexemas con los que se inicializ el arreglo lexpal. Esto
se debe a que la estrategia que se pretende implementar utiliza el mismo ndice de lexpal en
tokpal para hacer una asignacin a token, como se ver posteriormente.






82
9.1.4 Cmo se obtienen los identificadores, nmeros, cadenas y caracteres

La estrategia de obtencin de tokens, que se implementa en el scanner, se basa en
autmatas finitos determinsticos (DFAs-por sus siglas en ingls), dado que son utilizados
para reconocer expresiones regulares.

DFA utilizado para reconocer un identificador o una palabra reservada en el scanner

q0 q1 q2
letra, dgito y "_"
letra
otro, dgito y "_"
otro


Figura 12. DFA para identificadores y palabras reservadas.


q
0
: Estado inicial.
q
1
: Estado de aceptacin de un identificador.
q
2
: Estado de rechazo.



DFA utilizado para reconocer un nmero entero o un nmero real.









Figura 13. DFA para nmeros enteros y reales.
q0 q1
dgito
dgito
otro
punto
q3
otro
dgito
q2
otro

83
q
0
: Estado inicial.
q
1
: Estado de aceptacin de un nmero entero.
q
2
: Estado de aceptacin de un nmero real.
q
3
: Estado de rechazo.



DFA utilizado para reconocer una cadena.
q0
letra, dgito
y smbolo
comilla
doble
letra, dgito y
smbolo
q3 q2 q1
letra, dgito y
smbolo
comilla
doble


Figura 14. DFA para cadenas.

q
0
: Estado inicial.
q
1
: Estado de rechazo.
q
2
: Estado de aceptacin de una cadena.
q
3
: Estado de rechazo.



DFA utilizado para reconocer un carcter.

q0
letra, dgito
y smbolo
comilla
simple
letra, dgito y
smbolo
q1
letra, dgito y
smbolo
comilla
simple
q3 q2 q4
letra, dgito y
smbolo



Figura 15. DFA para caracteres.

84
q
0
: Estado inicial.
q
1
: Estado de rechazo.
q
2
: Estado de rechazo.
q
3
: Estado de aceptacin de un carcter.
q
4
: Estado de rechazo.



9.1.5 Clasificacin de operadores y smbolos especiales.


Los operadores sern clasificados en dos tipos diferentes: los operadores dobles
(compuestos por dos smbolos) y los operadores simples y smbolos especiales.

a) Operadores dobles. Son los operadores de mayor o igual (>=), menor o igual (<=),
el de igualdad (= =) y el diferente.


b) Operadores simples. Son los operadores asignador (=), suma (+), resta (-),
multiplicacin (*), divisin (/), mayor que (>), menor que (<), conjuncin (&) y
disyuncin (|).

Los smbolos especiales que se permiten son: numeral (#), parntesis de apertura y de
cierre, punto y coma, corchete de apertura y de cierre.


9.2 Analizador sintctico

9.2.1 Construccin de analizador sintctico descendente: Aplicacin de reglas R y R.



Reglas
R
Reglas
R'
G
(Gramtica independiente
del contexto)
Representacin grfica,
Diagrama de sintaxis (DS)
Algoritmo resultante:
Parser descendente para
G
G
(Gramtica independiente
del contexto y LL1)



Figura 16. Diagrama para la construccin de analizador sintctico descendente.

85
La construccin de un analizador sintctico descendente parte de una gramtica
independiente del contexto, la cual cumple con ser una gramtica LL1, pasando por un
diagrama de sintaxis y resultando en un algoritmo, quin es al final implementado en
cdigo.

Un ejemplo sencillo de cmo esto se realiz tomando como referencia la produccin
Cuerpo se muestra a continuacin:

Dada la produccin:

Cuerpo =
{Declaracion_Variable} {Subalgoritmo} "principal" "(" ")" Bloque.


Aplicando las reglas R, para obtener su respectivo diagrama de sintaxis:



Figura 17. Diagrama de sintaxis para la produccin Cuerpo.


Y para finalizar se aplican las reglas R con lo que se obtiene un algoritmo, el cual se
muestra a continuacin implementado en lenguaje C:

void cuerpo(){
while(token == caracterTok || token == cadenaTok ||
token == enteroTok || token == realTok){
declaracionVariable();

86
}
while(token == procedimientoTok || token == funcionTok){
subalgoritmo();
}
if (token == principalTok){
obtoken();
if(token == parena){
obtoken();
if (token == parenc){
obtoken();
bloque();
}else error(11);
}else error(12);
}else error(48);
}



9.2.2 Presentacin de los errores generados durante el proceso de compilacin

Definicin de la estrategia a seguir para la presentacin de los errores.

Con el objetivo de simplificar este proceso de presentacin de errores en tiempo de
compilacin al usuario, se ha optado por una estrategia cuyos dos elementos constituyentes
son:

Un archivo .h que contenga un arreglo de cadenas, donde cada una de estas cadenas
corresponda a un posible error generado durante el proceso de compilacin de un
programa escrito en el lenguaje AEGOLI.

Una funcin encargada de mostrar el error generado y que utilice el arreglo de
cadenas presente en el archivo .h en base a un nmero que corresponder a la
posicin en dicho arreglo que contiene el error que se desea mostrar.

87

Entonces, cuando sea necesario comunicarle un error al usuario, ser suficiente invocar a la
funcin correspondiente envindole como parmetro un nmero entero correspondiente a la
posicin del arreglo que se desea mostrar, simplificando as este proceso y tornndolo a la
vez ms prctico y de fcil mantenimiento.


9.2.3 Definicin de la tabla de smbolos

Definicin de elementos a almacenar en la tabla de smbolos.

Antes de definir la estructura de la tabla de smbolos que ser utilizada por las distintas
fases del compilador, es necesario definir y tener claro cules son los elementos que se
desean almacenar dentro de ella.

En base a la sintaxis del lenguaje AEGOLI (Ver Anexo A), se han identificado los
siguientes elementos como necesarios de almacenamiento:

El nombre del algoritmo para un archivo determinado que contenga un programa
escrito en el lenguaje AEGOLI.

Los distintos subalgoritmos que podran ser definidos para un algoritmo dentro de
un programa escrito en el lenguaje AEGOLI.

Los parmetros de los subalgoritmos definidos dentro de un programa escrito en el
lenguaje AEGOLI. Los cuales se utilizarn como variables dentro del mbito del
subalgoritmo al que pertenecen.

Las variables definidas y utilizadas, tanto para el algoritmo de un programa escrito
en el lenguaje AEGOLI como para todos sus subalgoritmos definidos.


88
En resumen, puede decirse que dentro de la tabla de smbolos del compilador se
almacenarn al menos cuatro tipo de objetos diferentes: algoritmos, subalgoritmos,
parmetros y variables.


Definicin de informacin necesaria para los objetos a almacenar en la tabla de
smbolos.

Como segundo paso es necesario definir para cada tipo de objeto que ser almacenado en la
tabla de smbolos la informacin que es necesaria para su manipulacin, identificacin y
ordenamiento.

A continuacin se presentan los datos que sern almacenados para cada objeto definido:

Para el caso de los algoritmos se necesita conocer:
Nombre del algoritmo.

Para el caso de los subalgoritmos se necesita conocer:
Nombre del subalgoritmo.
Si se trata de una funcin o un procedimiento.
Tipo de dato a retornar por el subalgoritmo si se trata de una funcin.
Cantidad, tipo y estructura de los parmetros.

Para el caso de los parmetros se necesita conocer:
Nombre del parmetro.
Tipo de dato del parmetro.
Si se trata de un arreglo o una matriz.

Para el caso de las variables se necesita conocer:
Nombre de la variable.
Tipo de dato de la variable.

89
Si se trata de un arreglo o una matriz.
Su longitud (en caso de ser un arreglo o una matriz).
Su anchura (en caso de ser una matriz).
mbito al que pertenece y su ubicacin dentro de ste.

Es necesario mencionar, para el caso de las variables, un caso particular muy importante: la
instruccin para. sta instruccin cuenta con una consideracin semntica que no se
encuentra en ninguna otra estructura ni elemento del lenguaje AEGOLI: la variable que se
encuentre en uso para la realizacin de la iteracin del para no debe poder ser alterada en el
interior de dicha instruccin. Por lo tanto, es necesario conocer si una variable se encuentra
en uso por una instruccin para de forma que se pueda hacer cumplir esta regla semntica.


Definicin de campos de la tabla de smbolos.

En base a lo expuesto en la seccin anterior, se determin que la tabla de smbolos contar
con los siguientes campos:
Nombre del objeto (necesario para todos los tipos de objeto que se almacenarn).

Tipo del objeto (si se trata de un algoritmo, un subalgoritmo, un parmetro o una
variable).

Subtipo del objeto (si se trata de una funcin o un procedimiento para el caso de los
subalgoritmos, o si se trata de un arreglo o una matriz para el caso de los parmetros
y las variables).

Tipo de dato del objeto (para los objetos que necesiten un tipo de dato como es el
caso de los parmetros, las funciones y las variables).

Longitud de un arreglo o un matriz (para las variables que sean cualquiera de estos
tipos de estructura).


90
Anchura de una matriz (para las variables que lo sean).

Cantidad de parmetros (para el caso de los subalgoritmos).

Valor booleano que indique utilizacin dentro de una instruccin para (necesario
tambin en el caso de las variables).

Nivel del objeto que indique el mbito para una variable (si se trata de una variable
local o global).

Direccin del objeto dentro del mbito al que pertenece (utilizado exclusivamente
por variables).

La lista de parmetros que el objeto posee (para el caso de los subalgoritmos).


Es necesario mencionar que, aunque para cada registro existirn todos estos campos, slo
sern utilizados los que correspondan al tipo de objeto del registro, y que las funciones que
se construyan para la manipulacin de la tabla de smbolos contarn con estas
consideraciones.


Definicin del tipo de estructura para la tabla de smbolos

En base a la poca complejidad que presenta el lenguaje AEGOLI, y en vista que se desea
implementar un cdigo legible y fcil de interpretar, se opt por disear una tabla de
smbolos cuyo diseo, organizacin y sistema de acceso sean de tipo lineal.

Adems, para optimizar un poco la agilidad y eficiencia en el uso de la tabla de smbolos,
dicha organizacin lineal ser implementada en el lenguaje C mediante una lista
doblemente enlazada sin nodo de control.


91
A pesar que la lista no contar con un nodo de control, el primer registro del arreglo ser de
carcter reservado y ser utilizado para las funcionalidades de bsqueda dentro de la tabla
de smbolos (esto se explicar con mayor detalle ms adelante).


9.2.4 Estrategia de manipulacin de la tabla de smbolos

Definicin de elementos necesarios para el almacenamiento, extraccin y
eliminacin de elementos en la tabla de smbolos.

Para poder contar con un nivel aceptable de eficiencia en el uso de la tabla de smbolos se
han considerado como necesarios los siguientes elementos:

Un apuntador al primer registro de la tabla de smbolos de forma que se puede
utilizar como frontera en los procesos de evaluacin y de bsqueda.

Un apuntador al ltimo registro aadido a la tabla de smbolos de forma que se
pueda contar con su informacin mientras su proceso de evaluacin permanezca
activo.

Una funcin encargada de reservar en memoria el espacio necesario para un registro
de la tabla de smbolos y que utilice dicho espacio para poder crear un registro
vaco.

Una funcin encargada de aadir un registro a la tabla de smbolos y de colocar en
todos sus campos los datos correspondientes que se consideren necesarios.

Una funcin encargada de buscar dentro de la tabla de smbolos algn registro
determinado utilizando como llave de bsqueda el nombre del objeto almacenado.

Una funcin encargada de eliminar registro por registro el contenido de la tabla de
smbolos de forma que se pueda liberar todo el espacio en memoria utilizado al
momento de terminar el proceso de compilacin.

92

Se presenta una pequea problemtica dentro de la estrategia de bsqueda de un elemento
dentro de la tabla de smbolos en relacin al caso que el objeto que se busca no se encuentre
almacenado dentro de ella. Esto se soluciona de una manera sencilla al utilizar la primera
posicin de la tabla de smbolos de manera reservada aplicando el siguiente procedimiento
al momento de realizar una bsqueda:

i. Se copia el elemento a buscar en la primera posicin de la lista.
ii. Se ubica el apuntador de bsqueda al final de lista.
iii. Se compara el elemento a buscar con el objeto almacenado en posicin en la lista
indicada por el apuntador de bsqueda.
iv. En caso de ser iguales irse al paso vii.
v. En caso de ser diferentes se retrocede una posicin el apuntador de bsqueda.
vi. Volver al paso ii.
vii. Retornar el valor del apuntador de bsqueda.

De esta forma, el elemento que se busca siempre ser encontrado dentro de la tabla de
smbolos, y la evaluacin a efectuar consiste en determinar si el valor devuelto por la
funcin corresponde a la primera posicin en la tabla de smbolos, de ser as el objeto no se
encuentra registrado y en caso contrario el objeto habr experimentado un registro exitoso.


Definicin de uso de los elementos necesarios para la manipulacin de la tabla de
smbolos.

Para el caso de los apuntadores denominados tabla e it no es necesario establecer
contextos o requisitos para su uso, por ser simplemente variables sern utilizadas en
cualquier situacin donde se considere necesario.

Para el caso de la funcin crearRegistro se ha definido que su utilizacin ser
exclusivamente para dos momentos: al inicio del proceso de compilacin para

93
inicializar la variable tabla, y dentro de la funcin poner para el almacenamiento de
registros a la tabla de smbolos.

Para el caso de la funcin poner se ha definido que ser utilizada exclusivamente al
momento de encontrar un nombre de algoritmo, de subalgoritmo, de parmetro o de
variable dentro de un contexto declarativo, aspecto que es determinado por los
diagramas de sintaxis del lenguaje AEGOLI (Ver Anexo A).

Para el caso de la funcin posicion se ha determinado que ser utilizada
exclusivamente al momento de encontrar un nombre de algoritmo, subalgoritmo,
parmetro o de variable dentro de un contexto no declarativo, es decir, dentro de un
contexto en que dicho nombre se encuentre en uso y no en declaracin o definicin.
Para esto tambin ser necesario auxiliarse de los diagramas de sintaxis del lenguaje
AEGOLI.

Para el caso de la funcin liberarMemoria se ha determinado que su utilizacin ser
reservada para cuando el proceso de compilacin sea finalizado o abortado ante la
presencia de un error (error simple cuando se trabaje con mecanismo de pnico o
error crtico cuando se trabaje con tratamiento de los errores).



Otros aspectos sobre el manejo de la tabla de smbolos.

La tabla de smbolos se utilizar de manera que respete el mbito de los objetos de
tipo variable. El mbito para las variables consta de dos niveles: variables globales
o variables de subalgoritmo. Las variables globales se declaran fuera de los
subalgoritmos y pueden ser utilizadas en cualquier parte del programa. Las
variables de subalgoritmo son declaradas dentro de subalgoritmo y solamente
pueden ser utilizadas dentro de l.


94
El subalgoritmo principal (ver Anexo A) ser manipulado como un subalgoritmo
ms y ser registrado en la tabla de smbolos con el nombre 01_principal, el cual
es un nombre imposible para un subalgoritmo o variable dentro del lenguaje
AEGOLI (ver Anexo B) garantizando as su unicidad dentro del conjunto de
registros.

Es importante mencionar que los parmetros sern registrados en la tabla de
smbolos como objetos de tipo variable que tendrn validez exclusivamente dentro
del mbito del subalgoritmo al que pertenecen.
95
95

9
.
3

T
r
a
t
a
m
i
e
n
t
o

d
e

l
o
s

e
r
r
o
r
e
s

9
.
3
.
1

D
i
a
g
r
a
m
a

d
e

D
e
p
e
n
d
e
n
c
i
a
s

F
i
g
u
r
a

1
8
.

D
i
a
g
r
a
m
a

d
e

d
e
p
e
n
d
e
n
c
i
a
s
.


96
El diagrama anterior muestra la manera en que las funciones del analizador sintctico del
compilador se llaman unas a otras durante un proceso de compilacin. Este diagrama es
utilizado para orientar y simplificar la implementacin de las estrategias de estabilizacin
que se describirn a continuacin.


9.3.2 Estrategias utilizadas para la estabilizacin de errores sintcticos y semnticos:

Cuando dentro de una funcin del analizador sintctico del compilador se haga un
llamado a alguna otra funcin, se enviar como parmetro un conjunto de tokens
seguidores denominado toksig, el cual ser conformado por todas las palabras
claves o caracteres especiales del lenguaje (como parntesis de cierre, corchetes de
cierre o comas) que se esperan ver despus de que la funcin invocada termine de
realizar el anlisis que le corresponde.

El objetivo de este conjunto es que ante la presencia de un error en la funcin
invocada (o incluso invocaciones que ella pueda realizar) se logre saltar texto hasta
encontrar un token con el que la funcin (la que realiz la primera invocacin de la
secuencia) pueda continuar analizando el cdigo fuente.


Cuando dentro de una funcin del analizador sintctico del compilador se haga un
llamado a alguna otra funcin, aadir al parmetro toksig de la funcin invocada su
propio conjunto toksig.

De esta manera, ante la presencia de un error en la funcin invocada, se podr
tambin realizar un salto hasta un token con el que la funcin precedente a la
funcin que realiz el llamado pueda utilizar.

Al inicio del proceso de anlisis sintctico se deber crear un conjunto toksig inicial
o de arranque, que contenga los elementos seguidores de la primera funcin del

97
anlisis sintctico, de manera que pueda iniciarse la sincronizacin encargada de
estabilizar la deteccin de errores dentro del compilador.


La lgica de construccin del compilador permite que en diversos sectores del
cdigo al invocar a una funcin del analizador sintctico se cuente en efecto con los
tokens que esta funcin necesita para trabajar. Se colocarn intentos de salto de
texto en todos los sectores donde no se garantice esta situacin, utilizando como
criterios el conjunto toksig de la funcin donde se intente el salto, as como los
tokens que dicha funcin necesita en el momento que se intenta realizar el salto.

Utilizar esta estrategia permite identificar posibles errores (en caso que a
continuacin no se cuente con un token que la funcin espera encontrar) as como la
realizacin de un salto de texto inteligente ante ellos, permitiendo que el proceso de
compilacin pueda continuar y evitando la generacin de errores en cascada.

En otras palabras, un intento de salto puede entenderse como un proceso de
verificacin del siguiente token, ya que evala si es un token adecuado al contexto
en el que se encuentra colocado.


La regla de las palabras clave indica que para ejecutar los saltos de texto deben
utilizarse exclusivamente palabras clave y algunos caracteres de enriquecimiento.
Sin embargo, se har una excepcin a esta regla y se incluir a los identificadores
dentro de los criterios de salto en los siguientes casos:

o Al inicio y al final de la funcin encargada de evaluar las instrucciones,
dado que de acuerdo a los diagramas de sintaxis (Ver Anexo A) siempre
puede colocarse una instruccin seguida de otra instruccin, y es necesario
tomar en cuenta al identificador para realizar un intento de salto ya que dos

98
tipos de instrucciones pueden comenzar por un identificador (las llamadas a
subalgoritmos y las asignaciones).

o Al momento de invocar a la funcin instruccin dentro de la funcin bloque
(Ver Anexo A), de manera que pueda controlarse el inicio de un bloque de
instrucciones en los casos en que la primera instruccin del bloque sea una
llamada a subalgoritmo o una asignacin.


Para poder implementar estas estrategias es necesario implementar conjuntos en el lenguaje
de programacin C, dado que este no es un tipo de dato definido dentro de dicho lenguaje,
los detalles de este proceso pueden consultarse en el Anexo C. Tambin se incluye en dicho
anexo la definicin de la funcin que realizar los intentos de salto.



9.4 Diseo del cdigo intermedio

El cdigo intermedio que ser generado por el compilador del lenguaje AEGOLI se
encuentra diseado en base al cdigo P que utiliza el compilador del lenguaje PASCAL, y
al igual que ste trabajar con una estructura de pila para el manejo de la memoria. A
continuacin se explican los elementos que lo constituirn.


9.4.1 Mnemnicos

El cdigo intermedio que ser generado por el compilador del lenguaje AEGOLI contar
con los siguientes mnemnicos para la construccin de sus instrucciones:

LIT: Cargar un valor literal al tope de la pila. Este valor literal puede ser un nmero
entero, un nmero real, un carcter o una cadena.


99
CAR: Cargar una variable al tope de la pila. Para el caso de los arreglos y matrices
cargar la posicin que se especifique.

ALM: Instruccin de almacenamiento equivalente a la asignacin.

LLA: Activacin de subalgoritmo, ya sea ste un procedimiento o una funcin.

INS: Instruccin de asignacin de espacio en la pila, tanto de espacio para variables
de control como espacio para variables del programa.

SAC: Salto condicional

SAL: Salto incondicional

OPR: Referencia a operacin relacional, aritmtica o predefinida en el lenguaje
AEGOLI.

CPY: Copia el contenido de una variable al tope de la pila. Cuando la variable sea
un arreglo o una matriz se copia todas sus posiciones.

RET: Variante de ALM. Almacena las primeras n posiciones desde el tope de la pila
en una variable. Para el caso de una variable simple el valor de n es 1, para el caso
de un arreglo es igual a su longitud y para el caso de una matriz es la cantidad de
casillas (numero de filas x numero de columnas).


9.4.2 Estructura de una instruccin en cdigo intermedio

El formato de una instruccin en cdigo intermedio es:

f n d t

100
Donde:

f: es el mnemnico de la instruccin.

n: es la diferencia esttica de nivel de la variable:
1. Un 0 indicar un nivel global.
2. Un 1 indicar un nivel local.

t: indica el tipo de dato con el que la instruccin trabaja:
1. Es 0 si la instruccin no trabaja con ningn tipo de datos en especfico.
2. Es 1 si se trabaja con nmeros enteros.
3. Es 2 si se trabajo con nmeros reales.
4. Es 3 si se trabaja con caracteres.
5. Es 4 si se trabaja con cadenas.
6. En el caso de la instruccin LLA indicar la cantidad de casillas utilizadas
por los parmetros del subalgoritmo a ejecutar.
7. En el caso de la instruccin INS con valor de 1 en n indicar si la variable
para la que se reservar espacio en la pila de memoria se trata de un arreglo
o de una matriz.

d: este valor depende del valor de f.
1. Si f es LIT, d indica el valor literal a cargar.
2. Si f es INS y n es 1 indica:
- La cantidad de posiciones para las variables que son arreglos.
- La cantidad de filas o de columnas paras las variables que son
matrices.
3. Si f es SAL, SAC o LLA, d es una direccin de salto.
4. Si f es CAR, ALM, CPY o RET, d es una direccin donde hay que buscar un
dato. Para los casos de variables que son arreglos o matrices en donde el
ndice que establece la posicin a utilizar slo puede conocerse en tiempo de
ejecucin, d indicar que la direccin donde se debe buscar un dato se

101
encuentra al tope de la pila de memoria que utilizar la mquina virtual (ver
seccin 9.5).
5. Si f es OPR, d indica el valor de una funcin a ejecutar. En estos casos n y t
pueden tomar otros significados, stos se expondrn en la seccin 9.5.

- Los valores que puede tomar d cuando f es OPR son:
o Funciones de la mquina virtual:
0: finalizacin de la ejecucin de un programa.
1: finalizacin de la ejecucin de un procedimiento.
2: finalizacin de la ejecucin de una funcin.
3: intercambio entre los valores de las primeras dos posiciones de la
pila.
4: suma del tope de la pila con el valor que se encuentra dos
posiciones atrs.
5: eliminacin de un posiciones en la pila de memoria (comenzando
desde el tope).
6: intercambio entre el valor al tope de la pila y el de la tercera
posicin.
7: verificacin del tipo de dato del tope de la pila.

o Funciones relacionales y lgicas:
10: negacin.
11: conjuncin.
12: disyuncin.
13: menor que.
14: menor o igual que
15: mayor que.
16: mayor o igual que.
17: igual a.
18: diferente de.

102
19: ejecuta una funcin 14 entre el valor del tope de la pila de
memoria con el valor de la segunda posicin si el valor de la tercera
posicin es positivo. Si el valor de la tercera posicin de la pila es
negativo, ejecuta una funcin 16 entre el valor del tope de la pila con
el de la segunda posicin.

o Funciones aritmticas:
20: cambio de signo.
21: suma.
22: resta.
23: multiplicacin.
24: divisin.

o Funciones de entrada y salida de datos:
30: Lectura de datos.
31: Escritura de datos.
32: Escritura de salto de lnea.
33: Apertura de archivo para la extraccin de datos.
34: Lectura de datos desde archivo.
35: Cierre de archivo para la extraccin de datos.
36: Evaluacin de final de archivo.

o Funciones numricas predefinidas del lenguaje AEGOLI:
100: funcin que devuelve el valor de .
101: funcin que evala el seno de un nmero.
102: funcin que evala el coseno de un nmero.
103: funcin que evala la tangente de un nmero.
104: funcin que evala el arcoseno de un nmero.
105: funcin que evala el arcocoseno de un nmero.
106: funcion que evala la arcotangente de un nmero.

103
107: funcin que aproxima un nmero por el mtodo de
truncamiento.
108: funcin que aproxima un nmero por el mtodo de redondeo.
109: funcin que devuelve el valor absoluto de un nmero.
110: funcin que evala la raz cuadrada de un nmero.
111: funcin que evala el logaritmo base 10 de un nmero.
112: funcin que evala el logaritmo natural de un nmero.
113: funcin que evala una potencia del nmero e.
114: funcin que obtiene la parte entera de una divisin.
115: funcin que evala la potencia de un nmero.
116: funcin que obtiene el residuo de una divisin.

o Funciones de cadena predefinidas del lenguaje AEGOLI:
200: funcin que concatena cadenas.
201: funcin que extrae subcadenas.
202: funcin que convierte una cadena en maysculas.
203: funcin que convierte una cadena en minsculas.

o Funciones numricas que trabajan con cadenas o caracteres y que se
encuentran predefinidas en el lenguaje AEGOLI:
300: funcin que compara dos caracteres.
301: funcin que compara dos cadenas.
302: funcin que busca una cadena dentro de otra.
303: funcin que evala la longitud de una cadena.

La manera en que se implementa la estrategia generacin del cdigo intermedio descrito
anteriormente dentro del compilador del lenguaje AEGOLI puede ser consultada en el
Anexo C.

104
9.5 La mquina virtual

La mquina virtual trabajar con una estructura de pila para el uso de la memoria. Las
instrucciones del cdigo intermedio diseado y explicado en la seccin anterior realizarn
manipulaciones directas sobre esta estructura de pila y este proceso constituir la ejecucin
de un programa escrito en el lenguaje AEGOLI.

Las variables poseern un nivel y una direccin, el nivel har referencia al mbito en el cual
se encuentra (global o local), mientras que la direccin har referencia a la ubicacin de la
variable dentro del mbito al que pertenecen. Es importante hacer notar que aunque una
variable ocupe varias casillas dentro de la pila de memoria (cosa que ocurre con arreglos y
matrices) el conjunto de casillas que utilice ser tratado como un solo objeto que poseer
una nica direccin. Se har uso de casillas de control en estos casos para recorrer el
contenido de las variables.

La manera en que cada instruccin de cdigo intermedio realizar modificaciones sobre la
pila de memoria de la mquina virtual puede ser consultada en el Anexo C.

105
CAPTULO 10. CONCLUSIONES Y RECOMENDACIONES

10.1 Conclusiones

El replanteamiento del tema como REVISIN DE LENGUAJE PARA LA
EJECUCIN DE ALGORITMOS EN PSEUDO-CDIGO Y CONSTRUCCIN
DE SU COMPILADOR es un factor importante para el xito del proyecto, ya que
permiti enfocar los esfuerzos del grupo en hacer una revisin completa del
lenguaje que se usaba hasta el momento, con el fin de hacer una definicin clara del
mismo tanto sintcticamente, como semnticamente y en cuanto a las
funcionalidades que poseera.


El anlisis y rediseo del lenguaje, as como la construccin manual del compilador
brindaron al grupo un control completo en cada etapa del proyecto, lo cual permiti
crear con facilidad mecanismos para la correcta estabilizacin del compilador.


Para poder desarrollar un software que fuera utilizado principalmente como una
herramienta didctica fue necesario tomar en cuenta las recomendaciones de
personas dedicadas a la enseanza de la programacin. Una de las estrategias para
lograr esto, fue hacer a un lado en el lenguaje ciertas caractersticas que lo hacan
ms complejo y complementar otras que volvieran su aprendizaje ms intuitivo,
sencillo y que a su vez fomentara buenas prcticas.


El tratamiento de los errores en el compilador fue considerado como una
caracterstica muy importante a ser implementada en el compilador del lenguaje
AEGOLI. Esto brindara a los programadores del lenguaje AEGOLI una mejor
experiencia en cuanto a la correccin de errores en el cdigo, de manera que puedan

106
ser corregidos ms eficientemente, esto gracias a que la cantidad de errores
fantasma, o errores que aparecen luego de corregir otros, se reduce drsticamente.

El diseo y realizacin de una batera de pruebas extensa sobre el compilador de
AEGOLI es imprescindible para lograr un producto de alta calidad y que genere
satisfaccin a los usuarios.



10.2 Recomendaciones

La construccin de un entorno de desarrollo, compuesto por una interfaz grfica y
que use el compilador desarrollado en este trabajo, es absolutamente necesario para
acercar el lenguaje AEGOLI a los usuarios finales. La interfaz grfica debe ser
amigable y sencilla de usar, de manera que los usuarios del entorno de desarrollo
experimenten un alto grado comodidad y practicidad durante la elaboracin de
programas de aplicacin en lenguaje AEGOLI. La interfaz debe poseer todas
funcionalidades bsicas de un editor de texto, adems de otras caractersticas
importantes como son:

o Coloreado de palabras reservadas, nmeros y comentarios para fcil
reconocimiento en el cdigo.

o Facilitar el sangrado del cdigo, para una mejor visualizacin de las
estructuras codificadas.

o Implementar un mecanismo de ejecucin paso a paso, para realizar procesos
de depuracin en el cdigo.

o Soporte para poder ser utilizada en diferentes sistemas operativos como
Linux o Windows.

107
Evaluar peridicamente la definicin del lenguaje AEGOLI con el fin de evaluar su
nivel de funcionalidad y poder detectar nuevos requerimientos que sean necesarios
para la enseanza de la programacin.


Si se desean hacer modificaciones al lenguaje AEGOLI, es importante recodar que
se debe hacer una actualizacin en cuanto a las expresiones regulares que describen
la lexicografa del lenguaje, la gramtica que describe la sintaxis lenguaje y por ello
los diagramas de sintaxis, las reglas semnticas, el tratamiento de los errores y la
generacin de cdigo si as fuese necesario. Luego, debido a que el analizador
sintctico del compilador es un parser descendente tambin ser necesario evaluar si
la gramtica cumple con ser an LL1, en caso de no cumplir, proceder a modificar
la gramtica o implementar una regla semntica que lo solucione.



109
GLOSARIO

Algoritmo: Un algoritmo es una serie de pasos organizados que describe el proceso que se
debe seguir, para dar solucin a un problema especfico.
mbito de una variable: rea del programa donde una variable existe y puede ser
utilizada.
Archivo fuente: Archivo que contiene el cdigo fuente en el lenguaje a compilar.
Backpatching: En generacin de cdigo intermedio, es un enfoque donde al momento de
generar un salto el objetivo de este salto se deja temporalmente indefinido, para ser
definido una vez se conozca el objetivo.
Buffer: Espacio de memoria, en el que se almacenan datos de manera temporal, en espera
de ser procesados.
Cadena: Secuencia ordenada de caracteres de longitud arbitraria.
Cerradura de Kleene: Bucle matemtico que indica que un smbolo puede repetirse varias
veces en la construccin de una palabra, por ejemplo, h* representara al conjunto de todas
las palabras formadas con cualquier cantidad de letras h, es decir, {, h, hh, hhh, }
Cdigo de mquina: Es una codificacin de programas en sistema binario, el cual es el
nico que puede ser ejecutado directamente por una computadora.
Cdigo fuente: Conjunto de lneas de texto que representan las instrucciones de un
programa escritas en un lenguaje de programacin determinado.
Cdigo intermedio: Cdigo abstracto independiente de la mquina para la que se generar
el cdigo objeto.
Cdigo objeto: Cdigo generado por un compilador que resulta de la traduccin del cdigo
fuente de un programa.
Cdigo p: Cdigo intermedio utilizado para el lenguaje PASCAL.
Compilador: Programa reconocedor-traductor, que recibe como entrada un programa
escrito en un lenguaje dotado de estructura y que pasando por una serie de esquemas de
reconocimiento y traduccin, produce otro programa en cdigo objeto.
Diagrama de sintaxis: Forma de representacin grfica de la sintaxis de un lenguaje.
Funcin: subprograma o subrutina que realiza una tarea especfica y devuelve un valor.

110
Identificador: Secuencia de caracteres que dentro del cdigo de un programa sirven para
nombrar los objetos como procedimientos, funciones, variables, etc.
Intrprete: programa que analiza y ejecuta simultneamente un programa en cdigo
fuente.
Lenguaje de programacin: Lenguaje utilizado para controlar el comportamiento de una
mquina, particularmente una computadora. Consiste en un conjunto de smbolos y reglas
sintcticas y semnticas que definen su estructura y el significado de sus elementos y
expresiones.
Lenguaje fuente: El lenguaje de programacin utilizado para la redaccin del cdigo
fuente.
Meta-compilador: Un meta-compilador o generador de parsers es una herramienta que, a
partir de la especificacin de un lenguaje, construye un programa o analizador que es capaz
de reconocer secuencias o elementos de dicho lenguaje. En general, la especificacin del
lenguaje abarca tanto el aspecto lxico como el sintctico, y son los que permiten la
construccin del parser, mientras que el aspecto semntico del lenguaje se deja en manos
del usuario, para que lo ensamble una vez obtenido el parser.
Mnemnico: Es una palabra que sustituye a un cdigo de operacin (lenguaje de mquina),
con lo cual resulta ms fcil la programacin, es de aqu de donde se aplica el concepto de
lenguaje ensamblador.
Notacin EBNF (Extended Backus Naur Form): Es un mtodo formal para expresar
lenguajes formales.
Palabra clave: Una palabra clave o palabra reservada es una palabra o identificador que
tiene un significado particular para un lenguaje de programacin. El significado de las
palabras clave y el significado de la nocin de palabra clave difieren ampliamente de un
lenguaje de programacin a otro.
Parmetro: Un parmetro (o argumento) es una variable que es recibida por una funcin,
procedimiento o subrutina. Un parmetro influye en el comportamiento o el resultado de la
ejecucin de la funcin, procedimiento o subrutina que lo recibe.
Pila: Una pila (stack en ingls) es una lista ordinal o estructura de datos en la que el modo
de acceso a sus elementos es de tipo LIFO (del ingls Last In First Out, ltimo en entrar,
primero en salir) que permite almacenar y recuperar datos. En cada momento slo se tiene

111
acceso a la parte superior de la pila, es decir, al ltimo objeto apilado (denominado tope de
la pila o TOS, Top of Stack en ingls).
Portabilidad: Caracterstica que posee un software para ejecutarse en diferentes
plataformas, el cdigo fuente del software es capaz de ser reutilizado en vez de crearse un
nuevo cdigo cuando el software pasa de una plataforma a otra. A mayor portabilidad
menor es la dependencia del software con respecto a la plataforma.
Estabilidad: Caracterstica que posee un software que por medio de ciertos mecanismos, le
permiten recuperarse de cualquier error generado y con ello seguir funcionando
correctamente.
Pre-procesador: La funcin principal de los preprocesadores es hacer inteligible, para el
compilador, el cdigo fuente, cambiando las directivas de pre-procesamiento por valores
para el compilador.
Procedimiento: Cuando una funcin no regresa valor alguno se llama procedimiento, en
todo caso el valor que regresa es nulo. Un procedimiento es un grupo de instrucciones, que
como su nombre lo dice realiza un procedimiento y nada mas, cuya ejecucin se lleva a
cabo cada vez que se invoca el nombre del procedimiento, posiblemente con algunos
valores como argumentos.
Produccin: Regla de una gramtica con cierta estructura que cumple con ciertas
caractersticas que definen a dicha gramtica.
Pseudo-cdigo: Es una descripcin de alto nivel de un algoritmo que emplea una mezcla
de lenguaje natural con algunas convenciones sintcticas propias de lenguajes de
programacin, como asignaciones, ciclos y condicionales. Es utilizado para describir
algoritmos en libros y publicaciones cientficas, y como producto intermedio durante el
desarrollo de un algoritmo.
Semntica: se refiere a los aspectos del significado, sentido o interpretacin del significado
de un determinado elemento, smbolo, palabra, expresin o representacin formal.
Smbolo no terminal: Es un smbolo de la gramtica que representa una construccin
gramatical que puede expresarse mediante reglas en trminos de construcciones ms
pequeas; en otras palabras, una construccin que no es un token.
Smbolo terminal: Es un smbolo de la gramtica que no tiene reglas en la gramtica y por
lo tanto es gramaticalmente indivisible.

112
Smbolos y Operadores especiales: tienen un significado especial para un lenguaje de
programacin en especfico y por lo tanto, tienen un token asociado en dicho lenguaje.
Sintaxis: Conjunto de reglas que definen las secuencias correctas de los elementos de un
lenguaje de programacin.
Subalgoritmo: Es cada una de las partes de un algoritmo ms general que resuelve cada
una de las tareas particulares necesarias para que dicho algoritmo general alcance el
objetivo para el que fue diseado, es decir resolver un problema. Este concepto est
vinculado al diseo estructurado de algoritmos, en el cual un problema se divide en partes
que posteriormente son resueltas por un mdulo. Cada mdulo coincidir con un
subalgoritmo.
Tiempo de compilacin: Se denomina al intervalo de tiempo en el que un compilador
compila cdigo escrito en un lenguaje de programacin a una forma de cdigo ejecutable
por una mquina.
Tiempo de ejecucin: Se denomina al intervalo de tiempo en el que un programa de
computadora se ejecuta en un sistema operativo. Este tiempo se inicia con la puesta en
memoria principal del programa, por lo que el sistema operativo comienza a ejecutar sus
instrucciones. El intervalo finaliza en el momento en que ste enva al sistema operativo la
seal de terminacin, sea sta una terminacin normal, en que el programa tuvo la
posibilidad de concluir sus instrucciones satisfactoriamente, o una terminacin anormal, en
el que el programa produjo algn error y el sistema debi forzar su finalizacin.







113
BIBLIOGRAFA

Abarca A. [2007]. Notas sobre la teora de autmatas finitos, expresiones regulares y
gramtica formal. UCA editores, San Salvador, El Salvador.

Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman. [1998]. Compiladores: principios, tcnicas y
herramientas. Versin en espaol. Addison Wesley Longman, Mxico.

Alfaro Aragn, I. M., R. M. Alvarado Carrillo, P. E. Melndez Guardado, A. J. Navarrete
Guerrero. [2008] Ampliacin y mejoras de una plataforma de aprendizaje de
programacin en pseudo-cdigo. Trabajo de graduacin presentado para optar al
grado de licenciado en ciencias de la computacin en la Universidad
Centroamericana Jos Simen Caas, San Salvador, El Salvador.

Compiladores, Intrpretes y Mquinas Virtuales. [en lnea]. La Tecla de Escape, 13 de
septiembre de 2006. <http://latecladeescape.com/w0/basico/compiladores-
interpretes-y-maquinas-virtuales.html> [Consulta: 30 marzo 2010].

Francisco Rodrguez Zamora, Jonathan Caldern Varela. Generacin de Cdigo
Intermedio. [en lnea]. Universidad de Costa Rica, Escuela de Ciencias de
Computacin e Informtica. San Jos, Costa Rica. 29 de junio de 2008 <
http://www.di-mare.com/adolfo/cursos/2008-1/pp-GenCodInterMed.pdf >
[Consulta: 2 abril 2010].

G. Snchez Dueas, J.A. Valverde Andreu. [1989]. Compiladores e Intrpretes: un enfoque
pragmtico. 2 Edicin. Corregida y ampliada. Daz de Santos, S.A. c/Juan Bravo,
3A. 28006 Madrid, Espaa.

Wirth, Niklaus. [1982]. Algoritmos + Estructura de datos= Programas. Versin en
espaol. Ediciones Del Castillo, Madrid, Espaa.


















ANEXO A
DESCRIPCIN DEL LENGUAJE AEGOLI



A-1

Lenguaje AEGOLI

Se denomina Lenguaje AEGOLI al lenguaje utilizado para la introduccin de los
estudiantes al mundo de la programacin en la materia Fundamentos de Programacin, la
cual es impartida como parte del programa de la carrera Licenciatura en Ciencias de la
Computacin en la Universidad Centroamericana Jos Simen Caas (UCA).

A continuacin se presentan los diagramas de sintaxis que describen la estructura de un
programa escrito en este lenguaje as como las caractersticas particulares del mismo.



Diagramas de sintaxis


Estructura general de un algoritmo escrito en el lenguaje AEGOLI:



Figura A-1. Diagrama de sintaxis de la estructura general de un algoritmo.

A-2

Cuerpo:

Figura A-2. Diagrama de sintaxis para la estructura interna de un algoritmo.


Declaracion_Variable:

Figura A-3. Diagrama de sintaxis para la declaracin de una variable.



Tipo:





Figura A-4. Diagrama de sintaxis que muestra los tipos existentes en el lenguaje AEGOLI.
A-3

Subalgoritmo:




Figura A-5. Diagrama de sintaxis para estructura de un subalgoritmo dentro de un programa.



Firma_Subalgoritmo:

Figura A-6. Diagrama de sintaxis para la firma de los subalgoritmos dentro de un programa.



Parametro:

Figura A-7. Diagrama de sintaxis para los parmetros en las firmas o encabezados de subalgoritmos.




A-4

Variable:

Figura A-8. Diagrama de sintaxis que muestra la forma en que puede utilizarse una variable dependiendo de si
es un arreglo, o matriz o variable sencilla.





Bloque:



Figura A-9. Diagrama de sintaxis para la estructura interna de un bloque en el subalgoritmo principal y en los
subalgoritmos externos.

A-5



Instruccin:


Figura A-10. Diagrama de sintaxis que muestra las diferentes instrucciones que pueden utilizarse en un
algoritmo.




A-6



Instrucciones_E/S:













Figura A-11. Diagrama de sintaxis para las distintas instrucciones de entrada y salida de datos.



Llamada_Subalgoritmo:

Figura A-12. Diagrama de sintaxis para la instruccin de llamada a un subalgoritmo dentro de otro.


A-7

Asignacion:




Figura A-13. Diagrama de sintaxis para la instruccin de asignacin de un valor a una variable.



Instruccion_Si:

Figura A-14. Diagrama de sintaxis para la instruccin si.


Instruccion_Hacer:

Figura A-15. Diagrama de sintaxis para la instruccin hacer.



A-8

Instruccion_Mientras:

Figura A-16. Diagrama de sintaxis para la instruccin mientras.


Instruccion_Repetir:

Figura A-17. Diagrama de sintaxis para la instruccin repetir.


Instruccion_Para:

Figura A-18. Diagrama de sintaxis para la instruccin para.


A-9


Instruccion_Leer:


Figura A-19. Diagrama de sintaxis para la instruccin leer.




Instruccion_Escribir:

Figura A-20. Diagrama de sintaxis para la instruccin escribir.



Instruccin_Escribirln:

Figura A-21. Diagrama de sintaxis para la instruccin escribirln.


A-10



Instruccion_AbrirArchivo:





Figura A-22. Diagrama de sintaxis para la instruccin abrirArchivo



Instruccion_AbrirArchivo:





Figura A-23. Diagrama de sintaxis para la instruccin leerArchivo



Instruccion_CerrarArchivo:





Figura A-24. Diagrama de sintaxis para la instruccin cerrarArchivo.



A-11


Expresion:







Figura A-25. Diagrama de sintaxis que muestra las diferentes expresiones que se puede utilizar.


Expresion_Numerica:

Figura A-26. Diagrama de sintaxis para una expresin numrica.



Expresion_Conjuncion:

Figura A-27. Diagrama de sintaxis para una expresin de conjuncin.
A-12


Expresion_Relacional:
Figura A-28. Diagrama de sintaxis para una expresin relacional.

Expresion_Aritmetica:








Figura A-29. Diagrama de sintaxis para la estructura de una expresin aritmtica.

Termino:





Figura A-30. Diagrama de sintaxis para la estructura de un trmino en una expresin numrica.
A-13

Factor:













Figura A-31. Diagrama de sintaxis que muestra los elementos que pueden conformar un factor en una
expresin numrica.


Funcion_Cadena:

Figura A-32. Diagrama de sintaxis que muestra la estructura de las funciones que devuelven una cadena
trabajando con cadenas.

A-14

Funcion_Numerica:

Figura A-33. Diagrama de sintaxis que muestra la estructura de las funciones que devuelven un valor
numrico trabajando con expresiones numricas.
A-15


Funcion_Numerica_Cadena_Caracter:


Figura A-34. Diagrama de sintaxis que muestra la estructura de las funciones que devuelven un valor
numrico trabajando con cadenas o con caracteres.


Dato_Caracter:









Figura A-35. Diagrama de sintaxis para los datos de tipo caracter utilizados como parmetro en subalgoritmos
o como valores en expresiones.



A-16






Dato_Cadena:











Figura A-36. Diagrama de sintaxis para los datos de tipo cadena utilizados como parmetro en subalgoritmos
o como valores en expresiones.


A-17



Tipos de datos

El lenguaje AEGOLI soporta los siguientes tipos de datos:

Tipo Descripcin
Entero Nmero entero positivo o negativo de
hasta 30 cifras.
Real Nmero real positivo o negativo de hasta
30 cifras enteras con un mximo de 20
cifras decimales.
Caracter Caracter ASCII simple.
Cadena Secuencia de hasta 3000 caracteres
ASCII simples.
Tabla A-1. Tipos de datos existentes en AEGOLI.



Operadores y funciones

El lenguaje de AEGOLI cuenta con los siguientes tipos de operadores:

i. Operadores Aritmticos

Operacin Representacin en AEGOLI

Suma +
Resta -
Multiplicacin *
Divisin /
Tabla A-2. Operadores aritmticos


A-18


ii. Operadores Relacionales

Operacin Representacin en AEGOLI

Menor que <
Menor o igual que <=
Mayor que >
Mayor o igual que >=
Comparacin de igualdad = =
Diferente ! =
Tabla A-3. Operadores relacionales


iii. Operadores Lgicos

Operacin Representacin en AEGOLI
Y lgico &
O lgico |
Negacin !
Tabla A-4. Operadores Lgicos


iv. Otros operadores y caracteres especiales

Operacin Representacin en AEGOLI
Asignacin =
Concatenacin (para elementos en las
instrucciones escribir y escribirln)
,
Comentariado de cdigo (una sola lnea) //
Comentariado de cdigo (bloque de
cdigo)
/* */
Tabla A-5. Otros operadores y caracteres especiales



A-19

En cuanto a funciones predefinidas del lenguaje AEGOLI se pueden mencionar dos tipos:

i. Funciones numricas
2


Operacin Sintaxis en AEGOLI Tipo de dato devuelto
Obtener la parte entera de
una divisin
div(entero,entero) Entero
Obtener el residuo de una
divisin
mod(entero,entero) Entero
Elevar un nmero a una
potencia
potencia(numero,numero) Entero o real
Obtener el valor del nmero

pi() Real
Evaluar la tangente de un
nmero
tangente(numero)

Real
Evaluar el seno de un
nmero
seno(numero) Real
Evaluar el coseno de un
nmero
coseno(numero) Real
Evaluar la arco-tangente de
un nmero
arctan(numero) Real
Evaluar el arco-seno de un
nmero
arcsen(numero) Real
Evaluar el arco-coseno de
un nmero
arccos(numero) Real
Truncar la parte fraccionaria
de un nmero
truncar(numero) Real
Evaluar el valor absoluto de
un nmero
absoluto(numero) Entero o real
Evaluar la raz cuadrada de
un nmero
raz(numero) Entero o real
Redondear un nmero a su
inmediato superior
redondear(numero) Real

2
Cuando se mencione numero como parmetro de una funcin, ste valor puede ser entero o real. En
cualquier otro caso se especifica el tipo de valor a utilizar.
A-20

Obtener el logaritmo base
10 de un nmero
log(numero) Real
Obtener el logaritmo natural
de un nmero
ln(numero) Real
Obtener el nmero e
elevado a una potencia
exp(numero) Real
Determinar si se ha
alcanzado el final de un
archivo de texto
finalArchivo Entero
Tabla A-6. Funciones numricas




ii. Funciones para el manejo de datos de tipo cadena o caracter

Operacin Sintaxis en AEGOLI Tipo de dato
devuelto
Comparar dos cadenas compararCadenas(
cadena 1, cadena 2)
Entero
Comparar dos caracteres compararCaracteres(
caracter 1, caracter 2)
Entero
Obtener la longitud de una
cadena
longitudCadena(cadena) Entero
Concatenar dos cadenas concatenar(cadena 1, cadena 2) Cadena
Extraer una sub-cadena de
una cadena
extraerCadena(cadena, liminf,
limsup)
Cadena
Buscar una sub-cadena en
una cadena
buscarCadena(cadena 1, cadena 2) Entero
Convertir los caracteres de
una cadena en maysculas
cadenaMayusculas(cadena) Cadena
Convertir los caracteres de
una cadena en minsculas
cadenaMinusculas(cadena) Cadena
Tabla A-7. Funciones para el manejo de datos de tipo cadena o caracter


A-21

A continuacin se detalla un poco ms el comportamiento de estas funciones:

Funcin Comportamiento
compararCadenas(
cadena 1, cadena 2)
Retorna 0 si las cadenas son iguales,
retorna -1 si la cadena 1 es menor que la
cadena 2 y retorna 1 si la cadena 1 es
mayor que la cadena 2
compararCaracteres(
caracter 1, caracter 2)
Retorna 0 si los caracteres son iguales,
retorna -1 si el caracter 1 es menor que
el caracter 2 y retorna 1 si el caracter 1
es mayor que el caracter 2
longitudCadena(cadena) Retorna la longitud de la cadena
concatenar(cadena 1, cadena 2) Retorna una cadena que es la
concatenacin de cadena 2 en cadena 1
extraerCadena(cadena, liminf, limsup) Retorna una sub-cadena perteneciente a
cadena entre las posiciones liminf y
limsup
buscarCadena(cadena 1, cadena 2) Retorna el valor entero correspondiente
a la posicin de la primera ocurrencia de
cadena 2 en cadena 1
cadenaMayusculas(cadena) Retorna la cadena con todos sus
caracteres en maysculas
cadenaMinusculas(cadena) Retorna la cadena con todos sus
caracteres en minsculas
Tabla A-8. Detalle de funciones para el manejo de datos de tipo cadena



Palabras reservadas

Por ltimo se presenta un compendio de las palabras reservadas en el lenguaje AEGOLI:

algoritmo inicio fin principal
caracter cadena entero real
procedimiento funcion ref comienza
A-22

termina retornar si entonces
sino finsi hacer mientrasque
mientras finmientras repetir hasta
para paso finpara leer
escribir escribirln tangente seno
coseno arctan arcsen arccos
truncar absoluto raiz redondear
log ln exp pi
mod potencia div concatenar
extraerCadena cadenaMayusculas cadenaMinusculas compararCadenas
buscarCadena longitudCadena compararCaracteres abrirArchivo
leerArchivo cerrarArchivo finalArchivo terminaPrograma
Tabla A-9. Palabras reservadas











ANEXO B
DEFINICIONES Y HERRAMIENTAS MATEMTICAS


B-1

1. Expresiones regulares

Las expresiones regulares sirven para representar un conjunto de cadenas sin enumerar sus
elementos. Son de gran utilidad en la bsqueda o reemplazo de cadenas que poseen un
patrn precisamente descrito por expresiones regulares.

Definicin formal de expresin regular.

Sea A un alfabeto. Las expresiones regulares sobre A y los lenguajes que estas denotan se
definen as:
1. El smbolo es una expresin regular y denota al lenguaje {}.
2. Considerando como la palabra vaca, es una expresin regular que denota al
lenguaje {}.
3. El smbolo a A es una expresin regular y denota al lenguaje {a} para todo a A.
4. Si V y S son expresin regulares que denotan a los lenguajes V y S
respectivamente, entonces:
i. V+S es una expresin regular que denota al conjunto formado por V U S
ii. VS es una expresin regular que denota al conjunto formado por VS (la
concatenacin de V con S.
iii. V* es una expresin regular que denota al conjunto formado por la cerradura
de Kleene de V. La cerradura de Kleene es un bucle matemtico que indica
que un smbolo puede repetirse varias veces en la construccin de una
palabra, por ejemplo, h* representara al conjunto de todas las palabras
formadas con cualquier cantidad de letras h, es decir, {, h, hh, hhh, }.

As por ejemplo, se puede describir a los identificadores de un lenguaje de programacin
usando la expresin regular letra(letra+digito)*, donde letra={a,b,,z,A,B,,Z} y
digito={0,1,2,,9}. As, esta expresin describe el hecho de que un identificador debe
comenzar con una letra y luego a continuacin por letras o dgitos en cualquier cantidad.


B-2

2. Autmatas Finitos Determinsticos

De manera formal, un autmata finito determinstico es un quintuplete (Q, A, , q
0
, F)
donde:
1) Q es un conjunto finito de estados.
2) A es un conjunto finito de smbolos llamado alfabeto de entrada.
3) es una funcin: : QXA Q, llamada funcin de transicin del autmata.
4) q
0
Q es el estado inicial del autmata.
5) F representa al conjunto de estados finales del autmata, luego, F esta incluido en
Q. Un estado final representa un estado de aceptacin.

Luego, para el ejemplo sobre los identificadores de un lenguaje de programacin el
autmata finito determinstico sera el siguiente:
Q= {q
0
, q
1
, q
2
}
A= {letra, digito, otro}
F= {q
1
}
Y la funcin de transicin:
(q
0
,letra)= q
1
(q
1
,letra)= q
1
(q
2
,letra)= q
2

(q
0
,digito)= q
2
(q
1
,digito)= q
1
(q
2
,digito)= q
2

(q
0
,otro)= q
2
(q
1
,otro)= q
2
(q
2
,otro)= q
2



Otra forma de especificar un DFA (Deterministic Finit Automata) es por medio de los
diagramas de transicin de estados. As, para el ejemplo anterior el diagrama
correspondiente es el que se muestra en la figura B-1.
B-3

q0 q1 q2
letra y dgito
letra
otro y dgito
otro
letra, dgito y otro


Figura B-1. Ejemplo de diagrama de transicin de estados.



3. Definicin formal de gramtica independiente del contexto.

Sea V un conjunto con el alfabeto de un leguaje dado. Una gramtica independiente del
contexto es un cuadruplete G = (V
n
, V
t
, P, S), donde:
1. V
n
esta incluido en V, V
n
conjunto de smbolos no terminales.
2. V
t
esta incluido en V, V
t
conjunto de smbolos terminales. Donde V
n
V
t = .

3. P es un conjunto de producciones de la forma , donde: V
*
-{} y V
*
(cerradura de Kleene). El smbolo se lee produce a.
4. S V
n
, se llama smbolo inicial de la gramtica.

Para que sea una gramtica independiente del contexto, todas las producciones de la forma
deben cumplir con la condicin || = 1 (la notacin |x| se refiere a la longitud del
elemento).

Por ejemplo, para definir expresiones formadas por dgitos y los signos ms y menos, como
8-4+1, 7-5, 5, etc. Se puede definir la siguiente gramtica independiente del contexto:
G = ( V
n
, V
t
, P, S)
B-4

V
n
= {lista, dgito}
V
t
={0,1,2,3,4,5,7,8,9}
S=lista
Y el conjunto de producciones P:
lista lista + dgito
lista lista dgito
lista dgito
dgito 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

As, la expresin 8-4+1 es generada por la Gramtica definida anteriormente, y para
comprobarlo se muestra el camino de derivacin:

lista lista + dgito lista dgito + dgito dgito dgito + dgito 8-4+1

Como se observa en el ejemplo anterior, de una gramtica se derivan cadenas empezando
con el smbolo inicial y reemplazando repetidamente un no terminal por el lado derecho o
el lado izquierdo de la produccin para ese no terminal. El conjunto de las cadenas de
componentes lxicos derivadas del smbolo inicial forman el lenguaje que define la
gramtica.


4. Definicin de Primero y Siguiente

El conjunto de smbolos terminales con las cuales una estructura gramatical puede
comenzar, se define de la siguiente manera:

Prim(X) = {t / t V
t
^ X t X
1
} con X V
n
y X
1
(V
n
U V
t
)*

As mismo, el conjunto de smbolos seguidores de una estructura gramatical se define a
continuacin:
B-5


Sig(X) = {t / t V
t
^ SXt} con X V
n
y , (V
n
U V
t
)*


5. Definicin de gramtica LL1

Para que una gramtica independiente de contexto cumpla con ser una gramtica LL1 se
debe la siguiente regla:

Dada una Gramtica libre de contexto G(CFG) y sus producciones de la forma:

1
|
2
| |
n
se debe cumplir que

Prim(
1
) Prim(
2
) Prim(
n
) =

Luego, si se puede derivar a (palabra vaca) de un smbolo no terminal X, se requiere
adems que:
Prim(X) Sig(X) =



6. Reglas R y R para la construccin de parser descendentes.

Reglas R

R
1
: Para transformar a una gramtica G a su forma en diagrama de sintaxis, aplquense
sucesivamente las siguientes reglas:

R2: Si x es un smbolo terminal, es decir, x V
t,
su representacin ser:


x
B-6

R3: Si X es un simbolo no terminal, es decir, X V
n
, su representacin ser:

X



R4: La produccin de la forma
1
|
2
| |
n
, se transforma en:









R5: La produccin de la forma
1

2

n
, se transforma en:

1
n 2
...



R6: La produccin: {} (cerradura de Kleene), se transforma en:



Luego de haber aplicado las reglas R, y obtengamos los diagramas de sintaxis, aplicaremos
las reglas R para construir un parser descendente.

1
n
2
.
.
.
B-7

Reglas R

R
1
: Para transformar una gramtica en diagramas de sintaxis a un parser descendente,
aplquense las siguientes reglas:

R2: Traducir los diagramas de sintaxis en un procedimiento (funcin o bloque) de acuerdo
a las siguientes reglas:

R3: El diagrama de sintaxis:
1
n 2
...

se traduce en :
Comienza
T(
1
)
T(
2
)

T(
n
)
Termina

Donde T(Ti) se obtiene de aplicar estas mismas reglas.

R4: Suponer que ch y es el componente lxico obtenido y se tiene el diagrama de sintaxis:









1
n
2
.
.
.
B-8

Se traduce en:
si ch Prim(
1
) entonces T(
1
)
otro si ch Prim(
2
) entonces T(
2
)

otro si ch Prim(
n
) entonces T(
n
)
otro llama ERROR!


R5: El diagrama de sintaxis:





Se traduce en:
mientras ch Prim() hacer T()


R6: Por ltimo,

a) Para el diagrama de sintaxis:


se traduce a una llamada al procedimiento que define a .


b) Para el diagrama de sintaxis:
x
, se traduce:

si ch= x entonces lee ch
otro llama ERROR!









ANEXO C
MANUAL TCNICO



C-1
1. Implementacin de los elementos necesarios para la lectura del archivo fuente.

a) Funcin extractora de caracteres desde el archivo fuente.

Esta funcin ha sido nombrada getline y su definicin es la siguiente:

int getline(char s[],int lim){
int c,i;
for (i=0;i<lim-1 && (c=getc(fp))!=EOF && c!='\n';++i)
s[i]=c;
if (c=='\n') {
s[i]=c;
++i;
}
s[i]='\0';
return (i);
}

Esta funcin recibe como parmetro el buffer de entrada (un arreglo de caracteres) y el
tamao mximo de este (su longitud). Posteriormente procede a extraer del archivo fuente
caracteres de uno en uno hasta que el buffer ha sido llenado, se ha alcanzado el final del
archivo fuente, o se ha encontrado un salto de lnea.


b) Funcin extractora de caracteres desde el buffer de entrada.

Esta funcin ha sido nombrada obtch y su definicin es la siguiente:

int obtch(){
if (fin_de_archivo==1){
liberarMemoria();

C-2
exit(1);
}
if (offset==ll-1) {
ll=getline(linea,MAXLINEA);
if (ll==0)
fin_de_archivo=1;
offset=-1;
}
++offset;
if ( (linea[offset]=='\0') || (fin_de_archivo==1) )
return(' ');
else
return(linea[offset]);
}

Esta funcin no recibe ningn parmetro pero trabaja utilizando cuatro variables que sern
definidas de manera global de la siguiente manera:

int offset;
int ll;
int fin_de_archivo;
int ch;

Estas variables se utilizan de la siguiente manera:

La variable offset se utiliza para indicar la posicin actual en el buffer de entrada y
se aumenta en uno cada vez que se extrae un carcter del mismo.

La variable ll se utiliza para determinar la longitud de la ltima lnea que fue leda
desde el cdigo fuente, es decir, de la longitud actual del buffer de entrada. Su valor

C-3
se modifica cada vez que se invoca a la funcin getline y se utiliza en conjunto con
la variable offset para determinar si se ha vaciado o no el buffer de entrada.

La variable fin_de_archivo se utiliza para determinar el momento en que se ha
alcanzado el final del archivo fuente que contiene el programa escrito en el lenguaje
AEGOLI. Esto es posible gracias a la funcin getline, la cual, cuando encuentra el
final del archivo fuente, devuelve como valor 0 indicando que el buffer de entrada
permanece vaco.

La variable ch se utiliza para almacenar el carcter extrado del buffer de entrada y
es el que ser utilizado a lo largo de todo el proceso de anlisis lexicogrfico.

Por lo tanto, la funcin obtch se encarga de abortar el proceso de ejecucin en caso de que
se haya alcanzado el final del archivo fuente, liberando primero todos los recursos de
memoria utilizados por el proceso de compilacin (la funcin liberarMemoria se discutir
en secciones posteriores), procediendo posteriormente a evaluar si se ha vaciado el buffer
de entrada para determinar si es necesario invocar a la funcin getline.

Por ltimo la funcin se encarga de extraer un carcter del buffer de entrada para
almacenarlo en la variable ch. Ntese que cuando se vaca el buffer de entrada o cuando se
ha alcanzado el final del archivo fuente, la funcin obtch almacena en ch un carcter
insignificante para el lenguaje AEGOLI; esto se realiza con el objetivo de provocar que
quien invoque a obtch no pueda efectuar operacin alguna y se vea forzado a invocara una
vez ms, provocando as el rellenado del buffer de entrada o el trmino del proceso de
compilacin.


2. Implementacin de la funcin que elimina blancos y comentarios en el cdigo fuente

La funcin encargada de este proceso inicial del anlisis lexicogrfico se define a
continuacin:


C-4
while (ch==' ' || ch=='\n' || ch=='\t' || ch=='/'){
if(ch=='\n') numlinea++;
if(ch=='/'){
ch=obtch();
if(ch=='/'){
do{
ch=obtch();
}while(ch!='\n');
numlinea++;
}else
if(ch=='*'){
do{
if(asterisco!=1) ch=obtch();
else asterisco = 0;
if(ch=='\n') numlinea++;
if(ch=='*'){
ch=obtch();
if(ch=='/') break;
else asterisco = 1;
}
}while(TRUE);
}else{
lexid[0]='/';
lexid[1]='\0';
token=barra;
return;
}
}
ch=obtch() ;
}


Como se puede apreciar a simple vista, en el bloque de cdigo anterior se crea un bucle en
el cual no se toman en cuenta y se eliminan los caracteres que se encuentran en la condicin
de la instruccin while ms externa. Una vez entramos a dicho while se procede a eliminar
tambin los comentarios de lnea y de bloque mientras aplique, para posteriormente extraer
otro carcter por medio de la funcin obtch y evaluarlo de nuevo en la condicin del while
con el objetivo de eliminarlo o de entrar en otra etapa del anlisis lexicogrfico.





C-5
3. Implementacin de los DFA diseados para el reconocimiento de los caracteres
lexicogrficos del lenguaje AEGOLI.


a) La implementacin del DFA para el reconocimiento de identificadores y palabras
claves es la siguiente:

if (isalpha(ch) || ch=='' || ch=='' || ch=='' || ch=='' || ch=='' || ch=='' || ch=='') {
switch(ch){
case '': cad[0]=0xA0; break ;
case '': cad[0]=0x82; break ;
case '': cad[0]=0xA1; break ;
case '': cad[0]=0xA2; break ;
case '': cad[0]=0xA3; break ;
case '': cad[0]=0xA4; break ;
case '': cad[0]=0xA5; break ;
}
lexid[0]=ch;
i=1;
while ( isalpha((ch=obtch())) || isdigit(ch) || ch==' || ch=='' || ch=='' || ch=='' || ch=='' ||
ch=='' || ch=='' || ch=='_') {
switch(ch){
case '': cad[0]=0xA0; break ;
case '': cad[0]=0x82; break ;
case '': cad[0]=0xA1; break ;
case '': cad[0]=0xA2; break ;
case '': cad[0]=0xA3; break ;
case '': cad[0]=0xA4; break ;
case '': cad[0]=0xA5; break ;
}

if (i<MAXID) lexid[i++]=ch;
}
lexid[i]='\0';


C-6
Luego, debido a que existe la posibilidad de que un identificador puede ser una palabra
reservada, luego con el lexema del identificador recientemente obtenido se procede a
realizar una bsqueda binaria en el arreglo de palabras reservadas llamado lexpal, el cdigo
es el siguiente:

j=0; k=MAXPAL-1;
while (j<=k) {
centro =((k+j) / 2);
if (strcmp(lexid,lexpal[centro])==0) {
ok=1;break;
} else
if (strcmp(lexid,lexpal[centro])<0)
k=centro-1;
else
j=centro+1;
}//fin while


Por ltimo, si el lexema se encontr en el arreglo el token ser una palabra reservada, en
caso contrario un identificado y por ltimo se copia en la variable lex:

if (ok==1)
token=tokpal[centro];
else{
token=identificador;
}
strcpy(lex,lexid);



b) La implementacin del DFA para el reconocimiento de nmero enteros y reales es
la siguiente:

if (isdigit(ch)) {
lexid[0]=ch;

C-7
i=j=1;
while ( isdigit( (ch=obtch()))) {
if (i<MAXDIGIT) lexid[i++]=ch;
j++;
}
lexid[i]='\0';
if (j>MAXDIGIT)
error(2); /*Este numero es demasiado grande*/


Si se sali del while en el cdigo anterior y prosigue un punto, entonces existe la
posibilidad de que sea un nmero real si existen ms dgitos luego del punto:

if(ch=='.'){
ch=obtch();
if(isdigit(ch)){
lexid[i++]='.';
lexid[i++]=ch;
j=1;
while ( isdigit( (ch=obtch()))) {
if (i<MAXDEC) lexid[i++]=ch;
j++;
}
lexid[i]='\0';
if (j>MAXDEC)
error(3); /*El mximo nmero de cifras*/
/*decimales ha sido sobrepasado*/
token=real;
valorReal=atof(lexid);
}


Si result ser solo un punto, por ejemplo el nmero 1122., se omitir el punto y se
considerar como un nmero entero:

C-8

else{
offset-=2;
ch=obtch();
token=entero;
valor=atol(lexid);
}
}


Si no era el caso de un punto se concluye que es un nmero entero

else{
token=entero;
valor=atol(lexid);
}



c) La implementacin del DFA para el reconocimiento de cadenas es la siguiente:

if(ch=='\"'){
loncad=1;
i=0;
while ( (ch=obtch())!='\"' && ch!='\n' ){
switch(ch){
case '': cad[0]=0xA0; break ;
case '': cad[0]=0x82; break ;
case '': cad[0]=0xA1; break ;
case '': cad[0]=0xA2; break ;
case '': cad[0]=0xA3; break ;
case '': cad[0]=0xA4; break ;
case '': cad[0]=0xA5; break ;
case : cad[0]=0\xA8; break;
case : cad[0]=0\xAD; break;

C-9
}
if(i<MAXLONCAD) cad[i++]=ch;
loncad++;
}
if(i>=MAXLONCAD) error(4);
if(ch=='\n' ) error(5);
cad[i]='\0';
token=cadena;
if(ch!='\n') ch=obtch();
}else



d) La implementacin del DFA para el reconocimiento de caracteres es la siguiente:

if(ch=='\''){
cad[0]=obtch();
switch(ch){
case '': cad[0]=0xA0; break ;
case '': cad[0]=0x82; break ;
case '': cad[0]=0xA1; break ;
case '': cad[0]=0xA2; break ;
case '': cad[0]=0xA3; break ;
case '': cad[0]=0xA4; break ;
case '': cad[0]=0xA5; break ;
case : cad[0]=0\xA8; break;
case : cad[0]=0\xAD; break;
}
cad[1]='\0';
ch=obtch();
token=caracter;
if(ch!='\'' ) error(6);
else ch=obtch();
}


C-10
e) Implementacin del reconocimiento de operadores.


Para el reconocimiento de operadores dobles se toma como ejemplo el operador mayor o
igual (>=) cuya implementacin sera la siguiente:

if (ch=='>') {
lexid[0]=ch;
ch=obtch();
if (ch=='=') {
lexid[1]=ch;
token = mayoroigual;
lexid[2]='\0';
ch = obtch();
} else {
token=mayor;
lexid[1]='\0';
}
}

En esta parte del cdigo tambin se detectan algunos operadores simples como se observa
para el smbolo mayor que (>).


Por ltimo, para los operadores simples no detectados con el mecanismo anterior y para los
smbolos especiales se usa el siguiente cdigo:

token=espec[ch];

Donde espec es un arreglo que se inicializa en la funcin init_espec( ), que dependiendo
del cdigo ASCII de ch reconoce el token correspondiente. As, por ejemplo, para el caso
del smbolo especial numeral (#), el token que le corresponde es el que se encuentra en la
posicin 35 del arreglo espec, debido a que el cdigo ASCII(decimal) de numeral es el
35.

C-11
4. Implementacin de herramientas para la presentacin de los errores.


1. Implementacin de la estructura del archivo .h

El archivo .h que contendr el arreglo de cadenas con todos los posibles errores a mostrar
ha sido nombrado Errores.h y su estructura se muestra a continuacin:

char *mensaje_de_error[]={error1, error2, error3,.., errorN}

Donde error1, error2, error3,.., errorN son cadenas de caracteres en un escenario donde
se han identificado N posibles errores a tiempo de compilacin.


2. Implementacin de la funcin encargada de mostrar los errores

La funcin que se encargar de mostrar los errores en tiempo de compilacin ha sido
nombrada simplemente error y su estructura se presenta a continuacin:

void error(int no){
if(PASADA==2){
++no_de_errores;
if(GUI==FALSE){
printf("\nL\xA1nea: %d - Error %d: %s Se encontr\xA2: '",
numlinea,no,mensaje_de_error[no]);
imprime_token(); printf("'");
}else{
ftemp=fopen("errores.xml","a");
if (ftemp==NULL){
printf("\nError al escribir el reporte de errores, se aborta el proceso de
compilaci\xA2n.\nPresione ENTER para terminar...");
while(getchar()!='\n');//Se limpia el buffer

C-12
liberarMemoria();
exit(1);
}
if(no_de_errores==1)
fprintf(ftemp,
"<?xml version=\"1.0\"?>\n<errores>\n");
fprintf(ftemp,"\t<error>\n\t\t<linea>%d</linea>\n\t\t
<codigo>%d</codigo>\n\t\t
<mensaje>%s</mensaje>\n\t\t
<info>Se encontro: ", numlinea,no,mensaje_de_error[no]);
imprime_token();
fprintf(ftemp,"</info>\n\t</error>\n");
fclose(ftemp);
}
}
}

Algunos elementos que son importantes de mencionar con respecto a la estructura de la
funcin error son:

no_de_errores se refiere a una variable de tipo entero que ser utilizada para contar
los errores que se encuentren durante todo el proceso de compilacin.

GUI es una variable global que indica que el compilador debe generar el reporte de
errores en un archivo externo. Esta variable contiene un valor de 1 (representado por
la macro TRUE) si se invoc al compilador se utiliz de la siguiente manera (ms
detalles en el Anexo D):

compilador <nombre programa> GUI


C-13
En caso contrario la variable GUI contiene un valor de 0 (representado por la macro
FALSE).

numlinea se refiere a una variable de tipo entero que ser utilizada para contar las
lneas del archivo fuente que se vayan leyendo, de forma que se pueda ubicar sin
problemas la lnea en donde ha ocurrido el error que se pretende comunicar.

La funcin imprime_token() escribe el ltimo lexema ledo desde el archivo fuente,
de forma que por cada error se pueda informar cul fue el lexema que lo gener.

La variable ftemp es un apuntador a archivo utilizado para el manejo del archivo
externo que contendr el reporte de los errores cuando el valor de GUI sea 1.

PASADA==2 indica que los errores son mostrados nicamente en la segunda
pasada del proceso de compilacin (ms informacin en la seccin 6).

En general, la variable GUI se utiliza para poder permitirle al compilador generar un
reporte de errores que pueda ser manipulado y presentado en un entorno grfico, de
manera que el compilador cuente con un mecanismo que le facilite su acoplamiento
a un entorno de desarrollo. El reporte de errores externo es generado en un archivo
XML que poseer la siguiente estructura para cada error producido:

<error>
<linea>LINEA</linea>
<codigo>CODIGO</codigo>
<mensaje>MENSAJE</mensaje>
<info>INFO</lexema>
</error>

Donde:

LINEA es el nmero de lnea en la que se encontr el error.

CODIGO es el cdigo del error.

C-14

MENSAJE es el mensaje que describe al error.

INFO es el ltimo lexema ledo (el lexema que provoc el error).




5. Implementacin de la tabla de smbolos.

En base a todo lo anteriormente planteado, la estructura de la tabla de smbolos queda
implementada en lenguaje C de la siguiente manera:

typedef struct Registro{
struct Registro* anterior;

char nombre[MAXID+1];
enum objeto tipo;
enum objeto subtipo;
enum objeto tipoDato;
int longitud;
int anchura;
int numparam;
int ownedbyfor;
enum nivel niv;
int dir;
struct ListaParam* abajo;

struct Registro* siguiente;
}Registro;

La macro MAXID, utilizada en el segundo campo de la estructura de la tabla de smbolos,
corresponder al mximo nmero de caracteres permitidos para el nombre de un objeto
dentro del lenguaje AEGOLI.

C-15
La enumeracin llamada nivel que puede apreciarse es utilizada dentro de la estructura de la
tabla de smbolos ser definida de la siguiente manera para el manejo de mbitos globales y
locales:
enum nivel{GLOBAL,LOCAL};

La enumeracin llamada objeto es utilizada dentro de la estructura de la tabla de smbolos
ser definida de la siguiente manera, tomando en cuenta los tipos de objeto almacenados,
sus caractersticas, y los tipos de datos soportados por el lenguaje AEGOLI:

enum objeto
{NULO,ALGORITMO,SUBALGORITMO,FUNCION,
PROCEDIMIENTO, VARIABLE,ARREGLO,MATRIZ,ENTERO,REAL,
CADENA, CARACTER};

Por ltimo, la estructura ListaParam es utilizada para almacenar los distintos parmetros
que un subalgoritmo puede poseer y se encuentra definida de la siguiente manera:

typedef struct ListaParam{
enum objeto subtipo;
enum objeto tipoDato;
struct ListaParam* siguiente;
}ListaParam;

Como puede verse, se trata de una lista lineal que contendr por cada parmetro su tipo de
estructura (arreglo, matriz o variable simple) y su tipo de dato. Esta lista ser manipulada
utilizando un nodo de control.


A continuacin se expone brevemente a qu corresponde cada una de las variables que
conforman la estructura Registro:


C-16
Nombre Tipo Uso
anterior Registro* Enlazador hacia atrs para la lista lineal.
nombre char[] Nombre del objeto.
tipo enum objeto Tipo del objeto (algoritmo, subalgoritmo o variable).
subtipo enum objeto Tipo de subalgoritmo (funcin o procedimiento) o
tipo de estructura para las variables (arreglo o
matriz).
tipoDato enum objeto Tipo de dato para las funciones y variables (entero,
real, cadena o carcter).
longitud int Para el caso de las variables que son arreglos o
matrices, indica su longitud.
anchura int Para el caso de las variables que son matrices, indica
su anchura.
numparam int Nmero de parmetros para el caso de los
subalgoritmos.
ownedbyfor int Bandera utilizada para bloquear la utilizacin de una
variable dentro de una instruccin
para si est siendo utilizada por sta para realizar la
iteracin.
niv enum nivel Indica, para el caso de las variables, si se trata de una
variable global o de una variable local.
dir int Indica la direccin de una variable dentro del mbito
al que pertenece.
abajo ListaParam* Apunta a una lista de elementos de tipo ListaParam
que representan, para el caso de un subalgoritmo, sus
parmetros.
siguiente Registro* Enlazador hacia adelante para la lista lineal.
Tabla C-1. Campos de la tabla de smbolos.




C-17
a) Implementacin de los elementos necesarios para la manipulacin de la tabla de
smbolos.

i. Apuntador al primer registro de la tabla de smbolos.

El apuntador al primer registro ha sido nombrado tabla y ser una variable global dentro
del cdigo fuente del compilador. Su definicin ser la siguiente:

Registro* tabla=NULL;

Ser hasta el inicio del proceso de compilacin, es decir, la funcin main del compilador,
que este apuntador ser inicializado utilizando la funcin designada a la creacin de nuevos
registros.


ii. Apuntador al ltimo registro de la tabla de smbolos.

El apuntador al ltimo registro aadido a la tabla de smbolos ha sido nombrado it y ser
tambin una variable global dentro del cdigo fuente del compilador. Su definicin ser la
siguiente:

Registro* it=NULL;

Esta variable tambin ser inicializada utilizada la funcin encargada de la creacin de
nuevos registro al inicio del proceso de compilacin.


iii. Funcin creadora de nuevos registros.

Esta funcin ha sido nombrada crearRegistro y su definicin es la siguiente:


C-18

Registro* crearRegistro(){
Registro* temp=NULL;
temp=(Registro*)malloc(sizeof(Registro));
temp->anterior=temp->siguiente=NULL;
return temp;
}

La funcin no contar con ningn parmetro y se encargar esencialmente de la creacin de
un nueva variable de tipo Registro (un registro nuevo para la tabla de smbolos) reservando
el espacio en memoria necesario y aterrizando sus enlazadores.


iv. Funcin almacenadora de registro en la tabla de smbolos.

Esta funcin ha sido nombrada poner y su definicin es la siguiente:

void poner(enum objeto tipo, enum objeto subtipo, enum objeto tipoDato,
int longitud, int anchura, int numparam){
it->siguiente = crearRegistro();
it->siguiente->anterior = it;
it=it->siguiente;

strcpy(it->nombre,lex);
it->tipo = tipo;
it->subtipo = subtipo;
it->tipoDato = tipoDato;
it->longitud = longitud;
it->anchura = anchura;
it->numparam = numparam;
it->ownedbyfor = FALSE;

C-19
it->niv = niv;
it->dir = nvar;
if(subAlg!=NULL) it->dir=it->dir + contadorParametros;
if(tipo==SUBALGORITMO)it->abajo = crearParametro();
else it->abajo = NULL;

it->siguiente = tabla;
tabla->anterior = it;
}

Esta funcin recibe como parmetros la mayora de elementos que contiene un registro en
la tabla de smbolos. Es importante notar que para el caso de un registro que no necesite la
totalidad de dichos elementos algunos de ellos poseern un valor nulo, esto no provocara
ninguna dificultad ya que dichos elementos no seran utilizados por las mismas razones.

Uno de los elementos que no se incluye como parmetro es el que corresponde al campo
ownedbyfor, ya que este es un indicador que solo se utiliza al momento que un objeto de
tipo variable es utilizada dentro de una instruccin para, por lo que la activacin y
desactivacin de esta bandera sern colocadas dentro del proceso de evaluacin de la
instruccin para, y dentro de la funcin poner ser suficiente inicializarlo con una valor
booleano falso (valor 0).

El otro elemento que no se incluye como parmetro de la funcin es el nombre del objeto a
almacenar dentro de la tabla de smbolos. Esto es debido a que se ha considerado que esta
funcin ser utilizada exclusivamente despus de la extraccin de un token desde el cdigo
fuente de un programa escrito en el lenguaje AEGOLI, lo que implicara que el nombre del
objeto se encontrara en ese momento almacenado en un arreglo de caracteres designado
para dicha tarea. La variable lex que puede observarse en el cdigo de la funcin poner
corresponde a este arreglo de caracteres.


C-20
La variable contadorParametros es una variable global que despus de una evaluacin de
declaracin de subalgoritmo contiene su cantidad de parmetros. La variable subAlg acta
como una bandera que indica que se ha declarado un subalgoritmo y que debe utilizarse el
valor almacenado en contadorParametros.

La funcin crearParametro es similar en estructura y funcionamiento a crearRegistro y su
definicin es la siguiente:
ListaParam* crearParametro(){
ListaParam* temp=NULL;
temp=(ListaParam*)malloc(sizeof(ListaParam));
temp->siguiente=NULL;
return temp;
}




v. Funcin encargada de buscar un registro en la tabla de smbolos


Esta funcin ha sido nombrada posicion y su definicin es la siguiente:

Registro* posicion(){
Registro* i;
strcpy(tabla->nombre,lex);
i=it;
while ( (strcmp(i->nombre,lex)) !=0)
i=i->anterior;
return(i);
}

Las razones por las que esta funcin hace uso del arreglo de caracteres encargado de
almacenar nombres de objetos (la variable lex) son las mismas que las expuestas
anteriormente para el caso de la funcin poner.

C-21

Una variante de esta funcin es necesaria para las etapas declarativas de un programa
escrito en el lenguaje AEGOLI:
Registro* posicionAmbito(){
Registro* i;
strcpy(tabla->nombre,lex);
i=it;
while((strcmp(i->nombre,lex))!=0
&& i->tipo!=SUBALGORITMO)
i=i->anterior;
if(i->tipo==SUBALGORITMO)
return tabla;
else
return i;
}

Esta variante se basa en la idea del control de mbitos para las variables. Una variable
puede tener dos posibles mbitos: un mbito global, una variable que se declara fuera de
cualquier subalgoritmo y pueden ser utilizadas en cualquier lugar de un programa; o un
mbito de subalgoritmo, una variable que se declara dentro de algn subalgoritmo
(incluyendo el subalgoritmo principal) y pueden ser utilizadas en cualquier parte de la
definicin del subalgoritmo al que pertenecen.

La funcin posicionAmbito busca un objeto de tipo variable (la funcin no se utilizar para
buscar ningn otro tipo de objeto) hasta llegar a la posicin reservada de la tabla de
smbolos o hasta encontrar un objeto de tipo subalgoritmo, lo que permite lo siguiente:

Evaluar la declaracin y redefinicin de variables dentro del mbito de un
subalgoritmo.


C-22
Permitir la renuncia al uso de una variable global en el caso que una variable de
subalgoritmo posea el mismo nombre.

La funcin posicionAmbito se auxilia de la siguiente funcin para poder realizar sus
operaciones correctamente:

void eliminarVariables(){
Registro *temp;
while(it->tipo!=SUBALGORITMO){
if(it==tabla){
free(tabla);
break;
}
temp=it;
temp->anterior->siguiente=temp->siguiente;
temp->siguiente->anterior=temp->anterior;
it=temp->anterior;
free(temp);
}
}

Esta funcin se ejecuta al final de la definicin de un subalgoritmo y se encarga de eliminar
todas las variables y parmetros que le pertenezcan de manera que al ejecutar una bsqueda
mediante la funcin posicionAmbito sta no pueda encontrarse de ninguna manera con una
variable que le pertenezca a algn otro subalgoritmo, respetando as el mbito para una
variable de subalgoritmo.


vi. Funcin liberadora de memoria utilizada por la tabla de smbolos.

Esta funcin ha sido nombrada liberarMemoria y su definicin es la siguiente:

C-23
void liberarMemoria(){
Registro* itemp,*itemp2;
if(tabla->siguiente!=NULL){
itemp=tabla->siguiente;
while(itemp!=tabla){
itemp2=itemp;
itemp=itemp->siguiente;
free(itemp2);
}
}
free(tabla);
}



6. Implementacin de dos pasadas para permitir el uso de recursin indirecta

Problema

Al modificar a sintaxis del lenguaje para la ejecucin de algoritmos en pseudo-cdigo para
eliminar la declaracin previa de subalgoritmos se provoc una problemtica, la cual se
ilustra en el siguiente ejemplo (donde se asume inexistencia de errores):

- Se declara y define el subalgoritmo A.
- Posteriormente se declara y define el subalgoritmo B.
- Dentro de la definicin de A se invoca a B.
- Durante el proceso de compilacin, B se agregara a la tabla de smbolos del
compilador despus de finalizar la evaluacin de A.
- Durante la evaluacin de A, al encontrar la invocacin a B se generara un error
1
a
pesar de que B existe y se encuentra correctamente declarado y definido.

1
En este caso el error Identificador no declarado.

C-24
Una consecuencia directa de este fenmeno es la imposibilidad de utilizar recursin
indirecta en un programa escrito en el lenguaje AEGOLI.


Solucin

Para solucionar esta problemtica el compilador se adapt a un proceso de dos pasadas
sobre el archivo fuente que contendr el programa escrito en el lenguaje AEGOLI:

La primera pasada se encargar de identificar nicamente las firmas de los
subalgoritmos declarados dentro del programa, almacenando cada subalgoritmo
junto a sus parmetros en una tabla de smbolos provisional.

La segunda pasada realizar el proceso normal de compilacin utilizando la tabla de
smbolos provisional en los casos donde se detecte una llamada a un subalgoritmo
no declarado previamente.

Cuando haya necesidad de buscar un subalgoritmo dentro de la tabla provisional y
ste no se haya encontrado se emitir el error correspondiente.

Por medio de esta estrategia se evita la problemtica antes planteada y podr entonces ser
posible el escribir programas en el lenguaje AEGOLI que utilicen mecanismos de recursin
indirecta.

La tabla de smbolos provisional ser definida como una lista lineal de la siguiente manera:

typedef struct RegProv{
char nombre[MAXID+1];
enum objeto tipo;
enum objeto subtipo;
enum objeto tipoDato;
int numparam;

C-25
int ic[100];
int contLlamada;
struct ListaParam* abajo;

struct RegProv *siguiente;
}RegProv;

Como puede verse, esta estructura cuenta con casi todos los campos con los que cuenta la
estructura correspondiente a la tabla de smbolos principal. Se han removido los campos
cuyo uso es exclusivo a variables, ya que el propsito de la tabla de smbolos provisional es
almacenar solamente subalgoritmos.

Se han aadido adems los siguientes campos:
ic es una arreglo que indica los lugares en el cdigo intermedio que se est
generando en dnde se llama al subalgoritmo antes de que este sea declarado, de
forma que se puedan realizar operaciones de backpatching.

contLlamada es un contador que indicar cuantas casillas de ic han sido utilizadas.


Al igual que la tabla de smbolos principal, la tabla de smbolos provisional contar con:

Un apuntador a la primera posicin:
RegProv* tablaProv=NULL;

Un apuntador a la ltima posicin:
RegProv* itProv=NULL;

Una funcin para crear un nodo:
RegProv *crearRegistroProv(){
RegProv *temp=NULL;
temp=(RegProv*)malloc(sizeof(RegProv));

C-26
temp->siguiente=NULL;
return temp;
}

Una funcin para ingresar un nodo a la lista:
void ponerProv(enum objeto tipo,
enum objeto subtipo,
enum objeto tipoDato, int numparam){
RegProv *Q=NULL;
itProv=crearRegistroProv();
strcpy(itProv->nombre,lex);
itProv->tipo=tipo;
itProv->subtipo=subtipo;
itProv->tipoDato=tipoDato;
itProv->numparam=numparam;
itProv->contLlamada=0;
itProv->abajo = crearParametro();

Q=tablaProv;
while(Q->siguiente)
Q=Q->siguiente;
Q->siguiente=itProv;
}

Una funcin para buscar un objeto dentro de la lista:
RegProv *posProv(){
RegProv *Q=NULL,*ip=NULL;
Q=tablaProv;
while(Q->siguiente){
Q=Q->siguiente;
if(strcmp(Q->nombre,lex)==0){

C-27
ip=Q;
break;
}
}
if(ip==NULL)ip=tablaProv;
return ip;
}

Por ltimo, es importante mencionar que todos estos elementos sern utilizados bajo las
mismas estrategias definidas para sus equivalentes correspondientes a la tabla de smbolos
principal.



7. Mecanismos para la construccin del rbol de parsing de expresiones numricas

Estos mecanismos fueron implementados ante la necesidad de contar con una manera de
realizar validaciones sobre las expresiones numricas, de manera que se pudiera mantener
una diferenciacin entre resultados booleanos y resultados aritmticos en un contexto
especfico.

En primer lugar, se defini una estructura para hacer posible la construccin de los rboles
de parsing. Esta estructura se denomin ArbolTok y su definicin es la siguiente:

typedef struct ArbolTok{
enum simbolo tkn;
char lex[MAXID+1];
int nlinea;
struct ArbolTok* izquierdo;
struct ArbolTok* derecho;
}ArbolTok;

C-28
Cada nodo del rbol almacenar un token, el lexema en el cdigo fuente equivalente al
token almacenado, y el nmero de lnea en el cdigo fuente en el que fue encontrado.

Como segundo paso, se construy una funcin que creara un nodo para el rbol. Esta
funcin fue nombrada crearNodoArbolTok y su definicin es:

ArbolTok* crearNodoArbolTok(){
ArbolTok* temp=NULL;
temp=(ArbolTok*)malloc(sizeof(ArbolTok));
temp->izquierdo=NULL;
temp->derecho=NULL;
return temp;
}

En tercer lugar se construy una funcin para eliminar el rbol despus de haber sido
utilizado. Esta funcin se llama limpiarArbolTok, su definicin es la siguiente:

void limpiarArbolTok(ArbolTok* n){
if(n!=NULL){
limpiarArbolTok(n->izquierdo);
limpiarArbolTok(n->derecho);
free(n);
}
}

Por ltimo, para los casos que sea necesario mostrar el contenido de un rbol de parsing, se
construyeron funciones que se encargaran de este proceso. Estas funciones son las
siguientes:

void mostrarArbolTok(ArbolTok* n){
printf("Arbol: ( ");

C-29
mostrarArbolTokPaso2(n);
printf(")\n");
}

void mostrarArbolTokPaso2(ArbolTok* n){
if(n!=NULL){
mostrarArbolTokAux(n->tkn);
printf(" ( ");
mostrarArbolTokPaso2(n->izquierdo);
printf(") ");
printf(" ( ");
mostrarArbolTokPaso2(n->derecho);
printf(") ");
}
}

void mostrarArbolTokAux(enum simbolo tkn){

switch(tkn) {
case mas:
printf("+ ");
break;
case menos:
printf("- ");
break;
case por:
printf("* ");
break;
case barra:
printf("/ ");
break;

C-30
case menor:
printf("< ");
break;
case menoroigual:
printf("<= ");
break;
case mayor:
printf("> ");
break;
case mayoroigual:
printf(">= ");
break;
case igual:
printf("== ");
break;
case diferente:
printf("!= ");
break;
case conjuncion:
printf("& ");
break;
case disyuncion:
printf("| ");
break;
case negacion:
printf("! ");
break;
case entero:
printf("e ");
break;
case real:

C-31
printf("r ");
break;
case identificador:
printf("i ");
break;
}
}

MostrarArbolTok inicializa el proceso colocando un ttulo al despliegue y termina el
proceso colocando un salto de lnea.

MostrarArbolTokPaso2 realiza el proceso recursivo en el que se muestra un nodo
seguido de su hijo izquierdo, y posteriormente su hijo derecho.

MostrarArbolTokAux examina el token del nodo a imprimir e imprime su signo
correspondiente. La funcin toma en cuenta nicamente los tokens que pueden ser
almacenados dentro de un rbol de parsing para expresiones numricas: los operadores
lgicos, los operadores aritmticos, los nmeros enteros y reales, y los identificadores
(para el caso de las variables). Para nmeros enteros se utiliza como signo el carcter
e, mientras que los caracteres r e i se utilizan para nmeros reales e identificadores
respectivamente.









Figura C-1. Ejemplo de rbol de parsing para una expresin numrica.


C-32
El rbol de la figura C-1 muestra el rbol de parsing para la expresin:

( a*5 + 3 ) != 5.3

Este rbol se mostrara de la siguiente manera:

( != ( + ( * i e ) e ) r )


Se definieron dos contextos para la evaluacin del rbol de parsing de una expresin
numrica:

a. Contexto de condicin: cuando se coloca una expresin numrica en instrucciones
que depende del cumplimiento de una condicin (si, hacer, etc.).

b. Contexto aritmtico: cuando se coloca una expresin numrica en instrucciones que
necesitan un valor aritmtico como resultado de evaluar dicha expresin (asignacin
una variable, llamada a subalgoritmo, escritura de datos en consola, etc.).

Se construy una funcin por cada uno de estos contextos, de forma que se pueda validar el
rbol de parsing de una expresin numrica de acuerdo al contexto en que se encuentra. La
funcin que evala el rbol en un contexto aritmtico es la siguiente:

void validarArbolArit(ArbolTok* n){
enum simbolo tkn;
char lextemp [MAXID+1];
int nlineat;
if(n!=NULL){
if(n->tkn==menor || n->tkn==menoroigual ||n->tkn==mayor
||n->tkn==mayoroigual ||n->tkn==igual ||n->tkn==diferente
||n->tkn==negacion || n->tkn==conjuncion || n->tkn==disyuncion){

C-33
tkn=token;
token=n->tkn;
strcpy(lextemp,lexid);
strcpy(lexid,n->lex);
nlineat=numlinea;
numlinea=n->nlinea;
error(67);/*Expresin aritmtica incorrecta.*/
token=tkn;
strcpy(lexid,lextemp);
numlinea=nlineat;
}
validarArbolArit(n->izquierdo);
validarArbolArit(n->derecho);
}
}

En un contexto aritmtico, la expresin numrica se considerar invlida ante la presencia
de cualquier operador lgico. La funcin validarArbolArit, al encontrar alguno de estos
operadores, marca un error utilizando el contenido del nodo que provoc el error: el token
que gener el error, su lexema equivalente, y el nmero de lnea en el cdigo fuente donde
fue encontrado.


La funcin que valida el rbol de parsing de una expresin numrica en un contexto de
condicin es la siguiente:

int validarArbolCond(ArbolTok* n){
int izq,der;
int nlineat;
if(n!=NULL){
if(n->tkn==identificador || n->tkn==real ||n->tkn==entero)

C-34
//Se encontr resultado aritmtico
return 1;
else{
izq=validarArbolCond(n->izquierdo);
der=validarArbolCond(n->derecho);
if(n->tkn==menor || n->tkn==menoroigual ||n->tkn==mayor ||n->tkn==mayoroigual
||n->tkn==igual ||n->tkn==diferente){
if(izq == 1 && der ==1)
//Se encontr resultado booleano
return 2;
else{
nlineat=numlinea;
numlinea=n->nlinea;
errorDescr
2
(68,"Se intenta realizar una comparacin utilizando valores booleanos
o se ha utilizado un operador incorrecto.");
numlinea=nlineat;
}
}else
if(n->tkn==conjuncion
|| n->tkn==disyuncion){
if(izq==2 && der==2)
//Se encontr resultado booleano
return 2;
else{
nlineat=numlinea;
numlinea=n->nlinea;
if(n->tkn==conjuncion)
errorDescr(68,"Se intenta realizar una conjuncin utilizando valores
aritmticos o se ha utilizado un operador incorrecto.");

2
errorDescr es una variante de error que recibe directamente el mensaje descriptivo del error, en lugar de
recurrir al ltimo token ledo.

C-35
else
errorDescr(68,"Se intenta realizar una disyuncin utilizando valores
aritmticos o se ha utilizado un operador incorrecto.");
numlinea=nlineat;
}
}else
if(n->tkn==negacion){
if(izq==2 && der==0)
//Se encontr resultado booleano
return 2;
else{
nlineat=numlinea;
numlinea=n->nlinea;
errorDescr(68,"Se intenta realizar una negacin para un valor aritmtico o
se ha utilizado un operador incorrecto.");
numlinea=nlineat;
}
}else
if(n->tkn==mas || n->tkn==por || n->tkn==barra){
if(izq==1 && der == 1)
//Se encontr resultado aritmtico
return 1;
else {
nlineat=numlinea;
numlinea=n->nlinea;
errorDescr(68,"Se intenta realizar una operacin aritmtica utilizando
valores booleanos o se ha utilizado un operador incorrecto.");
numlinea=nlineat;
}
}else
if(n->tkn==menos){

C-36
if(izq==1 && der ==1)
//Se encontr resultado aritmtico
return 1;
else
if(izq==1 && der ==0)
//Se encontr resultado aritmtico
return 1;
else {
nlineat=numlinea;
numlinea=n->nlinea;
errorDescr(68,"Se intenta realizar una operacin aritmtica utilizando
valores booleanos o se ha utilizado un operador
incorrecto.");
numlinea=nlineat;
}
}
}
}else return 0; //No se encontr un resultado
}

En un contexto de condicin se toman en cuenta las siguientes situaciones:

- Un nodo que contenga un nmero entero, un nmero real o un identificador se
considera un resultado aritmtico.

- Un nodo que contenga un operador aritmtico, siempre y cuando sus hijos sean
vlidos, se considera un resultado aritmtico.

- Un nodo que contenga un operador lgico, siempre y cuando sus hijos sean vlidos,
se considera un resultado booleano.

- Un nodo que no contenga ningn tipo de token se considera un resultado nulo.

C-37

- Los hijos de un nodo que contenga un operador relacional se consideran vlidos si
producen resultados aritmticos.

- Los hijos de un nodo que contenga un operador de conjuncin o un operador de
disyuncin, se consideran vlidos si producen resultados booleanos.

- Los hijos de un nodo que contenga un operador de negacin se consideran vlidos si
el izquierdo produce un resultado booleano y el derecho produce un resultado nulo.

- Los hijos de un nodo que contenga un operador aritmtico se consideran vlidos si
producen resultados aritmticos.

- Los hijos de un nodo que contenga el operador menos (-)se consideran vlidos
tambin si el izquierdo produce un resultado aritmtico y el derecho produce un
resultado nulo (para el caso del operador - unario).


Utilizando todo lo anterior, una llamada a la funcin evaluadora de expresiones numricas
en un contexto aritmtico estara constituida de la siguiente secuencia de instrucciones:

ArbolTok* n;
n=crearNodoArbolTok();
expresionNumerica(setpaso,&n);
validarArbolArit(n);
//mostrarArbolTok(n);
limpiarArbolTok(n);

Para un contexto de condicin simplemente se invoca a la funcin validarArbolCond en
lugar de la funcin validarArbolArit.



C-38
El proceso de construccin del rbol se realiza en sentido inverso, comenzando por las
hojas para posteriormente conectarlas a sus nodos padres. Este proceso se repite hasta llegar
al nodo raz, que es el que se cre antes de llamar a la funcin evaluadora de expresiones
numricas.

Este proceso de construccin del rbol de parsing es dirigido por la misma sintaxis del
lenguaje AEGOLI. A manera de ejemplo, se coloca a continuacin el cdigo de la funcin
Expresion_Conjuncion:

void expresionConjuncion(int toksig[],ArbolTok** arbol){
ArbolTok* n=NULL,*izq=NULL,*der=NULL;
int entered=FALSE;
int setpaso[NOTOKENS];
char lext[MAXID+1];
int nlineat;

copia_set(setpaso,toksig);
setpaso[conjuncion]=1;

expresionRelacional(setpaso,&izq);

while (token==conjuncion) {
strcpy(lext,lexid);
nlineat=numlinea;
obtoken();

expresionRelacional(setpaso,&der);
n=crearNodoArbolTok();

if(entered==FALSE){
entered=TRUE;

C-39
n->izquierdo=izq;
}else n->izquierdo=(*arbol);

n->tkn=conjuncion;
strcpy(n->lex,lext);
n->nlinea=nlineat;
n->derecho=der;
(*arbol)=n;
n=izq=der=NULL;

gen(OPR,0,11,0,"",NULO,ENTERO);
}

if(entered==FALSE) (*arbol) = izq;
}

Como puede observarse, la estrategia de construccin del rbol es la siguiente:

- Se recibe como parmetro un doble apuntador al nodo padre del rbol que se
construir en la funcin activa.

- Para el rbol de la funcin activa, se crean apuntadores a un posible nodo principal
y a sus hijos izquierdo y derecho.

- Se enva por direccin el apuntador al hijo izquierdo a la funcin que se encargar
de evaluar la expresin que constituye el operando izquierdo del operador de la
funcin activa (para el ejemplo es el operador de conjuncin, &). Un rbol ser
construido durante este proceso y le ser asignado al apuntador enviado, de manera
que al volver el hijo izquierdo se encuentra completamente construido.


C-40
- Ante la ausencia de un operador, el hijo izquierdo es asignado al nodo padre
recibido como parmetro, constituyendo entonces la totalidad del rbol de la
funcin activa.

- Ante la presencia de un operador, se crea un nodo principal con el operador
encontrado, se le asigna su hijo izquierdo (el que fue construido al evaluar el
operando izquierdo) y se enva por direccin el apuntador al hijo derecho a la
funcin que evaluar el operando derecho.

- Al volver, un rbol se completa asignndole al nodo principal su hijo derecho.

- Al encontrarse ms operadores, el rbol construido se convierte en el hijo izquierdo
de un nuevo nodo principal, y se enva de nuevo el apuntador al hijo derecho a la
funcin que evaluar el nuevo operando.

- De no encontrase ms operadores, el ltimo rbol construido conforma el rbol de
la funcin activa y se le asigna al nodo padre recibido como parmetro.


Las hojas de estos rboles son construidas en las funciones Factor, Funcion_Numerica y
Funcion_Numerica_Cadena_Caracter:

- En Factor se construye un nodo cuyo token es entero al encontrar un nmero
entero, real al encontrar un nmero real, o identificador al encontrar una variable.

- En Funcion_Numerica y Funcion_Numerica_Cadena_Caracter, se construye un
nodo cuyo token es entero o real dependiendo del tipo de dato de retorno de la
funcin predefinida del lenguaje AEGOLI que se est evaluando.


Por ltimo, es importante mencionar que el rbol de parsing se utiliza exclusivamente para
validar el tipo de expresin utilizada en un contexto dado, y no se utiliza para ningn tipo
de evaluacin sintctica o semntica. Estas validaciones son siempre realizadas por las

C-41
funciones del analizador sintctico descendente del compilador, y la construccin del rbol
dentro de algunas de ellas es simplemente una tarea adicional.



8. Implementacin de conjuntos usando la funcin caracterstica de conjuntos

Definicin: Sea A un conjunto y x un elemento, entonces la funcin caracterstica para
A se define as:

A
x=


Como primer elemento de define una macro dentro del compilador que represente el
nmero total de tokens con los que se pueden trabajar (para el caso son 88):

#define NOTOKENS 88

De esta forma, utilizando la funcin caracterstica un conjunto como

{coma, finsiTok, corchea}

Queda representado mediante las siguientes lneas de cdigo:

int A[NOTOKENS];
A[coma] = A[finsiTok] = A[corchea] = 1;


Luego, utilizando esta estrategia pueden definirse las siguientes funciones:

1 , Si xA
0 , Si xA

C-42

i. Una funcin para crear un conjunto vaco.

void init_set(int conjunto[]){
int i;
for (i=0;i<NOTOKENS;++i)
conjunto[i]=0;
}


ii. Una funcin para hacer una copia de un conjunto.

void copia_set(int conjunto1[],int conjunto2[]){
int i;
for (i=0;i<NOTOKENS;++i)
conjunto1[i]=conjunto2[i];
}


iii. Una funcin para unir dos conjuntos.

void union_set(int conjunto1[],
int conjunto2[],int conjunto3[]){
int i;
for (i=0;i<NOTOKENS;++i)
if (conjunto2[i]==0 && conjunto3[i]==0)
conjunto1[i]=0;
else
conjunto1[i]=1;
}


C-43
iv. Funcin encargada de realizar salto de texto.

Esta funcin se encarga de aplicar lo definido en la Regla antipnico y la Regla de las
palabras claves, dado que ante la presencia de errores comienza a saltar texto de manera
inteligente mediante el uso de los conjuntos de tokens seguidores definidos para las
funciones del analizador sintctico.

void test (int conjunto1[],int conjunto2[],int n){
int conj_union[NOTOKENS];

if (conjunto1[token]==0) {
/*el token no esta en el conjunto1*/

error(n); /*se marca el error*/

union_set(conj_union,conjunto1,conjunto2);

/*se salta texto de manera inteligente*/
while (conj_union[token]==0)
obtoken();
}
}

conjunto1 es un conjunto de tokens deseados para el token que se encuentra activo
al momento de invocar a la funcin test.

conjunto2 es el conjunto de tokens seguidores de la funcin que realiz la
invocacin a la funcin test.

n es un cdigo de error.


C-44
La funcin evala si el token activo pertenece al conjunto de tokens deseados para poder
continuar con el proceso de compilacin sin problemas. En caso de que no lo sea, la
funcin comunica al usuario el error indicado por la variable n, realiza una unin entre los
dos conjuntos que recibi como parmetro y comienza a extraer tokens hasta encontrar uno
que pertenezca a este conjunto unin.

En otras palabras, ante la presencia de un error, la funcin test salta texto hasta encontrar un
token con el que se pueda continuar la compilacin en el punto donde fue interrumpida o
hasta encontrar un token seguidor de la funcin que se encontraba haciendo una evaluacin
sintctica al momento de invocar a la funcin test, esto ltimo con el objetivo de poder
continuar la compilacin en un punto posterior en el cdigo fuente a lo que corresponde a la
funcin que invoc a test.



9. Estrategia de generacin de cdigo intermedio

A continuacin se presenta una lista de las producciones de la gramtica del lenguaje
AEGOLI que generarn cdigo intermedio durante el proceso de compilacin,
especificando para cada una de ellas las instrucciones de cdigo intermedio que le
correspondern:

Produccin Cuerpo:
1. Se generar un INS de 3 posiciones con valor 0 para n al inicio de la
produccin para las variables de control del algoritmo.
2. Se generar un SAL antes de las definiciones de los subalgoritmos. El salto
se realizar hasta la instruccin que inicia la ejecucin del subalgoritmo
principal, valor que a estas alturas no se conocer.
3. Despus de las definiciones de los subalgoritmos se har un backpatching a
la instruccin de salto incondicional del punto anterior.

C-45
4. Se generar un INS de 3 posiciones con valor 0 para n antes de invocar a
Bloque para las variables de control del subalgoritmo principal.
5. Se generar un LLA para invocar al subalgoritmo principal como primer
paso de una ejecucin.

Produccin Declaracion_Variable:
1. Se generarn instrucciones INS para la variable en declaracin de manera
que pueda asignrsele el espacio necesario en la pila de memoria tomando
en cuenta el tipo de dato de la variable, su tipo de estructura (variable
sencilla, arreglo o matriz) y sus dimensiones,

Produccin Bloque:
1. Si corresponde al bloque de un subalgoritmo definido como procedimiento
se generar al final un OPR con la funcin 1 (fin de ejecucin de
procedimiento) especificando la cantidad de espacio en la pila utilizado por
las variable locales del subalgoritmo.
2. Si corresponde al bloque del subalgoritmo principal se generar al final un
OPR con la funcin 0 (fin de ejecucin de programa).

Produccin Instruccion:
1. Cuando se encuentra una instruccin retornar se generar un OPR con la
funcin 2 (fin de ejecucin de funcin) especificando la cantidad de espacio
en la pila utilizado por las variable locales del subalgoritmo.
2. Cuando se encuentre una instruccin terminaPrograma se generar un OPR
con la funcin 0 (fin de ejecucin de programa).

Produccin Variable:
Por cada variable declarada se tomarn en cuenta los siguientes aspectos:
1. Si se ha llamado a esta produccin desde la produccin
Llamada_Subalgoritmo se generar un CPY de la variable en evaluacin.

C-46
Los datos de esta variable (tipo de dato, tipo de estructura y dimensiones)
sern almacenados en variables globales para su uso en otras producciones.
2. Si se ha llamado a esta produccin desde las producciones Factor,
Dato_Cadena o Dato_Caracter, y se cumplen las siguientes dos
condiciones:
i. La variable es lo primero que se encontr dentro de la produccin
que invoc a Variable.
ii. A continuacin se encuentra una coma o un parntesis de cierre.
Se entender como un envo de variable por valor y se generar entonces un
CPY de la variable en evaluacin y se almacenarn sus datos en variables
globales al igual que en el punto anterior.
3. En caso de fallar alguna de las condiciones planteadas anteriormente se
evala si se ha llamado a esta produccin desde la produccin Asignacion,
de ser as, se almacenarn los datos de la variable para ser utilizadas al
momento del almacenamiento de datos correspondientes a Asignacion.
4. En caso que fallen todas las condiciones anteriores se entender que la
funcin pertenece a una expresin y simplemente se generar un CAR con el
valor de la variable (o de la posicin dentro de la variable para arreglos y
matrices) para su posterior utilizacin.

Produccin Asignacion:
1. Se generar un ALM en la variable especificada para realizar la asignacin
utilizando los datos almacenados en variables globales por parte de la
produccin Variable. Este ALM ser generado despus de haber evaluado
la expresin que indica el valor a asignar.

Produccin Llamada_Subalgoritmo:
1. Se generar al inicio un INS de tres posiciones con valor 0 para n para las
variables de control del subalgoritmo a ejecutar.

C-47
2. Por cada parmetro se evaluar si se trata de una variable enviada por
referencia, si se trata de una variable enviada por valor, o si se trata de una
expresin que genera un valor.
3. Si se trata de una expresin que genera un valor se generar un OPR con la
funcin 7 para verificar, en tiempo de ejecucin, que el tipo de dato del
resultado de la expresin sea el correcto.
4. Si se trata de una expresin que genera un valor se almacenar en una pila
de instrucciones un OPR con la funcin 5 (eliminar posiciones desde el tope
de la pila) especificando que se eliminar una casilla.
5. Si se trata de una variable enviada por valor se almacenar en una pila de
instrucciones un OPR con la funcin 5 especificando que se eliminarn
tantas casillas como utilice la variable que se enva por valor.
6. Si se trata de una variable enviada por referencia se almacenar en la pila de
instrucciones un RET utilizando los datos de la variable almacenados por la
produccin Variable.
7. Luego de evaluar los parmetros se generar un LLA especificando la
instruccin donde comienza el subalgoritmo a ejecutar.
8. Por ltimo, se colocar, comenzando desde el tope, lo almacenado en la pila
de instrucciones. De esta manera se podrn ejecutar el almacenamiento de
datos correspondiente a las variables enviadas por referencias y a la
eliminacin de posiciones de memoria innecesarias.

Produccin Instruccion_Si:
1. Se generar un SAC despus de evaluar la condicin de la instruccin. La
direccin del salto se desconoce en este momento.
2. Se generar un SAL despus de evaluar el primer bloque de instrucciones.
La direccin del salto se desconoce en este momento. Luego de generarlo se
har un backpatching al SAC del punto anterior.
3. Se har un backpatching al SAL del punto anterior despus de evaluar el
segundo bloque de instrucciones.


C-48
Produccin Instruccin_Hacer:
1. Despus de evaluar el bloque de instrucciones y la condicin de la
instruccin, se generar un SAC cuya direccin de salto no es conocida por
el momento.
2. Luego se efectuar un SAL hacia el inicio del bloque de instrucciones.
3. Por ltimo, se efectuar un backpatching al SAC del primer punto planteado
para esta produccin.

Produccin Instruccin_Mientras:
1. Despus de evaluar la condicin se generar un SAC. La direccin de salto
an no se conoce.
2. Despus de evaluar el bloque de instrucciones de generar un SAL hacia el
inicio de la evaluacin de la condicin.
3. Por ltimo, se efectuar un backpatching al SAC del primer punto planteado
para esta produccin.

Produccin Instruccin_Repetir:
1. Despus de evaluar el bloque de instrucciones y luego de evaluar la
condicin, se generar un SAC hacia el inicio del bloque de instrucciones.

Produccin Instruccin_Para:
1. Se generar un ALM sobre la variable de iteracin despus de evaluar la
expresin correspondiente a su valor inicial.
2. Despus de evaluar las expresiones que representan al valor final de la
iteracin y del paso, se generar un OPR con la funcin 3 (intercambio de
valores entre el tope y la segunda posicin de la pila).
3. Se generar un CAR de la variable de iteracin.
4. Se generar un OPR con la funcin 19 (evaluacin relacional entre el valor
del tope de la pila y del valor de la segunda posicin), es decir, evala si se
ha alcanzado el valor final de la iteracin.
5. Se generar un SAC cuya direccin de salto no se conoce todava.

C-49
6. Se evala el bloque de instrucciones.
7. Se generar un CAR de la variable de iteracin.
8. Se generar un OPR con la funcin 4 (suma del valor que se encuentra en la
tercera posicin de la pila de memoria con el valor del tope), es decir, se
sumar el paso a la variable de iteracin.
9. Se generar un ALM sobre la variable de iteracin utilizando el resultado
anterior.
10. Se generar un SAL hacia la direccin correspondiente a la instruccin CAR
generada en el tercer punto.
11. Se efectuar un backpatching a la instruccin SAC generada en el quinto
punto.
12. Al final se generar un OPR con la funcin 5 especificando que se
eliminarn 2 posiciones, de forma que se libere el espacio utilizado por el
paso y el valor final de la iteracin.

Produccin Instruccin_Leer:
1. Se generar un OPR con la funcin 30 (lectura de datos) indicando el tipo de
dato que desea obtener mediante el tipo de dato de la variable en la que se
desea almacenar el resultado de la operacin.
2. Se generar un ALM sobre la variable especificada utilizando los datos
ledos.
3. Los dos puntos anteriores se repetirn por cada variable colocada como
parmetro en la instruccin leer.

Produccin Instruccin_Escribir:
1. Despus de evaluar cada expresin a escribir en pantalla se generar un OPR
con la funcin 31 (escritura de datos).

Produccin Instruccin_Escribirln:
1. Despus de evaluar cada expresin a escribir en pantalla se generar un OPR
con la funcin 31 (escritura de datos).

C-50
2. Al escribir todos los elementos especificados se generar un OPR con la
funcin 32 (escritura de salto de lnea).

Produccin Instruccion_AbrirArchivo:
1. Despus de evaluar el parmetro de la funcin se generar un OPR con la
funcin 33 (apertura de archivo para la extraccin de datos).

Produccin Instruccion_LeerArchivo:
1. Se generar un OPR con la funcin 34 (lectura de datos desde un archivo)
indicando el tipo de dato que desea obtener mediante el tipo de dato de la
variable en la que se desea almacenar el resultado de la operacin.
2. Se generar un ALM sobre la variable especificada utilizando los datos
ledos.

Produccin Instruccion_CerrarArchivo:
1. Despus de evaluar el parmetro de la funcin se generar un OPR con la
funcin 35 (cierre de archivo para la extraccin de datos).

Produccin Expresion_Numerica:
1. Despus de cada dos expresiones de conjuncin evaluadas se generar un
OPR con la funcin 12 (disyuncin).

Produccin Expresion_Conjuncin:
1. Despus de cada dos expresiones de conjuncin evaluadas se generar un
OPR con la funcin 11 (conjuncin).

Produccin Expresion_Relacional:
1. Si dos expresiones aritmticas fueron evaluadas se generar un OPR con la
funcin equivalente al operador relacional utilizado.
2. Al final, se generar un OPR con la funcin 10 (negacin) si el operador de
negacin fue utilizado.

C-51
Produccin Expresion_Numerica:
1. Despus de cada trmino evaluado se generar un OPR con la funcin 21
(suma) o un OPR con la funcin 22 (resta) segn se haya especificado.

Produccin Termino:
1. Despus de cada factor evaluado se generar un OPR con la funcin 23
(multiplicacin) o un OPR con la funcin 24 (divisin) segn se haya
especificado.

Produccin Factor:
1. Si el factor es un nmero entero o un nmero real, se generar un LIT con el
valor especificado y su tipo de dato.
2. Al final, se generar un OPR con la funcin 20 (cambio de signo) si fue
utilizado el operador - unario un nmero impar de veces.

Producciones Funcion_Numerica, Funcion_Cadena y
Funcion_Numerica_Cadena_Caracter:
1. Se generar un OPR con la funcin equivalente a la funcin del lenguaje
AEGOLI utilizada.

Produccin Dato_Caracter:
1. Si se trata de un caracter, se generar un LIT con el caracter especificado y
con el tipo de dato caracter.

Produccin Dato_Cadena:
1. Si se trata de una cadena, se generar un LIT con la cadena especificada y
con el tipo de dato cadena.





C-52
10. Estrategia de implementacin del cdigo intermedio en la mquina virtual

A continuacin se plantea la manera en que cada instruccin de cdigo intermedio realizar
modificaciones sobre la pila de memoria de la mquina virtual:

Instruccin INS:
o Caso INS 0 X T:
Se crearn
3
X casillas en la pila de memoria que alojarn datos de tipo T. Si
X es 3 se entiende como la reserva de espacio para casillas de control, en
este caso a la primera casilla creada se le asignar CONTROL como tipo.

o Caso INS ARREGLO P T:
Reserva de espacio para una variable que es un arreglo del tipo T. Se crear
una casilla de control que contendr el valor de P, el cual corresponde a la
longitud del arreglo. Posteriormente se crearn P casillas.

o Caso INS MATRIZ P T:
Reserva de espacio para una variable que es una matriz del tipo T. Se
crearn una casilla que contendr el valor de P, el cual corresponde a la
cantidad de filas o de columnas de la matriz. Luego que se utilicen dos
instrucciones de este tipo de manera continua (lo equivalente a especificar
las filas y columnas de una matriz) se crearn PxQ casillas para el contenido
de la variable.


Instruccin LIT:
o Caso LIT 0 V T:
Se crear una casilla para colocar el dato V, el cual es del tipo de dato T.



3
La creacin de casillas se realiza sobre el tope de la pila de memoria.

C-53
Instruccin CAR:
o Caso CAR N D T:
Se crear una casilla para colocar el dato de tipo T que se encuentra en la
direccin D del nivel N. Si D es -1 indica que el valor de la direccin debe
ser extrado de la pila (el tope y la segunda posicin para el caso de las
matrices y nicamente el tope para el caso de los arreglos).

Instruccin ALM:
o Caso ALM N D T:
Se almacenar en la posicin D del nivel N el dato de tipo T que se
encuentra en el tope de la pila de memoria. Posteriormente se eliminar esta
casilla. Si D es -1 indica que el valor de la direccin debe ser extrado de la
pila (el tope y la segunda posicin para el caso de las matrices y nicamente
el tope para el caso de los arreglos).

Instruccin SAC:
o Caso SAC 0 D 0:
Si el valor de la casilla que se encuentra al tope de la pila es 0 la ejecucin
continuar en la instruccin que se encuentra en la posicin D del cdigo
intermedio.

Instruccin SAL:
o Caso SAL 0 D 0:
La ejecucin continuar en la instruccin que se encuentra en la posicin D
del cdigo intermedio.

Instruccin CPY:
o Caso CPY N D T:
Se crearn las casillas necesarias para copiar la variable de tipo de dato T
que comienza a partir de la direccin D en el nivel N.


C-54
Instruccin LLA:
o Caso LLA 0 D 0:
La ejecucin continuar en la direccin D del cdigo intermedio despus de
almacenar en una casilla de control el valor de la base actual de la pila y el
valor de la direccin donde continuar la ejecucin al finalizar el
subalgoritmo invocado.
Dado que al momento de ejecutar una instruccin LLA al tope de la pila se
encuentran los parmetros a enviar, se retroceder hasta encontrar una
casilla de tipo CONTROL para poder ubicar las casillas de control del
subalgoritmo a ejecutar. La cantidad de casillas retrocedidas se considerar
cmo la cantidad de casillas utilizadas por los parmetros del subalgoritmo a
ejecutar, este valor tambin ser almacenado en una casilla de control.

Instruccin RET:
o Caso RET N D T:
El contenido de la variable de tipo T que comienza en la posicin D del
nivel N ser reemplazado con las primeras X casillas de la pila de memoria,
donde X equivale a la cantidad de casillas utilizadas por la variable en
cuestin.

Instruccin OPR:
o Caso OPR 0 0 0:
Se finalizar la ejecucin del cdigo intermedio en la mquina virtual. No se
realizar ninguna operacin sobre la pila de memoria.

o Caso OPR V 1 0:
Las primeras V casillas a partir del tope de la pila se eliminarn. Este valor
V indica la cantidad de casillas utilizadas por las variables locales al
subalgoritmo que se est finalizando.

C-55
Se almacenarn en una pila temporal desde la casilla al tope de la pila hasta
la ltima casilla antes de las casillas de control. Estas casillas corresponden a
los valores actuales de los parmetros del subalgoritmo.
Se eliminarn las casillas almacenadas en la pila temporal de la pila de
memoria.
Se eliminarn las casillas de control del subalgoritmo (procedimiento) que
est finalizando, restaurando el valor de la base y de la siguiente instruccin
a ejecutar (valores que fueron almacenados en las casillas de control al
momento de invocar al subalgoritmo).
Se crearn las casillas necesarias para recolocar las casillas almacenadas en
la pila temporal sobre la pila de memoria.

o Caso OPR 0 2 T:
El valor de la casilla al tope de la pila se almacenar en una variable
temporal. Este es el valor de retorno del subalgoritmo (funcin) que se est
finalizando y deber ser de tipo T.
Se eliminar la casilla al tope de la pila. Se extrae de la casilla de control
correspondiente la cantidad de casillas utilizadas por los parmetros de la
funcin. Se recorrer dicha cantidad de casillas desde la ltima casilla de
control, de forma que el puntero de ubique en la ltima casilla utiliza por un
parmetro.
Se eliminarn las casillas desde del tope de la pila hasta la ltima casilla
utilizada por un parmetro de la funcin.
Se almacenar en una pila temporal desde la casilla al tope de la pila hasta la
ltima casilla antes de las casillas de control. Estas casillas corresponden a
los valores actuales de los parmetros del subalgoritmo.
Se eliminarn las casillas de control del subalgoritmo (procedimiento) que
est finalizando, restaurando el valor de la base y de la siguiente instruccin
a ejecutar (valores que fueron almacenados en las casillas de control al
momento de invocar al subalgoritmo).
Se crear una casilla para recolocar el valor de retorno de la funcin.

C-56

Se crearn las casillas necesarias para recolocar las casillas almacenadas en
la pila temporal sobre la pila de memoria.

o Caso OPR 0 3 0:
Se intercambiarn los valores de la casilla al tope de la pila y su casilla
inmediata inferior.

o Caso OPR 0 4 0:
Al valor que se encuentra en la casilla al tope de la pila se le sumar el valor
que se encuentra dos casillas abajo (la tercera posicin de la pila desde el
tope).

o Caso OPR X 5 T:
Se eliminarn X casillas comenzando desde el tope de la pila. Si T es
ARREGLO o MATRIZ se eliminarn casillas hasta encontrar casillas de
control para posteriormente eliminar las casillas de control.

o Caso OPR 0 6 0:
Se intercambiarn los valores de la casilla al tope de la pila y la casilla de la
tercera posicin.

o Caso OPR L 7 T:
Se verifica que la casilla al tope de la pila sea de tipo T. En caso contrario,
se informa que en la lnea L de cdigo en el archivo fuente hay un llamada a
un subalgoritmo con un parmetro con tipo de dato incorrecto.

o Caso OPR 0 10 0:
Si el valor al tope de la pila es 1 se cambiar a 0.
Si el valor al tope de la pila es 0 se cambiar a 1.


C-57
o Caso OPR 0 11 0:
Si el valor al tope de la pila y el valor en la casilla inmediata inferior son
distintos de 0, se eliminar la casilla al tope de la pila y se colocar 1 como
valor en el nuevo tope. Se colocar 0 en el nuevo tope en cualquier otro caso
(alguno de los valores en evaluacin es 0).

o Caso OPR 0 12 0:
Si el valor al tope de la pila y el valor en la casilla inmediata inferior son 0,
se eliminar la casilla al tope de la pila y se colocar 0 como valor en el
nuevo tope. Se colocar 1 en el nuevo tope en cualquier otro caso (alguno de
los valores en evaluacin es distinto de 0).

o Caso OPR 0 13 0:
Si el valor en la segunda posicin de la pila de memoria es menor que el
valor en el tope de la pila, se eliminar la casilla al tope de la pila y se
colocar 1 como valor en el nuevo tope. Se colocar 0 como valor en el
nuevo tope en cualquier otro caso.

o Caso OPR 0 14 0:
Si el valor en la segunda posicin de la pila de memoria es menor o igual
que el valor en el tope de la pila, se eliminar la casilla al tope de la pila y se
colocar 1 como valor en el nuevo tope. Se colocar 0 como valor en el
nuevo tope en cualquier otro caso.

o Caso OPR 0 15 0:
Si el valor en la segunda posicin de la pila de memoria es mayor que el
valor en el tope de la pila, se eliminar la casilla al tope de la pila y se
colocar 1 como valor en el nuevo tope. Se colocar 0 como valor en el
nuevo tope en cualquier otro caso.



C-58

o Caso OPR 0 16 0:
Si el valor en la segunda posicin de la pila de memoria es mayor o igual al
valor en el tope de la pila, se eliminar la casilla al tope de la pila y se
colocar 1 como valor en el nuevo tope. Se colocar 0 como valor en el
nuevo tope en cualquier otro caso.

o Caso OPR 0 17 0:
Si el valor en la segunda posicin de la pila de memoria es igual al valor en
el tope de la pila, se eliminar la casilla al tope de la pila y se colocar 1
como valor en el nuevo tope. Se colocar 0 como valor en el nuevo tope en
cualquier otro caso.

o Caso OPR 0 18 0:
Si el valor en la segunda posicin de la pila de memoria es distinto al valor
en el tope de la pila, se eliminar la casilla al tope de la pila y se colocar 1
como valor en el nuevo tope. Se colocar 0 como valor en el nuevo tope en
cualquier otro caso.

o Caso OPR 0 19 0:
Se crear una casilla para colocar el resultado de la siguiente operacin:
- Si el valor de la tercera posicin desde el tope de la pila es positivo
se compara si el valor al tope de la pila es menor o igual al valor de
la segunda posicin. De ser as, se colocar un 1 en el tope, en caso
contrario se colocar un 0.

- Si el valor de la tercera posicin desde el tope de la pila es negativo
se compara si el valor al tope de la pila es mayor o igual al valor de
la segunda posicin. De ser as, se colocar un 1 en el tope, en caso
contrario se colocar un 0.


C-59
o Caso OPR 0 20 0:
Se multiplicar el valor al tope de la pila por -1. El resultado se colocar al
tope de la pila.

o Caso OPR 0 21 0:
Se sumarn los valores del tope de la pila y de la segunda posicin. El
resultado se colocar en la segunda posicin de la pila y se eliminar la
casilla que se encuentra al tope.

o Caso OPR 0 22 0:
Se restar del valor al tope de la pila el valor de la segunda posicin. El
resultado se colocar en la segunda posicin de la pila y se eliminar la
casilla que se encuentra al tope.

o Caso OPR 0 23 0:
Se multiplicarn los valores del tope de la pila y de la segunda posicin. El
resultado se colocar en la segunda posicin de la pila y se eliminar la
casilla que se encuentra al tope.

o Caso OPR 0 24 0:
Se dividir entre el valor al tope de la pila el valor de la segunda posicin. El
resultado se colocar en la segunda posicin de la pila y se eliminar la
casilla que se encuentra al tope.

o Caso OPR 0 30 T:
Se leer un dato de tipo T desde consola. Se crear una casilla para colocar
el dato ledo.

o Caso OPR 0 31 0:
El dato al tope de la pila se escribir en consola. Se eliminar la casilla al
tope de la pila.

C-60

o Caso OPR 0 32 0:
Se escribir en consola un salto de lnea.

o Caso OPR 0 33 0:
Al tope de la pila debe encontrarse el nombre de un archivo de texto,
utilizando ese dato se abrir un flujo del archivo para permitir la extraccin
de datos. Al final, se eliminar la casilla al tope de la pila.

o Caso OPR 0 34 T:
Se leer un dato de tipo T desde el flujo activo para algn archivo de texto.
Se crear una casilla para colocar el dato ledo.

o Caso OPR 0 35 0:
Se cerrar el flujo del archivo para detener la extraccin de datos.

o Caso OPR 0 36 0:
Si se ha llegado al final del archivo se crear una casilla para colocar un
valor de 1. En caso contrario se crear una casilla para colocar un valor de 0.

o Caso OPR 0 100 0:
Crear una casilla para colocar el valor del nmero .

o Caso OPR 0 101 0:
Se calcular el seno del valor al tope de la pila, el resultado se colocar al
tope de la pila.

o Caso OPR 0 102 0:
Se calcular el coseno del valor al tope de la pila, el resultado se colocar al
tope de la pila.


C-61
o Caso OPR 0 103 0:
Se calcular la tangente del valor al tope de la pila, el resultado se colocar
al tope de la pila.

o Caso OPR 0 104 0:
Se calcular el arcoseno del valor al tope de la pila, el resultado se colocar
al tope de la pila.

o Caso OPR 0 105 0:
Se calcular el arcocoseno del valor al tope de la pila, el resultado se
colocar al tope de la pila.

o Caso OPR 0 106 0:
Se calcular la arcotangente del valor al tope de la pila, el resultado se
colocar al tope de la pila.

o Caso OPR 0 107 0:
El valor al tope de la pila ser sometido a un proceso de aproximacin por el
mtodo de truncamiento. El resultado se colocar al tope de la pila.

o Caso OPR 0 108 0:
El valor al tope de la pila ser sometido a un proceso de aproximacin por el
mtodo de redondeo. El resultado se colocar al tope de la pila.

o Caso OPR 0 109 0:
Se calcular el valor absoluto del valor al tope de la pila, el resultado se
colocar al tope de la pila.

o Caso OPR 0 110 0:
Se calcular la raz cuadrada del valor al tope de la pila, el resultado se
colocar al tope de la pila.

C-62
o Caso OPR 0 111 0:
Se calcular el logaritmo base 10 del valor al tope de la pila, el resultado se
colocar al tope de la pila.

o Caso OPR 0 112 0:
Se calcular el logaritmo natural del valor al tope de la pila, el resultado se
colocar al tope de la pila.

o Caso OPR 0 113 0:
Se calcular el nmero e elevado al valor al tope de la pila, el resultado se
colocar en el tope de la pila.

o Caso OPR 0 114 0:
Se dividir entre el valor al tope de la pila el valor de la segunda posicin.
La parte entera del resultado se colocar en la segunda posicin de la pila y
se eliminar la casilla que se encuentra al tope.

o Caso OPR 0 115 0:
Se calcular una potencia utilizando como exponente el valor al tope de la
pila y como base el valor en la segunda posicin. El resultado se colocar en
la segunda posicin de la pila y se eliminar la casilla al tope.

o Caso OPR 0 116 0:
Se dividir entre el valor al tope de la pila el valor de la segunda posicin. El
residuo de la divisin se colocar en la segunda posicin de la pila y se
eliminar la casilla que se encuentra al tope.

o Caso OPR 0 200 0:
Al tope de la pila y en la segunda posicin deben encontrarse datos de tipo
cadena, se concatenar la cadena al tope de la pila a la cadena que se
encuentra en la segunda posicin. La cadena resultante se colocar en la

C-63

segunda posicin de la pila y se eliminar la casilla que se encuentra en el
tope.

o Caso OPR 0 201 0:
Se extraer de la cadena que debe encontrarse en la tercera posicin de la
pila (contando desde el tope) una subcadena cuyo inicio y fin dentro de la
cadena original son indicados por los valores en la segunda posicin de la
pila y en el tope respectivamente. La cadena extrada se colocar en la
tercera posicin de la pila y se eliminarn las casillas del tope y de la
segunda posicin.

o Caso OPR 0 202 0:
Cada carcter de la cadena que debe encontrarse al tope de la pila ser
convertido a maysculas. La cadena resultante se colocar al tope de la pila.

o Caso OPR 0 203 0:
Cada carcter de la cadena que debe encontrarse al tope de la pila ser
convertido a minsculas. La cadena resultante se colocar al tope de la pila.

o Caso OPR 0 300 0:
Se compararn los caracteres que debern encontrarse al tope de la pila y en
la segunda posicin. El resultado de la comparacin ser un nmero entero y
ser colocado en la segunda posicin de la pila. La casilla al tope ser
eliminada.
El resultado ser:
- 0 si los caracteres son iguales.
- 1 si el carcter al tope de la pila es mayor.
- -1 si el carcter en la segunda posicin es mayor.



C-64
o Caso OPR 0 301 0:
Se compararn las cadenas que debern encontrarse al tope de la pila y en la
segunda posicin. El resultado de la comparacin ser un nmero entero y
ser colocado en la segunda posicin de la pila. La casilla al tope ser
eliminada.
El resultado ser:
- 0 si las cadenas son iguales.
- 1 si la cadena al tope de la pila es mayor.
- -1 si la cadena en la segunda posicin es mayor.

o Caso OPR 0 302 0:
Se buscar en la cadena que deber encontrarse en la segunda posicin de la
pila la secuencia de caracteres indicada por la cadena que deber encontrarse
al tope. La posicin en la cadena de bsqueda donde se encuentre la primera
aparicin de la cadena buscada ser colocada como resultado en la segunda
posicin de la pila, en caso de no encontrarse se colocar un -1. Por ltimo,
se eliminar la casilla al tope de la pila.

o Caso OPR 0 303 0:
Se calcular la longitud de la cadena que deber encontrarse al tope de la
pila. Este valor ser colocado en el tope de la pila.



11. Pasos para conectar el compilador y la mquina virtual a una interfaz

Si se desea utilizar el compilador de AEGOLI junto con una interfaz se recomienda seguir
los siguientes pasos:
1. Implementar un procedimiento para llamar a compilador.exe desde la interfaz, de
manera que sea llamado cuando el usuario decida compilar el archivo fuente activo
en la interfaz.

C-65
2. La llamada al ejecutable se debe hacer de la siguiente manera:

compilador <nombre archivo fuente> GUI

Notar que compilador, hace referencia al nombre del ejecutable a llamar y el
<nombre archivo fuente> y GUI son parmetros con los que se mandar a llamar. El
parmetro GUI le indica al compilador que ante la presencia de errores en el archivo
fuente el reporte de errores debe ser generado en un archivo externo.

3. El archivo que el compilador genera es un archivo XML llamado errores.xml. Un
ejemplo se muestra en la figura C-2.








Figura C-2. Contenido de archivo XML externo para el reporte de errores.

4. Luego, se deben implementar los procedimientos necesarios en la interfaz para leer
el contenido de errores.xml. La informacin extrada puede ser utilizada para
mostrar una lista de errores en la interfaz, donde cada elemento se encuentre
relacionado a una lnea en el cdigo fuente para facilitar la tarea de localizar el
error.

5. errores.xml no ser creado cuando no se encuentren errores durante el proceso de
compilacin, en estos casos se generar en su lugar un archivo binario externo cuyo
nombre es el mismo del archivo fuente con la extensin .ob, archivo que
corresponde al ejecutable del programa fuente sometido a compilacin.

C-66
Especficamente, este archivo contendr las instrucciones de cdigo intermedio, las
cuales podrn ser interpretadas por la mquina virtual al invocar a exec.exe.

6. Para realizar la ejecucin del programa, primero se debe implementar un
procedimiento para llamar a exec.exe desde la interfaz, de manera que sea llamado
cuando el usuario decida ejecutar un programa en AEGOLI una vez halla sido
compilado de manera exitosa.

7. La llamada al ejecutable se debe hacer de la siguiente manera:
exec <nombre archivo ejecutable (.ob)>

8. Por ltimo, para mostrar la ejecucin del programa se sugiere se invoque a la
consola del sistema operativo.











ANEXO D
MANUAL DE USUARIO



D-1
Introduccin

AEGOLI es un lenguaje de programacin diseado como una herramienta cuya finalidad es
ensear de manera sencilla y eficaz, a programadores principiantes, los conceptos y
tcnicas bsicas de programacin tales como: ciclos, control de flujo, manejo de variables,
etc.

AEGOLI est diseado para ser utilizado en un nivel de educacin media y educacin
superior, as como por parte de todos los estudiantes en general, profesores y profesionales
de otras reas del conocimiento que estn interesados en conocer los principios bsicos de
la programacin de computadoras como una herramienta para dar solucin a diversos
problemas.

Algunos requisitos para la utilizacin de las aplicaciones encargadas de compilar y ejecutar
un programa escrito en AEGOLI son:

El usuario debe poseer conocimientos elementales sobre lo que es una computadora.

Tener una experiencia mnima en el manejo de comandos de consola del sistema
operativo Windows.

Una nocin bsica sobre operaciones aritmticas y lgica matemtica.


AEGOLI est dirigido a personas que estn interesadas en aprender y conocer acerca de la
programacin de computadoras, en un nivel de principiante. El objetivo principal es la
enseanza mediante el uso de pseudocdigos.


D-2
1. Instalacin

El compilador del lenguaje AEGOLI consta de un archivo ejecutable llamado
Compilador.exe, mientras que la mquina virtual que ejecuta el cdigo intermedio generado
por el compilador es otro archivo ejecutable denominado Exec.exe.

Para un desempeo ptimo al momento de utilizar el compilador y la mquina virtual, los
archivos ejecutables deben ser colocados en la misma ubicacin en disco donde se
encuentren los archivos con cdigo fuente en lenguaje AEGOLI que se desean compilar y
ejecutar (tal y como lo muestra la figura D-1).
Figura D-1. Instalacin de compilador y mquina virtual.



2. Modo de utilizacin.

2.1 Compilador.exe

Debe abrirse una consola de Windows y ubicarse en la direccin en disco en donde fueron
colocados los archivos con cdigo fuente en lenguaje AEGOLI y el archivo
Compilador.exe. La figura D-2 muestra un ejemplo donde los archivos involucrados han
sido colocados en una carpeta llamada AEGOLI en el escritorio de la computadora:

D-3











Figura D-2. Ubicacin de Compilador.exe desde consola.

Para utilizar el compilador debe ejecutarse en consola el s iguiente comando:

Compilador <nombre archivo fuente>

Una vez ejecutado un archivo mediante el comando anterior podr visualizarse en consola
algo similar a lo que muestra la figura D-3:












Figura D-3. Compilacin de un programa.

D-4
En el resultado que puede apreciarse en la figura D-3 se visualizan dos secciones:

Una seccin que informa la ausencia de errores durante el proceso de compilacin.
Cuando se han encontrado errores esta seccin informar el total de errores
encontrados (ver figura D-5).

Una seccin que muestra el cdigo intermedio generado para el programa
compilado. Este cdigo intermedio ser el destinado a ser ejecutado por la mquina
virtual mediante el archivo Exec.exe.
Nota: No se genera cdigo intermedio si se encontraron errores durante el proceso
de compilacin.

El cdigo intermedio es generado en un archivo binario externo cuyo nombre es el mismo
del archivo fuente compilado y cuya extensin es .ob. La figura D-4 muestra el archivo
OB generado en el ejemplo anterior:
Figura D-4. Ejemplo de archivo OB generado.

Cuando un programa contiene errores un intento de compilacin se ver de la siguiente
manera:

Figura D-5. Compilacin de un programa con errores encontrados.


D-5
En este caso pueden destacarse las siguientes secciones:
Una seccin que muestra todos los errores encontrados informando lo siguiente para
cada uno de ellos:
o La lnea en el archivo fuente que contiene el error.
o El cdigo del error encontrado.
o Una breve descripcin del error.
o La palabra en el archivo fuente que se encontr al momento de detectar el
error.

Una seccin que informa el total de errores encontrados.


Para una presentacin alterna de los errores, puede invocarse a Compilador.exe de la
siguiente manera:

Compilador <nombre archivo fuente> GUI

El aadir el parmetro GUI le indica al compilador que ante la presencia de errores en el
archivo fuente el reporte de errores debe ser generado en un archivo externo. Esto permite
que el entorno grfico que invoc al compilador pueda contar con un medio de acceso a los
reportes generados para poder realizar una presentacin grfica de los mismos.

La figura D-6 muestra un ejemplo de utilizacin del parmetro GUI:
Figura D-6. Compilacin de un programa utilizando el parmetro GUI.

El reporte de errores es generado en un archivo externo como puede apreciarse en la figura
D-7, mientras que un ejemplo de la estructura del contenido de este archivo externo se
muestra en la figura D-8

D-6
Figura D-7. Ejemplo de archivo XML externo para el reporte de errores.

Figura D-8. Contenido de archivo XML externo para el reporte de errores.



2.2 Exec.exe

Al igual que para el caso del archivo Compilador.exe, debe abrirse una consola de
Windows y ubicarse en la direccin en disco en donde fueron colocados los archivos con
cdigo fuente en lenguaje AEGOLI y el archivo Exec.exe (ver figura D-2).

Para utilizar el compilador debe ejecutarse en consola el siguiente comando:

Exec <nombre archivo OB>

Una vez ejecutado un archivo mediante el comando anterior podr visualizarse en consola
algo similar a lo que muestra la figura D-9:


D-7




Figura D-9. Ejecucin de un programa.

Como puede observarse, a l ejecutar el comando la mquina virtual procede a ejecutar al
programa compilado.






Un error durante el proceso de ejecucin ser tratado como crtico y la ejecucin del
programa que provoc el error ser abortado. En consola se informar el error producido y
se le solicitar al usuario presionar la tecla ENT ER para finalizar (figura D-10).


Figura D-10. Error durante la ejecucin de un programa.




D-8

3. Generalidades del lenguaje AEGOLI

3.1 Estructura de un algoritmo y subalgoritmo.

La estructura general de un algoritmo es la siguiente:

algoritmo <Nombre_algoritmo>
inicio
<Declaracin de variables globales>
<subalgoritmo 1>
<subalgoritmo 2>
. . .
<subalgoritmo n>
principal()
comienza
<Declaracin de variables locales>
<instruccin 1>
< instruccin 2>
. . .
< instruccin n>
termina
fin

Mientras que la estructura general de un subalgoritmo es:

i. Si se trata de un procedimiento:
procedimiento <Nombre_procedimiento> (<parmetros>)
comienza
<Declaracin de variables locales>
<instruccin 1>

D-9
<instruccin 2>
. . .
< instruccin n>
termina


ii. Si se trata de una funcin:

funcion <tipo> <Nombre_procedimiento> (<parmetros>)
comienza
<Declaracin de variables locales>
<instruccin 1>
<instruccin 2>
. . .
< instruccin n>
termina

Nota: Una funcin debe poseer al menos una instruccin retornar por cada camino
de ejecucin dentro de su conjunto de instrucciones.



3.2 Palabras reservadas

El lenguaje AEGOLI consta de un conjunto de palabras, llamadas "palabras reservadas",
que son utilizadas para denotar las estructuras y funciones propias del lenguaje, estas
palabras no pueden ser utilizadas para nombrar variables, algoritmos o subalgoritmos.

Las palabras reservadas del lenguaje AEGOLI son las siguientes:

i. Palabras reservadas para la estructura de un algoritmo:

D-10
- algoritmo
- inicio
- fin

ii. Palabras reservadas para la estructura de un subalgoritmo:
- principal
- procedimiento
- funcion
- ref
- comienza
- termina

Nota: principal() usa estas palabras tambin dado que es tratado como un
subalgoritmo ms, especficamente como un procedimiento.

iii. Palabras reservadas para declarar variables:
- entero
- real
- caracter
- cadena

iv. Palabras reservadas para el manejo de instrucciones de seleccin e iteracin:
- para
- paso
- finpara
- hacer
- mientrasque
- repetir
- hasta
- si
- entonces

D-11
- sino
- finsi
- mientras
- finmientras
- retornar
- terminaPrograma

v. Palabras reservadas para el manejo de instrucciones de lectura y escritura de datos:
- escribir
- escribirln
- leer
- abrirArchivo
- cerrarArchivo
- leerArchivo
- finalArchivo



3.3 Operadores

i. Operadores aritmticos

Un operador aritmtico es aquel que se utiliza para realizar operaciones de adicin,
sustraccin, multiplicacin y divisin.

Los operadores aritmticos que son vlidos en un algoritmo en AEGOLI son los siguientes:
Operacin Operador
Suma +
Resta -
Multiplicacin *
Divisin /
Tabla D-1. Operadores aritmticos.


D-12

ii. Operadores relacionales

Un operador relacional nos sirve para entender la relacin que tiene un valor respecto de
otro. Se basan en el concepto de verdadero o falso y en todos los casos operan con solo dos
estados diversos.

Los operadores relacionales son smbolos que se usan para comparar dos valores
aritmticos. Si el resultado de la comparacin es correcto la expresin considerada es
verdadera, en caso contrario es falsa.
Los operadores relacionales con los que se puede trabajar en AEGOLI son los siguientes:

Operacin Operador
Menor que <
Menor o igual que <=
Mayor que >
Mayor o igual que >=
Comparacin de igualdad = =
Diferente ! =
Tabla D-2. Operadores relacionales.


iii. Operadores Lgicos

Los operadores lgicos se utilizan para combinar valores lgicos (verdadero y falso) y
obtener nuevos valores lgicos que determinen el flujo de control de un algoritmo o
programa.
En AEGOLI los operadores lgicos son los siguientes:

Operacin Operador
Y lgico &
O lgico |
Negacin !
Tabla D-3. Operadores Lgicos.

D-13



iv. Operadores de asignacin

Un operador de asignacin sirve para asignar un valor y no para establecer relaciones de
igualdad. En otras palabras al utilizar este operador estamos creando como una fotocopia
del valor que queda a la derecha del operador en el lado de la izquierda del operador.

El signo de operacin para la asignacin es el siguiente:

Operacin Operador
Asignacin =
Tabla D-4. Operador de asignacin.




v. Operadores de concatenacin

Un operador de concatenacin sirve para crear una nueva cadena a partir de varias. En
AEGOLI se utiliza para concatenar y desplegar una sola cadena en el contexto de la
instrucciones escribir y escribirln. En cualquier otro contexto, la concatenacin se realiza
por medio de la funcin predefinida concatenarCadenas.


Operacin Operador
Concatenacin ,
Tabla D-5. Operador de concatenacin.




D-14

3.4 Variables

Una variable es una localizacin o casillero en la memoria principal que almacena un valor
que puede cambiar en el transcurso de la ejecucin de un algoritmo. Toda variable tiene un
nombre, un tipo de dato y un valor.

Antes de poder utilizar una variable es necesario declararla especificando su nombre y su
tipo de dato. Los tipos de datos existentes en el lenguaje AEGOLI son los siguientes:

Tipo Descripcin
entero Nmero entero positivo o negativo de
hasta 30 cifras.
real Nmero real positivo o negativo de hasta
30 cifras enteras con un mximo de 20
cifras decimales.
caracter Caracter ASCII simple. Se representa
entre comillas simples. Ej: a, b, etc.
cadena Secuencia de hasta 1000 caracteres
ASCII simples. Se representa entre
comillas dobles. Ej.: cadena,
AEGOLI, etc.
Tabla D-6. Tipos de datos existentes en AEGOLI.


Debido a que en AEGOLI no existen secuencias de escape, dentro de las cadenas no
pueden usarse comillas dobles y de igual manera, la comilla simple no puede usarse como
un dato tipo carcter.

Para declarar una variable se hace de la siguiente manera:

<tipo de dato> <nombre de la variable>


D-15
Ejemplo: Si se quiere declarar una variable de tipo de dato real, que guarde el valor de 3.4,
debemos poner antes de asignar el valor a sta, lo siguiente:

real a

El alcance de una variable se refiere a cuales subalgoritmos pueden hacer uso de ella. Una
variable definida en el cuerpo del algoritmo (es decir fuera de todo subalgoritmo) tiene un
alcance global, y puede ser accedida por cualquier subalgoritmo durante cualquier
momento de su ejecucin. Una variable dentro de un subalgoritmo no est disponible al
resto de subalgoritmos y por ello se dice que tiene un alcance local.



3.5 Tipos de estructuras

i. Arreglos

Un arreglo es una coleccin de datos del mismo tipo, que se almacenan en posiciones
consecutivas de memoria y reciben un nombre comn.


Se dice que un arreglo es:

- Finito: porque todo arreglo tiene un lmite, es decir, debe determinarse cul ser el
nmero mximo de elementos que podrn formar parte del arreglo.

- Homogneo: porque todos los elementos del arreglo deben ser del mismo tipo.

- Ordenado: porque se puede determinar cul es el primer elemento, el segundo, el
tercero, y as sucesivamente hasta llegar al n-simo elemento (la numeracin de
estos va de 0 a n-1).


D-16
Para referirse a un determinado elemento de un arreglo se deber utilizar un ndice, que
especifique su posicin relativa en el arreglo. Ejemplo:

entero A[5]
A[0]=2

De manera que la primera casilla del arreglo tendr un valor igual a 2.



ii. Matrices

Una matriz es un conjunto de datos homogneo, finito y ordenado, donde se hace referencia
a cada elemento por medio de dos ndices. El primero se utiliza para las filas y el segundo
para las columnas. Internamente en memoria se reservan MxN posiciones consecutivas para
almacenar todos los elementos de una matriz de M filas y N columnas. Ejemplo:

entero A[5,5]



iii. Arreglos y matrices como parmetros

Cuando en la lista de parmetros de un subalgoritmo se necesite un arreglo o una matriz
esto se debe indicar por medio del carcter especial #.

Ejemplo:

algoritmo matricesyarreglos
inicio
procedimiento asignar( entero A[#] )

D-17
comienza
A[0]=3
escribir(A[0]=,A[0])
termina

funcion entero dev( entero M[#,#] )
comienza
real R
R=5
retornar R*M[0,0]
termina

principal()
comienza
entero A[5],M[2,2]
/*llamada a un procedimiento con un arreglo*/
asignar(A)
/*Llamada a una funcin con una matriz*/
M[0,0]=5
escribirln(La funcin retorno: ,dev(M))
termina
fin



3.6 Instrucciones

i. Instrucciones de seleccin

Las instrucciones de seleccin son estructuras de control utilizadas para la toma de
decisiones dentro de un programa. A estas instrucciones se conocen tambin como

D-18
instrucciones selectivas o instrucciones de decisin, en AEGOLI se cuenta con la
representante ms sencilla: la instruccin de seleccin si.
Con la instruccin si se puede ejecutar una accin o un grupo de acciones slo si se cumple
una determinada condicin. Su estructura es la siguiente:

si (condicion) entonces
instruccion1
instruccion2
...
instruccionN
sino
instruccion1
instruccion2
...
instruccionN
finsi

La clusula sino es opcional. Si la condicin es verdadera, se ejecutarn las sentencias
dentro del bloque si, mientras que si es falsa, se ejecutar el bloque de sentencias de sino.



ii. Instrucciones de iteracin

Las instrucciones de iteracin sirven para ejecutar repetidamente un bloque de
instrucciones. En el lenguaje AEGOLI se permiten las siguientes:

- para

Instruccin de iteracin "fija", que permite ejecutar el conjunto de sentencias que se
encuentran dentro de ella un nmero determinado de veces, este nmero es fijado al

D-19
principio de la estructura y funciona por tanto como un contador. Su estructura es la
siguiente:


para <variable>=<valor1> hasta <valor2> paso <valor3> hacer
instruccion1
instruccion2
...
instruccionN
finpara

La variable comienza en valor1 y despus de cada iteracin se le agrega el valor del paso
(valor3), las iteraciones finalizan cuando la variable ha alcanzado el valor lmite (valor2).
Si el paso es negativo, ste se le resta a la variable en cada iteracin, donde se realizara un
conteo en descendencia.




- mientras

Instruccin de iteracin utilizada para ejecutar las sentencias contenidas dentro de esta
estructura mientras se cumpla cierta condicin establecida al principio de ella. Su estructura
es la siguiente:

mientras(condicin)
instruccion1
instruccion2
...
instruccionN
finmientras

D-20


- hacer

Instruccin de iteracin utilizada para ejecutar un nmero de sentencias mientras se cumpla
cierta condicin establecida. A diferencia de la instruccin mientras, esta instruccin se
ejecutara al menos una vez, puesto que la condicin se evala al final de cada ejecucin de
las sentencia. Su estructura es la siguiente:

hacer
instruccion1
instruccion2
...
instruccionN
mientrasque(condicin)


- repetir

Instruccin de iteracin utilizada para ejecutar un nmero de sentencias hasta que se
cumpla cierta condicion establecida. Al igual que la estructura hacer, esta estructura se
ejecutara al menos una vez, puesto que la verificacin de la condicin ofrece esa
posibilidad. Su estructura es la siguiente:

repetir
instruccion1
instruccion2
...
instruccionN
hasta(condicin)


D-21


3.7 Instrucciones escribir y escribirln

Estas son instrucciones que se utilizan para mostrar valores de variables en la consola as
como tambin valores literales o constantes.

La nica diferencia entre ambas instrucciones es que escribirln coloca un salto de lnea
luego de colocar todos sus parmetros en consola, mientras que escribir no lo hace. Los
parmetros de estas instrucciones se separan por el operador de concatenacin ,.
Ejemplo:

algoritmo
inicio
principal()
comienza
area=25
escribir(El rea del circulo es , area, metros cuadrados)
termina
fin

Resultado
en consola: El rea del circulo es 25 metros cuadrados



3.8 Instruccin leer

Instruccin que se utiliza para asignar valores a variables desde el teclado. Se pueden
colocar varias variables separadas por comas dentro de la instruccin:

leer(<var1>,<var2>,,<varN>)

D-22

Si es una casilla de un arreglo el nombre del arreglo debe ir seguido por el nmero de la
casilla entre corchetes. Ejemplo:

leer(A[8])

Si es una casilla de una matriz el nombre de la matriz debe ir seguido por la fila y la
columna entre corchetes y separados por coma. Ejemplo:

leer(Tablero[2,1])





3.9 Instrucciones para la extraccin de datos desde archivos de texto.

Como primer paso, el archivo de texto debe ser abierto para prepararlo a la extraccin de
datos, esto se realiza mediante la instruccin abrirArchivo:

abrirArchivo(<ruta archivo de texto>)

La ruta debe ser una cadena especificando la ubicacin en disco del archivo de donde se
extraern los datos. Si el archivo de texto se encontrar en la misma ubicacin del archivo
Exec.exe (la mquina virtual) puede colocarse exclusivamente el nombre del archivo de
texto. Ejemplos:
abrirArchivo(C:\Users\Usuario\Desktop\archivo.txt)
abrirArchivo(archivo.txt)

Nota: Slo podr mantenerse un archivo abierto a la vez, si dos instrucciones de este tipo
se colocan de manera consecutiva slo contar para la extraccin de datos la ltima que fue
colocada.

D-23

Como segundo paso se utiliza la instruccin leerArchivo, cuyo uso es igual al de la
instruccin leer, siendo la nica diferencia el hecho de que la instruccin leer archivo slo
puede leer una variable a la vez. Ejemplos:

leerArchivo(var)
leerArchivo(M[5,2])

Cada uno de los elementos dentro del archivo a leer, deben estar separados por un ENTER.


A veces ser necesario saber en qu momento se ha llegado al final del archivo para obtener
esta informacin se puede usar la funcin finalArchivo, la cual devuelve un valor de 1 si ya
se alcanz el final del archivo, y 0 en caso contrario. Un ejemplo de cmo podra utilizarse
se muestra a continuacin:

algoritmo manejoArchivos
inicio
principal( )
comienza
cadena cad
abrirArchivo(elementos.txt)
mientras (finalArchivo = = 0)
leerArchivo(cad)
escribirln(cad)
finmientras
cerrarArchivo( )
termina
fin

En el archivo elementos.txt los elementos deben encontrarse de la siguiente manera:

D-24


Elemento 1
Elemento 2
Elemento 3
Elemento 4
Elemento 5
Elemento 6
Elemento 7
Elemento 8
Elemento 9
Figura D-11. Ejemplo de contenido para un archivo txt.

Por ltimo, como se muestra en el ejemplo se debe cerrar el archivo mediante la siguiente
instruccin:

cerrarArchivo()



3.10 Envo de parmetros por valor y por referencia.

Al invocar un subalgoritmo que fue definido con parmetros, stos deben ser colocados en
la llamada, por ejemplo:

algoritmo parametros
inicio

procedimiento mostrar(caracter A, entero B)
comienza
escribirln(caracter de A ,A)
escribirln(valor de B: ,B)

D-25
termina

principal()
comienza
caracter c
entero i
c=f
i=3
mostrar(c,i)
termina
fin

En el ejemplo anterior, c e i han sido enviados como parmetros, en este caso han sido
enviados como parmetros por valor.


Un parmetro es enviado por valor cuando lo que se enva es su contenido de manera que
ste pueda ser utilizado en el subalgoritmo invocado sin que la variable sufra algn cambio.
En el ejemplo anterior, la variable c contiene el valor f, cuando c se enva como parmetro
por valor estar representada en el subalgoritmo mostrar a travs de la variable A, quien
puede ser manipulada y su valor alterado dentro del subalgoritmo. Sin embargo, c siempre
contendr f como valor sin importar lo que le suceda a A.


Otra manera de enviar un parmetro es por referencia. Cuando un parmetro se enva por
referencia su valor ser alterado de igual forma en que ser alterado el valor de la variable
que representar al parmetro en el subalgoritmo. En AEGOLI un parmetro se enva por
referencia colocando la palabra reservada ref antes del parmetro al momento de hacer la
invocacin.



D-26

Ejemplo:

algoritmo parametrosReferenciados
inicio

procedimiento cambiar(caracter A, entero B)
comienza
B=4
A=d
termina

principal()
comienza
caracter c
entero i
c=f
i=3
cambiar(c,ref i)
escribirln(caracter de c: ,c)
escribirln(valor de i: ,i)
termina
fin


En el ejemplo anterior, c ha sido enviado por valor mientras que i ha sido enviado por
referencia. i estar representado en el subalgoritmo cambiar por la variable B, y dado que
se envo por referencia, todo lo que le suceda al valor de B le suceder tambin al valor de
i.



D-27

3.11 Funciones predefinidas en el lenguaje AEGOLI

i. Funciones numricas

Las funciones numricas son funciones que realizan operaciones numricas sobre datos
numricos. Las funciones de este tipo existentes en AEGOLI son las siguientes:

Operacin Sintaxis Tipo de dato
devuelto
Restricciones
Obtener la parte
entera de una
divisin
div(entero1,entero2) Entero entero2 0
Obtener el residuo
de una divisin
mod(entero,entero2) Entero entero2 0
Elevar un nmero a
una potencia
potencia(numero,numero) Entero o real
Obtener el valor del
nmero
pi() Real
Evaluar la tangente
de un nmero
tangente(numero)

Real
Evaluar el seno de
un nmero
seno(numero) Real
Evaluar el coseno
de un nmero
coseno(numero) Real
Evaluar la arco-
tangente de un
nmero
arctan(numero) Real
Evaluar el arco-
seno de un nmero
arcsen(numero) Real
numero debe
estar en
[-1,1]
Evaluar el arco-
coseno de un
nmero
arccos(numero) Real
numero debe
estar en
[-1,1]
Truncar la parte
fraccionaria de un
nmero
truncar(numero) Real
Evaluar el valor
absoluto de un
nmero
absoluto(numero) Entero o real

D-28
Evaluar la raz
cuadrada de un
nmero
raz(numero) Entero o real numero 0
Redondear un
nmero a su
inmediato superior
redondear(numero) Real
Obtener el
logaritmo base 10
de un nmero
log(numero) Real

numero 1
Obtener el
logaritmo natural de
un nmero
ln(numero) Real numero 1
Obtener el nmero
elevado a una
potencia
exp(numero) Real
Tabla D-7. Funciones numricas.



ii. Funciones de cadena

Las funciones de cadena son funciones que devuelven datos de tipo cadena o valores
numricos realizando operaciones sobre datos de tipo cadena. Las funciones de este tipo
existentes en AEGOLI son las siguientes:

Operacin Sintaxis Tipo de dato
devuelto
Comparar dos cadenas
compararCadenas(
cadena 1, cadena 2)
Entero
Comparar dos caracteres
compararCaracteres(
caracter 1, caracter 2)
Entero
Obtener la longitud de una
cadena
longitudCadena(cadena) Entero
Concatenar dos cadenas concatenar(cadena 1, cadena 2) Cadena
Extraer una sub-cadena de
una cadena
extraerCadena(cadena, liminf,
limsup)
Cadena
Buscar una sub-cadena en una
cadena
buscarCadena(cadena 1, cadena 2) Entero

D-29
Convertir los caracteres de
una cadena en maysculas
cadenaMayusculas(cadena) Cadena
Convertir los caracteres de
una cadena en minsculas
cadenaMinusculas(cadena) Cadena
Tabla D-8. Funciones de cadena.


Una breve descripcin de la utilizacin y restricciones de las funciones de cadena en
AEGOLI pueden consultarse en la tabla D-9:

Funcin Comportamiento
compararCadenas(
cadena 1, cadena 2)
Retorna 0 si las cadenas son iguales,
retorna -1 si la cadena 1 es menor que la
cadena 2 y retorna 1 si la cadena 1 es
mayor que la cadena 2
compararCaracteres(
caracter 1, caracter 2)
Retorna 0 si los caracteres son iguales,
retorna -1 si el caracter 1 es menor que
el caracter 2 y retorna 1 si el caracter 1
es mayor que el caracter 2
longitudCadena(cadena) Retorna la longitud de la cadena
concatenar(cadena 1, cadena 2) Retorna una cadena que es la
concatenacin de cadena 2 en cadena 1
extraerCadena(cadena, liminf, limsup) Retorna una sub-cadena perteneciente a
cadena entre las posiciones liminf y
limsup.
Con:
1) 0 liminf limsup
2) limsup longitud de
cadena
buscarCadena(cadena 1, cadena 2) Retorna el valor entero correspondiente
a la posicin de la primera ocurrencia de
cadena 2 en cadena 1
cadenaMayusculas(cadena) Retorna la cadena con todos sus
caracteres en maysculas
cadenaMinusculas(cadena) Retorna la cadena con todos sus
caracteres en minsculas

D-30
Tabla D-9. Descripcin de funciones de cadena.

3.12 Instruccin terminaPrograma

Esta es considerada una funcin especial, dado que su uso, como su nombre lo indica,
termina la ejecucin de un programa hecho en AEGOLI de manera instantnea. Ejemplo:

algoritmo abortarPrograma
inicio
principal( )
comienza
entero i
para i = 0 hasta 10 paso 1
si(i == 4)entonces
terminaPrograma
escribirln(Este escribir no se realiza)
finsi
finpara
termina
fin

En el cdigo anterior en cuanto la variable de iteracin i alcance el valor de 4 el
programa finalizara sin que se ejecute el escribir que sigue y sin que necesariamente se
hagan las 10 iteraciones del para.



3.12 Comentarios


D-31
Un comentario es una porcin de texto dentro de un programa que no es tomada en cuenta
para el proceso de compilacin. En AEGOLI se utiliza // al inicio de una lnea para
comentar la lnea en su totalidad.

Ejemplo:

algoritmo comentarios//Ejemplo comentarios de lnea
inicio
principal()
comienza
caracter c
//carcter d
entero i
c=f
//d=h
i=3
unir(c,i)
termina
fin

En el ejemplo anterior la primera, tercera y sexta lnea han sido comentadas, lo que
significa que no sern tomadas en cuenta para el proceso de compilacin. Tambin se
pueden comentar bloques de cdigo utilizando los operadores /* y */. Ejemplo:

algoritmo comentariosBloque
/*Ejemplo comentarios
de bloque*/
inicio
principal()
comienza
caracter c

D-32
carcter d
entero i
c=f
//d=h
i=3
unir( /*d,*/ c, i)
termina
fin

Todo lo que se encuentre entre los operadores de comentado de bloque no ser tomado en
cuenta para el proceso de compilacin.



3.13 Listado de errores detectados por el compilador.

-Errores detectados por el scanner.

Cdigo
de error
Mensaje de error
1 Se ha alcanzado el final del archivo. Posible algoritmo incompleto.
2 Este nmero es demasiado grande.
3 El mximo nmero de cifras decimales ha sido sobrepasado.
4 La cadena es demasiado larga.
5 Falta la comilla de cierre de cadena.
6 Falta la comilla de cierre de caracter.
Tabla D-10. Lista de errores detectados por el scanner.


-Errores sintcticos detectados por el parser.


D-33
Cdigo
de error
Mensaje de error
7 Se esperaba un dato de tipo cadena.
8 Se esperaba 'fin'. Programa incompleto.
9 Se esperaba 'inicio'.
10 Se esperaba un identificador.
11 Se esperaba parntesis de cierre.
12 Se esperaba parntesis de apertura.
13 Se esperaba corchete de cierre.
14 Se esperaba 'termina'.
15 Se esperaba 'comienza'.
16 Se esperaba un nmero entero.
17 Se esperaba el tipo de la variable.
18 Se esperaba el operador de asignacin.
19 Se esperaba 'finsi'.
20 Se esperaba 'entonces'.
21 Se esperaba un operador relacional.
22 Se esperaba 'mientrasque'.
23 Se esperaba 'finmientras'.
24 Se esperaba 'hasta'.
25 Se esperaba 'finpara'.
26 Se esperaba 'paso'.
27 Se esperaba una coma.
28 Expresin incorrecta.
62 Se esperaba '#'.
63 Se esperaba 'hacer'
64 El algoritmo debe tener un subalgoritmo principal.
65 Se esperaba 'algoritmo'.

D-34
66 Hay cdigo despus del final del algoritmo.
67 Expresin aritmtica incorrecta.
68 Expresin condicional incorrecta.
Tabla D-11. Lista de errores sintcticos.
-Errores semnticos detectados por el parser.

Cdigo
de error
Mensaje de error
29 Identificador no declarado.
30 No se puede llamar a una variable o algoritmo.
31 No se puede realizar una asignacin a un subalgoritmo o algoritmo.
32 No se puede indexar una variable que no es arreglo.
33 Nmero de parmetros incorrecto.
34 No puede utilizarse como factor una variable de tipo cadena.
35 Se esperaba una variable de tipo 'entero'.
36 Se esperaba la especificacin de un tipo.
37 El identificador no corresponde a un subalgoritmo declarado.
38 Incompatibilidad de tipos con respecto a la declaracin previa del
subalgoritmo.
39 Este subalgoritmo no es una funcin, no debe retornar ningn valor.
40 Se esperaba una variable de tipo 'cadena'.
41 No se puede llamar a un algoritmo o llamar a una funcin sin utilizar
su valor de retorno.
42 No se pueden utilizar algoritmos o procedimientos como valores.
43 Se esperaba una variable de tipo 'caracter'.
44 Se esperaba una variable de tipo 'entero' o 'real'.
45 Una matriz necesita un indexado de par ordenado.
46 No se puede utilizar como parmetro un identificador previamente
asignado a un algoritmo o subalgoritmo.

D-35
47 Un arreglo no necesita un indexado de par ordenado.
48 La variable est siendo utilizada por una instruccin 'para'.
49 Identificador ya asignado a otro objeto.
50 Smbolo incorrecto al inicio de un algoritmo.
51 Smbolo incorrecto al inicio de una instruccin.
52 Al menos un camino de ejecucin en la funcin no posee una
instruccin 'retornar'.
53 El ndice debe ser mayor o igual a 1.
54 Declaracin incorrecta de subalgoritmo, la compilacin continuar
en el siguiente subalgoritmo.
55 Smbolo incorrecto al inicio de una declaracin.
56 Smbolo incorrecto en la declaracin de un parmetro.
57 Tipo de parmetro incorrecto
58 No se puede utilizar como variable de retorno un arreglo o una
matriz.
59 Se esperaba una funcin que retorne un nmero.
60 Se esperaba una funcin que retorne un caracter.
61 Se esperaba una funcin que retorne una cadena.
70 Limitacin especfica del compilador. El programa fuente es
demasiado largo.
Tabla D-12.Lista de errores semnticos.


-Errores detectados por la mquina virtual.

Nmero
de error
Mensaje de error
1 Desbordamiento de memoria.
2 Indexado que no utiliza un nmero entero.

D-36
3 Violacin de segmento.
4 Incompatibilidad de tipos en una asignacin
5 Se intenta asignar a una variable de tipo entero un valor que excede
los tamaos permitidos para nmeros enteros.
6 Tipo de dato incorrecto para el valor de retorno de una funcin.
7 Se intenta retornar como valor entero un valor que excede los
tamaos permitidos para nmeros enteros.
8 Se utilizan nmeros no enteros en una instruccin 'para'.
9 Se intenta enviar como parmetro un valor que excede los tamaos
permitidos para nmeros enteros.
10 Tipo de parmetro incorrecto en la lnea <numero_linea>.
11 Se intenta realizar una conjuncin sobre elementos no numricos.
12 Se intenta realizar una disyuncin sobre elementos no numricos.
13 Se intenta realizar una operacin relacional sobre elementos no
numricos.
14 Se intenta realizar una suma con elementos no numricos
15 El resultado de una suma es un nmero que excede los tamaos
permitidos para nmeros reales.
16 Se intenta realizar una resta con elementos no numricos
17 El resultado de una resta es un nmero que excede los tamaos
permitidos para nmeros reales.
18 Se intenta realizar una multiplicacin con elementos no numricos.
19 El resultado de una multiplicacin es un nmero que excede los
tamaos permitidos para nmeros reales.
20 Se intenta realizar una divisin con elementos no numricos.
21 Se intenta dividir entre cero.
22 El resultado de una divisin es un nmero que excede los tamaos
permitidos para nmeros reales.
23 Se esperaba un entero en la entrada

D-37
24 Se esperaba un real en la entrada.
25 Se esperaba un caracter en la entrada.
26 Error al abrir el archivo <nombre_archivo>
27 No se ha abierto ningn archivo.
28 Se alcanz el final del archivo al intentar hacer una lectura.
29 No se ha abierto ningn archivo para cerrarlo.
30 No se ha abierto ningn archivo para utilizar 'finalArchivo'
31 Se intenta evaluar el seno de un elemento no numrico.
32 Se intenta evaluar el coseno de un elemento no numrico.
33 Se intenta evaluar la tangente de un elemento no numrico.
34 El resultado de la funcin 'tangente' excede los tamaos permitidos
para nmeros reales.
35 Se intenta evaluar el arcoseno de un elemento no numrico.
36 Parmetro invlido para la funcin arcoseno.
37 Se intenta evaluar el arcocoseno de un elemento no numrico.
38 Parmetro invlido para la funcin arcocoseno.
39 Se intenta evaluar la arcotangente de un elemento no numrico
40 Se intenta truncar un elemento no numrico.
41 El resultado de la funcin 'truncar' excede los tamaos permitidos
para nmeros enteros.
42 Se intenta redondear un elemento no numrico.
43 El resultado de la funcin 'redondear' excede los tamaos permitidos
para nmeros enteros.
44 Se intenta obtener el valor absoluto de un elemento no numrico.
45 Se intenta evaluar la raz cuadrada de un elemento no numrico.
46 Se intenta evaluar la raz cuadrada de un nmero negativo.
47 Se intenta evaluar el logaritmo base 10 de un elemento no numrico.
48 Se intenta evaluar el logaritmo base 10 de un nmero negativo o 0.
49 Se intenta evaluar el logaritmo natural de un elemento no numrico.

D-38
50 Se intenta evaluar el logaritmo natural de un nmero negativo o 0.
51 Se intenta evaluar la funcin exponencial utilizando un elemento no
numrico.
52 El resultado de la funcin 'exp' excede los tamaos permitidos para
nmeros reales.
53 Se intenta realizar una divisin entera con elementos no numricos.
54 Se intenta dividir entre cero.
55 El resultado de la funcin 'div' excede los tamaos permitidos para
nmeros enteros.
56 Se intenta evaluar la funcin potencia con elementos no numricos.
57 El resultado de la funcin 'potencia' excede los tamaos permitidos
para nmeros reales.
58 Se intenta realizar una operacin de mdulo con elementos no
enteros.
59 Se intentan concatenar elementos que no son cadenas.
60 Cadena demasiado larga
61 Parmetros incorrectos para la funcin 'extaerCadena'.
62 Indices incorrectos para la extraccin de una subcadena
63 Se intenta convertir a maysculas un elemento que no es una cadena.
64 Se intenta convertir a minsculas un elemento que no es una cadena.
65 Se intentan comparar elementos que no son caracteres.
66 Se intentan comparar elementos que no son cadenas.
67 Se intentan usar elementos que no son cadenas en la funcion
buscarCadena.
68 Se intenta obtener la longitud de un elemento que no es una cadena.
Tabla D-13. Lista de errores detectados en tiempo de ejecucin.



3.14 Ejercicios de prctica

D-39

Para desarrollar la habilidad del estudiante, se describen a continuacin una serie de
ejercicios que se podrn resolver en el transcurso del aprendizaje.

Elabore para cada uno un programa en lenguaje AEGOLI que solucione lo que se pide:

1. Escriba un programa que lea dos nmeros enteros A y B, realice la comparacin y
despliegue un mensaje indicando cul es el mayor. Su programa tambin debe
considerar la posibilidad de que ambos nmeros sean iguales.

2. Dadas dos variables A y B, que representan nmeros enteros, obtener la suma,
diferencia, producto y cociente.

3. Escriba un algoritmo que, dado como entrada un nmero entero n, indique cuantos
millares, centenas, decenas y unidades componen dicho nmero.

4. Escriba un programa que imprima una lista de nmeros en orden ascendente,
iniciando desde 1 y terminando en 100.

5. Se pretende imprimir una lista de nmeros en orden ascendente, iniciando con el
valor n y terminando con el valor m. Realcelo de tres maneras distintas, utilizando
instrucciones para la ejecucin de iteraciones.

6. Escriba un programa que d como resultado la suma de todos los nmeros pares
que hay en el intervalo [n, m].
7. Para determinar si un ao es bisiesto se procede de la siguiente manera: si el ao es
divisible entre 400 se dice que es bisiesto. Si no es divisible entre 400, se prueba lo
siguiente: que sea divisible entre 4 y no sea divisible entre 100, si cumple esta
segunda premisa, se dice que es bisiesto, sino, no es bisiesto. Escriba un programa
que, dado un ao, diga si es bisiesto o no.


D-40
8. Escriba un programa que genere los primeros n trminos de la serie de Fibonacci.
Esta serie inicia con 0 y 1. Para determinar el k-simo elemento, se procede as:

ak = ak-1 + ak-2

9. Determine el factorial de un nmero entero N no negativo.

10. Dados dos nmeros enteros llamados Mayor y menor, obtener el mximo comn
divisor (MCD) de ambos por el mtodo de Euclides. Para resolver este problema se
procede as:

a) Se realiza la divisin entera del Mayor entre el menor.
b) Si el residuo es cero, el MCD est en la variable llamada menor, despliega
el resultado y termina el programa.
c) Pero si el residuo no es cero, el valor de menor pasa a Mayor y el valor de
residuo pasa a menor.
d) Repetir el paso a.

11. Determine el nmero combinatorio de dos nmeros n y k. Dado que parte del
proceso incluye el clculo de tres factoriales, utilice un subalgoritmo para el clculo
del factorial. La expresin para el clculo del nmero combinatorio es:



12. Dado un arreglo en cuyas casillas se guardan caracteres, indicar si la palabra de
longitud n, que est contenida en l, es palndrome. Ejemplo: anona.

13. Dada una matriz cuadrada M, indicar si la matriz es simtrica. Nota: una matriz es
simtrica si los elementos m(i, j) por encima de la diagonal principal, son iguales a
los m(j, i) por debajo de la diagonal.


D-41
14. Se tiene un vector de caracteres de longitud n, escriba un programa que indique
cuantas veces se repite cada vocal.

15. Entre los descuentos que debe realizar una empresa a sus empleados se encuentran
los siguientes:

ISS.
Renta (10% del sueldo bruto).
Anticipos.
AFP (segn a cul est afiliada el empleado).

Elabore un programa que lea los datos de n empleados y para cada uno de ellos
calcule el sueldo neto, descuentos y el sueldo neto a pagar.

Para solucionar los literales a y d investigue los detalles sobre cmo se realizan estos
descuentos. Adems de reportar los detalles sobre cada empleado, el programa debe
reportar un consolidado de descuentos y salarios.







ANEXO E
BATERA DE PRUEBAS



E-1
Batera de pruebas

El compilador y la mquina virtual fueron sometidos a una batera de pruebas con las
siguientes caractersticas:

o Fue registrada como un servicio de horas sociales.

o Cont con la colaboracin de 12 personas para su realizacin.

o El grupo de participantes estuvo conformado por estudiantes de 3 a 5 ao de la
carrera Licenciatura en Ciencias de la Computacin de la Universidad
Centroamericana Jos Simen Caas.

o Se llev a cabo en 7 sesiones de 3 horas durante un perodo de 2 semanas.

o Paralelamente se realizaron procesos de depuracin y correccin del proyecto,
basados en los resultados obtenidos durante las sesiones de pruebas.

A continuacin, se detallan las actividades realizadas con el grupo de participantes en cada
una de las sesiones de la batera de pruebas, mencionando los problemas encontrados y las
fallas detectadas. Adems, se expone para cada de uno de estos elementos la manera en que
fueron solucionados y, en donde aplica, se mencionan sus causas.


Sesin #1 (16 de agosto de 2010)

Agenda de trabajo:
i. Distribucin de compilador y mquina virtual a cada uno de los participantes.
ii. Distribucin de manual de AEGOLI a cada uno de los participantes.
iii. Lectura en comn del manual de AEGOLI, incluyendo explicacin y ejemplos de
cada uno de los elementos del lenguaje.
iv. Sesin de preguntas y respuestas sobre el contenido del manual.

E-2
v. Asignacin de ejercicios:
1. Hacer un programa que diga cuantos nmeros 4 existen entre 1 y 2000,
tomando en cuenta cada cifra de cada nmero. Ejemplos: 44 posee dos
nmeros 4, entre 1 y 4 hay un solo nmero 4, entre 40 y 50 hay 10 nmeros
4, etc.
2. Hacer un programa que dada una palabra diga si la palabra es palndroma.


Fallas encontradas:

La descripcin de las funciones div y mod se encontraba invertida en el manual de
usuario y, por lo tanto, tambin en el documento.
Solucin: se corrigi la descripcin de cada una de estas funcionas de forma que se
explicara adecuadamente lo que cada una de ellas realiza.

Los caracteres propios del lenguaje castellano (, , , , , y ) no se mostraban
adecuadamente en consola y no se lean adecuadamente desde el archivo fuente.
Causa: estos caracteres pertenecen a la tabla ASCII extendida. La consola de
Windows, algunos compiladores de C para Windows y algunas aplicaciones de
manipulacin de texto no incluyen la tabla ASCII extendida por defecto en sus
funcionalidades.
Solucin: en las secciones del scanner encargadas del reconocimiento de
identificadores y del reconocimiento de cadenas, al leer alguno de estos caracteres
desde el archivo fuente el valor se sustituye por su equivalente en hexadecimal en la
tabla ASCII extendida mediante el siguiente cdigo:

switch(ch){
case '': cad[0]=0xA0; break ;
case '': cad[0]=0x82; break ;
case '': cad[0]=0xA1; break ;
case '': cad[0]=0xA2; break ;

E-3
case '': cad[0]=0xA3; break ;
case '': cad[0]=0xA4; break ;
case '': cad[0]=0xA5; break ;
}

Para imprimir estos caracteres en consola se utiliz la misma estrategia: si era
necesario imprimir alguno de estos caracteres en consola se sustitua por su
equivalente en hexadecimal de la tabla ASCII extendida utilizando el operador de
escape de acuerdo a la tabla E-1:

\xA0
\x82
\xA1
\xA2
\xA3
\xA4
\xA5
Tabla E-1. Equivalentes de la tabla ASCII extendida para escapar caracteres del lenguaje castellano
en salidas a consola.

El compilador permita colocar una instruccin leer sin parmetros:
leer()
Solucin: se incluy esta validacin en la funcin del compilador encargada de la
evaluacin sintctica de la instruccin leer: al encontrar un parntesis de apertura se
genera un error si lo que le sigue es un parntesis de cierre.

Cuando en un test, durante un proceso de salto se alcanzaba el final de archivo, el
compilador intentaba seguir saltando texto, lo que provocaba un congelamiento del
proceso de compilacin.
Solucin: se incluyeron en las funciones encargadas del salto de texto validaciones
para terminar el proceso de compilacin al alcanzar el final del archivo.

E-4

El operador >= funcionaba igual que el operador >.
Solucin: se corrigi el funcionamiento de la funcin equivalente al operador >=
en la mquina virtual (OPR 16).

Cuando se utilizaba como variable de iteracin en la instruccin para un
identificador no declarado, ocurra un congelamiento del proceso de compilacin al
intentar utilizar su valor.
Solucin: se incluy un test en la funcin del compilador encargada de la
evaluacin sintctica de la instruccin para, de forma que el compilador pudiera
estabilizarse ante este caso: ignorando la declaracin de la instruccin ante un
identificador invlido (sea este el de la variable de iteracin, el del valor final o el
del paso).



Sesin #2 (18 de agosto de 2010)

Agenda de trabajo:
i. Distribucin de compilador y mquina virtual con las correcciones de la sesin 1 a
todos los participantes.
ii. Asignacin de ejercicios:
1. Pedir un nmero entero y una cadena. Realizar operaciones aritmticas sobre
este nmero hasta obtener un nmero entero entre 1 y 10, luego utilizar este
resultado para realizar un encriptacin de la cadena solicitada. El mtodo de
encriptacin es arbitrario.
2. Dadas dos matrices, A y B, de 5 filas y 5 columnas, realizar el producto de
ambas y al resultado obtenerle su matriz transpuesta.
3. Hacer un programa para jugar equis-cero.



E-5
Fallas encontradas:

El compilador permita colocar una instruccin escribir o escribirln sin parmetros:
escribir()
escribirln()
Solucin: se incluy esta validacin en las funciones del compilador encargadas de
la evaluacin sintctica de las instrucciones escribir y escribirln, de igual manera
que para el caso de la instruccin leer.

La mquina virtual no permita acceder a casillas vlidas de matrices e informaba
que los ndices eran incorrectos.
Causa: no se calculaba bien la posicin en la pila de memoria correspondiente a la
casilla de la matriz a la que se deseaba acceder.
Solucin: se corrigieron en la mquina virtual las condiciones utilizadas para
validar los ndices de matrices, de forma que siempre fuera posible determinar a qu
casilla en la pila de memoria se haca referencia.

No poda colocarse una instruccin para dentro de otra instruccin para.
Causa: el problema se deba a que los datos de la variable de iteracin del para
interno sustituan a los datos de la variable de iteracin del para externo.
Solucin: los datos de la variable de iteracin de una instruccin para se almacenan
en variable globales. Se crearon variable equivalentes locales dentro de la funcin
del compilador encargada de la evaluacin sintctica de la instruccin para, de tal
forma que se les asignara el valor de las variable globales antes de evaluar cualquier
otra instruccin. Esto permite que cada instancia de la instruccin para mantenga
activos los datos de su variable de iteracin.

Las instrucciones leer y leerArchivo no eran capaces de leer una cadena que tuviera
espacios.

E-6
Causa: en la mquina virtual estas operaciones se realizaban mediante la funcin
scanf del lenguaje C, la cual no permite la lectura de cadenas que contengan
espacios.
Solucin: se sustituy el uso de la funcin scanf por una lectura completa del buffer
de entrada de datos mediante el uso de la funcin getchar del lenguaje C.

Cuando un comentario de bloque no se cerraba, caso en el que el resto de un archivo
fuente debe ser considerado como comentario, se produca un congelamiento del
proceso de compilacin al encontrar el final del archivo.
Solucin: se incluyeron validaciones en la parte del scanner encargada del
reconocimiento de comentarios para terminar el proceso de compilacin al
encontrar el final del archivo fuente.

Se produca un congelamiento del proceso de compilacin al no asignarle un valor
de inicio a la variable de iteracin de una instruccin para.
Causa: durante la evaluacin en tiempo de compilacin de una instruccin para se
genera una sentencia de cdigo intermedio SAC
1
, en la que se coloca la direccin de
la primera sentencia de cdigo intermedio posterior al bloque de instrucciones
pertenecientes al para. Como dicha direccin no se conoce hasta despus de haber
evaluado la totalidad del para, es necesario realizar un backpatching sobre el SAC
generado.
Cuando no se le asignaba un valor de inicio a la variable de iteracin, la instruccin
para era ignorada y la sentencia SAC no era generada, intentando entonces realizar
un backpatching sobre un elemento de cdigo intermedio inexistente.
Solucin: se corrigi el mecanismo de generacin de cdigo intermedio equivalente
a la instruccin para, de tal forma que ante una mala declaracin no se realizara
ningn tipo de operacin relacionada con generacin de cdigo intermedio.

Se permita colocar como parmetro la variable de iteracin de un para en
instrucciones leer y leerArchivo pertenecientes al bloque de instrucciones del para.

1
Ver Anexo C

E-7
Esto permita una alteracin de su valor, lo cual se solicit que no fuera posible
como parte de los requisitos de funcionamiento del lenguaje AEGOLI.
Solucin: la funcin encargada de evaluar variables durante el proceso de
compilacin recibe como parmetro una macro denominada ASIG si ha sido
invocada desde una instruccin de asignacin. Esto se utiliza en conjunto con el
campo ownedbyfor de la tabla de smbolos para evitar alteraciones a las variables de
iteracin de las instrucciones para.
En los casos en los que leer y leerArchivo invocan a esta funcin evaluadora de
variables, se incluy el envo del parmetro ASIG, de forma que se evitara alterar
variables mediante estas instrucciones dentro de un para entendiendo su
funcionalidad como el de una instruccin de asignacin.

No era posible realizar agrupaciones de condiciones tales como:
a==0 & ( b > 1 | b < -1 )
Causa: los diagramas de sintaxis y, por lo tanto, el analizador sintctico
descendente del compilador, estaban diseados de tal forma que esto no fuera
posible (ver figuras E-1 y E-2).



Figura E-1. Diagrama de sintaxis para una expresin condicional.





E-8



Figura E-2. Diagrama de sintaxis para los miembros que conforman una expresin condicional.


Solucin: como propuesta inicial se plante modificar el diagrama de sintaxis
Condicion de forma que permitiera la agrupacin de condiciones tal y como lo
muestra la figura E-3:








P
Figura E-3. Propuesta de modificacin al diagrama de sintaxis para una expresin condicional.


Sin embargo, al evaluar si la traduccin a EBNF del diagrama anterior cumpla con
ser LL1 se encontr el siguiente problema:
( Prim(Miembro_Condicion)


Esto se debe a que Miembro_Condicion llama a Expresion_Numerica, la cual,
durante un proceso de evaluacin, es capaz de llegar a un factor de la forma:
( <Expresion Numerica> )

E-9

Por lo tanto, durante la evaluacin de una condicin, no era posible determinar qu
camino de evaluacin sintctica deba seguirse al encontrar un parntesis de
apertura.

Por ser esta situacin altamente relacionada con la definicin del lenguaje AEGOLI,
se llev a cabo una reunin con los profesores asesores que estuvieron disponibles
en su momento y se llego a las siguientes propuestos de solucin:

1. Implementar la agrupacin de condiciones mediante llaves ({}) en lugar de
parntesis.
2. Modificar los diagramas de sintaxis necesarios para incluir a las expresiones
condicionales y a las expresiones numricas en un solo tipo de expresin.
Luego, implementar mecanismos que generen el rbol de parsing de
cualquier expresin, para poder as realizar validaciones sobre este rbol
dependiendo del contexto el que se ha colocado una expresin (como una
condicin o como una expresin aritmtica).


Para mantener la naturalidad en el uso de los elementos del lenguaje AEGOLI, se
opt por implementar la segunda opcin
2
. A continuacin, se expone lo realizado
durante la realizacin de este proceso:

a. Los diagramas de sintaxis Condicion y Miembro_Condicion fueron eliminados.

b. Expresion_Numerica cambi de nombre a Expresion_Aritmetica, y la parte
encargada de los operadores unarios fue extrada:




2
Aunque este problema surgi en la Sesin #2, la solucin fue implementada posteriormente a la Sesin #3 y
antes de la Sesin #4.

E-10






H
Figura E-4. Diagrama de sintaxis para una expresin aritmtica.



c. Se crea un nuevo diagrama llamado Expresion_Numerica
3
:





Figura E-5. Diagrama de sintaxis para una expresin numrica.



d. Se crea el diagrama de sintaxis Expresion_Conjuncion:





Figura E-6. Diagrama de sintaxis para una expresin de conjuncin.



3
Las llamadas a Condicion en otros diagramas de sintaxis fueron sustituidas por llamadas a
Expresion_Numerica.

E-11

e. Se crea el diagrama de sintaxis Expresion_Relacional:








Figura E-7. Diagrama de sintaxis para una expresin relacional.

f. Se extrae de Funcion_Numerica el camino que produce un factor de la forma:
( <Expresion Numerica> )

g. Lo anterior, junto con los operadores unarios, son incluidos en Factor:














Figura E-8. Diagrama de sintaxis para un factor.


E-12
h. Se modific el cdigo del compilador de manera que se adecuara a los nuevos
diagramas de sintaxis.

i. Se implementaron mecanismos para la construccin del rbol de parsing de las
expresiones (los detalles de esta implementacin se pueden consultar en el
Anexo C).

j. Se definieron dos contextos para la evaluacin del rbol de parsing de
una expresin numrica:
a. Contexto de condicin: cuando se coloca una expresin numrica en
instrucciones que depende del cumplimiento de una condicin (si, hacer,
etc.).
b. Contexto aritmtico: cuando se coloca una expresin numrica en
instrucciones que necesitan un valor aritmtico como resultado de
evaluar dicha expresin (asignacin una variable, llamada a
subalgoritmo, escritura de datos en consola, etc.).

k. Se construyeron dos funciones de validacin del rbol de parsing de una
expresin numrica en base a los contextos definidos en el punto anterior (los
detalles de esta implementacin se pueden consultar tambin en el Anexo C).

Un parmetro mal declarado para un subalgoritmo siempre era registrado en la tabla
de smbolos provisional, lo que provocaba problemas durante la segunda pasada del
proceso de compilacin al momento de consultar los parmetros de un
subalgoritmo.
Solucin: se modificaron las funciones que realizan la primera pasada del
compilador de tal forma que un parmetro mal declarado fuera completamente
ignorado, evitando registrarlo en la tabla de smbolos y reportando el error
correspondiente.

Al realizar una llamada a un subalgoritmo utilizando una mayor cantidad de
parmetros que los declarados en su definicin, se produca un congelamiento del

E-13
proceso de compilacin. El problema tambin ocurra si se utilizaba algn
parmetro y el subalgoritmo haba sido definido sin parmetros.
Causa: el campo abajo de la tabla de smbolos es de tipo ListaParam
4
, la cual es
una estructura de lista que contiene todos los parmetros para un subalgoritmo.
Cuando un subalgoritmo se define sin parmetros, la lista slo posee un nodo de
control.
El problema ocurra debido a que siempre se intentaba consultar el nodo siguiente al
nodo de control, adems, al finalizar el recorrido de la lista, tambin se intentaba
consultar un nodo ms.
Solucin: se incluyeron validaciones en el recorrido del campo abajo de la tabla de
smbolos, de tal forma que el proceso se detuviera al momento de encontrar una
referencia nula a un nodo siguiente (campo siguiente de la estructura ListaParam
con valor NULL). Esto se incluy tanto al inicio como al final del recorrido.


Sesin #3 (20 de agosto de 2010)

Agenda de trabajo:
i. Distribucin de compilador y mquina virtual con las correcciones de la sesin 2 a
todos los participantes.
ii. Asignacin de ejercicios:
1. Se tienen tres matrices de enteros A, B, C. A es de 5 filas y 3 columnas. B es
de 3 filas y 4 columnas. C es de 5 filas y 4 columnas.
Pedir datos para llenar de A, B y C, efectuar el producto AxB y al resultado
obtenerle su matriz transpuesta, est ltima se denominar D. Por ltimo,
informar cuntas casillas tienen en comn C y D.
2. Hacer un programa que permita jugar buscaminas con una matriz de 5 filas y
5 columnas.



4
Ver Anexo C.

E-14
Fallas encontradas:

Los caracteres y no eran mostrados adecuadamente en las instrucciones
escribir y escribirln.
Causa: al igual que el caso de las vocales tildadas y la letra , estos caracteres
pertenecen a la tabla ASCII extendida.
Solucin: se aplic la misma estrategia utilizada para el caso de las vocales tildadas
y la letra . Los valores hexadecimales utilizados fueron:

\xA8
\xAD
Tabla E-2. Equivalentes de la tabla ASCII extendida para escapar los caracteres y en salidas a
consola.


Sesin #4 (23 de agosto de 2010)

Agenda de trabajo:
i. Distribucin de compilador y mquina virtual con las correcciones de la sesin 3 a
todos los participantes.
ii. Asignacin de ejercicios:
1. Se tiene el siguiente diagrama de Venn (ver figura E-9). En el diagrama
pueden observarse seis conjuntos (1-6) que se intersectan de tal forma que
generan 19 secciones (A-S). Cada una de estas secciones tiene asociados 3
nmeros entre 1 y 57.
Se debe declarar un arreglo de enteros R de 30 posiciones y pedir desde
consola nmeros entre 1 y 57 (validar las entradas), por cada uno de estos
nmeros realizar lo siguiente:
Primera parte: informar a cul de las 19 secciones pertenece. Ej.: el nmero
26 pertenece a la seccin G, el nmero 55 pertenece a la seccin Q, etc.
Segunda parte: determinar a cuales conjuntos pertenece y almacenarlos en
un arreglo A. Por cada elemento de A (los conjuntos a los que pertenece el

E-15
nmero ingresado), determinar cules de las siguientes caractersticas
cumple:
a) Ser un nmero primo.
b) Ser un nmero no primo.
c) Ser un nmero par.
d) Ser un nmero impar.
Una vez determinado lo anterior, modificar el nmero ingresado mediante
operaciones aritmticas y funciones predefinidas arbitrarias de tal forma que
se obtenga un nmero por cada elemento de A, y que cumpla con las
caractersticas determinadas para ese elemento de A. Estos resultados deben
almacenarse en R.
Ejemplo: 11 pertenece a los conjuntos 2, 3 y 5. Estos tres nmeros seran los
elementos de A para el nmero ingresado 11. Estos elementos cumplen con
las siguientes caractersticas:
a) 2 es primo y par.
b) 3 es primo e impar.
c) 5 es impar y no primo.
Por lo tanto, se utilizaran operaciones aritmticas y funciones predefinidas
arbitrarias para a partir de 11 obtener tres nmeros con las caractersticas de
los conjuntos a los que pertenece:
a) Un nmero primo y par.
b) Un nmero primo e impar.
c) Un nmero impar y no primo.
Una vez obtenidos estos tres resultados se almacenarn en R.

El proceso terminar cuando R se encuentre lleno. Por ltimo, se pedirn
datos para llenar una matriz M de 5 filas y 5 columnas, y deber informarse
cuntas veces aparece cada elemento de R en M.

E-16















Figura E-9. Diagrama de Venn para el ejercicio de la sesin #4 de la batera de pruebas.


Fallas encontradas:

No se poda utilizar una instruccin retornar en una funcin dentro de una
instruccin para.
Causa: la sentencia OPR con la funcin 2 es el equivalente a la instruccin retornar
en el cdigo intermedio. El funcionamiento de esta sentencia no tomaba en cuenta la
creacin de casillas adicionales a la del valor de retorno y las de los parmetros de
un subalgoritmo en la pila de memoria en tiempo de ejecucin. La instruccin para
crea casillas adicionales para mantener el valor lmite y el paso del proceso de
iteracin, por lo que se creaba una desestabilizacin durante la ejecucin de un
programa.
Solucin: se modific el funcionamiento de la funcin 2 de la sentencia OPR de
cdigo intermedio en la mquina virtual, de tal forma que sea independiente de si se

E-17
han creado o no casillas adicionales a la del valor de retorno y las de los parmetros
de un subalgoritmo en la pila de memoria.
5


No era posible retornar una casilla de un arreglo o de una matriz en una funcin.
Causa: dentro de la funcin del compilador encargada de evaluar variables se
realizaba una validacin que impeda retornar arreglos y matrices en su totalidad.
Esta validacin se haba colocado antes de evaluar si se haba colocado un ndice
para la variable, evitando poder devolver una casilla especfica.
Solucin: se desplaz la validacin mencionada despus de evaluar los posibles
ndices para una variable que sea arreglo o matriz.

Si una firma de un subalgoritmo se construa errneamente provocaba un
congelamiento del proceso de compilacin al evaluar el contenido del subalgoritmo.
Causa: el compilador trabaja de tal forma que ante una mala firma de un
subalgoritmo la totalidad del subalgoritmo es ignorada (esto se le informa al
programador en el mensaje de error). Sin embargo, esto se haba implementado para
un mal inicio en la firma de un subalgoritmo, y no se haba tomado en cuenta la
presencia de un error en el resto del contenido de la firma.
Solucin: se modific la funcin del compilador encargada de evaluar la firma de
un subalgoritmo de tal forma que, ante la presencia de un error en cualquier sector
de la firma, el proceso de compilacin contine en el siguiente subalgoritmo.

El error que se genera cuando hay cdigo despus de la palabra reservada fin en un
programa escrito en AEGOLI se generaba tambin si lo que se encontraba eran
nicamente comentarios.
Solucin: se cre una variable global cuyo valor es TRUE mientras lo que se haya
ledo del archivo fuente sea un comentario, al encontrar cualquier token su valor
ser FALSE. Luego, se utiliza el valor de esta variable para determinar si
efectivamente hay cdigo despus de fin en un programa escrito en AEGOLI.


5
Esto puede consultase con mayor detalle en el Anexo C.

E-18
Dejar al programador toda la responsabilidad del manejo del final de un archivo de
texto al utilizar las funciones abrirArchivo, leerArchivo y cerrarArchivo demostr
ser poco eficiente durante la realizacin de las pruebas: los usuarios solan olvidar
este detalle, lo que provocaba un mal funcionamiento de sus programas.
Solucin: se discuti esta situacin con el director del proyecto y se decidi incluir
una nueva funcin predefinida en el lenguaje AEGOLI encargada de determinar si,
durante el uso de un archivo de texto, se ha alcanzado el final del archivo o no.
Esta nueva funcin se llama finalArchivo y sus detalles pueden ser consultados en la
seccin 8.2, en el Anexo A y en el Anexo C.

Mejoras efectuadas:

Durante la discusin del punto anterior, se solicit de parte del director del proyecto
la inclusin de una instruccin cuyo funcionamiento fuera terminar la ejecucin de
un programa. Se cre entonces la instruccin terminaPrograma, la cual finaliza en
su totalidad la ejecucin de un programa escrito en AEGOLI al momento de ser
evaluada (sus detalles pueden ser consultados en la seccin 8.2, en el Anexo A y en
el Anexo C).


Sesin #5 (25 de agosto de 2010)

Agenda de trabajo:
i. Distribucin de compilador y mquina virtual con las correcciones de la sesin 4 a
todos los participantes.
ii. Asignacin de ejercicios:
1. Pedir 30 nmeros enteros entre 1 y 2000 (validar entrada). Por cada uno de
ellos informar el primer nmero que se encuentre despus en la recta
numrica y que pertenezca a la sucesin de Fibonacci (usar recursin).
Ej.: teniendo la sucesin de Fibonacci 1,1,2,3,5,8,13,21,34,55,89,.
Al ingresar 3 se informa 5.

E-19
Al ingresar 21 se informa 34.
Al ingresar 55 se informa 89.
2. Pedir 30 nmeros enteros entre 1 y 2000 (validar entrada). Por cada uno de
ellos informar cuantas cifras posee (usar recursin).
3. Hacer un programa con al menos tres subalgoritmos que utilice recursin
indirecta.
4. Hacer un programa que utilice la instruccin terminaPrograma y la funcin
finalArchivo.
iii. Durante la ltima hora de esta sesin se realiz una prctica libre en la que los
participantes podan probar las funcionalidades del lenguaje que desearan.


Fallas encontradas:

Algunos mensajes de error en la mquina virtual presentaban problemas de
redaccin.
Solucin: se revisaron todos los mensajes de error de la mquina virtual de forma
que se eliminarn todos los problemas de redaccin presentes.

Al utilizar instrucciones de bifurcacin (si, mientras, para) en una funcin, se
permita finalizar su ejecucin sin retornar ningn tipo de valor.
Solucin: se incluyeron validaciones en las instrucciones de bifurcacin de forma
que en el bloque de instrucciones de una funcin, todos los posibles finales de
ejecucin cuenten con una instruccin retornar.

La compatibilidad entre nmeros enteros y reales no se aplicaba en la instruccin
retornar. Ej.: no poda retornarse un valor entero si la funcin era de tipo real.
Solucin: se modific la sentencia de cdigo intermedio OPR con la funcin 2 (fin
de ejecucin de una funcin) de forma que se pudiera retornar un valor entero en
una funcin de tipo real y viceversa.


E-20
Las funciones log y ln permitan parmetro negativos y el 0.
Solucin: se incluyeron validaciones en las sentencias de cdigo intermedio
equivalentes a estas dos funciones para permitir nicamente argumentos
pertenecientes a su dominio.

Los errores lexicogrficos se informaban dos veces durante el proceso de
compilacin.
Causa: esto se deba a que tambin se informaba ese tipo de errores durante la
primera pasada del compilador.
Solucin: se modific la funcin del compilador encargada del reporte de errores de
forma que slo se informen errores durante la segunda pasada del compilador.
6


La funcin extraerCadena permita un valor para liminf mayor al valor de limsup.
Solucin: se modificaron las validaciones de los argumentos de la funcin
extraerCadena de forma que liminf sea menor a limsup, donde ambos estn siempre
dentro de los ndices permitidos para la cadena sobre la que se desea aplicar la
funcin.

Mejoras efectuadas:

Se aument el lmite de casillas para la pila de memoria de la mquina virtual para
reducir las posibilidades de un agotamiento de la pila en la ejecucin de un
programa extenso. Para evitar agotamiento de memoria de parte del lenguaje C para
la ejecucin de la mquina virtual, la mayor cantidad de caracteres para una cadena
fue reducida. En la tabla E-3 se muestran los valores anteriores y los valores
actuales:
Aspecto Valor anterior Valor Actual
LONGSTACK 1000 3000
MAXLONCAD 3000 1000
Tabla E-3. Cambio de valores para LONGSTACK y MAXLONCAD.

6
Ms informacin sobre las dos pasadas del compilador se puede consultar en el Anexo C.

E-21
Para un escenario en el que se agote la pila de memoria durante la ejecucin de un
programa, se incluy en la mquina virtual una validacin del puntero al tope de la
pila de forma que dicho evento se le pueda informar al programador.


Sesin #6 (27 de agosto de 2010)

Agenda de trabajo:
i. Distribucin de compilador y mquina virtual con las correcciones de la sesin 5 a
todos los participantes.
ii. Asignacin de ejercicios:
1. Hacer todos los ejercicios de la gua de prctica del manual de usuario.


Mejoras efectuadas:

Se incluyeron validaciones en todas las funciones de la mquina virtual que
producen resultados numricos, de forma que dichos resultados sean evaluados
antes de ser almacenados en la pila de memoria. Los criterios de evaluacin son los
siguientes:
o Si el resultado ser almacenado como un nmero real, se verifica que el
nmero no exceda los valores mximos para nmeros reales que maneja el
lenguaje C.
o Si el resultado ser almacenado como un nmero entero, se verifica que el
nmero no exceda los valores mximos para nmeros enteros que maneja el
lenguaje C.
Estas validaciones se agregaron para evitar la generacin de valores de overflow
durante la ejecucin de un programa escrito en AEGOLI, cosa que alterara los
resultados esperados.


E-22
La implementacin de las funciones 30 y 34 de la sentencia de cdigo intermedio
OPR (equivalentes a las instrucciones leer y leerArchivo) fue mejorada para incluir
validaciones de los valores ledos, de forma que fueran acordes al tipo de dato de las
variables donde sern almacenados.

Se cre una nueva funcin para la sentencia OPR: la funcin 7. Esta funcin, dado
un tipo de dato, verifica que el valor al tope de la pila sea compatible con el tipo de
dato especificado. Mayores detalles sobre la implementacin de esta nueva funcin
pueden consultarse en la seccin 9.4.2 y en el Anexo C.


Sesin #7 (30 de agosto de 2010)

Agenda de trabajo:
i. Distribucin de compilador y mquina virtual con las correcciones de la sesin 6 a
todos los participantes.
ii. Asignacin de ejercicios:
1. Terminar de hacer todos los ejercicios de la gua de prctica del manual de
usuario.
2. Pedir una cadena y convertirla a nmero, informar si se ha convertido en
nmero real o en un nmero entero. Validar que la cadena sea convertible en
nmero.
3. Pedir un nmero real o entero y convertirlo en cadena.


Mejoras efectuadas:

A la funcin 7 de la sentencia de cdigo intermedio OPR creada en la sesin #6, se
le agreg como parmetro el nmero de lnea en el cdigo fuente en donde se
encuentra la llamada al subalgoritmo cuyos parmetros se desean evaluar (en cuanto
a qu tipo de dato poseen). Esto se llev a cabo con la finalidad de dejar mucho ms
claro el mensaje de error correspondiente en tiempo de ejecucin.

E-23
Se cre una funcin en la mquina virtual utilizada para convertir de una mejor
manera un nmero real a un nmero entero:

int ftoi(double f){
if(f<0.0) return (-1)*((-1)*f+0.5);
else
if(f>0.0) return f+0.5;
else return 0;
}

La funcin utiliza mecanismos de aproximacin por redondeo, y fue diseada para
compensar los truncamientos que realiza el lenguaje C al hacer un casting explcito
a int de un dato de tipo float o double.

El tipo de dato float en campos de las estructuras utilizadas para la generacin de
cdigo intermedio en el compilador y para el manejo de la pila de memoria en la
mquina virtual, fue sustituido por el tipo de dato double con el objetivo de permitir
una mejor precisin en resultados de operaciones con nmeros reales.

Anda mungkin juga menyukai