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.