Está en la página 1de 104

MANUAL DE PROGRAMACIN DE

SISTEMAS I

Programacin de Sistemas 1
Semestre: Sexto
Nm. Horas/semana: 4
Crditos: 8
Objetivos generales:
El alumno estar capacitado para disear, construir e
implementar de la manera ms eficiente los analizadores lxicos y
sintcticos de un compilador las caractersticas y funcionamiento
de cargadores, emsambladores y macroprocesadores.
Bibliografa Bsica:
COMPILADORES
Principios, tcnicas y herramientas
Aho, Sethi & Ullman
Ed. Addison-Wesley iberoamericana
MODERN COMPILER IMPLEMENTATION IN C
Basic techniques
Appel, Andrew W.
Ed. Cambridge
FUNDAMENTOS DE COMPILADORES
Cmo traducir al lenguaje de computadora
Lemone, Karen A.
Ed. CECSA
COMPILADORES
Conceptos fundamentales
Teufel, Schmidt & Teufel
Ed. Addison-Wesley iberoamericana

PLAN

DE

TRABAJO

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

1.

Datos Generales.

Materia:

2.

3.

Terica/Prctica
Horas de Clase por semana:
4 Hrs.
Horas de clase por semestre:
60 Hrs.
Carrera en que se imparte:
Ing. en Sist. Comp.
Semestre:
Sexto

Ubicacin de la materia.
A.

Ubicacin terica.
Se imparte en sexto semestre; sus antecedente son
las materias de Lenguajes y Autmatas y Admn.
De Archivos.
Materias paralelas: ninguna
Materias subsecuentes:
Programacin
de
Sistemas II

B.

Ubicacin practica.
Tipo de Alumnos:
diversos; algunos trabajan. Son
de clase baja-media-alta, ambos sexos.
Grupo: 20 alumnos por grupo promedio.
Horario: matutino
Recursos: saln austero en todo o con clima, Sala
Audiovisual, TV, Video, PC, Proy. De acetatos.

Objetivos generales de aprendizaje.


A.
Objetivos informativos.
Aplicar las estructuras bsicas de diseo de
compiladores (NFAs, e.r. y C.F.G.s)
Comprender el funcionamiento de traductores,
ensambladores, etc.
Conocer y manejar las herramientas para diseo
de sw de base (Java CC).
Disear una CFG para la construccin de un
Lenguaje de Programacin en sus dos primeras
fases (lxica y sintctica)
B.
Objetivos formativos.

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

4.

Intelectual.
Que el alumno aprenda a
preparar exposiciones profesionales y exponer sus
ideas de manera clara y por escrito.
Intelectual.
Que el alumno aprenda a
pensar, razonar, analizar, sintetizar, resumir y
esquematizar.
Intelectual.
Que
el
alumno
realice
investigacin y a discutir lo investigado con otros.
Humano.
Que el alumno tenga un deseo
de superacin continua, espritu de profesionalismo,
calidad y excelencia.
Social.
Que el alumno aprenda a
convivir con diferentes grupos, con un espritu de
colaboracin y participacin.
Profesional.
Que el alumno identifique la
diferencia en el perfil de un Ingeniero en Sistemas
Computacionales en relacin con el resto de los
usuarios de computadoras.
Profesional.
Que
el
alumno
disee
herramientas (software de base) para la generacin
de nuevo conocimiento.

Metodologa de trabajo.

En este curso se planean exposiciones de temas de repaso,


reforzando la investigacin con dinmicas grupales. Adems se forman
equipos de trabajos para el desarrollo de proyectos de software de base
(equipos no mayores de 3 integrantes) pudiendo ser estas agrupaciones
al azar o a gusto de los integrantes. Se utiliza, para realzar la clase
equipo audiovisual como TV, PC y Proyector de acetatos. La revisin del
proyecto final se realiza en dos partes para mayor facilidad del alumno.

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

UNIDAD I
INTRODUCCIN
CONCEPTOS
PROGRAMACIN DE SISTEMAS: Conjunto de reglas para crear
soluciones a problemas computables. Conjunto de herramientas
que nos permiten crear software de base que son de utilidad para
interactuar con la mquina.
SOFTWARE DE
Cargador.

BASE:

Compilador,

Querys,

Sistema

Operativo,

AUTMATA: Son las cadenas posibles que aceptan un lenguaje.


EXPRESIONES REGULARES: Conjunto de smbolos que aceptan una
palabra reservada.
GRAMTICA: Reglas para escribir las sentencias del lenguaje.

LENGUAJES DE PROGRAMACIN
LENGUAJE DE PROGRAMACIN: Es la notacin formal para la
descripcin de algoritmos, basada en un conjunto de instrucciones en
alto nivel, que finalmente pasarn a bajo nivel para interactuar con el
hardware y generar herramientas de trabajo.
Los lenguajes son sistemas de comunicacin. Un lenguaje de
programacin consiste en todos los smbolos, caracteres y reglas de uso
que permiten a las personas "comunicarse" con las computadoras.
Existen por lo menos varios cientos de lenguajes y dialectos de
programacin diferentes. Algunos se crean para una aplicacin especial,
mientras que otros son herramientas de uso general ms flexibles que
son apropiadas para muchos tipos de aplicaciones. En todo caso los
lenguajes de programacin deben tener instrucciones que pertenecen a
las categoras ya familiares de entrada/salida, clculo/manipulacin de
textos, lgica/comparacin y almacenamiento/recuperacin.

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

EJEMPLO DE SMBOLOS QUE COMPONEN UN PROGRAMA :


SIMBOLOS ESPECUALES
FUNCIONES
SIMBOLOS QUE RECHAZA EL LENGUAJ E
IDENTIFICADORES

ARITMETICOS
LENGUAJ E

LOGICOS

PASCAL

AND
NOT
OR

RELACIONALES

<
>
>
<
=
=

ASIGNACION

:=

DELIMITADORES
OPERACIONALES

PALABRAS
RESERVADAS

+,-,*,/,MOD

CICLOS
DECLARACION DE VARIABLES
DECLARACION DE CONSTANTES

No obstante, aunque todos los lenguajes de programacin tienen


un conjunto de instrucciones que permiten realizar dichas operaciones,
existe una marcada diferencia en los smbolos, caracteres y sntaxis de
los lenguajes de mquina, lenguajes ensambladores y lenguajes de alto
nivel.
Lenguaje de mquina
El lenguaje de mquina de una computadora consta de cadenas de
nmeros binarios (ceros y unos) y es el nico que "entienden"
directamente los procesadores. Todas las instrucciones preparadas en
cualquier lenguaje de mquina tienen por lo menos dos partes. La
primera es el comando u operacin, que dice a la computadora cul es
la funcin que va a realizar. Todas las computadoras tiene un cdigo de

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

operacin para cada una de sus funciones. La segunda parte de la


instruccin es el operando, que indica a la computadora donde hallar o
almacenar los datos y otras instrucciones que se van a manipular; el
nmero de operandos de una instruccin vara en las distintas
computadoras.
Lenguaje ensamblador
La comunicacin en lenguaje de mquina es particular de cada
procesador que se usa, y programar en este lenguaje es muy difcil y
tedioso, por lo que se empez a buscar mejores medios de comunicacin
con
sta.
A principios de la dcada de 1950, y con el fin de facilitar la labor de los
programadores, se desarrollaron cdigos mnemotcnicos para las
operaciones y direcciones simblicas. Uno de los primeros pasos para
mejorar el proceso de preparacin de programas fue sustituir los cdigos
de operacin numricos del lenguaje de mquina por smbolos
alfabticos, que conforman un lenguaje mnemotcnico. Todas las
computadoras actuales tienen cdigos mnemotcnicos aunque,
naturalmente, los smbolos que se usan varan en las diferentes marcas
y modelos. La computadora sigue utilizando el lenguaje de mquina
para procesar los datos, pero los programas ensambladores traducen
antes los smbolos de cdigo de operacin especificados a sus
equivalentes en lenguaje de mquina.
Los lenguajes ensambladores tienen ventajas sobre los lenguajes de
mquina. Ahorran tiempo y requieren menos atencin a detalles . Se
incurren en menos errores y los que se cometen son ms fciles de
localizar. Adems, los programas en lenguaje ensamblador son ms
fciles de modificar que los programas en lenguaje de mquina. Pero
existen limitaciones. La codificacin en lenguaje ensamblador es todava
un proceso lento. Adems, una desventaja importante de estos
lenguajes es que tienen una orientacin a la mquina. Es decir, estn
diseados para la marca y modelo especfico de procesador que se
utiliza.
En el principio de la computacin este era el lenguaje que tena
que "hablar" el ser humano con la computadora y consista en insertar
en un tablero miles de conexiones y alambres y encender y apagar
interruptores.

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Aunque en la actualidad ya no se emplea, es importante reconocer que


ya no es necesario que nos comuniquemos en este lenguaje de "unos" y
"ceros", pero es el que internamente una computadora reconoce o
"habla".
Lenguajes de alto nivel
Los primeros programas ensambladores producan slo una
instruccin en lenguaje de mquina por cada instruccin del programa
fuente. Para agilizar la codificacin, se desarrollaron programas
ensambladores que podan producir una cantidad variable de
instrucciones en lenguaje de mquina por cada instruccin del programa
fuente. Dicho de otra manera, una sola macroinstruccin poda producir
varias
lneas
de
cdigo
en
lenguaje
de
mquina.
El
desarrollo
de
las
tcnicas
mnemotcnicas
y
las
macroinstrucciones condujo, a su vez, al desarrollo de lenguajes de alto
nivel que a menudo estn orientados hacia una clase determinada de
problemas de proceso.
A diferencia de los programas de ensamble, los programas en lenguaje
de alto nivel se pueden utilizar con diferentes marcas de computadoras
sin tener que hacer modificaciones considerables. Esto permite reducir
sustancialmente el costo de la reprogramacin cuando se adquiere
equipo nuevo.

Los lenguajes de programacin se dividen en 4


principales paradigmas: imperativo, funcional, orientado a
objetos y lgico.
Lenguajes imperativos
Son llamados as porque estn casados en comandos que
actualizan variables que estn en almacenamiento.
En 1950, cuando los programadores reconocieron que las
variables y comandos de asignacin constituyen una simple pero
til abstraccin de memoria que se actualiza.
Debido a su relacin cerrada con las arquitecturas de las
mquinas, los lenguajes de programacin imperativa pueden ser
implementados eficientemente. La razn fundamental de la

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

programacin imperativa est relacionado a la naturaleza y


propsito de la programacin.

ADA

CLIPPER & XBASE

ENSAMBLADOR

QUICKBASIC

BASIC

EUPHORIA

FORTRAN

PASCAL

Lenguajes funcionales
Los lenguajes funcionales se basan en el concepto de funcin, por tanto,
el objeto bsico y fundamental que manejamos son las funciones,
que se pueden considerar las principales estructuras de control
en este tipo de lenguajes.
La base fundamental para comprender este tipo de lenguajes consiste
en ver los programas y aplicaciones expresados a travs de
funciones y aplicacin entre funciones.
Las caractersticas fundamentales de estos lenguajes se exponen a
continuacin:
a. Utilizacin de funciones sobre elementos de primer orden.
b. Utilizacin de funciones polimrficas, es decir, aqullas cuyo
tipo devuelto depende del tipo de los argumentos.

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

c. Utilizacin de funciones de orden superior, es decir, aquellas


funciones que aceptan en su lista de argumentos otras
funciones.
d. Evaluacin perezosa (o lazy), es decir, las expresiones no se
evalan hasta que no se necesitan los resultados. Es
justamente, lo contrario de la evaluacin eager(ansiosa),
donde la evaluacin de los argumentos se realiza antes de
aplicar la funcin. La evaluacin perezosa nos proporciona la
ventaja de trabajar con listas potencialmente infinitas.
e. Existencia de un sistema de tipos fuerte
f. Uso del Patter Matching: comprobacin de patrones.
Vistas las caractersticas fundamentales de los lenguajes funcionales,
estos pueden clasificarse en dos tipos:

Puros: aquellos en los que slo podemos aplicar funciones.


Estas son las nicas estructuras de control. Posee evaluacin
perezosa.
Impuros: aquellos que poseen evaluacin ansiosa.

Ejemplos de lenguajes funcionales:

ML
CAML

Haskell

Sheme

LISP

Lamda Clculo

Iswim

APL

FP

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Hope

Miranda

Eden

Gofer

Erlang

Programacin Orientada a Objetos

SmallTalk

Programacin Orientada a la lgica

PROLOG

LENGUAJES ESTRUCTURADOS
Los lenguajes estructurados incorporan una serie de
instrucciones que facilitan la construccin modular de los
programas as como correccin de errores y soporte de sistemas.
Esto facilita la comprensin del cdigo por cualquier otro
programador o analista y hace ms fcil la tarea de probar y
depurar los programas.
Adems poseen una abundante variedad de instrucciones que
facilitan el flujo o secuencia de los procedimientos o pasos que
debe seguir el programa para la realizacin de su objetivo.

ALGOL
ADA

COBOL

PASCAL

10

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

LENGUAJES DE INTELIGENCIA ARTIFICIAL


Podemos distinguir tres grandes estilos o subfamilias de los
lenguajes de inteligencia artificial. Los tres estilos de
programacin son los siguientes: programacin funcional,
programacin relacional y programacin por objetos. El lenguaje
ms representativo del estilo funcional es el LISP, LOGO por su
identificacin con LSIP, cae de lleno dentro de este estilo. El
lenguaje ms representativo del estilo relacional PROLOG. El
lenguaje ms representativo del estilo de programacin por
objetos es el SMALLTALK, pero existen varios dialectos de LISP
que permite programar en esta forma.

TRADUCTORES
Los traductores son programas que permiten pasar de un programa
fuente a un programa objeto.
En los lenguajes de bajo nivel los programas que permiten pasar de un
programa fuente a un programa objeto se llaman programas
ensambladores, mientras en los lenguajes de alto nivel estos programas
se denominan compiladores e intrpretes.
INTRPRETES
Un intrprete es un traductor que toma un programa fuente, lo traduce a
un programa objeto instruccin por instruccin, al mismo tiempo que
ejecuta el programa.
COMPILADORES
Los Compiladores son programas que traducen los programas fuentes a
programas objetos.
El compilador traduce sentencia a sentencia cada una de las
instrucciones del programa fuente a cdigo mquina y posteriormente
ejecuta el programa.

ESTRUCTURA DE UN COMPILADOR

11

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

La estructura de un compilador, esta dividida en cuatro


grandes mdulos, cada uno independiente del otro, se podra decir
que un compilador esta formado por cuatros mdulos mas a su vez. El
primero de ellos es el preprocesador, es el encargado de transformar el
cdigo fuente de entrada original en el cdigo fuente puro. Es decir en
expandir las macros, incluir las libreras, realizar un preprocesado
racional (capacidad de enriquecer a un lenguaje antiguo con recursos
ms modernos), extender el lenguaje y todo aquello que en el cdigo de
entrada sea representativo de una abreviatura para facilitar la escritura
del mismo.
El segundo modulo es el de compilacin que recibe el cdigo
fuente puro, este es l modulo principal de un compilador, pues si
ocurriera algn error en esta etapa el compilador no podra avanzar. En
esta etapa se somete al cdigo fuente puro de entrada a un anlisis
lxico grfico, a un anlisis sintctico, a un anlisis semntico, que
construyen la tabla de smbolos, se genera un cdigo intermedio al cual
se optimiza para as poder producir un cdigo de salida generalmente en
algn lenguaje ensamblador.
El tercer modulo es el llamado modulo de ensamblado, este
modulo no es ni ms mi menos que otro compilador pues recibe un
cdigo fuente de entrada escrito en ensamblador, y produce otro cdigo
de salida, llamado cdigo binario no enlazado. Si por un momento
viramos a este modulo como un programa independiente, veramos
que en este caso los trminos programa compilador y proceso de
compilacin son los mismos. Pues este modulo no es mas que un
compilador, que en su interior realiza como su antecesor un anlisis
lxico grfico, un anlisis sintctico, un anlisis semntico, crea una
tabla de smbolos, genera un cdigo intermedio lo optimiza y produce un
cdigo de salida llamado cdigo
binario no enlazado, y a todo este
conjunto de tares se los denomina proceso de compilacin. Como se
puede ver este compilador (llamado ensamblador) a diferencia de los
dems compiladores no realiza una expansin del cdigo fuente
original(cdigo fuente de entrada), tiene solamente un proceso de
compilacin y por supuesto no enlaza el cdigo fuente. Es un compilador
que carece de los mdulos de preprocesado y enlazado, y donde los
mdulos de compilacin y ensamblado son los mismos.

12

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

El cuarto y ultimo modulo es el encargado de realizar el enlazado


del cdigo de fuente de entrada (cdigo maquina relocalizable) con las
libreras que necesita, como as tambin de proveer al cdigo de las
rutinas necesarias para poder ejecutarse y cargarse a la hora de llamarlo
para su ejecucin, modifica las direcciones relocalizables y ubica los
datos en las posiciones apropiadas de la memoria. Este ultimo
modulo es el que produce como salida el cdigo binario enlazado. Ya sea
dinmico o esttico, al decir dinmico se refiere a que el cdigo
producido utiliza libreras dinmicas (libreras ya cargadas en el
sistema), esto implica que se obtendr un cdigo ms corto y que se
actualizara automticamente si aparece alguna nueva versin de las
libreras, mientras que el esttico se refiere al echo que no se realiza
enlace con ninguna librera y por lo tanto se obtendr un cdigo mas
largo con una copia de las rutinas de librera que necesita.

Estructura del proceso de Compilacin:


Analizando en detalle el proceso de compilacin, se divide en dos
grandes fases, una de Anlisis y la otra de Sntesis.

Fase de Anlisis:
En el llamado anlisis lexicogrfico o lxico, el compilador
revisa y controla que las "palabras" estn bien escritas y pertenezcan a
algn tipo de token (cadena) definido dentro del lenguaje, como por
ejemplo que sea algn tipo de palabra reservada, o si es el nombre de
una variable que este escrita de acuerdo a las pautas de definicin del
lenguaje. En esta etapa se crea la tabla de smbolos, la cual contiene las
variables y el tipo de dato al que pertenece, las constantes literales, el
nombre de funciones y los argumentos que reciben etc.
En el anlisis sintctico como su nombre lo indica se encarga de
revisar que los tokens estn ubicados y agrupados de acuerdo a la
definicin del lenguaje. Dicho de otra manera, que los tokens
pertenezcan a frases gramaticales validas, que el compilador utiliza para
sintetizar la salida. Por lo general las frases gramaticales son
representadas por estructuras jerrquicas, por medio de rboles de
anlisis sintctico. En esta etapa se completa la tabla de smbolos con la
dimensin de los identificadores y los atributos necesarios etc.

