Você está na página 1de 10

ANLISE SINTTICA

RESUMO

O Analisador Sinttico uma das etapas da construo de um compilador,


sendo ainda tido como corao do mesmo. Cada linguagem de programao
possui as regras que descrevem a estrutura sinttica dos programas bem-
formados, j que a sintaxe das construes de uma linguagem pode ser descrita
pelas gramticas livres de contexto. Com isso, a responsabilidade principal da
anlise sinttica verificar se a sequncia de smbolos (tokens), enviadas pela
anlise lxica, contidas no programa fonte forma um programa vlido ou no.

Palavras-chave: Analisador Sinttico. Linguagem de programao. Tokens.


Compilador. Erros de sintaxe.

ABSTRACT

The Parser is one of the steps of building a compiler, still regarded as the heart
of the same. Each programming language has rules which describe syntactic
structure of well-formed programs, since the syntax of a language constructs
can be described by the context-free grammars. Thus the primary responsibility
of parsing is to verify that the sequence of symbols (tokens), sent the lexical
analysis, contained in the source program form a valid program or not.

Key-Words: Syntactic Analyzer. Programming language. Tokens. Compiler.


Syntax erros.

INTRODUO

A anlise sinttica, tambm conhecida como parsing, a segunda fase da etapa de anlise de
um compilador, ocorrendo logo aps a anlise lxica. O seu principal objetivo estabelecer a
estrutura sinttica do cdigo-fonte a partir do fluxo de tokens produzido pela anlise lxica,
como tambm, identificar se esse cdigo possui sentenas vlidas para a linguagem de
programao.
Dessa forma, o analisador sinttico reuni os tokens providos pelo analisador lxico em
estruturas sintticas, que so utilizados para produzir uma rvore sinttica similar. Para isso,
ele emprega um conjunto de regras de sintaxe, que so responsveis por formar a gramtica
correspondente a linguagem fonte. Alm disso, o mesmo tem como funo reconhecer
possveis erros sintticos, que so trechos do programa fonte que no esto de acordo com as
regras de formao de estruturas sintticas especificadas atravs de uma gramtica livre de
contexto.

Portanto, essa fase do compilador pode ser entendida como um agrupamento de palavras para
formar frases. Porm, para que essas frases faam sentido, as palavras precisam estar
dispostas na ordem correta.

1. O PAPEL DO ANALISADOR SINTTICO

Aps a etapa de anlise lxica, a cadeia de tokens gerada enviada para o analisador sinttico,
que verifica a validade da sequncia de smbolos contida no programa fonte. Espera-se ainda
que o analisador sinttico relate quaisquer erros de sintaxe de uma forma inteligvel. Deve
tambm se recuperar dos erros que ocorram mais comumente, a fim de poder continuar
processando o resto de sua entrada.

Existem trs tipos de analisadores sintticos. Os mtodos universais de analise sinttica, tais
como o algoritmo de Cocke-Younger-Kasami e o de Earley, podem tratar qualquer gramatica.
Esses mtodos, entretanto, so muito ineficientes para se usar num compilador de produo.
Os mtodos mais comumente usados nos compiladores so classificados como top-down ou
bottom-up. Como indicado por seus nomes, os analisadores sintticos top-down constroem
arvores do topo (raiz) para o fundo (folhas), enquanto que os bottom-up comeam pelas folhas
e trabalham arvore acima at a raiz. Em ambos os casos, a entrada varrida da esquerda para
a direita, um smbolo de cada vez.

O top-down e o bottom-up, mtodos de anlise mais eficientes, trabalham de igual modo em


determinadas subclasses, porm muitas delas como as de gramaticas LL e LR, so
suficientemente expressivas para descrever a maioria das construes sintticas das
linguagens de programao. As gramaticas LL utilizam analisadores implementados
manualmente, j as gramaticas LR so construdos usualmente atravs de ferramentas
automatizadas.
2. TRATANDO ERROS DE SINTAXE

Se um compilador tivesse que processar somente programas corretos, seu projeto e sua
implementao seriam grandemente simplificados. Mas os programadores frequentemente
escrevem programas incorretos, e um bom compilador deveria assistir o programador na
identificao e localizao de erros. gritante que, apesar dos erros serem lugar-comum,
poucas linguagens so projetadas tendo-se o tratamento de erros em mente. Nossa civilizao
seria radicalmente diferente se as linguagens faladas tivessem as mesmas exigncias de
correo sinttica que as das linguagens de computadores. A maioria das especificaes das
linguagens de programao no descreve como um compilador deveria responder aos erros:
tal tarefa deixada para o projetista do compilador. O planejamento do tratamento de erros
exatamente desde o incio poderia tanto simplificar a estrutura de um compilador quanto
melhorar sua resposta aos erros.

