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.