You are on page 1of 61

Captulo 1.

Introduccin

Ral Jos Palma Mendoza


El propsito primario de un lenguaje de
programacin es ayudar al programador en la
prctica de su arte
Charles Hoare
Introduccin

Las primeras computadoras eran artefactos


monstruosos: grandes, costosas y con el poder
de procesamiento de un calculadora.
Los programadores crean que el tiempo de
stas era ms importante que el de ellos
mismos.
Ellos programaban usando lenguaje de
mquina.
Introduccin

Ejemplo de un programa en lenguaje de


mquina para calcular el mximo comn divisor
de dos enteros el procesador MIPS R4000:
Introduccin
Introduccin

Los lenguajes ensambladores se disearon


originalmente para tener una correspondencia
uno a uno entre los mnemnicos y las
instrucciones de lenguaje de mquina.
Se le llam ensamblador al software de
sistema encargado de hacer la traduccin.
Luego se les aadi capacidades de expasin
de macros que permitan definir abreviaciones
parametrizadas para secuencias de
instrucciones comunes.
Introduccin

Era necesario escribir programas nuevos para


cada mquina nueva que apareca.
Las personas empezaron a desear un lenguaje
independiente de la mquina, en el cual los
clculos numricos fuesen expresados de
forma ms similar a al lenguaje matemtico.
Fua hasta mediados de los 50's que se
desarroll el dialecto original de Fortran, el
primer lenguaje de programacin de alto nivel.
Poco despus aparecieron Lisp y Algol.
Introduccin

Traducir de un lenguaje de alto nivel a lenguaje


ensamblador o lenguaje de mquina es el
trabajo del compilador.
Los compiladores son mucho ms complejos
que los ensambladores, pues ya no existe la
relacin uno a uno entre el lenguaje de alto
nivel y el lenguaje de mquina.
Los lenguajes de alto nivel tambin se pueden
interpretar, por ejemplo: Phyton y Javascript.
Introduccin

Al inicio era ms eficiente escribir directamente


en lenguaje de mquina que compilar, pero
ahora los compiladores han avazando tanto
que en general producen cdigo ensamblador
ms eficiente, que lo que puede producir un ser
humano.
1.1 El Arte del Diseo de Lenguajes

Actualmente hay miles de lenguajes de alto


nivel, por razones como:
Evolucin. Las ciencias de la computacin son una
disciplina joven en constante evolucin.
Propsitos especiales. Hay varios lenguajes que se
desarrollan para problemas especficos.
Preferencias personales. A las personas les gustan
diferentes cosas: brevedad, recursividad, iteracin,
punteros, etc. todo esto hace improbable que algn
da exista un lenguaje universal.
1.1 El Arte del Diseo de Lenguajes

Aunque hay miles qu caractersticas


contribuyen a que un lenguaje sea ampliamente
usado?
Potencia expresiva. Escribir cdigo claro,
conciso y mantenible.
Facilidad de uso para el novato. Tener una
curva de aprendizaje baja, ej.: Basic, Logo,
Pascal.
Facilidad de implementacin. Ej.: Basic,
Pascal.
1.1 El Arte del Diseo de Lenguajes

Estandarizacin. Casi todos los lenguajes


ampliamente usados tienen un estndar
internacional oficial. Pascal fall en eso al no
estandarizar elementos como las cadenas y la
compilacin separada. Algol 60 tambin fall al
no estandarizar una librera de entrada y salida.
Cdigo Abierto. Muchos lenguajes
ampliamente usados tienen un compilador o
intrprete de cdigo abierto en la actualidad. C
se cre para implementar Unix y tambin
actualmente se usa para Linux.
1.1 El Arte del Diseo de Lenguajes

Excelentes compiladores. Los compiladores de


Fortran son famosos por su eficiencia, otros
lenguajes como Common Lisp tienen
compiladores y herramientas que ayudan
mucho al manejo de proyectos grandes.
Economa y Patrocinio. Muchos lenguajes
permanecen debido al respaldo de fuertes
empresas y a que reemplazarlos sera muy
costos. Ej.: Ada debe su vida al DoD (U.S.
Department of Defense), pues es complejo de
implementar, C# debe su gran aceptacin a
Microsoft.
1.1 El Arte del Diseo de Lenguajes

