Haskell解析器是否应允许数字文字中的Unicode数字?

问题描述 投票:9回答:1

[作为练习,我从头开始为Haskell编写解析器。在制作词法分析器时,我注意到Haskell 2010 Report上的以下规则:

digitascDigit | uniDigitascDigit0 |1| …|9uniDigit→任何Unicode十进制数字octit0 |1| …|7hexitdigit |A| …|F|a| …| f

十进制数字 {数字}八进制八进制 {八进制}十六进制hexit {hexit}] >>

整数

十进制 |0o八进制 |0O八进制 |0x十六进制 |0X十六进制floatdecimal.decimal [exponent] | 十进制指数指数→([e | E)[+ | -] 十进制

十进制和十六进制文字以及浮点文字都基于digit

,后者接受任何Unicode十进制数字,而不是ascDigit,后者仅接受ASCII的基本数字0-9。奇怪的是,octal是基于octit的,而后者仅允许ASCII数字0-7。我猜这些“ Unicode十进制数字”是带有“ Nd”常规类别的任何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的(明智的)行为实际上是正确的,还是在技术上违反了报告中的规范?我在任何地方都找不到此消息。

[作为练习,我从头开始为Haskell编写解析器。在制作词法分析器时,我注意到Haskell 2010 Report的以下规则:digit→ascDigit | uniDigit ascDigit→0 | 1 | ...

haskell syntax language-lawyer literals
1个回答
0
投票

在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
© www.soinside.com 2019 - 2024. All rights reserved.