Logo Studenta

Analizador de programas escritos en Turbo Pascal Orientado a Objetos

¡Este material tiene más páginas!

Vista previa del material en texto

“Analizador de programas escritos en 
Turbo Pascal Orientado a Objetos”
Indice:
			
	
	Pag.
	
	
	1. Introducción.
	3
	
	
	2. Especificación de Requerimientos Software de la aplicación a desarrollar.
	4
	
	
	3. Manual de Usuario.
	12
	
	
	4. Manual del Programador.
	16
	
	
	5. Listados del código fuente de la aplicación desarrollada.
	23
	
	
	6. Listados de las propiedades y eventos empleados en la aplicación.
	48
	
	
	7. Calendario del Proyecto
	63
Introducción
	Este proyecto consiste en implementar un explorador de código sobre un programa en Turbo Pascal Orientado a Objetos. 
	Para la ejecución de nuestro proyecto partimos de un programa en Pascal compilado y que funciona correctamente, por tanto no podemos ejecutar un programa escrito con otro compilador ni, por supuesto, uno que no funcione correctamente.
	Partiendo de estos hechos, abrimos un programa fuente, y al ejecutar nuestro proyecto generamos un fichero de tipo registro con el formato dado, en el cual vamos introduciendo las clases, atributos, asociaciones, métodos, herencia ...
	El proyecto ha sido implementado en Delphi, por tanto es necesario Windows para poder ejecutarlo (3.1 o superior). Decir que hemos utilizado una resolución de 800x600, con un color de alta calidad (high color). De no ser ejecutado bajo estas condiciones, algunas cosas pueden aparecer desplazadas de sitio, llegando incluso a no verse en pantalla, así como las fotografías no visualizarse con la calidad que nosotros deseáramos.
	Junto al programa se adjuntan los consiguientes manuales, tanto de programador como de usuario, para intentar resolver los problemas que puedan surgir al utilizar el proyecto, así como analizar la forma en la que lo hemos implementado. De todos modos, el programa es muy fácil de manejar al funcionar bajo Windows y ser la interfaz muy simple.
Especificación de Requerimientos Software 
del Proyecto Fin de Carrera I ( Enunciado 2 ).
1. Introducción.
	1.1. Propósito.
	El propósito del presente apartado es definir cuales son los requerimientos que debe tener un programa que analice el código fuente de una aplicación escrita en Turbo Pascal Orientado a Objetos y a partir del mismo genere el Modelo de Objetos correspondiente.
	Esta especificación de requerimientos está destinada a ser leída tanto por los usuarios de la aplicación como por cualquier sujeto que tenga interés en saber como funciona el programa.
	1.2. Ámbito.
	El programa que vamos a describir puede clasificarse como una aplicación de análisis y depuración de programas desarrollados con el lenguaje Turbo Pascal Orientado a Objetos.
	El presente producto analiza el código fuente de la aplicación en estudio y guarda los resultados de dicho análisis en una Base de Datos interna, a partir de la cual se podrá obtener el Modelo de Objetos de la misma y representarlo en el formato A DETERMINAR.
	1.3. Definiciones, acrónimos y abreviaturas.
	TPOO. Turbo Pascal Orientado a Objetos.
	OMT. Modelo de Objetos.
	BDA.. Base de Datos.
	IEEE. Asociación internacional dedicada a la estandarización de procesos de fabricación y desarrollo.
	API. Término con el que se conoce un documento asociado a un producto de desarrollo de aplicaciones en el que se explica detalladamente el mismo (Interfaz del Programador de Aplicaciones).
	CUA. Documento desarrollado por IBM que normaliza el comportamiento de una aplicación de ventanas. [4]
	Icono. Una imagen de bits miniatura que normalmente realiza una acción al ser seleccionada.
	1.4. Referencias.
	Para la realización de este texto se han tenido en cuenta los siguientes documentos:
	[1] Guía del IEEE para la Especificación de Requerimientos de Software. Boletín de prácticas de la asignatura de Ing. del Software de la EUI, UPV. 1996.
	[2] Object Modeling Technique. XXXXX
	[3] El API de Windows se explica en muchos libros, pero una relación completa del mismo puede encontrarse en el archivo windows.h del paquete Borland C++.
	[4] Lee Adams. Programación Avanzada en de Gráficos en C para Windows. McGraw-Hill / Interamericana de España, S.S. 1993. Pág. 24.
 2. Descripción general.
	A continuación vamos a ver los factores que afectan al producto y a sus requerimientos.
	2.1. Perspectivas del producto.
	El presente producto debe ser un programa en Borland Delphi para Windows y como tal debe cumplir todas las especificaciones de un programa que funcione bajo Windows, así como beneficiarse de las ventajas que ello supone, como es la sencillez de la interface con el usuario que tal sistema utiliza.
	Por lo tanto el programa podrá ser ejecutado en cualquier estación de trabajo que funcione bajo el sistema Windows.
	Como el programa a desarrollar es, básicamente, un analizador de código, ello permitirá que con la misma estructura de este programa se pueda generar otro semejante que trabaje sobre aplicaciones escritas en otros lenguajes similares al TPOO, como por ejemplo el TURBO C++ y el BORLAND C. 
	2.2. Funciones del producto.
	Las funciones que debe realizar el producto las podemos clasificar en varios bloques:
	a) Obtención de los datos necesarios para realizar el análisis.
- Obtención del código fuente del programa principal de la aplicación a estudiar.
- Obtención del código fuente de los distintos subprogramas que componen la aplicación a estudiar.
- Obtener los objetos de la aplicación a estudiar y almacenarlos en una BD para su utilización posterior.
- Obtener los atributos y métodos de dichos objetos y almacenarlos en una BD para su utilización posterior.
- Obtener los enlaces entre objetos de la aplicación y almacenarlos en una BD para su utilización posterior.
	b) Almacenamiento del fichero de resultados.
- Almacenar en un fichero los datos contenidos en la BD.
- Almacenar en un fichero los datos de un archivo de texto que se utilizará para comprobar el buen funcionamiento de la aplicación. 
	c) Herramientas de ayuda en el uso de la aplicación.
- Imprimir tanto los datos obtenidos de la aplicación como el fichero de texto generado en el formato determinado.
- Configurar la impresora por defecto y el modo de impresión.
- Poder cambiar las opciones de representación del fichero de texto con los resultados en lo referente a colores y tipos de letra. 
	2.3. Características del usuario.
	A continuación vamos a ver qué tipo de usuario van a usar el producto y como afectan estos a las funciones que debe realizar el producto.
	En primer lugar aparecen los iniciados en la programación con TPOO que pueden usar el producto para la obtención rápida del Modelo de Objetos de una aplicación sobre la que estén trabajando. Este tipo de usuarios esperarán un tiempo de respuesta muy breve y la posibilidad de obtener el OMT de la aplicación que estén estudiando en el formato que ellos deseen, así como una copia impresa de los resultados, tanto del modelo como de la información obtenida de los objetos de la aplicación.
	El otro tipo de usuarios serán aquellos que están comenzando con la programación en lenguaje TPOO y quieren obtener información fiable, es decir, corregida por un programa de análisis, de la aplicación que estén desarrollando.
	Dado que el programa trabajará sobre aplicaciones ya acabadas y el proceso de análisis deberá ser rápido y prácticamente automático, la interacción con el usuario será poca y eso hace que el programa no tenga ningún tipo de limitación idiomática, por lo que puede fácilmente ser utilizado por usuarios extranjeros.
	Cabe la posibilidad de hacer que el programa funcionara en otros tipos de máquinas con distintos sistemas operativos (MS-DOS, Linux, etc.) escribiéndolo en TP, tal modificación es bastante sencilla, ya que el Borland Delphi y el Turbo Pascal son muy similares. De esta forma se podría realizar todo el proceso de obtención del OMT desde la línea de comandos, lo cual daría más rapidez a la aplicación.
	2.5. Supuestos y dependencias.
	El presente producto depende enteramente de Windows y donde llega Windows 3.1 y sus futuras versiones (Win ‘95, Windows NT ...) debe poder llegar el programa,ya que debe cumplir todas las normas Windows expresadas en su API (Interfaz de para el Programador de Aplicaciones).
