21/12/2007
Compilador de Pascal Analizador léxico
Grupo 2: Antonio De Miguel Vicenti Daniel Dionne González Borja Gómez Gómez Miguel Martínez Segura Alberto Milán Gutiérrez
Grupo 2
Compilador de Pascal Analizador léxico
Contenido Contenido ..........................................................................................................................1 Introducción ..................................................................................................................... 2 JFlex ................................................................................................................................. 2 Estructura del archivo .flex ...................................................................................................................... 2 Expresiones regulares .............................................................................................................................. 3
Léxico................................................................................................................................ 3 Especificación ........................................................................................................................................... 3 Tokens ........................................................................................................................................................ 5 Implementación........................................................................................................................................ 5
Tabla de símbolos ............................................................................................................ 6 Gestor de errores .............................................................................................................. 8 Errores .......................................................................................................................................................8 El tipo TError ............................................................................................................................................8 El Gestor de errores ..................................................................................................................................8 Uso del Gestor de Errores ........................................................................................................................8
Casos de prueba ............................................................................................................... 9 Prueba1.pas ............................................................................................................................................... 9 Prueba2.pas............................................................................................................................................. 10 Prueba3.pas..............................................................................................................................................11 Prueba4.pas............................................................................................................................................. 14 Prueba5.pas ............................................................................................................................................. 16 Prueba de un archivo que no exista o que este corrupto ..................................................................... 19
1
Grupo 2
Introducción JFlex Para el desarrollo de nuestro analizador léxico hemos utilizado la herramienta JFlex (http://jflex.de/). Más abajo se especifica con más detalle la implementación con esta herramienta.
Léxico La sección léxico del proyecto especificará el diseño e implementación de las estructuras y codificaciones de los que dispone el analizador para interpretar el código. Es la parte del proyecto en la que aparece el scanner y los tokens elegidos. Así mismo nos servirá para explicar detenidamente las expresiones regulares deducidas de pascal y las acciones semánticas asociadas. Tabla de símbolos
Gestor de errores Para la gestión de errores hemos optado por el uso de un ArrayList con objetos de tipo TError que guardan información de la fila y la columna donde se produjo el error.
JFlex Para la generación del autómata de estados del analizador léxico hemos utilizado JFlex (http://jflex.de/). Se trata de una potente herramienta, que dadas las expresiones regulares que reconocen los tokens del lenguaje y sus acciones asociadas, generan el autómata reconocedor de forma automática. En el código se incluyen, en el paquete Lexico, el archivo original (Lexico.flex) y el compilado por JFlex, Lexico.java.
Estructura del archivo .flex -
Una cabecera con las inclusiones de código (imports) necesarias. Una serie de variables utilizadas por JFlex para insertar las declaraciones, y la definición del Token devuelto en el final del fichero. Código empotrado (que se copia ad hoc al .java) en donde se declara la tabla de símbolos y se define la función creaToken(). Lo que hace esta función es instanciar un Token con la información generada por el autómata: return new Token(type.ordinal(), yyline, yycolumn, atributos); El ordinal hace referencia al enumerado, que dice de qué tipo de Token se trata. yyline hace referencia a la línea donde está ubicado el Token. yycolumn hace referencia a la columna donde está ubicado el Token. atributos es un Object que define los atributos del Token, generados en esta función a partir del tipo. Luego viene el conjunto de expresiones regulares, que sigue un esquema: nombre_expresión = expresión_regular Más abajo se explica cómo se definen las expresiones regulares. Por último, se definen las acciones asociadas a los patrones, que bien pueden estar definidos por expresiones regulares en el apartado anterior, o se pueden definir directamente. Aquí se o o o o
-
-
2
Grupo 2
utiliza la función creaToken mencionada antes. Si llega al final y no ha entrado en ninguna de las acciones, entonces se considera que el Token es erróneo y se notifica al gestor de errores.
Expresiones regulares Introducimos aquí un pequeño resumen de cómo se escriben algunas expresiones regulares que hemos usado de JFlex, como referencia para aquéllos que no conozcan el lenguaje: Expresión [A-Z] [^c] {n_e1}|{n_e2} {nombre} (exp)? (exp)* (exp)+ \. \{ \‟ \ \n \r \t
Descripción Conjuntos de caracteres del intervalo Conjunto de caracteres que excluye el carácter „c‟ e1 OR e2 Referencia al nombre de una expresión definida La expresión exp una sola vez La expresión exp cero o más veces La expresión exp una o más veces „\‟: carácter de escape, representa los caracteres que le siguen. Caracteres especiales: nueva línea, retorno, tabulación
Léxico Como ya se mencionó en la introducción, en esta sección de proyecto se observa cómo se comporta el analizador léxico para gestionar cada entrada del código. Podemos distinguir dos partes, la especificación y la implementación. En la primera comentaremos cómo es la gramática que reconoce el analizador, cómo se ha diseñado la estructura interna de los tokens del lenguaje y su codificación. En la segunda parte, veremos la forma en que hemos plasmado en JAVA toda esta información y la interfaz de acceso para el analizador sintáctico.
Especificación Gramática Estudiando el lenguaje pascal, llegamos a ciertas reglas con las que hemos generado una serie de expresiones regulares para reconocer los tokens. A continuación mostramos dichas expresiones y las acciones semánticas que hemos asociado a dichos patrones. Expresiones Regulares letra = [A-Za-z] digito = [0-9] alfanumerico = {letra}|{digito} caracter = \'([^'])?\' cadena = \'([^'])*\' identificador = {letra}({alfanumerico})* entero = {digito}+ numeroE = \E | \e real = {digito}+\.{digito}+({numeroE}{digito}+)? llaveIzq = \{ llaveDer = \} comentarioIni = \(\* comentarioFin = \*\) todoMenosLlave = [^}] todoMenosParen = [^)] cuerpoComentario1= {todoMenosLlave}* cuerpoComentario2= {todoMenosParen}*
3
Grupo 2
comentario = {llaveIzq}{cuerpoComentario1}{llaveDer} | {comentarioIni}{cuerpoComentario2}{comentarioFin} espacio = [ \n\t\r] Nota: Expresiones codificadas en sintaxis de JFlex El autómata que obtenemos por la gramática, obtenido gracias a JFlex minimizado y sin fallos se adjunta a este documento debido a su enorme extensión. Acciones semánticas asociadas a los patrones "*" { return creaToken(TipoToken.OPER_ARIT, TipoOperadoresAritmeticos.POR); } "+" { return creaToken(TipoToken.OPER_ARIT, TipoOperadoresAritmeticos.MAS); } "-" { return creaToken(TipoToken.OPER_ARIT, TipoOperadoresAritmeticos.MENOS); } "/" { return creaToken(TipoToken.OPER_ARIT, TipoOperadoresAritmeticos.DIVIDE); } ";" { return creaToken(TipoToken.SEPARADOR, TipoSeparadores.PUNTOYCOMA); } "," { return creaToken(TipoToken.SEPARADOR, TipoSeparadores.COMA); } "(" { return creaToken(TipoToken.ABREPAREN, yytext()); } ")" { return creaToken(TipoToken.CIERRAPAREN, yytext()); } "[" { return creaToken(TipoToken.ABRECORCHETE, yytext()); } "]" { return creaToken(TipoToken.CIERRACORCHETE, yytext()); } "(." { return creaToken(TipoToken.ABRECORCHETE, yytext()); } ".)" { return creaToken(TipoToken.CIERRACORCHETE, yytext()); } "and" { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.AND); } "or" { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.OR); } "not" { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.NOT); } "xor" { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.XOR); } "shl" { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.DESP_IZQ); } "shr" { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.DESP_DER); } "=" { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.IGUAL); } "<" { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.MENOR); } ">" { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.MAYOR); } "<=" { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.MENOROIGUAL); } ">=" { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.MAYOROIGUAL); } "!=" { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.DISTINTO); } ":" { return creaToken(TipoToken.SEPARADOR, TipoSeparadores.DOSPUNTOS); } ":=" { return creaToken(TipoToken.OPER_ASIGNACION, yytext()); } "." { return creaToken(TipoToken.SEPARADOR, TipoSeparadores.PUNTO); } "^" { return creaToken(TipoToken.PUNTERO, yytext()); } "#" { return creaToken(TipoToken.ASCII, yytext()); } "$" { return creaToken(TipoToken.HEXADECIMAL, yytext()); } {identificador} { return creaToken(TipoToken.IDENTIFICADOR, yytext()); } {entero} { return creaToken(TipoToken.LITERAL_ENTERO, new Integer(yytext())); } {real} { return creaToken(TipoToken.LITERAL_REAL, new Double(yytext()));} {caracter} { return creaToken(TipoToken.LITERAL_CARACTER, new Character(yytext().charAt(1)));} {cadena} { return creaToken(TipoToken.LITERAL_CADENA, new String(yytext().substring(1,yytext().length()-1)));} {comentario} /*En la versión final ignorará comentarios */ System.out.println("Comentario reconocido: " + yytext()); }
4
Grupo 2
{espacio} .
{ /* Ignora espacios. */ } { System.out.println("Caracter ilegal, '" + yytext() + "' linea: " + yyline + ", columna: " + yychar); Nota: Expresiones codificadas en sintaxis de JFlex
Tokens La materia de trabajo esencial para un analizador léxico son los tokens, que deben estar bien especificados y con una estructura clara. Cada token de nuestro analizador consta de un tipo y de los atributos asociados a dicho token. Además incluye la línea y la columna donde se encuentra situado en el código. Los tipos de token que pueden darse, responden a una lista concreta que hemos diseñado partiendo del lenguaje Pascal. El scanner se encarga de elegir cual será el tipo de un token recibido. Las directrices proporcionadas a JFlex, condicionadas por la gramática del diseño y sus acciones asociadas obligan a que se encuentre siempre un tipo. En caso de que el token no se asociase a ningún patrón establecido, sería un error léxico. A continuación mostramos una tabla orientativa del diseño de los tokens. Tipo de token EOF, PAL_RES, IDENTIFICADOR, PUNTERO, LITERAL_ENTERO, LITERAL_REAL, LITERAL_CARACTER, LITERAL_CADENA, OPER_ARIT, SEPARADOR, ABREPAREN, CIERRAPAREN, ABRECORCHETE, CIERRACORCHETE, OPER_RELACIONAL, OPER_ASIGNACION, OPER_LOGICO, SIMBOLO, ASCII, HEXADECIMAL
Codificación elegida (PAL_RES, [Puntero a tabla]) (IDENTIFICADOR, [Puntero a tabla]) (LITERAL_ENTERO, [valor entero]) (LITERAL_REAL, [valor double]) (LITERAL_CARACTER, [carácter]) (LITERAL_CADENA, [string]) (OPER_ARIT, [tipo enumerado asociado]) (SEPARADOR, [tipo enumerado asociado]) (ABREPAREN, []) (CIERRAPAREN,[]) (ABRECORCHETE, []) (CIERRACORCHETE, []) (OPER_RELACIONAL,[ tipo enumerado asociado]) (OPER_ASIGNACION, [tipo enumerado asociado]) (OPER_ARIT, [tipo enumerado asociado]) (OPER_LOGICO, [tipo enumerado asociado]) (OPER_ARIT, [tipo enumerado asociado]) (ASCII , []) (OPER_ARIT, [tipo enumerado asociado])
Cabe destacar que cada token lleva además el numero de fila y columna de su posición en el código La interfaz con el analizador sintáctico, a nivel del analizador léxico, se basará únicamente en un método de solicitud de un nuevo token.
Implementación
5
Grupo 2
Se ha decidido implementar el analizador en el lenguaje JAVA. Hemos diseñado una estructura que simplifica el control del código, permitiendo así la actualización del analizador con nuevos tipos de token o atributos de estos. La clase token.java, gestiona el objeto Token. Proporcionándole los atributos de los que ya hemos hablado en la especificación. La clase principal es lexico.java, donde se empotra el código recibido de JFlex, generando el scanner. Aquí se decide que tipo de token se recibe, se monta en un objeto Token y se procesa. Además contiene el método nextToken() gracias al cual el analizador sintáctico solicita los nuevos tokens del analizador léxico. Las clases TipoToken.java, TipoOperadoresAritmeticos.java, TipoSeparadores.java, TipoOperadoresRelacionales.java y TipoOperadoresLogicos.java son de tipo enumerado. En ellas se definen todos los tipos considerados por el analizador. TipoToken.java es la más genérica y las demás profundizan en cada uno de los tipos. A continuación mostramos los tipos de token implementados, dentro de cada enumerado. Para información más detallada sobre la implementación, recomendamos consultar el javadoc adjunto. TipoToken EOF, PAL_RES, IDENTIFICADOR, PUNTERO, LITERAL_ENTERO, LITERAL_REAL, LITERAL_CARACTER, LITERAL_CADENA, OPER_ARIT, SEPARADOR, ABREPAREN, CIERRAPAREN, ABRECORCHETE, CIERRACORCHETE, OPER_RELACIONAL, OPER_ASIGNACION, OPER_LOGICO, SIMBOLO, ASCII, HEXADECIMAL TipoOperadoresLogicos AND, OR, NOT, XOR, DESP_IZQ, DESP_DER
TipoOperadoresRelacionales IGUAL, MENOR, MAYOR, MENOROIGUAL, MAYOROIGUAL, DISTINTO
TipoOperadoresAritmeticos MAS, MENOS, POR, DIVIDE
TipoSeparadores COMA, PUNTOYCOMA, PUNTO, DOSPUNTOS
Tabla de símbolos La tabla de símbolos es la entidad contenedora de información y datos del compilador. Para ello se requiere un acceso rápido y óptimo a los datos necesarios durante el proceso, y dada la optimalidad de
6
Grupo 2
los objetos predefinidos por Sun MicroSystems en su JDK 1.6 hemos decidido el uso de listas dinámicas y tablas hash ofrecidas por el mismo. El esquema que la tabla de símbolos posee es el ofrecido en clase en su tercera implementación. La tabla, actualmente, maneja ámbitos y posee opciones de editabilidad. NOTA: Cabe señalar que la gestión de palabras reservadas del lenguaje está monitorizada e implementada dentro de una tabla perteneciente al módulo presentado. La tabla de símbolos podría resumirse, en esquema, de la siguiente forma: -
-
-
-
Tabla de palabras reservadas Clave-String Valor-Tipo de palabra reservada. Lista de tablas para cada ámbito Para cada tabla se sigue el siguiente esquema: Clave-String Valor-Lista polimórfica de atributos. La clave será, en cada caso, el lexema particular de cada identificador y contendrá asociada la lista de todos sus atributos. Se ha elegido una lista polimórfica general (Object) para generalizar en todo lo posible los contenidos de la misma y facilitar las posibles próximas ediciones. Tabla organizadora: Clave-Entero Valor-Entero. Esta tabla asociará cada ámbito con su "padre" a nivel de anidamiento según la organización del código. Puntero a ámbito actual: Entero. El puntero señalará al ámbito en el cual se encuentre el análisis del código en el momento actual. Flag de inserciones toleradas: Booleano. Este flag permitirá, según su valor, insertar nuevas entradas en la tabla de símbolos. Su gestión, y edición, será supuestamente controlada por el Analizador Sintáctico o Semántico, según se decida implementar.
Los métodos ofrecidos por la clase son los descritos en la documentación Javadoc del proyecto. Como decisión de diseño hay que referir las siguientes cualidades: -
-
-
-
Palabras reservadas: Si se intenta insertar un identificador cuyo lexema coincide con una palabra reservada se retornará la referencia a la tabla de palabras reservadas en su entrada correspondiente. Palabras ya declaradas: Si se intenta insertar un identificador cuyo lexema ya ha sido declarado, ya sea en el ámbito actual o en cualquier ámbito de orden superior de anidamiento, se retornará la referencia a dicha entrada, en el ámbito que corresponda. Palabra nueva, escritura inhabilitada: Si se intenta insertar un identificador cuyo lexema no coincide con ninguno insertado previamente pero no está habilitado el flag de tolerar inserción se retornará el valor null para que el analizador léxico gestione el error de manera particular. Palabra nueva, escritura habilitada: Si no se cumple ninguna de las anteriores opciones, se generará una nueva entrada en la tabla del ámbito actual y se retornará la referencia a la misma.
La tabla de símbolos está orientada al uso máximo posible desde su inicio, así que puede darse la situación de tener que especificarla más detalladamente en alguna sección para su correcta funcionalidad según avance el uso y necesidad de la misma.
7
Grupo 2
Gestor de errores El gestor de errores incluye tres clases distintas: -
Errores TError GestorErrores.
Errores Hemos creado un tipo enumerado con los tipos básicos de errores: LEXICO_ELEMENTO_YA_INSERTADO Cuando ya se ha añadido un elemento con ese identificador. LEXICO_CARACTER_NO_VALIDO El carácter no genera un token válido. LEXICO_ERROR_DE_IO Se produce un error de Entrada/Salida.
El tipo TError El tipo TError contiene, en primer lugar, un parámetro del tipo enumerado Errores. Además, contiene dos variables de tipo integer que guardan información de la línea y la columna en la que se ha registrado el error. De esta manera cada error podrá tratarse como una entidad independiente, y podrá almacenarse de manera sencilla. Además de los setters y getters de la línea, la columna y el tipo de error, la clase TError contiene un método toString() (que hereda de Object) que devuelve un String con la información del error con un formato legible por el usuario. Ejemplo: llamando a este método con un error de tipo CARACTER_NO_VALIDO en la línea 5, columna 17, el String será: “Línea: 5 Columna: 17. CARÁCTER NO VALIDO”.
El Gestor de errores El gestor de errores del analizador léxico está implementado usando una lista tipo ArrayList de elementos de TError (ArrayList). El gestor de errores se comunica por el resto de bloques por una sencilla interfaz. Los métodos principales son: setErrores(ArrayList errores) Setter que introduce el ArrayList de errores que se le introduce como parámetro como lista de errores del programa. insertaError(TError error) Inserta un error, que se le pasa como parámetro, en la lista de errores. Este es el método principal que el resto de módulos usan para la tarea de la gestión de errores.
Uso del Gestor de Errores El método principal main utiliza el gestor de errores de las siguientes maneras: -
Lo crea al comienzo de la ejecución. Llama al método gestor.muestraListaErrores() al terminar el escáner para mostrar por pantalla los errores registrados. Cuando gestiona una excepción de Entrada/Salida añade un nuevo error al gestor de errores.
8
Grupo 2
La unidad Lexico.java, en la función next_token() llama también al gestor de errores cuando el autómata llega a un estado de error por carácter no valido: gestor.insertaError(new GestorDeErrores.TError(Errores.LEXICO_CARACTER_NO_VALIDO,yyline,yycolumn));
Casos de prueba A continuación pasamos a mostrar algunas de las diferentes pruebas que hemos realizado, incluyendo el programa de entrada con sintaxis Pascal, y su respectivas salidas de tokens generadas por el analizador léxico. En la presente documentación detallaremos tan solo algunas pruebas de las que hemos realizado, siendo estas lo suficientemente representativas como para que el lector se haga una idea del resultado general de las pruebas. Tanto estas, como otras pruebas se pueden encontrar en el proyecto, empezando desde el archivo con formato pruebaX.pas, donde X será un número entre 1 y 12. Para ejecutar una prueba, simplemente bastará con ejecutar el proyecto. Antes de comenzar, aparecerá una caja de dialogo en la que se nos pedirá que insertemos la ruta del archivo que queremos procesar. Por defecto los hemos introducido en la carpeta Pruebas, así que veremos que en la venta que aparece aparecerá /pruebas. Si queremos ejecutar, por ejemplo, el archivo Prueba1.pascal, tan solo tendremos que añadir al texto ya escrito “/prueba/” (que se refiere a la carpeta del proyecto en la que queremos buscar), el nombre del archivo. Al final tendríamos que ves escrito en la caja de dialogo “/prueba/Prueba1.pascal”. Al darle a aceptar se ejecutará el analizador léxico para esta prueba. Hemos intentado abarcar todos los casos posibles de palabras reservadas, así como de errores léxicos. A continuación pasamos a detallar diferentes entradas y salidas de pruebas, así como una breve descripción del cometido de cada prueba:
Prueba1.pas Se hacen diferentes usos de las cadenas y los caracteres.
Entrada Program var caracter : char; var estrin : String; begin caracter := 'a'; estrin := 'aa'; [pipi] (.pipi.) END.
Salida Comentario reconocido: (*Este es para probar las cadenas y los caracteres, y los punteros de regalo*)
9
Grupo 2
Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token
"program" -> PAL_RES [38] Linea: 1 Columna: 0 "type" -> PAL_RES [37] Linea: 2 Columna: 2 "puntero" -> IDENTIFICADOR [puntero] Linea: 2 Columna: 7 "=" -> OPER_RELACIONAL [IGUAL] Linea: 2 Columna: 15 "^" -> PUNTERO [^] Linea: 2 Columna: 17 "real" -> PAL_RES [1] Linea: 2 Columna: 18 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 2 Columna: 22 "var" -> PAL_RES [20] Linea: 3 Columna: 2 "caracter" -> IDENTIFICADOR [caracter] Linea: 3 Columna: 6 ":" -> SEPARADOR [DOSPUNTOS] Linea: 3 Columna: 15 "char" -> PAL_RES [3] Linea: 3 Columna: 17 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 3 Columna: 21 "var" -> PAL_RES [20] Linea: 4 Columna: 2 "estrin" -> IDENTIFICADOR [estrin] Linea: 4 Columna: 6 ":" -> SEPARADOR [DOSPUNTOS] Linea: 4 Columna: 13 "String" -> PAL_RES [4] Linea: 4 Columna: 15 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 4 Columna: 21 "begin" -> PAL_RES [22] Linea: 5 Columna: 0 "caracter" -> IDENTIFICADOR [caracter] Linea: 6 Columna: 1 ":=" -> OPER_ASIGNACION [] Linea: 6 Columna: 10 "'a'" -> LITERAL_CARACTER [a] Linea: 6 Columna: 13 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 6 Columna: 16 "estrin" -> IDENTIFICADOR [estrin] Linea: 7 Columna: 1 ":=" -> OPER_ASIGNACION [] Linea: 7 Columna: 8 "'aa'" -> LITERAL_CADENA [aa] Linea: 7 Columna: 11 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 7 Columna: 15 "[" -> ABRECORCHETE [] Linea: 8 Columna: 1 "pipi" -> IDENTIFICADOR [pipi] Linea: 8 Columna: 2 "]" -> CIERRACORCHETE [] Linea: 8 Columna: 6 "(." -> ABRECORCHETE [] Linea: 9 Columna: 1 "pipi" -> IDENTIFICADOR [pipi] Linea: 9 Columna: 3 ".)" -> CIERRACORCHETE [] Linea: 9 Columna: 7 "END" -> PAL_RES [12] Linea: 10 Columna: 0 "." -> SEPARADOR [PUNTO] Linea: 10 Columna: 3
Prueba2.pas Se utiliza un puntero, así como la creación de tipos definidos por el usuario
Entrada Type tDimension = 1..100; eMatriz(f,c: tDimension) = array [1..f,1..c] of real; tRango = record f,c: tDimension value 1; end; tpMatriz = ^eMatriz;
Salida Token "type" -> PAL_RES [37] Linea: 0 Columna: 0 Token "tDimension" -> IDENTIFICADOR [tDimension] Linea: 1 Columna: 0 10
Grupo 2
Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token
"=" -> OPER_RELACIONAL [IGUAL] Linea: 1 Columna: 11 "1" -> LITERAL_ENTERO [1] Linea: 1 Columna: 13 "." -> SEPARADOR [PUNTO] Linea: 1 Columna: 14 "." -> SEPARADOR [PUNTO] Linea: 1 Columna: 15 "100" -> LITERAL_ENTERO [100] Linea: 1 Columna: 16 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 1 Columna: 19 "eMatriz" -> IDENTIFICADOR [eMatriz] Linea: 2 Columna: 0 "(" -> ABREPAREN [] Linea: 2 Columna: 7 "f" -> IDENTIFICADOR [f] Linea: 2 Columna: 8 "," -> SEPARADOR [COMA] Linea: 2 Columna: 9 "c" -> IDENTIFICADOR [c] Linea: 2 Columna: 10 ":" -> SEPARADOR [DOSPUNTOS] Linea: 2 Columna: 11 "tDimension" -> IDENTIFICADOR [tDimension] Linea: 2 Columna: 13 ")" -> CIERRAPAREN [] Linea: 2 Columna: 23 "=" -> OPER_RELACIONAL [IGUAL] Linea: 2 Columna: 25 "array" -> PAL_RES [7] Linea: 2 Columna: 27 "[" -> ABRECORCHETE [] Linea: 2 Columna: 33 "1" -> LITERAL_ENTERO [1] Linea: 2 Columna: 34 "." -> SEPARADOR [PUNTO] Linea: 2 Columna: 35 "." -> SEPARADOR [PUNTO] Linea: 2 Columna: 36 "f" -> IDENTIFICADOR [f] Linea: 2 Columna: 37 "," -> SEPARADOR [COMA] Linea: 2 Columna: 38 "1" -> LITERAL_ENTERO [1] Linea: 2 Columna: 39 "." -> SEPARADOR [PUNTO] Linea: 2 Columna: 40 "." -> SEPARADOR [PUNTO] Linea: 2 Columna: 41 "c" -> IDENTIFICADOR [c] Linea: 2 Columna: 42 "]" -> CIERRACORCHETE [] Linea: 2 Columna: 43 "of" -> PAL_RES [8] Linea: 2 Columna: 45 "real" -> PAL_RES [1] Linea: 2 Columna: 48 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 2 Columna: 52 "tRango" -> IDENTIFICADOR [tRango] Linea: 3 Columna: 0 "=" -> OPER_RELACIONAL [IGUAL] Linea: 3 Columna: 7 "record" -> PAL_RES [11] Linea: 3 Columna: 9 "f" -> IDENTIFICADOR [f] Linea: 4 Columna: 0 "," -> SEPARADOR [COMA] Linea: 4 Columna: 1 "c" -> IDENTIFICADOR [c] Linea: 4 Columna: 2 ":" -> SEPARADOR [DOSPUNTOS] Linea: 4 Columna: 3 "tDimension" -> IDENTIFICADOR [tDimension] Linea: 4 Columna: 5 "value" -> IDENTIFICADOR [value] Linea: 4 Columna: 16 "1" -> LITERAL_ENTERO [1] Linea: 4 Columna: 22 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 4 Columna: 23 "end" -> PAL_RES [12] Linea: 5 Columna: 0 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 5 Columna: 3 "tpMatriz" -> IDENTIFICADOR [tpMatriz] Linea: 6 Columna: 0 "=" -> OPER_RELACIONAL [IGUAL] Linea: 6 Columna: 9 "^" -> PUNTERO [^] Linea: 6 Columna: 11 "eMatriz" -> IDENTIFICADOR [eMatriz] Linea: 6 Columna: 12 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 6 Columna: 19
Prueba3.pas 11
Grupo 2
Uso de las sentencias while, for e if. Uso de arrays. Error por identificador mal construido: Podemos ver como hemos intentado declarar el identificador 1cont, pero como empieza por un digito, el léxico no reconoce que pueda ser un identificador, por lo que separa en dos tokens. 1 literal entero y un identificador.
Entrada program recorridos; var cont1,cont2: integer; vector= array [1..100] of real; encontrado: boolean; 1cont: integer (* ejemplo de error por identificador mal construido *) begin cont1 := 1; cont2 := 1; (*recorrido con while*) while ((cont1 <= 100) AND (encontrado = false)) do begin if (vector[cont1] == 1) encontrado = true; else cont1 = cont1+1; end; (*recorrido con for*) for cont2 := 1 to 100 do Begin if (vector[cont2] = 1) then encontrado = true end; END.
Salida Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token
"program" -> PAL_RES [38] Linea: 0 Columna: 0 "recorridos" -> IDENTIFICADOR [recorridos] Linea: 0 Columna: 8 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 0 Columna: 18 "var" -> PAL_RES [20] Linea: 2 Columna: 2 "cont1" -> IDENTIFICADOR [cont1] Linea: 2 Columna: 6 "," -> SEPARADOR [COMA] Linea: 2 Columna: 11 "cont2" -> IDENTIFICADOR [cont2] Linea: 2 Columna: 12 ":" -> SEPARADOR [DOSPUNTOS] Linea: 2 Columna: 17 "integer" -> PAL_RES [0] Linea: 2 Columna: 19 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 2 Columna: 26 "vector" -> IDENTIFICADOR [vector] Linea: 3 Columna: 2 "=" -> OPER_RELACIONAL [IGUAL] Linea: 3 Columna: 8 "array" -> PAL_RES [7] Linea: 3 Columna: 10 "[" -> ABRECORCHETE [] Linea: 3 Columna: 16 "1" -> LITERAL_ENTERO [1] Linea: 3 Columna: 17 "." -> SEPARADOR [PUNTO] Linea: 3 Columna: 18
12
Grupo 2
Token "." -> SEPARADOR [PUNTO] Linea: 3 Columna: 19 Token "100" -> LITERAL_ENTERO [100] Linea: 3 Columna: 20 Token "]" -> CIERRACORCHETE [] Linea: 3 Columna: 23 Token "of" -> PAL_RES [8] Linea: 3 Columna: 25 Token "real" -> PAL_RES [1] Linea: 3 Columna: 28 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 3 Columna: 32 Token "encontrado" -> IDENTIFICADOR [encontrado] Linea: 4 Columna: 2 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 4 Columna: 12 Token "boolean" -> PAL_RES [2] Linea: 4 Columna: 14 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 4 Columna: 21 Token "1" -> LITERAL_ENTERO [1] Linea: 5 Columna: 2 Token "cont" -> IDENTIFICADOR [cont] Linea: 5 Columna: 3 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 5 Columna: 7 Token "integer" -> PAL_RES [0] Linea: 5 Columna: 9 Comentario reconocido: (* ejemplo de error por identificador mal construido *) Token "begin" -> PAL_RES [22] Linea: 7 Columna: 0 Token "cont1" -> IDENTIFICADOR [cont1] Linea: 9 Columna: 0 Token ":=" -> OPER_ASIGNACION [] Linea: 9 Columna: 6 Token "1" -> LITERAL_ENTERO [1] Linea: 9 Columna: 9 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 9 Columna: 10 Token "cont2" -> IDENTIFICADOR [cont2] Linea: 10 Columna: 0 Token ":=" -> OPER_ASIGNACION [] Linea: 10 Columna: 6 Token "1" -> LITERAL_ENTERO [1] Linea: 10 Columna: 9 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 10 Columna: 10 Comentario reconocido: (*recorrido con while*) Token "while" -> PAL_RES [26] Linea: 13 Columna: 3 Token "(" -> ABREPAREN [] Linea: 13 Columna: 9 Token "(" -> ABREPAREN [] Linea: 13 Columna: 10 Token "cont1" -> IDENTIFICADOR [cont1] Linea: 13 Columna: 11 Token "<=" -> OPER_RELACIONAL [MENOROIGUAL] Linea: 13 Columna: 17 Token "100" -> LITERAL_ENTERO [100] Linea: 13 Columna: 20 Token ")" -> CIERRAPAREN [] Linea: 13 Columna: 23 Token "AND" -> PAL_RES [17] Linea: 13 Columna: 25 Token "(" -> ABREPAREN [] Linea: 13 Columna: 29 Token "encontrado" -> IDENTIFICADOR [encontrado] Linea: 13 Columna: 30 Token "=" -> OPER_RELACIONAL [IGUAL] Linea: 13 Columna: 41 Token "false" -> IDENTIFICADOR [false] Linea: 13 Columna: 43 Token ")" -> CIERRAPAREN [] Linea: 13 Columna: 48 Token ")" -> CIERRAPAREN [] Linea: 13 Columna: 49 Token "do" -> PAL_RES [27] Linea: 13 Columna: 51 Token "begin" -> PAL_RES [22] Linea: 14 Columna: 3 Token "if" -> PAL_RES [23] Linea: 15 Columna: 3 Token "(" -> ABREPAREN [] Linea: 15 Columna: 6 Token "vector" -> IDENTIFICADOR [vector] Linea: 15 Columna: 7 Token "[" -> ABRECORCHETE [] Linea: 15 Columna: 13 Token "cont1" -> IDENTIFICADOR [cont1] Linea: 15 Columna: 14 Token "]" -> CIERRACORCHETE [] Linea: 15 Columna: 19 Token "=" -> OPER_RELACIONAL [IGUAL] Linea: 15 Columna: 21
13
Grupo 2
Token "=" -> OPER_RELACIONAL [IGUAL] Linea: 15 Columna: 22 Token "1" -> LITERAL_ENTERO [1] Linea: 15 Columna: 24 Token ")" -> CIERRAPAREN [] Linea: 15 Columna: 25 Token "encontrado" -> IDENTIFICADOR [encontrado] Linea: 16 Columna: 5 Token "=" -> OPER_RELACIONAL [IGUAL] Linea: 16 Columna: 16 Token "true" -> IDENTIFICADOR [true] Linea: 16 Columna: 18 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 16 Columna: 22 Token "else" -> PAL_RES [25] Linea: 17 Columna: 3 Token "cont1" -> IDENTIFICADOR [cont1] Linea: 18 Columna: 5 Token "=" -> OPER_RELACIONAL [IGUAL] Linea: 18 Columna: 11 Token "cont1" -> IDENTIFICADOR [cont1] Linea: 18 Columna: 13 Token "+" -> OPER_ARIT [MAS] Linea: 18 Columna: 18 Token "1" -> LITERAL_ENTERO [1] Linea: 18 Columna: 19 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 18 Columna: 20 Token "end" -> PAL_RES [12] Linea: 19 Columna: 3 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 19 Columna: 6 Comentario reconocido: (*recorrido con for*) Token "for" -> PAL_RES [30] Linea: 23 Columna: 4 Token "cont2" -> IDENTIFICADOR [cont2] Linea: 23 Columna: 8 Token ":=" -> OPER_ASIGNACION [] Linea: 23 Columna: 14 Token "1" -> LITERAL_ENTERO [1] Linea: 23 Columna: 17 Token "to" -> PAL_RES [31] Linea: 23 Columna: 19 Token "100" -> LITERAL_ENTERO [100] Linea: 23 Columna: 22 Token "do" -> PAL_RES [27] Linea: 23 Columna: 26 Token "Begin" -> PAL_RES [22] Linea: 24 Columna: 5 Token "if" -> PAL_RES [23] Linea: 25 Columna: 7 Token "(" -> ABREPAREN [] Linea: 25 Columna: 10 Token "vector" -> IDENTIFICADOR [vector] Linea: 25 Columna: 11 Token "[" -> ABRECORCHETE [] Linea: 25 Columna: 17 Token "cont2" -> IDENTIFICADOR [cont2] Linea: 25 Columna: 18 Token "]" -> CIERRACORCHETE [] Linea: 25 Columna: 23 Token "=" -> OPER_RELACIONAL [IGUAL] Linea: 25 Columna: 25 Token "1" -> LITERAL_ENTERO [1] Linea: 25 Columna: 27 Token ")" -> CIERRAPAREN [] Linea: 25 Columna: 28 Token "then" -> PAL_RES [24] Linea: 25 Columna: 30 Token "encontrado" -> IDENTIFICADOR [encontrado] Linea: 26 Columna: 8 Token "=" -> OPER_RELACIONAL [IGUAL] Linea: 26 Columna: 19 Token "true" -> IDENTIFICADOR [true] Linea: 26 Columna: 21 Token "end" -> PAL_RES [12] Linea: 27 Columna: 7 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 27 Columna: 10 Token "END" -> PAL_RES [12] Linea: 29 Columna: 0 Token "." -> SEPARADOR [PUNTO] Linea: 29 Columna: 3
Prueba4.pas Declaración de todo tipo de variables, así como uso de los dos tipos de comentarios. Error de carácter no válido (el guión bajo en la sentencia y:= _ba).
Entrada { Programa Ejemplo para Analisis Léxico. }
14
Grupo 2
(* Segundo formato de comentarios *) program var i,j,k: integer; var x,y: real; var letra : char; var cadena : String; begin if (i > 10) then x := i + j * k / y; else y := i + j * k / x; x := 5.2E10; y := _ba; END.
Salida Comentario reconocido: { Programa Ejemplo para Analisis Léxico. } Comentario reconocido: (* Segundo formato de comentarios *) Token "program" -> PAL_RES [38] Linea: 2 Columna: 0 Token "var" -> PAL_RES [20] Linea: 3 Columna: 2 Token "i" -> IDENTIFICADOR [i] Linea: 3 Columna: 6 Token "," -> SEPARADOR [COMA] Linea: 3 Columna: 7 Token "j" -> IDENTIFICADOR [j] Linea: 3 Columna: 8 Token "," -> SEPARADOR [COMA] Linea: 3 Columna: 9 Token "k" -> IDENTIFICADOR [k] Linea: 3 Columna: 10 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 3 Columna: 11 Token "integer" -> PAL_RES [0] Linea: 3 Columna: 13 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 3 Columna: 20 Token "var" -> PAL_RES [20] Linea: 4 Columna: 2 Token "x" -> IDENTIFICADOR [x] Linea: 4 Columna: 6 Token "," -> SEPARADOR [COMA] Linea: 4 Columna: 7 Token "y" -> IDENTIFICADOR [y] Linea: 4 Columna: 8 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 4 Columna: 9 Token "real" -> PAL_RES [1] Linea: 4 Columna: 11 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 4 Columna: 15 Token "var" -> PAL_RES [20] Linea: 5 Columna: 2 Token "letra" -> IDENTIFICADOR [letra] Linea: 5 Columna: 6 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 5 Columna: 12 Token "char" -> PAL_RES [3] Linea: 5 Columna: 14 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 5 Columna: 18 Token "var" -> PAL_RES [20] Linea: 6 Columna: 2 Token "cadena" -> IDENTIFICADOR [cadena] Linea: 6 Columna: 6 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 6 Columna: 13 Token "String" -> PAL_RES [4] Linea: 6 Columna: 15 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 6 Columna: 21 Token "begin" -> PAL_RES [22] Linea: 7 Columna: 0 Token "if" -> PAL_RES [23] Linea: 8 Columna: 3 Token "(" -> ABREPAREN [] Linea: 8 Columna: 6
15
Grupo 2
Token "i" -> IDENTIFICADOR [i] Linea: 8 Columna: 7 Token ">" -> OPER_RELACIONAL [MAYOR] Linea: 8 Columna: 9 Token "10" -> LITERAL_ENTERO [10] Linea: 8 Columna: 11 Token ")" -> CIERRAPAREN [] Linea: 8 Columna: 13 Token "then" -> PAL_RES [24] Linea: 8 Columna: 15 Token "x" -> IDENTIFICADOR [x] Linea: 9 Columna: 6 Token ":=" -> OPER_ASIGNACION [] Linea: 9 Columna: 8 Token "i" -> IDENTIFICADOR [i] Linea: 9 Columna: 11 Token "+" -> OPER_ARIT [MAS] Linea: 9 Columna: 13 Token "j" -> IDENTIFICADOR [j] Linea: 9 Columna: 15 Token "*" -> OPER_ARIT [POR] Linea: 9 Columna: 17 Token "k" -> IDENTIFICADOR [k] Linea: 9 Columna: 19 Token "/" -> OPER_ARIT [DIVIDE] Linea: 9 Columna: 21 Token "y" -> IDENTIFICADOR [y] Linea: 9 Columna: 23 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 9 Columna: 24 Token "else" -> PAL_RES [25] Linea: 10 Columna: 3 Token "y" -> IDENTIFICADOR [y] Linea: 11 Columna: 6 Token ":=" -> OPER_ASIGNACION [] Linea: 11 Columna: 8 Token "i" -> IDENTIFICADOR [i] Linea: 11 Columna: 11 Token "+" -> OPER_ARIT [MAS] Linea: 11 Columna: 13 Token "j" -> IDENTIFICADOR [j] Linea: 11 Columna: 15 Token "*" -> OPER_ARIT [POR] Linea: 11 Columna: 17 Token "k" -> IDENTIFICADOR [k] Linea: 11 Columna: 19 Token "/" -> OPER_ARIT [DIVIDE] Linea: 11 Columna: 21 Token "x" -> IDENTIFICADOR [x] Linea: 11 Columna: 23 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 11 Columna: 24 Token "x" -> IDENTIFICADOR [x] Linea: 12 Columna: 3 Token ":=" -> OPER_ASIGNACION [] Linea: 12 Columna: 5 Token "5.2E10" -> LITERAL_REAL [5.2E10] Linea: 12 Columna: 8 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 12 Columna: 14 Token "END" -> PAL_RES [12] Linea: 13 Columna: 0 Token "." -> SEPARADOR [PUNTO] Linea: 13 Columna: 3 Linea: 13 Columna: 7. LEXICO CARACTER NO VALIDO
Prueba5.pas Uso de los operadores booleanos y los relacionales
Entrada (*operadores relacionales*) program boolsYrelacionales; var verdadero: boolean; falso: boolean; y: integer; x: integer;
16
Grupo 2
Begin verdadero := verdadero OR falso; verdadero := verdadero AND verdadero; falso := falso AND verdadero; falso := verdadero AND NOT verdadero; if if if if if
(xy) then x:= y; (x>=y) then x:= y; (x=y) then x:= y;
End.
Salida Comentario reconocido: (*operadores relacionales*) Token "program" -> PAL_RES [38] Linea: 2 Columna: 0 Token "boolsYrelacionales" -> IDENTIFICADOR [boolsYrelacionales] Linea: 2 Columna: 8 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 2 Columna: 26 Token "var" -> PAL_RES [20] Linea: 4 Columna: 0 Token "verdadero" -> IDENTIFICADOR [verdadero] Linea: 6 Columna: 0 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 6 Columna: 9 Token "boolean" -> PAL_RES [2] Linea: 6 Columna: 11 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 6 Columna: 18 Token "falso" -> IDENTIFICADOR [falso] Linea: 7 Columna: 0 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 7 Columna: 5 Token "boolean" -> PAL_RES [2] Linea: 7 Columna: 7 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 7 Columna: 14 Token "y" -> IDENTIFICADOR [y] Linea: 9 Columna: 0 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 9 Columna: 1 Token "integer" -> PAL_RES [0] Linea: 9 Columna: 3 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 9 Columna: 10 Token "x" -> IDENTIFICADOR [x] Linea: 10 Columna: 0 Token ":" -> SEPARADOR [DOSPUNTOS] Linea: 10 Columna: 1 Token "integer" -> PAL_RES [0] Linea: 10 Columna: 3 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 10 Columna: 10 Token "begin" -> PAL_RES [22] Linea: 16 Columna: 0 Token "verdadero" -> IDENTIFICADOR [verdadero] Linea: 18 Columna: 0 Token ":=" -> OPER_ASIGNACION [] Linea: 18 Columna: 10 Token "verdadero" -> IDENTIFICADOR [verdadero] Linea: 18 Columna: 13 Token "OR" -> PAL_RES [18] Linea: 18 Columna: 23 Token "falso" -> IDENTIFICADOR [falso] Linea: 18 Columna: 26 Token ";" -> SEPARADOR [PUNTOYCOMA] Linea: 18 Columna: 31 Token "verdadero" -> IDENTIFICADOR [verdadero] Linea: 19 Columna: 0 Token ":=" -> OPER_ASIGNACION [] Linea: 19 Columna: 10 Token "verdadero" -> IDENTIFICADOR [verdadero] Linea: 19 Columna: 13 Token "AND" -> PAL_RES [17] Linea: 19 Columna: 23 Token "verdadero" -> IDENTIFICADOR [verdadero] Linea: 19 Columna: 27
17
Grupo 2
Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token
";" -> SEPARADOR [PUNTOYCOMA] Linea: 19 Columna: 36 "falso" -> IDENTIFICADOR [falso] Linea: 20 Columna: 0 ":=" -> OPER_ASIGNACION [] Linea: 20 Columna: 6 "falso" -> IDENTIFICADOR [falso] Linea: 20 Columna: 9 "AND" -> PAL_RES [17] Linea: 20 Columna: 15 "verdadero" -> IDENTIFICADOR [verdadero] Linea: 20 Columna: 19 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 20 Columna: 28 "falso" -> IDENTIFICADOR [falso] Linea: 21 Columna: 0 ":=" -> OPER_ASIGNACION [] Linea: 21 Columna: 6 "verdadero" -> IDENTIFICADOR [verdadero] Linea: 21 Columna: 9 "AND" -> PAL_RES [17] Linea: 21 Columna: 19 "NOT" -> PAL_RES [14] Linea: 21 Columna: 23 "verdadero" -> IDENTIFICADOR [verdadero] Linea: 21 Columna: 27 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 21 Columna: 36 "if" -> PAL_RES [23] Linea: 24 Columna: 0 "(" -> ABREPAREN [] Linea: 24 Columna: 3 "x" -> IDENTIFICADOR [x] Linea: 24 Columna: 4 "<" -> OPER_RELACIONAL [MENOR] Linea: 24 Columna: 5 "y" -> IDENTIFICADOR [y] Linea: 24 Columna: 6 ")" -> CIERRAPAREN [] Linea: 24 Columna: 7 "then" -> PAL_RES [24] Linea: 24 Columna: 9 "x" -> IDENTIFICADOR [x] Linea: 24 Columna: 14 ":=" -> OPER_ASIGNACION [] Linea: 24 Columna: 15 "y" -> IDENTIFICADOR [y] Linea: 24 Columna: 18 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 24 Columna: 19 "if" -> PAL_RES [23] Linea: 26 Columna: 0 "(" -> ABREPAREN [] Linea: 26 Columna: 3 "x" -> IDENTIFICADOR [x] Linea: 26 Columna: 4 "<=" -> OPER_RELACIONAL [MENOROIGUAL] Linea: 26 Columna: 5 "y" -> IDENTIFICADOR [y] Linea: 26 Columna: 7 ")" -> CIERRAPAREN [] Linea: 26 Columna: 8 "then" -> PAL_RES [24] Linea: 26 Columna: 10 "x" -> IDENTIFICADOR [x] Linea: 26 Columna: 15 ":=" -> OPER_ASIGNACION [] Linea: 26 Columna: 16 "y" -> IDENTIFICADOR [y] Linea: 26 Columna: 19 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 26 Columna: 20 "if" -> PAL_RES [23] Linea: 28 Columna: 0 "(" -> ABREPAREN [] Linea: 28 Columna: 3 "x" -> IDENTIFICADOR [x] Linea: 28 Columna: 4 ">" -> OPER_RELACIONAL [MAYOR] Linea: 28 Columna: 5 "y" -> IDENTIFICADOR [y] Linea: 28 Columna: 6 ")" -> CIERRAPAREN [] Linea: 28 Columna: 7 "then" -> PAL_RES [24] Linea: 28 Columna: 9 "x" -> IDENTIFICADOR [x] Linea: 28 Columna: 14 ":=" -> OPER_ASIGNACION [] Linea: 28 Columna: 15 "y" -> IDENTIFICADOR [y] Linea: 28 Columna: 18 ";" -> SEPARADOR [PUNTOYCOMA] Linea: 28 Columna: 19 "if" -> PAL_RES [23] Linea: 30 Columna: 0 "(" -> ABREPAREN [] Linea: 30 Columna: 3 "x" -> IDENTIFICADOR [x] Linea: 30 Columna: 4
18
Grupo 2
Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token Token
">=" "y" ")" "then" "x" ":=" "y" ";" "if" "(" "x" "=" "y" ")" "then" "x" ":=" "y" ";" "if" "(" "x" "<" ">" "y" ")" "then" "x" ":=" "y" ";" "End" "."
-> OPER_RELACIONAL [MAYOROIGUAL] Linea: 30 Columna: 5 -> IDENTIFICADOR [y] Linea: 30 Columna: 7 -> CIERRAPAREN [] Linea: 30 Columna: 8 -> PAL_RES [24] Linea: 30 Columna: 10 -> IDENTIFICADOR [x] Linea: 30 Columna: 15 -> OPER_ASIGNACION [] Linea: 30 Columna: 16 -> IDENTIFICADOR [y] Linea: 30 Columna: 19 -> SEPARADOR [PUNTOYCOMA] Linea: 30 Columna: 20 -> PAL_RES [23] Linea: 32 Columna: 0 -> ABREPAREN [] Linea: 32 Columna: 3 -> IDENTIFICADOR [x] Linea: 32 Columna: 4 -> OPER_RELACIONAL [IGUAL] Linea: 32 Columna: 5 -> IDENTIFICADOR [y] Linea: 32 Columna: 6 -> CIERRAPAREN [] Linea: 32 Columna: 7 -> PAL_RES [24] Linea: 32 Columna: 9 -> IDENTIFICADOR [x] Linea: 32 Columna: 14 -> OPER_ASIGNACION [] Linea: 32 Columna: 15 -> IDENTIFICADOR [y] Linea: 32 Columna: 18 -> SEPARADOR [PUNTOYCOMA] Linea: 32 Columna: 19 -> PAL_RES [23] Linea: 34 Columna: 0 -> ABREPAREN [] Linea: 34 Columna: 3 -> IDENTIFICADOR [x] Linea: 34 Columna: 4 -> OPER_RELACIONAL [MENOR] Linea: 34 Columna: 5 -> OPER_RELACIONAL [MAYOR] Linea: 34 Columna: 6 -> IDENTIFICADOR [y] Linea: 34 Columna: 7 -> CIERRAPAREN [] Linea: 34 Columna: 8 -> PAL_RES [24] Linea: 34 Columna: 10 -> IDENTIFICADOR [x] Linea: 34 Columna: 15 -> OPER_ASIGNACION [] Linea: 34 Columna: 16 -> IDENTIFICADOR [y] Linea: 34 Columna: 19 -> SEPARADOR [PUNTOYCOMA] Linea: 34 Columna: 20 -> PAL_RES [12] Linea: 36 Columna: 0 -> SEPARADOR [PUNTO] Linea: 36 Columna: 3
Prueba de un archivo que no exista o que este corrupto Si nos equivocamos de nombre de fichero, o intentamos introducir uno que no exista, se nos dará error de Entrada salida, y veremos esto en consola: Linea: -1 Columna: -1. LEXICO ERROR DE IO
19