Als Übung schreibe ich einen Parser für Haskell von Grund auf neu. Bei der Erstellung des Lexers habe ich die folgenden Regeln im Haskell 2010-Bericht beachtet :
Ziffer → ascDigit | uniDigit
ascDigit →0
|1
| … |9
uniDigit → beliebiges Unicode-Dezimalstellen-
Oktit →0
|1
| … |7
hexit → Ziffer |A
| … |F
|a
| … |f
Dezimal → Ziffer { Ziffer }
Oktal → Oktit { Oktit }
Hexadezimal → Hexit { Hexit }Ganzzahl → Dezimalzahl |
0o
oktal |0O
oktal |0x
hexadezimal |0X
hexadezimaler
Gleitkommawert → dezimaler.
Dezimalwert [ Exponent ] | Dezimalexponenten
Exponent → (e
|E
) [+
|-
] dezimal
Dezimal- und Hexadezimalliterale sowie Float-Literale basieren alle auf einer Ziffer , die eine beliebige Unicode-Dezimalstelle zulässt, anstelle von ascDigit , die nur die Grundziffern 0-9 aus ASCII zulässt. Seltsamerweise basiert Oktal auf Oktit , das stattdessen nur die ASCII-Ziffern 0-7 zulässt. Ich würde vermuten, dass diese "Unicode-Dezimalstellen" beliebige Unicode-Codepunkte mit der allgemeinen Kategorie "Nd" sind. Dies schließt jedoch Zeichen wie die Ziffern Full-9 in voller Breite und die Devanagari-Ziffern ०-९ ein. Ich kann sehen, warum es wünschenswert sein könnte, diese in Bezeichnern zuzulassen, aber ich kann überhaupt keinen Vorteil darin sehen, dass man ९0
für das Literal schreiben darf 90
.
GHC scheint mir zuzustimmen. Wenn ich versuche, diese Datei zu kompilieren,
module DigitTest where
x1 = 1
es spuckt diesen Fehler aus.
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
Allerdings diese Datei
module DigitTest where
x1 = 1
kompiliert ganz gut. Lese ich die Sprachspezifikation falsch? Ist das (vernünftige) Verhalten von GHC tatsächlich korrekt oder widerspricht es technisch der Spezifikation im Bericht? Ich kann das nirgendwo erwähnen.