Gramática não contextual

Na ciência da computação linguística e teórica , uma gramática livre de contexto , ou gramática livre de contexto , também chamada de gramática livre de contexto ou gramática "livre de contexto" é uma gramática formal em que cada regra de produção tem a forma

onde é um símbolo não terminal e é uma string que consiste em terminais e / ou não terminais. O termo “não contextual” vem do fato de que um não terminal pode ser substituído por , independentemente do contexto em que aparece. Uma linguagem formal é não contextual (ou fora de contexto, ou mesmo algébrica) se houver uma gramática não contextual que a gera.

Em contraste, uma regra do formulário é contextual

devido à parte esquerda da regra que indica um contexto para X. Tal regra significa que X, no caso (contexto) em que é precedido pelo símbolo do terminal e pelo literal , pode ser substituído por .

Assim, em uma gramática não contextual , um símbolo não terminal está sempre sozinho na parte esquerda de qualquer regra, o que significa que seu ambiente sintático (ou contexto) não é considerado.

Gramáticas algébricas são poderosas o suficiente para descrever a parte principal da sintaxe da maioria das linguagens de programação , com algumas extensões conforme necessário. A forma Backus-Naur é a notação mais comum usada para descrever uma gramática não contextual que descreve uma linguagem de programação. Na hierarquia de Chomsky , essas gramáticas são do tipo 2.

Se encontrarmos vários termos para nomear uma gramática algébrica, é porque o termo em inglês “  livre de contexto  ” é difícil de traduzir. Todos os termos fornecidos acima são usados ​​e equivalentes.

Definições formais

Uma gramática algébrica é composta:

Uma regra geralmente é escrita no formulário . A variável e a palavra são chamadas de membro esquerdo e direito da regra, respectivamente. Estendemos essa notação e escrevemos quando resulta da substituição, em , de um membro esquerdo da regra (que é, portanto, uma variável) por seu membro direito, portanto, se houver palavras e uma regra como e . Notamos o fechamento reflexivo e transitivo dessa relação. Quando

,

dizemos que deriva no .

A linguagem gerada pela gramática , notada , é o conjunto de palavras terminais (não mais contendo variáveis) que derivam do axioma , ou seja,

.

Chamamos de linguagem algébrica ou linguagem não contextual uma linguagem que pode ser gerada por uma gramática algébrica. A "  linguagem expandida  " gerado pela gramática consiste em todas as palavras de que derivam do axioma , mesmo contendo variáveis.

Exemplos

Exemplo 1

Considere a seguinte gramática algébrica:

onde denota a palavra vazia. Essa gramática gera uma linguagem que não é uma linguagem racional .

Também podemos usar uma barra vertical para agrupar as regras com o mesmo símbolo não terminal do membro esquerdo e escrever a gramática na seguinte forma condensada:

.

Exemplo 2

Aqui é uma gramática algébrica que gera as expressões aritméticas em três variáveis , e , corretamente entre parênteses:

Esta gramática gera, por exemplo .

Exemplo 3

A gramática a seguir gera o idioma composto pelas palavras en e en , e cujo número de é diferente do número de  :

produz palavras com o mesmo número de e's , produz palavras com mais que e produz palavras com menos que .

Exemplo 4

As línguas de Dyck ou as línguas de palavras bem colocadas entre parênteses são línguas algébricas.

Outro exemplo

Gramáticas não contextuais não se limitam a linguagens formais em matemática. Eles também são usados ​​em linguística, embora as gramáticas contextuais sejam frequentemente mais adequadas. Um exemplo notável é o trabalho do linguista indiana Panini , asset IV ª  século  aC. AD Ele descreveu a gramática do Sânscrito em um sistema altamente formalizado, com quase 4000 regras. Essas regras são apresentadas em uma notação próxima à forma de Backus-Naur .

Filiais e galhos de árvores

Existem duas maneiras de descrever como uma palavra foi gerada a partir de uma dada gramática, a primeira consiste em listar a sequência de mapeamentos das regras, a segunda sintetiza essa lista em uma árvore, chamada de árvore de derivação.

O primeiro método lista a sequência de palavras (começando com o símbolo inicial, o axioma, e terminando com a palavra pesquisada). Palavras intermediárias, contendo variáveis, às vezes são chamadas de proto-sentenças ( formas sentenciais em inglês) ou palavra de linguagem estendida . Além dessas palavras, listamos as regras aplicadas para passar de uma palavra para a próxima. Se, além disso, usarmos a estratégia que consiste em "substituir sempre o não terminal mais à esquerda", então é suficiente fornecer a lista das regras aplicadas. A derivação obtida é chamada de derivação esquerda da palavra. Por exemplo, para a seguinte gramática:

a string "   ", portanto, admite várias derivações. A derivação representada pela lista [(1), (1), (2), (3), (2)] é obtida da seguinte forma:

((1) aplicado a S) ((1) aplicado ao segundo S) ((2) aplicado ao segundo S) ((3) aplicado ao primeiro S) ((2) aplicado a S)

nesta derivação, os caracteres não terminais são substituídos em nenhuma ordem específica.

Para obter um bypass esquerdo, sempre substituímos o não terminal mais à esquerda. A derivação esquerda da string "   " é, portanto, obtida desta forma:

((1) aplicado a S) ((3) aplicado ao primeiro S) ((1) aplicado a S) ((2) aplicado ao primeiro S) ((2) aplicado a S)

que dá a lista [(1), (3), (1), (2), (2)].

Da mesma forma, uma derivação certa é a lista de regras usadas ao substituir sistematicamente o não terminal mais à direita primeiro. No exemplo anterior, uma derivada certa é [(1), (2), (1), (2), (3)], obtida desta forma:

