En un lenguaje informático , una palabra reservada (también conocida como identificador reservado ) es una palabra que no se puede utilizar como identificador , como el nombre de una variable, función o etiqueta ; está "reservada para su uso". Esta es una definición sintáctica y una palabra reservada puede no tener un significado definido por el usuario.
Una noción estrechamente relacionada y que a menudo se confunde es la de palabra clave , que es una palabra con un significado especial en un contexto particular. Se trata de una definición semántica . Por el contrario, los nombres que se encuentran en una biblioteca estándar pero que no están integrados en un lenguaje no se consideran palabras reservadas o palabras clave. Los términos "palabra reservada" y "palabra clave" se suelen utilizar indistintamente (se puede decir que una palabra reservada está "reservada para su uso como palabra clave") y el uso formal varía de un idioma a otro. Para este artículo, distinguimos lo anterior.
En general, las palabras reservadas y las palabras clave no tienen por qué coincidir, pero en la mayoría de los lenguajes modernos las palabras clave son un subconjunto de las palabras reservadas, ya que esto facilita el análisis, ya que las palabras clave no se pueden confundir con los identificadores. En algunos lenguajes, como C o Python , las palabras reservadas y las palabras clave coinciden, mientras que en otros lenguajes, como Java , todas las palabras clave son palabras reservadas, pero algunas palabras reservadas no son palabras clave, ya que se reservan para un uso futuro. En otros lenguajes, como los lenguajes más antiguos ALGOL , FORTRAN y PL/I , hay palabras clave pero no palabras reservadas, y las palabras clave se distinguen de los identificadores por otros medios.
Los conjuntos de palabras reservadas y palabras clave de un idioma suelen coincidir o ser casi iguales, y la distinción es sutil, por lo que los términos suelen usarse indistintamente. Sin embargo, si se usan con cuidado, se pueden distinguir.
Hacer que las palabras clave sean palabras reservadas facilita el análisis léxico , ya que una cadena de caracteres será inequívocamente una palabra clave o un identificador, sin depender del contexto; por lo tanto, las palabras clave suelen ser un subconjunto de palabras reservadas. Sin embargo, las palabras reservadas no necesitan ser palabras clave. Por ejemplo, en Java, goto
es una palabra reservada, pero no tiene significado y no aparece en ninguna regla de producción en la gramática. Esto generalmente se hace por compatibilidad con versiones posteriores , por lo que una palabra reservada puede convertirse en una palabra clave en una versión futura sin afectar los programas existentes.
Por el contrario, las palabras clave no necesitan ser palabras reservadas, con su función entendida a partir del contexto, o pueden distinguirse de otra manera, como por ejemplo mediante el uso de un stropping . Por ejemplo, la frase if = 1
es inequívoca en la mayoría de las gramáticas, ya que una declaración de control de una cláusula if no puede comenzar con un =
, y por lo tanto está permitida en algunos lenguajes, como FORTRAN . Alternativamente, en ALGOL 68 , las palabras clave deben estar marcadas de alguna manera para distinguirse en el lenguaje estricto mediante su inclusión en negrita, y por lo tanto no son palabras reservadas. Por lo tanto, en el lenguaje estricto la siguiente expresión es legal, ya que la palabra clave if en negrita no entra en conflicto con el identificador ordinario if
:
Sin embargo, en ALGOL 68 también hay un régimen de restricción en el que las palabras clave son palabras reservadas, un ejemplo de cómo estos conceptos distintos a menudo coinciden; esto se sigue en muchos idiomas modernos.
Una palabra reservada es aquella que "parece" una palabra normal, pero no se permite utilizarla como tal. Formalmente, esto significa que satisface la sintaxis léxica habitual (sintaxis de las palabras) de los identificadores (por ejemplo, ser una secuencia de letras), pero no se puede utilizar donde se utilizan identificadores. Por ejemplo, la palabra if
es comúnmente una palabra reservada, mientras que por x
lo general no lo es, por lo que x = 1
es una asignación válida, pero if = 1
no lo es.
Las palabras clave tienen usos variados, pero principalmente se dividen en unas pocas clases: parte de la gramática de frases (específicamente una regla de producción con símbolos no terminales ), con varios significados, que a menudo se usa para el flujo de control , como la palabra if
en la mayoría de los lenguajes procedimentales, que indica una cláusula condicional y toma (los símbolos no terminales); nombres de tipos primitivos en un lenguaje que admite un sistema de tipos , como ; valores literalesint
primitivos como para Boolean true; o, a veces, comandos especiales como . Otros usos de palabras clave en frases son para entrada/salida, como .true
exit
print
Las definiciones distintas son claras cuando se analiza un idioma mediante una combinación de un analizador léxico y un analizador sintáctico, y la sintaxis del idioma se genera mediante una gramática léxica para las palabras y una gramática independiente del contexto de reglas de producción para las frases. Esto es común en el análisis de idiomas modernos y, en este caso, las palabras clave son un subconjunto de las palabras reservadas, ya que deben distinguirse de los identificadores a nivel de palabra (por lo tanto, palabras reservadas) para ser analizadas sintácticamente de manera diferente a nivel de frase (como palabras clave).
En este caso, las palabras reservadas se definen como parte de la gramática léxica y cada una de ellas se tokeniza como un tipo separado, distinto de los identificadores. En la notación convencional, las palabras reservadas if
y, then
por ejemplo, se tokenizan como tipos IF
y THEN
, respectivamente, mientras que x
y y
se tokenizan como tipo Identifier
.
Las palabras clave, por el contrario, aparecen sintácticamente en la gramática de frases como símbolos terminales . Por ejemplo, la regla de producción para una expresión condicional puede ser IF Expression THEN Expression
. En este caso IF
y THEN
son símbolos terminales, que significan "un token de tipo IF
o THEN
, respectivamente" - y debido a la gramática léxica, esto significa la cadena if
o then
en la fuente original. Como ejemplo de un valor constante primitivo, true
puede ser una palabra clave que represente el valor booleano "verdadero", en cuyo caso debería aparecer en la gramática como una posible expansión de la producción BinaryExpression
, por ejemplo.
Además de reservar listas específicas de palabras, algunos idiomas reservan rangos enteros de palabras para usarlos como espacios privados para futuras versiones del idioma, dialectos diferentes, extensiones específicas del proveedor del compilador o para uso interno de un compilador, en particular en la alteración de nombres .
Esto se hace más a menudo usando un prefijo, a menudo uno o más guiones bajos . C y C++ son notables en este sentido: C99 reserva los identificadores que comienzan con dos guiones bajos o un guión bajo seguido de una letra mayúscula, y reserva además los identificadores que comienzan con un solo guión bajo (en los espacios ordinarios y de etiqueta) para su uso en el ámbito de archivo ; [1] con C++03 reserva además los identificadores que contienen un guión bajo doble en cualquier lugar [2] – esto permite el uso de un guión bajo doble como separador (para conectar identificadores de usuario), por ejemplo.
El uso frecuente de guiones bajos dobles en identificadores internos en Python dio lugar a la abreviatura dunder; esta fue acuñada por Mark Jackson [3] e independientemente por Tim Hochberg, [4] con minutos de diferencia, ambos en respuesta a la misma pregunta en 2002. [5] [6]
La lista de palabras reservadas y palabras clave en un lenguaje se define cuando se desarrolla un lenguaje, y ambas forman parte de la especificación formal de un lenguaje . Generalmente se desea minimizar la cantidad de palabras reservadas, para evitar restringir los nombres de identificadores válidos. Además, la introducción de nuevas palabras reservadas rompe los programas existentes que usan esa palabra (no es compatible con versiones anteriores), por lo que esto se evita. Para evitar esto y proporcionar compatibilidad con versiones posteriores , a veces se reservan palabras sin tener un uso actual (una palabra reservada que no es una palabra clave), ya que esto permite que la palabra se use en el futuro sin romper los programas existentes. Alternativamente, se pueden implementar nuevas características del lenguaje como predefinidas, que se pueden anular, sin romper los programas existentes.
Las razones para la flexibilidad incluyen permitir que los proveedores de compiladores extiendan la especificación al incluir características no estándar, diferentes dialectos estándar del lenguaje para extenderla o futuras versiones del lenguaje para incluir características adicionales. Por ejemplo, un lenguaje procedimental puede anticipar la adición de capacidades orientadas a objetos en una versión futura o algún dialecto, en cuyo punto se podrían agregar palabras clave como class
o object
. Para dar cabida a esta posibilidad, la especificación actual puede hacer que estas palabras sean reservadas, incluso si no se utilizan actualmente.
Un ejemplo notable es Java , donde const
y goto
son palabras reservadas: no tienen significado en Java, pero tampoco se pueden usar como identificadores. Al reservar los términos, se pueden implementar en futuras versiones de Java, si se desea, sin romper el código fuente de Java anterior. Por ejemplo, hubo una propuesta en 1999 para agregar C++-like const
al lenguaje, lo que era posible usando la const
palabra, ya que estaba reservada pero actualmente no se usaba; sin embargo, esta propuesta fue rechazada, en particular porque, aunque agregar la característica no rompería ningún programa existente, usarla en la biblioteca estándar (especialmente en colecciones) rompería la compatibilidad. [7] JavaScript también contiene una serie de palabras reservadas sin funcionalidad especial; la lista exacta varía según la versión y el modo. [8]
Los lenguajes difieren significativamente en la frecuencia con la que introducen nuevas palabras reservadas o palabras clave y en cómo las nombran. Algunos lenguajes son muy conservadores e introducen palabras clave nuevas rara vez o nunca, para evitar romper los programas existentes, mientras que otros lenguajes introducen nuevas palabras clave con más libertad, lo que requiere que los programas existentes cambien los identificadores existentes que entran en conflicto. Un estudio de caso lo dan las nuevas palabras clave en C11 en comparación con C++11 , ambas de 2011; recuerde que en C y C++, los identificadores que comienzan con un guión bajo seguido de una letra mayúscula están reservados: [9]
El comité C prefiere no crear nuevas palabras clave en el espacio de nombres de usuario, ya que generalmente se espera que cada revisión de C evite romper los programas C más antiguos. En comparación, el comité C++ (WG21) prefiere hacer que las nuevas palabras clave tengan un aspecto tan normal como las antiguas. Por ejemplo, C++11 define una nueva
thread_local
palabra clave para designar el almacenamiento estático local de un hilo. C11 define la nueva palabra clave como_Thread_local.
En el nuevo encabezado C11 <threads.h>, hay una definición de macro para proporcionar el nombre de aspecto normal: [10]
#define thread_local _Thread_local
Es decir, C11 introdujo la palabra clave _Thread_local
dentro de un conjunto existente de palabras reservadas (aquellas con un prefijo determinado), y luego utilizó una función separada (procesamiento de macro) para permitir su uso como si fuera una nueva palabra clave sin ningún prefijo, mientras que C++11 introdujo la palabra clave thread_local
a pesar de que esta no era una palabra reservada existente, rompiendo cualquier programa que la usara, pero sin requerir procesamiento de macro.
Un concepto relacionado con las palabras reservadas son las funciones, métodos, subrutinas, tipos o variables predefinidos, en particular las rutinas de biblioteca de la biblioteca estándar. Son similares en el sentido de que forman parte del lenguaje básico y pueden utilizarse para fines similares. Sin embargo, difieren en que el nombre de una de estas entidades suele clasificarse como un identificador en lugar de una palabra reservada y no se trata de forma especial en el análisis sintáctico. Además, el programador no puede redefinir las palabras reservadas, pero las predefinidas a menudo pueden anularse en la medida de lo posible .
Los lenguajes varían en cuanto a lo que se proporciona como palabra clave y lo que es predefinido. Algunos lenguajes, por ejemplo, proporcionan palabras clave para operaciones de entrada/salida, mientras que en otros son rutinas de biblioteca. En Python (versiones anteriores a la 3.0) y muchos dialectos de BASICprint
, es una palabra clave. Por el contrario, los equivalentes de C, Lisp y Python 3.0 printf
, format
, y print
son funciones de la biblioteca estándar. De manera similar, en Python anterior a la 3.0, None
, True
y False
eran variables predefinidas, pero no palabras reservadas, pero en Python 3.0 se convirtieron en palabras reservadas. [11]
Algunos utilizan los términos "palabra clave" y "palabra reservada" indistintamente, mientras que otros distinguen su uso, por ejemplo, utilizando "palabra clave" para referirse a una palabra que es especial solo en ciertos contextos, pero "palabra reservada" para referirse a una palabra especial que no se puede utilizar como un nombre definido por el usuario. El significado de las palabras clave, y el significado de la noción de palabra clave , difiere ampliamente de un idioma a otro. Concretamente, en ALGOL 68, las palabras clave se escriben con acento circunflejo (en el lenguaje estricto, en negrita) y no son palabras reservadas; la palabra sin acento circunflejo se puede utilizar como un identificador ordinario.
La " Especificación del lenguaje Java " utiliza el término "palabra clave". [12] La norma ISO 9899 para el lenguaje C utiliza el término "palabra clave". [13]
En muchos lenguajes, como C y entornos similares como C++ , una palabra clave es una palabra reservada que identifica una forma sintáctica. Las palabras que se utilizan en las construcciones de flujo de control , como if
, then
y else
son palabras clave. En estos lenguajes, las palabras clave no se pueden utilizar también como nombres de variables o funciones.
En algunos lenguajes, como ALGOL y ALGOL 68 , las palabras clave no se pueden escribir textualmente, sino que deben marcarse con un carácter especial. Esto significa que las palabras clave se deben marcar de alguna manera, por ejemplo, entrecomillándolas o anteponiéndoles un carácter especial. En consecuencia, las palabras clave no son palabras reservadas y, por lo tanto, la misma palabra se puede utilizar como identificador normal. Sin embargo, un régimen de marcado con un carácter especial consistía en no marcar las palabras clave y, en su lugar, hacer que fueran simplemente palabras reservadas.
Algunos lenguajes, como PostScript , son extremadamente liberales en este enfoque, permitiendo que las palabras clave principales se redefinan para propósitos específicos.
En Common Lisp , el término "palabra clave" (o "símbolo de palabra clave") se utiliza para un tipo especial de símbolo o identificador. A diferencia de otros símbolos, que normalmente representan variables o funciones, las palabras clave se citan y evalúan a sí mismas [14] :98 y están internas en el KEYWORD
paquete. [15] Las palabras clave se utilizan normalmente para etiquetar argumentos nombrados para funciones y para representar valores simbólicos. Los símbolos que nombran funciones, variables, formas especiales y macros en el paquete llamado COMMON-LISP son básicamente palabras reservadas. El efecto de redefinirlas no está definido en ANSI Common Lisp. [16] Es posible vincularlas. Por ejemplo, (if if case or)
es posible la expresión, cuando if
es una variable local. El más a la izquierda if
se refiere al if
operador; los símbolos restantes se interpretan como nombres de variable. Dado que hay un espacio de nombres separado para funciones y variables, if
podría ser una variable local. En Common Lisp, sin embargo, hay dos símbolos especiales que no están en el paquete de palabras clave: los símbolos t
y nil
. Cuando se evalúan como expresiones, se evalúan a sí mismos. No se pueden utilizar como nombres de funciones o variables, por lo que están reservados de facto. (let ((t 42)))
es una expresión bien formada, pero el let
operador no permitirá su uso.
Normalmente, cuando un programador intenta utilizar una palabra clave para el nombre de una variable o función, se genera un error de compilación. En la mayoría de los editores modernos, las palabras clave se configuran automáticamente para que tengan un color de texto particular para recordar o informar a los programadores que son palabras clave.
En lenguajes con macros o evaluación diferida , las construcciones de flujo de control como if
pueden implementarse como macros o funciones. En lenguajes sin estas características expresivas, generalmente son palabras clave.
Los distintos lenguajes suelen tener cantidades muy variables de palabras reservadas. Por ejemplo, COBOL tiene unas 400. Java y otros derivados de C tienen un conjunto bastante escaso, unas 50. Prolog y PL/I puros no tienen ninguna.
La definición de palabras reservadas en un lenguaje plantea problemas. El lenguaje puede resultar difícil de aprender para los nuevos usuarios debido a una larga lista de palabras reservadas que memorizar y que no se pueden usar como identificadores. Puede resultar difícil ampliar el lenguaje porque la adición de palabras reservadas para nuevas funciones puede invalidar los programas existentes o, por el contrario, la "sobrecarga" de palabras reservadas existentes con nuevos significados puede resultar confusa. La migración de programas puede ser problemática porque una palabra que no está reservada por un sistema o compilador puede estar reservada por otro.
Debido a que las palabras reservadas no se pueden usar como identificadores, los usuarios pueden elegir errores ortográficos deliberados de palabras reservadas como identificadores, como en clazz
el caso de las variables Java de tipo Class
. [17]
La especificación de infraestructura de lenguaje común (CLI) .NET de Microsoft permite combinar código escrito en más de 40 lenguajes de programación diferentes para formar un producto final. Por este motivo, pueden producirse colisiones entre identificadores y palabras reservadas cuando el código implementado en un lenguaje intenta ejecutar código escrito en otro. Por ejemplo, una biblioteca de Visual Basic (.NET) puede contener una definición de clase como la siguiente:
' Definición de clase de This en Visual Basic.NET:Clase pública this ' Esta clase hace algo... Fin de clase
Si esto se compila y distribuye como parte de una caja de herramientas, un programador de C# que desee definir una variable de tipo " this
" se encontrará con un problema: 'this'
es una palabra reservada en C#. Por lo tanto, lo siguiente no se compilará en C#:
// Usando esta clase en C#:esto x = nuevo esto (); // ¡No se compilará!
Un problema similar surge al acceder a miembros, anular métodos virtuales e identificar espacios de nombres.
Esto se resuelve con stropping . Para solucionar este problema, la especificación permite colocar (en C#) el signo arroba antes del identificador, lo que obliga al compilador a considerarlo un identificador en lugar de una palabra reservada:
// Usando esta clase en C#:@this x = new @this (); // ¡Se compilará!
Para mantener la coherencia, este uso también está permitido en configuraciones no públicas, como variables locales, nombres de parámetros y miembros privados.
Las siguientes secuencias de caracteres, formadas a partir de letras ASCII, están reservadas para su uso como palabras clave y no pueden utilizarse como identificadores [...]
Los símbolos anteriores (que distinguen entre mayúsculas y minúsculas) están reservados (en las fases de traducción 7 y 8) para su uso como palabras clave y no se deben utilizar de otro modo.