31 marzo 2008

Un compilador sencillo paso a paso (5)

En el quinto acercamiento vamos a reconocer una estructura algo más parecida a un fuente "real" en pascal, que comience con "program" y tenga un cuerpo de programa delimitado ente "begin" y "end", incluso con espacios en blanco, como ésta:


program ej;
begin
 cls;
 locate(10,5);
 writeChar( 'a' );
 locate ( 1 , 10 );
 writeChar('c');
end.


Esto supone dos cambios:


  • Vamos a sacar del cuerpo del programa lo que será el "analizador
    sintáctico", el encargado de indicar en qué orden deben estar los
    elementos del programa (por ejemplo: después de "program" debe aparecer
    un identificador y un punto y coma, luego "begin" y una secuencia
    de órdenes, etc).

  • Ampliaremos un poco el analizador léxico para que sea capaz
    de "saltarse" los espacios en blanco.



En cuanto al "analizador sintáctico", simplemente ampliamos el anterior "analizarCualquierOrden", que ahora estará dentro de un "analizarPrograma", que se asegura de que antes aparezca program, begin, etc, así:


procedure analizarPrograma;
begin
(* program <identificador>; *)
orden := upcase(obtenerIdentificador);
if orden <> 'PROGRAM' then
begin
writeln('No se ha encontrado PROGRAM');
halt;
end;
obtenerIdentificador;
leerSimbolo(';');

(* begin *)
orden := upcase(obtenerIdentificador);
if orden <> 'BEGIN' then
begin
writeln('No se ha encontrado BEGIN');
halt;
end;

(* Resto de ordenes *)
while not finFicheroEntrada do
begin
analizarCualquierOrden;
end;
end;



Por lo que respecta al analizador léxico, cada vez que vayamos a leer un identificador, un entero o a esperar un símbolo concreto, deberemos antes saltar los espacios en blanco que pudiera haber:


function obtenerIdentificador: string;
var
lexema: string;
letra: char;
begin
saltarBlancos;
lexema := '';
letra := obtenerLetra;
[...]

procedure saltarBlancos;
begin
while (lineaDeEntrada[posicionLineaActual+1] in espacioBlanco) do
obtenerLetra;
end;

espacioBlanco: set of char = [chr(32), chr(10), chr(13)];


Para más detalles, todo el código está en la página del proyecto en Google Code:

http://code.google.com/p/cpcpachi/