13

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

El anlisis semntico se encarga de revisar que cada agrupacin


o conjunto de token tenga sentido, y no sea un absurdo. En esta etapa
se
rene la informacin sobre los tipos para la fase posterior, en
esta etapa se utiliza la estructura jerrquica de la etapa anterior y as
poder determinar los operadores, y operandos de expresiones y
preposiciones.

Fase de Sntesis:
Etapa de generacin de cdigo intermedio, aunque algunos
compiladores no la tienen, es bueno saber de su existencia, en esta
etapa se lleva el cdigo del programa fuente a un cdigo interno para
poder trabajar mas fcilmente sobre l. Esta representacin interna
debe tener dos propiedades, primero debe ser fcil de representar y
segundo debe ser fcil de traducir al cdigo objeto.
En la etapa de optimizacin de cdigo, se busca obtener el
cdigo mas corto y rpido posible, utilizando distintos algoritmos de
optimizacin.
Etapa de generacin de cdigo, se lleva el cdigo intermedio
final a cdigo maquina o cdigo objeto, que por lo general consiste en
un cdigo maquina relocalizable o cdigo ensamblador. Se selecciona las
posiciones de memoria para los datos (variables) y se traduce cada una
de las instrucciones intermedias a una secuencia de instrucciones de
maquina puro.
La tabla de smbolos no es una etapa del proceso de
compilacin, sino que una tarea, una funcin que debe realizar el
proceso de compilacin. En ella se almacenan los identificadores que
aparecen en el cdigo fuente puro, como as tambin los atributos de los
mismos, su tipo, su mbito y en el caso de los procedimientos el nmero
de argumentos el tipo de los mismos etc. En otras palabras una tabla de
smbolos es una estructura de datos, que contiene un registro por cada
identificador, y sus atributos. La tabla de smbolo es accedida tanto para
escritura como parar lectura por todas las etapas. Detector de errores o
manejador de errores, al igual que la tabla de smbolos no es una etapa
del proceso de compilacin, si no que es una funcin, muy importante,
pues al ocurrir un error esta funcin debe tratar de alguna forma el error
para as seguir con el proceso de compilacin (la mayora de errores son

14

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

detectados en las etapas de anlisis lxico, anlisis sintctico, anlisis


semntico).
Supongamos que un compilador tiene que analizar la siguiente
preposicin:
Preposicin: suma = var1 + var2 + 10;
Anlisis Lxico
El analizador lxico lee los caracteres del programa
fuente, y verifica que correspondan a una secuencia lgica
(identificador, palabra reservada etc.). Esta secuencia de caracteres
recibe el nombre componente lxico o lexema. En este caso el
analizador lxico verifica si el identificador id1 (nombre interno para
"suma") encontrado se halla en la tabla de smbolos, si no esta produce
un error porque todava no fue declarado, si la preposicin hubiese sido
la declaracin del
identificador "suma" en lenguajes C, C++ (int
suma;) el analizador lxico agregara un identificador en la tabla de
smbolos, y as sucesivamente con todos los componentes lxicos que
aparezcan.
id1= id2+ id3 * 10
Anlisis Sintctico
El analizador sintctico impone una estructura jerrquica a la cadena de
componentes lxicos, generada por el analizador lxico, que es
representada en forma de un rbol sintctico.
=
/ \
id1 +
/ \
id2 +
/ \
id3 10
Anlisis Semntico
El analizador semntico verificara en este caso que cada operador
tenga los operandos permitidos.

15

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

=
/ \
id1 +
/ \
id2 +
/ \
id3 tipo_ent
|
10

Generador de cdigo intermedio


una representacin intermedia
maquina abstracta.

Esta etapa se lleva la preposicin a


como un programa para una

temp1= tipo_ent(10)
temp2= id3 * temp1
temp3= id2 + tem2
id1= temp3
Optimizacin de cdigo
El cdigo intermedio obtenido es
representado de una forma mas optima
y eficiente.
temp1= id3 * 10.0
id1= id2 + temp1
Generador de cdigo
Finalmente lleva el cdigo intermedio a un
cdigo objeto que en este
caso es un cdigo relocalizable o cdigo
ensamblador (tambin llamado cdigo no enlazado).
MOVF id3, R2
MULT #10.0, R2
MOVF id2, R1
ADDF R2, R1
MOVF R1, id1
Este el cdigo objeto obtenido que es enviado al modulo de ensamblado.
Para entender todo esto veamos un ejemplo utilizando como lenguaje en
este caso al popular lenguaje de programacin C creado por Kernighan

16

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

y Ritchie. El siguiente cdigo esta definido de acuerdo al standard ANSI


C.
#include<stdio.h>
void main()
{
char* frase= " Hola Mundo...!!!";
printf("%s", frase );
};
). Al pasar por l modulo de preprocesado, el cdigo fuente queda de la
siguiente manera.
# 1 "hmundo.c"
# 1 "c:/compilador/include/stdio.h" 1 3
# 1 " c:/compilador/include/sys/types.h" 1 3
# 12 " c:/compilador/include/stdio.h" 2 3
typedef void *va_list;
typedef long unsigned int size_t;
typedef struct {
int _cnt;
char *_ptr;
char *_base;
int _bufsiz;
int _flag;
int _file;
char *_name_to_remove;
} FILE;
El nuevo cdigo contiene el encabezado o prototipo de la/s funcin/es
que se encuentran en el archivo de cabecera stdio.h, y que sern
posiblemente utilizadas en el cdigo fuente original. Este cdigo es
pasado al modulo de compilacin quien luego de analizarlo y verificar si
se encuentra correcto, transformara el cdigo fuente puro (expandido)
en cdigo ensamblador y lo enva al modulo de ensamblado.
.file "hmundo.c"
compiler_compiled.:
___compiled_c:
.text
LC0:
.ascii " Hola Mundo...!!!\0"

17

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

LC1:
Este cdigo ser analizado por l modulo de ensamblado, que lo llevara
a cdigo binario no enlazado, y lo enviara al modulo de enlazado. El
cdigo de salida enviado al modulo de enlazado es el
siguiente.
L&#0;(7&#0;.text&#0;
@&#0;&#0;&#0;&#0; &#0;
.............
.data&#0;@&#0;@&#0;@&#0;
.bss&#0;@&#0;@&#0;&#128;
Hola Mundo...!!!&#0;%s&#0;v&#0;
UE&#0;EPh&#0;
v&#0;.file&#0;&#0;
ghmundo.c&#0;&#0;&#0;&#0;.

UNIDAD II
ELEMENTOS DE LA PROGRAMACIN DE SISTEMAS
CARGADORES
La programacin de sistemas se refiere a la creacin de programas
cuya finalidad es servir a otros programas.
Entre los programas que se manejan en la programacin de
sistemas se encuentran: los sistemas operativos, los compiladores, los
manejadores de base de datos.
Un cargador es un programa que coloca en la memoria para su
ejecucin,
el programa
guardado
en
algn
dispositivo
de
almacenamiento secundario.
Dependiendo de la manera en que se manejan los procesos de
ligas y carga, podemos clasificar a los cargadores en: cargadores
iniciales, absolutos, con reubicacin y ligadores.
Cargadores Iniciales: son aquellos que indican ala PC la forma de
poner en memoria principal, unos datos almacenados en un
perifrico de memoria externa (cintas, discos, etc.) sirven para
cargar con la memoria pequeos programas que inician el
funcionamiento de la computadora.

18

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Cargadores Absolutos: como ya se menciono, el programa


cargador pone en memoria las instrucciones guardadas en
sistemas externos. Si dichas instrucciones se almacenan siempre
en el mismo espacio de memoria (cada vez que se ejecute el
programa cargador), se dice que es un cargador absoluto.
Cargadores con publicacin: en ocasiones, un mismo programa
necesita ejecutarse en diferentes posiciones de memoria. Para
esto, la introduccin debe realizarse de forma adecuada, es decir,
sin emplear referencias absolutas a direcciones de memoria, si no
referencias relativas a una direccin especial llamada Direccin de
Reubicacin.
El calculo de las direcciones de reubicacin las hace el mismo
cargador a medida que va cargando las instrucciones en el espacio de
memoria que le indique al usuario o el sistema operativo de la maquina.
Cargadores ligadores: conocidos tambin como Link Editor por
su trmino en ingles o simplemente Linker, ala accin de motor
se le llama vulgarmente Lindar.
Montar un programa consiste en aadir al programa objeto.
Obteniendo en la traduccin las rutinas externas a las que hace
referencia dicho programa.
El ensamblador debe permitir dichas referencias y las rutinas debe
estar a su vez en lenguaje maquina guardadas en algn elemento
accesible al montaje.
Generalmente dichas rutinas se encuentran guardadas en ficheros
especiales llamados Libreras; donde estn almacenadas todas las
rutinas externas susceptibles a ser empleados por los diferentes
programas del usuario.
All va el programa ligador cuando esta realizando el montaje de un
programa a buscarlas y las adjunta al programa objeto.
En el proceso de carga reubicable (relocalizable), un mismo programa
puede ejecutarse en diferentes posiciones de memoria. Para esto, el

19

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

programa objeto debe utilizar referencias a relativas a una direccin


especial llamada direccin de reubicacin.
EI clculo de las direcciones reubicables es realizado por el cargador a
medida quo va ubicando las instrucciones en el espacio de memoria que
le indique el sistema operativo.
Cuando se utilizan subrutinas en un programa, el cdigo ejecutable de
cada una de ellas debe encontrarse en memoria al tiempo de ejecucin.
Para esto, antes de cargar un programa, debe ligarse su cdigo objeto
con los cdigos objeto (guardados en uno o ms archivos) de cada una
de las subrutinas invocadas por l, obteniendo as un programa
ejecutable que contiene tanto el cdigo del mdulo invocador como el
cdigo de los mdulos invocados. En este punto, es posible guardar el
resultado del proceso de liga en un archivo que podr ser utilizado por
un cargador, o el mismo programa ligador puede tambin realizar la
tarea de carga. Esto ltimo evita el tener que guardar el cdigo
ejecutable en un archivo, con lo que se ahorra espacio en disco. Este
ahorro de espacio en disco se paga con el tiempo gastado al tener que
ligar todos los mdulos cada vez que se necesite ejecutar el programa.
Este enlace se llama esttico porque se realiza antes de ejecutar el
programa.
Existe otro proceso llamado enlace dinmico, el cual consiste en enlazar
en tiempo de ejecucin los mdulos que contienen a las subrutinas.

ENSAMBLADORES
Que es ensamblador y para que sirve?
Cuando se empezaron a utilizar smbolos nemotcnicos, se
escribieron programas para traducir automticamente los programas
escritos en lenguaje ensamblador a lenguaje mquina. A estos
programas traductores se les llamo ensambladores.
La entrada para un ensamblador es un programa fuente escrito en
lenguaje ensamblador. La salida es un programa objeto, escrito en
lenguaje de mquina. El programa objeto incluye tambin la informacin

20

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

necesaria para que el cargador pueda preparar el programa objeto para


su ejecucin.
Para evitar confusiones, de aqu en adelante llamaremos lenguaje
ensamblador al conjunto de nemotcnicos y a las reglas para su manejo.
Al programa que traduce un programa objeto a partir de un programa
escrito en lenguaje ensamblador lo llamaremos ensamblador
Motivos para utilizarlo

Rapidez
Mayor control de la computadora
Independencia del lenguaje
La mayora de las computadoras pueden ensamblarlo

Motivo para no utilizarlo

Dependencia de hardware
Mayor tiempo de codificacin
Comprensin mas profunda de la computadora
Errores mas frecuentes en el programa

Tipos de Ensambladores.
Aunque todos los ensambladores realizan bsicamente las mismas
tareas, podemos clasificarlos de acuerdo a caractersticas.
As podemos clasificarlos en:

Ensambladores Cruzados (Cross-Assembler).

Se denominan as los ensambladores que se utilizan en una


computadora que posee un procesador diferente al que tendrn las
computadoras donde va a ejecutarse el programa objeto producido.
El empleo de este tipo de traductores permite aprovechar el soporte
de medios fsicos (discos, impresoras, pantallas, etc.), y de
programacin que ofrecen las mquinas potentes para desarrollar
programas que luego los van a ejecutar sistemas muy especializados en
determinados tipos de tareas.

Ensambladores Residentes.

21

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Son aquellos que permanecen en la memoria principal de la


computadora y cargan, para su ejecucin, al programa objeto producido.
Este tipo de ensamblador tiene la ventaja de que se puede comprobar
inmediatamente el programa sin necesidad de transportarlo de un lugar
a otro, como se haca en cross-assembler, y sin necesidad de programas
simuladores.
Sin embargo, puede presentar problemas de espacio de memoria, ya
que el traductor ocupa espacio que no puede ser utilizado por el
programador. Asimismo, tambin ocupar memoria el programa fuente y
el programa objeto. Esto obliga a tener un espacio de memoria
relativamente amplio. Es el indicado para desarrollos de pequeos
sistemas
de
control
y
sencillos
automatismo
empleando
microprocesadores.
La ventaja de estos ensambladores es que permiten ejecutar
inmediatamente el programa; la desventaja es que deben mantenerse
en la memoria principal tanto el ensamblador como el programa fuente
y el programa objeto.

Macroensambladores.

Son ensambladores que permiten el uso de macroinstrucciones


(macros). Debido a su potencia, normalmente son programas robustos
que no permanecen en memoria una vez generado el programa objeto.
Puede variar la complejidad de los mismos, dependiendo de las
posibilidades de definicin y manipulacin de las macroinstrucciones,
pero normalmente son programas bastantes complejos, por lo que
suelen ser ensambladores residentes.

Microensambladores.

Generalmente, los procesadores utilizados en las computadoras


tienen un repertorio fijo de instrucciones, es decir, que el intrprete de
las mismas interpretaba de igual forma un determinado cdigo de
operacin.

22

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

El programa que indica al intrprete de instrucciones de la UCP cmo


debe actuar se denomina microprograma. El programa que ayuda a
realizar este microprograma se llama microensamblador. Existen
procesadores que permiten la modificacin de sus microprogramas, para
lo cual se utilizan microensambladores.

Ensambladores de una fase.

Estos ensambladores leen una lnea del programa fuente y la


traducen directamente para producir una instruccin en lenguaje
mquina o la ejecuta si se trata de una pseudoinstruccin. Tambin va
construyendo la tabla de smbolos a medida que van apareciendo las
definiciones de variables, etiquetas, etc.
Debido a su forma de traduccin, estos ensambladores obligan a
definir los smbolos antes de ser empleados para que, cuando aparezca
una referencia a un determinado smbolo en una instruccin, se conozca
la direccin de dicho smbolo y se pueda traducir de forma correcta.
Estos ensambladores son sencillos, baratos y ocupan poco espacio, pero
tiene el inconveniente indicado.

Ensambladores de dos fases.

Los ensambladores de dos fases se denominan as debido a que


realizan la traduccin en dos etapas. En la primera fase, leen el
programa fuente y construyen una tabla de smbolos; de esta manera,
en la segunda fase, vuelven a leer el programa fuente y pueden ir
traduciendo totalmente, puesto que conocen la totalidad de los smbolos
utilizados y las posiciones que se les ha asignado.
Estos ensambladores son los ms utilizados en la actualidad.
El proceso de ensamble de uno, dos o ms pasos.
Como se vio en la seccin anterior, existen ensambladores que
realizan su tarea en una o ms fases o pasos.
El proceso de ensamble de un paso consiste en leer una lnea de
programa fuente y traducirla a lenguaje mquina cuando se trata de una
instruccin, o se ejecuta si es una seudoinstruccin.

23

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

La tabla de smbolos se va construyendo a medida que se avanza


en la lectura de las lneas del programa fuente.
Para que el ensamble de un paso funciones, todos los smbolos
deben estar definidos antes de emplearse. Esto debido a que, para
traducir correctamente cada instruccin, se debe conocer la direccin de
cada uno de los smbolos que intervienen en ella. En otras palabras, no
pueden quedar referencias pendientes porque ya no habr otra
oportunidad de resolverlas.
Tampoco podrn hacerse saltos hacia lneas posteriores. No es
posible saltar hacia una lnea cuya etiqueta todava no ha sido definida.
Para resolver el problema que presenta el proceso de ensamble de
un paso, se utiliza el proceso de ensamble de dos pasos o fases. En la
primera fase, se lee el programa fuente y se construye la tabla de
smbolos.
En la segunda fase, se vuelve a leer el programa fuente y se
traduce totalmente ya que se conoce la totalidad de los smbolos
utilizados (incluyendo las etiquetas) y las posiciones de memoria que se
les han asignado. Como ya se conocen las direcciones de las etiquetas
utilizadas, pueden realizarse saltos hacia adelante.
Literales y Expresiones.
En computacin, las literales son mecanismos mediante los cuales
se reservan espacios de memoria para guardar valores de cierto tipo.
Generalmente, el trmino literal se asocia un smbolo para representar la
direccin del primer byte de espacio asignado. En el espacio asignado se
pueden almacenar valores constantes o variables.
Las expresiones son combinaciones de literales y operadores. En
lenguaje ensamblador las expresiones involucran valores constantes y
operadores. Los resultados se almacenan como constantes ya que los
clculos ocurren durante el ensamble, no durante la ejecucin. Los
operadores que se utilizan en las expresiones de lenguaje ensamblador
no tienen ningn efecto en tiempo de ejecucin del programa
ensamblado. No debe confundirse el manejo de expresiones en lenguaje
ensamblador con el manejo de expresiones en los lenguajes de alto
nivel. En los lenguajes de alto nivel, la evaluacin de las expresiones se
hace en tiempo de ejecucin.

24

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Cada traductor dar sus reglas de construccin de expresiones y,


muy importante, de cmo las evala.

MACROPROCESADORES
USOS DE UN MACROPROCESADOR
Con el fin de evitar al programador la tediosa repeticin de partes
idnticas de un programa, los ensambladores y compiladores cuentan
con macroprocesadores que permiten definir una abreviatura para
representar una parte de un programa y utilizar esa abreviatura cuantas
veces sea necesario.
Para utilizar una macro, primero hay que declararla. En la
declaracin se establece el nombre que se le dar a la macro y el
conjunto de instrucciones que representar.
El programador escribir el nombre de la macro en cada uno de los
lugares donde se requiera la aplicacin de las instrucciones por ella
representadas.
La declaracin se realiza una sola vez, pero la utilizacin o
invocacin a la macro (macrollamada) puede hacerse cuantas veces sea
necesario.
La utilizacin de macros posibilita la reduccin del tamao del
cdigo fuente, aunque el cdigo objeto tiende a ser mayor que cuando
se utilizan funciones.
Es tan comn el empleo de macroinstrucciones se les considera
como una extensin de los lenguajes. De manera similar se considera al
procesador de macroinstrucciones o macroprocesador como una
extensin del ensamblador o compilador utilizado.
El macroprocesador se encarga, en una primera pasada, de
registrar todas las declaraciones de macros y de rastrear el programa
fuente para detectar todas las macrollamadas. En cada lugar donde
encuentre una macrollamada, el macroprocesador har la sustitucin
por las instrucciones correspondientes. A este proceso de sustitucin se
le denomina expansin de la macro.