3. Requerimientos específicos.
	3.1. Requerimientos funcionales.
		3.1.1. Obtención del código fuente del programa principal de la 				aplicación a estudiar.
	El programa a desarrollar deberá abrir el fichero fuente del programa principal de la aplicación que se estudie, para poder analizar el código de esta, así como aquellos otros módulos de código (unidades de programación) de los cuales se sirva.
		3.1.2. Obtención del código fuente de los distintos subprogramas 				que componen la aplicación a estudiar.
	El presente producto debe ser capaz de acceder al código fuente de aquellos subprogramas en los que se basa la aplicación que se estudie, para poder analizar también dicho código. Sin esta operación solo se podría analizar un bloque de código fuente, el del programa principal, perdiendo toda relación con las demás unidades en las cuales se apoye, por lo tanto, esta operación se deberá realizar sobre el programa principal y sobre cada uno de los subprogramas que utilice.
	Esta función deberá tomar de la línea uses del código fuente de la unidad en estudio los nombres de las unidades en las cuales se basa, comprobar si esta disponible el código fuente de las mismas, para que en caso negativo sean ignoradas, y en caso de que exista pueda se analizado posteriormente.
		3.1.3. Obtener los objetos de la aplicación a estudiar y 	almacenarlos 			en una BD para su utilización posterior.
	La aplicación en una primera pasada del código en estudio deberá obtener los nombres de los objetos que se definan en la unidad estudiada y almacenarlos en un formato determinado en una BD.
	Para ello bastará con estudiar las líneas donde se halla la instrucción Object de TPOO y comprobar si se trata o no de una herencia, a fin de poder incluir tal información en la BD, tomar el nombre y guardar la información obtenida en la BD.
		3.1.4. Obtener los atributos y métodos de dichos objetos y pasar a 				almacenarlos en una BD para su utilización posterior.
	En el lenguaje TPOO cuando se define un objeto, a continuación se definen los atributos y métodos propios de él, esto es lo que analizará nuestro programa, línea a línea en el código a estudiar.
	Para ello se deberá tener en cuenta que cada nombre de atributo va seguido de dos puntos (:), a continuación el tipo de dato de que se trata (integer, real, string...) y finalmente un punto y coma (;). No hay que olvidar que varios atributos pueden ser definidos en la misma instrucción separando sus nombres con comas (,).
	En lo referente a los métodos, estos siempre van precedidos de la instrucción procedure o function, por lo que su identificación aún es más simple.
	Toda la información obtenida deberá guardarse en la BD incluyendo para cada método y atributo a qué objeto pertenece.
		3.1.5. Obtener los enlaces entre objetos de la aplicación y pasar a 				almacenarlos en una BD para su utilización posterior.
	Nuestra aplicación deberá ser capaz de identificar las relaciones entre los distintos objetos del código en estudio, es decir, deberá estudiar las llamadas que cada método del objeto hace a los otros objetos y comprobar si tal llamada es a un método propio o pertenece a otro objeto.
	Esta función deberá leer cada línea de código, verificar si hay llamadas a los métodos asociados a objetos (objeto.método), extraer el objeto al cual se llama y comprobar si es el objeto al cual pertenece el método que se esta estudiando en ese momento. Si no lo es ya podremos decir que entre los dos objetos se establece una relación. Luego deberemos recorrer la lista de objetos de la BD para ver si el objeto al cual se llamaba esta en ella, en caso afirmativo solo estableceremos la relación entre los dos objetos, pero en caso negativo deberemos averiguar a que unidad pertenece ese objeto y analizarla posteriormente.
		3.1.6. Almacenar en un fichero los datos contenidos en la BD.
	La aplicación deberá disponer de capacidad para almacenar en un fichero los datos que haya almacenado en la BD interna, como fruto del análisis de un programa en TPOO. Dicha función deberá ser similar a las que utilizan los demás productos desarrollados para Windows, ya que al trabajar bajo ese entorno los usuarios están acostumbrados a emplear una interface que les resulta tan familiar.
3.1.7. Almacenar en un fichero los datos de un archivo de texto que se utilizará para comprobar el buen funcionamiento de la aplicación.
	Además del fichero anterior y con el fin de evitar confusión a la hora de comprobar el correcto funcionamiento del programa, se creará un archivo de texto, visible desde la propia aplicación a traves de la apertura de un archivo, cuyo contenido será igual al del fichero de resultados pero esta vez en formato de texto.
3.1.8. Imprimir tanto los datos obtenidos de la aplicación como el fichero de texto generado en el formato determinado.
3.1.9. Configurar la impresora por defecto y el modo de impresión.
3.1.10. Poder cambiar las opciones de representación del fichero de texto con los resultados en lo referente a colores y tipos de letra. 
	3.2. Requerimientos de interfaces externos.
		3.2.1.	Interfaces de usuario.
	En este apartado, vamos a hablar de los procesos existentes entre el ordenador y el usuario. Para ello abordaremos en primer lugar el comportamiento del producto en la pantalla.
	El usuario pretende ver cuando ejecuta una aplicación Windows un comportamiento semejante al de todas las aplicaciones diseñadas para este sistema. Por ejemplo todas las aplicaciones permiten configurar la impresora, realizan llamadas a Windows y muestran un cuadro de dialogo común diseñado por el fabricante.
	Por ello, la aplicación contendrá cuadros de dialogo para acceder a los ficheros (obtener y almacenar), semejantes a los que ofrece Windows.
	Otro aspecto a tener en cuenta, es que la aplicación deberá tener zonas de selección, iconos o botones que activen distintas acciones del programa. Los menús de la aplicación deben seguir el orden que encontramos en todas las aplicaciones y que esta plasmado en el documento CUA de IBM. 
	En cuanto a las entradas realizadas a través de teclado, debemos destacar algunos aspectos, como tener teclas de acceso rápido a los elementos del menú, así como a los elementos dentro de los cuadros de dialogo. Por supuesto deben respetarse los comportamientos estándares dentro de los cuadros de dialogo, como por ejemplo, usar la tecla <TAB> para avanzar los campos de textos.
		3.2.2.	Interfaces hardware.
	Inicialmente, el presente producto puede usar todos los dispositivos que admite Windows. Hacer una lista de todo el hardware compatible Windows es demasiado extenso y contraproducente. Hay que destacar el concepto de independencia que aporta el desarrollo de programas bajo sistemas tan extendidos como Windows.
		3.2.3.	Interfaces software.
	El producto que estamos describiendo se desarrolla bajo el sistema operativo MSDOS en su versión 6.2, y sobre dicho sistema, se ha usado Windows 3.1 como entorno sobre el que se va a ejecutar la aplicación. En ultima instancia, la aplicación usa las funciones de los interfaces de Windows y por tanto, realmente no depende de MSDOS. De hecho existen versiones superiores de Windows que son completos sistemas operativos, como Windows NT o Windows 95. En principio, el presente producto debe usar las funciones de los tres interfaces que presenta Windows 3.1. Dado que el API de Windows 3.1 posee cerca de 1000 funciones, a continuación se presenta una breve descripción de los más usuales.
	3.4. Restricciones de diseño.
		3.4.1.	Estándares cumplidos.
	Como ya se ha especificado, la aplicación desarrollada deberá cumplir todos los estándares propios del sistema Windows bajo el cual va a trabajar.
Manual de usuario
	Como hemos mencionado anteriormente, la interfaz de usuario es muy sencilla de entender y manejar, aun así comentaremos brevemente el manejo de la aplicación.
	Hemos dividido la pantalla en:- Menú principal de aplicación.
		- Barra de herramientas.
		- Panel de controles.
		- Tres cajas de edición.
Menú principal.
	El menú principal de la aplicación consta de cuatro opciones, que pasamos a enumerar:
Fichero: En esta opción se incluye un submenú bastante estandard de todas las acciones que se suelen realizar con archivos. Estas son:
		
Abrir: Aparece la pantalla estandard de Windows para abrir ficheros y abre el fichero seleccionado, colocándolo en una de las cajas de edición.	
Imprimir: Aparece la pantalla estandard de Windows para imprimir ficheros. Imprime el texto situado en la caja de edición activa (donde está el cursor). Las cajas se activan pinchando sobre ellas con el ratón.
Por problemas con el Delphi, para poder imprimir con un tamaño normal, hay que ampliar considerablemente el tamaño de la fuente.
Configurar impresoras: Aparece la pantalla estandard de Windows para configurar impresoras, pudiendo adaptar la impresión a la impresora que se posea.			
Preferencias: En esta opción hay otro submenú, que tepermite cambiar el color de fondo y el estilo, color y tamaño de la fuente de la caja de edición activa en ese momento. También utilizamos las ventanas estandard de Windows.
Salir: Termina la aplicacion.
Ejecutar: Contiene un submenú con la opción Ejecución que permite ejecutar la aplicación. Esta opción no estará activa hasta que no se tenga un fichero abierto.
Ver Resultados: Contiene un submenú con la opción Visualizar Resultados que permite visualizar el fichero donde ha sido almacenada la ejecución de la aplicación. El submenú no estará activo hasta que no se haya ejecutado el programa.
Acerca de... : Contiene un submenú con la opción Acerca de... que visualiza los componentes que han realizado esta aplicación.
	
	En todas las opciones se han incluido aceleradores de teclas para su manejo mediante teclado. La combinación a utilizar es la tecla <Alt> + la letra subrayada de la opción correspondiente.
			
		
