Sie sind auf Seite 1von 13

Compiladores.

Gua 3 Facultad: Ingeniera Escuela: Computacin Asignatura: Compiladores

Tema: Anlisis Sintctico


Contenido
En esta gua se abordarn los conceptos pertenecientes al componente de anlisis sintctico de un compilador de forma que sirva de introduccin a la simulacin del mismo adems de complementarlo con el anlisis lxico de la gua anterior y los conceptos aprendidos hasta el momento.

Objetivos Especficos
Conocer las caractersticas y principal funcin de un analizador sintctico. Analizar e interpretar como un compilador realiza el anlisis sintctico de un programa.

Material y Equipo
Gua de Laboratorio N 6. Computadora con programa Dev-C++. Dispositivo de Almacenamiento (USB).

Introduccin Terica
Anlisis Sintctico

Gua 3

El anlisis sintctico es un anlisis a nivel de sentencias, yGua es mucho ms complejo que el anlisis lxico. Su funcin es 4 tomar el programa fuente en forma de tokens, que recibe del analizador lxico, y determinar la estructura de las fa sentencias del programa. Este proceso es similar a determinar la estructura de una frase en Castellano, determinando quien es el sujeto, predicado, el verbo y los complementos.

Compiladores. Gua 3

El anlisis sintctico agrupa a los tokens en clases sintcticas (denominadas no terminales en la definicin de la gramtica), tales como expresiones, procedimientos, etc. El analizador sintctico o parser obtiene un rbol sintctico (u otra estructura equivalente) en la cual las hojas son los tokens, y cualquier nodo que no sea una hoja, representa un tipo de clase sintctica (operaciones). Por ejemplo el anlisis sintctico de la siguiente expresin: (A+B)*(C+D) Con las reglas de la gramtica que se presenta a continuacin dar lugar al rbol sintctico de la figura 3:
<expresin> ::= <trmino> <ms trminos>

<ms trminos>::= +<trmino> <ms trminos>| - <trmino> <ms trminos> | <vaco> <trmino> ::= <factor> <ms factores>

<ms factores>::= * <factor> <ms factores>|/ <factor> <ms factores> | <vaco> <factor> ::= ( <expresin> ) | <variable> | <constante>

La estructura de la gramtica anterior refleja la prioridad de los operadores, as los operadores + y - tienen la prioridad ms baja, mientras que * y / tienen una prioridad superior. Se evaluaran en primer lugar las constantes, variables y expresiones entre parntesis. Los rboles sintcticos se construyen con un conjunto de reglas conocidas como gramtica, y que definen con total precisin el lenguaje fuente. Al proceso de reconocer la estructura del lenguaje fuente se conoce con el nombre de anlisis sintctico (parsing). Hay distintas clases de analizadores o reconocedores sintcticos, pero en general se clasifican en 2 grandes grupos: A.S. Ascendentes y A.S. Descendentes. La principal tarea del analizador sintctico no es comprobar que la sintaxis del programa fuente sea correcta, sino construir una representacin interna de ese programa y en el caso en que sea un programa incorrecto, dar un mensaje de error. Para ello, el analizador sintctico (A.S.) comprueba que el orden en que el analizador lxico le va entregando los tokens es vlido. Si esto es as significar que la sucesin de

Compiladores. Gua 3 3

smbolos que representan dichos tokens puede ser generada por la gramtica correspondiente al lenguaje del cdigo fuente.

Ejemplo: Entrada: num*num+num Gramtica: E ::= E + T | T T ::= T * F | F F ::= num (E: expresin, T: trmino, F: factor)

Obsrvese que en el anlisis descendente, partiendo del smbolo inicial hasta alcanzar las hojas, obtenemos una derivacin por la izquierda. En el ascendente, partiendo de las hojas hasta llegar al axioma obtenemos la inversa de una derivacin por la derecha.

Compiladores. Gua 3

Procedimiento
A continuacin se presenta la gramtica aceptada por nuestro Gua 3 de programacin llamado MUSIM, utilizando la lenguaje notacin BNF: <Programa> ::= <bloque> ::= fa <otra_sentencia>::= <sentencia> ::= <asignacin> ::= <expresin> ::= <mas trminos> ::= <termino> <mas factores> ::= ::=

Gua 4

<factor> <lectura> <escritura> <variable> <constante>

::= ::= ::= ::= ::=

M { <bloque> } <sentencia> <otra_sentencia> ; <sentencia> <otra_sentencia>| <vaco> <asignacin>|<lectura>|<escritura> <variable> = <expresin> <termino> <mas trminos> + <termino> <mas trminos> | - <termino> <mas trminos> | <vaco> <factor> <mas factores> * <factor> <mas factores> | / <factor> <mas factores> | % <factor> <mas factores> | <vaco> (<expresin>)|<variable>|<constante> R <variable> W <variable> a | b | c | ... | z 0 | 1 | 2 | ... | 9

