Sebagai latihan, saya menulis parser untuk Haskell dari awal. Dalam membuat lexer, saya perhatikan aturan berikut pada Laporan Haskell 2010 :
digit → ascDigit | uniDigit
ascDigit →0
|1
| … |9
uniDigit → setiap Unicode desimal digit
octit →0
|1
| … |7
hexit → digit |A
| … |F
|a
| … |f
desimal → digit { digit }
oktal → oktit { oktit }
heksadesimal → hexit { heksit }integer → desimal |
0o
oktal |0O
oktal |0x
heksadesimal |0X
hexadecimal
float → desimal.
desimal [ eksponen ] | eksponen
eksponen desimal → (e
|E
) [+
|-
] desimal
Literal desimal dan heksadesimal, bersama dengan float literals, semuanya didasarkan pada digit , yang menerima digit desimal Unicode, alih-alih ascDigit , yang hanya menerima digit dasar 0-9 dari ASCII. Anehnya, oktal didasarkan pada octit , yang sebaliknya hanya mengakui angka ASCII 0-7. Saya akan menebak bahwa ini "Unicode desimal digit" s adalah setiap codepoint Unicode dengan Kategori Umum "Nd". Namun, ini termasuk karakter seperti digit Lebar Penuh 0-9 dan angka Devanagari ०-९. Saya dapat melihat mengapa mungkin diinginkan untuk memungkinkan ini dalam pengidentifikasi, tetapi saya tidak dapat melihat manfaat apa pun untuk membiarkan seseorang menulis ९0
untuk literal 90
.
GHC tampaknya setuju dengan saya. Ketika saya mencoba mengkompilasi file ini,
module DigitTest where
x1 = 1
itu memuntahkan kesalahan ini.
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
Namun, file ini
module DigitTest where
x1 = 1
mengkompilasi dengan baik. Apakah saya salah membaca spesifikasi bahasa? Apakah perilaku (masuk akal) GHC benar, atau apakah secara teknis bertentangan dengan spesifikasi dalam Laporan? Saya tidak dapat menemukan ini di mana pun.
sumber
Jawaban:
Di file kode sumber GHC
compiler/parser/Lexer.x
, Anda dapat menemukan kode berikut:Di sini,
$decdigit
digunakan untuk parsing desimal dan heksadesimal (dan varian floating point mereka), sementara$digit
digunakan untuk bagian "numerik" pengidentifikasi alfanumerik. Catatan "ToDo" memperjelas bahwa ini adalah penyimpangan GHC yang diakui dari standar bahasa.Jadi, Anda membaca spek dengan benar, dan GHC secara sengaja melanggar spek. Ada tiket terbuka yang menyarankan setidaknya mendokumentasikan penyimpangan, tetapi saya tidak berpikir ada orang yang menyatakan minat untuk memperbaikinya.
sumber