25

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

El macroprocesador elabora dos tablas para el manejo de las macros:


Una tabla de macronombres que consiste de los nombres de las macros
y un ndice que le permite localizar la definicin de la macro en otra
tabla llamada tabla de macrodefiniciones.
Como su nombre lo indica, la tabla de macrodefiniciones contiene
las definiciones de todas las macros a utilizar en el programa.
En ocasiones es conveniente agrupar macros, de acuerdo a las
tareas que realizan, y almacenarlas en archivos que se constituyen en
bibliotecas de macros.
De esta manera, cuando se requiera la utilizacin de alguna macro
en particular, se incluye en el programa fuente el archivo de la biblioteca
de macros correspondiente.
La mayora de los ensambladores y compiladores permiten el uso
de pseudoinstrucciones condicionales del tipo IF ... ELSE, por medio de
las cuales se puede controlar la traduccin de ciertos bloques de
programa.

SISTEMAS OPERATIVOS
Es un programa que acta como intermedio entre el usuario y el
hardware de una PC y su propsito es proporcionar un entorno en el cual
el usuario pueda ejecutar sus programas.
El objetivo principal de un sistema operativo es, entonces, lograr
que el sistema de computacin se use de manera cmoda, y el objetivo
secundario es que el hardware del computador se emplee de manera
eficiente.
Un sistema Operativo es parte importante de casi cualquier
sistema de cmputo, el cual cuenta con y componentes bsicos:
hardware, Sistemas Operativos, programas de aplicacin y los usuarios.
El principal objetivo de un sistema operativo es proporcionar una
interfaz entre el equipo y los programas, para esto debe administrar los
recursos del sistema, de tal manera que su uso sea lo mas sencillo y
eficiente.

26

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

El hardware (unidad central de proceso (UCP), memoria y


dispositivos de entrada y salida (E/S)) proporciona los recursos de
computacin bsica bsicos.
Los programas de aplicacin (compiladores, sistemas de bases de
datos, juegos de vdeo y programas para negocios) definen la forma en
que estos recursos se emplean para resolver los problemas de
computacin de los usuarios. Puede haber distintos usuarios (personas,
mquinas, otros computadores) que intentan resolver problemas
diferentes; por consiguiente, es posible que haya diferentes programas
de aplicacin. El sistema operativo controla y coordina el uso del
hardware entre los diversos programas de aplicacin de los distintos
usuarios.
Los sistemas operativos son ante todo administradores de
recursos; el principal recurso que administran es el hardware del
computador: los procesadores, los medios de almacenamiento, los
dispositivos de entrada/salida, los dispositivos de comunicacin y los
datos. Los sistemas operativos realizan muchas funciones, como
proporcionar la interfaz con el usuario, permitir que los usuarios
compartan entre s el hardware y los datos, evitar que los usuarios
interfieran recprocamente, planificar la distribucin de los recursos,
facilitar la entrada y salida, recuperarse de los errores, contabilizar el
uso de los recursos, facilitar las operaciones en paralelo, organizar los
datos para lograr un acceso rpido y seguro, y manejar las
comunicaciones en red.
No existe una definicin universal aceptada de qu forma parte de
un sistema operativo y qu no. Una perspectiva sencilla considera como
tal todo lo que enva un vendedor cuando se ordena la adquisicin del
"sistema operativo". Sin embargo, los requisitos de memoria y las
caractersticas incluidas varan en forma considerable de un sistema a
otro. Algunos requieren menos de un megabyte de espacio e incluso
carecen de un editor de pantalla, mientras que otros necesitan cientos
de megabytes de espacio e incluyen revisores ortogrficos y sistemas de
ventanas. Una definicin ms comn es que el sistema operativo es el
programa que se ejecuta todo el tiempo en el computador (conocido
usualmente como ncleo), siendo programas de aplicacin todos los
dems. La segunda definicin es la ms comn y es la que utilizamos en
general.

27

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Quiz sea ms fcil definir los sistemas operativos por lo que


hacen, en vez de hacerlo por lo que son. El objetivo principal de un
sistema operativo es la comodidad para el usuario. Un objetivo
secundario es la utilizacin eficiente del sistema de computacin. Este
propsito tiene una importancia especial en los grandes sistemas
multiusuario compartidos; stos suelen ser muy costosos, por lo que es
deseable hacerlos lo ms eficientes posible.
Tipos de Sistemas Operativos.
Una forma de clasificacin de los sistemas operativos se basa en el
nmero de usuarios que el sistema puede atender al mismo tiempo.
As, tenemos sistemas de una sola tarea o trabajo, los cuales
pueden atender solo un trabajo (y por lo tanto un solo usuario) a la vez.
Un sistema de multiprogramacin permite que se ejecuten varios
trabajos al mismo tiempo. El sistema operativo se encarga de
intercambiar la atencin del procesador entre los programas en
ejecucin y las funciones de apoyo propias.
Un sistema de multiprocesamiento difiere del sistema de
multiprogramacin por el hecho de trabajar con varios procesadores a la
vez.
Otra forma de clasificar a los sistemas operativos toma en cuente
el tipo de acceso que proporcionan al usuario. En este caso, se tienen:
sistemas de procesamiento por lotes (batch processing), donde un
trabajo se define como una secuencia de instrucciones de control
almacenadas en algn dispositivo para que el sistema operativo pueda
leer y ejecutar una serie de trabajos, limitando la intervencin del
operador solo al montaje de cintas y discos. Por otra parte se tienen los
sistemas de tiempo compartido (multiusuario) que proporcionan acceso
interactivo o conversacional a varios usuarios, proporcionando a cada
uno de ellos pequeos intervalos de tiempo de acuerdo a la cantidad de
usuarios presentes y a la prioridad de cada uno de los procesos.

28

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

COMPILADORES
La necesidad de establecer comunicacin con dispositivos de
cmputo para un creciente nmero de usuarios ha obligado a construir
herramientas que permitan que esta comunicacin se realice de manera
ms efectiva y con menor consumo de tiempo.
Esto lo podemos apreciar desde finales de la dcada de los 50's,
cuando con el advenimiento de computadoras comerciales surge
tambin la necesidad de programarlas.
Se disearon lenguajes como FORTRAN y COBOL que permiten
realizar esta tarea de comunicacin al establecer una relacin entre los
problemas de los usuarios y lo que las mquinas eran capaces de
realizar.
Estos primeros lenguajes tambin vinieron acompaados de un
nuevo trmino: Compilador.
Se le atribuye a Grace Murray Hopper la acuacin de este trmino
y se refera al trabajo que estaba detrs de la programacin en aquellos
tiempos: exista una biblioteca de programas constituida de un conjunto
de rutinas, cada una de ellas probada individualmente; cuando se
necesitaba un programa, se elegan las rutinas necesarias de esa
biblioteca y se integraban para conformar el proceso que ejecutara la
computadora. Quin realizaba este trabajo de acopio de rutinas y de
integracin se le denominaba compilador, de ah que los nuevos
lenguajes tuviesen sus propios "compiladores" para la integracin del
proceso que programar representaba.
En nuestros das, el trmino an se conserva aunque con un
sentido ligeramente diferente al planteado por Hopper. Hoy en da, un
compilador es un traductor que facilita la comunicacin entre el
programador y la mquina, por medio de un proceso de transformacin.
Un compilador es un programa que lee las lneas escritas en un
lenguaje de programacin (como Pascal) y las traduce a otro que pueda
ejecutar la computadora. Los programas compilados se ejecutan ms
rpido que los interpretados, debido a que han sido completamente
traducidos a lenguaje de mquina y no necesitan compartir memoria
con el intrprete.

29

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

A grandes rasgos un compilador es un programa que lee un


programa escrito es un lenguaje, el lenguaje fuente, y lo traduce a un
programa equivalente en otro lenguaje, el lenguaje objeto. Como parte
importante de este proceso de traduccin, el compilador informa a su
usuario de la presencia de errores en el programa fuente.

Clasificacin de Compiladores
El programa compilador traduce las instrucciones en un lenguaje de
alto nivel a instrucciones que la computadora puede interpretar y
ejecutar. Para cada lenguaje de programacin se requiere un compilador
separado.
El compilador traduce todo el programa antes de ejecutarlo. Los
compiladores son, pues, programas de traduccin insertados en la
memoria por el sistema operativo para convertir programas de cmputo
en pulsaciones electrnicas ejecutables (lenguaje de mquina). Los
compiladores pueden ser de:

una sola pasada: examina el cdigo fuente una vez, generando el


cdigo o programa objeto.

pasadas mltiples: requieren pasos intermedios para producir un


cdigo en otro lenguaje, y una pasada final para producir y
optimizar el cdigo producido durante los pasos anteriores.

Optimacin: lee un cdigo fuente, lo analiza y descubre errores


potenciales sin ejecutar el programa.

Compiladores incrementales: generan un cdigo objeto instruccin


por instruccin (en vez de hacerlo para todo el programa) cuando
el usuario teclea cada orden individual. El otro tipo de
compiladores requiere que todos los enunciados o instrucciones se
compilen conjuntamente.

Ensamblador: el lenguaje fuente es lenguaje ensamblador y posee


una estructura sencilla.

30

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Compilador cruzado: se genera cdigo en lenguaje objeto para una


mquina diferente de la que se est utilizando para compilar. Es
perfectamente normal construir un compilador de Pascal que
genere cdigo para MS-DOS y que el compilador funcione en Linux
y se haya escrito en C++.

Compilador con montador: compilador que compila distintos


mdulos de forma independiente y despus es capaz de
enlazarlos.

Autocompilador: compilador que est escrito en el mismo lenguaje


que va a compilar. Evidentemente, no se puede ejecutar la
primera vez. Sirve para hacer ampliaciones al lenguaje, mejorar el
cdigo generado, etc.

Metacompilador: es sinnimo de compilador de compiladores y se


refiere a un programa que recibe como entrada las
especificaciones del lenguaje para el que se desea obtener un
compilador y genera como salida el compilador para ese lenguaje.
El desarrollo de los metacompiladores se encuentra con la
dificultad de unir la generacin de cdigo con la parte de anlisis.
Lo que s se han desarrollado son generadores de analizadores
lxicos y sintcticos. desarrollados para UNIX. Los inconvenientes
que tienen son que los analizadores que generan no son muy
eficientes.

Descompilador: es un programa que acepta como entrada cdigo


mquina y lo traduce a un lenguaje de alto nivel, realizando el
proceso inverso a la compilacin.

31

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

UNIDAD III
ANLISIS LXICO
EL ANALIZADOR LXICO
El analizador lxico lee los caracteres del programa fuente, y
verifica que correspondan a una secuencia lgica (identificador, palabra
reservada etc.). Esta secuencia de caracteres recibe el nombre
componente lxico o lexema.
FUNCIN DEL ANALIZADOR LXICO

Su principal funcin consiste en leer los caracteres de entrada y


elabora como salida una secuencia de componentes lxicos
(tokens) que utiliza el analizador sintctico para hacer el
anlisis.
Es la parte del compilador que lee el texto fuente.
Recibida la orden "obtn el siguiente componente lxico" del
analizador sintctico, el analizador lxico lee los caracteres de
entrada hasta que pueda identificar el siguiente componente
lxico.
Elimina del programa fuente comentarios, espacios en blanco,
caracteres TAB y de lnea nueva.

32

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Otra funcin es relacionar los mensajes de error del compilador


con el programa fuente.
En algunos compiladores, el analizador lxico se encarga de
hacer una copia del programa fuente en el que estn marcados
los mensajes de error.

El analizador Lxico dentro del modelo de un compilador.


En algunas ocasiones, los analizadores lxicos se dividen en dos
fases; la primera llamada "examen", y la segunda, "anlisis lxico". El
examinador se encarga de realizar tareas sencillas, mientras que el
analizador lxico es el que realiza las operaciones ms complejas.
El objetivo del anlisis lxico es gestionar el "bajo nivel" de la
entrada (en este caso, texto) y suministrarle al analizador sintctico la
misma ya "filtrada", es decir, conteniendo solamente terminales de la
gramtica a definir.
En ese trabajo se engloba facilitar la definicin de la gramtica ya
que, el hecho de tener que incluir todas las reglas hasta llegar a los
terminales ms bajos (caracteres) aumenta indeseablemente la
gramtica.
Este tipo de trabajos ms sencillos (como reconocer nmeros,
buscar palabras clave, obviar espacios y dems separadores...) se
suelen dejar al analizador lxico, que ser un programa muy sencillo y
funcionar siempre en tiempo lineal (si le asignamos un trabajo mayor
es que seguramente lo estaremos sobrecargando con funciones de
anlisis sintctico, lo cual nunca debiera ocurrir).
Realmente, el hecho de esta separacin simplemente busca
simplificar al mximo la gramtica independiente del contexto
trabajando con las unidades ms abstractas posibles.

33

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

La gramtica que queda para el anlisis lxico, siempre debe ser


regular, ya que cada unidad lxica puede venir determinada, por una
expresin regular.
La relacin entre el analizador lxico y el sintctico son los tokens
y la tabla de smbolos, ya que la funcin principal del anlisis lxico es
leer los caracteres de entrada y genera como salida una secuencia de
componentes lxicos previamente definidos en expresiones regulares.

ASPECTOS A CONSIDERAR PARA EL ANLISIS LXICO


Un diseo sencillo de un analizador lxico corresponde a unas
reglas del lenguaje meramente sencillas, sin embargo estas son algunas
consideraciones importantes:

Mientras menos complicadas sean las gramticas, ms fcil


ser realizar un compilador, slo que previamente se deben
considerar las expresiones regulares.
Hay que considerar si se debe o puede mejorar la eficiencia
del compilador.
Tambin mejorar la transportabilidad del compilador, ya que
las letras del alfabeto y los errores propios de los dispositivos
pueden limitar al analizador lxico.

El trabajo bsico es reconocer los terminales (que podemos llamar ya


unidades lxicas), y para ello podemos hacer una tabla con todas las
posibilidades que encontraremos en el fichero de la entrada y agruparlos
en los tipos necesarios.

Caracteres que corresponden directamente con la unidad lxica.

Unidades lxicas (terminales) que pueden contener varios


caracteres.

Caracteres que pueden figurar en el texto pero que no se


consideran (se desechan).

Cualquier otro carcter es errneo, y producir, por ello, un error


lxico.
Bajo esta fase se generan los tokens. La generacin de los tokens se
ha llevado a cabo mediante la carga del fichero que contiene el cdigo
fuente en una lista, tras esto se procede a convertir tabuladores y saltos

34

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

de lnea en espacios para despus dejar estrictamente los necesarios


para diferenciar las distintas palabras introducidas en el archivo fuente.
Por ejemplo, una entrada del tipo:
Si

a>b

Entonces

