Está en la página 1de 10

PROYECTO FINAL VB: LEX Y YACC

COMPILADORES 2010

Universidad Católica de Salta


Facultad de Ingeniería e Informática
Carrera: Ingeniería en Informática

Profesores:

Dra. Alicia Pérez

Lic. Carolina Cardoso

Alumnos:

Lema Lucio Agustín

Cabezas Jorge Matías


Índice

Introducción 1

Tokens y Expresiones Regulares 1-2

Gramáticas Regulares 2-3

Lista de Errores (Léxicos y Sintácticos) 3

Problemas Surgidos 4

Aspectos Relevantes

Lista de Funciones Implementadas

Códigos Fuentes . vbl.l vby.y

1
Introducción

Este proyecto consiste en la implementación de las primeras fases de un compilador de un


Subconjunto de instrucciones del lenguaje de programación vb.

Dicho subconjunto de instrucciones, considera las siguientes estructuras:


 Tipos: Decimal, Cadena, Booleano.
 Sentencias: If, Asignación, Do-loop
 Operadores aritméticos: +,-,*,/
 Operadores lógicos:
 Comentarios
 Módulos: Procedimientos

Tokens y Expresiones Regulares

Tokens Expresión Regular


_Sub (s|S)(u|U)(b|B)
_End (e|E)(n|N)(d|D)
_If (i|IE)(f|F)
_Then (t|T)(h|H)(e|E)(n|N)
_Else (e|E)(l|L)(s|S)(e|E)
_Elseif (e|E)(l|L)(s|E)(i|I)(f|F)
_do (d|D)(o|O)
_loop (l|L)(o|O) (o|O)(p|P)
_tipo (d|D)(o|O)(u|U)(b|B)(l|L)(e|E)
|(s|S)(t|T)(r|R)(i|I)(n|N)
|(b|B)(o|O)(o|O)(l|L)(e|E)(a|A)(n|N)
Oper_aritm "+"|"-"|"*"|"/"
pr_truefalse “(t|T)(r|R)(u|U)(e|E”|”(f|F)(a|A)(l|L)(s|S)(e|E)”
_igual “=”
parentL (
parentR )
Oper_rel <=|>=|<|>
Id [a-zA-Z](([a-zA-Z0-9])|[.])*
_param (b|B)(i|I)(r|R)(e|E)(f|F) |(b|B)(i|I)(v|V)(a|A)(l|
L)
_as (a|A)(s|S)
_until (u|U)(n|N)(t|T)(i,I)(l,L)
_and (a|A)(n|N)(d|D)
_or (o|O)(r|R)
““
digito [0-9]
letra [a-zA-Z]
com [']

2
simbolo [!$%&]
Decimal {dig}+"."{dig}+
Oper_rel {com}({letra}|{dig})*[ \n]
_dim (d|D)(i|I)(m|M)
id [a-zA-Z](([a-zA-Z0-9])|[.])*
Cadena (\")(([a-zA-Z0-9])+)(\")
coma ,

Gramaticas Regulares
program_head: _sub id parentL _param id _as _tipo parentR body_program

body_program:decl_var body_program
|decl_var body_sent
|body_sent

decl_var:_dim variable _as tipo


|tipo asignacion

variable:
|id

tipo:
|_tipo

body_sent:
|sentencias body_sent
|sentencias body_program

sentencias:
|asignacion sentencias
|sent_if sentencias
|sent_loop sentencias
|decl_var sentencias

asignacion:id igual id
|id igual call_metodo
|id oper_aritm id
|igual id
|id igual cadena
|igual cadena
|id oper_rel id

var_asig:constante
|id
|cadena
|lista_operacion

constante:id
|decimal

3
|booleano
|cadena

booleano:pr_truefalse

lista_operacion:operacion
|operacion oper_aritm list_operacion

operacion:cadena oper_aritm cadena


|id oper_aritm id
|decimal oper_aritm decimal
|id oper_aritm cadena
|cadena oper_aritm id
|id oper_aritm decimal
|decimal oper_aritm id

sent_if: _if parentL lista_condicion parentR _then sentencia _end _if


|_if parenL lista_condicion parentR _then sentencia elseif sentencia _end _if

Elseif: sentencia
| sentencia elseif
|_else
sent_loop: _do body_program _until condicion

condicion:id oper_rel numero


|id oper_rel id
|id igual decimal
|id igual id
| id oper_rel decimal
|id igual booleano

lista_condicion:condicion
|condicion _and lista_condicion
|condicion _or lista_condicion

Lista de Errores (léxicos, sintacticos) considerados


En Lex: La lista de errores léxicos que se pueden considerar tiene que ver con cada uno de los
tokens que fueron definidos en “vbl.l”. Es decir, si la cadena a analizar no responde a algún token
definido, o no coincide con la expresión regular definida, se produce un error léxico. Algunos
ejemplos:

Entrada Salida

4
If a>b then a:=a+b; Análisis correcto!!!

If a>b ten a:=a+b; Símbolo desconocido ‘ten’ en línea 1.

If a>bbbbbbbbbbb then a:=a+b Error en línea 1 con símbolo


bbbbbbbbbbb.1

Para indicar el error léxico de un programa ejemplo se retornará un mensaje que indique dicho
error y se finalizará con la aplicación debido a que no tiene sentido pasar a la etapa siguiente.

En Yacc: los errores que se detecten dependerán de que si el archivo de texto que se lee responde
a las gramáticas definidas para el lenguaje, o no.

Algunos ejemplos:

Entrada Salida

If a>b then a:=a+b; Análisis correcto!!!

If a>b else a:=a+b; Error en línea 1 con símbolo else.

Para señalar el error sintáctico se mostrará un mensaje que mencione dicho error, la línea en que
se produjo el error y, además, el token más próximo al error.

Problemas Surgidos
Durante el proceso de construcción de los analizadores nos encontramos con diversos problemas,
los cuales se describen a continuación.

En primer lugar, con la instalación de Turbo Pascal 7.0, puesto que utilizamos Windows XP, tuvimos
que buscar e instalar la versión correcta para que funcione en este sistema operativo.

Hubo problemas con las herramientas Lex y Yacc, porque al instalarlas en la carpeta BIN y
posteriormente compilarlas en Turbo Pascal, surgía un error a partir de la falta de archivos TPU

5
relacionados a los mismos. Se solucionó cambiando los directorios correspondientes en Pascal
(Options/Directories).

En varias ocasiones se presentaron problemas difíciles de resolver que nos llevaron unas cuantas
horas para darnos con la solución después de un proceso de prueba y error.

Otro problema surgido se debió al almacenamiento del archivo de texto con espacios es decir con
tabs o líneas, el programa recorría las líneas en blanco y las marcaba como erróneas.

En ciertos casos los cambios realizados en Lex y Yacc, a pesar de que estaban lógicamente
correctos, no eran admitidos a la hora de compilar el archivo .PAS en Pascal. Lo solucionamos
reiniciando todo el proceso, es decir, volviendo a compilar en disco nuevamente: Lex.PAS,
LexLib.PAS, Yacc.PAS y YaccLib.PAS, generado otra vez el analizador (léxico y/o sintáctico) y
finalmente corriendo en Pascal el archivo .PAS.

Aspectos relevantes
Números: Se reconocen decimales

Identificadores: Comienzan con una letra y pueden tener caracteres siguientes tanto sean letras
como dígitos.

Caracter: conformado por una letra encerrada entre “ ”.

Comentarios: Cualquier combinación de letras, dígitos y espacios en blanco encerrados entre " "se
reconocen pero no devuelve tokens.

Espacio en blanco: el espacio en blanco es descartado por el análisis.

Lista de funciones implementadas


Las funciones utilizadas, tanto en Lex (mylex.l) como en Yacc (myyacc.y) son algunas de las
siguientes:

En Lex (vbl.l):

 Se definió un procedimiento “InfError”, el cual tiene como parámetro una cadena de texto
(string), y utilizando la función “yylineno”, muestra un mensaje de error cuando se
identifico un token que no esté definido en el lenguaje. En éste caso “yylineno” contiene la
línea del archivo actual.

procedure InfError (V:string);

6
begin

writeln('Símbolo desconocido ',V,' en línea: ',yylineno);

halt

end;

 También se utiliza una función “yytext” que contiene a la cadena de caracteres actual.

InfError (yytext);

En Yacc (vby.y):

 Aquí se define un procedimiento “yyError”, con un parámetro “msg” que reconoce una
cadena (string), el cual muetra un mensaje de error. Éste procedimiento utiliza dos
funciones: “yylineno” (muestra la línea donde se produjo el error) y “yytext” (muestra el
símbolo en donde se encuentra el error).

procedure yyError (msg:string);

begin

writeln('Error en línea: ',yylineno,' con símbolo: ',yytext)

end;

Códigos Fuentes .L .Y

vbl.l

7
vby.y

8
9

También podría gustarte