Sabe-se que os programas podem conter erros em muitos nveis diferentes. Por exemplo, os
erros podem ser:

Lxicos, tais como errar a grafia de um identificador, palavra-chave ou operador;


Sintticos, tais como uma expresso aritmtica com parnteses no-balanceados;
Semnticos, tais como um operador aplicado a um operando incompatvel;
Lgicos, tais como uma chamada infinitamente recursiva.

Frequentemente, boa parte da deteco e recuperao de erros num compilador gira em torno
da faze de anlise sinttica. Isto porque os erros ou so sintticos por natureza ou so expostos
quando o fluxo de tokens proveniente do analisador lxico desobedece s regras gramaticais
que definem a linguagem de programao. Outra razo est na preciso dos modernos
mtodos de anlise sinttica: podem detectar muito eficientemente a presena de erros
sintticos num programa. Detectar precisamente a presena de erros semnticos ou lgicos em
tempo de compilao uma tarefa muito mais difcil. A seguir, algumas tcnicas bsicas para
a recuperao de erros sintticos.

O tratador de erros num analisador sinttico possui metas simples de serem estabelecidas:

Deve relatar a presena de erros clara e perfeitamente.


Deve se recuperar de cada erro suficientemente rpido a fim de ser capaz de detectar.
No deve retardar significativamente o processamento de programas corretos.

A realizao efetiva dessas metas apresenta desafios difceis.


Felizmente, os erros comuns so simples e frequentemente basta um mecanismo de
tratamento de erros relativamente direto. Em alguns casos, entretanto, um erro pode ter
ocorrido muito antes de sua presena ter sido detectada e sua natureza precisa pode ser muito
difcil de ser deduzida. Em casos difceis, o tratador de erros pode ter que adivinhar o que o
programador tinha em mente quando o programa foi escrito.

Vrios mtodos de anlise sinttica, tais como os mtodos LL e LR, detectam os erros to
cedo quanto possvel. Mais precisamente, possuem a propriedade do prefixo vivel,
significando que detectam que um erro ocorreu to logo tenham examinado um prefixo da
entrada que no seja o de qualquer cadeia da linguagem.

A fim de se ter uma apreciao dos tipos de erros que ocorrem na prtica, vamos examinar os
erros que Ripley e Druseikis [1978] encontraram numa amostra de programa Pascal de
estudantes.

Ripley e Druseikis descobriram que os erros no ocorrem com tanta frequncia; 60% dos
programas compilados estavam semntica e sintaticamente corretos. Mesmo quando os erros
ocorriam de fato, eram um tanto dispersos; 80% dos enunciados contendo erros possuam
apenas um, 13% dois. Finalmente, a maioria constitua-se de erros triviais; 90% eram erros
em um nico token.

Muitos dos erros poderiam ser classificados simplificadamente: 60% eram erros de
pontuao, 20% de operadores e operandos, 15% de palavras-chave e os 5% restantes de
outros tipos. O grosso dos erros de pontuao girava em torno do uso incorreto do ponto-e-
vrgula.

Para alguns erros concretos, consideremos o seguinte programa Pascal. A imagem a esquerda
traz um trecho de um cdigo contendo erros de sintaxe, enquanto que a direita temos o mesmo
cdigo, porm com os erros corrigidos.
Figura 1: Demonstrao de erros sintticos, em programa Pascal.

Um erro comum de pontuao o de se usar uma vrgula em lugar de ponto-e-vrgula na lista


de argumentos de uma declarao de funo (por exemplo, usar uma vrgula em lugar do
primeiro ponto-e-vrgula linha (4)); outro o de omitir um ponto-e-vrgula obrigatrio ao
final de uma linha (por exemplo, o ponto-e-vrgula ao final da linha (4)); um terceiro o de
colocar um ponto-e-vrgula estranho ao fim de uma linha antes de um seno (por exemplo,
colocar um ponto-e-vrgula ao fim da linha (7)).

3. TIPOS DE ANALISADORES SINTTICOS

3.1. ANLISE SINTTICA DESCENDENTE - TOP DOWN

A anlise sinttica top-down pode ser vista como uma tentativa de se 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 frequentemente. 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.

3.2. ANLISE SINTTICA ASCENDENTE BOTTOM-UP

A anlise sinttica bottom-up conhecida como anlise de empilhar e reduzir. A anlise


