Beruflich Dokumente
Kultur Dokumente
Introduo
Introduo
Anlise Sinttica ou Parser o processo de analisar uma sequncia de entrada para determinar sua estrutura gramatical segundo uma determinada gramtica formal.
Normalmente a entrada uma sequncia de Tokens vindas do Analisador Lxico.
Introduo - Esquema
Obter prximo token programa Analisador Analisador fonte Sinttico Lxico token Tabela de smbolos
Estrutura Gramatical
Toda linguagem de programao possui regras que descrevem a estrutura sinttica de programas escritos corretamente; A sintaxe de programas pode ser descrita atravs de Gramticas Livres de Contexto.
Gramticas
Gramticas
Oferece uma estrutura linguagem de programao para a traduo de programas fonte em programas objeto corretos; Para novas construes que devem ser adicionadas a uma linguagem de programao, sua adio mais fcil quando a implementao existente for baseada na descrio atravs de gramtica.
A partir da gramtica da linguagem, rvores de sintaxe so construdas para verificar se os tokens podem ser produzidos:
Analisadores sintticos descendentes (top-down); Analisadores sintticos ascendentes (bottom-up).
Descendente:
E E+T T+T id+T id+T*F id+F*F id+id*F id+id*id
Ascendente:
id+id*id F+id*id T+id*id E+id*id E+F*id E+T*id E+T*F E+T E
rvore Gramatical
montante := deposito + taxa_juros * 60
Analisador lxico id1 := id2 + id3 * num Analisador sinttico
:=
id1 id2 + * id3
num
Tratamento de Erros
Erros de Sintaxe
Erros de Sintaxe
A maioria dos erros encontrados em programas so simples e existem mtodos eficientes que geralmente so suficientes.
Erros de Sintaxe
Em alguns casos, um erro pode ter acontecido muito antes da posio em que ele foi descoberto: mais difcil deduzir a natureza do erro; Em alguns casos, o tratamento de erros deve adivinhar o que o programador tinha em mente ao escrever o programa. Alguns mtodos de parsing - detectam um erro o mais cedo possvel
Erros de Sintaxe
Erros de Sintaxe
Erros de Sintaxe
Indicar a linha onde aconteceu o erro indicando o lugar em que o erro foi detectado e emitir uma mensagem clara: ponto e vrgula ausente.
Gramtica BNF
Consiste de 4 partes: Um Smbolo Inicial (Start Symbol) Um conjunto de Tokens Um conjunto de Smbolos Noterminais Um conjunto de Produes (ou Regras)
Estrutura BNF
Smbolo inicial <prog> -> program id() <vars> begin <cmds> end. <vars> -> var <dec-list> <dec-list> -> <dec><dec-list> | <dec> <dec> -> <lista-ids> : <tipo>;
Uma produo
Smbolos no-terminais
Consiste de 4 partes: Um Smbolo Inicial (Start Symbol) Um conjunto de Smbolos terminais (Tokens) Um conjunto de Smbolos Noterminais Um conjunto de Produes (ou Regras)
Smbolo Inicial
O Smbolo inicial trata-se de um noterminal particular que forma a raiz da rvore de Anlise Sinttica para a gramtica. Por conveno, trata-se sempre do primeiro smbolo da Gramtica
Os Tokens so as menores unidades possveis de uma sintaxe. O Token pode definir um tipo lgico da unidade, neste caso, o Lexema representa a escrita literal. Tokens so atmicos Ou seja, no so tratados como sendo compostos por partes menores.
Smbolos No-Terminais
Smbolos No-Terminais representam grandes pedaos da gramtica So Strings envolvidas por < e > como no exemplo <tipo>. No so Strings que ocorrem literalmente no texto do programa. A gramtica informa como eles podem ser expandidos em Tokens.
Produes
As produes so as regras construtoras da rvore Cada uma tem um lado-esquerdo, o separador (::= ou ), e um lado direito.
O lado Esquerdo apenas um No-Terminal O lado Direito composto por uma sequncia de um ou mais Tokens ou NoTerminais.
EBNF
EBNF
Parte pode ser repetida indefinidamente ou omitida completamente: delimitada por chaves
Permite que listas sejam construdas com uma nica regra, em vez de usar recurso e duas regras
EBNF
Derivao Esquerda
Derivao
Existem vrias formas de ver o processo como uma gramtica deriva uma linguagem;
rvores de sintaxe e derivaes
As derivaes oferecem uma descrio precisa da construo de uma rvore de sintaxe de forma top-down; Na derivao, uma produo tratada como uma regra de substituio em que um no terminal da esquerda substitudo pelo string do lado direito da produo;
Exemplo de Derivao
Seja a gramtica:
E E + E | E * E | ( E ) | - E | id
A derivao fornece uma prova de como uma instncia particular gerada a partir da gramtica Em E - (id), dizemos que E deriva - (id)
Derivao
Para entender como os analisadores sintticos trabalham, devemos considerar derivaes em que sempre o smbolo no terminal mais esquerda em qualquer forma sentencial substitudo
Derivao Esquerda
Consiste em uma tcnica para construo da rvore de Anlise Sinttica. A cada vez deve-se expandir sempre o primeiro No-terminal mais a esquerda. Importante porque todo projeto de Compilador Top-Down segue esta forma de construo da rvore.
Exemplo de Gramtica
<prog> begin <lista_instr> end <lista_instr> <instr> | <instr> ; <lista_instr> <instr> <var> := <expr> <var> identificador <expr> <expr> + <expr> | <expr> - <expr> | <var> | numero
Derivao Esquerda
<prog> begin <lista_instr> end begin <instr>; <lista_instr> end begin <var> := <expr>; <lista_instr> end begin A := <expr>; <lista_instr> end begin A := <expr> + <expr>; <lista_instr> end begin A := 2 + <expr>; <lista_instr> end begin A := 2 + <var>; <lista_instr> end begin A := 2 + B; <lista_instr> end begin A := 2 + B; <instr> end begin A := 2 + B; <var> := <expr> end begin A := 2 + B; C := <expr> end begin A := 2 + B; C := <var> end begin A := 2 + B; C := B end
rvore de Sintaxe
As folhas de uma rvore de sintaxe da esquerda para a direita formam a produo da rvore, que a string gerada ou derivada pelo smbolo no terminal da raiz da rvore; Toda rvore impe uma ordem natural da esquerda para a direita Outra definio de uma linguagem gerada por uma gramtica o conjunto de strings que podem ser gerados por uma rvore de sintaxe.
Se um nodo a est a esquerda de um nodo b, ento os filhos de a tambm esto
rvores de Sintaxe
E -> E+E | E*E | (E) | -E | id
E E E E ) ( E E ) E
E
E
E +
rvores de Sintaxe
E E
E
E ) E
E
E ) E id
E + id
E + id
Gramticas Ambguas
Gramticas Ambguas
Uma gramtica ambgua se a partir dela uma sentena pode dar origem a duas rvores sintticas Uma gramtica ambgua traz problemas na implementao de um compilador Eliminao de ambigidade quase sempre possvel
Transformaes na gramtica Definir regras para torn-las no ambguas.
Em alguns casos, uma gramtica ambgua no precisa ser reescrita para eliminar sua ambigidade
<cmd> if <exp> then <cmd> | if <exp> then <cmd> else <cmd> | outro
A string abaixo possui duas rvores de sintaxe if E1 then if E2 then C1 else C2 A regra geral que a gramtica deve seguir casar cada else com o then mais prximo
Transformao de Ling.
Em outros casos, preciso transformar a gramtica Exemplo clssico: gramtica para expresses aritmticas
E ::= id | E '*' E | E +' E | '-' E |'(' E ')'
*
E +
c
E
a
E
Transformao de Ling.
Recurso Esquerda
Recurso Esquerda
Uma gramtica recursiva esquerda se ela possui um no terminal A tal que A A para alguma string :
<exp> <exp> + <termo>
possvel que um analisador sinttico entre em loop infinito quando ele utiliza derivaes de uma gramtica recursiva esquerda.
Considere a produo
A Ab | c
Aplicaes repetidas da primeira regra constroem bs direita de A, terminando eventualmente com um c esquerda
Construmos a string da direita para esquerda.
A A A c b b ... b b b ...
Produz:
A cA A bA |
A
... A A
...
Gramticas LL(1)
Para implementar um Analisador Sinttico Descendente mais facilmente, a gramtica deve ser bem escrita. Alm de no serem recursivas esquerda, as gramticas devem obedecer duas restries:
O lado direito das produes devem comear por terminais; Para um no terminal qualquer, no devem existir duas regras que comecem com um mesmo terminal.
Gramticas LL(1)
As gramticas que:
No so recursivas esquerda; Para um mesmo no terminal, no existem regras cujo lado direito comecem com o mesmo terminal .
Dispondo de uma gramtica LL(1), podese fazer ASD preditivo de forma mais eficiente.
Fatorao Esquerda
Fatorao Esquerda
Regra:
para cada no terminal A, achar o maior prefixo comum a duas ou mais alternativas; se h um prefixo em comum, ento substituir a produo A 1 | ... | n | (em que representa as alternativas que no comeam por ) por A A| A 1|...|n
Fatorao Esquerda
Exemplo
<atribuio> id = <exp> ; <funo> id ( <lista-exp> ) ;
Fatorao Esquerda
Fatorao Esquerda
Exemplo 2
<if> ::= if <e> then <c> <if-else> ::= if <e> then <c> else <c>
<if> if <e> then <c> ( else <c> | ) <if> if <e> then <c> [ else <c> ]
A construo top-down de uma rvore de sintaxe a partir de uma seqncia de tokens de entrada feita comeando pela raiz, rotulada pelo smbolo inicial, e repetidamente executando os seguintes passos:
No nodo n rotulado pelo no terminal A, selecione uma das produes de A e construa filhos para o nodo n para cada smbolo do lado direito da produo; Encontre o prximo nodo onde uma subrvore pode ser construda.
Seja a gramtica:
<tipo> <tipo-simples> | id | array [ <tipo_simples> ] of <tipo> <tipo_simples> integer | char | num ponto-ponto num
Seja a entrada:
Fonte
D)
tipo
E)
integer
Um analisador sinttico descendente recursivo um mtodo top-down de anlise sinttica em que uma srie de chamadas recursivas so aplicadas quando se processa a string de entrada:
Um procedimento associado a cada no terminal da gramtica.
A seqncia de procedimentos que so executados ao se processar a string de entrada definem implicitamente uma rvore de sintaxe para a string de entrada; Cada no terminal encontrado gera uma chamada a um procedimento para trat-lo; Cada terminal da entrada casado com o terminal do lado direito da produo; O atributo token quem guia a escolha sobre qual produo deve ser usada;
Implementao
Seja a gramtica:
<tipo> <tipo-simples> | id | array [ <tipo_simples> ] of <tipo> <tipo_simples> integer | char | num ponto-ponto num
O analisador sinttico preditivo para esta gramtica pode ser implementado conforme os prximos passos:
Pseudo-Cdigo
procedimento parse() Token <- AnLex.obterProxToken(); tipo(); //Smbolo Inicial da Gram. procedimento casaToken(Esperado) Se Token = Esperado Token<- AnLex.obterProxToken(); Seno Erro Sinttico; Imprime Esperado:+Esperado; Fim Se
Pseudo-Cdigo
procedimento tipo_simples() Se Token = INTEGER casaToken(INTEGER); Seno Se Token = CHAR casaToken(CHAR); Seno Se Token = NUM casaToken(NUM); casaToken(PONTO-PONTO); casaToken(NUM); Seno Erro Sinttico; Fim Se
Pseudo-Cdigo
procedimento tipo() Se Token = INTEGER ou CHAR ou NUM tipo_simples(); Seno Se Token = ID casaToken(ID); Seno Se Token = ARRAY casaToken(ARRAY); casaToken(ABRE_COLCHETES); tipo_simples(); casaToken(FECHA_COLCHETES); casaToken(OF); tipo(); Seno Erro Sinttico;
Conjunto Primeiro
Conjunto Primeiro
O analisador sinttico preditivo confia na informao sobre quais os primeiros smbolos podem ser gerados pelo lado direito da produo Definimos PRIMEIRO () o conjunto de tokens que aparecem como os primeiros smbolos de uma ou mais strings de :
PRIMEIRO (tipo_simples) = { integer, char, num } PRIMEIRO (array [ tipo_simples ] of tipo) = {array} PRIMEIRO (tipo) = {integer, char, num, id, array}
Conjunto Primeiro
Conjunto Primeiro
As construes de controle de fluxo na maioria das linguagens de programao, com suas palavras chave distintas, podem ser analisadas pelo analisador sinttico preditivo: <cmd>::= if <exp> then <cmd> [else <cmd>]
| while <exp> do <cmd> | begin <cmds_opcs> end
As palavras reservadas if, while e begin nos informam qual alternativa a nica correta.