a=c+d:
FinEntonces:
pasara a ser Si a>b Entonces a=c+d: FinEntonces: en nuestra lista de
entrada.
Una vez que tenemos la lista de entrada limpia se procede a la
creacin de los tokens; para ello, se ha definido otro tipo de lista llamado
Tokens que contendr el nombre del token (cadena leda por la pantalla)
junto con el tipo al que pertenece.
La implementacin del analizador lxico responde al mtodo
general de programacin visto en teora, por lo tanto se manejan dos
punteros, uno al ltimo carcter ledo y otro al ltimo carcter aceptado
con lo cual podemos movernos por la lista de entrada en bsqueda del
siguiente token sin perder la posicin desde donde comenzamos la
presente bsqueda. Los tokens, o smbolos terminales de la gramtica,
han sido representados mediante dos tablas, una para los que van
acompaados de un parntesis y otra para los que no.
El motivo de esta separacin ha sido el trato distinto que se les ha
dado a ambos para no tener que distinguir, dentro de las rdenes que
lleva un parmetro, si entre el final de la orden y el parntesis que rodea
al parmetro hay o no espacios. As las ordenes Mira (id) y Mira(id) son
tratadas como el mismo token y toman el ``('' como parte de l.
Los smbolos separadores (espacios, ``:'', etc.) han sido recogidos
del mismo modo en otra tabla dado el trato distinto de los anteriores
que recibirn.
Con esta forma de recoger los tokens que reconoce este analizador
hemos conseguido no tener que realizar grandes modificaciones sobre

35

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

esta fase del compilador, si algn da fuera modificado el conjunto de


smbolos terminales de la gramtica.

ANLISIS LXICO: DESARROLLO


Objetivo
El objetivo bsico del scanner o analizador lxico es separar el
programa fuente en unidades mnimas y asociarles una determinada
clase o token.
Por qu?

Formalmente, para separar lo lineal de lo jerrquico. En el scanner no


hay que mirar hacia atrs: las unidades lxicas se forman con
caracteres siempre consecutivos y no pueden solaparse dos unidades
lxicas. Hay que tener en cuenta que las reglas lxicas son bastante
sencillas y no necesitan una notacin tan poderosa como una
gramtica; las expresiones regulares son ms sencillas y fciles de
entender que una gramtica.
Eficiencia, porque es el nico proceso que lee el programa fuente y
por ello pueden estudiarse tcnicas especializadas de manejo de
dispositivos de almacenamiento (la eficiencia es ms fcilmente
alcanzable partiendo de expresiones regulares que de gramticas).
Diseo modular del compilador, relacionado con esto ltimo.
Portabilidad, ya que la mayora de diferencias del mismo lenguaje
entre distintos entornos suele ser en caracteres especiales,
capitalizacin, cdigos de caracteres, etc. y as se encapsulan en el
scanner.

Funciones del scanner


Las funciones bsicas del scanner son:

Leer el programa fuente

Delimitar los lexemas

Identificar cada token

Asignar atributo a cada unidad lxica


Para hacer la interaccin con el parser, lo ms habitual es convertir al
scanner en una subrutina del parser, para que as pueda responder a la
orden "obtener la siguiente unidad lxica" recibida del parser.

36

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Como el scanner lee el programa fuente, tambin realiza ciertas


funciones secundarias como son eliminar comentarios y caracteres no
significativos (espacios, tabuladores, retornos de carro...) o preprocesar
las macros.
Otra funcin secundaria del analizador lxico es relacionar los
mensajes de error con el programa fuente (ya que para que al usuario le
sean significativos es necesario que no se pierda esta relacin).
En este sentido, en algunos compiladores el scanner va produciendo
una copia del fuente en la que se marcan los mensajes de error, se
expanden las macros, etc.
La ltima funcin del scanner es detectar los errores lxicos que
puedan producirse. A este nivel, los errores se restringen a localizar
caracteres no reconocidos, combinaciones de caracteres imposibles, o
intentos de lectura por detrs del fin de fichero.
Tipos de unidades lxicas: concepto de patrn
Hay dos clases de unidades lxicas:

Las definidas por el lenguaje: palabras clave, operadores, smbolos


especiales. Nmero finito (quizs 1) de lexemas.
Las definidas por el programador (bajo ciertas normas genricas):
identificadores, literales, comentarios. Normalmente, el nmero
"posible" de lexemas es infinito.

El patrn de las primeras es la simple enumeracin de los lexemas;


de las segundas, una serie de normas que describen todas las cadenas
que corresponden al mismo token.
El patrn permite identificar el token y asignar el atributo
(suponiendo delimitado el lexema). Es decir, una vez delimitado el
lexema, cumplir algn patrn, y ese es el que marca el token. Se dice
que el patrn concuerda con el lexema que cumple ese patrn.
De este modo, lo primero que debe definirse en todo lenguaje de
programacin es una tabla con todos los patrones lxicos del lenguaje
indicando token y atributo para cada patrn.

37

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Por ejemplo, tomando un subconjunto de Pascal:


Token

Lexemas
ejemplo

Descripcin del patrn

pc-then

then

(t/T)(h/H)(e/E)(n/N)

pc-while

while

while

pc-write

write

write

pc-incdec

to

to

downto

downto

<

<

>

>

par-ab

par-cer

ident

Hola, A77aH,
pepe

Letra seguida de letras y dgitos

lit-ent

34, 23442, 1

Dgito no cero seguido de dgitos

lit-real

34.0, 23.4e-5

Dgito no cero seguido de dgitos


seguido opcionalmente de punto
decimal y dgitos, seguido
opcionalmente de 'E' o 'e' y dgitos

lit-string

'Hola', 'pe pe '

Caracteres entre ', excepto '

op-rel

En la mayora de los lenguajes se consideran tokens las


construcciones: palabras clave, operadores, identificadores, literales y
signos de puntuacin. Por supuesto, dependiendo del lenguaje se
subdividirn en varios componentes lxicos ms.
Normas lxicas
El problema ahora es cmo delimitamos el lexema? En un
principio, podramos pensar en utilizar un carcter fijo para delimitar
lexemas, por ejemplo el espacio. De este modo, la sentencia
if A < 50 then write ( 4 )
puede verse fcilmente separada en los lexemas "if", "A", "<", "50",
"then", "write", "(", "4", ")", simplemente observando las series de

38

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

caracteres separadas por espacios. Dado cada uno de estos lexemas,


ser muy sencillo ver si cumple algn patrn y devolver el token y
atributo correspondiente al patrn que se cumple.
En este funcionamiento es fundamental, por ello, la influencia de las
distintas normas lxicas: si las palabras clave pueden usarse como
identificadores, cules son los separadores, etc. De hecho, la evolucin
de los distintos lenguajes de programacin ha ido tendiendo a utilizar
reglas lxicas que hagan cada vez ms sencillo el desarrollo del scanner.
Vamos a enunciar brevemente las ms influyentes en este sentido:

En general, los espacios (y tambin tabuladores y retornos) no son


significativos (es decir, no forman parte de ningn lexema ni
constituyen un token) pero s son separadores.

Las palabras clave suelen ser reservadas. Cuando no lo son (por


ejemplo, en PL/I), el scanner debe distinguir entre palabras clave e
identificadores, lo cual suele ser complicado.
Por ejemplo:
if then then then = else ; else else = then;
El scanner, no puede diferenciar entre identificadores y palabras
clave, o bien diferenciarlos le supone trabajo "extra".

En caso de conflicto, se elige el lexema ms largo. Por ejemplo, ifa es


el identificador ifa y no la palabra clave if seguida del identificador a.
Esto es lgico porque si no limitaramos mucho los identificadores, al
no poder indicar ninguna variable ni nombre de procedimiento o
funcin empezada por do, ni por if, ni por or, ni por and ...
(imaginemos lo que ocurrira con lenguajes con muchas palabras
reservadas).

El problema del anlisis lxico, se reduce entonces a reconocer el


cumplimiento de patrones por determinados lexemas. Hay dos
herramientas formales que nos permiten hacer este trabajo de un modo
muy sencillo:

39

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Los autmatas finitos.

Son las posibles cadenas que acepta un lenguaje. Se compila una


expresin regular en un reconocedor construyendo un diagrama de
transicin que es una instrumentacin de un modelo formal
denominado autmatas finitos, conocidos tambin como mquinas de
estado finito o (con menos frecuencia en la actualidad) mquinas
secuenciales.
Es la representacin grfica de las posibles cadenas que acepta un
lenguaje dentro de un conjunto de smbolos, se conforma por una
quntupla donde:
Q es el conjunto de posibles estados
representa al alfabeto
representa la funcin de transicin y los estados por los que se
acepta cada uno de los smbolos
qo estado inicial
F conjunto de estados finales

Las expresiones regulares.

Son los posibles smbolos que puede aceptar un lenguaje los cuales
se pueden representar con un autmata. Conjunto de smbolos para
aceptar una palabra reservada.
Una expresin regular es una frmula para denotar "ciertos"
lenguajes. Advirtase que decimos lenguaje, no cadena de
caracteres. Una expresin regular nica denota un conjunto de
cadenas, es decir un lenguaje, no una simple cadena. Las expresiones
regulares se pueden usar para especificar unidades lxicas presentes

40

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

en un lenguaje de programacin. No todos los lenguajes pueden ser


expresados utilizando una expresin regular.
Sea un alfabeto . La expresin regular sobre y los conjuntos que
denotan se definen de manera recursiva como sigue:
1. es una expresin regular y denota al conjunto vaco {}.
2. Para cada a , a es una expresin regular y denota al
conjunto {a}.
3. Si r y s son expresiones regulares que denotan a los lenguajes R
y S.;
respectivamente, entonces tenemos lo siguiente.
r+s
(r)
rs
r*
desde

es
es
es
es

una
una
una
una

expresin
expresin
expresin
expresin

regular
regular
regular
regular

que
que
que
que

denota
denota
denota
denota

a los conjuntos R S.
al conjunto R.
a los conjuntos RS.
al conjunto R*, equivale

cero a ms repeticiones del lenguaje R.


r+
es una expresin regular que denota al conjunto R+,
equivale a una
o ms repeticiones del lenguaje R.
ri es una expresin regular que denota al conjunto Ri, a s
mismo.

a)

TABLAS DE SMBOLOS
Es una estructura de datos que contiene un registro por cada
token o identificador que define los atributos de ellos mismos. La
estructura de datos permite encontrar rpidamente el registro para ser
almacenado o consultado por otras fases.
Cuando el anlisis lxico detecta un token en el programa fuente,
este se introduce e la tabla de smbolos, sin embargo, sus atributos no
pueden determinarse durante el anlisis lxico.
Por ejemplo, dada la siguiente instruccin:

41

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Var
inicial, velocidad: integer ;
Posicin
en
memoria

Token

Valor

;
integer
:
velocidad
,
inicial
Var

Delimitador
P. R. Int
S. Punt.
Id
Separador
Id
P. R. Var

Utilizado
por

El tipo entero no se conoce cuando el analizador lxico pasa por


toda la instruccin, las fases restantes introducen informacin sobre los
tokens en la tabla y despus hace uso de ella.
Cuando se hace el anlisis semntico y la generacin de cdigo
intermedio se necesita saber los tipos de cada uno de los identificadores
para comprobar si el programa fuente los usa en forma vlida y as
generar las operaciones apropiadas con ellos.
MTODOS GENERALES PARA LA IMPLANTACIN DE UN ANALIZADOR
LXICO
a) Utilizar un generador de analizador lxico automtico. Por ejemplo:
La herramienta Lex, que proporciona rutinas para leer la entrada y
generar componentes lxicos.
b) Describir el analizador lxico en un lenguaje convencional de
programacin utilizando subrutinas de entrada / salida.
c) Escribir el analizador lxico en lenguaje ensamblador.

42

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

UNIDAD IV
ANLISIS SINTCTICO
El objetivo fundamental del anlisis sintctico es "construir un
rbol sintctico" con la cadena de entrada (el "programa"), en la forma
de unidades lxicas que determina el analizador lxico, como se
muestra en la siguiente figura:

El Analizador Sintctico dentro del modelo de un compilador.


Si esto se consigue, el programa es (sintcticamente) correcto; y
es incorrecto en caso contrario. Se supone que el analizador sintctico
informar de cualquier error de sintaxis de manera inteligible. Tambin
deber recuperarse de los errores que ocurren frecuentemente para
poder continuar procesando el resto de su entrada.

43

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Existen tres tipos generales de analizadores sintcticos para


gramticas. Los mtodos universales de anlisis sintctico, como el
algoritmo de Cocke-Younger-Kasami y el de Earley, pueden analizar
cualquier gramtica. Estos mtodos sin embargo, son demasiado
ineficientes para usarlos en la produccin de compiladores. Los mtodos
empleados generalmente en la produccin de compiladores se clasifican
como descendentes o ascendentes.
Los dos tipos principales de anlisis sintctico son:
Descendente: construye el rbol desde la raz hacia las hojas.
Ascendente: construye el rbol desde las hojas hacia la raz.
En ambos casos, se examina la entrada al analizador sintctico de
izquierda a derecha, un smbolo a la vez. Los mtodos descendentes y
ascendentes ms eficientes trabajan slo con subclases de gramticas.
La salida del analizador sintctico es una representacin del rbol
de anlisis sintctico para la cadena de componentes lxicos producida
por el analizador lxico. En la prctica, hay varias tareas que se pueden
realizar durante el anlisis sintctico, como recoger informacin sobre
distintos componentes lxicos en la tabla de smbolos, realizar la
verificacin de tipo y otras clases de anlisis semntico. Para la
implementacin del analizador sintctico debe de ser necesaria la
redefinicin de la gramtica dada en la prctica de modo que sea
``entendible'' por la computadora. Dentro de la gramtica generada se
deber eliminar la recursividad a izquierdas.
Se sabe que los programas pueden contener errores de muy
diversos tipos. Por ejemplo los errores pueden ser:

Lxicos, como escribir mal un identificador, palabra clave u


operador.
Sintcticos, como una expresin aritmtica con parntesis no
equilibrados.
Semnticos, como un operador aplicado a un operando
incompatible.
Lgicos, como una llamada infinitamente recursiva.

A menudo, gran parte de la deteccin y recuperacin de errores en


un compilador se centra en la fase de anlisis sintctico. Una razn es
que muchos errores son de naturaleza sintctica o se manifiestan

44

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

cuando la cadena de componentes lxicos que proviene del analizador


lxico desobedece la reglas gramaticales que definen el lenguaje de
programacin. Otra razn es la precisin de los mtodos modernos de
anlisis sintctico, que pueden detectar la presencia de errores dentro
de los programas de una forma muy eficiente. La deteccin exacta de la
presencia de errores semnticos y lgicos en el momento de la
compilacin es mucho ms difcil.
El manejador de errores en un analizador sintctico tiene objetivos
fciles de establecer:

Debe de informar de la presencia de errores con claridad y


exactitud.
Se debe de recuperar de cada error con la suficiente rapidez como
para detectar errores posteriores.
No de be retrazar de manera significativa el procesamiento de
programas correctos.

Afortunadamente lo errores ms comunes son simples y a menudo


basta con un mecanismo sencillo de manejo de errores. sin embargo, en
algunos casos un error pudo haber ocurrido mucho antes de la posicin
en que se detect su presencia, y puede ser muy difcil deducir su
naturaleza precisa de error. En los casos difciles, el manejador de
errores quiz tenga que adivinar qu tena en mente el programador
cuando escribi el programa.
Varios mtodos de anlisis sintctico, detectan un error lo antes
posible. Es decir, tienen la propiedad del prefijo viable, la cual quiere
decir que detectan la presencia de un error nada ms con ver un prefijo
de la entrada que no es prefijo de ninguna cadena del lenguaje.
Cmo debe informar un manejador de errores de la presencia de un
error ?, al menos debe informar del lugar en el programa fuente donde
se detecta el error, porque es muy probable que el error real se haya
producido en alguno de los componentes lxicos anteriores. Una
estrategia comn empleada por muchos compiladores e imprimir la lnea
errnea con un apuntador a la posicin donde se detecta el error. Si hay
una posibilidad razonable de saber cul es realmente el error, tambin
se incluye un mensaje de diagnstico informativo y comprensible; por
ejemplo "Falta punto y coma en esta posicin".

45

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Una vez detectado el error, Cmo se debe de recuperar el


analizador sintctico ?, En la mayora de los casos, no es adecuado que
el analizador sintctico abandone despus de detectar el primer error,
porque el posterior procesamiento de la entrada podra revelar ms
errores. Normalmente, hay alguna forma de recuperacin del error
donde el analizador sintctico intenta volver l mismo a un estado en el
que el procesamiento de la entrada pueda continuar con una esperanza
razonable de que har el anlisis de la entrada correcta o de que ser
manejada correctamente por el compilador.
Una estrategia conservadora para un compilador es inhibir los
mensajes de error que provengan de errores descubiertos demasiado
cerca uno de otros en la cadena de entrada. Despus de descubrir un
error sintctico, el compilador podra exigir que varios componentes
lxicos se analizarn sintcticamente con xito antes de permitir otro
mensaje de error. En algunos casos, puede haber demasiados errores
como para que el compilador contine un procesamiento razonable.
Parece que una estrategia de recuperacin de errores tiene que ser un
compromiso cuidadosamente considerado, teniendo en cuenta la clase
de errores que se pueden presentar y que sean de procesamiento
razonable. Algunos compiladores intentan reparar el error proceso en el
cual el compilador intenta adivinar lo que pretenda escribir el
programador.
Hay muchas estrategias generales distintas que puede emplear un
analizador sintctico para recuperarse de un error sintctico. Aunque
ninguna de ellas ha demostrado ser la aceptacin universal, algunos
mtodos tienen una amplia aplicabilidad. Mencionaremos algunas
estrategias, entre las cuales estn:

Recuperacin en modo de pnico: Este es el mtodo ms sencillo


de implantar y pueden utilizarlo la mayora de los mtodos de
anlisis sintctico. Al descubrir un error, el analizador sintctico
desecha smbolo de entrada, de uno en uno, hasta que encuentra
uno perteneciente a un conjunto designado de componente lxicos
de sincronizacin. Estos componente lxicos de sincronizacin son
generalmente delimitadores, como el punto y coma o la palabra
clave end, cuyo papel en el programa fuente est claro. Es
evidente que quien disea el compilador debe seleccionar los
componentes lxicos de sincronizacin adecuados para el lenguaje
fuente. Aunque la correccin en modo de pnico a menudo omite

46

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

una cantidad considerable de entrada sin comprobar la existencia


de errores adicionales, tiene la ventaja de la sencillez y, a
diferencia de otros mtodos, esta garantizado contra lazos
infinitos. En situaciones en donde son raros los errores mltiples
en la misma proposicin, este mtodo puede resultar bastante
adecuado.

Recuperacin a nivel de frase: Al descubrir un error, el analizador


sintctico puede realizar una correccin local de la entrada
restante; es decir, puede sustituir un prefijo de la entrada restante
por alguna cadena que permita continuar al analizador sintctico.
Una correccin local tpica sera sustituir una coma por un punto y
coma, suprimir un punto y coma sobrante e insertar un punto y
coma que falta. La eleccin de la correccin local corresponde al
diseador del compilador. Por supuesto se debe de tener cuidado
de elegir sustituciones que no conduzcan a lazos infinitos.
Este tipo de sustitucin puede corregir cualquier cadena de entrada y ha
sido empleado en varios compiladores que corrigen los errores. El
mtodo se us por primera vez en el anlisis sintctico descendente. Su
principal desventaja es su dificultad para afrontar situaciones en que el
error real se produjo antes del punto de deteccin.

Producciones de error: Si se tiene una buena idea de los errores


comunes que puede encontrarse, se puede aumentar la gramtica
del lenguaje con producciones que generen la construcciones
errneas. Entonces se usa esta gramtica aumentada con las
producciones de error para construir el analizador sintctico. Si el
analizador sintctico usa una produccin de error, se pueden
generar diagnsticos de error apropiados para indicar la
construccin errnea reconocida en la entrada.

Correccin global: Idealmente, sera deseable que un compilador


hiciera el mnimo de cambios posibles al procesar una cadena de
entrada incorrecta. Existen algoritmos para elegir una secuencia
mnima de cambios para obtener una correccin global de menor
costo. Dada una cadena de entrada incorrecta x y la gramtica G,
estos algoritmos encontrarn un rbol de anlisis sintctico para
una cadena relacionada y, tal que el nmero de inserciones,
supresiones y modificaciones de componentes lxicos necesarios
para transformar x en y sea el mnimo posible. Por desgracia, la
implantacin de estos mtodos es en general demasiado costosa

47

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

en trminos de tiempo y espacio, as que estas tcnicas en la


actualidad slo son de inters terico.
Se debe sealar que un programa correcto ms parecido al original
puede no ser lo que el programador tena en mente. Sin embargo, la
nocin de correccin de costo mnimo proporciona una escala para
evaluar las tcnicas de recuperacin de errores, y se ha usado para
encontrar cadenas de sustitucin ptimas para recuperacin a nivel de
frase.
Gramticas.
Las gramticas describen lenguajes. Los lenguajes naturales como
el espaol o el ingles, son con frecuencia descritos por una gramtica
que agrupa las palabras en categoras sintcticas tales como sujetos,
predicados, frases preposicionales, etc.
Expresndolo en forma matemtica, una gramtica es un
dispositivo formal para expresar un lenguaje potencialmente infinito, en
una manera finita, puesto que es imposible enumerar todas las cadenas
de caracteres en un lenguaje, ya sea espaol ingls o Pascal. Al mismo
tiempo un gramtica impone una estructuras a la sentencias en el
lenguaje. Es decir una gramtica, G, define un lenguaje L(G) mediante la
definicin de una manera de para derivar todas las cadenas en el
lenguaje.
De una manera ms general:
Una gramtica es un sistema para definir un lenguaje, como
tambin una herramienta para imponer a las cadenas del lenguaje una
estructura til.
Una gramtica G es una 4-tupla G = {N,,P, S} donde:
N : alfabeto de no-terminales " n N n
: alfabeto terminal
P : Conjunto finito de producciones consistente de expresiones de la
forma con (N )+ y (N )*
S : smbolo inicial S N
NS =

