parsing lexer tokenize

parsing - ¿Es trabajo de Lexer analizar números y cadenas?



tokenize (3)

¿Es un trabajo de Lexer analizar números y cadenas?

Esto puede parecer tonto o no, dado el hecho de que estoy preguntando si un lexer debería analizar la entrada. Sin embargo, no estoy seguro de si ese es, de hecho, el trabajo del analizador o el del analizador, porque para poder leer correctamente, el analizador necesita analizar la cadena / número en primer lugar , por lo que parecería que el código se duplicaría si el analizador hace esto

¿Es de hecho el trabajo de Lexer? ¿O debería el lexer simplemente dividir una cadena como 123.456 en las cadenas 123 123.456 , 456 y deja que el analizador descubra el resto? Hacer esto no sería tan sencillo con cadenas ...


La respuesta simple es "Sí".

En abstracto, no necesitas léxers en absoluto. Simplemente podría escribir una gramática que utilizara caracteres individuales como tokens (y de hecho eso es exactamente lo que hacen los analizadores SGLR, pero esa es una historia para otro día).

Necesita lexers porque los analizadores creados utilizando caracteres como elementos primitivos no son tan eficientes como los analizadores que dividen la secuencia de entrada en "tokens", donde tokens son los elementos primitivos del lenguaje que está analizando (espacios en blanco, palabras clave, identificadores, números, operadores , cuerdas, comentarios, ...). [Si no le importa la eficiencia, puede omitir el resto de esta respuesta e ir a leer sobre los analizadores SGLR].

Los buenos lexers normalmente toman conjuntos de expresiones regulares que representan los elementos del lenguaje y los compilan en una máquina de estados finita eficiente que puede segmentar la secuencia de entrada en dichos elementos de lenguaje rápidamente. (Si no desea utilizar un generador lexer, para los idiomas simples puede codificar el FSA). Tales FSA compilados ejecutan solo unas pocas decenas de instrucciones de la máquina por carácter de entrada (obtienen el carácter del búfer de entrada, activan el carácter a nuevo, deciden si token está completo, si no lo hacen de nuevo), y por lo tanto pueden ser extremadamente rápidos.

La salida de tales lexers es típicamente un código que representa el elemento de idioma (o nada para espacios en blanco si el analizador lo ignora de todos modos) y alguna información de posición (comienza en el archivo foo, línea 17 columna 3) para permitir el informe de errores.

Uno puede detenerse allí y tener lexers útiles. A menudo es útil hacer un paso de conversión, que convierte la cadena de caracteres en el valor de máquina nativa equivalente para ese token, ya sea cuando se recopilan los caracteres o cuando se completa el token, porque uno todavía tiene conocimiento de los caracteres específicos implicados en el token Esto se usa para convertir números (de radixes variables) en el idioma destino a su equivalente binario nativo, para convertir cadenas literales que contienen secuencias de escape en los caracteres reales que componen la cadena, e incluso tomar nombres de identificación y buscarlos en una tabla hash de modo que identificadores idénticos se determinan fácilmente. El analizador generalmente no está interesado en estos valores convertidos, pero los pasos más allá del análisis sintáctico (análisis semántico, comprobación de optimizaciones, generación de código) necesitan los valores convertidos de todos modos, por lo que también podría convertirlos a medida que los descubra. (Podría retrasar esta conversión hasta que se necesite su valor binario, pero en la práctica casi siempre necesita el valor, por lo que demorar la conversión no es muy caro).


Supongo que quieres tratar "123.456" como un valor total, en cuyo caso lo pasarás al analizador, a menos que necesites codificarlo de alguna manera, como

struct DecimalRep{ double mantissa, double exponent }

pero supongo que todo depende de lo que el analizador espera.


Un lector esencialmente identifica TOKENs de la entrada. En este caso, el lexer posiblemente "emparejará" el número como un número flotante TOKEN. El analizador esencialmente procesa tokens y realiza análisis de sintaxis