Compiladores. Análise Sintática

Documentos relacionados
Compiladores. Exemplo. Caraterísticas de Gramáticas. A αβ 1 αβ 2. A αx X β 1 β 2. Lembrando... Gramáticas Livres de Contexto

Compiladores Aula 6. Celso Olivete Júnior.

V Análise Sintática. V.1.1 Gramáticas Livres de Contexto Definições de GLC

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática

Análise sintática. Análise sintática ascendente. Parte-se dos símbolos terminais em direção ao símbolo inicial da gramática. Derivação mais à direita

Compiladores Analisador Sintático. Prof. Antonio Felicio Netto Ciência da Computação

Compiladores Aula 4. Celso Olivete Júnior.

Análise Sintática (Cap. 04) Análise Sintática Descendente

BNF (Backus-Naur Form) Gramática Livres de Contexto / Estruturas Recursivas

Compiladores - Análise Ascendente

Compiladores - Análise Ascendente

INE5416 Paradigmas de Programação. Ricardo Azambuja Silveira INE CTC UFSC E Mail: URL:

Vantagens de uma Gramática. Sintaxe de uma Linguagem. Analisador Sintático - Parser. Papel do Analisador Sintático. Tiposde Parsers para Gramáticas

Plano da aula. Compiladores. Os erros típicos são sintáticos. Análise Sintática. Usando Gramáticas. Os erros típicos são sintáticos

Compiladores. Introdução

Compiladores. Análise Léxica

Análise Sintática I. Eduardo Ferreira dos Santos. Abril, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 42

Construção de Compiladores Aula 16 - Análise Sintática

Análise Sintática. Fabiano Baldo

Sintaxe e Semântica. George Darmiton da Cunha Cavalcanti.

INE5317 Linguagens Formais e Compiladores AULA 9: Propriedades e Reconhecimento das Linguagens Livres do Contexto

Como construir um compilador utilizando ferramentas Java

Análise Sintática II: Analisadores Descendentes Preditivos

Análise Sintática LL(1)

Análise Sintática. Eduardo Ferreira dos Santos. Outubro, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 18

Linguagens Livres de Contexto

Parsing Preditivo. Antes de ser abordado o Parsing Preditivo, será apresentado o Analisador Sintático Descendente Recursivo.

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática

Python e sua sintaxe LNCC UFRJ

Linguagens Formais e Autômatos P. Blauth Menezes

Um Compilador Simples. Definição de uma Linguagem. Estrutura de Vanguarda. Gramática Livre de Contexto. Exemplo 1

IV Gramáticas Livres de Contexto

Análise sintática. Análise sintática. Top-down ou descendente. Com retrocesso: por tentativa e erro. Preditiva: para gramáticas LL(1) 09/04/2012

Análise Sintática Descendente

Compilação: Erros. Detecção de Erros: * Analisadores Top-Down - Preditivo Tabular (LL) - Feito a mão. * Analisadores Botton-Up: - Shift-Reduce (SLR)

Gramáticas Livres de Contexto

Análise Sintática II. Eduardo Ferreira dos Santos. Outubro, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 34

LINGUAGEM LIVRE DE CONTEXTO GRAMÁTICA LIVRE DE CONTEXTO

Análise sintática. Prof. Thiago A. S. Pardo Tratamento de erros sintáticos

Compiladores - Gramáticas

Análise Sintática Bottom-up

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática

INE5318 Construção de Compiladores. AULA 4: Análise Sintática

Linguagens Formais e Autômatos. Simplificação de Gramáticas Livre do Contexto (GLC)

Conceitos de Linguagens de Programação

Compiladores - Análise LL(1)

Compiladores: P ASCAL jr

Tokens, Padroes e Lexemas

Compiladores. Capítulo 3: Análise Sintática Introdução

Reduce: reduz o que está imediatamente à esquerda do foco usando uma produção

Disciplina: LINGUAGENS FORMAIS, AUTÔMATOS E COMPUTABILIDADE Prof. Jefferson Morais

