Como señaló, los humanos se comunican entre sí a través de un lenguaje "natural" como el inglés, el francés, el alemán. Se llaman naturales porque los adquirimos naturalmente en lugar de inventarlos intencionalmente (el esperanto es una excepción).
Un lenguaje formal es uno inventado para un propósito u otro. Un lenguaje de programación como C, por ejemplo, es un lenguaje formal inventado con el propósito de programar computadoras.
Todos los idiomas se pueden describir usando una gramática. Noam Chomsky describió una jerarquía de gramáticas en 1956. Consta de los siguientes niveles:
Gramáticas tipo 0 (gramáticas sin restricciones). Son los más generales y equivalen a una máquina de Turing. Como tal, el problema de decidir si una cadena dada es parte de una gramática sin restricciones es indecidible.
Gramáticas tipo 1 (gramáticas sensibles al contexto). Casi todos los idiomas naturales como el inglés son sensibles al contexto. Un ejemplo de sensibilidad al contexto en inglés son las dos frases: "El tiempo vuela como una flecha". y "La fruta vuela como un plátano". En general, es difícil para las computadoras entender lenguajes sensibles al contexto.
Gramáticas tipo 2 (sin contexto). Los lenguajes sin contexto son la base teórica para la sintaxis de la mayoría de los lenguajes de programación.
Gramáticas tipo 3 (gramáticas regulares). La familia de idiomas regulares se puede obtener mediante expresiones regulares. Los lenguajes regulares se usan comúnmente para definir patrones de búsqueda y la estructura léxica de los lenguajes de programación.
Las gramáticas tipo 2 (sin contexto) y tipo 3 (regular) son más frecuentes en las computadoras porque los analizadores pueden implementarse de manera eficiente.
BNF (Backus Normal Form o Backus – Naur Form) es una técnica de notación para gramáticas libres de contexto, a menudo utilizada para describir la sintaxis de los lenguajes utilizados en informática.
Por ejemplo, un identificador podría describirse como:
<identifier> ::= <letter> { <letter> | <digit> }
lo que significa que debe comenzar con una letra y puede contener letras o dígitos adicionales.
Anteriormente, una letra se define como 'a' | 'b' | 'c', etc., y el dígito se define como '0' a '9' usando el mismo tipo de notación.
La declaración "for" de CA puede definirse como:
<for_statement> ::=
'for' '(' <expression> ';' <expression> ';' <expression> ')' <statement>
Los analizadores y analizadores léxicos (las primeras etapas de un compilador o intérprete) se construyen para aceptar la gramática específica descrita por el BNF para un idioma en particular. Los analizadores léxicos se usan generalmente para separar los diversos tokens de un idioma (como una palabra clave, un identificador o un número), y el analizador se usa para descubrir cómo funcionan juntos los tokens, como cómo se construye una declaración "for" .