Analizador Léxico Básico

download Analizador Léxico Básico

of 13

description

Análisis con código de un analizador léxico en c#

Transcript of Analizador Léxico Básico

Analizador Lxico Bsico enC#La primera sesin una de las fases iniciales en el proceso de compilacin es el anlisis lxico. En esta prctica vamos a construir un analizador lxico bsico para un lenguaje llamado OperA, este lenguaje permite la definicin de operaciones aritmticas bsicas, utilizando variables, nmeros, signos de agrupacin y operadores. Componentes Lxicos Siempre que se va a disear un nuevo lenguaje la primera fase es definir formalmente los componentes lxicos validos para el mismo, en nuestro caso son: Un nmero entero es una secuencia de dgitos Un identificador es una secuencia de letras y luego dgitos o letras Los espacios son ignorados Los operadores son multiplicativos y de adicin Los signos de agrupacin son parntesis derecho e izquierdo. Formalmente utilizando expresiones regulares se definiranTokenPatrn

OPERADD[+-]

OPERMUL[*/]

NUMEINT[0-9]+

IDENT[a-zA-Z]+

AGRUP[()]

Requerimientos funcionales del analizador lxico R1 : Generar los Tokens del lenguaje OperA Entradas : Un texto de entrada Salidas : Una coleccin de smbolos con los tokens encontrados en el texto de entrada. Construyendo el Analizador Lxico Un diagrama de clases para nuestro sistema puede ser:

Un analizador lxico puede generar 0 o ms smbolos, cada smbolo debe corresponder a un token especfico. Anlisis de las funciones a realizar Obtener un Token Un analizador lxico en esencia debe leer carcter por carcter de la entrada de datos hasta identificar un Token vlido, retornar dicho token y continuar con el proceso hasta encontrar el fin de la entrada de datos. El algoritmo general para el mtodo que obtiene un token es: Obtenga un carcter del texto de entrada Si es un carcter en blanco ignrelo Si es un operador(matemtico o de agrupacin) retorne el token correspondiente Si es un digito siga leyendo caracteres del texto de entrada hasta encontrar un carcter que no sea digito y al terminar retorne el token de numero entero Si es una letra (y es la primera) siga leyendo mientras sea letra o nmero. Al terminar retorne el token de identificadorObtener Lista de Tokens Otra funcin del analizador lxico es obtener todos los tokens existentes en el archivo fuente. El algoritmo general para el mtodo que obtiene la lista de tokens es: Mientras no se obtenga el token de fin Obtener token con el mtodo anterior Almacenar el token en la lista Implementacin del Componente Analizador Lexico para OperA Para la implementacin utilizaremos el lenguaje de programacin C# y el Visual Studio. Creando una dll para el analizador 1. Ingrese al Visual Studio

Una vez en el entorno de desarrollo vamos a crear un componente (dll) con las clases para el analizador Lxico. Seleccione File/New/Project

Configure el proyecto como se muestra en la siguiente grfica:

Al ingresar se aparece una plantilla con cdigo en C#. Vamos a adicionar un enum (enumeracin), que representa los tokens validos en el lenguaje, este se define antes de la clase pero en el mismo Namespace.

Luego de la definicin del enum vamos a adicionar la clase Smbolo como se muestra a continuacin:

Por ltimo se implementa la clase AnaLexOperA

Ahora implementamos en esta clase la propiedad que permite recorrer la cadena de entrada (con el cdigo fuente) al retornar el carcter actual de la entrada.

El siguiente mtodo identifica un token en la entrada y devuelve un objeto simbolo con el token encontrado. Puede verse que es una implementacin a fuerza bruta

Por ltimo implementamos el mtodo que retorna todos los tokens encontrados.

Compile la aplicacin Creando Un cliente para la dll Vamos a crear una aplicacin de consola que permita verificar el funcionamiento de la dll anterior. Cree un nuevo proyecto como se muestra a continuacin

En este programa agregue la librera que creamos en la primera parte, busque en la ventana Solutions Explorer la pestaa References y de clic derecho Add Reference .NET Assembly Browser y ubique la carpeta bin/debug del proyecto AnaLexperA y seleccione la dll.

