Estoy escribiendo un analizador para un lenguaje de marcado que he creado (escribiendo en python, pero eso no es realmente relevante para esta pregunta; de hecho, si parece una mala idea, me encantaría una sugerencia para una mejor camino).
Estoy leyendo sobre analizadores aquí: enlace , y estoy trabajando en escribir el lexer que debería , si entiendo correctamente, divide el contenido en tokens. Lo que tengo problemas para entender es qué tipos de token debo usar o cómo crearlos. Por ejemplo, los tipos de token en el ejemplo que vinculé son:
- STRING
- IDENTIFICADOR
- NÚMERO
- ESPACIO BLANCO
- COMENTARIO
- EOF
- Muchos símbolos como {y (cuentan como su propio tipo de token
El problema que tengo es que los tipos de token más generales me parecen un poco arbitrarios. Por ejemplo, ¿por qué es STRING su propio tipo de token separado vs. IDENTIFICADOR? Una cadena podría representarse como STRING_START + (IDENTIFIER | WHITESPACE) + STRING_START.
Esto también puede tener que ver con las dificultades de mi idioma. Por ejemplo, las declaraciones de variables se escriben como {var-name var value}
y se implementan con {var-name}
. Parece que '{'
y '}'
deberían ser sus propios tokens, pero ¿son VAR_NAME y VAR_VALUE tipos de tokens elegibles, o ambos estarían bajo IDENTIFICADOR? Lo que es más es que VAR_VALUE puede contener espacios en blanco. El espacio en blanco después de var-name
se usa para indicar el inicio del valor en la declaración. Cualquier otro espacio en blanco es parte del valor. ¿Este espacio en blanco se convierte en su propio token? El espacio en blanco solo tiene ese significado en este contexto. Además, {
puede no ser el inicio de una declaración de variable ... depende del contexto (¡hay otra palabra!). {:
inicia una declaración de nombre, y {
incluso puede usarse como parte de algún valor.
Mi lenguaje es similar a Python en que los bloques se crean con sangría. Estaba leyendo acerca de cómo Python usa el lexer para crear tokens INDENT y DEDENT (que sirven más o menos como lo que {
y }
harían en muchos otros idiomas). Python afirma que está libre de contexto, lo que significa para mí que al menos el lexer no debería preocuparse por dónde se encuentra en la secuencia al crear tokens. ¿Cómo sabe Python's lexer que está creando un token de INDENT de una longitud específica sin saber sobre los caracteres anteriores (por ejemplo, que la línea anterior era una nueva línea, así que comienza a crear los espacios para INDENT)? Lo pregunto porque también necesito saber esto.
Mi última pregunta es la más estúpida: ¿por qué es incluso necesario un lexer? Me parece que el analizador podría ir carácter por personaje y averiguar dónde está y qué espera. ¿El lexer agrega el beneficio de la simplicidad?