gramatical de empilhar e reduzir tenta construir uma rvore gramatical para uma cadeia de
entrada comeando pelas folhas (o fundo) e trabalhando rvore acima em direo raiz (o
topo). Podemos pensar neste processo como o de reduzir uma cadeia w ao smbolo de
partida de uma gramtica. A cada passo de reduo, uma subcadeia particular, que reconhea
o lado direito de uma produo, substituda pelo smbolo esquerda daquela produo e, se
a subcadeia tiver sido escolhida corretamente a cada passo, uma derivao mais direita ter
sido rastreada na ordem inversa.

4. ESTRATEGIA DE RECUPERAO DE ERROS

Existem muitas estratgias gerais diferentes que um analisador sinttico pode empregar para
se recuperar de um erro sinttico. Apesar de nenhuma delas ter provado ser universalmente
aceitvel, uns poucos mtodos tm ampla aplicabilidade. Introduzimos aqui as seguintes
estratgias:

Recuperao na modalidade do desespero: este o mtodo mais simples de implementar e


pode ser usado pela maioria dos mtodos de anlise sinttica. Ao descobrir um erro, o
analisador sinttico descarta smbolos de entrada, um de cada vez, at que seja encontrado um
token pertencente a um conjunto designado de tokens de sincronizao. Os tokens de
sincronizao so usualmente delimitadores, tais como o ponto-e-vrgula ou o fim, cujo papel
no programa-fonte seja claro. A correo na modalidade do desespero, que frequentemente
pula uma parte considervel da entrada sem verific-la, procurando por erros adicionais,
possui a vantagem da simplicidade e, diferentemente dos outros mtodos a serem enfocados
adiante, tem a garantia de no entrar num lao infinito. Nas situaes em que os erros
mltiplos num mesmo enunciados sejam raros, esse mtodo pode ser razoavelmente
adequado.

Aqui temos o mais simples de todos os mtodos de recuperao, que vai simplesmente ignorar
todos os tokens seguintes ao ponto em que o erro foi determinado, at encontrar um token que
tenha, de fato, uma posio precisamente definida dentro de qualquer programa. Assim,
tokens como '{' , '}' , 'while' , 'for', etc., que marcam precisamente ou o incio ou o final de um
bloco de comandos (frases) podem ser usados para determinar o momento de reincio do
parsing. A simplicidade desse modelo faz com que ele seja bastante usado quando fazemos a
implementao do compilador de forma manual, mas peca pelo fato de que pode acabar por
ignorar alguns erros que estejam embutidos entre os tokens no analisados pelo parser.

Recuperao de frases: ao descobrir um erro, o analisador sinttico pode realizar uma


correo local na entrada restante. Isto , pode substituir um prefixo da entrada remanescente
por alguma cadeia que permita ao analisador seguir em frente. Correes locais tpicas seriam
substituir uma vrgula por ponto-e-vrgula, remover um ponto-e-vrgula estranho ou inserir
um ausente. A escolha da correo local deixada para o projetista do compilador.
Naturalmente devemos ser cuidadosos, escolhendo substituies que no levem a laos
infinitos, como seria o caso, por exemplo, se inserssemos para sempre na entrada algo
frente do seu smbolo corrente.

Embora este mtodo no tenha muita aplicao prtica, o mesmo serve como base para
entendermos qual , de fato, o processo de recuperao de erros. O que se faz nesse mtodo
tentar corrigir a fonte (de modo imaginrio claro), atravs de insero, deleo ou
modificao de tokens, para atingir um parsing correto. Se o mesmo for feito no nvel de
frase, ou comando, o que se busca a alterao da frase para que ela passe a ser considerada
como gramaticalmente correta, num processo de minimizao de erros ou alteraes. O
problema desse mtodo que o mesmo complexo e ainda pode causar a entrada em loops,
ao inserir tokens que acabem exigindo sempre a insero de mais tokens para fazer a correo
da frase.

Regras de Produes para erro: se tivssemos uma boa ideia dos erros comuns que poderiam
ser encontrados, poderamos aumentar a gramtica para a linguagem em exame com as
produes que gerassem construes ilegais. Usamos, ento, a gramtica aumentada com
essas produes de erro para construir um analisador sinttico. Se uma produo de erro for
usada pelo analisador, podemos gerar diagnsticos apropriados para indicar a construo
ilegal que foi reconhecida na entrada.

A contrapartida ao mtodo de recuperao por pnico dada pelos mtodos de implementao