LFA Aula 09. Gramáticas e Linguagens Livres de Contexto 18/01/2016. Linguagens Formais e Autômatos. Celso Olivete Júnior.

Análise sintática. Prof. Thiago A. S. Pardo. Análise sintática ascendente

Análise Sintática Introdução

Tratamento dos Erros de Sintaxe. Adriano Maranhão

Compiladores. Top-Down x Bottom Up. Plano da aula. Redução exemplo 1. Redução exemplo 1. Lembrando: construir a tabela de análise LL(1) A Abc b B d

Construção de Compiladores Aula 17 - Análise Sintática Descendente

Gramáticas Livres de Contexto Parte 1

Gramática. Prof. Yandre Maldonado e Gomes da Costa. Prof. Yandre Maldonado - 1

Gramática. Gramática. Gramática

Conceitos de Linguagens de Programação

Linguagens Livres do Contexto. Adaptado de H. Brandão

Analisadores Sintáticos LR

Linguagens e Programação Gramáticas. Paulo Proença

Introdução à Programação

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 12. Instituto de C

Concurso Público para provimento de cargo efetivo de Docentes. Edital 20/2015 CIÊNCIA DA COMPUTAÇÃO II Campus Rio Pomba

Análise sintática. Análise sintática ascendente. Bottom-up, ascendente ou redutiva. Analisadores de precedência de operadores Analisadores LR

Capítulo 5 Análise sintática

Construção de Compiladores Aula 3 - Analisador Sintático

COMPILADORES. Revisão Linguagens formais Parte 02. Prof. Geovane Griesang

Se o símbolo inicial não fizer parte do conjunto de símbolos férteis, a linguagem gerada pela gramática é vazia.

Linguagens de Programação

Revisão de GLC e Analisadores Descendentes

Interfaces de Vanguarda do Compilador

Compiladores - Análise Léxica

Transcrição:

Compiladores Análise Sintática

Análise Sintática Vejamos um exemplo, seja a seguinte instrução de atribuição: posicao = inicial + incremento * 60 Na análise sintática tenta-se construir uma frase correta com os tokens produzidos pela fase anterior. É usual construir uma estrutura em árvore para representar a frase obtida. A partir dos tokens cria uma representação intermediária tipo árvore (árvore sintática) mostra a estrutura gramatical da sequência de tokens

Análise sintática Regras Sintáticas Especificam as sequências de símbolos que constituem estruturas sintáticas válidas; Estas regras permitem o reconhecimento de expressões e comandos; Exemplo: Pascal: atribuição a:=b; C: atribuição a=b;

Análise sintática As linguagens de programação possuem regras precisas para descrever a estrutura sintática de programas bem formados; Exemplo: Linguagem C Funções declaração e comando Comando expressões A estrutura sintática das construções de uma linguagem de programação é especificada pelas regras gramaticais de uma gramática livre de contexto

Análise sintática Benefícios para projetistas de linguagens: Uma gramática provê uma especificação sintática precisa e fácil de entender para as linguagens de programação; A partir de determinadas classes gramaticais, podemos construir automaticamente um analisador sintático eficiente; Durante o processo de construção do analisador, podem ser detectadas ambiguidades sintáticas; Uma gramática permite o desenvolvimento de uma linguagem iterativamente, possibilitando lhe acrescentar novas construções para realizar novas tarefas;

Análise sintática Utiliza os tokens produzidos pela análise léxica e verifica a formação do programa com o uso de GLC (Gramáticas Livres de Contexto) A partir dos tokens é criada uma representação intermediária da árvore sintática mostra a estrutura gramatical da sequência de tokens;

Análise Sintática posicao = inicial + incremento * 60 <id, 1>, <=>, <id, 2>, <+>, <id, 3>, <*>, <numero, 60> Analisador Sintático <=> Árvore Sintática <id, 1> <+> <id,2> <*> <id,3> 60

