Jako ćwiczenie piszę parser Haskella od zera. Tworząc leksyk zauważyłem następujące zasady dotyczące raportu Haskell 2010 :
cyfra → ascDigit | uniDigit
ascDigit →0
|1
| … |9
uniDigit → dowolny Unicode cyfry dziesiętne
octit →0
|1
| … |7
hexit → cyfra |A
| … |F
|a
| … |f
dziesiętny → cyfra { cyfra }
ósemkowy → octit { octit }
szesnastkowy → hexit { hexit }liczba całkowita → dziesiętny |
0o
ósemkowy |0O
ósemkowy |0x
szesnastkowy |0X
szesnastkowy
pływak → dziesiętny.
dziesiętny [ wykładnik ] | dziesiętny wykładnik
wykładnik → (e
|E
) [+
|-
] dziesiętny
Literały dziesiętne i szesnastkowe, wraz z literami zmiennoprzecinkowymi, są oparte na cyfrach , które dopuszczają dowolną cyfrę dziesiętną Unicode, zamiast ascDigit , która dopuszcza tylko podstawowe cyfry 0-9 z ASCII. Co dziwne, ósemkowy jest oparta na octit , który zamiast tylko przyznaje ASCII cyfr 0-7. Domyślam się, że te „cyfry dziesiętne Unicode” są dowolnymi punktami kodowymi Unicode z kategorii ogólnej „Nd”. Obejmuje to jednak takie znaki, jak cyfry pełnej szerokości 0-9 i cyfry Devanagari ०-९. Rozumiem, dlaczego pożądane może być dopuszczenie ich w identyfikatorach, ale nie widzę żadnej korzyści z umożliwienia pisania ९0
dla literału 90
.
GHC wydaje się ze mną zgadzać. Kiedy próbuję skompilować ten plik,
module DigitTest where
x1 = 1
wyrzuca ten błąd.
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
Jednak ten plik
module DigitTest where
x1 = 1
kompiluje się dobrze. Czy źle czytam specyfikację języka? Czy zachowanie (rozsądne) GHC jest rzeczywiście prawidłowe, czy technicznie jest niezgodne ze specyfikacją w Raporcie? Nigdzie nie mogę o tym wspominać.