automtica de compiladores , justamente, a gerao de produes de erros, que nada mais
so do que produes inseridas na gramtica, disparveis apenas quando o autmato
bloquearia em determinados estados. Assim, o disparo de uma dada regra faz com que o
autmato no bloqueie naquele estado, mas que ao invs disso seja gerada uma mensagem de
erro, indicando seu tipo, e que o processo de parsing possa prosseguir normalmente, como se
nada tivesse ocorrido. O grande obstculo para esse mtodo a dificuldade em se obter as
produes de erros, isso , obter produes que identifiquem o erro e faam a recuperao do
mesmo. Alm disso, muito difcil usarmos essa estratgia para compiladores feitos
manualmente, pois elas apenas estariam aumentando (e muito) o nmero de produes e
estados do autmato. Para a implementao usando YACC ou outro gerador qualquer, o
acrscimo dessas produes no representa obstculo para a implementao.

Correo global: idealmente, gostaramos que um compilador fizesse to poucas mudanas


quanto possvel, ao processar uma cadeia de entrada ilegal. Existem algoritmos para escolher
uma sequncia mnima de mudanas de forma a se obter uma correo global de menor custo.
Dadas uma cadeia de entrada incorreta x e uma gramtica G, esses algoritmos iro encontrar
uma rvore gramatical para uma cadeia relacionada y, de tal forma que as inseres, remoes
e mudanas de tokens requeridas para transformar x em y sejam to pequenas quanto possvel.
Infelizmente, esses mtodos so em geral muito custosos de implementar, em termos de
tempo e espao e, ento, essas tcnicas so correntemente apenas de interesse terico.

Esse outro mtodo que, embora teoricamente vlido, no usado na prtica. Aqui o
processo de correo da fonte (para atingir um parsing correto) feito sobre todo o programa
e no apenas sobre frases isoladas. Como se pode perceber, os problemas apresentados no
mtodo anterior apenas so agravados com essa estratgia.

5. AMBIGUIDADE

Uma gramtica ambgua quando existe pelo menos uma sentena gerada pela gramtica que
pode ser gerada de duas ou mais formas diferentes; ou seja, essa sentena ter duas ou mais
rvores de derivao diferentes.
Figura 2: Demonstrao de ambiguidade.

A ambiguidade um problema pois significa que uma mesma sentena pode ter duas
estruturas sintticas diferentes, na mesma gramtica. A estrutura sinttica de uma sentena vai
influenciar no seu significado e como ela interpretada pelo compilador, por exemplo. Desta
forma, uma gramtica ambgua para uma linguagem de programao significa que certos
programas poderiam funcionar de duas (ou mais) maneiras diferentes, dependendo de como o
compilador interprete as partes ambgua.

Obviamente importante que uma linguagem tenha programas que funcionem sempre de uma
mesma maneira, caso contrrio o programador teria dificuldade para aprender como trabalhar
com a linguagem.

Uma ambiguidade por ser evitada de duas formas:

Reescrevendo a gramatica afim de remover a ambiguidade, porm isso pode tornar a


gramatica mais complexa.
Definindo ordens de prioridade durante a derivao.

CONSIDERAES FINAIS

Neste artigo, foi proposto um estudo do funcionamento da etapa de anlise sinttica dos
compiladores. Para isso, foram utilizados alguns conceitos e, tambm, explicitadas as suas
principais funes. Assim, atravs do estudo deste artigo possvel obter um maior
entendimento acerca de um analisador sinttico e as tcnicas utilizadas pelo mesmo para a
identificao de erros de sintaxe em cdigos-fontes e a sua reao a esses erros, como por
exemplo, os alertas que devero ser emitidos ao programador para informa-lo da existncia de
tais erros, em que linhas foram encontrados e qual a possvel causa e soluo.

REFERNCIAS

Compiladores para humanos. Disponvel em: https://johnidm.gitbooks.io/compiladores-para-


humanos/content/part1/syntax-analysis.html. Acesso em: 14 de junho de 2016.

URICER Universidade Regional Integrada do Alto Uruguai e das Misses Campus de


Erechim. Apostila de compiladores. Disponvel em: http://www.cin.ufpe.br/~pftbm/apostila-
LFeC-II.pdf. Acesso em: 14 de junho de 2016.

Anlise Sinttica de Programas. Disponvel em:


http://www.trampoescolar.com/2013/04/analise-sintatica-de-programas.html. Acesso em: 14
de junho de 2016.

Anlise sinttica. Disponvel em:


http://www.dcce.ibilce.unesp.br/~aleardo/cursos/compila/cap03.pdf. Acesso em: 14 de junho
de 2016.

Ricardo Lus de Freitas. Compiladores. Disponvel em: http://ftp-acd.puc-


campinas.edu.br/pub/professores/ceatec/ricardo/Compiladores/Apostila%20de
%20Compiladores.PDF. Acesso em: 14 de junho de 2016.

Você também pode gostar