Análise sintática O analisador sintático recebe do analisador léxico uma cadeia de tokens representando o programa fonte e verifica se essa cadeia de tokens pertence à linguagem gerada pela gramática.

Análise sintática O analisador sintático constrói uma árvore de derivação e a passa ao restante do front-end do compilador para processamento. Obs: na prática não é necessário construir a árvore de derivação explicitamente, pois as ações de verificação e tradução podem ser implementados em um único módulo.

Análise sintática Existem 3 estratégias gerais de análise sintática para o processamento de gramáticas: Universal, Descendente (Top Down) e Ascendente (Bottom Up). Em ambas as estratégias a entrada do analisador sintático é consumida da esquerda para a direita, um símbolo de cada vez Os analisadores criados à mão normalmente utilizam gramáticas LL Os analisadores sintáticos para a maioria de gramáticas LR geralmente são construídos utilizando ferramentas automatizadas

Análise sintática Para descrever uma linguagem é necessário uma série de regras gramaticais; As regras são formadas por uma única estrutura do lado esquerdo seguida do metasímbolo ::= e por uma sequência de itens do lado direito (símbolos ou estruturas); Estruturas entre <> são chamadas de não terminais; Símbolos como garota e cachorro são chamados de terminais; As regras gramaticais são as produções.

Análise sintática Exemplo de uma gramática para expressões aritméticas de adição e multiplicação: <exp>::= <exp>+<exp> <exp>*<exp> (exp) <num> <num> ::= <num><digito> <digito> <digito> ::= 0 1 2 3 4 5 6 7 8 9

Análise sintática BNF Sentenças simples consistem de uma frase nominal e de uma frase verbal seguida de um ponto, da seguinte maneira: <sentence> ::= <frase_nominal><frase_verbal>. Deve-se saber descrever a estrutura de uma frase nominal e de uma frase verbal: <frase_nominal> ::= <artigo><substantivo> <artigo> ::= um a <substantivo> ::= garota cachorro <frase_verbal> ::= <verbo> <frase_nominal> <verbo> ::= viu abraça

Análise sintática Cada regra gramatical apresentada consiste de uma string colocada entre < e >, esta string é o nome da estrutura que está sendo descrita; O símbolo ::= pode ser lido como consiste de ou é o mesmo que ; Após o símbolo ::=, temos uma sequência de outros nomes e símbolos;

Análise sintática Construção de uma sentença legal: Inicia-se com o símbolo <sentença> e prossegue-se trocando o lado esquerdo por alternativas do lado direito nas regras; Este processo criará uma derivação na linguagem; Desta forma, podemos construir a sentença: A garota viu um cachorro ;

Análise sintática Montando a derivação da sentença: a garota viu um cachorro <sentença> <frase_nominal><frase_verbal>. <artigo><substantivo><frase_verbal>. a <substantivo><frase_verbal>. a garota <frase_verbal>. a garota <verbo><frase_nominal>. a garota viu <frase_nominal>. a garota viu <artigo><substantivo>. a garota viu um <substantivo>. a garota viu um cachorro. Pode-se começar com a sentença a garota viu um cachorro, e voltar até <sentença> para provar que é uma sentença válida da linguagem.

Análise sintática - Extensão da BNF EBNF (Extend BNF) Definição EBNF para uma calculadora Definição de sintaxe para uma linguagem Definição EBNF para uma linguagem de programação simples

Análise sintática Recursão a Esquerda Na gramática a seguir, o não-terminal E representa expressões consistindo em termos separados pelo operador +; T representa termos consistindo em fatores separados pelo operador *; e F representa fatores que podem ser expressos entre parênteses ou identificadores. E E+T T T T*F F F (E) id Essa gramática não pode ser usada com o método de análise descendente pois é recursiva a esquerda.