El implementador est interesado en cmo


decirle a la computadora qu hacer, y el
programador en cmo expresar sus algoritmos
e ideas. Al inicio el primer punto de vista era
dominante.
En 1984 Donald Knuth sugiri que la
programacin debera de ser reconocida como
el arte de decirle a otro humano qu es lo que
uno desea que la computadora haga.
1.2 El Abanico de los Lenguajes

Podemos hacer varias clasificaciones y


someterlas a discusin en nuestro caso
tomaremos las siguiente:
Declarativos
Funcionales Lisp/Scheme, ML, Haskell
Flujo de Datos Id, Val
Lgicos y basados en restricciones Prolog, hojas
de clculo
Basados en plantillas XSLT
1.2 El Abanico de los Lenguajes

Imperativos
von Neumann: C, Ada, Fortran, ...
Scripting: Perl, Python, PHP,
Orientados a objetos: Smalltalk, Eiffel, Java,
Los lenguajes funcionales utilizan modelo
computacional basado en la definicin
recursiva de funciones, toman su inspiracin en
el clculo lambda un modelo computacional
formal desarrollado por Alonzo Church en los
1930's.
1.2 El Abanico de los Lenguajes

Los lenguajes de flujo de datos modelan la


computacin como un flujo de informacin a
travs de nodos funcionales primitivos, este
modelo es inherentemente paralelo, los nodos
se activan al recibir datos (tokens) y pueden
operar concurrentemente.
Los lenguajes lgicos o basados en
restricciones toman su inspiracin en la lgica
de predicados, modelan la computacin como
un intento de encontrar valores que satisfagan
ciertas relaciones especificadas, usando una
bsqueda diriga por metas.
1.2 El Abanico de los Lenguajes

En ocasiones se clasifica dentro de los


lenguajes lgicos o basados en restricciones al
lenguaje SQL, al lenguaje XSLT y a algunos
aspectos programables de hojas de clculo
como Excel.
Los lenguajes de von Neumann son los ms
usados, modelan la computacin como serie de
cambios de estado o de modificaciones de
variables. Estn basados en enunciados
secuenciales que influencian al siguiente
usando efectos de lado.
1.2 El Abanico de los Lenguajes

Los lenguajes de scripting son un subconjunto


de los lenguajes de von Neumann hacen
nfasis en pegar o conectar componentes
hechos en diferentes lenguajes, no hacen
nfasis en la eficiencia, sino en la brevedad de
escritura, generalmente son interpretados.
Los lenguajes orientados a objetos en general
estn estrechamente relacionados con los
lenguajes de von Neumann pero tienen un
modelo de computacin y de la memoria
mucho ms estructurado y distribuido.
1.2 El Abanico de los Lenguajes

De los lenguajes orientados a objetos el ms


puro es Smalltalk, C++ y Java probablemente
los ms usados.
Podramos pensar en que los lenguajes
concurrentes son una clase independiente,
pero lo ocurre es que la concurrencia se
investiga e implementa en cada una de las
clases mencionadas.
1.2 El Abanico de los Lenguajes

Ahora veamos tres ejemplos para encontrar el


mximo comn divisor (gcd) en tres lenguajes
distintos:
int gcd(int a, int b) { // C
while (a != b) {
if (a > b) a = a - b;
else b = b - a;
} return a;
}
1.2 El Abanico de los Lenguajes

; Scheme
(define gcd
(lambda (a b)
(cond ((= a b) a)
((> a b) (gcd (- a b) b))
(else (gcd (- b a) a)))))
1.2 El Abanico de los Lenguajes

% Prolog
gcd(A,B,G) :- A = B, G = A.
gcd(A,B,G) :- A > B, C is A-B, gcd(C,B,G).
gcd(A,B,G) :- B > A, C is B-A,
gcd(C,A,G).
1.3 Por qu Estudiar Lenguajes de
Programacin?
Para saber seleccionar el lenguaje adecuado
recordando la frase de Charles Hoare.
Para aprender nuevos lenguajes fcilmente.
Para saberlos aprovechar mejor al conocerlos
internamente.
1.3 Por qu Estudiar Lenguajes de
Programacin?
Algunos de los beneficios son:
Entender caractersticas oscuras.
Escoger correctamente entre formas alternativas de
expresar las cosas.
Hacer buen uso de los depuradores, enlazadores,
ensambladores.
Simular caractersticas tiles de un lenguaje en
otro.
Hacer uso de la tecnologa de lenguajes donde sea
que aparezca.
1.4 Compiladores e Intrpretes

