El analizador
desarrollado contiene técnicas de sincronizacion de errores similares a las
presentadas en la práctica 6. En particular, el método skipTo() permite
sincronizar el análisis a ciertos tokens. Para desarrollar el esquema de
tratamiento de errores se han incluido tanto métodos del tipo parse...()),
que analizan sintácticamente un símbolo de la gramática, como métodos del tipo
try...() que permiten sincronizarse en caso de error en algún método
parse.
La gramática BNF que
describe la cabecera de los ficheros Tinto es la siguiente:
Para realizar el análisis semántico es necesario modificar
los métodos asociados a cada símbolo para añadir las
verificaciones y acciones semánticas y para devolver los
datos correspondientes. A continuación se describen las
diferentes funciones de análisis:
-
LibraryDeclaration tryCompilationUnit(String):
analiza el símbolo inicial. Añade el tratamiento de errores
al análisis del símbolo CompilationUnit,
devolviendo el mismo objeto que genera la función
parse...() correspondiente.
-
LibraryDeclaration parseCompilationUnit(String): analiza el símbolo
inicial. Devuelve como atributo sintetizado el objeto LibraryDeclaration que describe la
biblioteca analizada. El argumento se utiliza para comprobar que el nombre de la
biblioteca coincide con el nombre del fichero analizado.
-
void tryImportClauseList(Vector<String>):
añade el tratamiento de errores al análisis del símbolo
ImportClauseList. Este símbolo tiene como atributo
heredado un vector de strings (imported) que
permite almacenar los nombres incluidos en las claúsulas
import.
-
void parseImportClauseList(Vector<String>):
analiza la lista de bibliotecas importadas. Utiliza ecomo
atributo heredado un vector de strings (imported)
que permite almacenar los nombres incluidos en las claúsulas
import.
-
void tryImportClause(Vector<String>): añade
el tratamiento de errores al análisis del símbolo
ImportClause. Utiliza un vector de strings como
atributo heredado para almacenar el nombre de la biblioteca importada.
-
void parseImportClause(Vector<String>): analiza una cláusula de
importación. Utiliza el vector de strings como atributo heredado para añadirle la
biblioteca importada.
-
LibraryDeclaration tryTintoDecl(String,
Vector<String>): añade el tratamiento de
errores al análisis del símbolo TintoDecl. Tiene
dos atributos heredados (el nombre de la biblioteca y un
vector con los nombres de las bibliotecas importadas) y un
atributo sintetizado (un objeto LibraryDeclaration
con la descripción de la biblioteca analizada).
-
LibraryDeclaration parseTintoDecl(String,
Vector<String>): analiza el cuerpo de una
biblioteca de Tinto, sea normal o nativa.
-
LibraryDeclaration tryLibraryDecl(String,
Vector<String>): analiza el cuerpo de la
biblioteca incluyendo el tratamiento de errores. La función crea el
objeto LibraryDeclaration con el nombre indicado y
le añade la lista de biblitecas importadas. A continuación
lanza el métod parse...() para analizar el símbolo
LibraryDecl, pasándole como atributo heredado el
objeto LibraryDeclaration.
-
void parseLibraryDecl(LibraryDeclaration): analiza el cuerpo de la
biblioteca. Utiliza el objeto LibraryDeclaration como atributo heredado.
Verifica que el identificador analizado corresponde con el
nombre de la biblioteca (que se extrajo del nombre del
fichero ".tinto") y traslada el objeto como atributo
heredado del símbolo FunctionList.
-
void tryFunctionList(LibraryDeclaration):
añade el tratamiento de errores al analisis del símbolo
FunctionList. Utiliza como atributo heredado el objeto
LibraryDeclaration que describe la biblioteca que
se está analizando y lo pasa a la función
parseFunctionList().
-
void parseFunctionList(LibraryDeclaration): analiza la lista de
funciones
definidas en la biblioteca. Utiliza el objeto LibraryDeclaration
para pasarlo como atributo heredado
al símbolo FunctionDecl, que le añadirá la función
que analice.
-
void tryFunctionDecl(LibraryDeclaration):
añade el tratamiento de errores al análisis del símbolo
FunctionDecl.
-
void parseFunctionDecl(LibraryDeclaration): analiza una
función definida en la biblioteca y ejecuta la acción
semántica actionLibraryFunction() para crear un
objeto Function y añadirlo al objeto LibraryDeclaration
(que recibe como atributo heredado).
-
LibraryDeclaration tryNativeDecl(String,
Vector<String>): analiza el cuerpo de la
biblioteca nativa incluyendo el tratamiento de errores.
El funcionamiento es similar al de las bibliotecas normales
salvo la llamada al método setNative() del objeto
LibraryDeclaration.
-
void parseNativeDecl(LibraryDeclaration): analiza el cuerpo de la
biblioteca nativa utilizando el objeto LibraryDeclaration como atributo heredado.
Verifica que el identificador analizado corresponde con el
nombre de la biblioteca (que se extrajo del nombre del
fichero ".tinto") y traslada el objeto como atributo
heredado del símbolo NativeFunctionList.
-
void tryNativeFunctionList(LibraryDeclaration):
añade el tratamiento de errores al analisis del símbolo
NativeFunctionList.
-
void parseNativeFunctionList(LibraryDeclaration): analiza la lista de
funciones
definidas en la biblioteca nativa.
-
void tryNativeFunctionDecl(LibraryDeclaration):
añade el tratamiento de errores al análisis del símbolo
NativeFunctionDecl.
-
void parseNativeFunctionDecl(LibraryDeclaration): analiza una
función definida en la biblioteca nativa y ejecuta la acción
semántica actionLibraryFunction() para crear un
objeto Function y añadirlo al objeto LibraryDeclaration
(que recibe como atributo heredado).
-
int tryAccess(): añade el tratamiento de
errores al anáisis del símbolo Access. Genera como
atributo sintetizado el código correspondiente al tipo de
acceso encontrado.
-
int parseAccess(): analiza el símbolo
Access. Genera como atributo sintetizado el código
correspondiente al tipo de acceso encontrado:
Access.PUBLIC_ACCESS o Access.PRIVATE_ACCESS.
-
int tryFunctionType(): añade el tratamiento
de errores al análisis del símbolo FunctionType.
Devuelve como atributo sintetizado el código del tipo de
dato de la función.
-
int parseFunctionType(): analiza el tipo de
dato de un método. Devuelve el código del tipo de dato como
atributo sintetizado.
-
int tryType(): añade el tratamiento de
errores al análisis del símbolo Type. Devuelve como
atributo sintetizado el código del tipo de dato.
-
int parseType(): analiza un tipo de dato simple. Devuelve el
código del tipo como atributo sintetizado.
-
Vector<Variable> tryArgumentDecl(): añade
el tratamiento de errores al análisis del símbolo
ArgumentDecl. Genera como atributo sintetizado un vector de
objetos Variable que describe los argumentos de la función
analizada.
-
Vector<Variable> parseArgumentDecl(): analiza los argumentos de un
método. Genera como atributo sintetizado un vector de
objetos Variable que describe los argumentos de la
función analizada.
-
void tryArgumentList(Vector<Variable>):
añade el tratamiento de errores al análisis del símbolo
ArgumentList. Utiliza como atributo heredado un vector
de objetos Variable al que irá añadiendo los
argumentos declarados en la función que se esté analizando.
-
void parseArgumentList(Vector<Variable>): analiza la lista de argumentos
de una función. Utiliza un vector de objetos Variable
como atributo heredado. El proceso de análisis consistirá en
añadir a este vector las declaraciones de los argumentos
encontrados.
-
void tryArgument(Vector<Variable>): añade
el tratamiento de errores al análisis del símbolo
Argument. Utiliza como atributo heredado un vector de
objetos Variable al que añadirá la definición del
argumento analizado.
-
void parseArgument(Vector<Variable>): analiza un argumento de una
función. Para ello recoge la información respecto al tipo de
dato y el identificador del argumento y ejecuta la acción
semántica actionAddArgument(). Esta acción se
encarga de verificar que el identificador no está duplicado
y de construir y añadir un objeto Variable con la
descripción del argumento analizado.
-
void tryMoreArguments(Vector<Variable>):
añade el tratamiento de errores al análisis del símbolo
MoreArguments. Utiliza como atributo heredado el vector
de objetos Variable que almacena la información de
los argumentos de la función analizada.
-
void parseMoreArguments(Vector<Variable>) : analiza el resto de lista de
argumentos de una función. Utiliza el vector de objetos
Variable como atributo heredado con la
lista de argumentos analizados.
-
void parseFunctionBody(): analiza el cuerpo
de una función. El analizador de cabecera no realiza ninguna
acción semántica en este punto, así que la función se limita
a recorrer un bloque de instrucciones, contando las llaves
abiertas y cerradas para detectar el final del bloque de
instrucciones.