miércoles, 29 de septiembre de 2010

Implementacion de Gold Parser y Pascal


Empezaremos a ver un pequeño ejemplo de la utilidad de Gold Parser sobre el Lenguaje de Pascal. Lo primero que se construirá será la gramática que va reconocer alguna estructura definida.

Esta sería la gramática que se emplearía, lo que reconoce es un lenguaje parecido al XML.
Al tener construida la gramática se procede a generar el archivo .pas, Gold Parser integra al programa el código necesario para realizar el análisis, por lo que no es necesario agregar otros módulos. El código que se genera puede ser compilado en cualquier compilador de Pascal.
Nos ubicamos en el Menú de Gold Parser  y en la parte de Project seleccionamos la opción Create a Skeleton Program… para generar el archivo que contendrá los módulos necesarios para realizar el parseo.
Seleccionamos Pascal – inline Engine V1.0. El programa resultante podrá leer un archivo de entrada esta se podrá especificar desde consola, así mismo se le puede especificar la ubicación del archivo de salida.
El motor de análisis de Gold Parser se basara en la plantilla PGT que tendrá definida la manera de realizar el parseo, las capacidades de PGT para la emisión del código son suficientes para realizar un análisis optimo.
Estructura del archivo generado
El programa llama al analizador a través de TParser.DoParser.

Esta es una rutina que en combinación con PGT realiza el análisis. 
Las acciones que se requieran pueden ser definidas en las rutinas que a continuación se describen:

TParser.DoAction, aquí se colocara alguna operación que se desee al momento de estar analizando.

Procedure TParser.DoAction (T:PTokenList; RuleNr,TokenCnt:Integer);

En esta parte se agregan los símbolos a una estructura que definirá cada valor que será leído.

Type  TParseEdge= procedure(T:PTokenList; S:PParser);

const ActionTable: array [0..112] of Pointer  =
((@TParser.Action_CONSTANT_DECLITERAL),   
 (@TParser.Action_CONSTANT_STRINGLITERAL),
 (@TParser.Action_CONSTANT_FLOATLITERAL), 
. . . );

begin
  if TokenCnt>0 then
  TParseEdge(ActionTable[RuleNr])(T, @Self);
end {DoAction};

TLexer.DoError, para el manejo de los errores se utiliza la rutina DoError, especificando en que línea y columna ha sido reportado el error.

Procedure TLexer.DoError(ErrorNr:Integer; TokenPtr:PToken);
begin
case ErrorNr of
  Err_StackOverflow: 
   begin
    writeln(Fe^,'Syntax Error: Overflow of parse stack at');
 writeln(Fe^,'Pos(',Token.LinePos:1,':',Token.CharPos:1,')=',Tab,Token.Tag,Tab,'"',LexemeStr,'"');
     end;
end;

TParser.DoCleanup, se utiliza para liberar la memoria.

Procedure TParser.DoCleanup(TokenPtr:PToken);
begin
end; 

TParser.DoAccept, esta rutina indica que el flujo de entrada ha sido analizado satisfactoriamente.

Procedure TParser.DoAccept(TokenPtr:PToken);
begin
  writeln('input has been parsed succesfuly');
end;

Cuando el analizador llama a TLexer.GetToken, está llamando a TLexer.GetLexeme que lee la entrada que se esta parseando.
En la mayoría de los casos TLexer.GetToken sólo construye un símbolo de ese lexema.

Cuando el tokenizer llama al analizador léxico en TLexer.GetLexeme, llama TLexer.GetChar.

Cuando el analizador léxico llama al lector de caracteres TLexer.GetChar este llama TScanner.Get y realiza un proceso como el número de línea y la posición de la fila del carácter.

Una vez que el código de Pascal se ha creado, se puede controlar el tipo de salida.

Esta rutina tendrá como parámetro el ingreso de un Path, donde posteriormente cuando se este ejecutando la aplicación se le colocara el archivo de entrada.

constructor TScanner.Init(FileName:String);
begin
  assign(Fi,FileName);
  reset(Fi);
  CurChar:=#0;
  NextChar:=#0;
  Get;
end;

Un ejemplo de lo que la gramática reconoce es lo siguiente:

<Ejemplo>
    <Usuario> Estuardo Zapeta </Usuario>
    <Password> Admin </Password>
    <Contenido>
         <Ocupacion> Estudiante </Ocupuacion>
         <Edad> 22 </Edad>
    </Contenido>
</Ejemplo>

Y la salida sería la siguiente:

Token(1:1):  Tag=56   : "<"
Token(1:14): Tag=49   : "Ejemplo"
Token(1:17): Tag=16   : ">"
...

No hay comentarios:

Publicar un comentario