Un compilador traduce un programa en cdigo


fuente a un programa equivalente en un cdigo
meta (usualmente en lenguaje de mquina). Y
luego termina su ejecucin:
1.4 Compiladores e Intrpretes

Un compilador por s mismo es un programa en


lenguaje de mquina, probablemente creado al
compilar otro lenguaje de alto nivel.
Cuando el lenguaje de mquina ha sido escrito
en un formato de archivo entendible para el
sistema operativo se le conoce como cdigo
objeto.
1.4 Compiladores e Intrpretes

A diferencia de un compilador, un intrprete


permanece ejecutando durante la ejecucin del
software, ste implementa una mquina virtual
cuyo lenguaje de mquina es el lenguaje de
programacin de alto nivel que se est
interpretando.
1.4 Compiladores e Intrpretes

La interpretacin generalmente conlleva a tener


mayor flexibilidad y mejores diagnsticos de
errores que la compilacin, algunas
caractersticas son casi imposibles de obtener
sin interpretacin, ej.: los programas que
pueden aadir nuevas lneas de cdigo a s
mismos durante la ejecucin y ejecutrlas
tambin.
En cambio la compilacin generalmente lleva a
una mayor eficiencia.
1.4 Compiladores e Intrpretes

En la prctica ocurre que muchas


implementaciones de lenguajes incluyen una
mezcla de compilacin e interpretacin:
1.4 Compiladores e Intrpretes

Para el caso anterior, diramos que el lenguaje es


interpretado si la traduccin inicial es sencilla y si es
compleja, si incluye un anlisis completo y el
programa intermedio no tiene parecido al programa
fuente, entonces decimos que es compilado.
La discusin surge en lenguajes como Java que tiene
una traduccin inicial compleja y luego tiene una
interpretacin compleja. Aunque en las ltimas
versiones de Java se est dejando la interpretacin
por la compilacin justo a tiempo (Just In Time).
1.4 Compiladores e Intrpretes

Preprocesamiento:
Ocurre como un paso previo en la mayora de los
lenguajes interpretados (ej.: Lisp), un
preprocesador, remueve comentarios, espacios en
blanco y agrupa caracteres en tokens como
palabras clave, identificadores, nmeros y
smbolos, tambin podra expandir macros, e
incluso indentificar estructuras sintcticas de alto
nivel como ciclos y subrutinas, con el fin de obtener
un cdigo ms eficiente para interpretar.
1.4 Compiladores e Intrpretes

Ejemplo: compilacin en Fortran, se asemeja a la


compilacin pura.
1.4 Compiladores e Intrpretes

Ejemplo: ensamblado
posterior a la
compilacin, este libera
al compilador de
cambios en el lenguaje
de mquina, un mismo
ensamblador puede ser
usado por varios
compiladores
1.4 Compiladores e Intrpretes

Ejemplo: el
preprocesador de C,
remueve comentarios y
expande macros,
adems puede ser
instrudo para borrar
partes del cdigo,
proveyendo un
compilacin condicional
con el mismo cdigo:
1.4 Compiladores e Intrpretes

Ejemplo: traduccin de
cdigo fuente en C++ a
cdigo fuente en C. Es
una compilacin
completa pues el
compilador de C++
hace una anlisis
exhaustivo y provoca un
cambio significativo (no
directo) en el cdigo.
1.4 Compiladores e Intrpretes

Bootstrapping
Muchos compiladores estn escritos en el
lenguaje que compilan, para lograr esto se usa
una tcnica conocida como bootstrapping,
nombrada debido a la frase en ingls: pull
oneself up by one's bootstraps.
Bsicamente consiste en crear un pequea
implementacin del lenguaje y usar esta para ir
creando otras ms complejas.
1.4 Compiladores e Intrpretes

