Como você apontou, os humanos se comunicam através de um idioma "natural", como inglês, francês, alemão, entre si. Eles são chamados naturais porque nós os adquirimos naturalmente, em vez de inventá-los intencionalmente (o esperanto é uma exceção).
Uma linguagem formal é aquela inventada para algum propósito ou outro. Uma linguagem de programação como C, por exemplo, é uma linguagem formal inventada com a finalidade de programar computadores.
Todos os idiomas podem ser descritos usando uma gramática. Uma hierarquia de gramáticas foi descrita por Noam Chomsky em 1956. Consiste nos seguintes níveis:
Gramáticas tipo 0 (gramáticas irrestritas). Eles são os mais gerais e são equivalentes a uma Máquina de Turing. Como tal, o problema de decidir se uma determinada sequência faz parte de uma gramática irrestrita é indecidível.
Gramáticas tipo 1 (gramáticas sensíveis ao contexto). Quase todos os idiomas naturais, como o inglês, são sensíveis ao contexto. Um exemplo de sensibilidade ao contexto em inglês são as duas frases: "O tempo voa como uma flecha". e "A fruta voa como uma banana". Em geral, é difícil para os computadores entenderem linguagens sensíveis ao contexto.
Gramáticas tipo 2 (sem contexto). Linguagens sem contexto são a base teórica para a sintaxe da maioria das linguagens de programação.
Gramáticas tipo 3 (gramáticas regulares). A família de idiomas regulares pode ser obtida por expressões regulares. Linguagens regulares são comumente usadas para definir padrões de pesquisa e a estrutura lexical das linguagens de programação.
As gramáticas do tipo 2 (sem contexto) e do tipo 3 (regulares) geralmente são feitas por computadores, porque os analisadores podem ser implementados com eficiência.
BNF (Backus Normal Form ou Backus – Naur Form) é uma técnica de notação para gramáticas sem contexto, frequentemente usada para descrever a sintaxe das linguagens usadas na computação.
Por exemplo, um identificador pode ser descrito como:
<identifier> ::= <letter> { <letter> | <digit> }
o que significa que deve começar com uma letra e pode conter letras ou dígitos adicionais.
Anteriormente, uma letra é definida como 'a' | 'b' 'c' etc., e dígito é definido como '0' a '9' usando o mesmo tipo de notação.
A instrução "for" da CA pode ser definida como:
<for_statement> ::=
'for' '(' <expression> ';' <expression> ';' <expression> ')' <statement>
Analisadores e analisadores lexicais (os primeiros estágios de um compilador ou intérprete) são então construídos para aceitar a gramática específica descrita pelo BNF para um idioma específico. Os analisadores lexicais são normalmente usados para separar os vários tokens de um idioma (como uma palavra-chave, identificador ou número), e o analisador é usado para descobrir como os tokens funcionam juntos, como a construção de uma declaração "for" .