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?

  1.  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  es un símbolo no terminal y w es una cadena de terminales y/o no terminales

V\rightarrow w
VwV\rightarrow w
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