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| … |fdziesiętny → cyfra { cyfra }
ósemkowy → octit { octit }
szesnastkowy → hexit { hexit }liczba całkowita → dziesiętny |
0oósemkowy |0Oósemkowy |0xszesnastkowy |0Xszesnastkowy
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 ९0dla 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ć.