Действительные символы идентификатора в Scala

Одна вещь, которую я нахожу довольно запутанной, - это знать, какие символы и комбинации я могу использовать в именах методов и переменных. Например,

val #^ = 1 // legal
val #  = 1 // illegal
val +  = 1 // legal
val &+ = 1 // legal
val &2 = 1 // illegal
val £2 = 1 // legal
val ¬  = 1 // legal

Как я понимаю, существует различие между буквенно-цифровыми идентификаторами и идентификаторами операторов. Вы можете смешивать совпадение одного или другого, но не оба, если они не разделены символом подчеркивания (смешанный идентификатор).

От программирования в разделе Scala раздела 6.10,

Идентификатор оператора состоит из одного или нескольких символов оператора. Операторские символы - это печатные символы ASCII, такие как +,:,?, ~ или #.

Более точно, символ оператора принадлежит к набору Unicode математических символов (Sm) или других символов (So) или 7-битных Символы ASCII, которые не являются буквами, цифрами, круглыми скобками, квадратными скобки, фигурные скобки, одинарная или двойная кавычка или символ подчеркивания, период, запятая, запятая или обратный тик.

Таким образом, мы исключаем использование ()[]{}'"_.;, и `

Я искал математические символы Unicode на Wikipedia, но те, которые я нашел, не включали +, :, ? и т.д. Есть ли окончательный список где-то из символов оператора?

Также любые идеи, почему математические операторы Unicode (а не символы) не считаются операторами?

Ответы

Ответ 1

Работа с синтаксисом EBNF в спецификации:

upper ::= ‘A’ | ... | ‘Z’ | ‘$’ | ‘_’ and Unicode category Lu
lower ::= ‘a’ | ... | ‘z’ and Unicode category Ll
letter ::= upper | lower and Unicode categories Lo, Lt, Nl
digit ::= ‘0’ | ... | ‘9’
opchar ::= "all other characters in \u0020-007F and Unicode
            categories Sm, So except parentheses ([]) and periods"

Но также с учетом самого начала на лексическом синтаксисе, который определяет:

Parentheses ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’.
Delimiter characters ‘‘’ | ‘’’ | ‘"’ | ‘.’ | ‘;’ | ‘,’

Вот что я придумал. Работая путем исключения в диапазоне \u0020-007F, исключая буквы, цифры, круглые скобки и разделители, мы имеем для opchar... (drumroll):

! # % & * + - / : < = > ? @ \ ^ | ~ а также Sm и So - за исключением круглые скобки и периоды.

(Изменить: добавление допустимых примеров здесь:). Вкратце, вот несколько примеров, которые показывают все случаи - обратите внимание на \ в REPL, мне нужно было бежать как \\:

val !#%&*+-/:<=>[email protected]\^|~ = 1 // all simple opchars
val simpleName = 1 
val withDigitsAndUnderscores_ab_12_ab12 = 1 
val wordEndingInOpChars_!#%&*+-/:<=>[email protected]\^|~ = 1
val !^©® = 1 // opchars ans symbols
val abcαβγ_!^©® = 1 // mixing unicode letters and symbols

Примечание 1:

Я нашел этот индекс Unicode , чтобы выяснить Lu, Ll, Lo, Lt, Nl:

  • Lu (прописные буквы)
  • Ll (строчные буквы)
  • Lo (другие буквы)
  • Lt (заголовок)
  • Nl (буквенные числа, такие как римские цифры)
  • Sm (символьная математика)
  • Итак (символ другой)

Примечание 2:

val #^ = 1 // legal   - two opchars
val #  = 1 // illegal - reserved word like class or => or @
val +  = 1 // legal   - opchar
val &+ = 1 // legal   - two opchars
val &2 = 1 // illegal - opchar and letter do not mix arbitrarily
val £2 = 1 // working - £ is part of Sc (Symbol currency) - undefined by spec
val ¬  = 1 // legal   - part of Sm

Примечание 3:

Другие операторские вещи, зарезервированные слова: _ : = => <- <: <% >: # @, а также \u21D2 ⇒ и \u2190

Ответ 2

Спецификация языка. дает правило в главе 1, лексический синтаксис (на странице 3):

  • Символы оператора. Они состоят из всех печатных ASCII символы \u0020-\u007F. которые ни в одном из приведенных выше наборов, математические символы (Sm) и другие символы (So).

Это в основном то же самое, что и выдержка из программирования в программировании в Scala. + не является математическим символом Юникода, но он определенно является ASCII печатным символом, не указанным выше (не буква, включая _ или $, цифрой, парантесом, разделителем).

В вашем списке:

  • # является незаконным не потому, что символ не является символом оператора (# ^ является законным), а потому что это зарезервированное слово (на странице 4) для проектирования типа.
  • & 2 является незаконным, поскольку вы смешиваете символ оператора и символ не оператора, цифру 2
  • £ 2 является законным, поскольку E не является символом оператора: это не семибитный ASCII, а 8-разрядный расширенный ASCII. Это не приятно, поскольку $ тоже не один (считается буквой).