Un parser Haskell dovrebbe consentire cifre Unicode in letterali numerici?


15

Come esercizio, scrivo da zero un parser per Haskell. Nel realizzare il lexer, ho notato le seguenti regole sul Rapporto Haskell 2010 :

cifraascDigit | uniDigit
ascDigit0| 1| ... | 9
uniDigit → qualsiasi Unicode decimale cifre
octit0| 1| ... | 7
esadecimalecifra | A| ... | F| a| ... |f

decimalecifra { cifra }
ottaleottit { octit }
esadecimalehexit { hexit }

interodecimale | 0o ottale | 0O ottale | 0x esadecimale | float 0X esadecimaledecimale 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 = 

sputa questo errore.

digitTest1.hs:2:6: error: lexical error at character '\65297'
  |
2 | x1 = 
  |      ^

Tuttavia, questo file

module DigitTest where
x = 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.


4
Divertente. Ho il sospetto che questo sia avvenuto in qualcosa del tipo "Ok, quindi i letterali consistono solo in cifre ASCII, facile." "Non aspettare, pensiamo all'internazionalizzazione, Unicode ... hanno anche altri simboli numerici, giusto?" "Oh sì, eh, non ci siamo mai occupati di questo ... ma ok, inseriamo una clausola per quello ..." "Fantastico." ... e poi è stato appena dimenticato e nessuno si è davvero preoccupato di implementarlo, o ha notato che non ha senso permettere di mescolare diverse famiglie di cifre.
lasciato circa il

Yikes. Sì, non preoccuparti di questo.
Boann,

Risposte:


8

Nel file di codice sorgente GHC compiler/parser/Lexer.x, è possibile trovare il seguente codice:

ascdigit  = 0-9
$unidigit  = \x03 -- Trick Alex into handling Unicode. See [Unicode in Alex].
$decdigit  = $ascdigit -- for now, should really be $digit (ToDo)
$digit     = [$ascdigit $unidigit]
...
$binit     = 0-1
$octit     = 0-7
$hexit     = [$decdigit A-F a-f]
...
@numspc       = _*                   -- numeric spacer (#14473)
@decimal      = $decdigit(@numspc $decdigit)*
@binary       = $binit(@numspc $binit)*
@octal        = $octit(@numspc $octit)*
@hexadecimal  = $hexit(@numspc $hexit)*
@exponent     = @numspc [eE] [\-\+]? @decimal
@bin_exponent = @numspc [pP] [\-\+]? @decimal

Qui, $decdigitviene utilizzato per l'analisi dei letterali decimali ed esadecimali (e le loro varianti in virgola mobile), mentre $digitviene utilizzato per la parte "numerica" ​​degli identificatori alfanumerici. La nota "ToDo" chiarisce che si tratta di una deviazione riconosciuta di GHC dallo standard linguistico.

Quindi, stai leggendo le specifiche correttamente e GHC sta violando semi-intenzionalmente le specifiche. C'è un biglietto aperto che suggerisce almeno di documentare la deviazione, ma non credo che nessuno abbia espresso alcun interesse a risolverlo.


Tutte e tre le deviazioni elencate sono abbastanza ragionevoli. Vedo perché non c'è una richiesta per "ripararli".
Ian Scherer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.