Come esercizio, scrivo da zero un parser per Haskell. Nel realizzare il lexer, ho notato le seguenti regole sul Rapporto Haskell 2010 :
cifra → ascDigit | uniDigit
ascDigit →0|1| ... |9
uniDigit → qualsiasi Unicode decimale cifre
octit →0|1| ... |7
esadecimale → cifra |A| ... |F|a| ... |fdecimale → cifra { cifra }
ottale → ottit { octit }
esadecimale → hexit { hexit }intero → decimale |
0oottale |0Oottale |0xesadecimale | float0Xesadecimale → decimale decimale [ esponente ] | decimale esponente esponente → ( | ) [ | ] decimale
.
eE+-
I letterali decimali ed esadecimali, insieme ai letterali float, sono tutti basati su digit , che ammette qualsiasi cifra decimale Unicode, anziché ascDigit , che ammette solo le cifre di base 0-9 da ASCII. Stranamente, l' ottale si basa su ottit , che invece ammette solo le cifre ASCII 0-7. Immagino che queste "cifre decimali Unicode" siano punti di codice Unicode con la categoria generale "Nd". Tuttavia, questo include caratteri come le cifre a larghezza intera 0-9 e i numeri Devanagari ०-९. Posso capire perché potrebbe essere desiderabile consentirli negli identificatori, ma non vedo alcun beneficio nel consentire a uno di scrivere ९0per il letterale 90.
GHC sembra essere d'accordo con me. Quando provo a compilare questo file,
module DigitTest where
x1 = 1
sputa questo errore.
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
Tuttavia, questo file
module DigitTest where
x1 = 1
compila bene. Sto leggendo le specifiche della lingua in modo errato? Il comportamento (sensibile) di GHC è effettivamente corretto o è tecnicamente contrario alle specifiche del Rapporto? Non riesco a trovare alcuna menzione di questo da nessuna parte.