Antecedentes
Durante una conferencia de la UNESCO sobre el lenguaje de programación ALGOL 58 el matemático John Backus presento un informe en el que describía bajo una notación formal dicho lenguaje.
Cuando Peter Naur leyó el informe realizo una serie de cambios respecto de la formalización propuesta por Backus que fue presentada en su informe para el ALGOL60. Esta última notación formal es la que hoy en día se emplea y se conoce como BNF.
Antecedentes
-
1959: Se describe un método de parsing de FORTRAN que introducía paréntesis adicionales alrededor de los operandos para ser capaz de analizar las expresiones.
-
1960: Se desarrollan los diversos métodos de parsers ascendentes y descendentes
-
1961: Se realiza el uso por primera vez de un parsing descendente recursivo.
-
1965: Se define las gramáticas LR y describe la construcción de una tabla canónica de parser LR.
-
1968: Se estudian y definen las gramáticas LL así como los parsers predictivos
-
1970: Se describen los métodos SLR y LALR de parser LR. Debido a su sencillez y a su capacidad de análisis para una gran variedad de lenguajes, la técnica de parsing LR va a ser la elegida para los generadores automáticos de parsers.
-
1975: Se crea el generador de analizadores sintácticos YACC para funcionar bajo un entorno UNIX . Junto al análisis sintáctico, también se fuedesarrollando el análisis semántico.
¿Qué es BNF?


- Knuth, Donald E. (1964). «Backus Normal Form vs. Backus Naur Form». Communications of the ACM 7 (12): pp. 735–736. (en inglés)
Metalenguaje
un metalenguaje es un lenguaje que se usa
para hablar acerca de otro lenguaje.
1*
[*] También de Wikipedia ;)
Gramática Libre de Contexto
es una estructura matemática con un conjunto de reglas de formación que definen las cadenas de caracteres admisibles en un determinado lenguaje formal en la que cada regla de producción tiene la forma:
Donde V es un símbolo no terminal y w es una cadena de terminales y/o no terminales
2*
Notación BNF
Backus-Naur Form
- Notación formal para definir la sintaxis de un lenguaje.
- Usada para especificar la mayoría de los lenguajes de programación
- Símbolos
- , definición
- , opción.
- Los terminales entre comillas y negrita, por ejemplo:
::=
|
'if', '5'
Ejemplo
<oración> ::= <sujeto> <predicado>
<sujeto> ::= Juan | Julia
<predicado> ::= <verbo> <adverbio>
<verbo> ::= maneja | corre
<adverbio> ::= descuidadamente | rápido | frecuentemente
- Julia maneja rápido
- Juan corre descuidadamente
- Julia corre frecuentemente
- ...
Más ejemplos
<número-decimal> ::= <entero-sin-signo> | <fracción-decimal>
<fracción-decimal> ::= <entero-sin-signo> . <fracción-decimal> |
<fracción-decimal>
<entero-sin-signo> ::= <dígito> | <dígito> <entero-sin-signo>
<dígito> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

La figura muestra un árbol de deducción, en esta gramática, del número decimal 23.14. Observe que el enunciado BNF es recursivo en la segunda parte de su lado derecho y también es normal.
En general, se sabe que muchas gramáticas diferentes pueden producir el mismo lenguaje.
Gramática Ambigua
Para una cadena terminal hay más de un árbol sintáctico
<expr> ::= x | y | z | (<expr>) | <expr> + <expr> | <expr> * <expr>
(recursión a izquierda y derecha para un mismo símbolo no-term.)
Dos árboles sintácticos para la cadena x + y * z :

