Como exercício, estou escrevendo um analisador para Haskell do zero. Ao fazer o lexer, observei as seguintes regras no Relatório Haskell 2010 :
dígito → ascDigit | uniDigit
ascDigit →0
|1
| ...9
uniDigit → qualquer dígito decimal Unicode
octit →0
|1
| ...7
hexágono → dígito |A
| ...F
|a
| ...f
decimal → dígito { dígito }
octal → octit { octit }
hexadecimal → hexit { hexit }número inteiro → decimal |
0o
octal |0O
octal |0x
hexadecimal | flutuação0X
hexadecimal → decimal decimal [ expoente ] | decimal expoente expoente → ( | ) [ | ] decimal
.
e
E
+
-
Literais decimais e hexadecimais, junto com literais flutuantes, são todos baseados em dígitos , que admitem qualquer dígito decimal Unicode, em vez de ascDigit , que admite apenas os dígitos básicos de 0 a 9 do ASCII. Estranhamente, octal é baseado em octit , que em vez disso apenas admite os dígitos ASCII de 0 a 7. Eu acho que esses "dígitos decimais Unicode" são quaisquer pontos de código Unicode com a categoria geral "Nd". No entanto, isso inclui caracteres como os dígitos de largura total 0-9 e os números de Devanagari ०-९. Percebo por que seria desejável permitir isso nos identificadores, mas não vejo nenhum benefício em permitir que se escreva ९0
para o literal 90
.
O GHC parece concordar comigo. Quando tento compilar este arquivo,
module DigitTest where
x1 = 1
cospe esse erro.
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
No entanto, esse arquivo
module DigitTest where
x1 = 1
compila muito bem. Estou lendo a especificação do idioma incorretamente? O comportamento (sensato) do GHC é realmente correto ou tecnicamente vai contra a especificação do relatório? Não encontro menção a isso em lugar nenhum.