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.
quelle
Antworten:
In der GHC-Quellcodedatei
compiler/parser/Lexer.x
finden Sie den folgenden Code:Hier
$decdigit
wird zum Parsen von Dezimal- und Hexadezimalliteralen (und ihren Gleitkommavarianten) verwendet, während$digit
für den "numerischen" Teil von alphanumerischen Bezeichnern verwendet wird. Der Hinweis "ToDo" macht deutlich, dass dies eine anerkannte Abweichung von GHC vom Sprachstandard ist.Sie lesen die Spezifikation also richtig und GHC verletzt die Spezifikation absichtlich. Es gibt ein offenes Ticket , das zumindest die Dokumentation der Abweichung vorschlägt, aber ich glaube, niemand hat Interesse daran bekundet, sie zu beheben.
quelle