Escolar Documentos
Profissional Documentos
Cultura Documentos
PROGRAMACIN DE SISTEMAS
ITSJC 20/11/2011
NDICE
INTRODUCCIN...................................................................................................................................... 3 5.1 ANLISIS SEMNTICO ...................................................................................................................... 4 5.2 VERIFICACIN DE TIPOS EN EXPRESIONES ...................................................................................... 6 5.3 SISTEMAS DE TIPOS Y COMPROBADORES DE TIPOS ........................................................................ 7 5.4 ACCIONES AGREGADAS EN UN ANALIZADOR SINTCTICO DESCENDENTE (TOP- DOWN). ........... 16 5.5 PILA SEMNTICA EN UN ANALIZADOR SINTCTICO ASCENDENTE (BOTTOM-UP). GRAMTICA DE ATRIBUTOS ........................................................................................................................................... 24 5.6 ADMINISTRACIN TABLA DE SMBOLOS........................................................................................ 27 5.7 ERRORES SEMNTICOS .................................................................................................................. 30 CONCLUSIN........................................................................................................................................ 35 BIBLIOGRAFA....................................................................................................................................... 36
INTRODUCCIN
ANLISIS SEMNTICO
Un analizador sintctico (en ingls parser) es una de las partes de un compilador que transforma su entrada en un rbol de derivacin. El anlisis sintctico convierte el texto de entrada en otras estructuras (comnmente rboles), que son ms tiles para el posterior anlisis y capturan la jerarqua implcita de la entrada. Un analizador lxico crea tokens de una secuencia de caracteres de entrada y son estos tokens los que son procesados por el analizador sintctico para construir la estructura de datos, por ejemplo un rbol de anlisis o rboles de sintaxis abstracta. El anlisis sintctico tambin es un estado inicial del anlisis de frases de lenguaje natural. Es usado para generar diagramas de lenguajes que usan flexin gramatical, como los idiomas romances o el latn. Los lenguajes habitualmente reconocidos por los analizadores sintcticos son los lenguajes libres de contexto. Cabe notar que existe una justificacin formal que establece que los lenguajes libres de contexto son aquellos reconocibles por un autmata de pila, de modo que todo analizador sintctico que reconozca un lenguaje libre de contexto es equivalente en capacidad computacional a un autmata de pila. Los analizadores sintcticos fueron extensivamente estudiados durante los aos 70 del siglo XX, detectndose numerosos patrones de funcionamiento en ellos, cosa que permiti la creacin de programas generadores de analizadores sintticos a partir de una especificacin de la sintaxis del lenguaje en forma Backus-Naur por ejemplo, tales y como yacc, GNU bison y javaCC. Se compone de un conjunto de rutinas independientes, llamadas por los analizadores morfolgico y sintctico.
El anlisis semntico utiliza como entrada el rbol sintctico detectado por el anlisis sintctico para comprobar restricciones de tipo y otras limitaciones semnticas y preparar la generacin de cdigo.
En compiladores de un solo paso, las llamadas a las rutinas semnticas se realizan directamente desde el analizador sintctico y son dichas rutinas las que llaman al generador de cdigo. El instrumento ms utilizado para conseguirlo es la gramtica de atributos.
En compiladores de dos o ms pasos, el anlisis semntico se realiza independientemente de la generacin de cdigo, pasndose informacin a travs de un archivo intermedio, que normalmente contiene informacin sobre el rbol sintctico en forma linealizada (para facilitar su manejo y hacer posible su
En cualquier caso, las rutinas semnticas suelen hacer uso de una pila (la pila semntic a) que contiene la informacin semntica asociada a los operandos (y a veces a los operadores) en forma de registros semnticos. El problema es que no tenemos garanta de que los dos procedimientos sean equivalentes. El segundo puede dar overflow, el primero prdida de precisin. La definicin del lenguaje debe especificar estos casos.
Las transformaciones posibles se pueden representar mediante un grafo cuyos nodos son los tipos de datos y cada arco indica una transformacin. Dado un operando de tipo A que se desea convertir al tipo B, se trata de encontrar una cadena de arcos que pase de A a B en el grafo anterior. Podra haber varios grafos, cada uno de los cuales se aplicar en diferentes condiciones, por ejemplo, uno para las asignaciones, otro para las expresiones, etc.
Para analizar los diferentes tipos que intervienen dentro de un programa, el compilador debe contar con una estructura interna que le permita manejar cmodamente las expresiones de tipos. Estructura interna: Debe ser fcilmente manipulable, pues su creacin se realizar conforme se hace la lectura del programa fuente Debe permitir comparar fcilmente las expresiones asignadas a distintos trozosde cdigo, especialmente a los identificadores de variables. La forma ms habitual de representacin son los grafos acclicos dirigidos (GADs) La ventaja de estas representaciones es que ocupan poca memoria y por tanto la comprobacin rapidez. de equivalencia se efecta con
Comprobacin de tipos Una caracterstica importante del sistema de tipos de un lenguajede programacin es el conjunto de reglas que permiten decidir cundo dos expresiones de tipo representan al mismo tipo. En muchos casos estas reglas no se definen como parte de las especificaciones del lenguaje.1. Diferentes interpretaciones de los creadores de compiladores. Estas diferencias afectan a la compatibilidad entre diferentes dialectos de un mismo lenguaje. Tres formas de equivalencia: Estructural Nominal
Funcional. Ejemplo: los tipos de A y de B son funcionalmente equivalentes:void Ordenar (int mat[], int
n){ /* ... */ }int A[10], B[20];Ordenar(A,10); Ordenar(B,20);Diferencia entre tipos compatibles y tipos funcionalmente equivalentes:En el primer caso, el compilador realiza sobre uno de ellos una transformacin interna paraque ambos se transformen en tipos equivalentes.En el segundo caso no se realiza ninguna modificacin interna, sino que se relaja el criterio de equivalencia.
Definicin
compilador es usando un lenguaje de expresiones de tipo. Un lenguaje de las expresiones de tipo debe describir de manera clara y sencilla los tipos del lenguaje fuente. No confunda este lenguaje con el sub-lenguaje del lenguaje fuente que consiste en las declaraciones o definiciones. No tienen por que ser iguales. El compilador traduce las declaraciones de tipo en expresiones de tipo. El lenguaje de las expresiones de tipo es la representacin interna que el compilador tiene de estas declaraciones y depende del compilador. El lenguaje de las declaraciones no. * Un sistema de tipos de un lenguaje/compilador es el conjunto de reglas del lenguaje (que es traducido e interpretado por el compilador que permiten asignar expresiones de tipo a las instancias de uso de los objetos del programa.
Si bien el sistema de tipos es una propiedad del lenguaje, no es raro que los compiladores introduzcan modificaciones en el sistema de tipos del lenguaje. Por ejemplo en Pascal el tipo de un array incluye los ndices del array10.1). Esto y las reglas de equivalencia de tipos de Pascal limitan gravemente la generosidad de las funciones en Pascal. Por eso algunos compiladores Pascal permiten en una llamada a funcin la compatibilidad de tipos entre arrays de diferente tamao y diferentes conjuntos de ndices.
Definicin
constructos de uso se atiene a lo especificado en sus declaraciones o definiciones de acuerdo a las reglas especificadas por el sistema de tipos.
Tipado Dinmico
Esttico
Tipado
Un lenguaje de programacin tiene tipado esttico si su comprobacin de tipos ocurre en tiempo de compilacin sin tener que comprobar equivalencias en tiempo de ejecucin.
Un lenguaje de programacin tiene tipado dinmico si el lenguaje realiza comprobaciones de tipo en tiempo de ejecucin. En un sistema de tipos dinmico los tipos suelen estr asociados con los valores no con las variables.
El tipado dinmico hace mas sencilla la escritura de metaprogramas: programas que reciben como datos otros cdigos y los manipulan para producir nuevos cdigos. Parse::Eyapp y Parse::Treeregexp son ejemplos de metaprogramacin. Cada vez que escribimos un procesador de patrones, templates o esqueletos de programacin estamos haciendo meta- programacin.
El lenguaje en el que se escribe el metaprograma se denomina metalenguaje. El lenguaje al que se traduce el metaprograma se denomina lenguaje objeto. La capacidad de un lenguaje de programacin para ser su propio metalenguaje se denomina reflexividad. Para que haya reflexin es conveniente que el cdigo sea un tipo de estructura de datos soportado por el lenguaje al mismo nivel que otros tipos bsicos y que sea posible traducir dinmicamente texto a cdigo.
Definicin
contrario Dbilmente Tipado varan con los autores, parece haber consenso en que los lenguajes con tipado fuerte suelen reunir alguna de estas caractersticas:
La comprobacin en tiempo de compilacin de las violaciones de las restricciones impuestas por el sistema de tipos. El compilador asegura que para cualesquiera operaciones los operandos tienen los tipos vlidos. Toda operacin sobre tipos invlidos es rechazada bien en tiempo de compilacin o de ejecucin. Algunos autores consideran que el trmino implica desactivar cualquier conversin de tipos implcita. Si el programador quiere una conversin deber explicitarla. La ausencia de modos de evadir al sistema de tipos.
Que el tipo de un objeto de datos no vare durante la vida del objeto. Por ejemplo, una instancia de una clase no puede ver su clase alterada durante la ejecucin.
Un smbolo se dice sobrecargado si su significado vara dependiendo del contexto. En la mayora de los lenguajes Los operadores aritmticos suelen estar sobrecargados, dado que se sustancian en diferentes algoritmos segn sus operandos sean enteros, flotantes, etc.
En algunos lenguajes se permite la sobrecarga de funciones. as es posible tener dos funciones llamadas min:
t = min(x,c); /* Error */
La inferencia de tipos hace referencia a aquellos algoritmos que deducen automticamente en tiempo de compilacin - sin informacin adicional del programador, o bien con anotaciones parciales del programador - el tipo asociado con un uso de un objeto del programa. Un buen nmero de lenguajes de programacin funcional permiten implantar inferencia de tipos (Haskell, OCaml, ML, etc). Vase como ejemplo de inferencia de tipos la siguiente sesin en OCaml:
pl@nereida:~/src/perl/attributegrammar/Language-AttributeGrammar0.08/examples$ ocaml
10
# minimo 2 3;;
- : int = 2
- : float = 4.9
- : string = "hola"
El compilador OCaml infiere el tipo de las expresiones. As el tipo asociado con la funcin minimo es 'a -> 'a -> 'a que es una expresin de tipo que contiene variables de tipo. El operador -> es asociativo a derechas y asi la expresin debe ser leda como 'a -> ('a -> 'a). Bsicamente dice: es una funcin que toma un argumento de tipo 'a (donde 'a es una variable tipo que ser instanciada en el momento del uso de la funcin) y devuelve una funcin que toma elementos de tipo 'a y retorna elementos de tipo 'a.
11
Definicin
tipo de la funcin minimo fuera 'a x 'a -> 'a, lo cierto es que en algunos lenguajes funcionales es usual que todas las funciones sean consideradas como funciones de una sla variable. La funcin de dos variables 'a x 'a -> 'a puede verse como una funcin 'a -> ('a -> 'a). En efecto la funcin minimo cuando recibe un argumento retorna una funcin: # let min_mundo = minimo
"mundo";;
# min_mundo "pedro";;
- : string = "mundo"
# min_mundo "antonio";;
- : string = "antonio"
# min_mundo 4;;
This expression has type int but is here used with type string
# min_mundo (string_of_int(4));;
- : string = "4"
Esta estrategia de reducir funciones de varias variables a funciones de una variable que retornan funciones de una variable se conoce con el nombre de
12
El polimorfismo es una propiedad de ciertos lenguajes que permite una interfaz uniforme a diferentes tipos de datos.
Se conoce como funcin polimorfa a una funcin que puede ser aplicada o evaluada sobre diferentes tipos de datos.
Un tipo de datos se dice polimorfo si es un tipo de datos generalizado o no completamente especificado. Por ejemplo, una lista cuyos elementos son de cualquier tipo.
Se
llama
Polimorfismo
Ad-hoc
aquel
en
el
que
el
nmero
de
combinaciones que pueden usarse es finito y las combinaciones deben ser definidas antes de su uso. Se habla de polimorfismo paramtrico si es posible escribir el cdigo sin mencin especfica de los tipos, de manera que el cdigo puede ser usado con un nmero arbitrario de tipos. Por ejemplo, la herencia y la sobrecarga de funciones y mtodos son mecanismos que proveen polimorfismo ad-hoc. Los lenguajes funcionales, como OCaml suelen proveer polimorfismo paramtrico. En OOP el polimorfismo paramtrico suele denominarse programacin genrica
En el siguiente ejemplo en OCaml construimos una funcin similar al map de Perl. La funcin mymap ilustra el polimorfismo paramtrico: la funcin puede ser usada con un nmero arbitrario de tipos, no hemos tenido que hacer ningn tipo de declaracin explcita y sin embargo el uso incorrecto de los tipos es sealado como un error:
13
La introduccin de nombres para las expresiones de tipo introduce una ambigedad en la interpretacin de la equivalencia de tipos. Por ejemplo, dado el cdigo:
v10 a;
int b[10];
Se habla de equivalencia de tipos estructural cuando los nombres de tipo son sustituidos por sus definiciones y la equivalencia de las expresiones de tipo se traduce en la equivalencia de sus rboles sintcticos o DAGs. Si los nombres no son sustituidos se habla de equivalencia por nombres o de equivalencia de tipos nominal.
Si utilizamos la opcin de sustituir los nombres por sus definiciones y permitimos en la definicin de tipo el uso de nombres de tipo no declarados se pueden producir ciclos en el grafo de tipos.
14
1.
2.
Se usa equivalencia estructural para todos los tipos con la excepcin de las
nereida:~/src/perl/testing>
gcc
-fsyntax-only
Definicin
dinmico en la que el conjunto de mtodos y propiedades del objeto determinan la validez de su uso. Esto es: dos objetos pertenecen al mismo tipo-pato si implementan/soportan la misma interfaz independientemente de si tienen o no una relacin en la jerarqua de herencia.
15
Existen
dos
representaciones
intermedias
principales:
Los operadores didicos (o binarios) pueden especificarse mediante tres notaciones principales:
Prefija: el operador didico es analizado antes que sus operandos. sus operandos. Sufija: el operador didico es analizado despus que sus operandos. Infija: el operador didico es analizado entre
En los lenguajes de programacin clsicos, los operadores didicos se representan usualmente en notacin infija. La notacin prefija permite al operador influir sobre la manera en que se procesan sus operandos, pero a cambio suele exigir mucha ms memoria. La sufija no permite esa influencia, pero es ptima en proceso de memoria y permite eliminar el procesado de los parntesis.
16
Adems, un rbol sintctico puede representarse en forma de tuplas de n elementos, de la forma (operador, operando-1, ..., operando-k, nombre). Las tuplas pueden tener longitud variable o fija (con operandos nulos). Las ms tpicas son las cudruplas, aunque stas pueden representarse tambin en forma de tripletes.
Notacin sufija
Llamada tambin postfija o polaca inversa, se usa para representar expresiones sin necesidad de parntesis.
Ejemplos:
a*b a*(b+c/d)
ab*
Los identificadores aparecen en el mismo orden. Los operadores en el de evaluacin (de izquierda a derecha).
Problema: operadores mondicos (unarios). O bien se transforman en didicos (binarios) o se cambia el smbolo.
17
Si el analizador sintctico es bottom-up, hacemos la siguiente suposicin: "Cuando aparece un no terminal V en el asidero, la cadena polaca correspondiente a la subcadena que se redujo a V ya ha sido generada".
Se utiliza una pila donde se genera la salida, inicialmente vaca. Las acciones semnticas asociadas a las reglas son:
Push Push -
Push i
F ::= (E)
F ::= - F
Push @
18
<Operando> ::= id |
cte |
Algoritmo de evaluacin de una expresin en notacin sufija que utiliza una pila:
Si el prximo smbolo es un identificador, se pasa a la pila. Corresponde a la aplicacin de la regla <Operando> ::= id
Si
el
prximo
smbolo
es
una
constante,
se
pasa
la
pila.
19
Si el prximo smbolo es un operador didico, se aplica el operador a los dos operandos situados en lo alto de la pila y se sustituyen stos por el resultado de la operacin. Corresponde a la aplicacin de la regla <Operando> ::= <Operando> <Operando> <Operador didico>
Si el prximo smbolo es un operador mondico, se aplica el operador al operando situado en lo alto de la pila y se sustituye ste por el resultado de la operacin. Corresponde a la aplicacin de la regla <Operando> ::= <Operando> <Operador mondico>
La asignacin, teniendo en cuenta que podemos no querer valor resultante. Adems, no interesa tener en la pila el valor del identificador izquierdo, sino su direccin. a:=b*c+d abc*d+: = La transferencia (GOTO).
20
GOTO L
L TR
La instruccin condicional
L1: L2:
Subndices:
se convierte en
Cudruplas
Tripletes
21
No se pone el resultado, se sustituye por referencias a tripletes. Por ejemplo: la expresin a*b+c*d equivale a:
Tripletes indirectos: se numeran arbitrariamente los tripletes y se da el orden de ejecucin. Ejemplo, sean las instrucciones:
(1) (*,b,c)
(2) (:=,(1),a) (3) (:=,(1),b) y el orden de ejecucin es (1),(2),(1),(3). Esta forma es til para preparar la optimizacin de cdigo. Si hay que alterar el orden de las operaciones o eliminar alguna, es ms fcil hacerlo ah. Generacin automtica de cudruplas
En un anlisis bottom-up, asociamos a cada smbolo no terminal una informacin semntica, y a cada regla de produccin una accin semntica. Ejemplo, sea la
22
gramtica
E.
V.
La
regla
U::=VoW
analiza la
compatibilidad
de los
operandos,
crea la
cudrupla
23
La regla U::=oV crea la cudrupla (o,Sem(V),,Ti) y asocia a U la informacin semntica Ti. La informacin semntica se suele almacenar en otra pila paralela. Ejemplo: anlisis de a*(b+c)
Por ejemplo: sea la gramtica simplificada que analiza las instrucciones de asignacin:
<T>
24
#RS: Realizar suma: POP los dos registros superiores de la pila; comprobar que es posible sumarlos; realizar la suma (mediante una llamada al generador de cdigo) o generar representacin intermedia (si es una compilacin en dos o ms pasos); PUSH registro semntico del resultado en la pila semntica. #RAs: Realizar asignacin: POP los dos registros superiores de la pila; comprobar que es posible realizar la asignacin; realizarla (mediante una llamada al generador de cdigo) o generar representacin intermedia (si es una compilacin en dos o ms pasos).
En los analizadores sintcticos top-down basados en gramticas LL(1), la introduccin de los smbolos de accin en las rutinas correspondientes es trivial. En los analizadores bottom-up basados en gramticas SLR(1) es ms delicado, pues los estados del anlisis se mueven simultneamente sobre varias reglas. Slo en el momento de realizar una reduccin sabemos exactamente dnde estamos. Por ello, se suele introducir la restriccin de que los smbolos de accin deben estar situados nicamente al final de una regla. Cuando no se cumple esto (como en el ejemplo anterior) es trivial conseguirlo, introduciendo smbolos no terminales adicionales. Algunos generadores de analizadores sintcticos (como YACC) lo realizan automticamente. En nuestro ejemplo, quedara:
<T>
25
A := B + 1. Otro ejemplo: instrucciones condicionales con las reglas <Instr> ::= If <Expr> #S2 then <Instr> #S1 |
Ms adelante se ver cules son las tres acciones semnticas. Para que todas queden al final de una regla, basta cambiar estas reglas por:
26
Una implementacin comn de una tabla de smbolos puede ser una tabla hash, la cual ser mantenida a lo largo de todas las fases del proceso de compilacin.
Puede tratarse como una estructura transitoria o voltil, que sea utilizada nicamente en el proceso de traduccin de un lenguaje de programacin, para luego ser descartada, o integrada en la salida del proceso de compilacin para una explotacin posterior, como puede ser por ejemplo, durante una sesin de depuracin, o como recurso para obtener un informe de diagnstico durante o despus la ejecucin de un programa.
Los smbolos en la tabla de smbolos pueden referirse a variables, a funciones o a tipos de datos en el cdigo fuente de un programa.
La tabla de smbolos forma parte de cada fichero que contiene el cdigo objeto durante el enlazado o linking de los diferentes ficheros; recae en la responsabilidad del linker o enlazador resolver cualquier referencia no resuelta.
27
Como ya se dijo en el esbozo la tabla de smbolos es una estructura de datos que se crea en tiempo de traduccin del programa fuente. Es como un diccionario variable, debe darle apoyo a la insercin, bsqueda y cancelacin de nombres (identificadores) con sus atributos asociados, representando las vinculaciones con las declaraciones. Debe aclararse que no necesariamente deber estar representada en una tabla como su nombre indica ya que tambin se emplean rboles, pilas , etc.
Los smbolos se guardan en la tabla con su nombre y una serie de atributos opcionales que dependern del lenguaje y de los objetivos del procesador, este conjunto de atributos almacenados se denominan registro de la tabla de smbolos.
La siguiente representa una serie de atributos que no es necesaria para todos los compiladores, sin embargo cada uno de ellos se puede utilizar en la implementacin de un compilador particular.
direccin en tiempo de ejecucin a partir del cual se almacenara el identificador si es una variable. tipo del identificador. Si es una funcin el tipo que devuelve la funcin.
numero de dimensiones del array(arreglo), o numero de miembros de una estructura o clase, o nmeros de parmetros si se trata de una funcin. tamao mximo o rango de cada una de las dimensiones de los array, si tiene dimensin esttica. etc..
28
En general en la TS se realizan dos operaciones: la insercin y la bsqueda. En C la operacin de insercin se realiza cuando se procesa una declaracin. Hay dos posibilidades: que la TS este ordenada (o sea, nombres de variables por orden alfabtico) o que no este ordenada.
Si esta ordenada, entonces la operacin de insercin llama a un procedimiento de bsqueda para encontrar el lugar donde colocar los atributos del identificador a insertar, por lo que en este caso la insercin lleva tanto tiempo como la bsqueda. En cambio, si no est ordenada la TS, la insercin se simplifica mucho
En la bsqueda, se detectan los identificadores que no hayan sido declarados previamente, emitiendo un mensaje de error.
ejemplo en lenguaje C: Undefined simbolo 'x', si es una variable que desea usarse pero no se declaro.
En la insercin, se detectan identififcadores que ya han sido declarados previamente, emitiendo un mensaje de error
29
En cierto modo, este tipo de error es el ms difcil de depurar, ya que ni el compilador ni el sistema proporcionan informacin sobre qu est fallando. Lo nico cierto es que el programa no se est comportando como debera.
El primer paso es intentar encontrar una correspondencia entre el cdigo del programa y el comportamiento que se observa. Necesitas formar una hiptesis acerca de qu es lo que el programa est haciendo. Uno de los inconvenientes que hacen esta tarea difcil es que los ordenadores funcionan muy rpido.
Muchas veces sera deseable que se pudiese ralentizar el programa hasta una velocidad humana, y con algunos depuradores es posible. Pero el tiempo que se emplea en intercalar algunas instrucciones print en el cdigo es bastante menor que el que se tarda en configurar el depurador, aadir y eliminar puntos de interrupcin y avanzar por el programa hasta el lugar en el que se produce el error.
Pregntate lo siguiente:
Hay algo que el programa debera hacer pero que, por contra, no parece estar haciendo? Encuentra la porcin de cdigo que realiza esa funcin y asegrate de que se ejecuta en el momento que debera. Est ocurriendo algo inesperado? Encuentra la porcin de cdigo que realiza esa funcin y comprueba si se est ejecutando en un momento inadecuado. Una seccin del cdigo produce efectos inesperados? Asegrate de que comprendes el cdigo en cuestin, especialmente si implica llamadas a funciones o mtodos en otros mdulos de Python. Lee la documentacin sobre las funciones que utiliza. Intenta probarlas examinando los resultados producidos por los casos ms simples posibles.
30
Para programar necesitas un modelo mental de cmo funcionan los programas. Cuando un programa no se comporta como debera, es muy frecuente que esto se deba ms al modelo mental que al programa en s mismo.
La mejor manera de corregir tu modelo mental es dividir el programa en sus componentes - usualmente las funciones y los mtodos- y comprobarlos por separado. Una vez que encuentres la discrepancia entre el modelo mental y la realidad, podrs resolver el problema.
Por supuesto, debes crear y comprobar los componentes a medida que desarrollas el programa. Si encuentras un problema, tan slo debera haber una pequea parte de cdigo nuevo cuyo funcionamiento no ha sido comprobado
Siempre y cuando sean legibles, no hay ningn problema por escribir expresiones largas, pero pueden ser difciles de depurar. Una buena opcin es dividir estas expresiones complejas en una serie de asignaciones temporales de variables.
La versin explcita es ms sencilla de leer porque los nombres de variable aaden informacin adicional, y es ms sencillo de depurar porque se puede determinar el tipo de las variables intermedias y mostrar sus valores.
Otro problema con las expresiones largas es que el orden en el que se evalan puede diferir del esperado. Por ejemplo, para traducir a Python la expresin
podras escribir:
y = x / 2 * math.pi;
31
Esto no es correcto, ya que la multiplicacin y la divisin tienen la misma prioridad en una expresin, y estas se evalan de izquierda a derecha. As, esta expresin es x pi / 2.
Una buena forma de depurar las expresiones es aadir parntesis para explicitar el orden de evaluacin:
y = x / (2 * math.pi);
Cuando no ests seguro del orden de evaluacin, usa parntesis. Esto no slo conseguir que el orden de evaluacin sea el deseado, sino que adems facilitar la lectura del programa a las personas que no conocen las reglas de precedencia. Si tienes una instruccin return con una expresin compleja, no podrs imprimir el valor que devuelve antes de salir de la funcin o mtodo. De nuevo, utiliza una variable temporal. Por ejemplo, en lugar de:
return self.manos[i].eliminarCoincidencias()
return cuenta
32
Lo primero que debes hacer es alejarte del ordenador unos minutos. Los ordenadores emiten ondas que afectan al cerebro, causando:
Frustracin o ira.
Creencias supersticiosas (el ordenador me odia) o mgicas (el programa solo funciona cuando llevo la gorra al revs). Programacin factorial (intentar escribir todos los programas posibles hasta encontrar el que hace lo que se quiere).
Si sufres cualquiera de estos sntomas, levntate y da un paseo. Cuando ests tranquilo, piensa en el programa. Qu est haciendo? Cules son las posibles causas de este comportamiento? Cundo fue la ltima vez que funcionaba, y qu hiciste despus?
A veces, encontrar un error no es ms que cuestin de tiempo. A menudo, los errores se encuentran alejndose del ordenador y dejando la mente divagar. Algunos de los mejores lugares para encontrar errores son trenes, duchas y la cama, justo antes de dormir.
A veces ocurre. Hasta los mejores programadores se quedan atascados de vez en cuando. El trabajar mucho en un programa puede impedir encontrar sus errores. Cuatro ojos ven ms que dos: busca ayuda.
33
Antes de involucrar a otra persona, asegrate de que has agotado todas las tcnicas descritas aqu. El programa debe ser tan simple como sea posible, y deberas haber encontrado el caso mnimo que provoca el error. Deberas tener instrucciones print en los lugares adecuados (y sus mensajes deberan ser comprensibles). Has de comprender el problema lo
Hay algn mensaje de error? Qu significa y a qu parte del programa se refiere? Qu fue lo ltimo que se hizo antes de que ocurriese el error? Cules son las ltimas lneas de cdigo que se escribieron? En qu nuevo caso de prueba falla?
Cuando encuentres un error, piensa qu es lo que podras haber hecho para encontrarlo ms rpido. La prxima vez que veas algo parecido, sers capaz de encontrar el error rpidamente.
34
CONCLUSIN
35
BIBLIOGRAFA
36