48

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

GRAMTICAS Y LENGUAJES SENSIBLES AL CONTEXTO.


Una forma de definir un lenguaje es mediante un reconocedor
que acepte las palabras que pertenecen a l. Los lenguajes sensibles al
contexto contienen, propiamente, a los lenguajes independientes al
contexto a su vez, los lenguajes recursivos contienen propiamente a los
lenguajes sensibles al contexto.
DEFINICION FORMAL MATEMATICA DE LAS GRAMTICAS SENSIBLES AL
CONTEXTO (CSGS)
Es una 4-TUPLA formada por (N, S ,S ,P) donde:
N: Coleccin de smbolos no terminales.
: Alfabeto del lenguaje.
S: Smbolo especial llamado smbolo inicial.
P: Conjunto de producciones si todas las producciones son de la forma
,
donde , (N U )+ y | | <= | |.
El conjunto de los lenguajes sensibles al contexto contiene el conjunto
de los lenguajes independientes del contexto. La restriccin de que el
lado derecho de las producciones en una gramtica sensible al contexto
sea al menos tan largo como el lado izquierdo hace que la gramtica sea
no contrctil. Puesto que la cadena vaca tiene longitud cero, podemos
deducir de la definicin que L(G), para cualquier gramtica que es
sensible al contexto. A veces es conveniente que la cadena pertenezca
al lenguaje que ha sido generado por una gramtica sensible al
contexto.
Clasificacin de las Gramticas.
Lenguaje
Lenguajes
Regulares

Gramtica

Autmata

Detector
Gramtica Regular deterministico no
deterministico finito

Ejemplo
a*

+ Gramtica-lineal
Derecha
+
Gramtica-lineal

49

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Izquierda
Lenguaje libre
de contexto

+ Gramtica libre
de contexto

Autmata pushdown
no
deterministico

ab

Lenguaje sensible
al contexto

+Gramtica
Sensible al
contexto

Autmata LinealVinculada

abc

Lenguajes
Recursivos
Enumerables

+ Gramtica norestringida

Maquina de Turng

Cualquier
Funcin
Computable

Jerarqua de Chomsky.
En 1959, Noam Chomsky clasific las gramticas en cuatro tipos
de lenguajes y esta clasificacin es conocida como la jerarqua de
Chomsky, tal como se muestra en al Tabla 3.1, en la cual cada lenguaje
es descrito por el tipo de gramtica generado. Estos lenguajes sirven
como base para la clasificacin de lenguajes de programacin.
Los cuatro tipos son: lenguajes recursivamente enumerables,
lenguajes sensibles al contexto, lenguajes libres de contexto y lenguajes
regulares. Dichos lenguajes tambin se identifican como lenguajes de
tipo 0,1,2 y 3.
Las gramticas sensibles al contexto reciben el nombre de
gramticas de tipo 1, porque del lado izquierdo puede haber ms de un
elemento, lo que implica que un smbolo puede reemplazarse en el
contexto de otros.
Una gramtica es de tipo 1 si se exige que la longitud del miembro
derecho de toda regla de produccin sea mayor o igual que la longitud
del izquierdo. Con esto se impide que las cadenas que se obtengan en el
transcurso de la aplicacin de las reglas sean de longitud decreciente, y
se impide as mismo el caso extremo de que mediante una gramtica de
tipo1 puedan desaparecer cadenas de smbolo.
Gramtica y lenguaje
Reconocedor
Que genera
Autmatas lineal
TIPO 1
(Sensible al contexto)

50

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Entre las gramticas no restringidas y la forma restringida de las


gramticas independientes al contexto, se pueden definir varias
gramticas con diferentes niveles de restriccin.
Existe una exacta correspondencia entre cada uno de estos tipos
de lenguajes y particulares arquitecturas de mquinas en el sentido que
por cada lenguaje tipo T hay una arquitectura de mquina A que
reconoce el lenguaje A hay un tipo T tal que todos los lenguajes
reconocidos por A son de tipo T. La correspondencia entre lenguajes y
arquitectura son mostrados en la siguiente tabla:
Tipo
Mquina

de

Recursivamente Mquina
Enumerables
Turing

de

Sensibles
contexto

al Autmata
Lineal Acotado

Libres
contexto

de Autmatas de
Pila

Tipo Lenguajes

Autmatas
Finitos
y
3
Expresiones
Regulares
Los cuatro tipos de gramticas.
Lenguajes
Regulares

Sobre un alfabeto dado, el conjunto de lenguajes recursivamente


enumerables contiene propiamente al conjunto de lenguajes recursivos
que contiene propiamente al conjunto de lenguajes sensibles al contexto
que contiene propiamente al conjunto de lenguajes libres de contexto,
que a su vez contiene propiamente a los lenguajes regulares, tal como
se muestra:

51

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Gramticas Ambiguas
Si una oracin en espaol tiene mas de un significado, se dice que es
ambigua. Con frecuencia tales oraciones pueden analizarse
sintcticamente en mas de una forma.
La oracin:
El tiempo vuela como una flecha.
Puede interpretarse tiempo como sustantivo, vuela como verbo y
una flecha, como una frase adverbial. Esta interpretacin es un
comentario acerca del rpido paso del tiempo. Sin embargo, si "tiempo"
se interpreta como adjetivo, "vuela" como sustantivo, "como" como un
verbo y flecha como un sujeto directo, la oracin se convertira en un
comentario acerca de la vida amorosa de alguna especie.
En forma similar, se asigna significado a las construcciones en los
lenguaje de programacin con base en sus sintaxis. Por consiguiente,

52

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

preferimos que las gramticas de los lenguajes de programacin


describan programas sin ambigedad alguna.
Una sentencia es ambigua si hay mas de una derivacin
distinta. Si una sentencia es ambigua, su rbol de anlisis
sintctico no es nico; podemos crear mas de un rbol sintctico
para la misma sentencia.
Una gramtica se dice que es ambigua si hay dos o ms
rboles de derivacin distintos para la misma cadena.
Para ver lo anterior consideraremos esta gramtica. O lo que es lo
mismo:
Es la gramtica que produce mas de una derivacin por la derecha
o por la izquierda para la misma frase
S SbS | ScS | a
Podemos derivar la cadena "abaca" de dos formas distintas como sigue:
S SbS SbScS SbSca Sbaca abaca
S ScS SbScS abScS abacS abaca
El rbol de derivacin para la derivacin 1 es el que se muestra en la
Figura:

53

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Primer rbol de derivacin para la gramtica dada.


mientras que el rbol para la derivacin 2 es el que se muestra en la
siguiente figura:

Segundo rbol de derivacin para la gramtica dada.


Obsrvese que los dos rboles son distintos, aunque las cadenas
producida son la misma. La ambigedad puede ser un problema para

54

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

ciertos lenguajes en los que su significado depende, en parte, de su


estructura, como ocurre con los lenguajes naturales y los lenguajes de
programacin. Si la estructura de un lenguaje tienen ms de una
composicin y si la construccin parcial determina su significado,
entonces el significado es ambiguo.
La ambigedad no siempre es una propiedad inherente de los
lenguajes; existen gramticas ambiguas y no ambiguas para algunas
construcciones.
Para demostrar que una gramtica es ambigua, lo nico
que hay que hacer es encontrar una cadena de componentes
lxicos que tanga mas de un rbol sintctico. Como una cadena
que cuenta con mas de un rbol sintctico suele tener mas de un
significado, para aplicaciones de compilacin es necesario disear
gramticas no ambiguas o utilizar gramticas ambiguas con reglas
adicionales para resolver las ambigedades.
Recurdese que una gramtica independiente del contexto es
ambigua si hay dos derivaciones por la izquierda que son distintas para
la misma cadena. La gramtica independiente del contexto:
S ASB |SS |
B b
Es ambigua, ya que hay dos derivaciones por la izquierda de a2b2.
Por desgracia, en general no es posible determinar si una
gramtica independiente del contexto es ambigua. Es decir, la cuestin
de la ambigedad de gramticas independientes del contexto.
CONCEPTOS:
SMBOLO TERMINAL: Es un smbolo que no aparece en el lado
izquierdo de ninguna produccin.
NO TERMINALES: Los no-terminales son los nodos no-hojas en un rbol
de anlisis sintctico.
PRODUCCIONES: Se pueden pensar como un conjunto de reglas de
reemplazo.

55

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

SMBOLO DE INICIO: El smbolo de partida o de inicio, tambin


denominado smbolo meta es un no- terminal especial diseado como el
nico a partir del cual todas las cadenas son derivadas.
FORMA SENTENCIAL: Una forma sentencial es cualquier cadena de
caracteres derivada desde el smbolo de inicio.
SENTENCIA: una sentencia es una forma que consiste solamente de
terminales tales como a + a * a

MTODOS DESCENDENTES O TOP-DOWN.


El anlisis sintctico descendente crea una derivacin ms a la
izquierda, los pasos son:
1)
2)

Comenzar con el smbolo de inicio como la raz del rbol de


anlisis sintctico.
En cada paso, reemplace el no terminal del lado izquierdo en la
forma sentencial actual.

Se puede considerar el anlisis sintctico descendente como un


intento de encontrar una derivacin por la izquierda para una cadena de
entrada. Equivalentemente puede ser visto como el intento de construir
un rbol de anlisis sintctico para la entrada comenzando desde la raz
y creando los nodos del rbol en orden previo. Por ejemplo considere la
gramtica:
S cAd
A ab | a
y la cadena de entrada w = cad. Para construir un rbol de anlisis
sintctico descendente para esta cadena, primero se crea un rbol
formado por un solo nodo etiquetado con S. Un apuntador a la entrada
apunta a c, el primer smbolo de w. Despus se utiliza la primera
produccin de S para expandir el rbol y obtener el rbol de la Fig.(a).
Se empareja la hoja ms a la izquierda, etiquetada con c, con el
primer smbolo de w, y a continuacin se aproxima el apuntador de
entrada a a, el segundo smbolo de w, y se considera la siguiente hoja

56

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

etiquetada con A. Entonces se puede expandir A utilizando la primera


alternativa de A para obtener el rbol de la Fig. (b).
Como ya se tiene una concordancia para el segundo smbolo de la
entrada, se lleva el apuntador de entrada a d, el tercer smbolo de la
entrada, y se compara d con la hoja siguiente, etiquetada con b. Como b
no concuerda con d, se indica fallo y se regresa a A para saber si existe
otra alternativa de A que no se haya intentado, pero se puede dar lugar
a un emparejamiento.
Al regresar a A, se debe restablecer el apuntador de entrada a la
posicin 2, aquella que tenia al ir a A por primera vez, se intenta a
continuacin la segunda alternativa de A para obtener el rbol de la Fig.
(c).
Se empareja la hoja a con el segundo smbolo de w, y la hoja d,
con el tercer smbolo. Como ya se ha producido un rbol de anlisis
sintctico par w, se para y se anuncia el xito de la realizacin completa
del anlisis sintctico.

Pasos en el Anlisis Sintctico Descendente.


Anlisis Sintctico por Descenso Recursivo.
Un analizador sintctico de descenso recursivo se compone de un
procedimiento para cada smbolo no terminal de la gramtica, cuando se

57

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

llama un procedimiento este intenta encontrar una subcadena de la


entrada, empezando por el componente lxico actual, que se pueda
interpretar como el no terminal con el cul est asociado al
procedimiento.
Durante este proceso puede llamar a otros procedimientos o
llamarse a s mismo recursivamente, para buscar otros no terminales. Si
un procedimiento encuentra el no terminal que pretende, devuelve una
indicacin con xito a quin lo llam, y tambin avanza el apuntador al
componente lxico situado despus de la subcadena que acaba de
reconocer. Si el procedimiento es incapaz de encontrar una subcadena
que pueda interpretarse como el no terminal deseado, devuelve una
indicacin de fallo o invoca a una rutina de diagnstico y recuperacin
de
errores.
A

modo

de

ejemplo

considrese

la

siguiente

gramtica:

<lect> ::=READ(<lista_id)>
<lista_id> ::=id | <lista_id>,id
que definen la sintaxis de la proposicin READ del lenguaje PASCAL.
El procedimiento para <lect> es un analizador sintctico de
descenso recursivo examina primero los 2 siguientes componentes
lxicos de entrada buscando READ y (. Si se encuentran, entonces el
procedimiento para <lect> llama el procedimiento para <lista_id>. Si
ese procedimiento tiene xito, el procedimiento <lect>, examina el
siguiente componente lxico buscando un ). Si todas estas pruebas
tienen xito el procedimiento <lect> devuelve una indicacin de xito a
quien lo llama y avanza al prximo componente lxico que sigue a ). En
otro caso el procedimiento devuelve una indicacin de fallo.
El procedimiento es ligeramente ms complicado cuando hay varias
opciones definidas por la gramtica para un no terminal. En este caso el
procedimiento debe decidir que opcin intentar. Para la tcnica de
descenso recursivo, se debe poder decidir qu opcin utilizar
examinando el siguiente componente lxico de entrada. Hay otros
mtodos descendentes que eliminan este requisito, aunque no son tan

58

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

eficientes

como

el

descendente

recursivo.

Si se intentara escribir los procedimientos para la gramtica anterior, se


descubrira un problema. El procedimiento para <lista_id>, sera incapaz
de decidir entre sus dos opciones, pues tanto id, como <lista_id>
pueden comenzar con id. Sin embargo hay una dificultad ms
importante, si el procedimiento hubiera decidido intentar la segunda
opcin <(lista_id,id)>, se llamara de inmediato a si mismo
recursivamente para encontrar una <lista_id>. Esto podra producir otra
llamada recursiva inmediata, que dara lugar a una cadena sin fin. La
razn de esto es que una de las opciones para <lista_id> empieza con
<lista_id>. Los analizadores sintcticos descendentes no pueden usarse
directamente con una gramtica que contenga esta clase de recursin
por
la
izquierda
inmediata.
A continuacin se muestra la gramtica anterior por la recursin
por la izquierda eliminada:
<lect> ::= READ(<lista_id>)
<lista_id> ::= id<mas_id>
<lista_id> ::= , id <mas_id>|
Pudindose representarse tambin as:
<lect> ::= READ(<lista_id>)
<lista_id> ::= id{,id}
Esta notacin, que es una extensin comn a BNF, especifica que
los trminos entre { y } se pueden omitir o repetir una o mas veces. De
esta forma la gramtica define a <lista_id> compuesta de un id seguida
de cero o mas ocurrencias de ",id". Con la definicin revisada, el
procedimiento para <lista_id> simplemente busca primero un id, y
despus sigue explorando la entrada mientras los dos siguientes
componentes lxicos sean una como(,) e id. Esto elimina el problema de
la recursin por la izquierda y tambin la dificultad de decidir que opcin
intentar
para
<lista_id>.

59

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Anlisis Sintctico descendente recursivo de una proposicin


READ.

La Fig. anterior ilustra el anlisis sintctico descendente recursivo


de la proposicin READ, con la gramtica anterior. En el apartado (1), se
ha llamado el procedimiento LECT y se han examinado los componentes
lxicos READ y "(" del flujo de entrada (indicado con lneas punteadas).
En el apartado (2), LECT ha llamado a LISTA_ID (indicado con lnea
continua), que ha examinado el componente id. En el apartado (3),
LISTA_ID ha vuelto a LECT indicando que ha tenido xito; por lo que LECT
ha examinado el componente lxico de entrada ), con esto se completa
el anlisis de la proposicin fuente. El procedimiento READ regresara
ahora a quin lo llam, indicando que se encontr satisfactoriamente un
<lect>. Obsrvese que la secuencia de llamadas a procedimientos y la
exploracin de componentes lxicos ha definido por completo la
estructura de la proposicin READ.

60

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Ejemplo Descendente Recursivo


Gramtica
Programa
Sentencias
Sentencias'
Sentencia
Asignacin
Expresin
Expresin'
Termino
Termino'
Factor

Sentencias

Sentencia Sentencias'

Sentencias |

Asignacin ;

Id := Expresin

Termino Expresin'

+ Termino Expresin' |

Factor Termino'

* Factor Termino' |

( Expresin )

|
|

Id
Literal

Anlisis sintctico Predictivo.


Un analizador sintctico predictivo, llamado tambin anlisis
sintctico descendente recursivo es un mtodo descendente en el que
se ejecuta un conjunto de producciones para procesar una entrada, a
cada smbolo no terminal de una gramtica se le asocia con una
produccin. Es una forma eficiente de implementar el anlisis sintctico
descendente implcitamente manteniendo una pila, en vez de hacerlo
implcitamente mediante llamadas recursivas. El modelo sintctico
predictivo puede verse en la figura de abajo. Un analizador sintctico es
guiado por una tabla en la que se encuentran las producciones.

61

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Modelo de un analizador sintctico predictivo.


Caractersticas:
Es una forma eficiente de un analizador sintctico recursivo.
Mantiene una PILA en vez de hacer llamadas recursivas.
El analizador sintctico predictivo tiene una ENTRADA, una
TABLA de anlisis sintctico y una SALIDA, adems de la PILA.
La Pila contiene una secuencia de smbolos de alguna gramtica
que debe de finalizar con un $ (delimitador).
El elemento inicial de la gramtica debe de ser la cima de la
PILA.
La
TABLA
es
un
arreglo
bidimensional
(matriz),
M
[smbolo_no_terminal , smbolo_terminal_$]
El analizador sintctico esta controlado por un programa que
trabaja como sigue. El programa determina a X, el smbolo en la cima de
la pila, y a, el smbolo de la entrada actual. Estos dos smbolos
determinan la accin del analizador sintctico: hay tres posibilidades:
1.Si X = a = $, el analizador sintctico se detiene y anuncia el
xito de la realizacin del anlisis sintctico.
2.Si X = a$, el analizador sintctico saca a X dela pila y avanza el
apuntador de entrada al siguiente smbolo de entrada.
3.Si X es un smbolo no terminal el programa consulta la entrada
M[X,a] de la tabla de anlisis sintctico. Esta entrada podra ser una

62

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

produccin cualquiera de la gramtica o un error. Si M[X,a] = {XUVW},


