Instruction manuals y goldparser gold parser ayuda tutorial guatemlaa">
Gold Parser
Gold Parser
Gold Parser
Nuestra Misión
Hacer uso de las herramientas tecnológicas tanto de hardware y software, para poder desarrollar
productos de alta calidad, que ayude a mejorar la vida ser humano y su entorno.
Nuestra Visión
Ayudar a mejorar o facilitar la situación de nuestro entorno, por medio del desarrollo de software
en distintas áreas de la sociedad.
OBJETIVOS
de este documento
Generales
Explicar fácil y gráficamente los pasos a seguir para pode realizar un analizador a partir de
una gramática.
Específicos
Implementar la gramática para los lenguajes ANSI C (C puro), C#, Java y Visual Basic
Caracteres comunes
NOMBRE INSTRUCCION DESCRIPCION
Conocido como Tab, escribe una
Tabulador {HT}
tabulación en la línea.
Se utiliza para bajar una línea en los
Salto de Línea {LF}
documentos
Se usa para saltase a la siguiente línea
Tabulación Vertical {VT}
marcada
Se usa para saltar toda la pantalla por
Limpia pantalla {FF}
ejemplo CLR o clear
Retorno de Carro Sirve retornar el apuntador al inicio de
{CR}
la línea
Espacio {Space} Se utiliza para separar caracteres
Se utiliza para los espacio donde el salto
Espacio sin Romper {NBSP}
de línea no es permitido
Símbolo del Euro {Euro Sign} Representa el símbolo del euro
Conjuntos de Caracteres comunes
NOMBRE INSTRUCCION DESCRIPCION
Numero {Number} Números del 0 al 9.
Esta instrucción es similar a number,
Digito {Digit} recomiendan NO USAR ESTA
INSTRUCCIÓN.
Reconoce una simple letra del alfabeto
Letra {Letter} en minúsculas o mayúsculas no incluye
la ñ.
Es la unión de las instrucciones Letter y
Alfanumérico {AlphaNumeric}
Number.
Reconoce cualquier carácter desde el
Cualquier Carácter {Printable} #32-#127 y #160 (No espacios
quebrados).
Reconoce todas las letra incluyendo los
Letra Extendida {Letter Extended}
caracteres especiales como ñ
Cualquier Carácter Reconoce todos los caracteres arriba del
{Printable Extended}
extendido carácter #127
Espacio en blanco Reconoce los caracteres como espacio,
{Whitespace}
salto de line.
Ejemplo:
!--comentario (parte I)
terminal1 = {Digit}+'.'{Digit}+
!-- define diferentes expresiones regulares para la gramatica
Para mostrar los diferentes usos de que se le pueden dar a GOLD Parser, presentamos 4 lenguajes
de programación, en los cuales damos paso a paso las instrucciones para implementarlo:
ANSI C
C#
JAVA
Visual Basic
ANSI C
Generado por GOLD Parser
GOLD PARSER Y ANSI C
GoldParser es
una
herramienta
que nos
ayuda a crear
un analizador
definiendo
una gramática
con BNF
(Backus-Naur
Form), como
se muestra en
la siguiente
imagen:
Siguiendo la gramática siguiente:
<lenguaje> ::= <Listas>
Para poder realizar las acciones deseadas para esta gramática. Debemos de pasar por 4 pasos en
GOL Parser:
PASO 1: Verificar que la gramática este correcta ( Sin errores léxicos, sintácticos, etc.)
PASO 2: Construir el analizador LALR (Look-Ahead Left Right), verifica que no existan
conflictos de reducción-reducción o desplazamiento-reducción.
Cuando pasamos por el paso 4 vamos a guardar la tabla compilada de nuestra gramática, este lo
vamos a utilizar más adelante
Para verificar que nuestro GCT esta correcto, vamos a comprobarlo con un archivo de entrada por
medio de la herramienta que nos provee GOLD Parser Builder, Le damos Clic en el icono de un
cheque verde (ver figura)
Cuando hayamos hecho lo anterior vamos a ingresar una cadena valida según nuestro lenguaje
para poder probarlo.
Para probar le damos clic en el icono verde que nos permite ir probando paso a paso, la forma en
que va leyendo nuestro archivo la tabla compilada de nuestra gramática, también podemos ir de
un solo al final del análisis ya sea algún error o como esta en este documento VALIDA (Acecept)
Ya que tenemos nuestra Gramática Compilada en Tabla, vamos a proceder a crear un esqueleto
para poderlo utilizar con nuestro lenguaje.
Existen 3 tipos de Motores (Engine) para ANSI C, pero nosotros para mayor facilidad
vamos a utilizar el 3 motor, KESSELS ENGINE, creado por J.C. Kessels
(http://kessels.com/Gold/index.html)
Guardamos el primer archivo .h (no importa el orden .h/.c) que contiene las declaraciones de los
símbolos.
El segundo archivo es el .c, vamos a guardarlo igual que el .h, este archivo contiene un
main por defecto como se verá más adelante
Una vez creados los 2 archivos, le damos clic en “Done” para poder proceder a ingresar las
acciones a nuestra gramática en ANSI C. (ambos archivos deben de estar en el directorio del
proyecto)
Ahora abrimos nuestro archivo *.c con algún compilador o editor para C/C++, en este ejemplo yo
utilizo Borland C++, pero pueden usan VC++.net o VC++ 6, asi como cualquier compilador de Linux
ya que el motor kessels es aceptado por compilador de C para Windows y Linux.
Creando un Nuevo proyecto VC++ 6
Vamos Agregar los archivos que están en esta carpeta el grammar.h y template.c
Dentro de los archivos deben de ir los Engine.h y engine.c que se pueden descargar de la página
del creador de estos motores http://kessels.com/Gold/index.html
Como menciona en la página anterior, ya descargados y descomprimidos solo
queda copiarlos a la carpeta donde tenemos nuestro proyecto y agregarlos.
Ahora vamos a agregar los esqueletos que fueron creados en GOLD Parser Build.
El archivo de gramatica.h tiene un pequeño problema con los caracteres, ya que yo tengo
el sistema español Latino (GUATEMALA) y me da un pequeño error a la hora de generarlo, como
se explica a continuación:
Otro pequeño problema que me tope es que cuando se ha construyendo el .exe se bloquean los
archivos y aparece el siguiente mensaje:
Antes de proceder a Construir vamos a cambiar el archivo de entrada que viene por
default
case (int)SymbolConstants.SYMBOL_NUMERO :
//Numero
return token.Text;
case (int)SymbolConstants.SYMBOL_NUMEROS :
//<numeros>
return token.Text;
case (int)SymbolConstants.SYMBOL_COMMA :
//','
//todo: Create a new object that corresponds to the symbol
return null;
case (int)SymbolConstants.SYMBOL_LBRACE :
//'{'
//todo: Create a new object that corresponds to the symbol
return null;
public static Object CreateObject(NonterminalToken token):
case (int)RuleConstants.RULE_LISTA_LBRACE_RBRACE :
//<lista> ::= '{' <numeros> '}'
//todo: Create a new object using the stored user objects.
return token.Tokens[1].UserObject;
case (int)RuleConstants.RULE_NUMEROS_COMMA_NUMERO :
//<numeros> ::= <numeros> ',' Numero
//todo: Create a new object using the stored user objects.
return null;
Lo que podemos observar allí:
case (int)RuleConstants.RULE_LENGUAJE :
//<lenguaje> ::= <Listas>
Resultado = ordenar((ArrayList)token.Tokens[0].UserObject);
return null;
lista.Sort();
<metodo> ::= <acceso> <tipo> id '(' ')' '{' <cuerpo_m> 'return' <valor> ';' '}'
| <acceso> 'void' id '(' ')' '{' <cuerpo_m>'}'
Nota: Para continuar con este ejemplo el lector debe haber antes estudiado o
tener conocimientos sobre los elementos necesarios para la conexión con C#
y como se unen los mismos (se puede encontrar en el ejemplo 1).
Luego de realizar la unión de los elementos (añadir el parser, las librerías y
definir el archivo *.cgt) vamos a añadir funcionalidad a nuestro parser.
case (int)SymbolConstants.SYMBOL_DOUBLE :
//double
return token.Text;
case (int)SymbolConstants.SYMBOL_ENTERO :
//entero
return token.Text;
case (int)SymbolConstants.SYMBOL_ID :
//id
return token.Text;
case (int)SymbolConstants.SYMBOL_PRIVATE :
//private
return null;
Pero, ¿por que devolvemos null? En nuestro ejemplo devolveremos null por
que el valor ‘private’ es estático, es decir siempre será el mismo, no así
valores infinitos como id, entero, texto, etc. ¿Pero si quisiera podría devolver
el valor? Y la respuesta es de nuevo si, podríamos retornar token.Text y lo
que devolveríamos seria el valor “private”. ¿Por que no lo hacemos? Por que
en nuestra gramática ya “sabemos” que vino private por lo tanto devolver
“private” seria algo redundante.
case (int)RuleConstants.RULE_ACCESO_PRIVATE :
//<acceso> ::= private
return "private";
case (int)RuleConstants.RULE_ACCESO_PROTECTED :
//<acceso> ::= protected
return "protected";
case (int)RuleConstants.RULE_TIPO_STRING :
//<tipo> ::= String
return "String";
case (int)RuleConstants.RULE_TIPO_INT :
//<tipo> ::= int
return "int";
case (int)RuleConstants.RULE_VALOR_TEXTO :
//<valor> ::= texto
return token.Tokens[0].UserObject;
case (int)RuleConstants.RULE_VALOR_ENTERO :
//<valor> ::= entero
return token.Tokens[0].UserObject;
Recordando del ejemplo 1, sabemos que Tokens es un array que contiene los
valores de la producción del lado derecho, indicando Tokens[0].UserObject
obtenemos el valor en la posición 1, el lector podría preguntarse ¿de donde
viene el valor de texto y entero? Esos valores provienen del método 1, donde
retornamos “token.Text”. Ahora veamos la producción <asigna>:
case (int)RuleConstants.RULE_ASIGNA_EQ :
//<asigna> ::= '=' <valor>
return token.Tokens[1].UserObject;
case (int)RuleConstants.RULE_ASIGNA :
//<asigna> ::=
//todo: Create a new object using the stored user
objects.
return null;
Esta producción tiene 2 valores posibles, nulo o <asigna> recibirá el dato
<valor>. La siguiente producción es la definición de una variable, su tipo, su
nombre y el valor asignado.
case (int)RuleConstants.RULE_DEF_VAR_ID_SEMI :
//<def_var> ::= <tipo> id <asigna> ';'
String[] variable = {
(string)token.Tokens[0].UserObject, (string)token.Tokens[1].UserObject,
(string)token.Tokens[2].UserObject };
return variable;
ArrayList aux2 =
(ArrayList)token.Tokens[0].UserObject;
aux2.Add(token.Tokens[1].UserObject);
return aux2;
case (int)RuleConstants.RULE_DEF_VARS2 :
//<def_vars> ::= <def_var>
if (token.Tokens[0].UserObject != null)
{
varaux = new ArrayList();
varaux.Add(token.Tokens[0].UserObject);
return varaux;
}
return null;
Siendo una gramatica recursiva por la izquierda el primer valor reducido sera
<def_vars> à <def_var> por lo tanto aca crearemos un arraylist que ira
agregando las definiciones de las variables. Antes de continuar debemos
realizar una validacion, recordemos que <def_var> puede producir nulo, por
lo mismo verificamos si trae valor y viene con valor nulo. Lo que
retornaremos si trae valor es “varaux” sino trae valor retornaremos nulo.
case (int)RuleConstants.RULE_LENGUAJE :
//<lenguaje> ::= <def_clases>
Resultado = (ArrayList)token.Tokens[0].UserObject;
return null;
v Clase:
1. Acceso
2. Nombre
3. Def_variables o nulo
4. Def_metodos
v Def_variables:
1. Tipo
2. Nombre
3. Valor, puede ser nulo
v Def_metodos:
1. Acceso
2. Tipo
3. nombre
4. variables, puede ser nulo
System.Windows.Forms.MessageBox.Show("Entrada correcta ");
String cadenaR = "";
if (auxclases[2] != null)
{
ArrayList auxvariables = (ArrayList)auxclases[2];
if (auxmetodos2[3] != null)
{
ArrayList auxvariables =
(ArrayList)auxmetodos2[3];
result = cadenaR;
Nota: Las variables Resultado de tipo ArrayList y result de tipo string son
variables globales a la clase.
EXPLICACIÓN DE FUNCIONALIDAD
PASO 1: Se ingresa la definición de clases con variables y métodos y se
presiona. ”Analizar”
Listado de Metodos
Acceso: protected
Listo ya se pueden implementar las acciones necesarias para realizar el análisis de cualquier
lenguaje que obedezca la gramática
Visual Basic
Generado por GOLD Parser
GOLD Parser con VB
En esta parte de la documentación se tratara sobre cómo generar gramáticas
desde GOLD Parser, para luego utilizarlas desde el lenguaje de Visual Basic.
A continuación se da una descripción detallada de los aspectos más
importantes para la generación de una gramática.
El cuarto y último paso es el encargado de guardar tanto las tablas generadas en el paso 2(LALR)
como las tablas generadas en el paso 3(DFA). Estas son guardadas en un archivo con extensión
.cgt.
Procede a realizar los cuatro pasos para la compilación de la gramatica y se guarda las tablas en el
archivo .cgt.
Habiendo compilado la gramática debemos de crear los skeleton que se
usaran en el programa, en este caso se trata de Visual Basic.
Descargar el Motor .NET a utilizar
Archivo GoldParser.dll
Integrantes
Juan J. Cruz 2004-12979
Joel Jimenez 2004-13135
Walter Ajanel 2005-15897
Mariano Sandoval 2007-15303
Jhony Quiem 2008-19401