Ejemplo 210

Enunciado

Hacer el analizador léxico del siguiente lenguaje usando ANTLR.

edad = 65;	 # Comentario de una línea
print a
read b;
print "fin"

Notas:

  • Los identificadores empiezan sólo por letras (mayúsculas y minúsculas) y a continuación pueden ser, además, dígitos.
  • Los comentarios son de una sola línea. Hacer dos versiones de los comentarios: una utilizando algún operador non-greedy y otra sin usarlos.
  • Los literales de string (delimitados por comillas), no pueden abarcar más de una línea.

Nótese que dos de las sentencias del ejemplo anterior no acaban en punto y coma. Esto, que aparentemente sería un error, no es asunto del léxico, que se limitará a indicar los tokens que encuentre. Si estos están desordenados o falta alguno será detectado por la siguiente fase, el analizador sintáctico.

Solución

Especificación del léxico en ANTLR.

lexer grammar Lexicon;

IGUAL : '=';
PCOMA : ';';

PRINT : 'print';
READ : 'read';

LITENT : [0-9]+;
IDENT : [a-zA-Z][a-zA-Z0-9]*;

// OJO: Son comillas dobles entre comillas simples ' " '
STRING : '"' (~[\r\n"])* '"';

// Versión con operador 'non-greedy'
COMENTARIO : '#' .*? '\n' -> skip;

WS : [ \t\r\n]+ -> skip;

Pregunta

⏳ Si se hubieran definido las literales de cadenas como:

STRING: '"' .*?  '"' ;`

¿Por qué no hubiera sido correcto? Pensar qué hubiera hecho ante una entrada como la siguiente:

print "hola
 a todos";

La versión del comentario sin utilizar el operador non-greedy sería:

// Versión sin usar operador 'non-greedy'
COMENTARIO : '#' ~[\r\n]* -> skip;

Ahora, solo quedaría pasar esta especificación por la herramienta para obtener la implementación del analizador léxico.

Código

💿 Se puede bajar el proyecto Java con todo lo necesario para poder ejecutar la solución de este ejemplo y así poder ver su resultado y probar otras alternativas.