Veamos el funcionamiento de un analizador léxico (también llamado Scanner)
Tomemos una expresión de ejemplo:
INPUT : cout << 3+2+3;
FORMATTING PERFORMED BY SCANNER : {cout}|space|{<<}|space|{3}{+}{2}{+}{3}{;}
aunque no la salida real.
EL ESCÁNER SIMPLEMENTE BUSCA REPETIDAMENTE UN LEXEME EN EL TEXTO DEL PROGRAMA FUENTE HASTA QUE SE AGOTE LA ENTRADA
Lexeme es una subcadena de entrada que forma una cadena de terminales válida presente en la gramática. Cada lexema sigue un patrón que se explica al final (la parte que el lector puede omitir al final)
(La regla importante es buscar el prefijo más largo posible que forme una cadena de terminales válida hasta que se encuentre el siguiente espacio en blanco ... explicado a continuación)
LEXEMES:
- cout
- <<
(aunque "<" también es una cadena de terminal válida, pero la regla mencionada anteriormente debe seleccionar el patrón para el lexema "<<" para generar el token devuelto por el escáner)
- 3
- +
- 2
- ;
TOKENS: Los tokens se devuelven uno a la vez (por el escáner cuando el analizador lo solicita) cada vez que el escáner encuentra un lexema (válido). El escáner crea, si aún no está presente, una entrada de tabla de símbolos (que tiene atributos: principalmente categoría de token y algunos otros) , cuando encuentra un lexema, para generar su token
'#' denota una entrada de tabla de símbolos. He señalado el número de lexema en la lista anterior para facilitar la comprensión, pero técnicamente debería ser un índice real de registro en la tabla de símbolos.
El analizador devuelve los siguientes tokens al analizador en el orden especificado para el ejemplo anterior.
<identificador, n.º 1>
<Operador, n.º 2>
<Literal, n.º 3>
<Operador, n.º 4>
<Literal, n.º 5>
<Operador, n.º 4>
<Literal, n.º 3>
<Puntuacionador, # 6>
Como puede ver la diferencia, un token es un par a diferencia del lexema, que es una subcadena de entrada.
Y el primer elemento del par es la clase / categoría de token
Las clases de tokens se enumeran a continuación:
PALABRAS CLAVE
IDENTIFICADORES
LITERALES
PUNTUADORES
OPERADORES
Y una cosa más, Scanner detecta espacios en blanco, los ignora y no forma ningún token para un espacio en blanco. No todos los delimitadores son espacios en blanco, un espacio en blanco es una forma de delimitador que utilizan los escáneres para su propósito. Las pestañas, las líneas nuevas, los espacios, los caracteres de escape en la entrada se denominan colectivamente delimitadores de espacios en blanco. Pocos otros delimitadores son ';' ',' ':' etc, que son ampliamente reconocidos como lexemas que forman token.
El número total de tokens devueltos es 8 aquí, sin embargo, solo se hacen 6 entradas de tabla de símbolos para lexemas. Los lexemas también son 8 en total (ver definición de lexema)
--- Puedes saltarte esta parte
A ***pattern*** is a rule ( say, a regular expression ) that is used to check if a string-of-terminals is valid or not
.
If a substring of input composed only of grammar terminals is
following the rule specified by any of the listed patterns , it is
validated as a lexeme and selected pattern will identify the category
of lexeme, else a lexical error is reported due to either (i) not
following any of the rules or (ii) input consists of a bad
terminal-character not present in grammar itself.
for example :
1. No Pattern Exists : In C++ , "99Id_Var" is grammar-supported string-of-terminals but is not recognised by any of patterns hence lexical error is reported .
2. Bad Input Character : $,@,unicode characters may not be supported as a valid character in few programming languages.`