Ejemplo de uso de la notación BNF para la descripción de un lenguaje de programación
<Programa> ::= <ListaDeFunciones>
<ListaDeFunciones> ::= <Función> | <ListaDeFunciones> <Función>
<Función> ::= FUNC <Variable> ( <ListaDeParámetros> ) <Sentencia>
<ListaDeParámetros> ::= <ListaDeVariables> | ε
<ListaDeVariables> ::= <Variable> | <ListaDeVariables> , <Variable>
<Variable> ::= <Letra> | <Variable> <Alfanumérico>
<Alfanumércio> ::= <Letra> | <Dígito>
<Letra> ::= a | b | ... | y | z
<Dígito> ::= 0 | 1 | ... | 8 | 9
<Sentencia> ::= <SentenciaDeAsignación> | <SentenciaDeRetorno> |
<SentenciaDeImpresión> | <SentenciaNula> |
<SentenciaCondicional> | <SentenciaWhile> | <Bloque>
<SentenciaDeAsignación> ::= <Variable> := <Expresión>
<Expresión> ::= <Expresión> <OperadorBinario> <Expresión> |
<OperadorUnario> <Expresión> | ( <Expresión> ) | <Entero> |
<Variable> | <Variable> (<ListaDeArgumentos> )
<OperadorBinario> ::= + | - | * | /
<OperadorUnario> ::= -
<Entero> ::= <Dígito> | <Entero> <Dígito>
<ListaDeArgumentos> ::= <ListaDeExpresiones> | ε
<ListaDeExpresiones> ::= <Expresión> | <Expresión> , <ListaDeExpresiones>
<SentenciaDeImpresión> ::= PRINT <ListaDeImpresión>
<ListaDeImpresión> ::= <ElementoDeImpresión> |
<ListaDeImpresión> , <ElementoDeImpresión>
<ElementoDeImpresión> ::= <Expresión> | “<Texto> ”
<Texto> ::= <Carácter> | <Carácter> <Texto>
<Carácter> ::= <CarácterImprimible> | <CarácterEscapado>
<CarácterImprimible> ::= Cualquier carácter ASCII imprimible
<CarácterEscapado> ::= \n
<SentenciaDeRetorno> ::= RETURN <Expresión>
<SentenciaNula> ::= CONTINUE
<SentenciaCondicional> ::= IF <Expresión> THEN <Sentencia> FI |
IF <Expresión> THEN <Sentencia> ELSE <Sentencia> FI
<SentenciaWhile> ::= WHILE <Expresión> DO <Sentencia> DONE
<Bloque> ::= { <ListaDeDeclaraciones> <ListaDeSentencias> }
<ListaDeDeclaraciones> ::= <Declaración> <ListaDeDeclaraciones> | ε
<Declaración> ::= VAR <ListaDeVariables>
<ListaDeSEntencias> ::= <Sentencia> | <ListaDeSentencias> <Sentencia>
Más ejemplos
G = (N, T, P, S)
N = {identificador, resto, dígito, letra}
T = {a, b, c, . . . , z, 0, 1, 2, 3, . . . , 9}
P = N U T
S = identificador
<identificador> ::= <letra> | <letra> <resto>
<resto> ::= <letra> | <dígito> |
<letra> <resto> | <dígito> <resto>
<resto> ::= a | b | c . . . | z
<dígito> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6| 7 | 8 | 9
De nuevo, se observa que las producciones que aparecen en el enunciado de resto, son recursivos y normales.
Más ejemplos
Ejemplo: expresión matemática en notación BNF:
---> 4*(3+1)
<expresión> ::= <numero> | (<expresión>) |
<expresión><operador><expresión>
<operador> ::= + | - | * | /
<numero> ::= <digito> | <numero><digito>
<digito> ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0


Representación en diagrama sintáctico:
Variantes
- EBNF (1996) - BNF Extendido
- ABNF (2008) - BNF Aumentado
Nuevos símbolos:
- '[ ]' para indicar sintaxis opcional.
- '*' para indicar repetición de 0 a más.
- '+' para indicar repetición de 1 a más.
- Agrupación por paréntesis '(' ')'
Notación BNF
By Richard Cotrina
Notación BNF
- 3,763