((1) aplicado a S) ((2) aplicado ao último S) ((1) aplicado a S) ((2) aplicado ao último S) ((3) aplicado ao primeiro S)

A distinção entre derivação esquerda e direita é importante na prática porque permite, na maioria dos analisadores, levar em consideração as prioridades das operações. Os analisadores LL produzem derivações à esquerda, e os analisadores LR ramificações retas (na verdade, reduções, isto é, determinam primeiro a última regra aplicada).

Uma derivação também impõe uma estrutura hierárquica da cadeia derivada.

{{{1} S + {a} S } S + {a} S } S

onde {...} S indica uma substring reconhecida como pertencente a S. Esta hierarquia também pode ser vista como uma árvore:

S /|\ / | \ / | \ S + S | /|\ | / | \ 1 S + S | | a a

Essa árvore é chamada de árvore de derivação , análise de árvore ou árvore de sintaxe concreta (em oposição à árvore de sintaxe abstrata ) da string. O ramo esquerdo mostrado acima e o ramo direito definem o mesmo eixo do ramo. Isso é normal porque as duas derivações são duas jornadas de profundidade da árvore derivada, a primeira obtida escolhendo o nó mais à esquerda, a segunda escolhendo o nó mais à direita. Existe uma bijeção entre as derivações esquerdas e as derivações direitas.

Uma gramática é ambígua quando pelo menos uma palavra gerada pela gramática tem pelo menos duas árvores de análise separada, caso contrário, é uma gramática inambiguë ou inequívoca . Uma linguagem é inequívoca ou inequívoca se tiver uma gramática inequívoca. É denominado inerentemente ambíguo se todas as gramáticas que o geram forem ambíguas.

Um exemplo de linguagem inerentemente ambígua é a linguagem:

Em todas as gramáticas, as palavras têm duas derivações distintas. A prova é feita por meio do lema de Ogden .

Na análise sintática de palavras geradas por uma gramática ambígua, devem ser utilizadas técnicas de análise não determinísticas e / ou técnicas adaptadas ( retrocesso , regras de desambiguação, ...)

Formas normais

Uma linguagem algébrica pode ser gerada por gramáticas algébricas de várias formas. Duas gramáticas são consideradas equivalentes quando geram a mesma linguagem.

Gramática reduzida e limpa

Forma normal de Chomsky

Uma gramática está na forma normal de Chomsky se todas as suas regras forem de uma das formas

onde estão variáveis ​​e é uma letra. Se o idioma gerado contém a palavra vazia, adicionamos a regra

onde está o axioma.

Qualquer gramática pode estar na forma normal de Chomsky. Esta forma normal é usada, por exemplo, na definição de um algoritmo de análise , o algoritmo CYK , que decide em tempo polinomial , se uma palavra está na linguagem gerada por esta gramática.

Forma normal de Greibach

Uma gramática está na forma normal de Greibach se os membros certos de todas as suas regras começam com uma letra e são possivelmente seguidos apenas por variáveis, formalmente


onde estão variáveis ​​e são letras. Por exemplo, gramática

que gera a linguagem de Lukasiewicz está na forma normal de Greibach. A forma quadrática de Greibach também impõe que haja no máximo duas variáveis ​​em cada membro da regra à direita (o que é o caso aqui). Qualquer gramática pode ser colocada em uma forma quadrática de Greibach, até a palavra vazia.

Forma normal bilateral de Greibach

A forma normal bilateral de Greibach é uma forma bilateral da forma normal de Greibach: os membros certos das regras são letras terminais ou começam e terminam com letras terminais e contêm apenas variáveis ​​entre elas. Todas as regras são do formulário


onde estão variáveis ​​e são letras. Qualquer gramática pode ser colocada na forma normal bilateral, e podemos até assumi-la na forma quadrática , ou seja, nestas regras.

Gramáticas estendidas

Encontramos, especialmente em aplicativos, uma forma de gramáticas estendidas: os membros certos das regras podem ser expressões regulares. Isso ocorre na forma normal de Backus estendido . Mais precisamente, denotemos o conjunto de membros direitos das regras cujo membro esquerdo é .

Podemos mostrar que as duas extensões de gramáticas sempre geram linguagens algébricas.

Análise de sintaxe

Gramáticas algébricas são simples o suficiente para permitir a criação de analisadores eficientes (ao contrário das gramáticas contextuais ) em tempo polinomial no tamanho da gramática e no comprimento da palavra a ser analisada. A tarefa de tal analisador é determinar, para uma determinada palavra, se e como ela pode ser gerada a partir da gramática. O algoritmo CYK e o analisador Earley são exemplos de tais algoritmos. Os analisadores LR e LL parsers operam em tempo linear no comprimento da palavra a ser analisada e são usados ​​na prática. Por outro lado, eles apenas permitem a análise de famílias mais restritivas de gramáticas algébricas.

Notas

  1. Idioma na Índia .
  2. Este resultado não é bem conhecido. Foi comprovado por G. Hotz. Uma prova é fornecida em: Joost Engelfriet , “  Uma prova elementar da forma normal dupla de Greibach  ”, Information Processing Letters , vol.  44, n o  21992, p.  291-293. Uma prova e um exemplo detalhado também são dados em Autebert, Berstel Boasson (1997) .

Bibliografia

Por sua natureza fundamental, muitos trabalhos teóricos de computador contêm pelo menos uma seção sobre gramáticas algébricas. Vários livros também foram traduzidos para o francês.

Livros em francêsLivro em alemãoLivros em inglesAulas

Veja também


<img src="https://fr.wikipedia.org/wiki/Special:CentralAutoLogin/start?type=1x1" alt="" title="" width="1" height="1" style="border: none; position: absolute;">