Puede observarse que este lenguaje slo permite 3 tipos de sentencias lectura, asignacin y escritura. Tiene un solo tipo de datos: entero. Las variables estn formadas por una nica letra minscula, y las constantes son de un dgito. Tiene 5 operadores + (adicin), - (diferencia), * (producto), / (divisin) y % (mdulo). Se permite el uso de parntesis. La precedencia de los operadores es la siguiente (de mayor a menor): 1. Evaluacin de expresiones entre parntesis ( ). 2. Producto, Divisin entera y Mdulo. 3. Suma y Resta. Las reglas sintcticas siguientes en BNF: <bloque> ::= <sentencia> <otra_sentencia> <otra_sentencia> ::= ; <sentencia> <otra_sentencia> | <vaco>

Compiladores. Gua 3 5

Tambin puede escribirse en una sola EBNF de la siguiente forma: <bloque> ::= <sentencia> { ; <sentencia> } Creacin del Analizador Sintctico La tcnica a utilizar es la denominada recursivo descendente sin retroceso, para su utilizacin se deben de cumplir dos requisitos: El lenguaje fuente debe estar definido con una gramtica LL(1). Con un solo token se decide la regla de la gramtica que debe aplicarse. El lenguaje de implementacin debe de permitir la recursividad. Antes de correr y probar el Analizador Sintctico, cree las libreras Lxico.h y Sintactico.h (desde Dev-C++) Siguiendo estos pasos: a) Cargar el Dev-C++. b) Dar clic a Archivo y seleccionar Nuevo Proyecto a. Seleccionar Consola Application. b. Colocar el nombre de proyecto Guia1. c) Guardar el archivo fuente con el nombre de lxico.h A continuacin escriba el cdigo de la gua anterior de la clase lxico de MUSIM/0, insrtelo todo excepto la funcin main. (La Clase Lxico se implemento en la gua anterior). Cree otra librera (sintacti.h) para insertar el cdigo que se presenta a continuacin: (Este cdigo es la implementacin del analizador lxico). #ifndef sintacti_H #define sintacti_H #include "lexico.h" #include <stdlib.h> using namespace std; class Sintactico{ void programa (void); void bloque (void); void sentencia (void); void otra_sentencia (void); void asignacion(void); void lectura (void);

Compiladores. Gua 3

void escritura(void); void variable(void); void expresion(void); void termino(void); void mas_terminos(void); void factor(void); void mas_factores(void); void constante(void); void errores (int codigo); Lexico lexico; //objeto lxico miembro de la clase public: Sintactico(char *fuente, int traza); ~Sintactico(void); }; Sintactico::Sintactico(char *fuente, int traza):lexico(fuente, traza) //se inicializa el constructor de la clase lxico { if (lexico.existeTraza()) cout<<"INICIO DE ANALISIS SINTACTICO"<<endl; programa(); } /***********************************************************/ Sintactico::~Sintactico(void) { if (lexico.existeTraza()) { cout<<"FIN DE ANALISIS SINTACTICO"<<endl; cout<<"FIN DE COMPILACION"<<endl; } } /***********************************************************/ void Sintactico::programa(void) { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <PROGRAMA>"<<endl; token=lexico.siguienteToken(); if (token=='M') cout <<"M"; else errores(8); token=lexico.siguienteToken(); if (token!='{') errores(9); bloque(); token=lexico.siguienteToken(); if (token=='}') {

Compiladores. Gua 3 7

cout<<"}"; } else errores(2); } /***********************************************************/ void Sintactico::bloque(void) { char token=' '; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <BLOQUE>"<<endl; sentencia(); otra_sentencia(); } /***********************************************************/ void Sintactico::otra_sentencia(void) { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <OTRA_SENTENCIA>"<<endl; token=lexico.siguienteToken(); if (token==';') { sentencia(); otra_sentencia(); } else lexico.devuelveToken(token); //vacio } /***********************************************************/ void Sintactico::sentencia(void) { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <SENTENCIA>"<<endl; token=lexico.siguienteToken(); if ((token>='a') && (token<='z')) { lexico.devuelveToken(token); asignacion(); } else if (token=='R') lectura(); else if (token=='W') escritura(); else if (token=='}') { lexico.devuelveToken(token); return; } else errores(6);

Compiladores. Gua 3

} /***********************************************************/ void Sintactico::asignacion() { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <ASIGNACION>"<<endl; variable(); token=lexico.siguienteToken(); if (token!='=') errores(3); expresion(); } /***********************************************************/ void Sintactico::variable(void) { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <VARIABLE>"<<endl; token=lexico.siguienteToken(); if ((token>='a') && (token<='z')) cout<<token; else errores(5); } /***********************************************************/ void Sintactico::expresion(void) { if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <EXPRESION>"<<endl; termino(); mas_terminos(); } /***********************************************************/ void Sintactico::termino(void) { if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <TERMINO>"<<endl; factor(); mas_factores(); } /***********************************************************/ void Sintactico::mas_terminos(void) { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <MAS_TERMINOS>"<<endl; token=lexico.siguienteToken(); if (token=='+') {

Compiladores. Gua 3 9

termino(); mas_terminos(); } else if (token =='-') { termino(); mas_terminos(); } else lexico.devuelveToken(token); // <vacio> } /***********************************************************/ void Sintactico::factor(void) { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <FACTOR>"<<endl; token=lexico.siguienteToken(); if ((token>='0') && (token<='9')) { lexico.devuelveToken(token); constante(); } else if (token=='(') { expresion(); token=lexico.siguienteToken(); if (token!=')') errores(4); } else { lexico.devuelveToken(token); variable(); } } /***********************************************************/ void Sintactico::mas_factores(void) { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <MAS_FACTORES>"<<endl; token=lexico.siguienteToken(); switch (token) { case '*':factor(); mas_factores(); break; case '/':factor();

