Академический Документы
Профессиональный Документы
Культура Документы
1 INTRODUO
Cada linguagem de programao possui as regras que descrevem a estrutura sinttica
dos programas bem formados. Em Pascal por exemplo, um programa constitudo por
blocos, um bloco por comandos, um comando por expresses , uma expresso por
tokens e assim por diante. A sintaxe das construes de uma linguagem de programao
pode ser descrita pelas gramticas livres de contexto ou pela notao BNF (Forma de
Bakcus Naur). As gramticas oferecem vantagens significativas tanto para os
projetistas de linguagens quanto para os escritores de compiladores.
Uma gramtica oferece, para uma linguagem de programao, uma
especificao sinttica precisa e fcil de entender.
pagar o seu custo. De fato, com a nfase crescente na computao interativa e bons
ambientes de programao, a tendncia parece estar na direo de mecanismos simples
de recuperao de erros.
4 ANLISE SINTTICA TOP-DOWN
A anlise sinttica top-down pode ser vista como uma tentativa de ser encontrar uma
derivao mais esquerda para uma cadeia de entrada. Equivalentemente, pode ser vista
como uma tentativa de se construir uma rvore gramatical, para a cadeia de entrada, a
partir da raiz, criando os ns da rvore gramatical em pr ordem. Consideramos agora
uma forma geral de anlise sinttica top-down, chamada de descendncia recursiva, que
pode envolver retrocesso, ou seja, a realizao de esquadrinhamentos repetidos da
entrada. Por outro lado, os analisadores sintticos com retrocesso no so vistos muito
freqentemente. Uma razo est em que o retrocesso raramente necessitado para
analisar sintaticamente construes de linguagens de programao. Em situaes tais
como a anlise sinttica de linguagens naturais, o retrocesso ainda ineficiente e
mtodos tabulares, tais como o algoritmo de programao dinmica ou mtodo de
Earley [1970] so preferidos.
O retrocesso exigido no prximo exemplo, e iremos sugerir uma forma de controlar a
entrada quando o mesmo ocorrer.
Exemplo: Consideremos a gramtica
S cAd
A ab | a
E a cadeia de entrada w=cad. Para construir uma rvore gramatical para esta cadeia, de
cima para baixo, criamos inicialmente uma rvore constituindo de um nico n rotulado
S. O apontador da entrada aponta para c, o primeiro smbolo de w. Em seguida, usamos
a primeira produo para S a fim de expandir a rvore.
A folha mais esquerda, rotulada c, reconhece o primeiro smbolo de w e, por
conseguinte, avanamos o apontador da entrada para a, o segundo smbolo de w, e
consideramos a prxima filha, rotulada A. Em seguida, expandimos A usando a sua
primeira alternativa, obtendo a rvore da figura (b). Temos agora um reconhecimento
para o segundo smbolo da entrada e, conseqentemente, avanamos para o apontador
da entrada para d, o terceiro smbolo da entrada, e comparamos d com a prxima folha,
rotulada b. Como b no igual a d, reportamos uma falha e retornamos a A a fim de
verificar se existe uma outra alternativa que no tenhamos tentado ainda, mas que
poderia produzir um reconhecimento.
Ao irmos de volta para A, precisamos restabelecer o apontador da entrada para a
posio 2, aquela que o mesmo detinha quando passamos pela primeira vez por A, o que
significa que o procedimento para A precisa armazenar o apontador da entrada numa
varivel local. Tentamos agora a segunda alternativa de A afim de obter a rvore na
figura (c). A folha a reconhece o segundo smbolo de w e a folha d o terceiro. Uma vez
que produzimos uma rvore gramatical para w, paramos e anunciamos o trmino com
sucesso da anlise sinttica.
efeito, lido A a partir da entrada, durante o tempo em que se movia do estado s para t.
Finalmente, se existir um lado de s para t rotulado , vai, a partir do estado s,
imediatamente para o estado t, sem avanar na entrada.
Um programa de anlise sinttica preditiva baseado num diagrama de transies tenta
reconhecer smbolos terminais na entrada e faz uma chamada de procedimento
potencialmente recursiva sempre que precisar seguir um lado rotulado por um no
terminal. Uma implementao no recursiva pode ser obtida empilhando-se o estado s
quando existir uma transio em um no terminal para fora de s e removendo-se o topo
da pilha quando o estado final para o no terminal for atingido.
A abordagem acima funcionar se o diagrama de transies dado for determinstico, isto
, no existir mais de uma transio de um mesmo para outros mesma entrada. Se a
ambigidade ocorrer, deveremos estar capacitados a resolv-la de uma forma ad-hoc. Se
o no determinismo no puder ser eliminado, no poderemos construir um analisador
sinttico preditivo, mas poderemos construir um analisador de descendncia recursiva
com retrocesso, de forma a tentar sistematicamente todas as possibilidades, se esta fosse
a melhor estratgia de anlise que pudssemos encontrar.
5.2 Anlise Sinttica Preditiva No-Recursiva
possvel construir um analisador preditivo no-recursivo mantendo explicitamente
uma pilha, ao invs de implicitamente atravs de chamadas recursivas. O problemachave durante a anlise preditiva determinar que produo deve ser aplicada a um
dado no terminal.
Um analisador sinttico preditivo dirigido por uma tabela possui um buffer de entrada,
uma pilha, uma tabela sinttica e um fluxo de sada. O buffer de entrada possui a cadeia
a ser analisada, seguida por um $ direita para indicar o fim da cadeia de entrada. A
pilha contm uma seqncia de smbolos gramaticais, com $ indicando o fundo da
pilha. Inicialmente, a pilha contm o smbolo de partida da gramtica acima de $. Uma
tabela sinttica um array bidimensional M[A,a], onde A um no terminal e a um
terminal ou outro smbolo $.
O analisador sinttico controlado por um programa que se comporta como segue. O
programa considera X o smbolo ao topo da pilha e a o smbolo corrente de entrada.
Esses dois smbolos determinam a ao do analisador. Existem trs possibilidades:
1. Se X=A=$, o analisador pra e anuncia o trmino com sucesso da anlise
sinttica.
2. Se X=a$, o analisador sinttico remove X da pilha e avana o apontador da
entrada para o prximo smbolo.
3. Se X um no terminal, o programa consulta a entrada M[X,a] da tabela
sinttica M. Essa entrada ser uma produo X da gramtica ou uma entrada
de erro. Se, por exemplo, M[X,a]={X UVW}, o analisador substitui X no topo
da pilha por WVU (com U ao topo). Como sada, iremos assumir que o
analisador sinttico simplesmente imprima a produo usada; de fato, qualquer
outro cdigo poderia ser executado aqui. Se M[X,a]=erro, o analisador chama
uma rotina de recuperao de erros.
direita da entrada. Inicialmente, a pilha est vazia e a cadeia w est entrada como
segue
Pilha
$
Entrada
w$
O analisador sinttico opera empilhando zero ou mais smbolos (na pilha) at que um
handle surja no topo da pilha. Reduz, ento, para o lado esquerdo da produo
apropriada. Repete este ciclo at que tenha detectado um erro ou que a pilha contenha o
smbolo de partida e a entrada esteja vazia:
Pilha
$S
Entrada
$
Aps entrar nesta configurao, pra e anuncia o trmino com sucesso da anlise
sinttica.
8.1 Prefixos Viveis
Os prefixos de uma forma sentencial direita que podem figurar na pilha deu m
analisador sinttico de empilhar e reduzir so chamados de prefixos viveis. Uma
definio equivalente de um prefixo vivel a de ser um prefixo de uma forma
sentencial direita, o qual no se estende para alm do limite direita do handle mais
direita, daquela forma sentencial. Por esta definio sempre possvel adicionar
smbolos terminais ao final de um prefixo vivel de modo a obter uma forma sentencial
direita. Por conseguinte, no h aparentemente erro na medida em que a poro da
entrada enxergada at um dado ponto possa ser reduzida a um prefixo vivel.
9 ANLISE SINTTICA DE PRECEDNCIA DE OPERADORES
A mais ampla classe de gramticas, para a qual os analisadores sintticos de empilhar e
reduzir podem ser construdos com sucesso so as gramticas LR. Entretanto, para uma
pequena, porm importante classe de gramticas, podemos facilmente construir
manualmente eficientes analisadores sintticos de empilhar e reduzir. Essas gramticas
possuem a propriedade (dentre outras exigncias essenciais) de que nenhum lado direito
de produo seja , ou tenha dois no terminais adjacentes. Uma gramtica com a
ltima propriedade chamada de uma gramtica de operadores.
Exemplo:
A seguinte gramtica para expresses
E EAE | (E) | -E |id
A+|-|*|/|
No uma gramtica de operadores porque o lado direito EAE possui dois (de fato trs)
no terminais consecutivos. Entretanto, se substituirmos A por cada uma de suas
alternativas, obtemos a seguinte gramtica de operadores:
E E + E | E E | E * E| E / E | E E | (E) | -E | id