演習として、Haskellのパーサーをゼロから作成しています。レクサーを作成する際に、Haskell 2010レポートの次のルールに気づきました。
数字 → ascDigit | uniDigit
ascDigit →0
|1
| …|9
uniDigit →任意のUnicode 10進数
オクティット →0
|1
| …|7
hexit → digit |A
| …|F
|a
| …|f
10進数 → 数字 { 数字 }
8進数 → octit { octit }
16進数 → hexit { hexit }整数 → 10進数 |
0o
8進数 |0O
8進数 |0x
16進数 |0X
16進数の
浮動小数点 → 10.
進数の10 進数 [ 指数 ] | 10進指数
指数 →(e
|E
)[+
|-
] 小数
10進数と16進数のリテラルは、フロートリテラルと共に、すべてに基づいている数字の代わりに任意のUnicode進数字を認め、ascDigit基本的な数字0-9 ASCIIからを認めます。奇妙なことに、8進数はoctitに基づいており、代わりにASCII数字0〜7のみを受け入れます。これらの "Unicode decimal digits"は "Nd" General Categoryを持つ任意のUnicodeコードポイントであると思います。ただし、これには全角数字0〜9やデバナーガリ数字०〜९などの文字が含まれます。識別子でこれらを許可するのが望ましい理由はわかります९0
が、リテラルの書き込みを許可することには何のメリットもありません90
。
GHCは私に同意するようです。このファイルをコンパイルしようとすると、
module DigitTest where
x1 = 1
このエラーを吐き出します。
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
ただし、このファイル
module DigitTest where
x1 = 1
正常にコンパイルされます。言語仕様を間違って読んでいますか?GHCの(賢明な)動作は実際に正しいですか、それとも技術的にはレポートの仕様に反していますか?これについての言及はどこにもありません。