En la ventana que aparece seleccione la pestaa Browse y ubique la dll generada en la primera parte.

Agregue el namespace donde est el analizador lxico:

using mnAnaLexOperA; Edite el siguiente cdigo namespace ConsolaOperA{class MainClass{public static void Main(string[] args) { string codigoFuente="(35+87*59) 76 "; AnaLexOperA analex= new AnaLexOperA(codigoFuente); foreach(Simbolo s in analex.GetSimbolos()) { switch((int)s.Token) { case (int)Tokens.IDENT:{Console.WriteLine("IDENT");break;} case (int)Tokens.OPERADD:{Console.WriteLine("OPERADD");break;} case (int)Tokens.OPERMUL:{Console.WriteLine("OPERMUL");break;} case (int)Tokens.NUMEINT:{Console.WriteLine("NUMEINT");break;} case (int)Tokens.OPERAGRU:{Console.WriteLine("OPERAGRU");break;} case (int)Tokens.ERROR:{Console.WriteLine("ERROR");break;} } } Console.ReadLine(); } }}

public Simbolo GetToken(){char carActual = GetCaracter;if(indice >textoEntrada.Length || carActual == @)return new Simbolo (Tokens.FIN, fin);switch (carActual){case : { break; }case \t': { break; }case \n': { break; }case +': {return new Simbolo(Tokens.OPERADD,+);}case -: { return new Simbolo(Tokens.OPERADD,-); }case *': { return new Simbolo(Tokens.OPERMUL,*); }case /':{if (GetCaracter == /){while (carActual != \n && carActual != @){carActual = GetCaracter;//System.Windows.Forms.MessageBox.Show(carActual.ToString());}break;}return new Simbolo(Tokens.OPERMUL,/);}case (: { return new Simbolo(Tokens.OPERAGRU,(); }case )': { return new Simbolo(Tokens.OPERAGRU,)); }case D':case d':{carActual = GetCaracter;if (carActual == o || carActual == O){return new Simbolo(Tokens.PALABRARES, do);}break;}case W':case w':{System.Windows.Forms.MessageBox.Show(carActual.ToString());carActual = GetCaracter;string palabraWhile = hile;string palabraWHILE = HILE;for (int i = 0; i < palabraWhile.Length; i++){//System.Windows.Forms.MessageBox.Show(carActual.ToString() + " " + palabraWHILE[i].ToString() + " " + palabraWhile[i].ToString());if (carActual != palabraWhile[i] && carActual != palabraWHILE[i]){break;}carActual = GetCaracter;}return new Simbolo(Tokens.PALABRARES,"while");}default:{if (Char.IsDigit(carActual)){string digito = "";while (Char.IsDigit(carActual)){digito += carActual.ToString();carActual = GetCaracter;MessageBox.Show(carActual.ToString());}if (carActual == 'E'){string notacionCient = "";notacionCient += carActual.ToString();carActual = GetCaracter;MessageBox.Show(carActual.ToString());if (carActual == '-' || carActual == '+'){notacionCient += carActual.ToString();carActual = GetCaracter;if (char.IsDigit(carActual)){MessageBox.Show(carActual.ToString());while (Char.IsDigit(carActual)){notacionCient += carActual.ToString();carActual = GetCaracter;MessageBox.Show(carActual.ToString());}digito += notacionCient;MessageBox.Show(digito.ToString());return new Simbolo(Tokens.NOTACIENT, digito);}}else{return new Simbolo(Tokens.ERROR, "");}}if (indice < textoEntrada.Length || carActual != '@')indice;return new Simbolo(Tokens.NUMEINT, digito);}else{if (Char.IsLetter(carActual)){string palabra = "";while (Char.IsLetter(carActual) || Char.IsDigit(carActual)){palabra += carActual.ToString();carActual = GetCaracter;}if (indice < textoEntrada.Length || carActual != '@')indice;return new Simbolo(Tokens.IDENT,palabra);}else{return new Simbolo(Tokens.ERROR,"");}}}}return new Simbolo(Tokens.VACIO,"");}