el analizador sintctico reemplaza a X en la cima de la pila por WVU (con
U en la cima). Si M[X,a] = error el analizador sintctico llama a una
rutina de recuperacin de error.
Se puede describir el comportamiento del analizador sintctico en
trminos de su configuracin, la cual es dada por el contenido de la pila
y la entrada restante. Inicialmente el analizador sintctico esta en la
configuracin:
Pila
Entrada
$S
w$
donde S es el smbolo de inicio dela gramtica y w es la cadena
que ha de ser analizada.
Gramtica
E TE'
E' TE' |
T FT'
T' FT |
F (E) | id
Algoritmo
1.
Si X = a = $, el analizador sintctico se detiene y anuncia el
xito de la realizacin del anlisis sintctico.
2.
Si X = a $,el analizador sintctico saca a X de la pila y
avnzale apuntador de entrada al siguiente smbolo de entrada.
3.
Si X es un smbolo no terminal el programa consulta la
entrada M[X,a] de la tabla de anlisis sintctico. Esta entrada podra ser
una produccin cualquiera dela gramtica o un error. Si M[X,a] =
{XUVW}, el analizador sintctico reemplaza a X en la cima dela pila
por WVU (con U en la cima). Si M[X,a] = error el analizador sintctico
llama a una rutina de recuperacin de error.
Se puede describir el comportamiento del analizador sintctico en
trminos de su configuracin, la cual es dada por el contenido de la pila
y la entrada restante. Inicialmente el analizador sintctico esta en la
configuracin:
Pila Entrada
$S
w$

63

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

donde S es el smbolo de inicio dela gramtica y w es la cadena que ha


de ser analizada.
Matriz de precedencia resultante
id
E

E TE

E TE
E E

T FT

T FT
T

T
F

E +TE

E
T

T *FT

F id

F(E)

Anlisis
Se analizar la cadena siguiente:
id + id * id $
Paso 1
Inicialmente la pila contiene el smbolo de inicio de la gramtica
precedido por el delimitador "$", as que tenemos en la pila a "$E". Y en
la entrada tenemos a la cadena completa.
Paso Pila
Entrada
Salida
1

$E

id + id * id
$

Paso 2
En la cima de la pila tenemos a "E" verificamos en la gramtica y
tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y
reemplazamos X = E por su produccin la cual es TE'. Introduciremos la
produccin en el orden inverso, y tendremos en la pila "$ E' T", y la
salida ser la produccin del no terminal "E".
Paso 3
En la cima de la pila tenemos a "T" verificamos en la gramtica y
tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y
reemplazamos X = T por su produccin la cual es FT'. Introduciremos la

64

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

produccin en el orden inverso, y tendremos en la pila "$ E' T' F", y la


salida ser la produccin del no terminal "T".
Paso 4
Como la cima de la pila esta X= F y este produce el smbolo de la
cadena leda, se sustituye por su produccin que es el terminal "id" y
avanza el apuntador de entrada al siguiente smbolo de la cadena,
ahora tendremos en la pila "$ E' T' id", y la salida ser la produccin de
"F".
Paso 5
Como "id" es igual al smbolo de entrada actual se compara y se saca de
la pila y avanza el apuntador al siguiente smbolo de entrada.
Paso 6
En la cima de la pila tenemos a "T'" verificamos en la gramtica y
tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y
reemplazamos X = T' por su produccin la cual es . Introduciremos la
produccin en el orden inverso, y tendremos en la pila "$ E' " "$ E' ", y
la salida ser la produccin del no terminal " T' ".
Paso 7
En la cima de la pila tenemos a " E' " verificamos en la gramtica y
tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y
reemplazamos X = E' por su produccin la cual es +TE'. Introduciremos
la produccin en el orden inverso, y tendremos en la pila "$ E' T +" y la
salida ser la produccin del no terminal " E' ".
Paso 8
Como "+" es igual al smbolo de entrada actual se compara y se saca de
la pila y avanza el apuntador al siguiente smbolo de entrada.
Paso 9
En la cima de la pila tenemos a " T " verificamos en la gramtica y
tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y
reemplazamos X = T por su produccin la cual es FT'. Introduciremos la
produccin en el orden inverso, y tendremos en la pila "$ E' T' F" y la
salida ser la produccin del no terminal " T ".
Paso 10
Como la cima de la pila esta X= F y este produce el smbolo de la
cadena leda, se sustituye por su produccin que es el terminal "id" y

65

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

avanza el apuntador de entrada al siguiente smbolo de la cadena,


ahora tendremos en la pila "$ E' T' id", y la salida ser la produccin de
"F".
Paso 11
Como "id" es igual al smbolo de entrada actual se compara y se saca de
la pila y avanza el apuntador al siguiente smbolo de entrada.
Paso 12
En la cima de la pila tenemos a " T' " verificamos en la gramtica y
tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y
reemplazamos X = T' por su produccin la cual es *FT'. Introduciremos la
produccin en el orden inverso, y tendremos en la pila "$ E' T' F *" y la
salida ser la produccin del no terminal " T' ".
Paso 13
Como "*" es igual al smbolo de entrada actual se compara y se saca de
la pila y avanza el apuntador al siguiente smbolo de entrada.
Paso 14
Como la cima de la pila esta X= F y este produce el smbolo de la
cadena leda, se sustituye por su produccin que es el terminal "id" y
avanza el apuntador de entrada al siguiente smbolo de la cadena,
ahora tendremos en la pila "$ E' T' id", y la salida ser la produccin de
"F".
Paso 15
Como "id" es igual al smbolo de entrada actual se compara y se saca de
la pila y avanza el apuntador al siguiente smbolo de entrada.
Paso 16
En la cima de la pila tenemos a " T' " verificamos en la gramtica y
tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y
reemplazamos X = T' por su produccin la cual es . Introduciremos la
produccin en el orden inverso, y tendremos en la pila "$ E'" "$ E' " y
la salida ser la produccin del no terminal " T' ".
Paso 17
En la cima de la pila tenemos a " E' " verificamos en la gramtica y
tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y
reemplazamos X = E' por su produccin la cual es . Introduciremos la

66

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

produccin en el orden inverso, y tendremos en la pila "$ E'" "$ E' " y
la salida ser la produccin del no terminal " T' ".
Paso

Pila

Entrada

Salida

$E

id + id * id $

$ E' T

id + id * id $

E TE

$ E' T' F

id + id * id $

T FT

$ E' T' Id

id + id * id $

F id

$ E' T'

+ id * id $

$ E'

+ id * id $

$ E' T +

+ id * id $

E +TE

$ E' T

id * id $

$ E' T' F

id * id $

T FT

10

$ E' T' Id

id * id $

F id

11

$ E' T'

* id $

12

$ E' T' F *

* id $

13

$ E' T' F

id $

14

$ E' T' Id

id $

15

$ E' T'

16

$ E'

17

T *FT
F id

En la cima de la pila tenemos a " $ " y este es igual al smbolo ledo y a


su vez es igual al delimitador, entonces el analizador sintctico se
detiene y anuncia el xito de la realizacin del anlisis de la cadena.

MTODOS ASCENDENTES O BOTTOM UP.


El anlisis sintctico por desplazamiento intenta construir un rbol
de anlisis sintctico para una cadena de entrada que comienza por las
hojas (el fondo) y avanza hacia la raz (la cima). Se puede considerar
este proceso como de "reducir" una cadena w al smbolo inicial de la
gramtica. En cada paso de reduccin se sustituye una subcadena

67

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

determinada que concuerde con el lado derecho de una produccin por


el smbolo del lado izquierdo de dicha produccin y si en cada paso se
elige correctamente la subcadena, se traza una derivacin por la
derecha en sentido inverso.
Considrese la siguiente gramtica:
S aABe
A Abc | b
Bd
La frase "abbcde" se puede reducir a S por los siguientes pasos:
abbcde
aAbcde
aAde
aABe
S
Se examina abbcde buscando una subcadena que concuerde con
el lado derecho de alguna produccin. La subcadenas b y d sirven.
Eljase la b ms situada a la izquierda y sustityase por A, el lado
izquierdo de la produccin A b; as se obtiene la cadena aAbcde. A
continuacin, las subcadenas Abc, b y d concuerdan con el lado derecho
de alguna produccin. Aunque b es la subcadena situada ms a la
izquierda que concuerda con el lado derecho de una produccin, se elige
sustituir la subcadena Abc por A, que es el lado derecho de la
produccin A Abc. Se obtiene ahora aAde. Sustituyendo despus d por
B que es el lado izquierdo de la produccin B d, se obtiene aABe,
ahora se puede sustituir toda la cadena por S. Por tanto, mediante una
secuencia de cuatro reducciones se puede reducir abbcde a S. De hecho,
estas reducciones trazan la siguiente derivacin por la derecha en orden
inverso:
S aABe aAde aAbcde abbcde

Anlisis Sintctico de Precedencia Simple.

Este mtodo realiza el anlisis sintctico buscando rpidamente el


mango (frase simple mas a la izquierda) u de la forma sentencial actual
y reducindola a un no terminal U, usando una regla U u . El problema

68

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

en cualquier analizador sintctico ascendente es encontrar el mango,


entonces saber a que no terminal se reducir.
Dada una forma sentencial X, considerar dos smbolos R y S en el
vocabulario V de una gramtica G . Suponer que hay una forma
sentencial ...RS... . En algn punto cualquiera R o S (o ambas), deben de
estar en un mango. Las siguientes tres posibilidades surgiran:
R es parte de un mango pero S no Fig. (a). En este caso escribimos R > S
y decimos que R es mas grande que S, o que R tiene precedencia sobre
S, porque deber ser reducido primero. Note que R deber ser el smbolo
final de alguna regla U ...R. Note que debido a que el mango esta a la
izquierda de S, S deber ser un terminal.
R y S estn ambos en un mango Fig.(b). Decimos que R S, ellos tienen
la misma precedencia y debern ser reducidos al mismo tiempo.
Obviamente deber existir una regla U ...RS... en la gramtica.
S es parte de un mango pero R no Fig. (c), decimos que R < S o que R es
menor que S y S deber ser la cabeza de alguna regla U S...
Si no hay una funcin sentencial ...RS... entonces decimos que no hay
relacin entre el par ordenado(R,S).

Ilustracin de las Relaciones de Precedencia.


Algoritmo de Anlisis de Precedencia Simple.
Cuando se usan las relaciones de precedencia para reconocer
sentencias, lo mejor es usar una forma compacta para representarlas, la
tcnica usual es tener la matriz P con los valores:

69

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

P[i,j] = 0
P[i,j] = 1
P[i,j] = 2
P[i,j] = 3

si no existe relacin entre Si y Sj


si Si < Sj
si Si = Sj
si Si > Sj

Podemos hacer esto para una gramtica de precedencia porque


sabemos que a lo sumo una relacin existe entre los entre dos smbolos
cualquiera.
Las reglas deben estar en una tabla, estructurada de tal forma
que, dado un lado derecho, podamos encontrarlo en las reglas y
encontrar el correspondiente lado izquierdo.
El algoritmo trabaja como sigue: Los smbolos de la cadena de
entrada son procesados de izquierda a derecha y almacenados en una
pila S, hasta que la relacin de precedencia > exista entre el smbolo de
la cima de la pila y el siguiente smbolo entrante. Esto significa que el
smbolo de la cima de la pila es el final del mango, y por lo tanto el
mango entero esta en la pila. Este mango es entonces encontrado en la
lista de reglas y reemplazado en la pila, por el correspondiente no
terminal el cual debe ser reducido. El proceso se repite hasta que la pila
contenga Z y el siguiente smbolo de entrada sea $ (delimitador). Cada
forma sentencial est encerrada entre los smbolos $ y $ (asumiendo
que $ no es un smbolo de la gramtica). Adems se establece que $ < S
y S > $ para cualquier smbolo S de la gramtica.
En la Fig. se muestra un diagrama de flujo para el analizador
sintctico usando la siguiente notacin:
S es una pila usada para mantener los smbolos; su contador es i.
j es un ndice usado para hacer referencia los elementos en la
cima de la pila.
La sentencia a ser analizada sintcticamente es TiT2...Tn.
Empezamos con el delimitador de la sentencia $ en la pila y asumimos
que ha sido anexada a la sentencia como T[n+1].
Q y R son variables para mantener ciertos smbolos durante el
proceso de anlisis.
Note que la cadena T1...Tn no es una sentencia, entonces el
algoritmo parar e indicar esto.

70

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Analizador sintctico de precedencia simple.


BLOQUE 1: Inicializar la pila S para mantener el delimitador de
sentencia ($). Poner el ndice de la sentencia apuntando al primer
smbolo.
BLOQUE 2: Obtener el siguiente smbolo, colocarlo en R e
incrementar k.
BLOQUE 3 - 4: Si (S(i),R) no esta en >, el mango no esta
completamente en la pila, entonces metemos R en la pila y obtenemos
el siguiente smbolo.
BLOQUE 5 - 7: Si S(i) >R, el mango deber estar en la pila. Estos
bloques buscan la cabeza del mango.

71

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

BLOQUE 8 - 9 :Checar la cadena S(j)...S(i). Si no esta en la parte


derecha de una regla, el proceso ha terminado. La cadena fue una
sentencia si y solamente si 1 = 2 y S(i) = Z. Si es la parte derecha de
una regla, borramos el mango de la pila (bloque 9), metemos en la pila
el smbolo el cual es reducido y regresamos al bloque 3 para buscar el
siguiente mango.
Una ventaja acerca de este y otros analizadores sintcticos
similares es que la cadena completa de los smbolos de entrada no
necesitan estar en memoria al mismo tiempo. Los smbolos son ledos
uno a la vez de la entrada y almacenados en la pila, pero como el mango
es reducido, estos desaparecen. Solamente si el mango est en el final
derecho de la cadena necesita que la cadena completa est
almacenada.
Ejemplo
Gramtica
E E + T | T
T T * F | F
F ( E ) | id
Matriz de precedencia resultante
E

+ *

> =

>

> >

>

id

= <

<

<

<

<

= < <

<

<

> >

>

id

> >

>

Anlisis
Se analizar la cadena siguiente:
(x+y)

72

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Paso Pila

Relaci
R Token
n

<

( x+y)$

$(

<

x +y)$

$(x

>

y)$

$(E

y)$

$(E+

<

)$

$
(E+y

>

$
(E+T

>

$(E

$(E)
>
$
$
Anlisis Sintctico LR.

El nombre de esta tcnica de anlisis sintctico LR(k) proviene de


L por el exmen de la entrada de izquierda a derecha (en ingls Left-toRight), la R por construir una derivacin por la derecha (en ingls
rightmost derivation) en orden inverso, y la k por el nmero de smbolos
de entrada de examen por anticipado utilizados para tomar las
decisiones del anlisis sintctico. Cuando sta se omite, se asume que k
es 1. Esta tcnica de anlisis sintctico resulta conveniente por varias
razones:
Se puede construir analizadores sintcticos LR para reconocer
prcticamente todas las construcciones de los lenguajes de
programacin para los que se pueden escribir gramticas libres de
contexto.
El mtodo de anlisis sintctico LR es el mtodo de anlisis por
desplazamiento y reduccin sin retroceso ms general que se conoce y
sin embargo se puede aplicar tan eficientemente como los otros
mtodos de desplazamiento y reduccin.
La clase de gramticas que pueden analizarse con los mtodos LR
es un supraconjunto de la clase de gramticas que se puedan analizar
con analizadores sintcticos predictivos.
Un analizador sintctico predictivo LR puede detectar un error
sintctico tan pronto como sea posible hacerlo en un examen de
izquierda a derecha de la entrada.

73

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

El principal inconveniente del mtodo es que supone demasiado


trabajo construir un analizador sintctico LR a mano para una gramtica
de un lenguaje de programacin tpico. Se necesita una herramienta
especializada: un generador de analizadores sintcticos LR, por ejemplo
YACC. Con este generador se puede escribir una gramtica libre de
contexto y el generador produce automticamente un analizador
sintctico para dicha gramtica .

Modelo de un analizador sintctico LR.


En la Fig se muestra de forma esquemtica de un analizador
sintctico LR. Consta de una entrada, una salida, una pila, un programa
conductor y una tabla de anlisis sintctico de dos partes (accin, ir_a).
El programa conductor es el mismo para todos los analizadores
sintcticos LR; solo cambian las tablas de un analizador a otro. La tabla
de anlisis sintctico consta de dos partes, la funcin accin que indica
una accin del analizador, y la funcin ir_a, que indica las transiciones
entre los estados.
Realizacin
Gramtica
EE+T

74

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

ET
TT*F
TF
F(E)
F id
Algoritmo
inicializar la pila al estado cero
agregar $ al final de la entrada
apuntar al primer smbolo de la entrada
repetir begin
sea s el estado de la cima de la pila y
a el smbolo de entrada actual
if accin [s,a] = desplazar # then
begin
meter a y despus # (el nuevo estado) en la pila
avanzar al siguiente smbolo de entrada
end
else if accin [s,a] = reducir A then
begin
sacar 2*| | smbolos de la pila
sea S el estado que ahora esta en la cima de la pila
meter a y despus ir_a[s,a] en la pila.
end
else if accin[s,a] = aceptar then
Return
else error()
end.
Matriz de precedencia resultante

75

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Anlisis
Inicializa la pila al estado cero, agregar el smbolo $ al final de la
cadena de entrada, paso 1:
id*(id+id)

Pila

Entrada

(1) 0

id*(id+id)
$

Acci
S a
n
0 id

Como [S,a] = [0,id], tenemos a S5 que es = desplazar, entonces


se mete a (id) y despus a # (5) (el nuevo estado) en la pila, avanzar al
Estado
0
1
2
3
4
5
6
7

id
d5

Accin
(
)
d4

d6
r2 d7
r4 r4
d5

r2
r4

Aceptar
r2
r4

r6

r6

d4
r6

8 2 3

r6

d5

d4

d5

d4

ir_a
E T F
1 2 3

9 3
1
0

8
d6
9
r1 d7
10
r3 r3
11
r5 r5
siguiente smbolo, paso 2:

d11
r1
r3
r5

r1
r3
r5

Verificando en la tabla tenemos (R6), como [S,a] = [5,*] = reducir


A , = 1 tenemos que sacar 2*||, ahora el tope de la pila es 0 y F el
lado izquierdo de la produccin 6, meter A que es F y el 3 obtenido en la
interseccin 0,F, paso 3:
Verificando en la tabla tenemos (R4), como [S,a] = [3,*] = reducir
A , = 1 tenemos que sacar 2*||, ahora el tope de la pila es 0 y T el

76

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

lado izquierdo de la produccin 4, meter A que es T y el 2 obtenido en la


interseccin 0,T, paso 4:
Verificando en la tabla tenemos (S7), como [S,a] = [2,*] =
desplazar, entonces se mete a(*) y despus a # (7) (el nuevo estado) en
la pila, avanzar al siguiente smbolo, paso 5:
Verificando en la tabla tenemos (S4), como [S,a] = [7,(] =
desplazar, entonces se mete a(() y despus a # (4) (el nuevo estado)
en la pila, avanzar al siguiente smbolo, paso 6:
Verificando en la tabla tenemos (S5), como [S,a] = [4,id] =
desplazar, entonces se mete a(id) y despus a # (5) (el nuevo estado)
en la pila, avanzar al siguiente smbolo, paso 7:
Verificando en la tabla tenemos (R6), como [S,a] = [5,+] = reducir
A , = 1 tenemos que sacar 2*||, ahora el tope de la pila es 4 y F el
lado izquierdo de la produccin 6, meter A que es F y el 3 obtenido en la
interseccin 4,F, paso 8:
Verificando en la tabla tenemos (R4), como [S,a] = [3,+] = reducir
A , = 1 tenemos que sacar 2*||, ahora el tope de la pila es 4 y T el
lado izquierdo de la produccin 4, meter A que es T y el 2 obtenido en la
interseccin 4,T, paso 9:
Verificando en la tabla tenemos (R2), como [S,a] = [2,+] = reducir
A , = 1 tenemos que sacar 2*||, ahora el tope de la pila es 4 y E el
lado izquierdo de la produccin 2, meter A que es E y el 8 obtenido en la
interseccin 4,E, paso 10:
Verificando en la tabla tenemos (S6), como [S,a] = [8,+] =
desplazar, entonces se mete a(+) y despus a # (6) (el nuevo estado)
en la pila, avanzar al siguiente smbolo, paso 11:
Verificando en la tabla tenemos (S5), como [S,a] = [6,id] =
desplazar, entonces se mete a(id) y despus a # (5) (el nuevo estado)
en la pila, avanzar al siguiente smbolo, paso 12:
Verificando en la tabla tenemos (R6), como [S,a] = [5,)] = reducir
A , = 1 tenemos que sacar 2*||, ahora el tope de la pila es 6 y F el

77

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

lado izquierdo de la produccin 6, meter A que es F y el 3 obtenido en la


interseccin 6,F, paso 13:
Verificando en la tabla tenemos (R4), como [S,a] = [3,)] = reducir
A , = 1 tenemos que sacar 2*||, ahora el tope de la pila es 6 y T el
lado izquierdo de la produccin 4, meter A que es T y el 9 obtenido en la
interseccin 6,T, paso 14:
Verificando en la tabla tenemos (R1), como [S,a] = [9,)] = reducir
A , = 3 tenemos que sacar 2*||, ahora el tope de la pila es 4 y E el
lado izquierdo de la produccin 1, meter A que es E y el 8 obtenido en la
interseccin 4,E, paso 15:
Verificando en la tabla tenemos (S11), como [S,a] = [8,)] =
desplazar, entonces se mete a()) y despus a # (11) (el nuevo estado)
en la pila, avanzar al siguiente smbolo, paso 16:
Verificando en la tabla tenemos (R5), como [S,a] = [11,$] =
reducir A , = 3 tenemos que sacar 2*||, ahora el tope de la pila es
7 y F el lado izquierdo de la produccin 5, meter A que es F y el 10
obtenido en la interseccin 7,F, paso 17:
Verificando en la tabla tenemos (R3), como [S,a] = [10,$] =
reducir A , = 3 tenemos que sacar 2*||, ahora el tope de la pila es
0 y T el lado izquierdo de la produccin 3, meter A que es T y el 2
obtenido en la interseccin 0,T, paso 18:
Verificando en la tabla tenemos (R2), como [S,a] = [2,$] = reducir
A , = 1 tenemos que sacar 2*||, ahora el tope de la pila es 0 y E el
lado izquierdo de la produccin 2, meter A que es E y el 1 obtenido en la
interseccin 0,E, paso 19:
Pila