Ejemplo:
Si quisiermos empezar a construir el primer
compilador de Java y tuvisemos ya un compilador de
C, podramos iniciar escribiendo un pequeo
compilador para un subconjunto de Java en C usando
un pequeo subconjunto de C.
Luego podramos desarrollar usando el subconjunto
de Java y compilar el pequeo compilador de Java en
el compilador que ya tenemos y despus podramos
usar este compilador de Java escrito en Java para
desarrollar y compilar un compilador que acepte un
subconjunto mayor de Java y as sucesivamente.
1.4 Compiladores e Intrpretes

Los compiladores no necesariamente traducen


de un cdigo de alto nivel a un lenguaje de
mquina, existen compiladores que traducen
una descripcin de un documento de texto en
comando para una impresora, una consulta
SQL en operaciones primitivas sobre archivos,
un diseo del ambiente de un edificio a un
lenguaje entendible por un motor de 3D, etc.
1.5 Ambientes de Programacin

Adems de los compiladores e intpretes los


programadores son asistidos en sus tareas por
otras herramientas como: ensambladores,
depuradores, preporcesadores, enlazadores,
editores de texto, entre otros.
Anteriormente estas herramientas se
ejecutaban individualmente, pero en la
actualidad estas se integran cada vez ms en
los conocidos Ambientes de Desarollo
Integrado o IDE por sus siglas en ingls. Por
ejemplo: Eclipse, Netbeans, Visual Studio.
1.6 Un Vistazo al Proceso de
Compilacin
1.6 Un Vistazo al Proceso de
Compilacin
Los primeros pasos hasta el anlisis semntico
inclusive sirven para determinar el significado del
programa, se le conoce como el front end del
compilador, la ltimos pasos sirven para encontrar un
programa equivalente en el cdigo meta, se conocen
como el back end del compilador.
Los compiladores estn divididos en pasos que
deben realizarse uno despus del otro, esto permite
que varios compiladores para distintos cdigos fuente
compartan el mismo back end y varios compiladores
para distintos lenguajes de mquina compartan el
mismo front end.
1.6.1 Anlisis Lxico y Sintctico

El anlisis lxico tambin llamado escaneo y el


anlisis sintctico tambin llamado parseo,
sirven para determinar la estructura del
programa.
El escner (analizador lxico) lee los
caracteres del programa en cdigo fuente y los
agrupa en tokens, que son la unidad con
sentido ms pequea que tienen los
programas. La prinicipal razn de hacer esto es
simplificar el trabajo del parser (analizador
sintctico).
1.6.1 Anlisis Lxico y Sintctico

Usualmente el escner remueve espacios en


blanco innecesarios, remueve comentarios y
etiqueta los tokes con nmeros de lnea y de
columna para poder hacer diagnsticos
acertados en fases posteriores.
1.6.1 Anlisis Lxico y Sintctico

Ejemplo: Dado el siguiente programa en C, sus


tokens se muestran a continuacin:
int main() {
int i = getint(), j = getint();
while (i != j) {
if (i > j) i = i - j;
else j = j - i;
} putint(i);
}
1.6.1 Anlisis Lxico y Sintctico

int main ( )
{ int i =
getint ( ) ,
j = getint (
) ; while (
i != j )
1.6.1 Anlisis Lxico y Sintctico

{ if ( i
> j ) i
= i - j
; else j =
j - i ;
} putint ( i
) ; }
1.6.1 Anlisis Lxico y Sintctico

El parseo crea un rbol de parseo que representa


contrucciones de mayor nivel que los tokens ( ej.:
enunciados, expresiones, subrutinas, etc.) en trminos
de otras construcciones y/o tokens.
Cada construccin es un nodo en el rbol, los
elementos que la conforman son sus hijos, la raz del
rbol es la construccin programa; las hojas siempre
son tokens recibidos del escner. Visto de forma
completa el rbol muestra como los tokens forman un
programa vlido.
La estructura del rbol se basa en una serie de reglas
potencialmente recursivas conocidas como una
gramtica libre de contexto.
1.6.1 Anlisis Lxico y Sintctico

Decimos que la sintaxis del lenguaje est


