A tabela sintática é a estrutura de apoio ao reconhecimento de sentenças pela técnica de construção descendente que tem como chave um par de símbolos. O primeiro componente da chave é um símbolo não-terminal, que corresponde ao símbolo que estará sendo analisado pelo algoritmo de reconhecimento da sentença. O segundo componente da chave é um símbolo da sentença, ou seja, um símbolo terminal ou o delimitador de fim de seqüência $. O valor associado a esse par de símbolos é a produção da gramática a ser aplicada para prosseguir com o reconhecimento da sentença.
Para construir a tabela sintática para uma gramática qualquer ,
deve-se analisar cada uma das produções
de
. Inicialmente, deve-se obter o conjunto de símbolos
terminais que podem iniciar uma cadeia a partir de
. Se
for um símbolo terminal, então esse conjunto é composto
apenas por esse próprio símbolo. Caso contrário, as possíveis
expansões de
devem ser analisadas até que os símbolos
terminais ou a string vazia sejam alcançados.
Caso símbolos terminais sejam alcançados, a tabela sintática recebe a
entrada com o valor
para cada chave
onde
é cada um dos símbolos terminais que podem ser alcançados
desde
. Caso a string vazia seja um dos resultados
possíveis para a expansão de
, é preciso analisar também as
possíveis expansões dos símbolos à direita do símbolo corrente na
produção.
Dois procedimentos auxiliares são definidos para a construção dessa
tabela. O primeiro, STF, computa os símbolos terminais
associados ao início das expansões de cada um dos símbolos da
gramática. Esse procedimento é descrito no Algoritmo 3.4.
O cômputo de STF pode também ser aplicado a uma cadeia de
símbolos, sendo que neste caso o valor resultante é o primeiro cômputo
de STF aplicado a cada símbolo da seqüência tal que o
resultado não tenha sido
. Caso o cômputo de
STF para todos os símbolos da cadeia resulte em
, este também será o resultado final.
O outro procedimento auxiliar deve computar, para cada símbolo
não-terminal da gramática , o conjunto de símbolos terminais que podem estar
imediatamente à direita do símbolo especificado em alguma forma
sentencial. Essa informação é mantida em uma lista
,
onde
é o símbolo de interesse. Para construir essas
listas, as seguintes regras devem ser aplicados até que se esgotem as
possibilidades de acrescentar algo às listas:
Com esses procedimentos, a construção da tabela sintática para uma
gramática procede como se segue. Para cada produção
em
:
Como exemplo, considere a construção do analisador sintático preditivo para a gramática da Figura 3.7. Como essa gramática é recursiva à esquerda, o primeiro passo nessa construção é construir a gramática equivalente sem esse tipo de recursão. O resultado da aplicação da técnica para eliminar a recursão à esquerda resulta na seguinte gramática:
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
![]() |
Para esta gramática, o cômputo de STF() para cada um dos símbolos não-terminais resulta em:
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
![]() |
A aplicação das regras para a construção das listas
resulta, para cada símbolo não-terminal:
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
![]() |
A construção da tabela sintática para essa gramática analisa cada uma das suas produções:
A Tabela 3.1 apresenta esses resultados na forma de um arranjo bidimensional, resumindo os resultados encontrados. Nessa tabela, a primeira coluna contém os símbolos não-terminais da gramática, que corresponderão aos símbolos que estarão no topo da pilha do analisador sintático. A primeira linha contém os símbolos que podem ser encontrados na sentença, ou seja, os símbolos terminais da gramática e o símbolo indicador de fim de sentença.
Para algumas gramáticas, pode ser que a tabela sintática apresente mais que uma produção por chave, o que reduz a aplicabilidade desse tipo de analisador -- seria necessário manter um registro do estado do analisador em pontos de múltipla escolha para eventualmente retornar a esse estado e tentar a outra alternativa, em caso de insucesso na escolha anterior. Gramáticas ambíguas e gramáticas recursivas à esquerda são exemplos de gramáticas que produziriam tabelas sintáticas com múltiplas produções para uma chave de par de símbolos.
Gramáticas com tabelas sintáticas sem múltiplas definições são denominadas gramáticas LL(1), indicando que a varredura da sentença ocorre da esquerda para a direita (Left-to-right) e que é utilizada a derivação canônica mais à esquerda (Leftmost derivation). O número entre parênteses indica quantos símbolos da sentença precisam ser analisados (lookahead) para a tomada de decisão no processo de reconhecimento.
Uma gramática com duas produções
e
é LL(1) se apresentar as seguintes propriedades: