Comme exercice, j'écris un analyseur pour Haskell à partir de zéro. En faisant le lexer, j'ai remarqué les règles suivantes sur le rapport Haskell 2010 :
digit → ascDigit | uniDigit
ascDigit →0
|1
| … |9
uniDigit → tout
octet de chiffre décimal Unicode →0
|1
| … |7
hexit → chiffre |A
| … |F
|a
| … |f
décimal → chiffre { chiffre }
octal → octit { octit }
hexadécimal → hexit { hexit }entier → décimal |
0o
octal |0O
octal |0x
hexadécimal | float0X
hexadécimal → décimal décimal [ exposant ] | exposant décimal exposant → ( | ) [ | ] décimal
.
e
E
+
-
Les littéraux décimaux et hexadécimaux, ainsi que les littéraux flottants, sont tous basés sur digit , qui admet tout chiffre décimal Unicode, au lieu de ascDigit , qui n'admet que les chiffres de base 0-9 de ASCII. Étrangement, octal est basé sur octit , qui n'admet à la place que les chiffres ASCII 0-7. Je suppose que ces "chiffres décimaux Unicode" sont des points de code Unicode avec la catégorie générale "Nd". Cependant, cela inclut des caractères tels que les chiffres pleine largeur 0-9 et les chiffres Devanagari ०-९. Je peux voir pourquoi il pourrait être souhaitable de les autoriser dans les identifiants, mais je ne vois aucun avantage à permettre d'écrire ९0
pour le littéral 90
.
GHC semble d'accord avec moi. Lorsque j'essaie de compiler ce fichier,
module DigitTest where
x1 = 1
il crache cette erreur.
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
Cependant, ce fichier
module DigitTest where
x1 = 1
compile très bien. Suis-je en train de lire la spécification de langue de manière incorrecte? Le comportement (sensé) de GHC est-il réellement correct ou va-t-il techniquement à l'encontre des spécifications du rapport? Je ne trouve aucune mention de cela nulle part.
la source
Réponses:
Dans le fichier de code source GHC
compiler/parser/Lexer.x
, vous pouvez trouver le code suivant:Ici,
$decdigit
est utilisé pour analyser les littéraux décimaux et hexadécimaux (et leurs variantes à virgule flottante), tandis que$digit
est utilisé pour la partie "numérique" des identificateurs alphanumériques. La note "ToDo" indique clairement qu'il s'agit d'un écart reconnu entre GHC et la norme linguistique.Donc, vous lisez correctement la spécification, et GHC viole semi-intentionnellement la spécification. Il existe un ticket ouvert qui suggère au moins de documenter l'écart, mais je ne pense pas que quiconque ait exprimé un intérêt à le corriger.
la source