Зарезервоване слово
На комп'ютерній мові зарезервоване слово (також відоме як зарезервований ідентифікатор) — це слово, яке не може використовуватися як ідентифікатор, наприклад, назва змінної, функції або мітки — воно «зарезервоване від використання». Це визначене синтаксисом слово і воно може зовсім не мати значення.
Доволі близькими є поняття «зарезервоване слово» та «ключове слово». Ці слова мають спеціальне значення в окремих випадках. Це визначено семантикою. Але імена в стандартній бібліотеці, які не є вбудованими в мову не вважаються зарезервованими чи ключовими словами. Терміни «зарезервоване слово» та «ключове слово» часто використовують як взаємнозамінні. Про зарезервовані слова можна сказати, що вони «зарезервовані для використання як ключові слова», а формальне використання змінюється залежно від мови.
В основному зарезервовані та ключові слова не повинні збігатися, але в найновіших мовах ключові слова є підмножиною зарезервованих, це робить парсинг простішим так як не можливо сплутати ключові слова з ідентифікаторами. В деяких мовах, таких як, С чи Python, зарезервовані та ключові слова збігаються, коли в інших мовах, як Java, всі ключові слова є зарезервованими, але деякі зарезервовані слова не є ключовими, вони є «зарезервованими для майбутнього використання». В старіших мовах, ALGOL, FORTRAN, і PL/I, є ключові слова, але немає зарезервованих, ключові слова відрізнялися від ідентифікаторів в інший спосіб. Це робить парсинг більш складним.
Відмінність
Набори зарезервованих та ключових слів в мові часто збігаються або є майже однаковими, і різниця між ними інколи є не відчутною, а ці терміни часто є взаємозамінними. Однак при уважному використанні ці терміни відрізняються.
Якщо зробити ключові слова зарезервованими, то це полегшує лексичний аналіз. Тому що можна однозначно визначити чим є рядок символів, ключовим словом чи ідентифікатором. Саме тому ключові слова зазвичай є зарезервованими. Однак зарезервовані слова не повинні бути ключовими. Як приклад в мові Java є зарезервоване слово goto
, але воно не має ніякого значення і воно не зустрічається в жодних правилах створення граматик. Це зроблено для сумісності з майбутніми версіями: у майбутніх версіях зарезервовані слова можуть стати ключовими, і це не вимагатиме змін у вже наявних програмах.
З іншого боку ключові слова не повинні бути зарезервованими, їх роль зрозуміла з контексту, або вони мають розрізнятись у інший спосіб, такий, як строппінг. Наприклад вираз if = 1
є однозначним у більшості граматик, оскільки умова в операторі if
не може починатися зі знака =
, тому такі вирази дозволені у деяких мовах, зокрема у FORTRAN. В ALGOL 68 ключові слова мають бути певним чином позначені — в суворій мові вони позначаються жирним шрифтом, і таким чином вони не є зарезервованими. Отже, наступний вираз є правильним, ключове слово if яке виділене жирним шрифтом не буде конфліктувати зі звичайним ідентифікатором if
- if if eq 0 then 1 fi
Проте в ALGOL 68 існує також режим stropping, в якому ключові слова є зарезервованими словами, що є прикладом того, як ці різні поняття часто збігаються; багато сучасних мов також слідують цьому правилу.
Синтаксис
Зарезервоване слово — це слово, яке «виглядає як» звичайне слово, але не може використовуватися як звичайне слово. Формально це означає, що воно задовольняє звичайний синтаксис (синтаксис слів) ідентифікаторів — наприклад, це послідовність букв — але не може використовуватися там, де використовуються ідентифікатори. Наприклад, слово if
зазвичай є зарезервованим словом, тоді як x
ніколи не є зарезервованим словом, тому x = 1
є допустимим виразом, а if = 1
— ні.
Ключові слова мають різноманітне використання, але в першу чергу входять у кілька класів: частину фрази граматики (зокрема, правила продукції з нетермінальними символами), з різними значеннями, часто використовуваних для порядку виконання операцій, наприклад, слово if
в більшості процедурних мов задає умовний перехід і приймає умову (нетермінальні символи); імена примітивних типів мови, що підтримують систему типізації, наприклад int
; примітивні значення літералу, такі як true
для Boolean true; або іноді спеціальні команди, такі як exit
. Інші використання ключових слів у фразах призначено для введення/виводу, наприклад, print
.
Різні визначення зрозумілі, коли мова аналізується комбінацією лексичного і синтаксичного аналізатора, а синтаксис мови генерується лексичною граматикою для слів, а контекстно-вільна граматика правилом породження (також називається правилом продукції) для фраз. Це характерно для аналізу сучасних мов, і в даному випадку ключові слова є підмножиною зарезервованих слів, оскільки вони повинні відрізнятися від ідентифікаторів на рівні слова (як зарезервовані слова) для синтаксичного аналізу відрізнятися на рівні фрази (як ключові слова).
У цьому випадку зарезервовані слова визначаються як частина лексичної граматики, і кожен з них маркується як окремий тип, відмінний від ідентифікаторів. Зазвичай зарезервовані слова, if
та then
, наприклад, маркуються як типи IF
і THEN
, відповідно, тоді як x
та y
обидва марковані як тип Identifier
.
Ключові слова, навпаки, синтаксично з'являються у фразі граматики, як термінальні символи. Наприклад, породжувальне правило для умовного виразу може бути IF Expression THEN Expression
. В цьому випадку IF
та THEN
— термінальні символи, які означають «токени типу IF
або THEN
, відповідно» — і згідно з граматикою це вказує на рядок if
або then
в первісному джерелі. Як приклад примітивного значення константи, true
може бути ключовим словом, що представляє логічне значення «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
до мови Java, оскільки воно була зарезервованим, але наразі не використовується; Однак ця пропозиція була відхилена — зокрема, тому, що навіть незважаючи на додавання функції робота існуючих програм не буде порушеною, використовуючи const
в стандартній бібліотеці (а зокрема, в колекціях) буде порушуватись сумісність.[7] JavaScript також містить ряд зарезервованих слів без особливої функціональності; точний список залежить від версії та режиму.[8]
Мови істотно відрізняються тим, як часто вони запроваджують нові зарезервовані слова або ключові слова, і як вони називають їх, деякі мови дуже консервативні та вводять нові ключові слова рідко або навіть ніколи, щоб уникнути порушення існуючих програм, тоді як інші мови запроваджують нові ключові слова більш вільно, вимагаючи змінювати існуючі програми а саме змінювати ідентифікатори які конфліктують. Створили певні правила для додавання нових ключових слів в C11 порівняно з C++ 11, обидва з 2011 р. — нагадуємо, що в C і C++ ідентифікатори, які починаються з підкреслення, за яким йде літера верхнього регістру є зарезервованими:[9]
Комітет С вважає, що краще не створювати нові ключові слова в просторі імен користувачів, оскільки, як правило, очікується, що кожна переробка чи оновлення С дозволить уникнути порушення сумісності зі старими програмами С. Для порівняння, комітет C++ (WG21) вважає, що краще створювати нові ключові слова як старі ключові слова. Наприклад, C++ 11 визначає нове ключове слово thread_local для позначення статичної пам'яті локальної для одного потоку. C11 визначає нове ключове слово як _Thread_local. У новому заголовку C11 <thread.h> існує визначення макросу, щоб забезпечити нормальне відображення імені: [10]
- #define thread_local _Thread_local
Тобто, C11 представив ключове слово _Thread_local в межах існуючого набору зарезервованих слів (воно з певним префіксом), а потім використовував окремий об'єкт (обробка макросів), щоб дозволити його використання, так щоб б це було як нове ключове слово без префікса, а C++ 11 вводять ключове слово thread_local, незважаючи на те, що це не є існуючим зарезервованим словом, що може порушити деякі програми, які використовували його, але не вимагаючи обробки макросів.
Попередньо визначені імена
Пов'язаним поняттям зарезервованих слів є попередньо визначені функції, методи, підпрограми або змінні, зокрема бібліотека підпрограм зі стандартної бібліотеки. Вони подібні тим, що вони є частиною основної мови і можуть використовуватися для подібних цілей. Однак вони відрізняються тим, що назва попередньо визначеної функції, методу або підпрограми зазвичай класифікується як ідентифікатор замість зарезервованого слова і не розглядається спеціально в синтаксичному аналізі. Далі, зарезервовані слова не можуть бути перевизначені програмістом, але попередньо задані імена часто можуть бути перевизначені в певній мірі.
Мови відрізняються залежно від того, що задано як ключове слово, і що є попередньо визначеним іменем. Деякі мови, наприклад, забезпечують ключові слова для операцій введення / виводу, тоді як в інших це бібліотечні підпрограми. У Python (версії до 3.0) і багатьох діалектах BASIC print
є ключовим словом. А в C, Lisp і Python 3.0 printf
, format
і print
є функціями в стандартній бібліотеці. Аналогічно, в Python до 3.0, None
, True
і False
були попередньо визначені змінні, але не зарезервовані слова, але в Python 3.0 це зарезервовані слова.[11]
Визначення
Деякі використовують терміни «ключове слово» та «зарезервоване слово» як взаємозамінні, в той час як інші розрізняють за використанням, скажімо, за допомогою «ключового слова» визначають слово, яке є спеціальним лише в певних контекстах, а «зарезервоване слово» означає спеціальне слово, яке не можна використовувати як визначене користувачем ім'я. Значення ключових слів — і суть поняття ключового слова — дуже відрізняється від мови до мови. Конкретно, в ALGOL 68 ключові слова є рядком (в суворих правилах мови, написані жирним шрифтом) і не є зарезервованими словами — слово яке не є рядком може використовуватися як звичайний ідентифікатор.
«Java Language Specification» використовує термін «ключове слово».[12] Стандарт ISO 9899 для мови програмування C використовує термін «ключове слово».[13]
У багатьох мовах, таких як C і подібні їй, як C++, ключове слово є зарезервованим словом, що ідентифікує синтаксичну форму. Слова, що використовуються в конструкціях потоків керування, такі як if
, then
та else
є ключовими словами. У цих мовах ключові слова також не можуть використовуватися як імена змінних або функцій.
У деяких мовах, таких як ALGOL і ALGOL 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
можуть бути реалізовані як макроси або функції. У мовах без цих виразних функцій вони зазвичай є ключовими словами.
Порівняння за мовою
Не всі мови мають однакову кількість зарезервованих слів. Наприклад, Java (та інші C-подібні мови) має досить малу кількість зарезервованих слів — приблизно 50 — тоді як COBOL має приблизно 400. А чистий Prolog і PL/I взагалі не мають.
Кількість зарезервованих слів на мові мало пов'язана з тим, наскільки «потужною» є мова. COBOL був розроблений у 1950-х роках як бізнес-мова і був зроблений як самодокументація з використанням англійських структурних елементів, таких як дієслова, статті, речення, розділи та підрозділи. C, з іншого боку, був написаний дуже суворо (синтаксично). Наприклад, порівняйте еквівалентні блоки коду з C і COBOL, щоб обчислити щотижневий прибуток:
// Обчислення на C:
if (salaried)
amount = 40 * payrate;
else
amount = hours * payrate;
*> Обчислення на COBOL:
IF Salaried THEN
MULTIPLY Payrate BY 40 GIVING Amount
ELSE
MULTIPLY Payrate BY Hours GIVING Amount
END-IF.
*> Інший приклад обчислення на COBOL:
IF Salaried
COMPUTE Amount = Payrate * 40
ELSE
COMPUTE Amount = hours * payrate
END-IF.
Логіка чистого Prolog виражається в термінах залежностей, а виконання виконується за допомогою виконання запитів над цими залежностями. Конструкції, такі як цикл, реалізуються з використанням рекурсії.
Всі ці три мови можуть вирішувати однакові типи «проблем», навіть якщо вони мають різну кількість зарезервованих слів. Ця «потужність» пов'язана з їхньою приналежністю до множини мов, що входять до складу мов які є повними за Тюрингом.
Недоліки
Визначення зарезервованих слів викликає проблеми. Можливо, новим користувачам буде важко вивчати мову через довгий список зарезервованих слів, які слід запам'ятати, які не можна використовувати як ідентифікатори. Може бути важко розширити мову, оскільки додавання зарезервованих слів для нових функцій може призвести до непрацездатності існуючих програм або, навпаки, «перевантаження» існуючих зарезервованих слів новими значеннями може призвести до плутанини. Перенесення програм може бути проблематичним, оскільки слово, не зарезервоване однією системою / компілятором, може бути зарезервоване іншим.
Зарезервовані слова та мовна незалежність
Microsoft's .NET Common Language Infrastructure дозволяє коду, написаному на 40+ різних мовах програмування, об'єднати в кінцевий продукт. Через це конфлікти ідентифікаторів / зарезервованих слів можуть відбуватися, коли код, реалізований однією мовою, намагається виконати код, написаний іншою мовою. Наприклад, бібліотека Visual Basic.NET може містити визначення класу, таке як:
' Визначення класу в Visual Basic.NET:
Public Class this
' This class does something...
End Class
Якщо це скомпільовано та розповсюджено як частину набору інструментів, програміст C#, який бажає визначити змінну типу «this
», може зіткнутися з проблемою: 'this'
є зарезервованим словом у C#. Таким чином, наступне не може бути скомпільованим в C#:
// Використання цього класу в C#:
this x = new this(); // Не буде скомпільовано
Аналогічна проблема виникає при доступі до членів, перевизначенні віртуальних методів і ідентифікації просторів імен. Це вирішується за допомогою строппінгу. Для того, щоб усунути цю проблему, специфікація дозволяє програмісту розмістити (у C#) знак перед ідентифікатором, який змушує компілятор вважати його ідентифікатором, а не зарезервованим словом:
// Використання цього класу в C#:
@this x = new @this(); // Буде скомпільовано!
Для узгодженості це використання також дозволено в непублічних параметрах, таких як локальні змінні, імена параметрів та приватні члени.
Див. також
- Список зарезервованих слів мови Java
- Символ (програмування)
Список літератури
- C99 specification, 7.1.3 Reserved identifiers
- C++03 specification, 17.4.3.2.1 Global names [lib.global.names]
- Jackson, Mark (26 вересня 2002). How do you pronounce "__" (double underscore)?. python-list mailing list. Процитовано 9 листопада 2014.
- Hochberg, Tim (26 вересня 2002). How do you pronounce "__" (double underscore)?. python-list mailing list. Процитовано 9 листопада 2014.
- Dunder (Double UNDERscore) Alias
- Notz, Pat (26 вересня 2002). How do you pronounce "__" (double underscore)?. python-list mailing list. Процитовано 9 листопада 2014.
- Bug ID: JDK-4211070 Java should support const parameters (like C++) for code maintainence [sic]. Bugs.sun.com. Процитовано 4 листопада 2014.
- Lexical grammar: Keywords
- C99 specification, 7.1.3 Reserved identifiers: «All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.»
- C11:The New C Standard, Thomas Plum, "A Note on Keywords"
- «The story of None, True and False (and an explanation of literals, keywords and builtins thrown in)», The History of Python, November 10, 2013, Guido van Rossum
- The Java Language Specification, 3rd Edition, Section 3.9: Keywords. Sun Microsystems. 2000. Процитовано 17 червня 2009. «The following character sequences, formed from ASCII letters, are reserved for use as keywords and cannot be used as identifiers[...]»
- ISO/IEC 9899:TC3, Section 6.4.1: Keywords. International Organization for Standardization JTC1/SC22/WG14. 7 вересня 2007. «The above tokens (case sensitive) are reserved (in translation phases 7 and 8) for use as keywords, and shall not be used otherwise.»
- Peter Norvig: Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp, Morgan Kaufmann, 1991, ISBN 1-55860-191-0, Web
- Type KEYWORD from the Common Lisp HyperSpec
- Constraints on the COMMON-LISP Package for Conforming Programs.