作为练习,我将从头开始为Haskell编写解析器。在编写词法分析器时,我注意到Haskell 2010报告中的以下规则:
数 → ascDigit | uniDigit
ascDigit →0
|1
| …|9
uniDigit →任意Unicode十进制数字
octit →0
|1
| …|7
hexit → 数字 |A
| …|F
|a
| …|f
十进制 → 位 { 位数 }
八进制 → octit { octit }
十六进制 → hexit { hexit }整数 → 十进制 |
0o
八进制 |0O
八进制 |0x
十六进制 |0X
十六进制
浮点数 → 十进制.
十进制 [ 指数 ] | 十进制指数
指数 →(e
|E
)[+
|-
] 十进制
十进制和十六进制文字以及浮点文字都基于digit,后者允许输入任何Unicode十进制数字,而不是ascDigit,后者仅接受ASCII的基本数字0-9。奇怪的是,八进制基于octit,它仅允许ASCII数字0-7。我猜这些“ Unicode十进制数字”是带有“ Nd”常规类别的任何Unicode代码点。但是,其中包括全角数字0-9和梵文数字०- characters。我可以看到为什么最好在标识符中允许使用这些标识符,但是我看不出任何允许使用标识符९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的(明智的)行为实际上是正确的,还是在技术上违反了报告中的规范?我在任何地方都找不到任何提及。