Flex no es compatible con Unicode. Sin embargo, Flex admite entrada binaria "8 bit clean". Por lo tanto, puede escribir patrones léxicos que coincidan con UTF-8. Puede utilizar estos patrones en áreas léxicas específicas del idioma de entrada, por ejemplo, identificadores, comentarios o literales de cadenas.
Esto funcionará bien en los lenguajes de programación típicos, donde puede afirmar a los usuarios de su implementación que el idioma de origen está escrito en ASCII/UTF-8 (y no se admite ninguna otra codificación, punto).
Este enfoque no funcionará si el escáner debe procesar texto que puede estar en cualquier codificación. Tampoco funcionará (muy bien) si necesita expresar reglas léxicas específicamente para elementos Unicode. Es decir. necesita caracteres Unicode y expresiones regulares Unicode en el propio escáner.
La idea es que se puede reconocer un patrón que incluye bytes UTF-8 utilizando una regla lex, (y tal vez tomar la yytext
, y convertirlo de UTF-8 o al menos validarlo.)
para un ejemplo de trabajo, ver el código fuente de la lengua TXR, en particular, este archivo: http://www.kylheku.com/cgit/txr/tree/parser.l
de desplazamiento hacia abajo para esta sección:
ASC [\x00-\x7f]
ASCN [\x00-\t\v-\x7f]
U [\x80-\xbf]
U2 [\xc2-\xdf]
U3 [\xe0-\xef]
U4 [\xf0-\xf4]
UANY {ASC}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
UANYN {ASCN}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
Como se puede ver, podemos definir patrones para que coincida con ASCII Characte rs así como los bytes de inicio y continuación UTF-8. UTF-8 es una notación léxica, y este es un generador de analizador léxico, así que ... ¡no hay problema!
Algunas explicaciones: El UANY
significa que coincide con cualquier carácter, ASCII de un byte o UTF-8 de varios bytes. UANYN
significa como UANY
pero no coincide con la nueva línea. Esto es útil para tokens que no se dividen en líneas, como por ejemplo un comentario de #
hasta el final de la línea, que contiene texto internacional.UONLY
significa que solo coincide con un carácter extendido UTF-8, no uno ASCII. Esto es útil para escribir una regla de lex que necesita excluir ciertos caracteres ASCII específicos (no solo la línea nueva), pero todos los caracteres extendidos están bien.
Exención de responsabilidad: Tenga en cuenta que las reglas del analizador utilizan una función llamada utf8_dup_from
para convertir el yytext
a cadenas de caracteres anchos que contienen puntos de código Unicode. Esa función es robusta; detecta problemas como secuencias excesivas y bytes no válidos y los maneja adecuadamente. Es decir. este programa no se basa en estas reglas lex para hacer la validación y la conversión, solo para hacer el reconocimiento léxico básico. Estas reglas reconocerán una forma demasiado larga (como un código ASCII codificado utilizando varios bytes) como sintaxis válida, pero la función de conversión las tratará adecuadamente. En cualquier caso, no espero problemas de seguridad relacionados con UTF-8 en el código fuente del programa, ya que tiene que confiar en que el código fuente se ejecutará de todos modos (¡pero los datos manejados por el programa pueden no ser confiables!) escribiendo un escáner para datos UTF-8 que no son de confianza, ¡ten cuidado!
¿Más sugerencias sobre la solución? – xiaohan2012
Copié mi respuesta de la lista de correo a la respuesta. –
Gracias. ¡Parece inspirarme mucho! – xiaohan2012