Como ejercicio, estoy escribiendo un analizador para Haskell desde cero. Al hacer el lexer, noté las siguientes reglas en el Informe Haskell 2010 :
dígito → ascDigit | uniDigit
ascDigit →0
|1
El | ... |9
uniDigit → cualquier dígito decimal Unicode
octit →0
|1
El | ... |7
hexit → dígito |A
El | ... |F
El |a
El | ... |f
decimal → dígito { dígito }
octal → octit { octit }
hexadecimal → hexit { hexit }entero → decimal |
0o
octal |0O
octal |0x
hexadecimal | flotante0X
hexadecimal → decimal decimal [ exponente ] | decimal exponente exponente → ( | ) [ | ] decimal
.
e
E
+
-
Los literales decimales y hexadecimales, junto con los literales flotantes, se basan en dígitos , que admiten cualquier dígito decimal Unicode, en lugar de ascDigit , que admite solo los dígitos básicos 0-9 de ASCII. Curiosamente, octal se basa en octit , que en cambio solo admite los dígitos ASCII 0-7. Supongo que estos "dígitos decimales Unicode" son puntos de código Unicode con la categoría general "Nd". Sin embargo, esto incluye caracteres como los dígitos de ancho completo 0-9 y los números de Devanagari ०-९. Puedo ver por qué sería deseable permitir estos en los identificadores, pero no veo ningún beneficio por permitir que uno escriba ९0
para el literal 90
.
GHC parece estar de acuerdo conmigo. Cuando intento compilar este archivo,
module DigitTest where
x1 = 1
escupe este error.
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
Sin embargo, este archivo
module DigitTest where
x1 = 1
compila muy bien. ¿Estoy leyendo la especificación del idioma incorrectamente? ¿Es correcto el comportamiento (sensible) de GHC, o técnicamente va en contra de la especificación en el Informe? No puedo encontrar ninguna mención de esto en ningún lado.
fuente
Respuestas:
En el archivo de código fuente de GHC
compiler/parser/Lexer.x
, puede encontrar el siguiente código:Aquí,
$decdigit
se usa para analizar literales decimales y hexadecimales (y sus variantes de coma flotante), mientras que$digit
se usa para la parte "numérica" de los identificadores alfanuméricos. La nota "ToDo" deja en claro que esta es una desviación reconocida de GHC del estándar de idioma.Entonces, está leyendo la especificación correctamente, y GHC está violando la especificación de forma semi intencional. Hay un boleto abierto que sugiere al menos documentar la desviación, pero no creo que nadie haya expresado ningún interés en solucionarlo.
fuente