Исходный код Синтаксис Юникода
Elixir поддерживает Юникод во всём языке. Этот документ — полная справка о том, как Elixir поддерживает Юникод в своём синтаксисе.
Строки ("olá") и списки символов ('olá') поддерживают Юникод начиная с Elixir v1.0. Строки закодированы в UTF-8. Списки символов представляют собой списки кодовых точек Юникода. В таких случаях содержимое сохраняется в том виде, в котором его ввели разработчики, без каких-либо преобразований.
Elixir также поддерживает Юникод в переменных, атомах и вызовах начиная с Elixir v1.5. Эта документация предоставляет общее введение в то, как Elixir позволяет использовать Юникод в своём синтаксисе. Мы также предоставляем техническую документацию, описывающую, как Elixir соответствует спецификации Юникода.
Чтобы проверить версию Юникода вашей текущей установки Elixir, выполните String.Unicode.version().
Введение
Elixir допускает использование символов Юникода в переменных, атомах и вызовах. Однако символы Юникода должны подчиняться правилам синтаксиса языка. В частности, переменные и вызовы не могут начинаться с заглавной буквы. В дальнейшем мы будем использовать термин «идентификаторы» для этих элементов.
Допустимые в идентификаторах символы определяются спецификацией Юникода. В общем случае, это символы, обычно используемые в активных письменных системах человеческих языков. В частности, это исключает такие символы, как эмодзи, альтернативные числовые представления, нотные знаки и тому подобное.
Elixir накладывает много ограничений на идентификаторы для обеспечения безопасности. Например, слово «josé» может быть записано в Юникоде двумя способами: как сочетание символов j o s é и как сочетание символов j o s e ́, где ударение — это отдельный символ. Первый вариант называется формой NFC, а второй — формой NFD. Elixir нормализует все символы до формы NFC.
Elixir также не допускает смешанных сценариев, которые не разделены явно _. Например, нельзя назвать переменную аdmin, где а — кириллица, а остальные символы — латиница. Это вызовет следующую ошибку:
** (SyntaxError) invalid mixed-script identifier found: аdmin
Mixed-script identifiers are not supported for security reasons. 'аdmin' is made of the following scripts:
\u0430 а {Cyrillic}
\u0064 d {Latin}
\u006D m {Latin}
\u0069 i {Latin}
\u006E n {Latin}
Make sure all characters in the identifier resolve to a single script or a highly
restrictive script. See https://hexdocs.pm/elixir/unicode-syntax.html for more information.
Наконец, Elixir также выдаст предупреждение о потенциально неоднозначных идентификаторах в одном файле. Например, Elixir выведет предупреждение, если в вашем коде используются переменные а (кириллица) и а (латиница).
Это общее введение в использование Юникода в идентификаторах Elixir. Вкратце, его цель — поддержка различных систем письма, используемых сегодня, при одновременном сохранении ясности и безопасности языка Elixir.
Технические детали см. в следующих разделах, посвященных техническим требованиям Юникода.
Приложение к Юникоду #31
Elixir реализует требования, изложенные в Приложении к Юникоду #31, версия 15.0.
R1. Идентификаторы по умолчанию
Общее правило Elixir для идентификаторов задается следующим образом:
<Identifier> := <Start> <Continue>* <Ending>?
где <Start> использует те же категории, что и спецификация, но нормализует их до формы NFC (см. R4):
символы, полученные из общей категории Unicode «заглавные буквы», «строчные буквы», «заглавные буквы», «модификаторы букв», «другие буквы», «цифры букв», плюс
Other_ID_Start, минусPattern_SyntaxиPattern_White_Spaceкодовые точкиВ записи множества:
[\p{L}\p{Nl}\p{Other_ID_Start}-\p{Pattern_Syntax}-\p{Pattern_White_Space}].
и <Continue> использует те же категории, что и спецификация, но нормализует их до формы NFC (см. R4):
символы ID_Start, плюс символы с общей категорией Unicode «неразрывные знаки», «разделительные комбинирующие знаки», «десятичные числа», «соединительные знаки пунктуации», плюс
Other_ID_Continue, минусPattern_SyntaxиPattern_White_Spaceкодовые точки.В записи множества:
[\p{ID_Start}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\p{Other_ID_Continue}-\p{Pattern_Syntax}-\p{Pattern_White_Space}].
<Ending> — дополнение, специфичное для Elixir, включающее только кодовые точки ? (003F) и ! (0021).
Спецификация также предоставляет набор <Medial>, но Elixir не включает ни одного символа из этого набора. Поэтому правило идентификатора было упрощено с учетом этого.
Elixir не разрешает использование ZWJ или ZWNJ в идентификаторах и поэтому не реализует R1a. Символы управления направлением биди также не поддерживаются. R1b гарантируется для обеспечения обратной совместимости.
Атомы
Атомы Юникода в Elixir следуют вышеуказанному правилу идентификаторов с указанными изменениями:
-
<Start>дополнительно включает кодовую точку_(005F) -
<Continue>дополнительно включает кодовую точку@(0040)
Обратите внимание, что атомы также могут быть заключены в кавычки, что позволяет использовать любые символы, такие как :"hello elixir". Все операторы Elixir также являются допустимыми атомами, такие как :+, :@, :|>, и другие. Полное описание допустимых атомов доступно в разделе "Атомы" в справочнике по синтаксису.
Переменные, локальные вызовы и удаленные вызовы
Переменные в Elixir следуют вышеуказанному правилу идентификаторов с указанными изменениями:
-
<Start>дополнительно включает кодовую точку_(005F) -
<Start>дополнительно исключает символы Lu (заглавные буквы) и Lt (заглавные буквы)
В записи множества: [\u{005F}\p{Ll}\p{Lm}\p{Lo}\p{Nl}\p{Other_ID_Start}-\p{Pattern_Syntax}-\p{Pattern_White_Space}].
Псевдонимы
Псевдонимы в Elixir допускают только символы ASCII, начинающиеся с заглавной буквы, и без знаков препинания.
R3. Символы пробелов и синтаксиса шаблонов
Elixir поддерживает только кодовые точки \t (0009), \n (000A), \r (000D) и \s (0020) как пробелы и поэтому не соответствует требованию R3. R3 требует поддержки более широкого набора символов пробелов и синтаксиса.
R4. Эквивалентные нормализованные идентификаторы
Идентификаторы в Elixir регистрозависимы.
Elixir нормализует все атомы и переменные до формы NFC. Однако атомы и строки, заключенные в кавычки, могут быть в любой форме и не проверяются анализатором.
Другими словами, атом :josé может быть записан только с кодовыми точками 006A 006F 0073 00E9 или 006A 006F 0073 0065 0301, но Elixir перепишет его в первый вариант (начиная с Elixir 1.14). С другой стороны, :"josé" может быть записано как 006A 006F 0073 00E9 или 006A 006F 0073 0065 0301, и его форма будет сохранена, поскольку оно находится в кавычках.
Выбор требования R4 автоматически исключает требования R5, R6 и R7.
Технический стандарт Юникода #39
Elixir соответствует пунктам, изложенным в Техническом стандарте Юникода #39 по безопасности, версия 15.0.
C1. Общий профиль безопасности для идентификаторов
Elixir не позволит токенизировать идентификаторы с кодовыми точками в \p{Identifier_Status=Restricted}.
Реализация, следующая профилю общей безопасности, не допускает никаких символов в \p{Identifier_Status=Restricted}, ...
Например, символ «ЗАПОЛНИТЕЛЬ HANGUL» (ㅤ), который часто невидим, является редкой кодовой точкой и вызовет это предупреждение.
См. примечание ниже о дополнительных нормализациях, которые могут выполнять автоматическую замену некоторых ограниченных идентификаторов.
C2. Обнаружение неоднозначных идентификаторов
Elixir выдаст предупреждение об идентификаторах, которые выглядят одинаково, но таковыми не являются. Например, в а = a = 1, две буквы «a» — кириллица и латиница и могут быть перепутаны; в 力 = カ = 1, обе — японские, но разные кодовые точки, в разных письменностях этой системы. Неоднозначные идентификаторы могут привести к трудноуловимым ошибкам (например, из-за скопированного кода) и могут быть небезопасны, поэтому мы выведем предупреждение об идентификаторах в одном файле, которые могут быть перепутаны.
Мы используем средства, описанные в разделе 4 «Обнаружение неоднозначных идентификаторов», с одним отмеченным изменением
В качестве альтернативы, следует объявить об использовании модификации и предоставить точный список соответствий символов, которые добавляются или удаляются из предоставленных.
Elixir не выдаст предупреждений об неоднозначности для идентификаторов, состоящих исключительно из символов a-z, A-Z, 0-9 и _. Это связано с тем, что идентификаторы ASCII существуют уже давно, и сообщество программистов разработало собственные методы обработки неоднозначностей между идентификаторами, например, l,1 или O,0 (например, шрифты, предназначенные для программирования, обычно облегчают различение этих символов).
C3. Обнаружение смешанных сценариев
Elixir не позволит токенизировать идентификаторы со смешанными сценариями, если это не происходит через блоки, разделенные символом подчёркивания, как http_сервер. Мы используем средства, описанные в разделе 5.1 «Обнаружение смешанных сценариев», чтобы определить, происходит ли смешение сценариев, с изменениями, задокументированными в разделе «Дополнительные нормализации» ниже.
Примеры: Elixir допускает идентификаторы, такие как 幻ㄒㄧㄤ, даже если они включают символы из нескольких «сценариев», потому что эти сценарии «восстанавливаются» до японского при применении правил разрешения из UTS 39 5.1. При смешении латинских и японских сценариев необходимы символы подчёркивания, как в :T_シャツ (японское слово для «футболка» с дополнительным символом подчёркивания, разделяющим букву T).
Elixir не допускает код, такой как if аdmin, do: :ok, else: :err, где набор сценариев для символа «a» — {кириллица}, но все остальные символы имеют наборы сценариев {латиница}. Наборы сценариев не разрешаются, и отображается описательная ошибка.
C4, C5 (неприменимо)
Соответствие «C4 — Обнаружение уровня ограничения» не заявлен и не относится к классификации уровня безопасности заданной произвольной строки в один из 5 уровней ограничения.
«C5 — Обнаружение смешанных чисел» неприменимо, так как Elixir не поддерживает числа Юникода.
Дополнительные нормализации и задокументированные изменения UTS 39
Начиная с Elixir 1.14, некоторые кодовые точки в \p{Identifier_Status=Restricted} нормализуются до других, неограниченных кодовых точек.
Изначально это делается только для перевода MICRO SIGN µ в греческую строчную му, μ.
Это не является модификацией пунктов UTS39 C1 (Общий профиль безопасности) или C2 (Обнаружение смешиваемости); однако это документированная модификация C3, «Обнаружение смешанного сценария».
Обнаружение смешанного сценария изменяется этими нормализациями в той мере, в которой нормализованному кодовому значению предоставляется объединение наборов символов как от одного, так и от другого символа.
Например, в примере MICRO => MU, Micro был символом «Общие» набора символов — тот же набор символов, что и у символа «_» подчеркивания, и таким образом, набор символов нормализованного символа будет {Греческий, Общий}. «Общие» пересекаются со всеми непустыми наборами символов, и таким образом, нормализованный символ может использоваться в маркерах, написанных на любом языке, не вызывая смешивания языков.
Кодовые точки, нормализованные таким образом, — это те, которые используются в сообществе и, как предполагается, маловероятно, что приведут к проблемам с небезопасным смешиванием сценариев. Например, кодовое значение MICRO или MU может использоваться в атоме или переменной, связанной с микросекундами.
© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.18.1/unicode-syntax.html