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


15

연습으로 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 (현명한) 행동이 실제로 정확합니까, 아니면 기술적으로 보고서의 사양에 맞지 않습니까? 나는 어디서나 이것에 대한 언급을 찾을 수 없습니다.


4
이상한. 나는 이것이 "Ok이므로 리터럴은 ASCII 숫자로 쉽게 구성됩니다." "잠깐만 요, 국제화, 유니 코드를 생각해 보자. 다른 숫자 기호도 가지고 있지?" "아, 그래, 절대 다루지 않았지만 ... 좋아, 그것에 대한 조항을 삽입하자 ..." "좋아." ... 그런 다음 잊어 버렸고 아무도 그것을 실제로 구현하지 않았거나 다른 숫자 계열을 혼합하는 것이 합리적이지 않다는 것을 알았습니다.
좌회전

Yikes. 예, 이것을 귀찮게하지 마십시오.
Boann

답변:


8

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가 의도적으로 스펙을 위반하는 것입니다. 최소한 위반 을 문서화 할 것을 제안 하는 공개 티켓 이 있지만,이를 수정하는 데 관심이있는 사람은 없다고 생각합니다.


이 세 가지 편차는 모두 상당히 합리적입니다. 왜 "수정"할 필요가 없는지 알 수 있습니다.
Ian Scherer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.