Entrada

Accin

(1) 0

id*(id+id)$

S5

id

(2) 0 id 5

*(id+id)$

R6

(3) 0 F 3

*(id+id)$

R4

(4) 0 T 2

*(id+id)$

S7

(5) 0 T 2 * 7

(id+id)$

S4

78

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

(6) 0 T 2 * 7 ( 4

id+id)$

S5

id

(7) 0 T 2 * 7 ( 4 id 5

+id)$

R6

(8) 0 T 2 * 7 ( 4 F 3

+id)$

R4

(9) 0 T 2 * 7 ( 4 T 2

+id)$

R2

(10) 0 T 2 * 7 ( 4 E 8

+id)$

S6

(11) 0 T 2 * 7 ( 4 E 8 + 6

)$

S5

id

(12) 0 T 2 * 7 ( 4 E 8 + 6 id
)$
5

R6

(13) 0 T 2 * 7 ( 4 E 8 + 6 F
)$
3

R4

(14) 0 T 2 * 7 ( 4 E 8 + 6 T
)$
9

R1

(15) 0 T 2 * 7 ( 4 E 8

)$

S11

(16) 0 T 2 * 7 ( 4 E 8 ) 11

R5

11

(17) 0 T 2 * 7 F 10

R3

10

(18) 0 T 2

R2

(19) 0 E 1

Verificando en la tabla tenemos (Aceptar), por lo tanto la cadena


ha sido completamente aceptada
Matrices de Transicin.
Una matriz de transicin es una matriz o tabla M, cuyos renglones
representan las "cabezas" (cadenas de smbolos, las cuales terminan en
un smbolo terminal) de los lados derechos de las reglas de las
gramticas, las cuales pueden aparecer en la pila, y cuyas columnas
representan los smbolos terminales, incluyendo el delimitador $. Los
elementos de la matriz sern nmeros o direcciones de subrutinas.
La Tabla muestra la estructura de una matriz de transicin para la
siguiente gramtica (parcialmente llena).
Gramtica:
<prog>
<estado>
<estado>

::= <estado>
::= IF <expr> THEN <estado>
::= <var> := <expr>

79

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

<expr>
<var>

::= <expr> + <var> | <var>


::= id
$

IF

THEN

: + id
=
1

$
1
IF
IF <expr>
THEN
<var> :=
<expr> +
id
Tabla parcialmente llena para la gramatica dada.
El analizador sintctico utiliza la tpica pila S y la variable para el
smbolo entrante R. Aunque la estructura de la pila tiene una pequea
diferencia; en lugar de slo smbolos, se permitir que cadenas de
smbolos aparezcan en la pila. Las cadenas que aparezcan aqu sern
cabezas (las cuales terminan en un smbolo terminal) de las partes
derechas de las reglas. Por ejemplo, si la pila convencional en algn
momento contiene:
$ IF <expr> THEN IF <expr> THEN <var>:=
La pila podra verse como:
<var>:=
IF <expr> THEN
IF <expr> THEN
$
Note que todo lo que se hace es mantener juntos todos esos
smbolos; los cuales sabemos, debern ser reducidos al mismo tiempo.
Tambin se utilizar una variable U, sta estar vaca o contendr el
smbolo el cual la ltima frase ha sido reducida. As, si la cadena parcial
analizada hasta el momento es:
$ IF <expr> THEN IF <expr> THEN <var>:= <expr>
Entonces la pila se vera como arriba y <expr> estara en U.

80

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

El analizador sintctico usa la matriz como sigue. En cada paso el


elemento en la cima de la pila corresponde a algn rengln de la matriz,
debido a que ambas representan la cabeza (terminando en un smbolo
terminal) de alguna parte derecha. El smbolo terminal entrante
determina una columna de la matriz. Estas dos juntas determinan un
elemento de la matriz el cual es el nmero de subrutina a ejecutar. Esta
subrutina ejecuta la reduccin necesaria o mete en la pila a R y obtiene
el siguiente smbolo de entrada.
Realizacin del Anlisis de Matriz de Transicin.
Para llevar a cabo el anlisis sintctico y al mismo tiempo construir
la matriz, se har uso de una pila S que en cuestin a su estructura es
algo diferente a las ya conocidas, ya que en estas podemos almacenar
no nicamente smbolos sino tambin cadenas de smbolos, stas
cadenas sern las cabezas que definimos como renglones de la matriz y
tambin se hace uso de una variable (R) que especificar el smbolo o
los smbolos que puedan entrar a la pila.
Ejemplo: Podemos tener en X momento esta expresin dentro de
la pila:
$ IF <expr> THEN IF <expr> THEN <var>:=
La pila podra verse como:
<var>:=
IF <expr> THEN
IF <expr> THEN
$
Tambin se hace uso de una variable U, la cual estar vaca o
contendr el smbolo de la ltima frase reducida.
En cada paso el elemento que se encuentre en la cima de la pila
corresponder a algn rengln de la matriz, el smbolo terminal R
determinar la columna de la matriz y los elementos pertenecientes a la
matriz sern los nmeros de subrutinas a ejecutar, las subrutinas
tendrn la tarea de meter a R en la pila o de llevar a cabo una reduccin.
Ejemplo:

81

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Cuando iniciamos el anlisis $ esta en la pila y la variable U est


vaca, de acuerdo a la gramtica que usamos en este ejemplo, el
smbolo entrante debe ser IF e id debido a que estas inician partes
derechas, por lo que colocaremos el nmero 1 (que corresponde a la
primera subrutina) en el rengln $ que es el elemento en la cima de la
pila y en las columnas IF e id, despus realizaremos la subrutina.
U=
R=

$
$
$
IF
IF <expr>
THEN
<var> :=
<expr> +
id

IF

THEN

: + id
=
1

Subrutina 1: IF U <> " " then ERROR;


i := i + 1 ;
S(i) = R ;
SIGCOMPLEX.
La funcin SIGCOMPLEX coloca el siguiente smbolo de la cadena
de entrada en R.
id
IF
$

U=
R=

Ahora haremos un recorrido en la matriz para ver o indicar en que


otras posiciones en la matriz se puede realizar la subrutina 1, para esto
se debe de analizar que posible smbolo terminal de la columna podra
seguirle al elemento terminal del rengln.
En el rengln IF basndonos en la regla 2, <expr> le sigue al
smbolo IF y como vemos en la regla 4 <expr>:= <var> y en la regla 5

82

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

<var>:= id ; por lo tanto id puede ser un smbolo que le siga a IF por lo


tanto colocamos en nmero 1 en la fila IF columna id.
En el rengln IF <expr> THEN, basndonos en la regla 2,
<estado> le sigue al smbolo THEN y como vemos en la misma regla 2
<estado>:= IF <expr> THEN <estado>; por lo tanto IF puede ser un
smbolo que le sigue a THEN y colocamos tambin el nmero 1 de la
subrutina en la fila IF <expr> THEN columna IF; tambin vemos en la
regla 3 que <estado>:= <var>:= <expr> y en la regla 5 <var>:= id por
lo tanto tambin id puede ser un smbolo que le siga a THEN y tambin
colocamos el nmero 1 en la misma fila pero en la columna id.
Valindose de estas reglas la matriz al terminar este paso queda:
$
$
IF
IF <expr>
THEN
<var> :=
<expr> +
id

IF

THEN

1
1

: + id
=
1
1
1
1
1

como vemos ahora en la cima de la pila se encuentra el smbolo id,


por lo que iremos al rengln id de la matriz y analizaremos que smbolo
(de las columnas) puede ser vlido en R, es decir, que smbolo podra
seguirle a id y vemos que los smbolos $, THEN, := + son vlidos, esto
es porque se puede tener una expresin como la siguiente:
IF id THEN id:= id + id $
por lo tanto la matriz queda:
$
$
IF
IF <expr>
THEN
<var> :=
<expr> +
id

IF

THEN

1
1

83

: + id
=
1
1
1
1
1
2 2 2

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Subrutina 2: IF U <> " " then ERROR;


i: = i - 1;
U = '<var>'.
Aqu se hace una reduccin y la pila queda:
U = ' <var> '
R=

IF
$

Ahora en la cima de la pila se encuentra el smbolo IF por lo que


iremos al rengln IF de la matriz y analizaremos que smbolo (de las
columnas) puede ser vlido en R, es decir que smbolo podra seguir a IF
pero tomando e cuenta que tenemos a <var> en U. Vemos que en el
rengln IF la nica que satisface tal condicin es el smbolo + , as como
tambin en el rengln <var>:=.
Por lo tanto la matriz quedar:
$ IF THEN : + id
=
$
1
1
IF
3 1
IF <expr>
1
1
THEN
<var> :=
3 1
<expr> +
1
id
2
2
2 2 2
Subrutina 3: IF U <> '<expr>' and U <> '<var>'then ERROR;
i := i + 1 ;
S(i) = '<expr>'+
SIGCOMPLEX.
'<expr>+'
U = ' <var> '
IF
R=
$
Ahora nos posicionamos en la fila <expr>+ de la matriz y
analizaremos que smbolo (de las columnas) puede ser vlido en R, es
decir que smbolo podra seguir a <expr>+ tomando en cuenta tambin
a <var> que esta en U y vemos que los smbolos $, THEN + son
vlidos, porque se puede tener una expresin como la siguiente:

84

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

IF <expr>+<var> THEN <var>:= <expr>+<var>+<var> $


<expr>

+<var>

Por lo tanto la matriz quedar:


$

IF

THEN

$
1
IF
IF <expr>
1
THEN
<var> :=
<expr> +
4
4
id
2
2
Subrutina 4: IF U <> "<var>" then ERROR;
i := i - 1 ;
U = '<expr>'

: + id
=
1
3 1
1
3 1
4 1
2 2 2

U = ' <var> ' :=


'<expr>+'
'<expr>'
IF
R=
$
Se hizo aqu otra reduccin.
Se siguen los mismos procedimientos, aunque cabe aclarar que en
la subrutina 5, se hace una parada.
Subrutina 5: IF U <> '<prog>' and U <> '<estado>' then ERROR;
STOP
de tal forma que as quedara la tabla:
$ IF THEN : + id
=
$
5 1
1
IF
3 1
IF <expr>
1
1
THEN
<var> :=
3 1
<expr> +
4
4
4 1
id
2
2
2 2 2
La matriz completa y las subrutinas para la gramtica de ejemplo
se muestran a continuacin:
$

IF

85

THEN

: + id

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

$
IF
IF <expr>
THEN
<var> :=
<expr> +
id

5
0
7

1
0
1

0
9
0

=
6 0 1
0 3 1
6 0 1

8
4
2

0
0
0

0
4
2

0 3 1
0 4 1
2 2 0

6:

if U <> '<var> then ERROR;


U := '';
i := i + 1;
S (i) = '<var> :=',
SIGCOMPLEX.

7:

if U<> '<estado>' then ERROR;


i := i - 1;
U :='<estado>'.

8:

9:

0:

if U <> '<var>' and


U <> '<expr>' then ERROR;
i := i - 1;
U:= '<estado>';
if U <> '<var>' and
U <> '<expr>' then ERROR;
S (i) := 'IF <expr> THEN';
U := '';
SIGCOMPLEX.
ERROR;
STOP.

86

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

EJEMPLO DE ANLISIS LXICO DEL LENGUAJE DTONE


