Исходный код Синтаксис Юникода
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. Вкратце, его цель — поддерживать различные письменные системы, используемые сегодня, сохраняя при этом сам язык Elixir ясным и безопасным.
Для получения технических деталей см. следующие разделы, которые охватывают технические требования Юникода.
Приложение Юникода #31
Elixir реализует требования, изложенные в Приложении Юникода #31, версия 15.0.
R1. Стандартные идентификаторы
Общее правило идентификаторов Elixir задается как:
<Identifier> := <Start> <Continue>* <Ending>?
где <Start> использует те же категории, что и спецификация, но нормализует их до формы NFC (см. R4):
символы, полученные из общей категории Юникода заглавных букв, строчных букв, прописных букв, модификаторов букв, других букв, буквенных чисел, плюс
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, плюс символы, имеющие общую категорию Юникода неразрывных знаков, разрывных соединительных знаков, десятичных чисел, знаков соединения, плюс
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}, ...
Например, символ «ЗАПОЛНИТЕЛЬ ГАНГУЛЬ» (ㅤ), который часто невидим, является редкой кодовой точкой и вызовет это предупреждение.
См. примечание ниже о дополнительных нормализациях, которые могут автоматически заменить некоторые ограниченные идентификаторы.
C2. Обнаружение проблемных идентификаторов
Elixir будет выдавать предупреждение об идентификаторах, которые выглядят одинаково, но таковыми не являются. Примеры: в а = a = 1, два символа «a» являются кириллическими и латинскими и могут быть перепутаны; в 力 = カ = 1, оба японские, но разные кодовые точки, в разных сценариях этой письменной системы. Проблемные идентификаторы могут привести к трудно обнаруживаемым ошибкам (например, из-за скопированного кода) и могут быть небезопасными, поэтому мы будем предупреждать об идентификаторах в одном файле, которые могут быть перепутаны друг с другом.
Мы используем методы, описанные в разделе 4, «Обнаружение проблемных идентификаторов», с одной отмеченной модификацией.
В качестве альтернативы, следует заявить об использовании модификации и предоставить точный список отображений символов, которые добавляются или удаляются из предоставленных.
Elixir не будет предупреждать о проблемах с идентификаторами, состоящими исключительно из символов a-z, A-Z, 0-9 и подчеркивания. Это связано с тем, что идентификаторы ASCII существуют так давно, что сообщество программистов имело собственные способы решения проблем с перепутанием таких идентификаторов, как l,1 или O,0 (например, шрифты, предназначенные для программирования, обычно позволяют легко различать эти символы).
C3. Обнаружение смешанных сценариев
Elixir не позволит токенизировать смешанные идентификаторы сценариев, если смешение не является одним из исключений, определенных в UTS 39 5.2, «Высокоограничительный». Мы используем методы, описанные в разделе 5.1, «Обнаружение смешанных сценариев», чтобы определить, происходит ли смешение сценариев, с модификацией, описанной в разделе «Дополнительные нормализации» ниже.
Примеры: Elixir допускает идентификаторы, такие как 幻ㄒㄧㄤ, хотя они и включают символы из нескольких «сценариев», потому что эти сценарии «разрешаются» до японского при применении правил разрешения из UTS 39 5.1. Он также допускает атом, например, :Tシャツ, японское слово для «футболки», который включает в себя заглавную латинскую букву T, поскольку {Latn, Jpan} является одним из разрешенных смешений сценариев в определении «Высокоограничительный» в UTS 39 5.2 и «покрывает» строку.
Однако Elixir предотвратит токенизацию кода, такого как if аdmin, do: :ok, else: :err, где набор сценариев для символа «a» — {Кириллица}, но все остальные символы имеют наборы сценариев {Латиница}. Наборы сценариев не разрешаются, и наборы сценариев из определения «Высокоограничительный» в UTS 39 5.2 также не покрывают строку, поэтому отображается описательная ошибка.
C4, C5 (неприменимо)
Соответствие требованию «C4 — Обнаружение уровня ограничения» не утверждается и не применяется к идентификаторам в коде; оно относится к классификации уровня безопасности заданной произвольной строки в один из 5 уровней ограничений.
'C5 - Обнаружение смешанных чисел' соответствие неприменимо, так как Elixir не поддерживает числа Unicode.
Нормализации добавления и документированные изменения UTS 39
Начиная с Elixir 1.14, некоторые кодовые точки в \p{Identifier_Status=Restricted} нормализуются до других, не ограниченных кодовых точек.
Изначально это делается только для перевода знака МИКРО µ в греческую строчную му μ.
Это не изменение пунктов UTS39 C1 (Общий профиль безопасности) или C2 (Обнаружение конфликтных символов); однако, это документированное изменение C3, 'Обнаружение смешанных сценариев'.
Обнаружение смешанных сценариев модифицируется этими нормализациями в той степени, в которой нормализованной кодовой точке предоставляется объединение наборов сценариев из обоих символов.
Например, в примере МИКРО => МЮ, МИКРО был символом сценария 'Общие' — тот же сценарий, что и у кодовой точки '_' подчеркивание — и, следовательно, набор сценариев нормализованного символа будет {Греческий, Общие}. 'Общие' пересекается со всеми непустыми наборами сценариев, и, следовательно, нормализованный символ может использоваться в токенах, написанных на любом сценарии, без возникновения смешивания сценариев.
Кодовые точки, нормализованные таким образом, — это те, которые используются в сообществе и, как предполагается, не вызовут проблем с небезопасным смешиванием сценариев. Например, кодовые точки МИКРО или МЮ могут использоваться в атоме или переменной, связанной с микросекундами.
© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.17.2/unicode-syntax.html