10 Compiladores. Gua 3

mas_factores(); break; case '%':factor(); mas_factores(); break; default: //<vacio> lexico.devuelveToken(token); } } /***********************************************************/ void Sintactico::lectura(void) { char token; token=lexico.siguienteToken(); if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <LECTURA> "<<token<<endl; if((token<'a')||(token>'z')) errores(5); } /***********************************************************/ void Sintactico::escritura(void) { char token; token=lexico.siguienteToken(); if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <ESCRITURA> "<<token<<endl; if ((token<'a') || (token>'z')) errores(5); } /************************************************/ void Sintactico::constante(void) { char token; if (lexico.existeTraza()) cout<<"ANALISIS SINTACTICO: <CONSTANTE>"<<endl; token=lexico.siguienteToken(); if ((token>='0') && (token<='9')) cout<<token; else errores(7); } /**********************************************************/ void Sintactico::errores(int codigo) { int x; cout<<"LINEA "<<lexico.lineaActual(); cout<<" ERROR SINTACTICO "<<codigo; switch (codigo) { case 1 :cout<<" :ESPERABA UN ;"<<endl;break;

Compiladores. Gua 3 11

case 2 :cout<<" :ESPERABA UNA }"<<endl;break; case 3 :cout<<" :ESPERABA UN ="<<endl;break; case 4 :cout<<" :ESPERABA UN )"<<endl;break; case 5 :cout<<" :ESPERABA UN IDENTIFICADOR"<<endl;break; case 6 :cout<<" :INSTRUCCION DESCONOCIDA"<<endl;break; case 7 :cout<<" :ESPERABA UNA CONSTANTE"<<endl;break; case 8 :cout<<" :ESPERABA UNA M DE MAIN"<<endl;break; case 9 :cout<<" :ESPERABA UNA {"<<endl;break; default: cout<<" :NO DOCUMENTADO"<<endl; } cin>>x; exit(-(codigo+100)); } #endif

Anlisis de resultados
Agregue comentarios al cdigo digitado y a continuacin cree un archivo de texto (prueba.txt), gurdelo en la misma carpeta donde guardo el proyecto gua3 y digite el ejemplo de la gua 1 de MUSIM/0 escogido la semana pasada. Finalmente cree el programa principal (ppal.cpp) para probar el analizador sintctico: #include<iostream> #include "sintacti.h" using namespace std; int main() { Sintactico sintactico("prueba.txt",1); return 0; } Despus de haber ejecutado con xito el analizador sintctico responda lo siguiente: 1. Coloque en el archivo prueba.txt algn carcter no reconocido por el lenguaje MUSIM/0. Vuelva a ejecutar la aplicacin generada en C++. Qu observ en la ejecucin? cul es la razn del resultado? ________________________________________________________ ________________________________________________________

12 Compiladores. Gua 3

________________________________________________________ ________________________________________________________ 2. Elimine el carcter ; de alguna de las instrucciones. Vuelva a ejecutar la aplicacin. Qu observ en la ejecucin? cul es la razn del resultado? ________________________________________________________ ________________________________________________________ ________________________________________________________

Investigacin complementaria
a) Investigar cules son los tipos de anlisis sintctico y sus caractersticas. b) Investigar que es la notacin LL(K) y LLR, adems de la notacin EBNF y BNF. c) Realice el analizador sintctico para el lenguaje Micro C.

Bibliografa
Compiladores- principios, tcnicas y herramientas Autores: Aho - Lam Sethi Ullman Editorial Pearson Addison Wesley Segunda edicin Construccin de compiladores Autor: Kenneth C. Louden Editorial Thomson

Compiladores. Gua 3 13

Gua 3: ANLISIS SINTCTICO


Tema: Presentacin del programa

Hoja de cotejo:

Docente:
MquinaMquina No: No: GL:
GL: Mquina No: a

3 1

Alumno:
Alumno:

Docente:
Docente: EVALUACION % CONOCIMIENTO Del 20 al 30% 1-4 Conocimie nto deficient e de los fundament os tericos 5-7

GL: Fecha:

8-10 Conocimiento completo y explicacin clara de los fundamentos tericos

Nota

Conocimiento y explicacin incompleta de los fundamentos tericos

APLICACIN DEL CONOCIMIENTO

Del 40% al 60%

ACTITUD Del 15% al 30% No tiene actitud proactiva . Actitud propositiva y con propuestas no aplicables al contenido de la gua. Tiene actitud proactiva y sus propuestas son concretas.

TOTAL

100%