Barra de herramientas.
	En esta barra se incluyen cuatro botones que se corresponden con las subsiguientes opciones del menú principal. Estas son:
		- Abrir fichero.
		- Imprimir.
		- Cambiar color, estilo y tamaño de fuente.
		- Cambiar color de fondo.	
	De todos modos, al situar el ratón sobre cada uno de los botones, aparece un comentario explicativo de la función que desempeña.
	Los botones de Imprimir y Cambiar color,estilo y tamaño de fuente no están habilitados hasta que no se abra ningún fichero.
Panel de Controles.
	En este panel se incluyen tres botones que se corresponden con las subsiguientes opciones del menú principal. Son estas:
		- Ejecutar.
		- Visualizar.
		- Salir.
	El botón de Ejecutar no está habilitado hasta que no se abra ningún fichero y el de Visualizar hasta que no se ejecute la aplicación.
Cajas de Edición.
	En la aplicación aparecen dos cajas de edición, inicialmente vacías. Al abrir un fichero, éste aparece en una de ellas. Cuando se ejecuta el programa, las unidades que explora van apareciendo en la otra caja de edición. Además existen etiquetas explicativas sobre cada caja.
	Al pulsar la opción de Visualizar, aparece otra caja en la cual se situa el fichero con los resultados de la ejecución del programa.
	Todas las cajas de edición son de sólo lectura, no pudiendo modificar ninguno de los archivos, pese a que el cursor aparezca en la que esté activa en cada momento.
Funcionamiento normal de la aplicación.
- Se abre el fichero a explorar.
- Aparece en una de las cajas de edición.
- Se ejecuta la aplicación. El programa pregunta la ruta y el nombre del archivo donde colocar el fichero de registros (los resultados). En caso de existir este archivo, pregunta si se desea sobreescribirlo. Si la ruta introducida no es válida, aparece un mensaje de error y vuelve a pedir una válida. A su vez graba un fichero imprimible en el directorio actual, con el nombre “datos.txt”.
- Si se desea, se visualizan los resultados, apareciendo éstos en otra caja de edición.
- El programa permite repetir estos pasos tantas veces como archivos se deseen explorar, saliendo cuando el usuario considere oportuno.
Manual del programador.
	En este manual nos vamos a centrar única y exclusicamente a la explicación de la programación propia de Turbo Pascal, dejando un poco de lado la interfaz de usuario que ha sido implementada en Borland Delphi. De todos modos se adjuntan los listados correspondientes a las propiedades y eventes de todos y cada uno de los componentes de la aplicación (*.DFM).
	A continuación pasamos a comentar el desarrollo del programa:
	La aplicación “Explorador de codigo” consta de dos unidades que se corresponden con dos formularios. 
	La unidad “explorar” contiene el código principal de la aplicación y la unidad “acercade” contiene la implementación correspondiente a la ventana de Acerca de, por lo cual nos vamos a centrar en la primera.
	Dicha unidad contine una clase “Texplorador” compuesta por los atributos y métodos que se corresponden con las posibles operaciones a realizar desde la interfaz de usuario. Obviaremos el comentario de estos atributos ya que no forma parte de la programación propiamente dicha sino que utilizan las facilidades visuales de Delphi. Si que comentaremos los métodos cuando entremos en la parte de implementación.
	La estructura de datos que hemos utilizado es un registro que contiene todos los posibles elementos que nos podemos encontrar al explorar las clases de cada programa o unidad.
	La estrutura básica es la siguiente:
elem_diag=record
	case tipo_elemento(...............) of
	 tipo1: (atributo1, atributo2,...);
	 tipo2: (atributo1, atributo2,...);
	 tipo3: (atributo1, atributo2,...);
	 ... 
	 ...
	 tipon: (atributo1, atributo2,...);
	end;
end;
 
	Los elementos que nos podemos encontrar son:
		- programa.
		- clase.
		- atributo.
		- métodos.
		- especializaciones.
		- asociaciones.
	Para cada uno de estos elementos que formarán el archivo de salida se definen los siguientes atributos:
	Programa: (nombre_pro:string);
donde nombre_pro es el nombre de la unidad o programa que estamos explorando.		
	Clase: (nombre_clase:string);
donde nombre_clase indica el nombre de cada clase que nos vamos encontrando.
	Atributo: (nombre_atrib,tipo_atrib:string);
		donde indican respectivamente el nombre y el tipo del atributo.
	Método: (nombre_método:string; parametros:reg_parametros);
donde el primero corresponde al nombre del método y el segundo es el registro de parámetros que contiene.
	Especialización: (superclase:string);
		donde indicamos cuál es la clase padre.
	Asociación: (con_clase:string);
		donde indicamos la clase con la que está asociada. 
	
	Respecto a las variables utilizadas en la aplicación, creemos que quedan suficientemente explicadas en los comentarios del código. Lo único a destacar es que la variable fichero utiliza la estructura de datos comentada anteriormente por lo que contendrá los resultados de la exploración. También nos hemos declarado un fichero de texto auxiliar f para poder visualizar ordenadamente los resultados por pantalla e impresora. Hemos definido el vector registros para contener las posibles asociaciones que puedan surgir dentro de otro registro que se encuentre fuera de la clase.
	Pasamos a comentar la implementación explicando cada uno de los procedimientos:
	Procedure AbrirClick(Sender:TObject);
	Abre el fichero seleccionado mediante la ventana Abrir de Windows y lo asignamos a nombre_fichero. Lo colocamos en la cajaedicion1. En path guardamos la ruta del fichero abierto para la posterior búsqueda de las demás unidades a explorar. El resto es para habilitar o deshabilitar los botones que sean oportunos y para mostrar las etiquetas. En este momento unidades_programa contiene la primera unidad que vamos a explorar (la que acabamos de abrir).
	Procedure SalirClick(Sender:TObject);
	Cierra la aplicación.
	Procedure ColoresClick(Sender:TObject);
	Cambia el color de fondo de la caja de edición seleccionada (la que tiene elcursor).
	Procedure TiposdeLetraClick(Sender:TObject);
	Cambia el color, estilo y tamaño de la fuente de la caja de edición seleccionada.
	Procedure ImprimirClick(Sender:TObject);
	Imprime el contenido de la caja de edición seleccionada. Como Delphi sólo permite imprimir objetos Canvas es necesario asignar cada línea de la caja de edición seleccionada a dicho objeto y desde ahí, mandarlo a impresora.
	Procedure ConfigurarImpresorasClick(Sender:TObject);
	Permite configurar la impresora que se vaya a utilizar.
	Procedure AcercadeClick(Sender:TObject);
	Muestra la ventana del Acerca de...
	Procedure Leepalabra;
	Introduce en palabra cada carácter que pueda formar parte de una palabra válida (consideramos caracteres válidos los que forman parte de este conjunto:
['0'..'9' , 'A'..'Z' , 'a'..'z' , 'ñ'..'Ñ' , '.' , '_' , '^'] ) y la convierte a minúscula (función ansilowercase). 
	Procedure Elimina_blancos;
	Lee caracteres mientras que sean blancos.
	Function Unidades:boolean;
	Devuelve true cuando la unidad leída de la cláusula uses de un programa es predefinida de Turbo Pascal.
	Function TipoAtributo:boolean;
	Devuelve true cuando el tipo del atributo leído es predefinido de Turbo Pascal o definido por el usuario.
	Function TipoRegistro(var auxi:string):boolean;
	Cuando esta función toma el valor true devuelve en auxi la clase con la que está asociada. En el procedimiento Ejecucion explicaremos cuándo utilizamos el registro registro comentado en la estructura de datos.
	Function repe:boolean;
	Controla que no se introduzca dos veces la misma unidad en el vector unidades_programa, para no explorarla más de una vez.
	Function Puntero:boolean;	
	Comprueba si la palabra leída se encuentra en el vector punteros, siendo éstas de tipo puntero y que están en el type de la unidad que está explorando.
	Procedure InicializaVectores;
	Este procedimiento borra lo que haya en los vectores puntero, tipos, asoc y registros, que son propios de la última unidad explorada, para introducir los de la nueva.
	Function AsociacionRepe(pal:string):boolean;
	Esta función comprueba si la palabra que le pasamos por parámetro, que es una asociacion, ya ha sido almacenada en el fichero de salida, con el fín de no almacenar más de una vez la misma asociación de una clase.
	Procedure Ejecucion(nombre_fichero:string);
	El funcionamiento de este procedimiento lo vamos a comentar secuencialmente, simulando el funcionamiento normal del programa.
 -Recibe par parámetro el nombre del fichero a explorar.
 	-Mientras no encontremos las palabra implementación, var o begin leemos 	palabra:
- Si la palabra es program o unit, leemos el nombre del mismo y lo introducimos en los dos ficheros (el de registros y el de texto).
- Si la palabra es uses, vamos guardando en el vector unidades_programa las unidades que no son de librería, controlando que no se repitan.
- Si la palabra es const, guardamos en el vector tipos las constantes que haya definidas.
- Si la palabra es type, examinamos todo su contenido hasta encontrar la palabra implementation o var (esta segunda es para no examinar variables que no formen parte de la clase en la que nos encontremos).
Vamos leyendo palabras; si encontramos Object, en aux está el nombre de la clase por lo que ya podemos introducirlo en los ficheros. 
Comprobamos si después del Object hay un paréntesis, lo que significaría que hay herencia y también introduciríamos la superclase en los ficheros. Vamos examinando los atributos y métodos de esta clase hasta encontrar un end que indica el fin de la misma. Cuando examinamos atributos, los almacenamos en el vector atributos hasta encontrar su tipo. Comprobamos si son definidos por el usuario o predefinidos de Turbo Pascal para introducir ambos (nombre y tipo del atributo) en los ficheros; de no ser así, es porque es una asociación, por tanto guardamos en los ficheros la clase con la que está asociada. Cuando examinamos métodos, introducimos en los ficheros su nombre así como los parámetros que tengan (con sus respectivos tipos). 
Si la palabra encontrada no es Object es porque se trata de un tipo definido por el usuario, por lo que los vamos almacenando en el vector 	tipos. Como podemos encontrarnos una asociación dentro de los campos de un registro, ha sido necesario declarar el vector registro. Para su mayor comprensión situamos un ejemplo de esta situación a continuación:
nombrePtr=^nombreObj;
nombreObj=record
		campo1:nombrePtr;
		campo2:nombreclasePtr; 
		{nombreclasePtr hace referencia a una
 		 clase}
	 end;	
Dentro de otra clase habrá un atributo cuyo tipo será nombrePtr, por lo que utilizamos la función TipoRegistro que nos devolverá la clase con la que está asociada.
				
	Procedure EjecucionClick(Sender:TObject);
	Primero pregunta la ruta y nombre del fichero donde almacenar los resultados (fichero de registros). Si la ruta no existe da un mensaje de error y vuelve a pedirla de nuevo. Si ya existe el fichero, pregunta si se desea sobreescribirlo o no. 
Asigna el fichero de registros al nombre que se acaba de introducir. Además asigna al fichero de texto f el nombre “datos.txt”, que será almacenado en el directorio actual. Va recorriendo el vector unidades_programa, pasándole cada nombre al procedimiento Ejecucion que recorrerá (conforme hemos explicado anteriormente) todas y cada una de las unidades que en él se encuentren. 
	Procedure FormCreate(Sender:TObject);
Inicializa los vectores unidades_Pascal y Tipos con las unidades y tipos predefinidos en Pascal. Activa la cajaedicion1.
	Procedure VisualizarResultadosClick(Sender:TObject);
Asigna al fichero de texto f el nombre “datos.txt”. Hace más pequeña la cajaedicion1 y muestra cajaedicion3 donde irá añadiendo dicho fichero. 
	Procedure Cajaedicion1Click(Sender:TObject);
	Activa cajaedicion1 y desactiva las otras dos.
	
	Procedure Cajaedicion2Click(Sender:TObject);
	Activa cajaedicion2 y desactiva las otras dos.
	Procedure Cajaedicion3Click(Sender:TObject);
	Activa cajaedicion3 y desactiva las otras dos.
	NOTA:
	En todos los procedimientos asociados a las pulsaciones sobre botones u opciones del menú, Delphi añade el parámetro Sender de tipo TObject. Esta último es la clase padre de todas las demás por defecto y el Sender se utiliza para indicar el objeto que en realidad activa este evento. Por ejemplo, si se pulsa un botón, el objeto Explorador es el que en realidad lo activa.
	Nosotros no hemos utilizado esto para nada, pero lo hemos dejado por seguir la sintaxis de Delphi.
Listado del programa.
program Proyecto;
uses
 Forms,
 Explorar in 'EXPLORAR.PAS' {Explorador},
 Acercade in 'ACERCADE.PAS' {AboutBox};
{$R *.RES}
begin
 Application.CreateForm(TExplorador, Explorador);
 Application.CreateForm(TAboutBox, AboutBox);
 Application.Run;
end.
unit Explorar;
interface
uses
 SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
 Forms, Dialogs, Menus, StdCtrls, ExtCtrls, Buttons, Printers,Acercade;
