[haskell] Haskell 파서는 숫자 리터럴의 유니 코드 숫자를 허용해야합니까?

연습으로 Haskell의 파서를 처음부터 작성하고 있습니다. 어휘 분석기를 만들면서 Haskell 2010 Report 에서 다음 규칙을 발견했습니다 .

숫자ascDigit | uniDigit
ascDigit0| 1| … | 9
uniDigit → 모든 유니 코드 소수점 자리
octit0| 1| … | 7
hexit숫자 | A| … | F| a| … |f

소수점자리 { 숫자 }
진수octit { octit }
진수hexit { hexit }

정수십진수 | 0o 8 진 | 0O 8 진 | 0x 16 진 | 0X 16
플로트10 . 진수 10 진수 [ 지수 ] | 소수점 지수
지수 → ( e| E) +| -] 십진수

부동 소수점과 함께 10 진수 및 16 진 리터럴은 모두 digit를 기반으로 하며 ASCII에서 0-9 사이의 기본 숫자 만 허용하는 ascDigit 대신 유니 코드 10 진수 를 허용합니다. 이상하게도, 8 진octit를 기반으로 하며 ASCII 숫자 0-7 만 허용합니다. 이 “유니 코드 10 진수”는 “Nd”일반 범주를 가진 모든 유니 코드 코드 포인트라고 생각합니다. 그러나 여기에는 전체 자릿수 0-9 및 Devanagari 숫자 ०-९와 같은 문자가 포함됩니다. 나는 그것들을 식별자로 허용하는 것이 바람직한 이유를 알 수 있지만 ९0리터럴 로 쓰도록 허용해도 아무런 이점이 없습니다.90 .

GHC는 저에게 동의하는 것 같습니다. 이 파일을 컴파일하려고 할 때

module DigitTest where
x1 = 

이 오류가 발생합니다.

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

그러나이 파일은

module DigitTest where
x = 1

잘 컴파일됩니다. 언어 사양을 잘못 읽습니까? GHC (현명한) 행동이 실제로 정확합니까, 아니면 기술적으로 보고서의 사양에 맞지 않습니까? 나는 어디서나 이것에 대한 언급을 찾을 수 없습니다.



답변

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십진 및 16 진 리터럴 (및 부동 소수점 변형)을 구문 분석하는 데 사용됩니다.$digit 데 사용되며 영숫자 식별자의 “숫자”부분에 사용됩니다. “ToDo”노트는 이것이 언어 표준과 GHC의 인식 된 편차라는 것을 분명히합니다.

따라서 스펙을 올바르게 읽고 GHC가 의도적으로 스펙을 위반하는 것입니다. 최소한 위반 을 문서화 할 것을 제안 하는 공개 티켓 이 있지만,이를 수정하는 데 관심이있는 사람은 없다고 생각합니다.


답변