Este es el cdigo en Java del Analizador Lxico.
Options { LOOKAHEAD = 3;
IGNORE_CASE = true;
STATIC = false;
}
PARSER_BEGIN(dtone3)
import java.io.*;
import java.lang.*;
import java.util.*;
import javax.swing.*;
public class dtone3{
public FileOutputStream Sint1;
public DataOutputStream Sint2;
public FileOutputStream Token1;
public DataOutputStream Token2;
public String ar[]=new String[1024];
public void archSint_crear(String nombre_arch)
{
try {
Sint1 = new FileOutputStream(nombre_arch);
Sint2 = new DataOutputStream(Sint1);
}
catch (IOException Ex)
{
System.err.println("No se creo el archivo correctamente");
}
}
public void archSint_cerrar()
{
try {
Sint1.close();
}
catch (IOException Ex)
{
System.err.println("No se cerro corectamente");
}
}
public void archSint_escribe(String Mensaje)
{
try {
Sint2.writeBytes(Mensaje+"\r");
Sint1.write('\n');
}
catch(IOException Ex)
{
System.err.println("No se escribio correctamente");
}

87

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

}
public void archtoken_crear(String nombre_arch)
{
try {
Token1 = new FileOutputStream(nombre_arch);
Token2 = new DataOutputStream(Token1);
}
catch (IOException Ex)
{
System.err.println("No se creo el archivo correctamente");
}
}
public void archtoken_cerrar()
{
try {
Token1.close();
}
catch (IOException Ex)
{
System.err.println("No se cerro corectamente");
}
}
public void archtoken_escribe(String Mensaje)
{
try {
Token2.writeBytes(Mensaje+"\r");
Token1.write('\n');
}
catch(IOException Ex)
{
System.err.println("No se escribio correctamente");
}
}
public static void main(String args[]) throws ParseException
{
dtone3 analiza;
if(args.length == 0)
{
System.err.println("Uso del programa: \"java dtone3 archivo.ejm\"");
}
else
{
if(args.length == 1)
{
try
{
analiza = new dtone3 (new java.io.FileInputStream(args[0]));
analiza.archSint_crear("Sint.txt");
analiza.dtone();
analiza.archSint_cerrar();
}
catch (java.io.FileNotFoundException e)

88

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

{
System.out.println("No se pudo leer el archivo : " + args[0] + " ");
}
try
{
analiza = new dtone3 (new java.io.FileInputStream(args[0]));
analiza.archtoken_crear("Lex.txt");
analiza.input(analiza);
}
catch (java.io.FileNotFoundException e)
{
System.out.println("No se pudo leer el archivo : " + args[0] + " ");
}
}
else
{
System.out.println("Formato: java dtone3 nombrearchivo.ejm");
}
}
}
void EscribeSintactico(String mensaje)
{
archSint_escribe(mensaje);
}
}
PARSER_END(dtone3)
SKIP :
{
""
| "\t"
| "\n"
| "\r"
| "\f"
}
TOKEN : {
<paccess: ("a")("c")("c")("e")("s")("s")>
|
<pbool: ("b")("o")("o")("l")>
|
<pbreak: ("b")("r")("e")("a")("k")>
|
<pbyte: ("b")("y")("t")("e")>
|
<pcase: ("c")("a")("s")("e")>
|
<pclass: ("c")("l")("a")("s")("s")>
|
<pcontinue: ("c")("o")("n")("t")("i")("n")("u")("e")>
|
<pdefault: ("d")("e")("f")("a")("u")("l")("t")>
|
<pdelete: ("d")("e")("l")("e")("t")("e")>
|
<pdo: ("d")("o")>
|
<pelse: ("e")("l")("s")("e")>
|
<pexport: ("e")("x")("p")("o")("r")("t")>
|
<pfalse: ("f")("a")("l")("s")("e")>
|
<pfor: ("f")("o")("r")>
|
<pif: ("i")("f")>
|
<pint8: ("i")("n")("t")("8")>

89

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

|
|
|
|
|
|
|
|
|
|
|
|
|
|

<pint16: ("i")("n")("t")("1")("6")>
<pint32: ("i")("n")("t")("3")("2")>
<pmodule: ("m")("o")("d")("u")("l")("e")>
<pnew: ("n")("e")("w")>
<pprivate: ("p")("r")("i")("v")("a")("t")("e")>
<preturn: ("r")("e")("t")("u")("r")("n")>
<pswitch: ("s")("w")("i")("t")("c")("h")>
<ptoken: ("t")("o")("k")("e")("n")>
<ptrue: ("t")("r")("u")("e")>
<puint8: ("u")("i")("n")("t")("8")>
<puint16: ("u")("i")("n")("t")("1")("6")>
<puint32: ("u")("i")("n")("t")("3")("2")>
<puses: ("u")("s")("e")("s")>
<pwhile: ("w")("h")("i")("l")("e")>

}
TOKEN :
{
<parenizq: "(">
| <parender: ")">
| <llaveizq: "{">
| <llaveder: "}">
| <corizq: "[">
| <corder: "]">
| <puncoma: ";">
| <dospuntos: ":">
| <coma: ",">
| <punto: ".">
| <comillas: "\"">
}
TOKEN :
{
<asigna: "=">
| <mayor: ">">
| <menor: "<">
| <menigual: "<=">
| <mayigual: ">=">
| <suma: "+">
| <resta: "-">
| <div: "/">
| <cambioizq: "<<">
| <cambioder: ">>">
| <producto: "*">
| <residuo: "%">
| <inc: "++">
| <dec: "--">
| <nobin: "~">
| <nolog: "!">
| <igual: "==">
| <dif: "!=">
| <ybin: "&">
| <obin: "|">
| <xor: "~|">
| <ylog: "&&">

90

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

| <olog: "||">
| <sumasigna: "+=">
| <restasigna: "-=">
| <prodasigna: "*=">
| <divasigna: "/=">
| <resasigna: "%=">
| <yasigna: "&=">
| <oasigna: "|=">
| <xorasigna: "~|=">
| <camizqasig: "<<=">
| <camderasig: ">>=">
}
TOKEN :
{
<dig: ["0"-"9"] >
| <letra: ["a" - "z","A" - "Z"] >
| <entero: (<dig>)+ >
| <real: ("-")? <entero> (".") <entero> >
| <ident: <letra> (<letra> | <dig> | "_")* >
| <cadena: <comillas> (~[ "'" ])* <comillas> >
| <c_noval: ("" |"^" | "" | "" | "" | "@" | "$") >
| <cad_noval:(<letra> | <dig> | "_")* (<c_noval>)+ (<letra> | <dig> | "_" | <c_noval>)* >
}
void input(dtone3 analiza) :
{
String mensaje;
}
{
(

)+

mensaje=Checa()
{
System.out.println(mensaje);
analiza.archtoken_escribe(mensaje);
}
<EOF>

}
String Checa() :
{ Token t; }
{
t=<paccess>
{ return ( t.image +"\t\t Palabra reservada access"); }
| t=<pbool>
{ return ( t.image +"\t\t Palabra reservada bool");}
| t=<pbreak>
{ return ( t.image +"\t\t Palabra reservada break");}
| t=<pbyte>

91

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

{ return ( t.image +"\t\t Palabra reservada byte");}


| t=<pcase>
{ return ( t.image +"\t\t Palabra reservada case");}
| t=<pclass>
{ return ( t.image +"\t\t Palabra reservada class");}
| t=<pcontinue>
{ return ( t.image +"\t\t Palabra reservada continue");}
| t=<pdefault>
{ return ( t.image +"\t\t Palabra reservada default");}
| t=<pdelete>
{ return ( t.image +"\t\t Palabra reservada delete");}
| t=<pdo>
{ return ( t.image +"\t\t Palabra reservada do");}
| t=<pelse>
{ return ( t.image +"\t\t Palabra reservada else");}
| t=<pexport>
{ return ( t.image +"\t\t Palabra reservada export");}
| t=<pfalse>
{ return ( t.image +"\t\t Palabra reservada false");}
| t=<pfor>
{ return ( t.image +"\t\t Palabra reservada for");}
| t=<pif>
{ return ( t.image +"\t\t Palabra reservada if");}
| t=<pint8>
{ return ( t.image +"\t\t Palabra reservada int8");}
| t=<pint16>
{ return ( t.image +"\t\t Palabra reservada int16");}
| t=<pint32>
{ return ( t.image +"\t\t Palabra reservada int32");}
| t=<pmodule>
{ return ( t.image +"\t\t Palabra reservada module");}
| t=<pnew>
{ return ( t.image +"\t\t Palabra reservada new");}
| t=<pprivate>
{ return ( t.image +"\t\t Palabra reservada private");}
| t=<preturn>
{ return ( t.image +"\t\t Palabra reservada return");}

92

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

| t=<pswitch>
{ return ( t.image +"\t\t Palabra reservada switch");}
| t=<ptoken>
{ return ( t.image +"\t\t Palabra reservada token");}
| t=<ptrue>
{ return ( t.image +"\t\t Palabra reservada true");}
| t=<puint8>
{ return ( t.image +"\t\t Palabra reservada uint8");}
| t=<puint16>
{ return ( t.image +"\t\t Palabra reservada uint16");}
| t=<puint32>
{ return ( t.image +"\t\t Palabra reservada uint32");}
| t=<puses>
{ return ( t.image +"\t\t Palabra reservada uses");}
| t=<pwhile>
{ return ( t.image +"\t\t Palabra reservada while");}
| t=<puncoma>
{ return ( t.image +"\t\t Simbolo ;");}
| t=<dospuntos>
{ return ( t.image +"\t\t Simbolo :");}
| t=<coma>
{ return ( t.image +"\t\t Simbolo ,");}
| t=<punto>
{ return ( t.image +"\t\t Simbolo .");}
| t=<parenizq>
{ return ( t.image +"\t\t Operador (");}
| t=<parender>
{ return ( t.image +"\t\t Operador )");}
| t=<corizq>
{ return ( t.image +"\t\t Operador [");}
| t=<corder>
{ return ( t.image +"\t\t Operador ]");}
| t=<llaveizq>
{ return ( t.image +"\t\t Operador {");}
| t=<llaveder>
{ return ( t.image +"\t\t Operador }");}
| t=<asigna>
{ return ( t.image +"\t\t Operador = ");}

93

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

| t=<mayor>
{ return ( t.image +"\t\t Operador > ");}
| t=<menor>
{ return ( t.image +"\t\t Operador < ");}
| t=<menigual>
{ return ( t.image +"\t\t Operador <= ");}
| t=<mayigual>
{ return ( t.image +"\t\t Operador >= ");}
| t=<suma>
{ return ( t.image +"\t\t Operador + ");}
| t=<resta>
{ return ( t.image +"\t\t Operador - ");}
| t=<div>
{ return ( t.image +"\t\t Operador / ");}
| t=<producto>
{ return ( t.image +"\t\t Operador * ");}
| t=<residuo>
{ return ( t.image +"\t\t Operador % ");}
| t=<cambioizq>
{ return ( t.image +"\t\t Operador << ");}
| t=<cambioder>
{ return ( t.image +"\t\t Operador >> ");}
| t=<inc>
{ return ( t.image +"\t\t Operador ++ ");}
| t=<dec>
{ return ( t.image +"\t\t Operador -- ");}
| t=<nobin>
{ return ( t.image +"\t\t Operador ~ ");}
| t=<nolog>
{ return ( t.image +"\t\t Operador ! ");}
| t=<igual>
{ return ( t.image +"\t\t Operador == ");}
| t=<dif>
{ return ( t.image +"\t\t Operador != ");}
| t=<ybin>
{ return ( t.image +"\t\t Operador binario & ");}
| t=<obin>

94

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

{ return ( t.image +"\t\t Operador binario | ");}


| t=<xor>
{ return ( t.image +"\t\t Operador binario ~| ");}
| t=<ylog>
{ return ( t.image +"\t\t Operador logico && ");}
| t=<olog>
{ return ( t.image +"\t\t Operador logico || ");}
| t=<sumasigna>
{ return ( t.image +"\t\t Operador asignacion += ");}
| t=<restasigna>
{ return ( t.image +"\t\t Operador asignacion -= ");}
| t=<prodasigna>
{ return ( t.image +"\t\t Operador asignacion *= ");}
| t=<divasigna>
{ return ( t.image +"\t\t Operador asignacion /= ");}
| t=<resasigna>
{ return ( t.image +"\t\t Operador asignacion %= ");}
| t=<yasigna>
{ return ( t.image +"\t\t Operador asignacion &= ");}
| t=<oasigna>
{ return ( t.image +"\t\t Operador asignacion |= ");}
| t=<xorasigna>
{ return ( t.image +"\t\t Operador asignacion ~|= ");}
| t=<camizqasig>
{ return ( t.image +"\t\t Operador asignacion <<= ");}
| t=<camderasig>
{ return ( t.image +"\t\t Operador asignacion >>= ");}
| t=<dig>
{ return ( t.image +"\t\t Digito ");}
| t=<ident>
{ return ( t.image +"\t\t Identificador ");}
| t=<letra>
{ return ( t.image +"\t\t Letra ");}
| t=<entero>
{ return ( t.image +"\t\t Numero Entero ");}
| t=<real>
{ return ( t.image +"\t\t Numero real ");}

95

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

| t=<c_noval>
{ return ( t.image +"\t\t Caracter no valido ");}
| t=<cad_noval>
{ return ( t.image +"\t\t Cadena no valida ");}
}
EJEMPLO DE ANALISIS SINTCTICO DEL LENGUAJE DTONE
Este es el cdigo en Java del Analizador Sintctico. Se describen las gramticas y se da
una breve descripcin de cada una de ellas.
Esta gramtica corresponde a la estructura general de todo el programa.
void dtone() : {}
{
try{
CABECERA() CUERPO()
}
catch(ParseException e)
{System.out.println("Error en el programa");
}
}
Esta es la gramtica que corresponde a la cabecera del programa. ste tiene que ser el primer comando
en todos los archivos. Identifica el archivo como cdigo del dtone.
void CABECERA() : {}
{try
{VERSION() LIBRERIAS()
}
catch(ParseException e) {
System.out.println("Error en la cabecera");
}
}
Esta es la gramtica que corresponde a la versin que va en la cabecera. La versin es muy til para
identificar la versin del compilador que este cdigo necesita.
void VERSION() : {}
{try
{<pdtone> <dig> <punto> <dig> <punto> <dig>
}
catch(ParseException e) {
System.out.println("Error en la version");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}

96

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Esta es la gramtica que corresponde a las libreras, lo que se hace es que se listan las libreras que van a
ser llamadas para la ejecucin del programa.
void LIBRERIAS() : {}
{try
{(<puses> <comillas> <ident>("/" <ident>)* "/*" <comillas> <puncoma>)+
}
catch(ParseException e) {
System.out.println("Error en las librerias");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta es la gramtica en la cual se define el cuerpo del programa, en el se van a listar las instrucciones para
del programa.
void CUERPO() : {}
{try
{<pmodule> <ident> <llaveizq> DECLARA() (INSTRUC())+ <llaveder>
}
catch(ParseException e) {
System.out.println("Error en el cuerpo");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta es la gramtica para las declaraciones de variables que se van a utilizar en el programa.
void DECLARA() : {}
{try
{(D_VAR() | D_ARR() | D_CONST() | D_FUNCION() )*
}
catch(ParseException e) {
System.out.println("Error en las declaraciones");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta es la gramtica de la declaracin de variables.
void D_VAR() : {}
{try
{(DEC_VAR() | DECINI_VAR()) <puncoma>
}
catch(ParseException e) {

97

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

System.out.println("Error en las declaracion de variable");


Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta es la gramtica de la declaracin de variables.
void DEC_VAR() : {}
{try
{TIPO() <ident>
}
catch(ParseException e) {
System.out.println("Error en las declaracion de variable");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica corrsponde al tipo de datos con el cual se va a declarar la variable.
void TIPO() : {}
{
(<pint8> | <pint16> | <pint32> | <puint8> | <puint16> | <puint32> | <pbool> | <pbyte>)
}
Esta gramtica corresponde a la declaracin e inicializacin de variables.
void DECINI_VAR() : {}
{try
{DEC_VAR() <igual> (<entero> | <real> | <cadena>) <puncoma>
}
catch(ParseException e) {
System.out.println("Error en las declaracion de variable");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica corresponde a la declaracin de un arreglo.
void D_ARR() : {}
{try
{TIPO() <ident> <corizq> (<entero>)* <corder> <puncoma>
}
catch(ParseException e) {
System.out.println("Error en las declaracion de arreglo");

98

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica corresponde a la declaracin de una constante.
void D_CONST() : {}
{try
{<pdefine> <ident> <igual> (<entero>|<real>|<cadena>) <puncoma>
}
catch(ParseException e) {
System.out.println("Error en las declaracion de constante");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica corresponde a la declaracin de una funcin.
void D_FUNCION() : {}
{try
{TIPO() <ident> <parenizq> PARAM() <parender> <llaveizq> DECLARA() (INSTRUC())+ < llaveder >
}
catch(ParseException e) {
System.out.println("Error en la declaracion de la funcion");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica corresponde a la declaracin de parmetros del programa.
void PARAM() : {}
{try
{(DEC_VAR() | D_ARR()) (<coma> (DEC_VAR() | D_ARR() ) )*
}
catch(ParseException e) {
System.out.println("Error en los parametros");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}

99

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Esta gramtica define las instrucciones que sern dadas para que el programa finalmente cumpla con las
ordenes que se le estn dando a travs de dichas instrucciones.
void INSTRUC() : {}
{try
{(ASIGNACION() | CICLO() | LLAM_FUNCION())
}
catch(ParseException e) {
System.out.println("Error en la instruccion");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta es la gramtica que define las asignaciones que podemos hacer en el lenguaje de programacin Dtone.
void ASIGNACION() : {}
{try
{IZQ() <asigna> DER() <puncoma>
}
catch(ParseException e) {
System.out.println("Error en la asignacion");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta es la gramtica que define la parte izquierda de las asignaciones que podemos hacer en el lenguaje de
programacin Dtone.
void IZQ() : {}
{try
{(<ident> | ARREGLO())
}
catch(ParseException e) {
System.out.println("Error en la parte izquierda de la asginacion");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica define al arreglo que puede ir en la parte izquierda de la asignacin, es decir al arreglo se le
va a asignar un valor.
void ARREGLO() : {}
{try
{<ident> <corizq> (<ident>|<entero>) (<coma> (<ident>|<entero>))* <corder>

100

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

}
catch(ParseException e) {
System.out.println("Error en el arreglo");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta es la gramtica que define la parte derecha de las asignaciones que podemos hacer en el lenguaje de
programacin Dtone.
void DER() : {}
{try
{(IZQ() | <cadena> | OPER_ARIT() | <entero> | <real>)
}
catch(ParseException e) {
System.out.println("Error en la parte derecha de la asignacion");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica corresponde a los operadores aritmticos que pueden ir en la parte derecha de una
asignacin.
void OPER_ARIT() : {}
{try
{(<ident> | <entero> | <real> | ARREGLO()) ARITOP() (<ident> | <entero> | <real> | ARREGLO())
}
catch(ParseException e) {
System.out.println("Error en la operacion");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica define el simbolo del operador aritmtico.
void ARITOP() : {}
{
(<suma> | <resta> | <div> | <producto> | <residuo>)
}
Esta gramtica define los ciclos que puede contener el cuerpo del programa en el lenguaje Dtone.
void CICLO() : {}

101

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

{
(GIF() | GWHILE() | GDO() | GFOR() | GCASE())
}

Esta es la gramtica del IF. Se evala la condicin, si produce una verdad, la verdadera trayectoria se
ejecuta, si no la falsa trayectoria (opcional) se ejecuta.
void GIF() : {}
{try
{<pif> <parenizq> OPER_REL() <parender> (INSTRUC())+
}
catch(ParseException e) {
System.out.println("Error en el IF");
}
}
Esta es la gramtica de los operadores relacionales que pueden ir dentro de alguna instruccin de control de
flujo.
void OPER_REL() : {}
{try
{(<ident> | <entero> | <real> | ARREGLO()) RELOP() (<ident> | <entero> | <real> | ARREGLO())
}
catch(ParseException e) {
System.out.println("Error en la operacion");
}
}
Esta es la gramtica de los smbolos de los operadores relacionales que pueden ir dentro de alguna
instruccin de control de flujo.
void RELOP() : {}
{
(<mayor> | <menor> | <menigual> | <mayigual> | <igual>)
}
Esta es la gramtica del ciclo WHILE. En este ciclo se ejecuta el cuerpo si la condicin es verdadera, en caso
contrario no.
void GWHILE() : {}
{try
{<pwhile> <parenizq> OPER_REL() <parender> <llaveizq> (INSTRUC())+ <llaveder>
}
catch(ParseException e) {
System.out.println("Error en el WHILE");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}

102

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

Esta es la gramtica del ciclo DO. En este ciclo, el cuerpo es ejecutado mientras que la condicin sea cierta.
El cuerpo del ciclo se ejecuta por lo menos una vez.
void GDO() : {}
{try
{<pdo> <llaveizq> (INSTRUC())+ <llaveder> <pwhile> <parenizq> OPER_REL() <parender> <puncoma>
}
catch(ParseException e) {
System.out.println("Error en el DO");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta es la gramtica del ciclo FOR. El cual tiene una estructura muy parecida a la de C.
void GFOR() : {}
{try
{<pfor> <parenizq> (DECINI_VAR() | ASIGNACION()) <puncoma> OPER_REL() <puncoma>
ASIGNACION() <parender> <llaveizq> (INSTRUC())+ <llaveder>
}
catch(ParseException e) {
System.out.println("Error en el FOR");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
Esta gramtica corresponde al case. Esta estructura no requiere declaraciones de ruptura.
void GCASE() : {}
{try
{<pswitch> <parenizq> (INSTRUC())+ <parender> <llaveizq> (<pcase> <entero> <dospuntos> (INSTRUC())
+)+ (<pdefault> <dospuntos> (INSTRUC())+)? <llaveder>
}
catch(ParseException e) {
System.out.println("Error en el CASE");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}
La siguiente gramtica describe la llamada a una funcin en Dtone.
void LLAM_FUNCION() : {}
{try

103

LIC. MARTHA MARTINEZ MORENO

MANUAL DE PROGRAMACIN DE
SISTEMAS I

{<ident> <parenizq> (<ident> | <entero> | <cadena> | <real>)* <parender> <puncoma>


}
catch(ParseException e) {
System.out.println("Error en la llamada");
Token t;
do{
t = getNextToken();}
while(t.kind != puncoma & t.kind != EOF);
}
}

104

LIC. MARTHA MARTINEZ MORENO

También podría gustarte