В компьютерном языке зарезервированное слово (также известное как зарезервированный идентификатор ) — это слово, которое нельзя использовать в качестве идентификатора , например имени переменной, функции или метки — оно «зарезервировано от использования». Это синтаксическое определение, и зарезервированное слово может не иметь значения, определяемого пользователем.
Близко связанным и часто смешиваемым понятием является ключевое слово , которое представляет собой слово, имеющее особое значение в определенном контексте. Это смысловое определение. Напротив, имена в стандартной библиотеке , но не встроенные в язык, не считаются зарезервированными словами или ключевыми словами. Термины «зарезервированное слово» и «ключевое слово» часто используются как взаимозаменяемые – можно сказать, что зарезервированное слово «зарезервировано для использования в качестве ключевого слова» – и формальное использование варьируется от языка к языку. В этой статье мы различаем, как указано выше.
Как правило, зарезервированные слова и ключевые слова не обязательно должны совпадать, но в большинстве современных языков ключевые слова представляют собой подмножество зарезервированных слов, поскольку это упрощает синтаксический анализ, поскольку ключевые слова нельзя путать с идентификаторами. В некоторых языках, таких как C или Python , зарезервированные слова и ключевые слова совпадают, в то время как в других языках, таких как Java , все ключевые слова являются зарезервированными словами, но некоторые зарезервированные слова не являются ключевыми словами и зарезервированы для будущего использования. В других языках, таких как более старые языки ALGOL , FORTRAN и PL/I , есть ключевые слова, но нет зарезервированных слов, причем ключевые слова отличаются от идентификаторов другими способами.
Наборы зарезервированных слов и ключевых слов в языке часто совпадают или почти равны, а различия невелики, поэтому эти термины часто используются как синонимы. Однако при бережном использовании они выделяются.
Создание зарезервированных ключевых слов упрощает лексику , поскольку строка символов однозначно будет либо ключевым словом, либо идентификатором, независимо от контекста; таким образом, ключевые слова обычно представляют собой подмножество зарезервированных слов. Однако зарезервированные слова не обязательно должны быть ключевыми словами. Например, в Java goto
это зарезервированное слово, но не имеющее значения и не встречающееся ни в каких правилах продукции грамматики. Обычно это делается для прямой совместимости , поэтому зарезервированное слово может стать ключевым словом в будущей версии, не нарушая при этом существующие программы.
И наоборот, ключевые слова не обязательно должны быть зарезервированными словами, их роль понимается из контекста, или их можно отличить другим способом, например, путем удаления . Например, эта фраза if = 1
однозначна в большинстве грамматик, поскольку управляющий оператор предложения if не может начинаться с символа =
и поэтому разрешен в некоторых языках, таких как FORTRAN . Альтернативно, в АЛГОЛе 68 ключевые слова должны быть сокращены (помечены каким-либо образом как выделенные) на строгом языке путем выделения жирным шрифтом и, таким образом, не являются зарезервированными словами. Таким образом, в строгом языке следующее выражение является допустимым, поскольку ключевое слово, выделенное жирным шрифтом, не конфликтует с обычным идентификатором if
:
Однако в АЛГОЛе 68 есть также режим ограничения, в котором ключевые слова являются зарезервированными словами, что является примером того, как эти разные понятия часто совпадают; этому следуют во многих современных языках.
Зарезервированное слово — это слово, которое «выглядит» как обычное слово, но не может использоваться как обычное слово. Формально это означает, что он удовлетворяет обычному лексическому синтаксису (синтаксису слов) идентификаторов – например, представляет собой последовательность букв – но не может использоваться там, где используются идентификаторы. Например, слово if
обычно является зарезервированным словом, хотя x
обычно таковым не является, так же как и x = 1
допустимое присвоение, но if = 1
это не так.
Ключевые слова имеют различное применение, но в основном делятся на несколько классов: часть грамматики фраз (в частности, правило производства с нетерминальными символами ) с различными значениями, часто используемое для потока управления , например слово if
в большинстве процедурных языков, которое указывает условия и принимает предложения ( нетерминальные символы); имена примитивных типов в языке, поддерживающем систему типов , например int
; примитивные литеральные значения, такие как true
логическое значение true; или иногда специальные команды, такие как exit
. Другие варианты использования ключевых слов во фразах предназначены для ввода/вывода, например print
.
Четкие определения становятся ясными, когда язык анализируется с помощью комбинации лексера и синтаксического анализатора, а синтаксис языка генерируется с помощью лексической грамматики слов и контекстно-свободной грамматики правил производства фраз. Это часто встречается при анализе современных языков, и в этом случае ключевые слова представляют собой подмножество зарезервированных слов, поскольку их необходимо отличать от идентификаторов на уровне слов (следовательно, зарезервированных слов), чтобы по-разному синтаксически анализировать их на уровне фразы (как ключевые слова).
В этом случае зарезервированные слова определяются как часть лексической грамматики, и каждое из них обозначается как отдельный тип, отличный от идентификаторов. В общепринятой нотации зарезервированные слова if
и then
например обозначаются как типы IF
и THEN
соответственно, тогда как x
и y
оба обозначаются как тип Identifier
.
Ключевые слова, напротив, синтаксически появляются в грамматике фраз как терминальные символы . Например, правилом производства условного выражения может быть IF Expression THEN Expression
. В данном случае IF
и THEN
являются терминальными символами, означающими «токен типа IF
или THEN
соответственно» – и в силу лексической грамматики это означает строку if
или then
в первоисточнике. Примером примитивного постоянного значения может быть ключевое слово, представляющее логическое значение «истина», и в этом случае оно должно появиться в грамматике , например, true
как возможное расширение производства .BinaryExpression
Помимо резервирования определенных списков слов, некоторые языки резервируют целые диапазоны слов для использования в качестве частных пространств для будущих языковых версий, различных диалектов, расширений , специфичных для компилятора, или для внутреннего использования компилятором, особенно при изменении имен .
Чаще всего это делается с помощью префикса, часто одного или нескольких подчеркиваний . В этом отношении примечательны C и C++ : C99 резервирует идентификаторы, начинающиеся с двух подчеркиваний или подчеркивания, за которыми следует прописная буква, а также резервирует идентификаторы, начинающиеся с одного подчеркивания (в обычном пространстве и пространстве тегов), для использования в области файлов ; [1] с C++03 дополнительно резервирует идентификаторы, содержащие двойное подчеркивание в любом месте [2] – это позволяет использовать двойное подчеркивание в качестве разделителя (например, для соединения идентификаторов пользователей).
Частое использование двойного подчеркивания во внутренних идентификаторах в Python привело к появлению аббревиатуры dunder; это было придумано Марком Джексоном [3] и независимо Тимом Хохбергом [4] с разницей в несколько минут, оба в ответ на один и тот же вопрос в 2002 году. [5] [6]
Список зарезервированных слов и ключевых слов в языке определяется при разработке языка, и оба являются частью формальной спецификации языка . Обычно желательно минимизировать количество зарезервированных слов, чтобы избежать ограничения допустимых имен идентификаторов. Кроме того, введение новых зарезервированных слов нарушает работу существующих программ, использующих это слово (оно не имеет обратной совместимости), поэтому этого следует избегать. Чтобы предотвратить это и обеспечить совместимость вперед , иногда слова резервируются, не имея текущего использования (зарезервированное слово, которое не является ключевым словом), поскольку это позволяет использовать слово в будущем, не нарушая существующие программы. Альтернативно, новые функции языка могут быть реализованы как предопределенные, которые можно переопределить, не нарушая при этом существующие программы.
Причины гибкости включают в себя разрешение производителям компиляторов расширять спецификацию, включая нестандартные функции, различные стандартные диалекты языка для ее расширения или будущие версии языка, включающие дополнительные функции. Например, процедурный язык может предвидеть добавление объектно-ориентированных возможностей в будущей версии или каком-либо диалекте, после чего можно будет добавить такие ключевые слова, как class
или object
. Чтобы учесть эту возможность, текущая спецификация может использовать эти зарезервированные слова, даже если они в настоящее время не используются.
Яркий пример — Java , где const
и goto
являются зарезервированными словами — они не имеют значения в Java, но их также нельзя использовать в качестве идентификаторов. Сохраняя условия, они могут быть реализованы в будущих версиях Java, если это необходимо, без нарушения старого исходного кода Java. Например, в 1999 году было предложение добавить const
к языку сходство с C++, что было возможно с использованием этого const
слова, поскольку оно было зарезервировано, но в настоящее время не используется; однако это предложение было отклонено - в частности, потому, что, хотя добавление этой функции не нарушит работу существующих программ, использование ее в стандартной библиотеке (особенно в коллекциях) нарушит совместимость. [7] JavaScript также содержит ряд зарезервированных слов без особой функциональности; точный список зависит от версии и режима. [8]
Языки существенно различаются по тому, как часто они вводят новые зарезервированные слова или ключевые слова и как они их называют. Некоторые языки очень консервативны и вводят новые ключевые слова редко или никогда, чтобы избежать нарушения существующих программ, в то время как другие языки вводят новые ключевые слова более свободно, требуя существующих программы для изменения существующих конфликтующих идентификаторов. В качестве примера приведены новые ключевые слова в C11 по сравнению с C++11 , оба с 2011 года — напомним, что в C и C++ идентификаторы, начинающиеся с подчеркивания, за которым следует прописная буква, зарезервированы: [9]
Комитет C предпочитает не создавать новые ключевые слова в пространстве имен пользователей, поскольку обычно ожидается, что каждая версия C не приведет к поломке старых программ на C. Для сравнения, комитет C++ (WG21) предпочитает делать новые ключевые слова такими же нормальными, как и старые. Например, в C++11 определено новое
thread_local
ключевое слово для обозначения статического хранилища, локального для одного потока. C11 определяет новое ключевое слово как_Thread_local.
В новом заголовке C11 <threads.h> есть определение макроса, обеспечивающее нормальное имя: [10]
#define thread_local _Thread_local
То есть C11 вводил ключевое слово _Thread_local
в существующий набор зарезервированных слов (с определенным префиксом), а затем использовал отдельную возможность (обработку макросов), чтобы разрешить его использование, как если бы это было новое ключевое слово без какого-либо префикса, в то время как C+ +11 представляет ключевое слово, thread_local
несмотря на то, что оно не является существующим зарезервированным словом, что нарушает работу всех программ, которые его использовали, но не требует обработки макросов.
Понятие, связанное с зарезервированными словами, — это предопределенные функции, методы, подпрограммы, типы или переменные, в частности библиотечные процедуры из стандартной библиотеки. Они схожи тем, что являются частью основного языка и могут использоваться для аналогичных целей. Однако они отличаются тем, что имя одного из этих объектов обычно классифицируется как идентификатор, а не как зарезервированное слово, и не обрабатывается специально в синтаксическом анализе. Кроме того, зарезервированные слова не могут быть переопределены программистом, но предопределенные часто могут быть переопределены в некоторой области действия .
Языки различаются в зависимости от того, что предоставляется в качестве ключевого слова, а что является предопределенным. Например, некоторые языки предоставляют ключевые слова для операций ввода-вывода, тогда как в других это библиотечные процедуры. В Python (версии до 3.0) и многих диалектах BASICprint
— это ключевое слово. Напротив, эквиваленты C, Lisp и Python 3.0 printf
, format
и print
являются функциями стандартной библиотеки. Точно так же в Python до версии 3.0 , None
, True
и False
были предопределенными переменными, но не зарезервированными словами, но в Python 3.0 они были преобразованы в зарезервированные слова. [11]
Некоторые используют термины «ключевое слово» и «зарезервированное слово» как синонимы, в то время как другие различают использование, например, используя «ключевое слово» для обозначения слова, которое является специальным только в определенных контекстах, а «зарезервированное слово» для обозначения специального слова, которое нельзя использовать. как имя, определяемое пользователем. Значение ключевых слов и значение понятия ключевого слова сильно различаются от языка к языку. Конкретно, в АЛГОЛе 68 ключевые слова обрезаны (на строгом языке выделены жирным шрифтом) и не являются зарезервированными словами – несрезанное слово может использоваться как обычный идентификатор.
В « Спецификации языка Java » используется термин «ключевое слово». [12] В стандарте ISO 9899 для языка C используется термин «ключевое слово». [13]
Во многих языках, таких как C и подобных средах, таких как C++ , ключевое слово — это зарезервированное слово, которое идентифицирует синтаксическую форму. Слова, используемые в конструкциях потока управления , такие как if
, then
и else
являются ключевыми словами. В этих языках ключевые слова также не могут использоваться в качестве имен переменных или функций.
В некоторых языках, таких как АЛГОЛ и АЛГОЛ 68 , ключевые слова не могут быть написаны дословно, а должны быть сокращены . Это означает, что ключевые слова должны быть как-то отмечены. Например, заключая их в кавычки или добавляя к ним специальный символ. Как следствие, ключевые слова не являются зарезервированными словами, и, следовательно, одно и то же слово можно использовать в качестве обычного идентификатора. Однако один из режимов ограничения заключался в том, чтобы не ограничивать ключевые слова, а вместо этого сделать их просто зарезервированными словами.
Некоторые языки, такие как PostScript , чрезвычайно либеральны в этом подходе, позволяя переопределять основные ключевые слова для конкретных целей.
В Common Lisp термин «ключевое слово» (или «символ ключевого слова») используется для обозначения особого вида символа или идентификатора. В отличие от других символов, которые обычно обозначают переменные или функции, ключевые слова заключаются в кавычки и самовычисляются [14] :98 и встроены в KEYWORD
пакет. [15] Ключевые слова обычно используются для обозначения именованных аргументов функций и для представления символических значений. Символы, обозначающие функции, переменные, специальные формы и макросы в пакете COMMON-LISP, по сути, являются зарезервированными словами. Эффект от их переопределения не определен в ANSI Common Lisp. [16] Их привязка возможна. Например, выражение (if if case or)
возможно, когда if
является локальной переменной. Крайний левый if
относится к if
оператору; остальные символы интерпретируются как имена переменных. Поскольку для функций и переменных существует отдельное пространство имен, if
переменная может быть локальной. Однако в Common Lisp есть два специальных символа, которых нет в пакете ключевых слов: символы t
и nil
. Когда они оцениваются как выражения, они оцениваются сами по себе. Их нельзя использовать в качестве имен функций или переменных, поэтому они де-факто зарезервированы. (let ((t 42)))
является правильно сформированным выражением, но let
оператор не разрешает его использование.
Обычно, когда программист пытается использовать ключевое слово для имени переменной или функции, возникает ошибка компиляции. В большинстве современных редакторов ключевым словам автоматически присваивается определенный цвет текста, чтобы напомнить или сообщить программистам, что они являются ключевыми словами.
В языках с макросами или отложенными вычислениями конструкции потока управления, например, if
могут быть реализованы как макросы или функции. В языках без этих выразительных функций они обычно являются ключевыми словами.
В разных языках часто имеется разное количество зарезервированных слов. Например, в COBOL их около 400. В Java и других производных от C набор довольно скудный, около 50. В чистом Prolog и PL/I их нет.
Определение зарезервированных слов в языке вызывает проблемы. Новым пользователям может быть сложно изучить этот язык из-за длинного списка зарезервированных слов, которые нельзя использовать в качестве идентификаторов. Расширить язык может быть сложно, поскольку добавление зарезервированных слов для новых функций может сделать недействительными существующие программы или, наоборот, «перегрузка» существующих зарезервированных слов новыми значениями может сбить с толку. Перенос программ может быть проблематичным, поскольку слово, не зарезервированное одной системой или компилятором, может быть зарезервировано другой.
Поскольку зарезервированные слова не могут использоваться в качестве идентификаторов, пользователи могут вместо этого выбирать в качестве идентификаторов преднамеренные ошибки в написании зарезервированных слов, например, clazz
для переменных Java типа Class
. [17]
Спецификация Microsoft .NET Common Language Infrastructure (CLI) позволяет объединять в конечный продукт код, написанный на более чем 40 различных языках программирования. Из-за этого могут возникнуть конфликты идентификатора и зарезервированного слова, когда код, реализованный на одном языке, пытается выполнить код, написанный на другом языке. Например, библиотека Visual Basic (.NET) может содержать такое определение класса :
' Определение класса This в Visual Basic.NET:Public Class this 'Этот класс что-то делает... Конец класса
Если это скомпилировано и распространено как часть набора инструментов, программист C# , желающий определить переменную типа " this
", столкнется с проблемой: 'this'
это зарезервированное слово в C#. Таким образом, в C# не будет компилироваться следующее:
// Использование этого класса в C#:это х = новое это (); // Не скомпилируется!
Аналогичная проблема возникает при доступе к членам, переопределении виртуальных методов и идентификации пространств имен.
Это решается остановкой . Чтобы обойти эту проблему, спецификация позволяет помещать (в C#) знак at перед идентификатором, что заставляет компилятор считать его идентификатором, а не зарезервированным словом:
// Использование этого класса в C#:@this x = новый @this (); // Скомпилируем!
Для единообразия такое использование также разрешено в закрытых настройках, таких как локальные переменные, имена параметров и частные члены.
Следующие последовательности символов, образованные из букв ASCII, зарезервированы для использования в качестве ключевых слов и не могут использоваться в качестве идентификаторов[...]
Вышеупомянутые токены (с учетом регистра) зарезервированы (на этапах трансляции 7 и 8) для использования в качестве ключевых слов и не должны использоваться иначе.