Análise sintática Recursão a Esquerda Gramáticas são recursivas à esquerda se possui um não-terminal A para o qual existam derivações do tipo A Aα para uma cadeia α. Para o par de produções recursivas à esquerda A Aα β A substituição abaixo elimina a recursão imediata à esquerda: A βa A αa ε Nenhuma outra modificação é requerida a partir de A.

Análise sintática Recursão a Esquerda Gramática para expressões simples: E E + T T T T * F F F ( E ) id Aplicando transformação na Primeira Regra E E + T T é do tipo A Aα β Obtemos: A βa E TE A αa ε E +TE ε

Análise sintática Recursão a Esquerda Gramática para expressões simples: E E + T T T T * F F F ( E ) id Aplicando transformação na Segunda Regra E T * F F é do tipo A Aα β Obtemos: A βa T FT A αa ε E *FT ε

Análise sintática Recursão a Esquerda Assim, obtemos a partir de: E E + T T T T * F F F ( E ) id A gramática equivalente sem recursão à esquerda: E TE E +TE T FT T *FT ε F (E) id

Análise sintática Recursão a Esquerda Exemplo 2: A Aa b Para o par de produções recursivas à esquerda A Aα β Exemplo 3: S SS+ SS* a Exemplo 4: S Sa B B Bb c Considere para eliminar a recursão A βa A αa ε

Análise sintática Recuperação de erro O recuperador de erros em um analisador sintático possui objetivos simples, mas desafiadores: Informar a presença de erros de forma clara e precisa; Recuperar-se de cada erro com rapidez suficiente para detectar erros subsequentes; Acrescentar um custo mínimo no processamento de programas corretos. Como um recuperador de erro deve informar a presença de um erro? No mínimo ele precisa informar o local no programa fonte onde o erro foi detectado, pois existe uma boa chance de que o local exato do erro seja em um dos tokens anteriores.

Análise sintática Recuperação de erro Recuperação em nível de frase Ao detectar um erro, o analisador sintático pode realizar a correção local sobre o restante da entrada. Uma correção local típica compreende a substituição de uma vírgula por um ponto-e-vírgula, exclusão de um ponto-e-vírgula desnecessário. A escolha da correção local fica a critério do projetista do compilador.

Análise sintática Recuperação de erro Produções de Erro Nesta estratégia de recuperação de erro podemos estender a gramática da linguagem em mãos com produções que geram construções erradas, antecipando assim os erros mais comuns.

Análise sintática Não é possível enumerar a sintaxe de todos os programas das mais diferentes linguagens; É necessário uma maneira de definir um conjunto infinito usando uma descrição finita: A sintaxe deuma linguagem é definida através deuma gramática; Gramática: conjunto de regras que definem todos os construtores que podem ser aceitos na linguagem.

Análise sintática Fortran foi definido através da especificação de algumas regras em inglês; Algol 60 foi definido através de uma gramática livre de contexto desenvolvida por Jonh Backus; Essa gramática ficou conhecida como BNF (Backus-Naur Form); BNF foi utilizada posteriormente na definição de várias linguagens como C, Pascal e Ada; BNF é uma metalinguagem pois consiste numa linguagem para descrição de outras linguagens.

Análise sintática Observe os dois trechos de código a seguir, sendo o código a. em C e o código b. em Pascal a. b. while(x!=y) while x<>y do { begin...... } end Ambas possuem a mesma estrutura conceitual, porém, diferem na aparência léxica; Quando duas construções diferem apenas no nível léxico, se diz que elas seguem a mesma sintaxe abstrata e diferem na sintaxe contreta.

Análise sintática Com tudo isso, é possível concluir que a descrição sintática de uma linguagem: Ajuda o programador a saber como escrever um programa sintaticamente correto; Pode ser usada para determinar se um programa está sintaticamente correto este é exatamente o trabalho do compilador!

Análise sintática - Análise Top-Down Como reconhecer se uma sentença está de acordo com uma gramática? Pode-se implementar reconhecedores de sentença Recursivamente, com retrocesso Com mecanismo preditivo First e Follow Para usar os reconhecedores, primeiramente deve-se transformar a Gramática Livre de Contexto Eliminação de produções vazias Eliminação de recursividade a esquerda Fatoração de uma gramática

