Ваша путаница возникает из-за смешения двух совершенно разных уровней:
escape-последовательности Unicode обрабатываются на уровне отдельных символов. Строго говоря, это происходит еще до лексического анализа. Это означает, что escape-последовательности Unicode ничего не знают о «именовании» или «именах» - когда они раскрываются, нет информации о том, что в данный момент обрабатывается: имя (идентификатор), зарезервированное ключевое слово или какая-то совершенно другая языковая конструкция. .
Информация о том, что такое «имена», становится доступной гораздо позже, только после лексического анализа, когда последовательность входных символов разбивается на токены.
Все, что делает Scala, просто заменяет escape-последовательности \uXXXX
на соответствующие символы Unicode. Например ( запустить ScalaFiddle ):
fo\u0072 (i <- 1 to 10) pri\u006Etln\u0028"hello, world\u0022)
- это совершенно правильная Scala программа, которая печатает hello, world
десять раз. Итак, вы видите, что:
- * * * * *
\u0072
расширяется до r
в середине ключевого слова (for
- зарезервированное ключевое слово, а не идентификатор) \u006E
раскрывается в середине другого идентификатора (println
) \u0028
и \u0022
заменяются на (
и "
соответственно. Эти символы даже не могут быть действительными частями идентификаторов (если они не заключены в обратные знаки).
Он просто не имеет ничего общего с «именами». Все дело в отдельных символах, и это происходит до того, как появятся «имена», «строковые литералы» или «комментарии», поэтому такие загадки возникают, когда escape-последовательности Unicode используются внутри строковых литералов или комментарии, которые некорректно обрабатываются подсветкой кода.
Все это в основном не связано с тем, что происходит с макросами в препроцессоре C. Макросам, созданным с использованием #define
, должно быть присвоено имя, которое является правильным идентификатором (т. Е. Состоит из символов, чисел, подчеркиваний), а если у макросов есть параметры, то препроцессор заменяет их дословно фактическими аргументами на сайте вызова. Ничего из этого невозможно с escape-последовательностями Unicode. Кроме того, C -процессор не будет разрывать токены: например, если вы #define u0072 r
, препроцессор не будет go и заменяет все fou0072
-идентификаторы ключом for
. Он работает совершенно по-другому и имеет совершенно другие цели.
Обновление: более подробные сведения
Если вы посмотрите на Сканеры. scala, вы можете видеть, что есть метод getUEscape , который обрабатывает escape-последовательности и помещает отдельные символы в буфер. Единственное место, где этот метод используется, - это другой вспомогательный метод getLitChar , так что все escape-последовательности Unicode всегда преобразуются в символы до того, как эти символы поступают в методы «более высокого уровня», такие как fetchToken . Это то, что я имел в виду, когда говорил, что обработка escape-последовательностей Unicode происходит еще до лексического анализа.
Как отметил Алексей Романов в комментариях ниже, побеги вскоре будут обрабатываться по-разному и расширяться в меньшем количестве контекстов. - изменения в , или , коммитах кажутся актуальными.