Gramáticas livres de contexto
Derivações, árvores sintáticas, ambiguidade e forma normal de Chomsky.
Nesta página
Uma gramática livre de contexto (CFG, de context-free grammar) gera palavras por substituição: cada regra troca um símbolo não terminal por uma sequência, independentemente do que está à volta (daí “livre de contexto”). São o formalismo por trás da sintaxe das linguagens de programação. Esta página mostra derivações, árvores, ambiguidade e a forma normal de Chomsky.
Definição e derivações
Uma CFG é um quádruplo onde são as variáveis (não terminais), os terminais (o alfabeto, disjunto de ), as regras (com e uma sequência de variáveis e terminais) e o símbolo inicial.
Uma derivação aplica regras até só restarem terminais. Escreve-se para um passo e para zero ou mais passos. A linguagem gerada é o conjunto das cadeias de terminais com .
Exemplo: com variável e regras (lê como “ou”). Derivação de :
Cada aplicação de acrescenta um à esquerda e um à direita, por isso a gramática gera exatamente , a linguagem que os autómatos finitos não alcançam. Vês a diferença de poder: a variável no meio da forma sentencial funciona como memória ilimitada.
Árvores sintáticas e ambiguidade
Uma árvore sintática (parse tree) mostra a estrutura da derivação: a raiz é , cada nó interior é uma variável com os filhos dados por uma regra, e as folhas da esquerda para a direita formam a palavra.
Uma gramática é ambígua se alguma palavra tem duas árvores sintáticas distintas (ou, equivalentemente, duas derivações mais à esquerda distintas). Exemplo clássico, expressões aritméticas com , e a palavra :
- Árvore 1: a raiz soma com , ou seja . Lê o no topo.
- Árvore 2: a raiz multiplica por no ramo direito, ou seja . Lê o no topo.
As duas árvores dão valores diferentes ( contra com numérico), por isso um compilador não pode aceitar esta gramática: a mesma expressão teria dois significados. A cura é estratificar por precedência, com uma variável por nível:
Agora só deriva com o no topo, porque o fica preso dentro de . Em exercícios, “remove a ambiguidade” significa quase sempre isto: introduz níveis para precedência e recursão à esquerda ou à direita para associatividade.
Forma normal de Chomsky
Uma CFG está na forma normal de Chomsky (CNF) se todas as regras têm uma destas formas: (duas variáveis), (um terminal) ou (só no inicial). Toda a CFG pode ser convertida para CNF (adicionando variáveis para terminais em regras longas e partindo regras com mais de dois símbolos).
Para que serve? Em CNF, cada derivação de uma palavra de comprimento usa exatamente passos: regras binárias para ramificar em variáveis e regras terminais. Este número fixo permite o algoritmo CYK, que testa pertença por programação dinâmica sobre os comprimentos crescentes. Não precisas de decorar o CYK célula a célula, mas percebe a ideia: a CNF torna o custo da análise sintática previsível, e é por isso que os parsers reais normalizam as gramáticas.
Exemplo de conversão: a regra viola a CNF (mistura terminais com variável e tem três símbolos). Introduz , e parte em duas regras com variável fresca : , , , , , .
Para levar para a próxima página
Gramáticas geram de cima para baixo (do inicial até à palavra). Os autómatos de pilha fazem o caminho inverso, reconhecendo de baixo para cima com a ajuda de uma pilha, e têm exatamente o mesmo poder.