ตัวแยกวิเคราะห์ Haskell ควรอนุญาตให้เลข Unicode เป็นตัวอักษรตัวเลขหรือไม่


15

ในการออกกำลังกายฉันกำลังเขียนโปรแกรมแยกวิเคราะห์สำหรับ Haskell ตั้งแต่เริ่มต้น ในการสร้าง lexer ฉันสังเกตเห็นกฎต่อไปนี้ในรายงาน Haskell 2010 :

หลักascDigit | uniDigit
ascDigit0| 1| … | 9
uniDigit →ใด ๆ Unicode ทศนิยมหลัก
octit0| 1| … | 7
hexitหลัก | A| … | F| a| … |f

ทศนิยมหลัก { หลัก }
ฐานแปดoctit { octit }
เลขฐานสิบหกhexit { hexit }

จำนวนเต็มทศนิยม | 0o ฐานแปด | 0O ฐานแปด | 0x เลขฐานสิบหก | 0X เลขฐานสิบหก
ลอยทศนิยม . ทศนิยม [ ตัวแทน ] | เลขชี้กำลังเลขชี้กำลัง
เลขชี้กำลัง → ( e| E) [ +| -] ทศนิยม

ทศนิยมและเลขฐานสิบหกพร้อมกับตัวอักษรลอยทั้งหมดขึ้นอยู่กับหลักซึ่งยอมรับทศนิยมทศนิยม Unicode ใด ๆ แทนascDigitซึ่งยอมรับเฉพาะตัวเลขพื้นฐาน 0-9 จาก ASCII ตระการฐานแปดขึ้นอยู่กับoctitซึ่งแทนที่จะยอมรับเฉพาะตัวเลข ASCII 0-7 ฉันเดาว่า "Unicode decimal digit" เหล่านี้เป็น Unicode codepoints ที่มีหมวดหมู่ทั่วไป "Nd" อย่างไรก็ตามสิ่งนี้รวมถึงตัวละครเช่นตัวเลขเต็มความกว้าง 0-9 และตัวเลข Devanagari ०-९ ฉันสามารถดูว่าทำไมมันอาจจะเป็นที่พึงประสงค์เพื่อช่วยให้เหล่านี้ในตัวบ่งชี้ แต่ฉันสามารถเห็นประโยชน์ใด ๆ เพื่อให้หนึ่งในการเขียนสำหรับอักษร९090

GHC ดูเหมือนจะเห็นด้วยกับฉัน เมื่อฉันพยายามรวบรวมไฟล์นี้

module DigitTest where
x1 = 

มันคายข้อผิดพลาดนี้

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

อย่างไรก็ตามไฟล์นี้

module DigitTest where
x = 1

รวบรวมได้ดี ฉันอ่านข้อกำหนดภาษาไม่ถูกต้องหรือไม่? พฤติกรรม (สมเหตุสมผล) ของ GHC นั้นถูกต้องจริงหรือในทางเทคนิคขัดกับข้อกำหนดในรายงานหรือไม่ ฉันไม่สามารถเอ่ยถึงเรื่องนี้ได้ทุกที่


4
ตลก. ฉันสงสัยว่าสิ่งนี้มาเกี่ยวกับบางสิ่งเช่น“ ตกลงดังนั้นตัวอักษรประกอบด้วยตัวเลข ASCII ง่าย” “ ไม่ต้องงั้นลองนึกถึงความเป็นสากล Unicode ... พวกเขายังมีสัญลักษณ์หลักอื่น ๆ ใช่มั้ย” “ ใช่แล้วเอ๊ะไม่เคยจัดการกับเรื่องนั้น ... แต่โอเคลองใส่ประโยคสำหรับเรื่องนั้น ... ”“ เยี่ยมมาก” ... และจากนั้นมันก็ถูกลืมไปแล้วและไม่มีใครใส่ใจเลยที่จะนำมันมาใช้จริงหรือสังเกตว่ามันไม่สมเหตุสมผลเลยที่จะอนุญาตให้ผสมครอบครัวต่าง ๆ
leftaroundabout

Yikes ใช่ไม่ต้องกังวลกับสิ่งนี้
Boann

คำตอบ:


8

ในไฟล์รหัสต้นฉบับ GHC compiler/parser/Lexer.xคุณสามารถค้นหารหัสต่อไปนี้:

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

ที่นี่$decdigitจะใช้สำหรับการแยกทศนิยมและตัวอักษรฐานสิบหก (และตัวแปรจุดลอยตัวของพวกเขา) ในขณะที่$digitใช้สำหรับส่วน "ตัวเลข" ของตัวระบุตัวเลขและตัวอักษร บันทึกย่อ "สิ่งที่ต้องทำ" ทำให้เห็นได้ชัดว่านี่เป็นส่วนเบี่ยงเบนที่ได้รับการยอมรับของ GHC จากมาตรฐานภาษา

ดังนั้นคุณกำลังอ่านข้อมูลจำเพาะอย่างถูกต้องและ GHC นั้นละเมิดข้อกำหนดโดยตั้งใจ มีตั๋วแบบเปิดที่แนะนำอย่างน้อยการบันทึกความเบี่ยงเบน แต่ฉันไม่คิดว่ามีใครแสดงความสนใจในการแก้ไข


ความเบี่ยงเบนทั้งสามรายการมีความสมเหตุสมผล ฉันเห็นได้ว่าทำไมไม่มีความต้องการ "แก้ไข" พวกเขา
Ian Scherer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.