Haskell ayrıştırıcısı, sayısal değişmez değerlerdeki Unicode basamaklarına izin vermeli mi?


15

Bir alıştırma olarak, Haskell için sıfırdan bir ayrıştırıcı yazıyorum. Lexer'ı hazırlarken Haskell 2010 Raporunda aşağıdaki kuralları fark ettim :

basamakascDigit | uniDigit
ascDigit0| 1| … | 9
uniDigit → herhangi bir Unicode ondalık basamaklı
oktit0| 1| … | 7
hexitbasamak | A| … |F| a| … |f

ondalıkhaneli { haneli }
sekizlikoctit { octit }
onaltılıkHexit { Hexit }

tamsayıondalık | 0o sekizli | 0O sekizli | 0x onaltılı | 0X onaltılık
yüzerondalık . ondalık [ üs ] | ondalık üs
üs → ( e| E) [ +| -] ondalık

Ondalık ve şamandıra değişmezleri ile birlikte onaltılık sabitler, tüm dayanmaktadır rakam yerine, herhangi bir Unicode ondalık rakamı kabul ettiği ascDigit sadece temel rakam ASCII 0-9 itiraf. Garip bir şekilde, sekizli , sadece ASCII basamaklarını 0-7 kabul eden oktit üzerine kuruludur . Bu "Unicode ondalık basamak" ın "Nd" Genel Kategori ile herhangi bir Unicode kod noktaları olduğunu tahmin ediyorum. Bununla birlikte, Tam Genişlik 0- dig basamakları ve Devanagari ०-९ rakamları gibi karakterler de buna dahildir. Bunlara tanımlayıcılarda izin verilmesinin neden istenebileceğini anlayabiliyorum, ancak bir ९0kişinin hazır bilgi için yazmasına izin vermenin hiçbir faydasını göremiyorum 90.

GHC bana katılıyor gibi görünüyor. Bu dosyayı derlemeye çalıştığımda,

module DigitTest where
x1 = 

bu hatayı verir.

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

Ancak, bu dosya

module DigitTest where
x = 1

derler gayet iyi. Dil özelliklerini yanlış mı okuyorum? GHC'nin (mantıklı) davranışı gerçekten doğru mu veya teknik olarak Rapordaki spesifikasyona aykırı mı? Bunun hiçbir yerinde bulamadım.


4
Komik. Bunun “Tamam, yani ASCII rakamlarından ibaret, kolay” gibi bir şeyden kaynaklandığından şüpheleniyorum. “Bekle, uluslararasılaşmayı düşünelim, Unicode ... başka rakam sembolleri de var, değil mi?” “Ah evet, ha, bununla hiç ilgilenmedin ... ama tamam, bunun için bir madde ekleyelim ...” “Harika.” ... ve daha sonra unutuldu ve kimse bunu uygulamaktan hiç rahatsız olmadı ya da farklı basamak ailelerinin karıştırılmasına izin vermenin mantıklı olmadığını fark etti.
leftaroundabout

Amanın. Evet, bununla uğraşma.
Ocak'ta Boann

Yanıtlar:


8

GHC kaynak kodu dosyasında compiler/parser/Lexer.xaşağıdaki kodu bulabilirsiniz:

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

Burada, alfasayısal tanımlayıcıların "sayısal" kısmı için kullanılırken $decdigit, ondalık ve onaltılık değişmez değerleri (ve bunların kayan nokta varyantlarını) ayrıştırmak $digitiçin kullanılır. "Yapılacaklar" notu, bunun GHC'nin dil standardından tanınan bir sapması olduğunu açıkça ortaya koymaktadır.

Yani, spesifikasyonu doğru okuyorsunuz ve GHC yarı bilinçli olarak spesifikasyonu ihlal ediyor. Orada bir var açık bilet sapma belgeleyen en azından önerir, ancak kimsenin en sabitleme de herhangi ilgilendiğini ifade sanmıyorum.


Orada listelenen sapmaların üçü de oldukça makul. Onları neden "düzeltmek" için bir talep olmadığını anlayabiliyorum.
Ian Scherer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.