Trình phân tích cú pháp Haskell có nên cho phép các chữ số Unicode bằng chữ số không?


15

Như một bài tập, tôi đang viết một trình phân tích cú pháp cho Haskell từ đầu. Khi tạo ra từ vựng, tôi nhận thấy các quy tắc sau đây về Báo cáo Haskell 2010 :

chữ sốascDigit | uniDigit
ascDigit0| 1| Sầu | 9
uniDigit → bất kỳ
octit chữ số thập phân Unicode → 0| 1| Sầu | 7
hexitchữ số | A| Sầu | F| a| Sầu |f

thập phânchữ số { chữ số }
bát phânoctit { octit }
thập lục phânhexit { hexit }

số nguyênthập phân | 0o bát phân | 0O bát phân | 0x thập lục phân | 0X hexadecimal
floatthập phân . thập phân [ ] | số mũ thập phân
→ ( e| E) [ +| -] thập phân

Chữ thập phân và thập lục phân, cùng với chữ nổi, tất cả đều dựa trên chữ số , thừa nhận bất kỳ chữ số thập phân Unicode nào, thay vì ascDigit , chỉ chấp nhận các chữ số cơ bản 0-9 từ ASCII. Thật kỳ lạ, bát phân dựa trên octit , thay vào đó chỉ thừa nhận các chữ số ASCII 0-7. Tôi đoán rằng những "chữ số thập phân Unicode" này là bất kỳ loại tiền mã hóa Unicode nào với Danh mục chung "Nd". Tuy nhiên, điều này bao gồm các ký tự như chữ số Toàn chiều rộng -9 và chữ số Devanagari -. Tôi có thể thấy lý do tại sao có thể mong muốn cho phép những thứ này trong định danh, nhưng tôi có thể thấy không có lợi ích gì khi cho phép một người viết ९0cho nghĩa đen 90.

GHC dường như đồng ý với tôi. Khi tôi cố gắng biên dịch tệp này,

module DigitTest where
x1 = 

nó phát ra lỗi này

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

Tuy nhiên, tập tin này

module DigitTest where
x = 1

biên dịch tốt Tôi đang đọc đặc tả ngôn ngữ không chính xác? Hành vi (hợp lý) của GHC có thực sự đúng hay về mặt kỹ thuật có đi ngược lại với đặc điểm kỹ thuật trong Báo cáo không? Tôi không thể tìm thấy đề cập đến điều này ở bất cứ đâu.


4
Buồn cười. Tôi nghi ngờ điều này xuất phát từ một cái gì đó giống như Ok Ok, vì vậy nghĩa đen chỉ bao gồm các chữ số ASCII, dễ dàng. Không có vấn đề gì, hãy nghĩ về quốc tế hóa, Unicode ... họ cũng có các ký hiệu chữ số khác, phải không? Càng ồ, ừ, không bao giờ giải quyết chuyện đó ... nhưng ok, chúng ta hãy chèn một mệnh đề cho điều đó ... ... Và sau đó nó đã bị lãng quên và thực sự không ai bận tâm đến việc thực hiện nó, hoặc nhận thấy rằng việc cho phép trộn các họ chữ số khác nhau là vô nghĩa.
rẽ trái

Rất tiếc. Vâng, đừng bận tâm với điều này.
Boann

Câu trả lời:


8

Trong tệp mã nguồn GHC compiler/parser/Lexer.x, bạn có thể tìm thấy mã sau:

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

Ở đây, $decdigitđược sử dụng để phân tích cú pháp chữ thập phân và thập lục phân (và các biến thể dấu phẩy động của chúng), trong khi$digit được sử dụng cho phần "số" của số nhận dạng chữ và số. Ghi chú "ToDo" cho thấy rõ đây là độ lệch được công nhận của GHC so với tiêu chuẩn ngôn ngữ.

Vì vậy, bạn đang đọc thông số kỹ thuật một cách chính xác và GHC đang cố tình vi phạm thông số kỹ thuật. Có một vé mở gợi ý ít nhất là ghi lại sự sai lệch, nhưng tôi không nghĩ có ai bày tỏ sự quan tâm đến việc sửa nó.


Cả ba độ lệch được liệt kê ở đó đều khá hợp lý. Tôi có thể thấy tại sao không có nhu cầu "sửa chữa" chúng.
Ian Scherer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.