type
 TExplorador = class(TForm)
 MenuPrincipal: TMainMenu;
 Fichero1: TMenuItem;
 Ejecutar: TMenuItem;
 VerResultados: TMenuItem;
 Imprimir: TMenuItem;
 ConfigurarImpresoras: TMenuItem;
 N2: TMenuItem;
 Preferencias: TMenuItem;
 Colores: TMenuItem;
 Tiposdeletra: TMenuItem;
 N3: TMenuItem;
 Salir: TMenuItem;
 BarraHerramientas: TPanel;
 N4: TMenuItem;
 Ayuda: TMenuItem;
 ColorDialog1: TColorDialog;
 FontDialog1: TFontDialog;
 Ejecucion1: TMenuItem;
 Acercade: TMenuItem;
 PrintDialog1: TPrintDialog;
 PrinterSetupDialog1: TPrinterSetupDialog;
 Visualizarresultados: TMenuItem;
 PanelPresentacion: TPanel;
 CajaEdicion1: TMemo;
 botonabrir: TSpeedButton;
 botonimprimir: TSpeedButton;
 PanelControles: TPanel;
 botonejecutar: TButton;
 botonvisualizar: TButton;
 botonsalir: TButton;
 botonfuente: TSpeedButton;
 botoncolor: TSpeedButton;
 Etiqueta1: TLabel;
 Etiqueta2: TLabel;
 Etiqueta3: TLabel;
 N1: TMenuItem;
 CajaEdicion2:TMemo;
 etiqueta4: TLabel;
 CajaEdicion3: TMemo;
 AbrirFuente: TMenuItem;
 OpenDialog1: TOpenDialog;
 procedure AbrirClick(Sender: TObject);
 procedure SalirClick(Sender: TObject);
 procedure ColoresClick(Sender: TObject);
 procedure TiposdeletraClick(Sender: TObject);
 procedure ImprimirClick(Sender: TObject);
 procedure ConfigurarImpresorasClick(Sender: TObject);
 procedure AcercadeClick(Sender: TObject);
 procedure Leepalabra;
 procedure Elimina_blancos;
 function Unidades:boolean;
 function TipoAtributo:boolean;
 function TipoRegistro(var auxi:string):boolean;
 function repe:boolean;
 function puntero:boolean;
 procedure inicializavectores;
 function AsociacionRepe(pal:string):boolean;
 procedure Ejecucion(nombre_fichero:string);
 procedure Ejecucion1Click(Sender: TObject);
 procedure FormCreate(Sender: TObject);
 procedure VisualizarresultadosClick(Sender: TObject);
 procedure CajaEdicion1Click(Sender: TObject);
 procedure CajaEdicion3Click(Sender: TObject);
 procedure CajaEdicion2Click(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
 tipo_elemento=(programa,clase,atributo,metodo,especializacion,asociacion);
 { contiene los posibles elementos del fichero registro}
 reg_parametros=record
 nombre,tipo_para:string;
 end;
 {registro para guardar los parametros de cada metodo de las clases}
 elemento=record
 case tipo_elemento of
 programa:(nombre_pro:string);
 clase:(nombre_clase:string);
 atributo:(nombre_atri,tipo_atri:string);
 metodo:(nombre_metodo:string;tipo_met:boolean;parametros:reg_parametros);
 especializacion:(superclase:string);
 asociacion:(con_clase:string);
 end;
 {registro para almacenar el fichero de resultados}
 regis=record
 nom_reg,asoc:string;
 end;
 {registro para almacenar asociaciones que estén dentro de un campo del mismo}
var
 f:textfile; {fichero de visualizacion de resultados}
 ele:elemento; {variable de tipo registro}
 explorador: TExplorador; {objeto}
 fichero:file of elemento; {fichero de resultados}
 fich:text; {fichero que contiene el codigo fuente que exploramos}
 Nombre_fichero:string; {Nombre del fichero que vamos a explorar}
 resultados:string; {Nombre del fichero en el cual almacenamos los resultados}
 nom:string; {Nombre del fichero de visualización}
 palabra:string; {almacenamos cada palabra que leemos del fichero fuente}
 path:string; {continene la ruta donde se encuentran los ficheros a explorar}
 c:char; {cada caracter que leemos del fichero fuente}
 unidades_pascal:array[1..23] of string; {vector que contiene las unidades predefinidas del pascal}
 unidades_programa:array[1..40] of string; {vector que contine las unidades que tenemos que explorar}
 tipos:array[1..30] of string; {contiene tanto los tipos predefinidos como los definidos por el usuario}
 atributos:array[1..10] of string; {guardamos los atributos que encontramos en cada clase}
 punteros:array[1..10] of string; {almacenamos las clases que nos encontramos}
 registros:array[1..10] of regis; {almacenamos asociaciones las cuales están en un campo del registro }
 j,cont,ind:integer; {indices de los distintos vectores}
 caja1,caja2,caja3:boolean; {variables para controlar que caja de edicion esta activa}
 asoc:array[1..10] of string; {almacenamos las asociaciones que nos encontramos en cada programa}
implementation
{$R *.DFM}
procedure TExplorador.AbrirClick(Sender: TObject);
{Procedimiento mediante el cual abrimos el fichero fuente}
var
 s:string; {variable auxiliar para el nombre de la etiqueta de la caja de edicion1}
begin
 if OpenDialog1.Execute then {si pulsamos la opcion de Abrir}
 begin
 CajaEdicion1.Lines.LoadFromFile(OpenDialog1.Filename);
 Nombre_fichero:=OpenDialog1.Filename;
 unidades_programa[1]:=nombre_fichero;
 path:=extractfilepath(unidades_programa[1]);
 unidades_programa[1]:=extractfilename(unidades_programa[1]);
 configurarimpresoras.enabled:=true;
 ejecucion1.enabled:=true;
 tiposdeletra.enabled:=true;
 imprimir.enabled:=true;
 colores.enabled:=true;
 botonejecutar.enabled:=true;
 botonimprimir.enabled:=true;
 botonfuente.enabled:=true;
 visualizarresultados.enabled:=false;
 botonvisualizar.enabled:=false;
 cajaedicion2.Clear;
 s:=etiqueta1.Caption;
 delete(s,22,255);
 etiqueta1.Caption:=s+' "'+unidades_programa[1]+'"';
 etiqueta2.Visible:=false;
 cajaedicion3.visible:=false;
 cajaedicion1.Width:=577;
 end;
end;
procedure TExplorador.SalirClick(Sender: TObject);
{cierra la aplicación}
begin
 Close;
end;
procedure TExplorador.ColoresClick(Sender: TObject);
{cambia el color de fondo de la caja de edición seleccionada}
begin
 if ColorDialog1.Execute then
 begin
 if caja1 then
 Cajaedicion1.Color:=ColorDialog1.Color;
 if caja2 then
 cajaedicion2.Color:=ColorDialog1.Color;
 if caja3 then
 cajaedicion3.Color:=ColorDialog1.Color;
 end;
end;
procedure TExplorador.TiposdeletraClick(Sender: TObject);
{cambia el color, tipo y tamaño de letra de la caja de edición seleccionada}
begin
 if FontDialog1.Execute then
 begin
 if caja1 then
 cajaedicion1.Font:=FontDialog1.font;
 if caja2 then
 cajaedicion2.Font:=FontDialog1.font;
 if caja3 then
 cajaedicion3.Font:=FontDialog1.font;
 end;
end;
procedure TExplorador.ImprimirClick(Sender: TObject);
{Imprimimos el contenido de la caja de edición seleccionada}
var
 prn:system.text;
 n:integer;
begin
 if printDialog1.execute then
 begin
 if caja1 then
 begin
 printer.canvas.font:=cajaedicion1.font;
 assignprn(prn);
 rewrite(prn);
 for n:=0 to cajaedicion1.lines.count-1 do
 writeln(prn,cajaedicion1.lines[n]);
 system.close(prn);
 end;
 if caja2 then
 begin
 printer.canvas.font:=cajaedicion2.font;
 assignprn(prn);
 rewrite(prn);
 for n:=0 to cajaedicion2.lines.count-1 do
 writeln(prn,cajaedicion2.lines[n]);
 system.close(prn);
 end;
 if caja3 then
 begin
 printer.canvas.font:=cajaedicion3.font;
 assignprn(prn);
 rewrite(prn);
 for n:=0 to cajaedicion3.lines.count-1 do
 writeln(prn,cajaedicion3.lines[n]);
 system.close(prn);
 end;
 end;
end;
procedure TExplorador.ConfigurarImpresorasClick(Sender: TObject);
{configuramos la impresora}
begin
 printerSetupDialog1.execute;
end;
procedure TExplorador.AcercadeClick(Sender: TObject);
 {llamamos a la unidad acercade para visualizarlo}
begin
 aboutbox.Show;
end;
procedure TExplorador.Leepalabra;
{ procedimiento para ir leyendo palabras del fichero fuente }
var
 i:integer;
begin
 while (c in ['0'..'9','A'..'Z','a'..'z','ñ'..'Ñ','.','_','^'])=false do
 read(fich,c);
 i:=0;
 palabra[i]:=c;
 i:=i+1;
 while c in ['0'..'9','A'..'Z','a'..'z','ñ'..'Ñ','.','_','^'] do
 begin
 palabra[i]:=c;
 i:=i+1;
 read(fich,c);
 end;
 delete(palabra,i,255);
 palabra:=ansilowercase(palabra);
 elimina_blancos;
end;
procedure TExplorador.elimina_blancos;
{leemos caracteres del fichero mientras encontremos espacios en blanco}
begin
 while (c=' ') do
 read(fich,c);
end;
function TExplorador.unidades:boolean;
{comprobamos si las unidades contenidas en el use del fichero fuente son
 unidades predefinidas del pascal o no }
var
 i:integer;
begin
 unidades:=false;
 for i:=1 to 23 do
 if palabra=unidades_pascal[i] then
 unidades:=true
end;
function TExplorador.TipoAtributo:boolean;
{comprobamos si el tipo de los atributos que vamos obteniendo del fichero fuente
 son predefinidos del pascal o definidos por el usuario}
var
 i:integer;
begin
 tipoatributo:=false;
 for i:=1 to cont do
 if palabra=tipos[i]then
 tipoatributo:=true
end;
function TExplorador.TipoRegistro(var auxi:string):boolean;
{esta funcion nos devuelve una asociación cuando la misma está en un campo
del registro}
var
 i:integer;
begin
 TipoRegistro:=false;
 for i:=1 to ind do
 if palabra=registros[i].nom_reg then
 begin
 TipoRegistro:=true;
 auxi:=registros[i].asoc
 end;
end;
function TExplorador.repe:boolean;
{comprobamos que las unidades que nos encontramos en los USES de los ficheros
 fuentes que examinamos no hayan sido ya almacenadas en el vector de unidades
 de programa}
var
 i:integer;
begin
 repe:=false;
 for i:=1 to j-1 do
 if (unidades_programa[i]=palabra) then
 repe:=true;
end;
function TExplorador.puntero:boolean;
{ comprueba si la palabra que hemos leido es un puntero}
var
 i:integer;
begin
 puntero:=false;
 for i:=0 to 20 do
 if palabra=punteros[i] then
 puntero:=true;
end;
procedure TExplorador.inicializavectores;
{ borra todo lo que haya en los vectores que utilizamos en el procedimiento
de ejecucion y que son independientes para cada unidad que exploramos }
var
 i:integer;
begin
 for i:=1 to ind do
 begin
 delete(registros[i].nom_reg,1,255);
 delete(registros[i].asoc,1,255);
 end;
 for i:=1 to 10 do
 delete(punteros[i],1,255);
 for i:=1 to 10 do
 delete(asoc[i],1,255);
 for i:=13 to cont do
 delete(tipos[i],1,255);
 for i:=1 to 10 do
 delete(atributos[i],1,255);
end;
function TExplorador.AsociacionRepe(pal:string):boolean;
{ comprueba si la asociación que le pasamos como parámetro ya ha sido almacenada
 en el fichero, para no hacerlo más de una vez }
var
 i:integer;
begin
 AsociacionRepe:=false;
 for i:=1 to 10 do
 if pal=asoc[i] then
 asociacionRepe:=true;
end;
procedure TExplorador.Ejecucion(nombre_fichero:string);
{este procedimiento va examinando cada unidad que le pasamos como parametro y
 vamos construyendo el fichero de resultados}
var
 i,n,k,a,p:integer;
 esta_en,repetida:boolean;
 aux,auxi,s:string;
begin
 assignFile(fich,nombre_fichero);
 reset(fich);
 delete(palabra,1,255);
 p:=1;
 inicializavectores;
 ind:=1;
 while (ansicomparetext(palabra,'implementation')<>0) and (ansicomparetext(palabra,'var')<>0)
 and (ansicomparetext(palabra,'begin')<>0) do
 begin
 leepalabra;
 if (ansicomparetext(palabra,'program')=0) then
 {escribimos en el fichero de salida el nombre del programa}
 begin
 leepalabra;
 ele.nombre_pro:=palabra;
 write(fichero,ele);
 writeln(f,'Programa : ',palabra);
 end;
 if (ansicomparetext(palabra,'unit')=0) then
 {escribimos en el fichero de salida el nombre de la unidad}
 begin
 leepalabra;
 ele.nombre_pro:=palabra;
 write(fichero,ele);
 writeln(f,'Unit : ',palabra);
 end;
 if (ansicomparetext(palabra,'uses')=0) then
 {almacenamos en el vector de unidades de programa el nombre de las
 unidades que vamos encontrando, que no sean predefinidas del pascal,
 para examinarlas posteriormente}
 begin
 while (c<>';') do
 begin
 leepalabra;
 esta_en:=unidades;
 if not esta_en then
 begin
 esta_en:=repe;
 if not esta_en then
 begin
 unidades_programa[j]:=palabra;
 j:=j+1;
 end;
 end;
 end;
 end;
 if (ansicomparetext(palabra,'const')=0) then
 {guardamos en el vector tipos las constantes definidas por el usuario}
 begin
 while (ansicomparetext(palabra,'type')<>0) and (ansicomparetext(palabra,'var')<>0) do
 begin
 if c<>'=' then
 begin
 leepalabra;
 tipos[cont]:=palabra;
 cont:=cont+1;
 end
 else
 begin
 leepalabra; { Lee el valor de la constante }
 leepalabra; { Lee la siguiente palabra: otra constante, type o var }
 end;
 end;
 end;
 if (ansicomparetext(palabra,'type')=0) then
 {vamos almacenando en el fichero de salida las distintas clases que nos vamos
 encontrando, asi como atributos, métodos, asociaciones...}
 begin
 i:=0;
 while (ansicomparetext(palabra,'implementation')<>0) and (ansicomparetext(palabra,'var')<>0) do
 begin
 aux:=palabra;
 leepalabra;
 if (ansicomparetext(palabra,'object')=0) then
 {comprobamos si hemos encotrado una clase }
 begin
 i:=i+1;
 ele.nombre_clase:=aux;
 write(fichero,ele); {introducimos el nombre de la clase en el fichero}
 writeln(f,'Clase: ',aux);
 if (c='(') then {comprobamos si hay herencia}
 begin
 leepalabra;
 ele.superclase:=palabra;
 write(fichero,ele);
 writeln(f,'Clase Padre: ',palabra);
 end;
 a:=0;
 leepalabra;
 while (ansicomparetext(palabra,'end')<>0) do
		{vamos almacenando los metodos y atributos de la clase que hemos 			encontrado}
 begin
 n:=0;
		if ( ansicomparetext (palabra,'procedure') <> 0 ) and ( ansicomparetext 			(palabra,'function') <> 0 ) then
 {examinamos los atributos de la clase encontrada}
 while ( (c=',') or (c=':') )do
 if c=',' then
 {almacenamos en el vector atributos aquellos que sean del mismo tipo}
 begin
 atributos[n]:=palabra;
 n:=n+1;
 leepalabra;
 end
 else { Se han encontrado ':' }
 begin
 atributos[n]:=palabra;
 read(fich,c);
 elimina_blancos;
 delete(s,1,255);
 if (c='(') or (c in ['0'..'9']) then
 {comprobamos si son tipos definidos por el usuario}
 begin
 if c='(' then
 begin
 while (c<>')') do
 begin
 leepalabra;
 s:=s+palabra+c;
 end;
 s:='('+s;
 end
 else
 begin
 s:=c;
 leepalabra;
 s:=s+palabra;
 end;
 for k:=1 to n do
 begin
 ele.nombre_atri:=atributos[n];
 ele.tipo_atri:=s;
 end;
 write(fichero,ele);
 {introducimos en el fichero de salida los atributos
 y el tipo de los mismos}
 writeln(f,'Atributo: ',atributos[n],': ',s);
 end {del if}
 else {el tipo de atributos no es definido por el usuario}
 begin
 leepalabra;
 palabra:=ansilowercase(palabra);esta_en:=TipoRegistro(auxi);
 {comprobamos si existe una asociación}
 if esta_en then
 begin
 repetida:=asociacionrepe(auxi);
 if not repetida then
 begin
 asoc[p]:=auxi;
 p:=p+1;
 ele.con_clase:=auxi;
 write(fichero,ele);
 {almacenamos en el fichero de salida con que
 clase esta asociada}
 writeln(f,'Clase ',aux,' asociada con ',auxi);
 end
 end
 else
 begin
 esta_en:=tipoatributo;
 {comprobamos si el tipo de atributo es predefinido}
 if esta_en then
 begin
 for k:=0 to n do
 begin
 ele.nombre_atri:=atributos[k];
 ele.tipo_atri:=palabra;
 write(fichero,ele);
 {guardamos en fichero de salida los atributos
 y el tipo de los mismos}
 writeln(f,'Atributo: ',atributos[k],':',palabra);
 end;
 if palabra='record' then
 repeat
 leepalabra;
 until palabra='end';
 end
 else
 begin
 repetida:=asociacionrepe(palabra);
 if not repetida then
 begin
 asoc[p]:=palabra;
 p:=p+1;
 ele.con_clase:=palabra;
 write(fichero,ele);
 {introducimos en el fichero de salida la clase con
 la que está asociada}
 writeln(f,'Clase ',aux,' asociada con ',palabra);
 end
 end
 end {del else sino está_en}
 end {del else de tipo de atributos no definido por el usuario}
 end {del primer else}
 else
 begin { Analisis de procedure y function }
 leepalabra;
 ele.nombre_metodo:=palabra;
 write(fichero,ele);
 {alamacenamos en el fichero de salida el nombre del método}
 writeln(f,'Método: ',palabra);
 if c='(' then
 {vamos guardando en el fichero de salida los nombres y tipo
 de atributos de cada metodo}
 while c<>')' do
 begin
 leepalabra;
 if (ansicomparetext(palabra,'var')<>0) then
 while ( (c=',') or (c=':') )do
 if c=',' then
 begin
 atributos[n]:=palabra;
 n:=n+1;
 leepalabra;
 elimina_blancos;
 end
 else { Se han encontrado ':' }
 begin
 atributos[n]:=palabra;
 leepalabra;
 esta_en:=tipoatributo;
 if esta_en then
 for k:=0 to n do
 begin
 ele.parametros.nombre:=atributos[k];
 ele.parametros.tipo_para:=palabra;
 write(fichero,ele);
 writeln(f,'Parámetro: ',atributos[k],':',palabra);
 end
 end
 end {del while}
 end ; {del else del analisis de procedure y function}
 leepalabra;
 end; {del while del end}
 leepalabra;
 end {del if del object}
 else { guardamos el tipo que no es un objeto }
 if (aux<>'type') then
 {examinamos lo que hay en el type fuera de una clase}
 begin
 if palabra='record' then
 {comprobamos si algun campo del registro es de tipo clase}
 begin
 while palabra<>'end' do
 begin
 while c<>';' do
 leepalabra;
 esta_en:=puntero;
 if not esta_en then
 begin
 esta_en:=tipoatributo;
 if not esta_en then
 begin
 registros[ind].asoc:=palabra;
 ind:=ind+1;
 end
 end;
 leepalabra;
 end;
 tipos[cont]:=aux;
 cont:=cont+1;
 end
 else
 begin
 while (c<>')') and (c<>';') and (aux<>'end') do
 leepalabra;
 if aux<>'end' then
 if palabra[1]<>'^' then
 begin
 tipos[cont]:=aux;
 cont:=cont+1;
 leepalabra;
 end
 else
 begin
 punteros[i]:=aux;
 i:=i+1;
 registros[ind].nom_reg:=aux;
 leepalabra;
 end;
 end; {del else}
 end {del if de aux<>type}
 end; {del while de implementacion y var}
 end; {del if del type}
 end {del primer while del procedimiento}
end;
procedure TExplorador.Ejecucion1Click(Sender: TObject);
{llama al procedimiento ejecutar pasandole el nombre de la unidad a explorar}
var
 i:integer;
 nombre,re:string;
 sobre:boolean;
begin
 repeat
 sobre:=true;
 resultados:=Inputbox('Ruta fichero salida','Introduce la ruta del fichero de salida','c:\noname.reg');
 {muestra por pantalla una caja de dialogo para introducir la ruta y nombre del fichero de salida}
 re:=extractfilepath(resultados)+'*.*';
 if fileexists(re) then
 {comprueba si existe la ruta,de no ser así muestra un mensaje de error}
 begin
 if FileExists(resultados) then
 {comprueba si el nombre del fichero introducido existe, en cuyo caso muestra un mensaje de error}
 if MessageDlg('El fichero "'+ExtractFileName(resultados)+'" existe, ¿Desea sobreescribirlo?',mtInformation,
 [mbYes,mbNo],0) = mrNo then
 sobre:=false
 end
 else
 begin
 MessageDlg('¡ La ruta "'+resultados+'" no existe !',mtInformation,[mbOK],0);
 sobre:=false;
 end;
 until (resultados<>'') and (sobre=true);
 cajaedicion2.clear;
 assignfile(fichero,resultados);
 rewrite(fichero);
 nom:='datos.txt';
 assignfile(f,nom);
 rewrite(f);
 i:=1;
 j:=2;
 nombre:=path+unidades_programa[i];
 repeat {llama al procedimiento ejecucion pasandole como parametro el nombre del fichero
 a explorar, hasta recorrer todo el vector que contiene las unidades de programa}
 ejecucion(nombre);
 cajaedicion2.Lines.Add(unidades_programa[i]);
 i:=i+1;
 nombre:=path+unidades_programa[i]+'.pas';
 until (i=j);
 closefile(fichero);
 closefile(f);
 visualizarresultados.enabled:=true;
 botonvisualizar.enabled:=true;
end;
procedure TExplorador.FormCreate(Sender: TObject);
{almacenamos en un vector las unidades y los tipos predefinidos del pascal}
begin
 unidades_pascal[1]:='app';
 unidades_pascal[2]:='colorsel';
 unidades_pascal[3]:='dialogs';
 unidades_pascal[4]:='dos';
 unidades_pascal[5]:='drivers';
 unidades_pascal[6]:='crt';
 unidades_pascal[7]:='editors';
 unidades_pascal[8]:='graph';
 unidades_pascal[9]:='graph3';
 unidades_pascal[10]:='histlist';
 unidades_pascal[11]:='memory';
 unidades_pascal[12]:='menus';
 unidades_pascal[13]:='msgbox';
 unidades_pascal[14]:='objects';
 unidades_pascal[15]:='outline';
 unidades_pascal[16]:='stdlg';
 unidades_pascal[17]:='strings';
 unidades_pascal[18]:='textview';
 unidades_pascal[19]:='turbo3';
 unidades_pascal[20]:='validate';
 unidades_pascal[21]:='views';
 unidades_pascal[22]:='wincrt';
 unidades_pascal[23]:='windos';
 tipos[1]:='integer';
 tipos[2]:='boolean';
 tipos[3]:='string';
 tipos[4]:='real';
 tipos[5]:='double';
 tipos[6]:='array';
 tipos[7]:='record';
 tipos[8]:='word';
 tipos[9]:='extended';
 tipos[10]:='byte';
 tipos[11]:='shorting';
 tipos[12]:='longint';
 cont:=13;
 caja1:=true;
 caja2:=false;
 caja3:=false;
end;
procedure TExplorador.VisualizarresultadosClick(Sender: TObject);
{visualizamos en una caja de edición el fichero de texto que hemos ido creando
 durante la ejecución de la aplicación}
var
 s:string;
 x:string;
begin
 resultados:='datos.txt';
 assignfile(f,resultados);
 reset(f);
 cajaedicion1.Width:=273;
 cajaedicion3.clear;
 x:=etiqueta2.Caption;
 delete(x,18,255);
 etiqueta2.Caption:=x+' "'+resultados+'"';
 etiqueta2.Visible:=true;
 cajaedicion3.Visible:=true;
 while not eof(f) do
 begin
 readln(f,s);
 cajaedicion3.Lines.Add(s);
 end;
end;
procedure TExplorador.CajaEdicion1Click(Sender: TObject);
{activa la caja de edicion1}
begin
 caja1:=true;
 caja2:=false;
 caja3:=false;
end;
procedure TExplorador.CajaEdicion3Click(Sender: TObject);
{activa la caja de edicion2}
begin
 caja1:=false;
 caja2:=false;
 caja3:=true;
end;
procedure TExplorador.CajaEdicion2Click(Sender: TObject);
{activa la caja de edicion3}
begin
 caja1:=false;
 caja2:=true;
 caja3:=false;
end;
END.
unit Acercade;
interface
uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, StdCtrls,
 Buttons, ExtCtrls;
type
 TAboutBox = class(TForm)
 Panel1: TPanel;
 OKButton: TBitBtn;
 ProgramIcon: TImage;
 ProductName: TLabel;
 Version: TLabel;
 Copyright: TLabel;
 Comments: TLabel;
 Label1: TLabel;
 Label2: TLabel;
 Label3: TLabel;
 Label4: TLabel;
 procedure OKButtonClick(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
var
 AboutBox: TAboutBox;
implementation
{$R *.DFM}
procedure TAboutBox.OKButtonClick(Sender: TObject);
begin
 close
end;
end.
 
Listado de propiedades y eventos del programa.
Unidad Explorar
object Explorador: TExplorador
 Left = 224
 Top = 133
 Width = 491
 Height = 409
 Caption = 'Explorador de código'
 Font.Color = clBlack
 Font.Height = -16
 Font.Name = 'Times New Roman'
 Font.Style = []
 Menu = MenuPrincipal
 PixelsPerInch = 96
 WindowState = wsMaximized
 OnCreate = FormCreate
 TextHeight = 19
 object BarraHerramientas: TPanel
 Left = 0
 Top = 0
 Width = 483
 Height = 41
 Align = alTop
 BevelOuter = bvNone
 BorderStyle = bsSingle
 Color = 10526880
 Ctl3D = True
 Locked = True
 ParentCtl3D = False
 ParentShowHint = False
 ShowHint = True
 TabOrder = 0
 object botonabrir: TSpeedButton
 Left = 8
 Top = 8
 Width = 25
 Height = 25
 Hint = 'Abrir'
 Glyph.Data = {}
 OnClick = AbrirClick
 end
 object botonimprimir: TSpeedButton
 Left = 40
 Top = 8
 Width = 25
 Height = 25
 Hint = 'imprimir'
 Enabled = False
 Glyph.Data = {}
 NumGlyphs = 2
 OnClick = ImprimirClick
 end
 object botonfuente: TSpeedButton
 Left = 72
 Top = 8
 Width = 25
 Height = 25
 Hint = 'fuente'
 Enabled = False
 Glyph.Data = {}
	NumGlyphs = 2
 OnClick = TiposdeletraClick
 end
 object botoncolor: TSpeedButton
 Left = 104
 Top = 8
 Width = 25
 Height = 25
 Hint = 'color de fondo'
 Glyph.Data = {}
Layout = blGlyphBottom
 NumGlyphs = 2
 OnClick = ColoresClick
 end
 end
 object PanelPresentacion: TPanel
 Left = 0
 Top = 41
 Width = 483
 Height = 322
 Align = alClient
 Color = 10526880
 Font.Color = clBlack
 Font.Height = -20
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 TabOrder = 1
 object Etiqueta1: TLabel
 Left = 24
 Top = 16
 Width = 147
 Height = 19
 Caption = 'Codigo fuente fichero '
 Font.Color = clBlack
 Font.Height = -16
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 end
 object Etiqueta2: TLabel
 Left = 336
 Top = 16
 Width = 118
 Height = 19
 Caption = 'Contenido fichero'
 Color = 10526880
 Font.Color = clBlack
 Font.Height = -16
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentColor = False
 ParentFont = False
 Visible = False
 end
 object Etiqueta3: TLabel
 Left = 616
 Top = 256
 Width = 82
 Height = 15
 Caption = 'CONTROLES:'
 Font.Color = clBlack
 Font.Height = -13
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 end
 object etiqueta4: TLabel
 Left = 624
 Top = 48
 Width = 144
 Height = 19
 Caption = 'Unidades exploradas:'
 Font.Color = clBlack
 Font.Height = -16
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 end
 object CajaEdicion1: TMemo
 Left = 24
 Top = 48
 Width = 577
 Height = 449
 Color = 15793151
 Font.Color = clBlack
 Font.Height = -16
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 Lines.Strings = (
 '')
 ParentFont = False
 ReadOnly = True
 ScrollBars = ssBoth
 TabOrder = 0
 OnClick = CajaEdicion1Click
 end
 object PanelControles: TPanel
 Left = 640
 Top = 280
 Width = 121
 Height = 193
 BevelInner = bvLowered
 BevelOuter = bvLowered
 BevelWidth = 2
 Color = 10526880
 TabOrder = 1
 object botonejecutar: TButton
 Left = 16
 Top = 24
 Width = 89
 Height = 33
 Caption = 'EJECUTAR'Enabled = False
 Font.Color = clGray
 Font.Height = -13
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 TabOrder = 0
 OnClick = Ejecucion1Click
 end
 object botonvisualizar: TButton
 Left = 16
 Top = 80
 Width = 89
 Height = 33
 Caption = 'VISUALIZAR'
 Enabled = False
 Font.Color = clBlack
 Font.Height = -13
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 TabOrder = 1
 OnClick = VisualizarresultadosClick
 end
 object botonsalir: TButton
 Left = 16
 Top = 136
 Width = 89
 Height = 33
 Caption = 'SALIR'
 Font.Color = clBlack
 Font.Height = -13
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 TabOrder = 2
 OnClick = SalirClick
 end
 end
 object CajaEdicion2: TMemo
 Left = 632
 Top = 80
 Width = 129
 Height = 137
 Color = 16777088
 Font.Color = clBlack
 Font.Height = -15
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 Lines.Strings = (
 '')
 ParentFont = False
 ReadOnly = True
 ScrollBars = ssBoth
 TabOrder = 2
 OnClick = CajaEdicion2Click
 end
 object CajaEdicion3: TMemo
 Left = 328
 Top = 48
 Width = 273
 Height = 449
 Color = 15793151
 Font.Color = clBlack
 Font.Height = -16
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 Lines.Strings = (
 '')
 ParentFont = False
 ScrollBars = ssBoth
 TabOrder = 3
 Visible = False
 OnClick = CajaEdicion3Click
 end
 end
 object MenuPrincipal: TMainMenu
 Left = 216
 Top = 104
 object Fichero1: TMenuItem
 Caption = '&Fichero'
 object AbrirFuente: TMenuItem
 Caption = '&Abrir Fuente'
 OnClick = AbrirClick
 end
 object N1: TMenuItem
 Caption = '-'
 end
 object Imprimir: TMenuItem
 Caption = '&Imprimir'
 Enabled = False
 OnClick = ImprimirClick
 end
 object ConfigurarImpresoras: TMenuItem
 Caption = 'Configurar I&mpresoras'
 Enabled = False
 OnClick = ConfigurarImpresorasClick
 end
 object N2: TMenuItem
 Caption = '-'
 end
 object Preferencias: TMenuItem
 Caption = '&Preferencias'
 object Colores: TMenuItem
 Caption = '&Color de fondo'
 OnClick = ColoresClick
 end
 object Tiposdeletra: TMenuItem
 Caption = '&Tipo y color de letra'
 Enabled = False
 OnClick = TiposdeletraClick
 end
 end
 object N3: TMenuItem
 Caption = '-'
 end
 object Salir: TMenuItem
 Caption = '&Salir'
 OnClick = SalirClick
 end
 end
 object Ejecutar: TMenuItem
 Caption = '&Ejecutar'
 object Ejecucion1: TMenuItem
 Caption = 'E&jecución'
 Enabled = False
 OnClick = Ejecucion1Click
 end
 end
 object VerResultados: TMenuItem
 Caption = '&Ver Resultados'
 object Visualizarresultados: TMenuItem
 Caption = 'Visualizar &resultados'
 Enabled = False
 OnClick = VisualizarresultadosClick
 end
 end
 object N4: TMenuItem
 end
 object TMenuItem
 end
 object Ayuda: TMenuItem
 Caption = '&Acerca de...'
 object Acercade: TMenuItem
 Caption = '&Acerca de ...'
 OnClick = AcercadeClick
 end
 end
 end
 object OpenDialog1: TOpenDialog
 Filter = 'Fichero fuente|*.pas'
 Options = [ofNoChangeDir]
 Left = 56
 Top = 104
 end
 object ColorDialog1: TColorDialog
 Left = 88
 Top = 104
 end
 object FontDialog1: TFontDialog
 Font.Color = clWindowText
 Font.Height = -13
 Font.Name = 'System'
 Font.Style = []
 MinFontSize = 0
 MaxFontSize = 0
 Left = 184
 Top = 104
 end
 object PrintDialog1: TPrintDialog
 Left = 152
 Top = 104
 end
 object PrinterSetupDialog1: TPrinterSetupDialog
 Left = 120
 Top = 104
 end
end
Unidad Acercade
object AboutBox: TAboutBox
 Left = 169
 Top = 105
 ActiveControl = OKButton
 BorderStyle = bsDialog
 Caption = 'Acerca de...'
 ClientHeight = 367
 ClientWidth = 528
 Font.Color = clBlack
 Font.Height = -13
 Font.Name = 'System'
 Font.Style = [fsBold, fsItalic]
 PixelsPerInch = 96
 Position = poScreenCenter
 TextHeight = 16
 object Panel1: TPanel
 Left = 8
 Top = 8
 Width = 513
 Height = 313
 BevelInner = bvRaised
 BevelOuter = bvLowered
 TabOrder = 0
 object ProgramIcon: TImage
 Left = 8
 Top = 8
 Width = 241
 Height = 233
 Picture.Data = {}
 Stretch = True
 IsControl = True
 end
 object ProductName: TLabel
 Left = 264
 Top = 16
 Width = 226
 Height = 16
 Caption = 'PROYECTO FIN DE CARRERA 1'
 Font.Color = clNavy
 Font.Height = -13
 Font.Name = 'MS LineDraw'
 Font.Style = [fsBold]
 ParentFont = False
 IsControl = True
 end
 object Version: TLabel
 Left = 264
 Top = 64
 Width = 99
 Height = 13
 Caption = 'COMPONENTES:'
 Font.Color = clNavy
 Font.Height = -12
 Font.Name = 'MS Sans Serif'
 Font.Style = [fsBold]
 ParentFont = False
 IsControl = True
 end
 object Copyright: TLabel
 Left = 288
 Top = 160
 Width = 169
 Height = 22
 Caption = 'Rubén Andrés Calvo'
 Font.Color = clPurple
 Font.Height = -19
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 IsControl = True
 end
 object Comments: TLabel
 Left = 288
 Top = 192
 Width = 185
 Height = 25
 Caption = 'Miguel López Gómez'
 Font.Color = clPurple
 Font.Height = -19
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 WordWrap = True
 IsControl = True
 end
 object Label1: TLabel
 Left = 288
 Top = 96
 Width = 204
 Height = 22
 Caption = 'Pepa Deogracia Guirado'
 Font.Color = clPurple
 Font.Height = -19
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 end
 object Label2: TLabel
 Left = 288
 Top = 128
 Width = 200
 Height = 22
 Caption = 'Paco Martínez González'
 Font.Color = clPurple
 Font.Height = -19
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 end
 object Label3: TLabel
 Left = 288
 Top = 224
 Width = 174
 Height = 22
 Caption = 'Marcelo Raso Mateo'
 Font.Color = clPurple
 Font.Height = -19
 Font.Name = 'Times New Roman'
 Font.Style = [fsBold]
 ParentFont = False
 end
 object Label4: TLabel
 Left = 24
 Top = 272
 Width = 191
 Height = 16
 Caption = 'Copyright 1996'
 Font.Color = clGray
 Font.Height = -13
 Font.Name = 'Wide Latin'
 Font.Style = []
 ParentFont = False
 end
 end
 object OKButton: TBitBtn
 Left = 215
 Top = 330
 Width = 77
 Height = 27
 Font.Color = clBlack
 Font.Height = -12
 Font.Name = 'MS Sans Serif'
 Font.Style = [fsBold]
 ParentFont = False
 TabOrder = 1
 OnClick = OKButtonClick
 Kind = bkOK
 Margin = 2
 Spacing = -1
 IsControl = True
 end
end
NOTA:
	La propiedad Glyph no se ha incluido en el listado de propiedades y eventeos en su totalidad, por contener caracteres ASCII que carecen de información, además de ocupar un tamaño excesivo.
image1.png

Continuar navegando

Materiales relacionados

111 pag.
105 pag.
280 pag.
Iniciacion_a_Delphi-HEPH

SIN SIGLA

User badge image

Stiven Fajardo