definida por una gramtica libre de contexto,
por ejemplo hay infinitas grmaticas libres de
contexto para definir C, a continuacin veremos
un ejemplo de un rbol de parseo para la
gramtica de C oficial del estndar de 1999.
En el proceso de escaneo y parseo el
compilador revisa que todos los tokens estn
bien formados y que su secuencia est
conforme a la sintaxis definida en la gramtica
libre de contexto, cualquier error deber ser
informado.
1.6.1 Anlisis Lxico y Sintctico
1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio
En el anlsis semntico se descubre el
significado del programa.
Se analiza si varias ocurrencias del mismo
identificador corresponden al mismo elemento
del programa.
En la mayora de los lenguajes lleva un control
de los tipos de los identificadores y de las
expresiones.
Genera y mantiene una tabla de smbolos que
relaciona cada identificador con la informacin
que se va obteniendo de l.
1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio
Por ejemplo en C, el analizador semntico lleva
el control de:
Cada identificador sea declarado antes de ser
usado.
Que cada identificador sea usando en un contexto
apropiado, (ej.: llamar a un entero como subrutina,
sumar una cadena a un real, etc.)
Que los llamados a subrutinas tengan el nmero y
tipo correcto en los argumentos.
Que las etiquetas de las ramas de un switch sean
distintas.
Etc.
1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio
En muchos compiladores, el trabajo del
analizador semntico toma la forma de rutinas
de accin semntica, invocada por el parser
cuando se da cuenta que ha llegado a un punto
en particular dentro de una regla gramatical.
No todas las reglas semnticas se puede
comprobar en tiempo de compilacin:
Las que pueden comprobar se conocen como
semtica esttica del lenguaje.
La que se deben comprobar en tiempo de
ejecucin se refieren como la semntica dinmica
del lenguaje.
1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio
Un ejemplo de semntica dinmica comn en
muchos lenguajes sera:
Verificar que las variables no se usan en una
expresin, a menos que se les ha dado un valor.
Verificar que los punteros no se desreferencian, a
menos que se refieren a un objeto vlido.
Verificar que el subndice se encuentran dentro de
los lmites de la matriz.
Verificar que las operaciones aritmticas no
provoquen un desbordamiento.
1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio
Un rbol de parseo se conoce a veces como un
rbol de sintaxis concreto, porque demuestra,
por completo y en concreto, cmo una
determinada secuencia de tokens se pueden
derivar conforme a las reglas de la gramtica
libre de contexto. Una vez que sabemos que
una secuencia de tokens es vlido, sin
embargo, mucha de la informacin en el rbol
de anlisis es irrelevante para las fases
posteriores de la compilacin.
1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio
El analizador semntico por lo general
transforma el rbol de parseo en un rbol de
sintaxis abstracta (tambin conocido como un
AST, o simplemente un rbol sintctico)
mediante la eliminacin de la mayor parte de lo
"artificial" nodos en el interior del rbol . El
analizador semntico tambin anota la
informacin til de los nodos restantes, como
los punteros de los identificadores a sus
entradas en la tabla de smbolos.
1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio

Ejemplo de rbol sintctico abstracto:


1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio

La tabla de smbolos para el rbol sera:


1.6.2 Anlisis Semtico y Generacin
de Cdigo Intermedio
En algunos compiladores el rbol sintctico y la
tabla de smbolos corresponden a la forma
intermedia que se pasa del front end al back
end.
En otros esta forma intermedia se obtiene a
partir de un recorrido de dicho rbol para
generar un grafo de control de flujo cuyos
nodos se asemejan a fragmentos de un
lenguaje ensamblador para una mquina
idealizada.
1.6.3 Generacin del Cdigo Meta

Para generar el cdigo meta, el generador de


cdigo usa la tabla de smbolos para asignar
lugares a las variables, y luego atraviesa la
representacin intermedia del programa,
generando las cargas y almacenamientos para
las referencias a variables, intercaladas con las
operaciones aritmticas correspondientes,
decisiones y ramificaciones
Usualmente el generador de cdigo
almacenar la tabla de smbolos para ser
usada por un depurador simblico,
incluyndola en el cdigo meta.
1.6.4 Mejoras al Cdigo

Usualmente se les llama optimizaciones,


aunque en realidad en raras ocasiones se logra
obtener un resultado ptimo.
Es una fase opcional de la compilacin que
busca que el cdigo sea ms eficiente.
Puede haber optimizaciones independientes de la
mquina que suelen hacerse sobre la
representacin intermedia.
Las optimizaciones dependientes de la mquina se
hacen a travs de transformaciones al cdigo meta.

You might also like