Análise sintática Conjuntos First First(α) Definição informal: conjunto de todos os terminais que começam com qualquer sequência derivável de α Definição formal Se existe um t T e um β V* tal que α * t β então t First(α) Se α * ε então ε First(α) A B C D first(a) = {b, c, d} B b C c D d first(b)= {b} first(c)= {c} first(d)= {d}

Análise sintática Conjuntos First Para determinar o FIRST(A): Se a é terminal, então o first(a) = a; Se A é não terminal e A aα é uma produção, então se acrescenta a ao conjunto de first de A, logo: first(a)=a; Se A ε é uma produção ε, logo first(a)=ε; Se A Y1Y2...Yk é uma produção, então todo i tal que todos Y1...Yi-1 são não terminais e FIRST(Yj) contém ε, onde j=1,2...i-1. acrescente todo símbolo diferente de ε de FIRST(Yj) a FIRST(A). Se ε FIRST(A), para todo i=1,2..k. então acrescente ε a FIRST(A).

Análise sintática Conjuntos First E TE E +TE ε T FT T *FT ε F (E) id First(E) = {? } First(E ) = {? } First(T) = {? } First(T ) = {? } First(F) = {? }

Análise sintática Conjuntos First E TE E +TE ε T FT T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(T ) = { *, ε } First(F) = { (, id }

Análise sintática Conjuntos First E TE E +TE ε T FT T *FT ε First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(T ) = { *, ε } F (E) id First(F) = { (, id } Se F derivasse em ε seria preciso incluir o first(t ) em first(t)

Análise sintática Conjuntos First E TE E +TE ε T FT H E T T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(H) = {? } First(T ) = { *, ε } First(F) = { (, id }

Análise sintática Conjuntos First E TE E +TE ε T FT H E T T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(H) = { First(E ) U First(T) } First(T ) = { *, ε } First(F) = { (, id }

Análise sintática Conjuntos First E TE E +TE ε T FT H E T T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(H) = { +, (, id } First(T ) = { *, ε } First(F) = { (, id }

Análise sintática Conjuntos Follow Se A é um não-terminal, o follow(a) é o conjunto de terminais imediatamente seguintes (à direita) de A

Análise sintática Conjuntos Follow Para determinar follow(a) 1. Colocar $ em follow(s) se S é o símbolo de partida. $ é o marcador de fim de entrada durante análise 2. Se existe uma produção A αbβ e β ε então tudo que estiver em first(β), exceto ε, deve ser adicionado em follow(b) 3. Se existe uma produção A αb ou A αbβ onde first(β) contem ε (β ε), então tudo que está em follow(a) está em follow(b)

Análise sintática Conjuntos Follow E TE E +TE ε T FT T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(T ) = { *, ε } First(F) = { (, id } Follow(E) = { ), $ } Follow(E ) = Follow(E) = { ), $ } Follow(T) = First(E ) U Follow(E) U Follow(E ) = { +, ), $} Follow(T ) = Follow(T) = {+, ), $} Follow(F) = First(T ) U Follow(T) U Follow(T ) = { *, +, ), $}

Análise sintática Conjuntos Follow Regra 2 e regra 1 E TE E +TE ε T FT T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(T ) = { *, ε } First(F) = { (, id } Follow(E) = { ), $ } Follow(E ) = Follow(E) = { ), $ } Follow(T) = First(E ) U Follow(E) U Follow(E ) = { +, ), $} Follow(T ) = Follow(T) = {+, ), $} Follow(F) = First(T ) U Follow(T) U Follow(T ) = { *, +, ), $}

