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