JavaCUP - Análisis Léxico

Analizador Léxico

En los parsers CUP 0.10j es posible incorporar analizadores léxicos, también llamados scanners, generados automáticamente por JLex u otros generadores de analizadores léxicos que generen código Java.

Para poder utilizar el código nuevo, el analizador léxico debería implementar la interface java_cup.runtime.Scanner, definida como sigue:

package java_cup.runtime;

public interface Scanner {
    public Symbol next_token() throws java.lang.Exception;
}

Además de contar con los métodos para la personalización del parser, la clase java_cup.runtime.lr_parser tiene dos métodos accesorios, setScanner() y getScanner(). la implementación por defecto de scan()es:

  public Symbol scan() throws java.lang.Exception {
    return getScanner().next_token();
  }

El parser generado también contiene un constructor que toma un Scanner e invoca setScanner() con él como parámetro. En la mayoría de los casos, las directivas init with y scan with pueden omitirse, simplemente creando el parser con una referencia al scanner deseado:

      /* creación de un objeto de parsing */
      parser parser_obj = new parser(new my_scanner());

o setear el scanner luego de crear el parser:

      /* creación de un objeto de parsing */
      parser parser_obj = new parser();
      /* seteo del scanner por defecto */
      parser_obj.setScanner(new my_scanner());

Para lograr la integración de un scanner predefinido, deben incluirse las siguientes tres líneas en la especificación del scanner, y constituyen todo lo que se requiere para utilizar un scanner JLex con CUP:

%implements java_cup.runtime.Scanner
%function next_token
%type java_cup.runtime.Symbol

Estas tres directivas pueden abreviarse con una única directiva:

%cup

La invocación del parser con el es scanner JLex es simplemente:

parser parser_obj = new parser( new Yylex(some_InputStream_or_Reader));

Debe notarse que aún debe manejarse el EOF de manera correcta. El código JLex realiza algo similar a lo siguiente:

%eofval{
  return sym.EOF;
%eofval}

donde sym es la misma clase del parser generado.