Análise sintática Conjuntos Follow Regra 3 E TE E +TE ε T FT T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(T ) = { *, ε } First(F) = { (, id } Follow(E) = { ), $ } Follow(E ) = Follow(E) = { ), $ } Follow(T) = First(E ) U Follow(E) U Follow(E ) = { +, ), $} Follow(T ) = Follow(T) = {+, ), $} Follow(F) = First(T ) U Follow(T) U Follow(T ) = { *, +, ), $}

Análise sintática Conjuntos Follow Regra 2 e Regra 3 E TE E +TE ε T FT T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(T ) = { *, ε } First(F) = { (, id } Follow(E) = { ), $ } Follow(E ) = Follow(E) = { ), $ } Follow(T) = First(E ) U Follow(E) U Follow(E ) = { +, ), $} Follow(T ) = Follow(T) = {+, ), $} Follow(F) = First(T ) U Follow(T) U Follow(T ) = { *, +, ), $}

Análise sintática Conjuntos Follow Regra 3 E TE E +TE ε T FT T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(T ) = { *, ε } First(F) = { (, id } Follow(E) = { ), $ } Follow(E ) = Follow(E) = { ), $ } Follow(T) = First(E ) U Follow(E) U Follow(E ) = { +, ), $} Follow(T ) = Follow(T) = {+, ), $} Follow(F) = First(T ) U Follow(T) U Follow(T ) = { *, +, ), $}

Análise sintática Conjuntos Follow Regra 2 e Regra 3 E TE E +TE ε T FT T *FT ε F (E) id First(E) = First(T) = First(F) ={ (,id } First(E ) = { +, ε} First(T) = First(F) = { (, id } First(T ) = { *, ε } First(F) = { (, id } Follow(E) = { ), $ } Follow(E ) = Follow(E) = { ), $ } Follow(T) = First(E ) U Follow(E) U Follow(E ) = { +, ), $} Follow(T ) = Follow(T) = {+, ), $} Follow(F) = First(T ) U Follow(T) U Follow(T ) = { *, +, ), $}

Análise sintática First Follow S AB first(s)={c} follow(s)={ $ } A c ε first(a)={c, ε} follow(a)={ c } B cbb ca first(b)={c} follow(b)={ $ }

Análise sintática Analisador Top-Down A análise top-down é realizada da raiz para as folhas Parte-se de um não-terminal que é o símbolo inicial da gramática em direção aos terminais

Análise sintática preditiva não-recursiva O símbolo da cadeia de entrada, em análise, é suficiente para determinar qual regra de produção deve ser escolhida São construídos utilizando gramáticas LL ( 1 ) Cadeia de entrada é analisada da esquerda para a direita ( Left-toright) A derivação das produções é feita mais a esquerda ( Leftmost) A cada passo é observado um ( 1) símbolo a frente para determinar que ação deve ser tomada

Análise sintática preditiva não-recursiva Condições Eliminar a recursividade a esquerda Fatorar a gramática Construir o conjunto first e follow

Análise sintática preditiva não-recursiva Construção da tabela preditiva Dimensão1: não terminal X Dimensão2: símbolo de entrada (terminal) t A entrada (X, t) contém a regra da produção a aplicar obtida a partir dos conjuntos first e follow S caa first(s)={c} follow(s)={ $ } A cb B first(a)={b, c, ε} follow(a)={ a } B bcb ε first(b)={b, ε} follow(b)={ a } Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro

Análise Sintática Tabela Preditiva Topo da pilha S S deriva em c? Sim: S caa Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$

Análise Sintática Tabela Preditiva S caa substitui na pilha o S por caa Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$

Análise Sintática Tabela Preditiva O topo da pilha é igual ao valor do topo de entrada Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c)

Análise Sintática Tabela Preditiva A deriva em b? Sim: A B Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$

Análise Sintática Tabela Preditiva Substitui o A na pilha por B Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$ A B Ba$ bca$

Análise Sintática Tabela Preditiva B deriva em b? Sim: B bcb Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$ A B Ba$ bca$

Análise Sintática Tabela Preditiva B deriva em b? Sim: B bcb Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$ A B Ba$ bca$ B bcb

