Forma de Backus-Naur
En informática, la forma de Backus-Naur () o forma normal de Backus (BNF) es una notación de metasintaxis para gramáticas independientes del contexto., a menudo utilizado para describir la sintaxis de los lenguajes utilizados en la informática, como los lenguajes de programación de computadoras, formatos de documentos, conjuntos de instrucciones y protocolos de comunicación. Se aplica dondequiera que se necesiten descripciones exactas de los lenguajes: por ejemplo, en las especificaciones oficiales del lenguaje, en manuales y en libros de texto sobre teoría de lenguajes de programación.
Se utilizan muchas extensiones y variantes de la notación original de Backus-Naur; algunos están definidos exactamente, incluida la forma Backus-Naur extendida (EBNF) y la forma Backus-Naur aumentada (ABNF).
Resumen
Una especificación BNF es un conjunto de reglas de derivación, escritas como
.símbolo■ ::= __expresion__
donde:
- ################################################################################################################################################################################################################################################################ nonterminal (variable) y el __expression__ consiste en una o más secuencias de símbolos terminales o no terminales;
::=
significa que el símbolo de la izquierda debe ser reemplazado por la expresión de la derecha.- más secuencias [de símbolos] están separadas por la barra vertical "vivir", indicando una opción, todo es una posible sustitución para el símbolo de la izquierda.
Los símbolos que nunca aparecen en el lado izquierdo son terminales. Por otro lado, los símbolos que aparecen en el lado izquierdo son no terminales y siempre están encerrados entre el par <>.
Ejemplo
Como ejemplo, considere este posible BNF para una dirección postal de EE. UU.:
.dirección postal■ ::= .name-part■ .calle-address■ .zip-part■ .name-part■ ::= .personal-part■ .apellido■ .opt-suffix-part■ .EOL■ Silencio .personal-part■ .name-part■ .personal-part■ ::= .inicial■ ". .primer nombre■ .calle-address■ ::= .house-num■ .calle-nombre■ .opt-apt-num■ .EOL■ .zip-part■ ::= .nombre de ciudad■ " .código estatal■ .ZIP-code■ .EOL■.opt-suffix-part■ ::= Señor. .roman-numeral■ Silencio "
.opt-apt-num■ ::= .apt-num■ Silencio "
Esto se traduce al inglés como:
- Una dirección postal consiste en una parte de nombre, seguida de una parte de dirección callejera, seguida de una parte de código postal.
- Una parte de nombre consiste en: una parte personal seguida de un apellido seguido de un sufijo opcional (Jr., Sr., o número dinástico) y final de línea, o una parte personal seguida de una parte de nombre (esta regla ilustra el uso de la recursión en BNFs, cubriendo el caso de las personas que usan nombres primarios e iniciales múltiples).
- Una parte personal consiste en un nombre o una inicial seguida de un punto.
- Una dirección callejera consta de un número de casa, seguido de un nombre callejero, seguido de un especificador de apartamento opcional, seguido de un extremo de línea.
- Una parte de cremallera consiste en un nombre de ciudad, seguido de un coma, seguido de un código de estado, seguido de un código ZIP seguido por un extremo de línea.
- Un opt-suffix-part consta de un sufijo, como "Sr.", "Jr." o un roman-numeral, o una cadena vacía (es decir, nada).
- Un opt-apt-num consta de un número de apartamento o una cadena vacía (es decir, nada).
Tenga en cuenta que muchas cosas (como el formato del nombre, el número de apartamento, el código postal y el número romano) no se especifican aquí. Si es necesario, pueden describirse utilizando reglas BNF adicionales.
Historia
La idea de describir la estructura del lenguaje usando reglas de reescritura se remonta al menos al trabajo de Pāṇini, un gramático del antiguo sánscrito indio y un reverenciado erudito del hinduismo que vivió en algún momento entre los siglos VI y IV a.C. Su notación para describir la estructura de las palabras en sánscrito es equivalente en poder a la de Backus y tiene muchas propiedades similares.
En la sociedad occidental, la gramática se consideró durante mucho tiempo como un tema de enseñanza, más que de estudio científico; las descripciones eran informales y estaban dirigidas al uso práctico. En la primera mitad del siglo XX, lingüistas como Leonard Bloomfield y Zellig Harris iniciaron intentos de formalizar la descripción del lenguaje, incluida la estructura de las frases.
Mientras tanto, matemáticos como Axel Thue (en 1914), Emil Post (décadas de 1920 a 1940) y Alan Turing (1936) introdujeron y estudiaron las reglas de reescritura de cadenas como sistemas lógicos formales. Noam Chomsky, enseñando lingüística a estudiantes de teoría de la información en el MIT, combinó lingüística y matemáticas tomando lo que es esencialmente el formalismo de Thue como base para la descripción de la sintaxis del lenguaje natural. También introdujo una distinción clara entre las reglas generativas (las de las gramáticas libres de contexto) y las reglas de transformación (1956).
John Backus, un diseñador de lenguajes de programación de IBM, propuso un metalenguaje de "fórmulas metalingüísticas" describir la sintaxis del nuevo lenguaje de programación IAL, conocido hoy como ALGOL 58 (1959). Su notación se utilizó por primera vez en el informe ALGOL 60.
BNF es una notación para las gramáticas independientes del contexto de Chomsky. Backus estaba familiarizado con el trabajo de Chomsky.
Como propuso Backus, la fórmula definía "clases" cuyos nombres están encerrados entre paréntesis angulares. Por ejemplo, <ab>. Cada uno de estos nombres denota una clase de símbolos básicos.
Un mayor desarrollo de ALGOL condujo a ALGOL 60. En el informe del comité de 1963, Peter Naur llamó a la notación de Backus forma normal de Backus. Donald Knuth argumentó que BNF debería leerse más bien como forma Backus-Naur, ya que "no es una forma normal en el sentido convencional", a diferencia, por ejemplo, de la forma normal de Chomsky. El nombre forma Pāṇini Backus también se sugirió una vez en vista del hecho de que la expansión forma normal de Backus puede no ser precisa, y que Pāṇini había desarrollado de forma independiente una notación similar anteriormente.
BNF es descrito por Peter Naur en el informe ALGOL 60 como fórmula metalingüística:
Las secuencias de caracteres encerrados en los corchetes representan variables metálicas cuyos valores son secuencias de símbolos. Las marcas ":=" y "vivir" (este último con el significado de "o") son conectividad metalinguística. Cualquier marca en una fórmula, que no es una variable o una conexión, se denota. Juxtaposición de marcas o variables en una fórmula significa yuxtaposición de la secuencia denotada.
Otro ejemplo del informe ALGOL 60 ilustra una gran diferencia entre el metalenguaje BNF y una gramática independiente del contexto de Chomsky. Las variables metalingüísticas no requieren una regla que defina su formación. Su formación puede describirse simplemente en lenguaje natural dentro de <> soportes. La siguiente especificación de comentarios de la sección 2.3 del informe ALGOL 60 ejemplifica cómo funciona esto:
Con el propósito de incluir texto entre los símbolos de un programa, las siguientes convenciones "comiendas" sostienen:
La secuencia de símbolos básicos: equivale a ; comentario No contiene ninguna secuencia: ; comenzar comentario No contiene ninguna secuencia: comenzar final Secuencia no contiene 'fin' o ';' o 'else' final Equivalencia aquí significa que cualquiera de las tres estructuras mostradas en la columna izquierda puede ser reemplazada, en cualquier ocurrencia fuera de las cuerdas, por el símbolo mostrado en la misma línea en la columna derecha sin ningún efecto en la acción del programa.
Naur cambió dos de los símbolos de Backus por caracteres comúnmente disponibles. El símbolo ::=
era originalmente un :≡
. El símbolo |
era originalmente la palabra "o" (con una barra encima).
BNF es muy similar a las ecuaciones de álgebra booleana de forma canónica que se usaban, y se usaban en ese momento, en el diseño de circuitos lógicos. Backus fue matemático y diseñador del lenguaje de programación FORTRAN. Los estudios de álgebra booleana son comúnmente parte de un plan de estudios de matemáticas. Ni Backus ni Naur describieron los nombres incluidos en < >
como no terminales. La terminología de Chomsky no se usó originalmente para describir la BNF. Naur los describió más tarde como clases en materiales del curso ALGOL. En el informe ALGOL 60 se denominaron variables metalingüísticas. Todo lo que no sea los metasímbolos ::=
, |
y los nombres de clase incluidos en < >
son símbolos del idioma que se está definiendo. El metasímbolo ::=
debe interpretarse como "se define como". El |
se utiliza para separar definiciones alternativas y se interpreta como "o". Los metasímbolos < >
son delimitadores que encierran un nombre de clase. BNF se describe como un metalenguaje para hablar sobre ALGOL por Peter Naur y Saul Rosen.
En 1947, Saul Rosen se involucró en las actividades de la incipiente Association for Computing Machinery, primero en el comité de idiomas que se convirtió en el grupo IAL y finalmente en ALGOL. Fue el primer editor gerente de Comunicaciones de la ACM. BNF se utilizó por primera vez como metalenguaje para hablar sobre el lenguaje ALGOL en el informe ALGOL 60. Así es como se explica en el material del curso de programación ALGOL desarrollado por Peter Naur en 1962. Los primeros manuales ALGOL de IBM, Honeywell, Burroughs y Digital Equipment Corporation siguieron al informe ALGOL 60 usándolo como metalenguaje. Saul Rosen en su libro describe BNF como un metalenguaje para hablar de ALGOL. Un ejemplo de su uso como metalenguaje sería en la definición de una expresión aritmética:
.expreso■ ::= .mandato■Silencio.expreso■.addop■.mandato■
El primer símbolo de una alternativa puede ser la clase que se está definiendo, la repetición, como explica Naur, tiene la función de especificar que la secuencia alternativa puede comenzar recursivamente con una alternativa anterior y puede repetirse cualquier número de veces. Por ejemplo, el <expr>
anterior se define como un <term>
seguido de cualquier número de <addop> <término>.
En algunos metalenguajes posteriores, como Schorre's META II, la construcción de repetición recursiva BNF se reemplaza por un operador de secuencia y símbolos del idioma de destino definidos mediante cadenas entrecomilladas. Se eliminaron los corchetes <
y >
. Se agregaron los paréntesis (
)
para la agrupación matemática. La regla <expr>
aparecería en META II como
EXPR = TERM $('+' TERM.OUT('ADD') durable '-' TERM.OUT('SUB'));
Estos cambios permitieron que META II y sus lenguajes de programación derivados definieran y ampliaran su propio metalenguaje, a costa de la capacidad de utilizar una descripción de lenguaje natural, variable metalingüística, descripción de construcción de lenguaje. Muchos metalenguajes derivados se inspiraron en BNF. Consulte META II, TREE-META y Metacompiler.
Una clase BNF describe la formación de una construcción de lenguaje, con la formación definida como un patrón o la acción de formar el patrón. El nombre de la clase expr se describe en lenguaje natural como <term>
seguido de una secuencia <addop> <término>. Una clase es una abstracción; podemos hablar de él independientemente de su formación. Podemos hablar de término, independientemente de su definición, como suma o resta en expr. Podemos hablar de que un término es un tipo de datos específico y cómo se va a evaluar una expresión con combinaciones específicas de tipos de datos, o incluso reordenar una expresión para agrupar tipos de datos y resultados de evaluación de tipos mixtos. El complemento de lenguaje natural proporcionó detalles específicos de la semántica de la clase de lenguaje que utilizará una implementación del compilador y un programador que escribe un programa ALGOL. La descripción en lenguaje natural también complementó aún más la sintaxis. La regla del número entero es un buen ejemplo de lenguaje natural y metalenguaje que se usa para describir la sintaxis:
.entero■ ::= .dígito■Silencio.entero■.dígito■
No hay detalles específicos sobre los espacios en blanco en lo anterior. En lo que dice la regla, podríamos tener espacio entre los dígitos. En el lenguaje natural complementamos el metalenguaje BNF explicando que la secuencia de dígitos no puede tener espacios en blanco entre los dígitos. El inglés es sólo uno de los posibles idiomas naturales. Las traducciones de los informes ALGOL estaban disponibles en muchos idiomas naturales.
El origen de BNF no es tan importante como su impacto en el desarrollo del lenguaje de programación. Durante el período inmediatamente posterior a la publicación del informe ALGOL 60, BNF fue la base de muchos sistemas compilador-compilador.
Algunos, como "Un compilador dirigido por sintaxis para ALGOL 60" desarrollado por Edgar T. Irons y "A Compiler Building System" Desarrollado por Brooker y Morris, BNF utilizado directamente. Otros, como Schorre Metacompilers, lo convirtieron en un lenguaje de programación con solo unos pocos cambios. <nombre de clase>
se convirtieron en identificadores de símbolos, eliminando el <,> y el uso de cadenas entre comillas para los símbolos del idioma de destino. La agrupación similar a la aritmética proporcionó una simplificación que eliminó el uso de clases donde la agrupación era su único valor. La regla de expresión aritmética META II muestra el uso de agrupación. Las expresiones de salida colocadas en una regla META II se utilizan para generar código y etiquetas en un lenguaje ensamblador. Las reglas en META II son equivalentes a las definiciones de clase en BNF. La utilidad de Unix yacc se basa en BNF con una producción de código similar a META II. yacc se usa más comúnmente como generador de analizador, y sus raíces son obviamente BNF.
BNF hoy en día es uno de los lenguajes informáticos más antiguos que todavía se utiliza.
Más ejemplos
La sintaxis de BNF en sí puede representarse con un BNF como el siguiente:
.sintaxis■ ::= .Regla■ Silencio .Regla■ .sintaxis■ .Regla■ ::= .opt-whitespace■ "Seguido" .nombre de la regla■ "No" .opt-whitespace■ "::=" .opt-whitespace■ .expresión■ .line-end■ .opt-whitespace■ ::= " .opt-whitespace■ Silencio "
.expresión■ ::= .lista■ Silencio .lista■ .opt-whitespace■ "Viva" .opt-whitespace■ .expresión■ .line-end■ ::= .opt-whitespace■ .EOL■ Silencio .line-end■ .line-end■ .lista■ ::= .mandato■ Silencio .mandato■ .opt-whitespace■ .lista■ .mandato■ ::= .literal■ TENIDO "Seguido" .nombre de la regla■ "No"
.literal■ ::= '' .texto 1■ """" """"" .texto2■ "
.texto 1■ ::= " .carácter1■ .texto 1■ .texto2■ ::= ' .carácter2■ .texto2■ .carácter■ ::= .carta■ Silencio .dígito■ Silencio .símbolo■ .carta■ ::= "A" Silencio "B" Silencio "I" Silencio "I" Silencio "I" Silencio "I" Silencio "I" Silencio" Silencio "V" Silencio "V"."
.dígito■ ::= "0" Silencio "1" TENIDO "2" TENIDO "3" TENIDO "4" TENIDO "5" TENIDO "6" ANTE "7" ANTE "8" ANTE "9"
.símbolo■ ::= ""Prince" """" """" """" """"" """"" """" """" """" """" """"" """ """" """" """" """" """" """" """" """"" """" """" """""""" """""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.carácter1■ ::= .carácter■ Silencio
.carácter2■ ::= .carácter■ Silencio
.nombre de la regla■ ::= .carta■ Silencio .nombre de la regla■ .rule-char■ .rule-char■ ::= .carta■ Silencio .dígito■ Silencio "-"
Tenga en cuenta que "" es la cadena vacía.
El BNF original no usaba comillas como se muestra en la regla <literal>
. Esto supone que no es necesario ningún espacio en blanco para la interpretación adecuada de la regla.
<EOL>
representa el especificador de fin de línea adecuado (en ASCII, retorno de carro, salto de línea o ambos, según el sistema operativo). <rule-name>
y <text>
deben sustituirse con el nombre/etiqueta de una regla declarada o texto literal, respectivamente.
En el ejemplo anterior de la dirección postal de EE. UU., la cita en bloque completa es una sintaxis. Cada línea o agrupación ininterrumpida de líneas es una regla; por ejemplo, una regla comienza con <name-part>::=. La otra parte de esa regla (aparte de un final de línea) es una expresión, que consta de dos listas separadas por una tubería
|
. Estas dos listas se componen de algunos términos (tres términos y dos términos, respectivamente). Cada término en esta regla en particular es un nombre de regla.
Variantes
EBNF
Existen muchas variantes y extensiones de BNF, generalmente ya sea por simplicidad y concisión, o para adaptarlo a una aplicación específica. Una característica común de muchas variantes es el uso de operadores de repetición de expresiones regulares como *
y +
. La forma extendida de Backus-Naur (EBNF) es común.
Otra extensión común es el uso de corchetes alrededor de elementos opcionales. Aunque no estaba presente en el informe ALGOL 60 original (en su lugar, se introdujo unos años más tarde en la definición PL/I de IBM), la notación ahora se reconoce universalmente.
ABNF
El formulario de Backus-Naur aumentado (ABNF) y el formulario de Backus-Naur de enrutamiento (RBNF) son extensiones que se usan comúnmente para describir los protocolos del Grupo de trabajo de ingeniería de Internet (IETF).
Las gramáticas de expresión de análisis se basan en la BNF y las notaciones de expresión regular para formar una clase alternativa de gramática formal, que es esencialmente de carácter analítico en lugar de generativo.
Otros
Muchas especificaciones de BNF que se encuentran en línea hoy en día están destinadas a ser legibles por humanos y no son formales. Estos a menudo incluyen muchas de las siguientes reglas y extensiones de sintaxis:
- Artículos opcionales incluidos entre corchetes:
[]
. - Los elementos existentes 0 o más veces están encerrados entre corchetes o sufijados con un asterisco (
*
) tales como::= {}
o::= *
respectivamente. - Los elementos existentes 1 o más veces se sufigen con un símbolo adicional (plus),
+
, como::= +
. - Las terminales pueden aparecer en negrita en lugar de cursivas, y no terminales en texto plano en lugar de ángulos.
- Donde los artículos se agrupan, se adjuntan en paréntesis simples.
Software que utiliza BNF
- ANTLR, otro generador de parser escrito en Java
- Qlik Sense, una herramienta BI, utiliza una variante de BNF para scripting
- BNF Converter (BNFC), operando en una variante llamada "forma de Backus-Naur etiquetada" (LBNF). En esta variante, cada producción para un no-terminal dado se da una etiqueta, que se puede utilizar como un constructor de un tipo de datos algebraicos que representa ese no-terminal. El convertidor es capaz de producir tipos y analizadores para la sintaxis abstracta en varios idiomas, incluyendo Haskell y Java.
- Coco/R, generador compilador aceptando una gramática atribuida en EBNF
- DMS Software Reengineering Toolkit, análisis de programas y sistema de transformación para idiomas arbitrarios
- GOLD BNF parser
- GNU bison, versión GNU de yacc
- Parser RPA BNF. Online (PHP) demo paresing: JavaScript, XML
- XACT X4MR System, a rule-based expert system for programming language translation
- XPL Analyzer, una herramienta que acepta BNF simplificada para un lenguaje y produce un parser para ese lenguaje en XPL; puede integrarse en el programa SKELETON suministrado, con el cual el lenguaje puede ser depurado (un programa aportado por SHARE, que fue precedido por el programa SKELETON suministrado, Un generador de compilador)
- Yacc, generador de parser (más utilizado comúnmente con el preprocesador de Lex)
- bnfparser2, una utilidad universal de verificación de sintaxis
- bnf2xml, entrada de Markup con etiquetas XML usando BNF avanzada.
- JavaCC, Java Compiler Compiler tm (JavaCC tm) - The Java Parser Generator.
- Herramientas de parser de Racket, lex y Yacc estilo Parsing (Beautiful Racket Edition)
Contenido relacionado
Contador de programa
Sistema de numeración ternario
Plato de disco duro