Análise Sintática Tabela Preditiva O topo da pilha é igual ao valor do topo de entrada Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$ A B Ba$ bca$ B bcb bcba$ bca$ casar(b)

Análise Sintática Tabela Preditiva O topo da pilha é igual ao valor do topo de entrada Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$ A B Ba$ bca$ B bcb bcba$ bca$ casar(b) cba$ ca$ casar(c)

Análise Sintática Tabela Preditiva B deriva em a? SIM: quando B ε Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$ A B Ba$ bca$ B bcb bcba$ bca$ casar(b) cba$ ca$ casar(c) Ba$ a$ B ε

Análise Sintática Tabela Preditiva O topo da pilha é igual ao valor do topo de entrada Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$ A B Ba$ bca$ B bcb bcba$ bca$ casar(b) cba$ ca$ casar(c) Ba$ a$ B ε a$ a$ casar(a)

Análise Sintática Tabela Preditiva O topo da pilha é igual ao valor do topo de entrada Não Terminal Símbolo de Entrada a b c S erro erro S caa A A B A B A cb B B ε B bcb erro Entrada: cbca Pilha Entrada Ação S$ cbca$ S caa caa$ cbca$ casar(c) Aa$ bca$ A B Ba$ bca$ B bcb bcba$ bca$ casar(b) cba$ ca$ casar(c) Ba$ a$ B ε a$ a$ casar(a) $ $ aceita

Análise sintática Analisador Bottom-up A análise top-down é realizada das folhas para a raiz Parte-se dos símbolos terminais em direção ao símbolo inicial da gramática

Análise sintática Analisador Bottom-up id * id F * id T * id T * F T E E E + T T T T * F F F (E) id id F id F id id T * F F id id T T * F F id Entrada: id*id id

Análise sintática Analisador Bottom-up O processo de análise sintática ascendente pode ser encarado como um processo de reduzir uma cadeia w para o símbolo inicial da gramática Redução : operação de substituição do lado direito de uma produção pelo nãoterminal correspondente do lado esquerdo Para a regra A α, α pode ser reduzido em A

Análise sintática Analisador Bottom-up Analisadores sintáticos Bottom-up Analisadores conhecidos como empilha-reduz (shift-reduce) Etapas do reconhecimento: determinar quando reduzir e determinar a produção a ser utilizada para que a análise prossiga

Análise sintática Analisador Bottom-up Componentes do analisador bottom-up Pilha, onde os símbolos a serem reduzidos são empilhados Tabela sintática, que guia o processo de shift e reduce Processo de reconhecimento de uma sentença 1. Empilhar símbolos da cadeia de entrada 2. Quando um lado direito apropriado de uma produção aparece, ele é reduzido (substituído) pelo lado esquerdo da produção 3. Se a análise tiver sucesso, esse processo ocorre até que os símbolos da cadeia de entrada sejam todos consumidos e a pilha fique apenas com o símbolo inicial da gramática

Análise sintática Analisador Bottom-up Gramática: S (L) a L L+S S Entrada: a+a Pilha Cadeia Regra $ (a+a)$ $ (a+a)$ shift ( $( a+a)$ shift a $(a +a)$ reduce S a $(S +a)$ reduce L S $(L +a)$ shift + $(L+ a)$ shift a $(L+a )$ reduce S a $(L+S )$ reduce L L+S $(L )$ shift ) $(L) $ reduce S (L) $S $ aceita

Análise sintática Analisador Bottom-up Operações durante a análise: Shift: coloca-se no topo da pilha o primeiro símbolo da cadeia de entrada Reduce: substitui-se o lado direito do handle pelo seu lado esquerdo Aceita: a cadeia de entrada é reconhecida Erro: a cadeia de entrada não é reconhecida

Referências SEBESTA, Robert W. Conceitos de linguagens de programação. 9ª ed. Porto Alegre: Bookman, 2011. 792 p. ISBN 978-85-7780-791-8. Notas de aula Professora Isabel Harb Manssour