Compiladores I Notas de aula Prof. José Carlos Bins Filho

Tamanho: px
Começar a partir da página:

Download "Compiladores I Notas de aula Prof. José Carlos Bins Filho"

Transcrição

1 1. Introdução Compiladores I Notas de aula Prof. José Carlos Bins Filho Software a serem usados: Lex e Yacc Web page: Fases de um compilador Programa fonte Análise Síntese T a b e l a d e s í m b o l o s Pré-processador Análise Léxica Análise sintática Análise semântica Geração de código intermediário Otimização do código intermediário Geração do código Programa Objeto Pré-processador: Lê código fonte e transforma este código fonte de forma a prepará-lo para compilação. Ex: transforma C++ em C, inclui arquivos, executa defines, etc... Análise Léxica: Lê o código fonte e gera um conjunto de tokens para os lexemas encontrados. Lexema: conjunto de caracteres do programa fonte que representa um elemento sintático. Palavra válida em uma linguagem. No caso, na Gramática livre de contexto que define a linguagem de programação usada. Token: Classificação léxica de um lexema. Ex: a = b + c; G e r ê n c i a m e n t o d e E r r o s Notas de aula de compiladores I José Carlos Bins Filho Página 1

2 Lexema Token a Identificador Caracter em branco = Operador de atribuição Caracter em branco b Identificador Caracter em branco + Operador Aritmético Caracter em branco c Identificador ; Separador de comandos Análise sintática: Recebe os tokens e usa as regras de sintaxe (produções) para agrupa-los em estruturas sintáticas. Atualiza a tabela de símbolos. Análise semântica: Testa o significado das palavras em relação ao contexto onde elas se encontram (espaço e tempo). Ex: escopo, declaração, tipo, etc... Geração de código intermediário: Cria um código numa linguagem simples sem uso de registradores. Otimização de código: Reduz o tamanho e aumenta a velocidade do código intermediário. Tem grande influência na performance final do código. Ex: remover comandos que não serão executados; unir loops; desenrolar loops; acessar tabelas esparsas de forma eficiente; Geração de código: Converte o código intermediário numa sequência de instruções de máquina. Tabela de símbolos: Tabela que armazena identificadores e seus atributos. É usada durante todo o processo de compilação. Exemplo de atributos: tipo, escopo, linha de declaração, valor (para constantes), etc Revisão de linguagens formais Alfabeto (Σ): Conjuntos de símbolos usados numa linguagem. O símbolo Λ representa a palavra vazia. Notas de aula de compiladores I José Carlos Bins Filho Página 2

3 Linguagem (L): Conjunto de palavras (sequência de símbolos do alfabeto) Expressão regular: Gerador recursivo de palavras pertencentes a uma linguagem. Todo símbolo do alfabeto (α Σ) é uma ER Se β 1 é uma ER e β 2 é uma ER então: β 1 β 2 é uma ER (concatenação) β 1 + β 2 é uma ER (alternativa) β 1 * é uma ER (fechamento de Kleene/repetição) (β 1 ) é uma ER Notações alternativas: β 1 + : uma ou mais repetições β 1?: zero ou uma repetição β 1 β 2 : alternativa Exercício 1: Dê exemplos de palavras geradas pelas expressões regulares abaixo. Diga que linguagem é representada pela expressão regular 0 * 1 + (0 * 10 * 10 * 10 * ) * (0 + 1) * (0 * 1 * ) * Autômatos finitos: Reconhecedor de palavras pertencentes a uma linguagem. Normalmente representado graficamente. : Nodo ou estado : Transição. As transições são marcadas por símbolos. Quando um símbolo da palavra é lido a transição marcada com aquele símbolo a partir do estado atual é efetuada. Se não há nenhuma transição a partir do estado atual marcada pelo símbolo lido então a palavra não pertence a linguagem. Se o estado atual é um estado final e não existem mais símbolos a serem lidos então a palavra é reconhecida como pertencendo a linguagem. Representação de estados iniciais e finais: Iniciais: ou Notas de aula de compiladores I José Carlos Bins Filho Página 3

4 Finais: ou + Todo autômato finito tem uma expressão regular correspondente. Se o autômato é determinístico não pode haver transição com o símbolo Λ nem duas ou mais transições partindo do mesmo estado com o mesmo símbolo. Exercicios: a b b =? ER a ab * ba = autômato finito determinístico Gramáticas: Uma gramática é um mecanismo para gerar sentenças/palavras de uma Linguagem. Uma Gramática é definida por uma quadrupla G={N,T,S,P} onde: N é o conjunto de símbolos não Terminais, T é o conjunto de símbolos terminais do alfabeto (Σ) da linguagem, S é o símbolo inicial S N, e P é o conjunto de regras de produção que descreve como os não-terminais devem ser derivados. Ex: G1 = {{S,B},{0,1},S,P} P: S B B 0B B 1B B Λ OBS: Λ representa o símbolo vazio. Pode-se representar produções de forma reduzida unindo-se o lado direito das mesmas por um símbolo (desde que o mesmo não faça parte da linguagem). EX: B 0B 1B Λ é equivalente as 3 produções acima. Notas de aula de compiladores I José Carlos Bins Filho Página 4

5 Uma gramática é dita regular se as suas produções são do tipo: α wβ e α w, onde α e β N w T*. Gramáticas regulares geram linguagens regulares que podem ser representadas também por expressões regulares e autômatos finitos. Uma gramática é livre de contexto se suas produções são do tipo: α β, onde α N e β (N T)*. Linguagens de programação são normalmente representadas por gramáticas livres de contexto. Lista de exercícios de revisão de Linguagens formais 1) Diferencie gerador de Linguagem de Reconhecedor de Linguagem e dê exemplos. 2) Mostre um autômato finito para a linguagem de todas as sentenças em {a,b} que terminem em número par de as. 3) Dê uma expressão regular para a linguagem de todos os números fracionários com sinal. 4) Dê uma gramática para a linguagem L = {a n b n n = 1, 2, 3,...}. 5) Mostre um Autômato Finito, se existe, para a linguagem L. 6) Diferencie Linguagem Livre de Contexto de Linguagem sensível ao contexto. 7) Dê o autômato finito e uma árvore de derivação mais a esquerda para a linguagem abaixo e para a sentença id + id * id. E E + E E * E id 3. Análise léxica O analisador léxico lê o programa fonte caracter a caracter e produz uma sequência de tokens que são usados pelo analisador sintático. Notas de aula de compiladores I José Carlos Bins Filho Página 5

6 Já que o analisador léxico é a única parte do compilador que lê todo o programa ele é muitas vezes responsável por realizar tarefas acessórias como retirar caracteres brancos, comentários, etc... Embora o analisador léxico seja a parte mais simples do compilador em algumas linguagens a analise léxica pode ser bastante complexa. Exemplo: Em fortran: Do 5 I = 1,25 (Comando Do) Do 5 I = 1.25 (Atribuição da variável Do5I) Em PLI: If then then then = else; else else = then; (then e else são variáveis além de partes do comando if) Um analisador léxico nada mais é do que um classificador de lexemas em tokens. Uma expressão regular é normalmente suficiente para representar lexemas, portanto expressões regulares são usadas para esta tarefa. Exercício: Dê expressões regulares para os tokens abaixo: Números inteiros com sinal Identificadores Comentários em C ++ As expressões regulares fornecem uma forma conveniente de especificar tokens, mas elas são geradores e portanto difíceis de implementar em forma de programas. Os autômatos finitos, no entanto, tem o mesmo poder de representação mas são reconhecedores e portanto se prestam melhor à tarefa. Além disto existem algoritmos capazes de converter facilmente uma expressão regular para um autômato finito. No entanto, isto não é tão fácil, pois existem normalmente centenas de tokens numa linguagem de programação cada um com a sua expressão regular e correspondente autômato finito. Todos estes autômatos devem ser unidos para gerar um único autômato para a linguagem. Este autômato final será então implementado e esta implementação é o analisador léxico. Notas de aula de compiladores I José Carlos Bins Filho Página 6

7 Exercício: Faça o autômato e tente uni-los para os seguintes tokens: Palavra reservada IF Identificador Número inteiro Um autômato pode ser implementado de duas maneiras básicas: como um algoritmo que executa o autômato diretamente ou como um algoritmo que executa um autômato dado sob forma tabular. Exemplo de algoritmo direto: int buffer, usou-buffer; void le-caracter(char *c) { } if (usou-buffer) { usou-buffer = 0; *c = buffer; } else fgetc(fp,c); void devolve_caracter(char c) { } usou_buffer = 1; buffer = c; char automato_dir() { char c; int estado, fim, erro; estado = fim = erro = 0; while (!fim) { switch (estado) { case 0: le_caracter(&c); if (c >= 0 && c <= 9 ) estado = 0; else if (c == + c == - ) estado = 1; Notas de aula de compiladores I José Carlos Bins Filho Página 7

8 } } case 1: case 2: else { devolve_caracter; fim = erro = 1; }; break; le_caracter(&c); if (c >= 0 && c <= 9 ) estado = 2; else { devolve_caracter; fim = erro = 1; }; break; le_caracter(&c); if (c == EOF) fim = 1; else if (c >= 0 && c <= 9 ) estado = 2; else { devolve_caracter; fim = erro = 1; }; break; main() { } automato_dir(); if (erro == 0) printf( sentença aceita\n ); else printf( sentença rejeitada\n ); Exercicio: Mostre o autômato correspondente ao algoritmo acima. Exemplo de um autômato tabular; Estado Col Simb Notas de aula de compiladores I José Carlos Bins Filho Página 8

9 int buffer, usou-buffer; void le-caracter(char *c) { } if (usou-buffer) { usou-buffer = 0; *c = buffer; } else fgetc(fp,c); void devolve_caracter(char c) { } usou_buffer = 1; buffer = c; int coluna(char c) { } if (isdigit((int)c)) return (int)c; else if (c == + ) return 10; else if (c == - ) return 11; else return 1; char automato_tab(int tab[3][12]) { char c; int estado, fim, erro; estado = fim = erro = 0; while (!fim) { le_caracter(&c); if (c == EOF) fim = 1; Notas de aula de compiladores I José Carlos Bins Filho Página 9

10 } else if (tab[estado][coluna(c)]!= -1) estado = tab[estado][coluna(c)]; else { devolve_caracter; fim = erro = 1; }; main() { int tab[3][12]; } cria_tabela(tab); automato_tab(tab); if (erro == 0) printf( sentença aceita\n ); else printf( sentença rejeitada\n ); Obs: para passar de um autômato para um analisador léxico, é necessário devolver o token cada vez que se chega a um estado final o que pode acontecer antes de se chegar ao fim da entrada. Portanto a tabela tem que ter alguma maneira de identificar um estado final, o que não foi feito acima. 3.1 Lex Gerador de analisadores léxicos. Recebe como entrada expressões regulares, regras de execução e codigo em C e gera um analisador léxico através da implementação de um autômato tabular. Existem várias implementações free do Lex, nas máquinas unix da informática usa-se o Flex. Veja manual do Lex no meu website. Resumo do Lex: Formato do código fonte: Identificador das Expressões regulares seguidos das próprias e/ou código em C começando na coluna 2 ou maior Separador (%%) Identificadores de expressões ou expressões e regras de execução Separador (%%) Notas de aula de compiladores I José Carlos Bins Filho Página 10

11 Código auxiliar em C. A função yywrapp deve ser declarada mesmo que vazia. Exemplo de um código fonte para o Lex: (calculadora simples) delim [ \t\n] espaco {delim}+ digito [0-9] inteiro {digito}+ endc fim %% {espaco} { /* faz nada */ } {inteiro} { yylval = atoi(yytext); return INT;} "+" { return MAIS;} "-" { return MENOS;} "*" { return VEZES;} "/" { return DIV;} "=" { return IGUAL;} {endc} { return END;}. { printf("erro lexico : %s\n",yytext);} %% int yywrap() {} As expressões regulares usam basicamente as mesmas convenções usadas anteriormente (, *,+,? ) mais: [] : seqüência de alternativas; ex: (a b c) = [abc]. : qualquer caracter : caracter branco \ : caracter especial, como em c. ex: \t = tabulação {} : delimitador de identificador de expressão. O conjunto de símbolos entre chaves é considerado um identificador de expressão e tem que ter sido declarado anteriormente. As regras de execução são compostas por qualquer código em C. Normalmente este código salva o nomes (identificadores) e valores das variáveis/constantes, e retorna o token correspondente ao lexema. Outros exemplo de código para o Lex: (Calculadora) delim espaco [ \t\n] {delim}+ Notas de aula de compiladores I José Carlos Bins Filho Página 11

12 binario B(0 1)+ digito [0-9] inteiro {digito}+ exp E{digito}{digito}? real ({digito}*\.{digito}+ {digito}+\.{digito}*){exp}? endc fim %% {espaco} { /* faz nada */ } {binario} { yylval.vb = chartobin(yytext); return BIN;} {inteiro} { yylval.vi = atoi(yytext); return INT;} {real} { yylval.vr = atof(yytext); return REAL;} "+" { return MAIS;} "-" { return MENOS;} "*" { return VEZES;} "/" { return DIV;} "=" { return IGUAL;} "." { return AND;} {endc} { return END;}. { printf("erro lexico : %s\n",yytext);} %% int yywrap() {} (Contador de linhas e caracteres) int num_lines = 0, num_chars = 0; %% \n ++num_lines; ++num_chars;. ++num_chars; %% main() { yylex(); printf( "# of lines = %d, # of chars = %d\n", num_lines, num_chars ); } int yywrap() {} (Analisador léxico para expressões aritméticas e comando if; código completo (não usa yacc)) delim [ \t\n] ws {delim}+ letra [A-Za-z] digito [0-9] id {letra}({letra} {digito})* Notas de aula de compiladores I José Carlos Bins Filho Página 12

13 numero {digito}+(\.{digito}+)?(e[+\-]?{digito}+)? %% {ws} { /* faz nada */ } if { printf("if found \n");} then { printf("then found \n");} else { printf("else found \n");} "<" { printf("relop found \n"); } "<=" { printf("relop found \n"); } "=" { printf("relop found \n"); } "<>" { printf("relop found \n"); } ">" { printf("relop found \n"); } ">=" { printf("relop found \n"); } {id} { printf("id found \n"); } {numero} { printf("numero found \n");} %% main() { yylex(); printf( "done it!!\n"); } int yywrap() {} Compilação do Lex: Geração do programa em C: flex -oexemplo.c exemplo.lex Compilação do programa C (sem Yacc): gcc exemplo.c o exemplo Caso o Yacc seja usado o melhor é dar um include do exemplo.c no código do Yacc 4. Tabela de símbolos e Análise sintática Tabela de símbolos A tabela de símbolos é uma estrutura gerada por varias fases do compilador para armazenar informações sobre variáveis, constantes, funções e procedimentos de um código fonte. A tabela de símbolos guarda atributos dos objetos armazenados nela. Alguns atributos importantes são: Identificador Tipo Escopo Limite (vetores) Número e tipo de parâmetros (funções) Notas de aula de compiladores I José Carlos Bins Filho Página 13

14 Ou ainda: Linha de declaração Erro na declaração (declaração duplicada, etc...) A tabela de símbolos pode começar a ser construída na análise léxica com a inclusão de um identificador na tabela de símbolos, mas os atributos só serão conhecidos na análise sintática e semântica. Por isto é comum só incluir o identificador na tabela quando a sua declaração for identificada na análise sintática. Durante a compilação, cada vez que um token identificador é reconhecido a tabela de símbolos é acessada para ver se o mesmo já foi declarado, e se necessário recuperar alguns dos seus atributos. Tipicamente existem 5 tipos de procedimentos que são usados para acesso a uma tabela de símbolos: Inclusão de um identificador na tabela de simbolos Exclusão de um identificador da tabela de símbolos (geralmente uma variável temporária) Inclusão de um ou mais atributos para um identificador Recuperação de um ou mais atributos para um identificador Alteração de um atributo para um identificador As tabelas de símbolos são normalmente construídas por listas lineares, árvores binárias ou tabelas de hash. Normalmente as suas entradas não são homogêneas uma vez que os objetos podem ter atributos diferentes. Ex: uma função tem parâmetros enquanto variáveis não o tem. Ex1: Dado o programa em C abaixo, idealize uma tabela de símbolos e a preencha. #include <stdlib.h> #include <math.h> #include <stdio.h> //***** calculate the confidence for the binomial test for 3 values //***** max number of successes, number of sucesses, total number (sucesses+failures) pag 380 main(int argc, char **argv) { double x,y,n,v, v1,v2,v3; x = atof(argv[1]); y = atof(argv[2]); n = atof(argv[3]); Notas de aula de compiladores I José Carlos Bins Filho Página 14

15 v1 = (x/n - y/n); v2 = (x+y)/(n+n); v3 = (1- v2); v = v1 / sqrt(v2*v3*(n+n)/(n*n)); printf("%f \n",v); } Ex2: Programe 2 funções para acessar a tabela que você criou: int inclui_id(char * id, int tipo): função que recebe um identificador e o correspondente tipo (você define os valores usados para cada tipo, mas deixe o valor 0 livre), inclui o identificador e o tipo na tabela e retorna 1 se tudo correu bem ou 0 se houve algum erro. int tipo_id(char * id): função que recebe um identificador e devolve o correspondente tipo ou 0 se houve algum erro. Notas de aula de compiladores I José Carlos Bins Filho Página 15

16 5. Análise sintática Agrupa itens léxicos nas diversas unidades sintáticas, construindo a árvore sintática. Para isto ele utiliza uma série de regras de sintaxe (ou produções) que constituem a gramática da linguagem fonte. Contexto Análise Léxica Análise Sintática Análise Semântica Tabela de Símbolos As linguagens de programação possuem construções que não podem ser representadas por gramáticas regulares, por isto utilizam-se gramáticas livres de contexto. De fato, algumas construções não podem ser representadas nem por gramáticas livres de contexto, mas estas construções são poucas e o problema é facilmente solucionado modificando-se a linguagem. Erros Um analisador sintático faz o reconhecimento de sentenças da linguagem, mas caso haja erros (sentença não reconhecida) o analisador deve reportar o erro e se possível recuperar o seu estado e continuar o reconhecimento. Esta recuperação de estado pode ser bastante difícil, por isto em protótipos de compiladores geralmente não é implementado. Tipos de analisadores sintáticos (parsers) O analisador sintático utiliza substituições para reconhecer uma sentença. Isto pode ser feito de duas maneiras diferentes: Top-down: à partir do símbolo inicial da gramática e por derivações sucessivas chega-se à sentença a ser reconhecida. Bottom-up: à partir da sentença a ser reconhecida e por substituições reduções sucessivas chega-se ao símbolo inicial. Este método é o mais usado. Notas de aula de compiladores I José Carlos Bins Filho Página 16

17 Ex: S A B C W = abc A a B bc C c Top-down Bottom-up Entrada Derivação Entrada Pilha abc$ S abc$ $ abc$ AB bc$ a bc$ ab bc$ A $ abc c$ Ab $ Abc $ AB $ S 5.1 Análise sintática top-down (descendente) Criação da árvore gramatical a partir do símbolo inicial Pode ser vista como uma tentativa de achar a derivação mais à esquerda para uma sentença de entrada È chamada de LL(K), onde: L: Left-to-right scan L: Leftmost derivation K: número de lookaheads Problema da fatoração: Existem gramáticas que possuem mais de uma produção para um não-terminal começando pelo mesmo conjunto de símbolos. Isto é chamado de uma gramática não fatorada. Este tipo de gramática é problemático para parsers descendentes porque não é possível definir à priori qual das produções deve ser usada. Uma solução para o problema é o backtracking, ou seja se for constatado um erro na derivação então a ultima derivação é desfeita e uma nova produção é escolhida. Este processo funciona e o parser é chamado de parser descendente recursivo com backtracking. No entanto esta técnica pode ser muito custosa para gramáticas extensas. A melhor solução é fatorar a gramática antes de gerar o parser descendente. Notas de aula de compiladores I José Carlos Bins Filho Página 17

18 Ex: Gramática não fatorada S aac A ab a Sentença: W = aad Derivação: S aac aabc (erro) aac (backtracking) Fatoração: Dada as produções A αβ 1 αβ 2 αβ 3... αβ n γ 1 γ 2 γ 3... γ m onde α, β 1, β 2, β 3,..., β n, γ 1, γ 2, γ 3,..., γ m (N T)*, estas produções podem ser fatoradas à esquerda criando-se as produções: A αb γ 1 γ 2 γ 3... γ m B β 1 β 2 β 3... β n Ex: Fatore as gramáticas abaixo: a) S S (S) (S > S) p q b) E id id O id C O + * - \ C N N.N N Parsers descendentes preditivos Parsers LL que não utilizam backtracking são chamados de descendentes preditivos. Existem dois tipos: recursivo e não-recursivo (ou tabular). Para que um parser seja preditivo é necessário que a gramática esteja fatorada à esquerda. O parser preditivo está baseado nos primeiros terminais que podem ser gerados numa derivação. Este conjunto de terminais é chamado de conjunto First. Notas de aula de compiladores I José Carlos Bins Filho Página 18

19 Definição do First: Dadas as produçôes A Bα 1 Cα 2 Dα 3... Zα n aβ 1 bβ 2 cβ 3... zβ m onde α 1, α 2, α 3,..., α n, β 1, β 2, β 3,..., β m (N T)*, A, B, C,..., Z N e a, b, c,..., z T, então First(A) = First(Bα 1 ) + First(Cα 2 ) + First(Dα 3 ) +..., First(Zα n ) + a + b + c z. Para gramáticas fatoradas First(Bα 1 ) First(Cα 2 ) First(Dα 3 )..., First(Zα n ) a b c... z Algoritmo de First Entrada: α = Xβ (N T)* Saida : First(α) Se X é terminal então First(α) = {X} Se X não é terminal e existe produção X ε (ε = vazio) então inclui ε e First(β) em First(α) Se X não é terminal e existe produção X γ (γ (N T)) então inclui First(γ) em First(α) Se X não é terminal e existe produção X γ δ (γ N e δ (N T)*) e * γ ε então inclui First(δ) em First(α) Ex: Ache o first para os não-terminais das gramáticas abaixo. Quais gramáticas não estão fatoradas? a) DECL LISTA.ID : TIPO LISTA-ID id LISTA-ID, id TIPO SIMPLES AGREGADO SIMPLES int real AGREGADO nat DIMENSÃO SIMPLES conj SIMPLES DIMENSAO...(id,id) c) A Ac Aad bd ε d) A Ab Abe Abed a e e) E E+E E*E (E) -E id Notas de aula de compiladores I José Carlos Bins Filho Página 19

20 f) B b L e L C R C i - E C ε R L R ε E T Z T F S Z + T R Z ε S * F S S ε F n F i F ( E ) Recursão à esquerda Parsers descendentes não funcionam se a gramática da linguagem é recursiva à esquerda. Uma gramática é recursiva à esquerda se existe um não-terminal A para o qual A + Aα. Existem dois casos possíveis de recursão à esquerda. A recursão direta onde existe uma produção do tipo A Aα e o caso mais complexo onde a recursão não é direta mas ocorre entre varias produções. Eliminando a recursão direta à esquerda: Dada as produções A Aα 1 Aα 2 Aα 3... Aα n β 1 β 2 β 3... β m onde α 1, α 2, α 3,..., α n (N T)*, e β 1, β 2, β 3,..., β m (N T)* e não começam por A, estas produções podem substituidas por : A β 1 B β 2 B β 3 B... β m B B α 1 B α 2 B α 3 B... α n B ε Notas de aula de compiladores I José Carlos Bins Filho Página 20

21 Eliminando a recursão indireta à esquerda: Para eliminar todas as recursões à esquerda (diretas e indiretas) deve-se executar o algoritmo abaixo. Para o algoritmo ser garantido de + funcionar a gramática não pode ter ciclos (A A) e nem produções vazias. Entrada: Gramática G sem ciclos ou produções vazias. Saida : Gramática equivalente sem recursão à esquerda mas com possíveis produções vazias. Ordene os não-terminais da gramática (A 1, A 2, A 3,..., A n ) Para i = 1 à n Para j = 1 to i-1 Troque cada produção da forma A i A j α pela produção A i β 1 α β 2 α β 3 α... β m α onde A j β 1 β 2 β 3... β m Elimine a recursão à esquerda imediata gerada Ex: S Aa b A Ac Sd ε Ordenar os não-terminais: S, A Para S (i=1, j=0) não faz nada Para A (i=2, j=1) existe A Sd então substitui S pelas produções de S: A Ac Aad bd ε Eliminando a recursão imediata: A bdb B B cb adb ε A gramática final é: S Aa b A bdb B B cb adb ε Notas de aula de compiladores I José Carlos Bins Filho Página 21

22 Exercicio: Elimine a recursão das gramáticas: a) S ( L ) a L L,S S b) S AS b A SA a Parser descendente preditivo recursivo (LL) É um parser descendente preditivo que usa informações dadas pelos conjuntos First dos não-terminais para prever qual produção deve ser usada. Não pode ser recursivo à esquerda. O parser descendente recursivo implementa um automato de pilha de forma implicita, nesta implementação (programa), cada não terminal corresponde a uma função. Dentro de cada função os terminais das produções são verificados e os não-terminais são chamados como funções. Ex: S AbC A ab C c First(S) = {a} Fisrt(A) = {a} First(C) = {c} Assuma: yylex retorna: TK-A para o simbolo a TK-B para o simbolo b TK-C para o simbolo c Notas de aula de compiladores I José Carlos Bins Filho Página 22

23 Parser: int token; error() { printf( sentença não pertence a linguagem ); } verifica( int tok) { if (token == tok) { token = yylex(); } else error(); } C() { if (token == TK_C) { verifica(tk_c); } else error(); } A() { if (token == TK_A) { verifica(tk_a); verifica(tk_b); } else error(); } S() { if (token == TK_A) { A(); verifica(tk_a); C(); } else error(); } Main() { token = yylex(); S(); } Notas de aula de compiladores I José Carlos Bins Filho Página 23

24 Exercícios: Faça parsers descendente preditivos recursivos para as linguagens representadas pelas gramáticas abaixo. a) S A B A as B b b) S Ab C A a ε C d Parser descendente preditivo não-recursivo As informações do First podem ser usadas tambem para criar um parser preditivo não-recursivo, mas neste caso necessita-se de um outr conjunto de simbolos chamado de Follow. O conjunto Follow identifica todos os tokens que podem aparecer após um não-terminal. Ex: Na gramática abaixo, e derivando a partir do símbolo inicial, quais simbolos podem seguir o A? S ABC C A B a ε B b d ε C e S ABC AbC S ABC AdC S ABC AC Ae Q b segue A Q d segue A Q e segue A Portanto o Follow(A) = {b,d,e} Notas de aula de compiladores I José Carlos Bins Filho Página 24

25 Algoritmo do Follow: Entrada: X N Saida : Follow(N) Se X é o símbolo inicial então incluir $ no Follow(X) Para a produção A αxβ, onde α e β (N T)*, incluir First(β) no Follow(X) Para produções A αx e A αxβ, onde α (N T), β N* e β * ε, incluir Follow(A) no Foloow(X) Exercicio: Calcule o Follow dos não-terminais das gramáticas abaixo. a) S A S B C A B a ε B b d ε C cbac ε b) P D BL D T id ; D ε BL { ST } ST id = EXP ; ST ε EXP const id T int char long c) BLOCO begin LCMD end LCMD CMD RE RE ; LCMD ε CMD id := E ε E T R T F S R + T R ε F num id ( E ) S * F S ε Notas de aula de compiladores I José Carlos Bins Filho Página 25

26 Modêlo do Parser preditivo não recursivo a + b $ Parser Preditivo Não-recursivo Saida Tabela do Parser Algoritmo do Parser preditivo não recursivo: Ent: Uma sentença w e a tabela do parser M Sai: Se w L(G) resulta em erro Inicialização: Inserir $ no fim de w ficando a entrada w$ Colocar $S, onde S é o símbolo inicial, na pilha Fazer ip, apontador de entrada, apontar para o primeiro símbolo da entrada Repita X topo a símbolo apontado por ip Se X (T {$}) Se X = a Retira X da pilha Avança ip senão erro() senão Se M[X,a] = X Y 1, Y 2,..., Y n Retira X da pilha Coloca a produção na pilha em ordem invertida (Y 1 no topo) senão erro() até que X = $ Notas de aula de compiladores I José Carlos Bins Filho Página 26

27 Algoritmo para criar a tabela do Parser: Ent: Gramática Sai: Tabela do parser (M) Para cada produção A α da gramática Para cada terminal a ε First(α) Inclua A α em M[A, a] Se ε First(α) Para cada terminal b Follow(A) Inclua A α em M[A, b] Se $ Follow(A) Inclua A α em M[A, $] Exemplo: Tabela: E TE E +TE ε T FT T *FT ε F (E) id id + * ( ) $ E E TE E TE E E +TE E ε E ε T T FT T FT T T ε T *FT T ε T ε F F id F (E) Como as vezes fica dificil escrever as produções dentro da tabela, é comum numerar as produções e usar estes números na tabela. 1. E TE 2. E +TE 3. E ε Notas de aula de compiladores I José Carlos Bins Filho Página 27

28 Tabela: 4. T FT 5. T *FT 6. T ε 7. F (E) 8. F id id + * ( ) $ E 1 1 E T 4 4 T F 8 7 Exercício: S i E t S S a S e S ε E b 5.2 Análise sintática Bottom-up (Ascendente) Analisadores (parsers) acendentes são nalisadores que à partir da sentença a ser reconhecida e por substituições e reduções sucessivas chega ao símbolo inicial. (ver exemplo página 17) Este tipo de parser é o mais comum pela abrangência de gramáticas que pode analisar. Antes de vermos as tecnicas bottom-up mais eficientes vamos ver uma técnica bastante simples que se aplica apenas a um número muito pequeno, mas muito importante, de gramáticas, que é o parser para gramática de operadores ou parser de precedência de operadores Parser de precedência de operadores. Uma gramática é dita uma gramática de operadores se não existe produção que leva a vazio e nenhuma produção tem dois não-terminais consecutivos. A gramática abaixo não é uma gramática de operadores. Notas de aula de compiladores I José Carlos Bins Filho Página 28

29 E E O E ( E ) -E id O + - * / Mas a gramática equivalente abaixo é uma gramática de operadores. E E + E E - E E * E E / E E E ( E ) -E id Par criar o parser de precedência de operadores são definidas 3 relações entre pares de terminais. Símbolo Relação Significado < a < b a dá a precedência à b = a = b a tem a mesma precedência que b > a > b a tem precedência sobre b Algoritmo do parser de precedência de operadores. Ent: Uma sentença w e a tabela de precedência de operadores M Sai: Se w L(G) resulta em erro Inicialização: Inserir $ no fim de w ficando a entrada w$ Colocar $ na pilha Fazer ip, apontador de entrada, apontar para o primeiro símbolo da entrada Repita a topo b símbolo apontado por ip Se a = b = $ Sair do repita Se a < b ou a = b Colocar b na pilha Avança ip senão Se a > b Repita Retirar o topo da pilha Até que o terminal no topo da pilha tenha a relação < com o ultimo terminal retirado da pilha senão erro() Notas de aula de compiladores I José Carlos Bins Filho Página 29

30 Exercício: Suponha que se deseja analisar a expressão id + id * id e é dada a tabela de precedência abaixo. id + * $ id > > > + < > < > * < > > > $ < < < Regras para a criação da tabela de precedência: 1. Se operador α tem maior precedência que operador β, faça α > β e β < α. 2. Se α e β tem igual precedência ou são o mesmo operador, faça: α > β e β > α se α e β são associativos à esquerda α < β e β < α se α e β são associativos à direita 3. Para todo operador α, faça: α < id e id > α α < ( e ( < α α > ) e ) > α α > $ e $ < α 4. Faça: ( = ) ( < ( ( < id id > ) id > $ $ < id $ < ( ) > $ ) > ) Notas de aula de compiladores I José Carlos Bins Filho Página 30

31 5.2.2 Parser SLR Parser LR são parsers ascendentes que podem ser usados para analisar um grande número de linguagens livres de contexto. O nome LR vem de : L: análise da esquerda para direita (Left to right) R: Construção de uma árvore de derivação mais a direita (Right) Existem 3 principáis técnicas de parser LR: SLR: Simple LR: Método mais simples mas que representa uma classe pequena de linguagens LR LR (CLR): LR canônico: Método mais complexo que representa uma classe maior de linguagens mas usualmente gera um número muito grande de estados. LALR: Look Ahead LR: Método que agrupa algums dos estados do CLR representando portanto a mesma classe do CLR mas diminuindo o número de estados gerados. Os diversos parsers LR diferem na maneira como a tabela do parser é montada. Uma vez montada a tabela a análise das sentenças é igual para todos eles. Modêlo do Parser LR a + b $ Parser LR Saida Tabela do Parser Duas operacões básicas: Shift: A operação de shift reconhece que o símbolo lido faz parte da produção e avança para o próximo símbolo. Notas de aula de compiladores I José Carlos Bins Filho Página 31

32 Reduce: A operação de reduce identifica que o lado direito todo de uma produção foi reconhecido e portanto elimina os símbolos deste lado direito. Em ambas as operações deve-se identificar para qual estado o parser vai. No shift isto é feito pelo valor associado ao shift: (S5) significa shift e vai para estado 5 No reduce isto é feito pela operação de goto. O número associado ao reduce é o número da produção reduzida: (R4) significa reduz a produção 4. Abaixo é dado o algoritmo do parser LR. Algoritmo de execução do parser LR: Ent: Uma sentença w e a tabela do parser M (ações e gotos) Sai: Se w L(G) resulta em erro Inicialização: Inserir $ no fim de w ficando a entrada w$ Colocar 0 (estado inicial) na pilha Fazer ip, apontador de entrada, apontar para o primeiro símbolo da entrada Repita S estado no topo a símbolo apontado por ip Se ação[s,a] = shift S Empilha a Empilha S Avança ip senão Se ação[s,a] = reduce A β Desempilha 2 * β símbolos, onde β é o número de simbolos S estado no topo Empilha A Empilha goto[s,a] senão Se ação[s,a] = accept Retorna senão Notas de aula de compiladores I José Carlos Bins Filho Página 32

33 erro() Exemplo: Gramática: 1 E E + T 2 E T 3 T T * F 4 T F 5 F ( E ) 6 F id Tabela: Ação Goto Estado id + * ( ) $ E T F 0 S5 S S6 ACC 2 R2 S7 R2 R2 3 R4 R4 R4 R4 4 S5 S R6 R6 R6 R6 6 S5 S S5 S S6 S11 9 R1 S7 R1 R1 10 R3 R3 R3 R3 11 R5 R5 R5 R5 Sentença a ser análisada: (id + id) * id Análise: Notas de aula de compiladores I José Carlos Bins Filho Página 33

34 Passo S a Ação[S,a] S A β Goto[S,A] Pilha resultante (base topo) ( Shift ( id Shift ( 4 id Reduce 6 4 F id 3 0 ( 4 F Reduce 4 4 T F 2 0 ( 4 T Reduce 2 4 E T 8 0 ( 4 E Shift ( 4 E id Shift ( 4 E id ) Reduce 6 6 F id 3 0 ( 4 E F ) Reduce 4 4 T F 9 0 ( 4 E T ) Reduce 1 4 E E + T 8 0 ( 4 E ) Shift ( 4 E 8 ) * Reduce 5 0 F ( E ) 3 0 F * Reduce 4 0 T F 2 0 T * Shift T 2 * id Shift T 2 * 7 id $ Reduce 6 7 F id 10 0 T 2 * 7 F $ Reduce 3 0 T T * F 2 0 T $ Reduce 2 0 E T 1 0 E $ Accept Para criar a tabela do parser SLR é preciso primeiro calcular os conjuntos de itens SLR. Conjuntos de itens SLR.: Cada conjunto distinto será um estado do parser. Nestes conjuntos utiliza-se um ponto para indicar quais símbolos já foram análisados. Os conjuntos são criados usando-se duas operaçãoes: Goto(E, S) : esta operação calcula como ficarão as produções do estado E caso o simbolo S seja reconhecido. Closure(N) : esta operação calcula quais produções podem ser alcançadas partindo do simbolo N (Não terminal). Notas de aula de compiladores I José Carlos Bins Filho Página 34

35 Goto(E,S) 1 : Dado um conjunto de itens I e um símbolo X, o conjunto goto(i,x) é o conjunto de todos os itens A α X β onde A α X β I. Ou seja, o conjuntos de todos os itens de I que tinham um ponto antes de X com este ponto passado para depois de X. Ex: Dado o conjunto I 0 abaixo o goto(i 0, E) é dado pelo conjunto I 1. I 0 : S E I 1 : Goto(I 0,E) E E + T S E E T E E + T T T * F T F F ( E ) F id No conjunto I 1 os itens (produções) que tem um ponto antes do E, são repassadas movendo-se o ponto para depois do E. Closure (I): A closure de I (fechamento de I) é o conjunto de itens construidos a partir do conjunto I segundo as regras abaixo: 1. item I item closure(i) 2. Se A α X β closure(i) e X γ é produção, então inclui X γ na closure(i). Ex: Dada a gramática abaixo e o conjunto I 0 abaixo a closure(i 0 ) é dado pelo conjunto I 1. Gramática: E E + T E T T T * F T F 1 O livro texto usado, define goto de uma maneira um pouco diferente, misturando a operação de goto com a operação de closure, nós preferimos separar as duas. Notas de aula de compiladores I José Carlos Bins Filho Página 35

36 F ( E ) F id I 0 : I 1 : closure(i 0 ) E E + T E E + T T T * F T F F ( E ) F id Algoritmopara criar os conjuntos de itens SLR. Ent: Gramática G Saida: Conjuntos de itens SLR. Aumente a gramática G gerando G pela inclusão de uma produção S S, onde S é o simbolo inicial de G. O conjunto inicial I 0 é closure({ S.S}). Para cada conjunto de itens I n e cada símbolo com ponto na frente X, crie um novo cojunto I m que será a closure(goto(i n, X)), caso este conjunto já não exista. Ex: um exemplo completo de geração dos itens SLR de uma gramática é dado abaixo. Gramática: E E + T E T T T * F T F F ( E ) F id Notas de aula de compiladores I José Carlos Bins Filho Página 36

37 Gramática aumentada e numerada: 0 S E 1 E E + T 2 E T 3 T T * F 4 T F 5 F ( E ) 6 F id Conjunto de conjuntos de itens SLR para a gramática. I 0 : S E E E + T E T T T * F T F F ( E ) F id I 5 : F ( E ) F id Goto(I 0, id) F id I 1 : I 2 : I 3 : Goto(I 0,E) S E E E + T Goto(I 0,T) E T T T * F Goto(I 0,F) T F I 4 : Goto(I 0, ( ) F ( E ) E E + T E T T T * F T F I 6 : Goto(I 1, +) E E + T T T * F T F F ( E ) F id I 7 : Goto(I 2, *) T T * F F ( E ) F id I 8 : Goto(I 4, E) F ( E ) E E + T I 2 : Goto(I 4, T) E T Notas de aula de compiladores I José Carlos Bins Filho Página 37

38 T T * F F id I 3 : Goto(I 4,F) T F I 10 : Goto(I 7, F) T T * F I 4 : Goto(I 4, ( ) F ( E ) E E + T E T T T * F T F F ( E ) F id I 4 : Goto(I 7, ( ) F ( E ) E E + T E T T T * F T F F ( E ) F id I 5 : Goto(I 4, id) F id I 5 : Goto(I 7, id) F id I 9 : Goto(I 6, T) E E + T T T * F I 3 : Goto(I 6, F) T F I 4 : Goto(I 6, ( ) F ( E ) E E + T E T T T * F T F F ( E ) F id I 11 : Goto(I 8, ) ) F ( E ) I 6 : Goto(I 8, +) E E + T T T * F T F F ( E ) F id I 7 : Goto(I 9, *) T T * F F ( E ) F id I 5 : Goto(I 6, id) Algoritmo para criar a tabela do Parser: Ent: Gramática e conjunto de conjuntos de itens Sai: Tabela do parser M (ações e gotos) Notas de aula de compiladores I José Carlos Bins Filho Página 38

39 Ações: Para cada conjunto de itens I n formado por um goto(i m, X), onde X T, fazer ação[i m, X] = S I n (shift I n ) Para item S S. I n, onde S é o símbolo inicial da gramática aumentada, fazer ação[i n, $] = ACC (Accept) Para item A α I n, fazer ação[i n, X] = R p (reduce da produção p = A α) para todo X Follow(A), onde isto não conflite com a regra anterior. Gotos: Para cada conjunto de itens I n formado por um goto(i m, X), onde X N, fazer goto[i m, X] = I n. Ex: Alguns exemplos de geração de celulas da tabela usando o conjunto de conjuntos de itens SLR dado no exemplo anterior. Ação[0,(] = S4: o conjunto I 4 pode ser formado a partir do goto(i 0, ( ). Ação[6,(] = S4: o conjunto I 4 também pode ser formado a partir do goto(i 6, ( ). Ação[3,+] = R4: o conjunto I 3 contem o item T F, portanto deve ser incluido um reduce da produção 4 (T F) para o estado 3 e para todos os símbolos no Follow(F) = {+,*,),$}. Goto[0,E] = 1: o conjunto I 1 pode ser formado a partir do goto(i 0, E). A tabela final fica: Ação Goto Estado id + * ( ) $ E T F 0 S5 S S6 Acc 2 R2 S7 R2 R2 3 R4 R4 R4 R4 4 S5 S R6 R6 R6 R6 6 S5 S S5 S S6 S11 9 R1 S7 R1 R1 Notas de aula de compiladores I José Carlos Bins Filho Página 39

40 10 R3 R3 R3 R3 11 R5 R5 R5 R5 Parser LR ou CLR (canonical LR). Para muitas gramáticas o parser SLR não é suficiente. Nestes casos a tabela gerada vai ter conflitos, ou seja mais de uma operação vai ser gerada para uma célula da tabela.por exemplo, uma regra manda por um shift numa célula e outra regra manda por um reduce na mesma célula (conflito shift/reduce). Isto significa que a linguagem descrita pela gramática não é uma linguagem SLR. Neste caso tem-se que usar um parser mais poderoso. O parser LR é capaz de resolver a maioria destes conflitos. A idéia é que os conflitos são gerados por problemas no calculo do Follow de alguns símbolos não terminais. O conjunto follow é gerado para um determinado símbolo não terminal, enquanto o que se deseja para montar a tabela é o conjunto de símbolos que segue o não terminal em uma determinada produção. O parser LR elimina este problema mantendo junto com os itens um conjunto de simbolos follow que depende da produção onde o símbolo foi gerado. Com isto as regras para construção do conjunto de itens e da tabela são modificadas. Um item LR é uma produção com um ponto em alguma parte do lado direito mais um conjunto de símbolos terminais associado a produção. Ex: A a B c, d/$ ponto separador produção conjunto de símbolos terminais Notas de aula de compiladores I José Carlos Bins Filho Página 40

41 Goto(E,S): Dado um conjunto de itens I e um símbolo X, o conjunto goto(i,x) é o conjunto de todos os itens A α X β, a onde A α X β, a I, e a T*. Ex: Dado o conjunto I 0 abaixo o goto(i 0, E) é dado pelo conjunto I 1. I 0 : S E, $ I 1 : Goto(I 0,E) E E + T, a/c S E, $ E T, a E E + T, a/c T T * F, a/d T F, $ F ( E ), $ F id, a/c No conjunto I 1 os itens (produções) que tem um ponto antes do E, são repassadas movendo-se o ponto para depois do E e o conjunto de símbolos associado a cada item é mantido. Closure (I): A closure de I (fechamento de I) é o conjunto de itens construidos a partir do conjunto I segundo as regras abaixo: 1. item I item closure(i) 2. Se A α X β, a closure(i) e X γ é produção, então inclui X γ, b na closure(i), onde b é o First(βa). Ou seja, o novo conjunto de símbolos associado a produção é o conjunto dos primeiros símbolos após o não terminal para o qual está se fazendo a closure, (X) seguido dos símbolos associados ao item original. Com * isto se β ε então a fará parte de b. Ex: Dada a gramática abaixo e o conjunto I 0 abaixo a closure(i 0 ) é dado pelo conjunto I 1. Gramática: S S S CC C c C Notas de aula de compiladores I José Carlos Bins Filho Página 41

42 C d I 0 : I 1 : closure(i 0 ) S S, $ S CC, $ C c C, c/d C d, c/d Algoritmopara criar os conjuntos de itens LR. Ent: Gramática G Saida: Conjuntos de itens SLR. Aumente a gramática G gerando G pela inclusão de uma produção S S, onde S é o simbolo inicial de G. O conjunto inicial I 0 é closure({ S S, $}). Para cada conjunto de itens I n e cada símbolo com ponto na frente X, crie um novo cojunto I m que será a closure(goto(i n, X)), caso este conjunto já não exista. Ex: um exemplo completo de geração dos itens LR de uma gramática é dado abaixo. Gramática: S L = R S R L * R L id R L Gramática aumentada e numerada: 0 S S 1 S L = R Notas de aula de compiladores I José Carlos Bins Filho Página 42

43 2 S R 3 L * R 4 L id 5 R L Conjunto de conjuntos de itens LR para a gramática. I 0 : S S, $ S L = R, $ S R, $ L * R, = L id, = R L, $ L * R, $ L id, $ S L = R, $ R L, $ L * R, $ L id, $ I 7 : Goto (I 4, R) L * R, =/$ I 1 : Goto (I 0, S) S S, $ I 2 : Goto (I 0, L) S L = R, $ R L, $ I 3 : Goto (I 0, R) S R, $ I 4 : Goto (I 0, *) L * R, =/$ R L, =/$ L * R, =/$ L id, =/$ I 5 : Goto (I 0, id) L id, =/$ I 6 : Goto (I 2, =) I 8 : Goto (I 4, L) R L, =/$ I 4 : Goto (I 4, *) L * R, =/$ R L, =/$ L * R, =/$ L id, =/$ I 5 : Goto (I 4, id) L id, =/$ I 9 : Goto (I 6, R) S L = R, $ I 10 : Goto (I 6, L) R L, $ I 11 : Goto (I 6, *) L * R, $ Notas de aula de compiladores I José Carlos Bins Filho Página 43

44 I 12 : R L, $ L * R, $ L id, $ Goto (I 6, id) L id, $ I 11 : Goto (I 11, *) L * R, $ R L, $ L * R, $ L id, $ I 13 : Goto (I 11, R) L * R, $ I 10 : Goto (I 11, L) R L, $ I 12 : Goto (I 11, id) L id, $ Algoritmo para criar a tabela do Parser: Ent: Gramática e conjunto de conjuntos de itens Sai: Tabela do parser M (ações e gotos) Ações: Para cada conjunto de itens I n formado por um goto(i m, X), onde X T, fazer ação[i m, X] = S I n (shift I n ) Para item S S, $ I n, onde S é o símbolo inicial da gramática aumentada, fazer ação[i n, $] = ACC (Accept) Para item A α, a I n, fazer ação[i n, X] = R p (reduce da produção p = A α) para todo X a, onde isto não conflite com a regra anterior. Gotos: Para cada conjunto de itens I n formado por um goto(i m, X), onde X N, fazer goto[i m, X] = I n. Ex: Alguns exemplos de geração de celulas da tabela usando o conjunto de conjuntos de itens LR dado no exemplo anterior. Ação[0,*] = S4: o conjunto I 4 pode ser formado a partir do goto(i 0, *). Ação[4,*] = S4: o conjunto I 4 também pode ser formado a partir do goto(i 4, *). Notas de aula de compiladores I José Carlos Bins Filho Página 44

45 Ação[8,=] = R5: o conjunto I 8 contem o item R L, portanto deve ser incluido um reduce da produção 5 (R L) para o estado 8 e para todos os símbolos no conjunto de não terminais assocuiado {=,$}. Goto[0,S] = 1: o conjunto I 1 pode ser formado a partir do goto(i 0, S). A tabela final fica: Ação Goto Estado id = * $ S L R 0 S5 S6 S ACC 2 R5 3 R2 4 S5 S R4 R4 6 S12 S R3 R3 8 R5 R5 9 R1 10 R5 11 S S12 R4 13 R3 Notas de aula de compiladores I José Carlos Bins Filho Página 45

46 Tradução digirida pela sintáxe A verificação sintática permite passar por todo o programa fonte para determinar se o mesmo está de acordo com as contruções permitidas pela gramática da linguagem. A tradução dirigida pela sintaxe (TDS) se aproveita desta verificação para executar ações e/ou gerar código ao mesmo tempo em que a análise sintática é feita. A TDS usa uma extensão das GLC para executar estas ações. Esta extensão é chamada de gramática de atributos. Ex: exp exp MAIS exp {printf("reduziu e+e\n"); exp 0.val = exp 1.val + exp 2.val;} exp MENOS exp {printf("reduziu e-e\n"); exp 0.val = exp 1.val - exp 2.val;} exp VEZES exp {printf("reduziu e*e\n"); exp 0.val = exp 1.val / exp 2.val;} exp DIV exp {printf("reduziu e/e\n"); exp 0.val = exp 1.val * exp 2.val;} INT {printf("reduziu int\n"); exp 0.val = int.val;} Atributo é qualquer informação associada a um símbolo da gramática; Nome/lexema/texto Valor Tipo Pointer para tabela de símbolos Escopo Numa gramática de atributos existem dois tipos de atributos: Herdados: quando o valor do atributo é calculado a partir de atributos oriundos dos pais e irmãos na arvore de derivação. Sintetizados: quando o valor do atributo é calculado a partir de atributos oriundos apenas dos filhos na arvore de derivação. Obs: O símbolo inicial não possui atributos herdados e os símbolos terminais não possuem atributos sintetizados. Existem dois tipos de Tradução dirigida por sintaxe: Definição dirigida por sintaxe: Neste caso a ordem de execução dos atributos é dada por um grafo de dependência que é calculado sobre Notas de aula de compiladores I José Carlos Bins Filho Página 46

47 a gramática de atributos. Portanto a ordem de calculo dos atributos normalmente não segue a ordem de execução do parser. Esquema de tradução: Neste caso a ordem de cálculo dos atributos é explicitada na gramática de atributos e não precisa ser calculada.ou seja os atributos são calculados na ordem em que aparecem na produção. S {A 1.h = 1} A 1 {A 2.h = 2} A 2 A a {print(a.h)} Definição dirigida por sintaxe: Grafos de dependência: Um grafo de dependência mostra a ordem de calculo dos atributos de uma produção e/ou conjunto de produções durante a análise de uma sentença. Ex: D T L { L.t = T.tipo} T int { T.tipo = inteiro } T real { T.tipo = real } L id, L 1 { addtipo(id.indice, L.t ); L 1.t = L.t } L id { addtipo(id.indice, L.t) } A definição dirigida por sintaxe segue ao seguinte algoritmo: Construção da arvore de derivação para a sentença Construção do grafo de dependência Travesia do grafo de dependência para calculo das ações semãnticas. Exemplo de Grafo de dependência: L E E E 1 + T E T { Printf( O resultado é %f/n, E.val);} { E.val = E 1.val + T.val} { E.val = T.val} Notas de aula de compiladores I José Carlos Bins Filho Página 47

48 T T 1 * F F id F ( E ) { T.val = T 1.val + F.val} { F.val = id.val} { F.val = E.val} Dada a gramática acima e a sentença id + id * id o gráfico de dependência fica: Exerc: 1. Façam gramaticas de atributos a) sem atributos herdados b) com atributos herdados que calculem: I. O valor em decimal de um número binário lido. II. O número de digitos lidos. III. O maior digito lido. IV. O digito mais comum. 2. Dê as árvores de derivação e os grafos de dependência para as gramáticas abaixo. I. Para a sentença int id, id, id D T L T int T real L 1 L 2, id L id { L.in = T.type} { T.type = integer} { T.type = real} { L 2.in= L 1.in; addtype (id.name, L 1.in} { addtype (id.name, L.in} Notas de aula de compiladores I José Carlos Bins Filho Página 48

49 II. Para a sentença texto sub texto texto (E 1.val) S B { B.ps = 10 S.ht = B.ht} B B 1 B 2 { B 1.ps = B.ps B 2.ps = B.ps B.ht = max (B 1.ht, B 2.ht)} B B 1 sub B 2 { B 1.ps = B.ps B 2.ps = shrink(b.ps) B.ht = disp (B 1.ht, B 2.ht)} B texto { B.ht = texto.h * B.ps} No exemplo acima e assumindo as regras abaixo calcule o valor de todos os atributos. Regras: - max(a,b): calcula o máximo entre a e b - disp(a,b): calcula a soma do a com 1/3 de b - shrink(a): divide a por 2 - texto.h é a altura do texto: se houverem letras maiusculas é 10, caso contrário é 5. Esquemas de tradução: - As ações semanticas são executadas na ordem em que aparecem na produção. - É o método mais usado porque facilita a construção de ferramentas de análise (parsers) embora dificulte a definição da gramática. Ex: Esquema de tradução que traduz oerações infixadas em pósfixadas. E T R R Op T { print(op.símbolo) } R T num { print(num.val) } Op + {Op.símbolo = '+' } Op - {Op.símbolo = '-' } Op * {Op.símbolo = '*' } Op / {Op.símbolo = '/' } Notas de aula de compiladores I José Carlos Bins Filho Página 49

50 Tipos de esquemas de tradução: S -atributo: só usam atributos sintetizados. É o mais adequado ao parser botom up. L atributo: usam atributos herdados segundo uma regra. Nem todo esquema de tradução que use atributos herdados é L-atributo. S-atributo: No esquema de tradução S-atributo a implementação é direta. Basta manter uma pilha de atributos junto com os símbolos. L-atributo: Def: Um esquema de tradução é L-atributo se para todas as produções da gramática de atributos (A X 1 X 2... X n ) cada atributo X i (1 i n) depende apenas de: 1 Dos atributos de X 1, X 2,..., X i-1 2 Dos atributos de A Ex: Decl Tipo Lista Lista Var, Lista Lista Var Tipo int Tipo real Var id Decl Tipo {Lista.tipo = Tipo.tipo} Lista Lista {Var.tipo = Lista.tipo} Var, {Lista 1.tipo = Lista.tipo} Lista 1 Lista {Var.tipo = Lista.tipo} Var Tipo int {Tipo.tipo = inteiro} Tipo real {Tipo.tipo = real} Var id {inclui(id.nome, Var.tipo);} OBS: Isto não funciona no YACC que não aceita atributos herdados No YACC existem 2 soluções: 1. Usar atributos sintetizados para criar uma lista de variáveis e incluir toda a lista de uma vez na tabela. Notas de aula de compiladores I José Carlos Bins Filho Página 50

51 2. Usar uma variável global para armazenar o tipo. Sol 1: Decl Tipo Lista {inclui_lista(lista.lnome, Tipo.tipo)} Lista Var, Lista 1 {Lista.lnome = concatena(lista 1.lnome, Var.nome) Lista Var {Lista.lnome = Var.nome} Tipo int {Tipo.tipo = inteiro} Tipo real {Tipo.tipo = real} Var id {Var.nome = id.nome} Sol 2: Decl Tipo {global_tipo = Tipo.tipo} Lista Lista Var, Lista Lista Var Tipo int {Tipo.tipo = inteiro} Tipo real {Tipo.tipo = real} Var id {inclui(id.nome, global_tipo);} Notas de aula de compiladores I José Carlos Bins Filho Página 51

V Teoria de Parsing. Termos Básicos: Parser Analisador Sintático Parsing Analise Sintática Parse Representação da analise efetuada

V Teoria de Parsing. Termos Básicos: Parser Analisador Sintático Parsing Analise Sintática Parse Representação da analise efetuada V Teoria de Parsing Termos Básicos: Parser Analisador Sintático Parsing Analise Sintática Parse Representação da analise efetuada Ascendentes: S + x (* Seq. Invertida Reducao *) dir Exemplo: Descendentes:

Leia mais

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

Compiladores. Exemplo. Caraterísticas de Gramáticas. A αβ 1 αβ 2. A αx X β 1 β 2. Lembrando... Gramáticas Livres de Contexto Compiladores Análise sintática (2) Análise Top-Down Lembrando... Gramáticas Livres de Contexto Análise sintática = parsing. Baseada em GLCs Gramática: S A B Top-Down Bottom-Up S AB cb ccbb ccbca S AB A

Leia mais

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

V Análise Sintática. V.1.1 Gramáticas Livres de Contexto Definições de GLC V Análise Sintática V.1 Fundamentos Teóricos V.1.1 G.L.C V.1.2 Teoria de Parsing V.2 Especificação Sintática de Ling. de Prog. V.3 - Implementação de PARSER s V.4 - Especificação Sintática da Linguagem

Leia mais

Análise Sintáctica. Definições: Conjuntos First() e Follow() Compiladores, Aula Nº 19 João M. P. Cardoso. Conjunto First(β)

Análise Sintáctica. Definições: Conjuntos First() e Follow() Compiladores, Aula Nº 19 João M. P. Cardoso. Conjunto First(β) Análise Sintáctica Compiladores, Aula Nº 19 João M. P. Cardoso 1 Definições: Conjuntos First() e Follow() 2 Notação T é terminal, NT é nãoterminal, S é terminal ou não-terminal, e α e β representam sequências

Leia mais

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

Compiladores Analisador Sintático. Prof. Antonio Felicio Netto Ciência da Computação Compiladores Analisador Sintático Prof. Antonio Felicio Netto antonio.felicio@anhanguera.com Ciência da Computação 1 Análise Sintática - A Análise Sintática constitui a segunda fase de um tradutor de uma

Leia mais

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

Um Compilador Simples. Definição de uma Linguagem. Estrutura de Vanguarda. Gramática Livre de Contexto. Exemplo 1 Definição de uma Linguagem Linguagem= sintaxe + semântica Especificação da sintaxe: gramática livre de contexto, BNF (Backus-Naur Form) Especificação Semântica: informal (textual), operacional, denotacional,

Leia mais

Revisão. Fases da dacompilação

Revisão. Fases da dacompilação 1 Revisão Prof. Julio Arakaki Julio Arakaki 1 Fases da dacompilação Código fonte Análise Léxica tokens e lexemas Análise Sintática Árvore Sintática Abstrata (ASA) Análise Semântica ASA decorada Geração

Leia mais

Analisadores Descendentes Tabulares; Cjs First Follow

Analisadores Descendentes Tabulares; Cjs First Follow Conteúdo da aula nalisadores Descendentes Tabulares; Cjs First Follow Marcelo Johann nalisadores Descendentes Recursivos com Retrocesso Recursivos Preditivos Conjunto FIRT e Implementação nalisador Preditivo

Leia mais

Análise Sintática Bottom-up

Análise Sintática Bottom-up MAB 471 2011.2 Análise Sintática Bottom-up http://www.dcc.ufrj.br/~fabiom/comp Recapitulando parsers top-down Constróem árvore sintática da raiz até as folhas Recursão à esquerda faz parsers entrarem em

Leia mais

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

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise sintática Parte 02 Prof. geovanegriesang@unisc.br Data Conteúdo 23/09/2013 3. Análise Sintática: 3.1 analisadores

Leia mais

Análise Bottom-Up. Compiladores. Parsing LR. Tabela Ações/Transições. Análise LR. Construindo tabelas LR

Análise Bottom-Up. Compiladores. Parsing LR. Tabela Ações/Transições. Análise LR. Construindo tabelas LR Análise Bottom-Up Compiladores Análise sintática 5) Gramáticas SLR), LR) e LALR String Entrada -> Símbolo Inicial Regras aplicadas em reverso adiar decisões mais poderoso Noção de handle, redução, uso

Leia mais

V.2 Especificação Sintática de Linguagens de Programação

V.2 Especificação Sintática de Linguagens de Programação V.2 Especificação Sintática de Linguagens de Programação Deve ser baseada: No planejamento da Linguagem / Compilador Objetivos, Filosofia, Potencialidades,... Nos critérios de projeto/avaliação Legibilidade,

Leia mais

Compiladores I Prof. Ricardo Santos (cap 3 Análise Léxica: Introdução, Revisão LFA)

Compiladores I Prof. Ricardo Santos (cap 3 Análise Léxica: Introdução, Revisão LFA) Compiladores I Prof. Ricardo Santos (cap 3 Análise Léxica: Introdução, Revisão LFA) Análise Léxica A primeira fase da compilação Recebe os caracteres de entrada do programa e os converte em um fluxo de

Leia mais

Analisadores Sintáticos LR

Analisadores Sintáticos LR FACULDADE ANGLO AMERICANO FOZ DO IGUAÇU Curso de Ciência da Computação 7º Periodo Disciplina: Compiladores Prof. Erinaldo Sanches Nascimento Analisadores Sintáticos LR SLR LR Canônicos LALR Analisadores

Leia mais

Análise Sintática II: Analisadores Descendentes Preditivos

Análise Sintática II: Analisadores Descendentes Preditivos Análise Sintática II: Analisadores Descendentes Preditivos Exercícios LL(1) = Left to right, Left-most derivation, 1 símbolo look-ahead 1. LL(1): definição 2. Para toda produção A -> α β Se β =>* λ, então

Leia mais

Compiladores - Análise Ascendente

Compiladores - Análise Ascendente Compiladores - Análise Ascendente Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Análise Descendente vs. Ascendente As técnicas de análise que vimos até agora (recursiva com retrocesso,

Leia mais

Compiladores - Análise Ascendente

Compiladores - Análise Ascendente Compiladores - Análise Ascendente Fabio Mascarenhas - 2013.2 http://www.dcc.ufrj.br/~fabiom/comp Análise Descendente vs. Ascendente As técnicas de análise que vimos até agora (recursiva com retrocesso,

Leia mais

Programa fonte token padrões lexema Tokens

Programa fonte token padrões lexema Tokens Análise Léxica Analisador Léxico Primeira fase de um compilador. Objetivo: ler os caracteres de entrada e produzir como saída uma seqüência de tokens que o parser vai usar para análise sintática. Programa

Leia mais

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

BNF (Backus-Naur Form) Gramática Livres de Contexto / Estruturas Recursivas Sintae => Usualmente Gramática Livre do Conteto (GLC) BNF (Backus-Naur Form) Gramática Livres de Conteto / struturas Recursivas comando => IF epressao THN epressao LS epressao epressao => (epressao) OR

Leia mais

Análise sintática. Questão. E se a análise sintática pudesse ser modelada por autômatos?

Análise sintática. Questão. E se a análise sintática pudesse ser modelada por autômatos? Análise sintática Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo

Leia mais

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

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COPILADORES Análise sintática Parte 03 Prof. geovanegriesang@unisc.br Analisador sem recursão Analisador sintático sem recursão pode

Leia mais

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

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 Análise sintática Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo

Leia mais

Compiladores - Análise SLR

Compiladores - Análise SLR Compiladores - Análise SLR Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Um exemplo que funciona Todo estado com um item de redução e algum outro item causa conflito LR(0)! A técnica LR(0)

Leia mais

Compiladores. Lex e Yacc / Flex e Bison. Ferramentas Flex/Bison

Compiladores. Lex e Yacc / Flex e Bison. Ferramentas Flex/Bison Ferramentas Flex/Bison Prof. Sergio F. Ribeiro Lex e Yacc / Flex e Bison São ferramentas de auxílio na escrita de programas que promovem transformações sobre entradas estruturadas. São ferramentas desenvolvidas

Leia mais

Tradução Dirigida Pela Sintaxe

Tradução Dirigida Pela Sintaxe Tradução Dirigida Pela Sintaxe Julho 2006 Sugestão de leitura: Livro do Aho, Sethi, Ullman (dragão) Seções 5.1 5.5 Tradução dirigida pela sintaxe É uma técnica que permite realizar tradução (geração de

Leia mais

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

Concurso Público para provimento de cargo efetivo de Docentes. Edital 20/2015 CIÊNCIA DA COMPUTAÇÃO II Campus Rio Pomba Questão 01 No processo de construção de compiladores, é essencial compreender e manipular as expressões regulares e suas equivalências. Dentro desse contexto, seja o alfabeto = {a, b, c, d, e} e a seguinte

Leia mais

Compiladores Aula 6. Celso Olivete Júnior.

Compiladores Aula 6. Celso Olivete Júnior. Aula 6 Celso Olivete Júnior olivete@fct.unesp.br Na aula passada Analisadores Sintáticos Descendentes ASD com retrocesso ASD preditivo recursivo não-recursivo 2 ASD Preditivo Recursivo Projeto Parte 2

Leia mais

INE5317 Linguagens Formais e Compiladores. AULA 10: Anális e S intática

INE5317 Linguagens Formais e Compiladores. AULA 10: Anális e S intática INE5317 Linguagens Formais e Compiladores AULA 10: Anális e S intática baseado em material produzido pelo prof Paulo B auth Menezes e pelo prof Olinto Jos é Varela Furtado Ricardo Azambuja Silveira INE-CTC-UFSC

Leia mais

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

Construção de Compiladores Aula 3 - Analisador Sintático Construção de Compiladores Aula 3 - Analisador Sintático Bruno Müller Junior Departamento de Informática UFPR 20 de Agosto de 2014 Definição A análise sintática (parsing) é um processo que verifica se

Leia mais

Introdução à Programação

Introdução à Programação Introdução à Programação Linguagens de Programação: sintaxe e semântica de linguagens de programação e conceitos de linguagens interpretadas e compiladas Engenharia da Computação Professor: Críston Pereira

Leia mais

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

Vantagens de uma Gramática. Sintaxe de uma Linguagem. Analisador Sintático - Parser. Papel do Analisador Sintático. Tiposde Parsers para Gramáticas Sintaxe de uma Linguagem Cada LP possui regras que descrevem a estrutura sintática dos programas. specificada através de uma gramática livre de contexto, BNF (Backus-Naur Form). 1 Vantagens de uma Gramática

Leia mais

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

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 Compiladores Análise sintática ) Análise ascendente Autômatos Empilhar/Reduzir Lembrando: construir a tabela de análise LL) Como fazer? Re-escrever gramática para satisfazer condições de LL) Calcular conjuntos

Leia mais

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

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 Plano da aula Compiladores Análise sintática (1) Revisão: Gramáticas Livres de Contexto 1 Introdução: porque a análise sintática? Noções sobre Gramáticas Livres de Contexto: Definição Propriedades Derivações

Leia mais

Compiladores. Motivação. Tradutores. Motivação. Tipos de Tradutores. Tipos de Tradutores

Compiladores. Motivação. Tradutores. Motivação. Tipos de Tradutores. Tipos de Tradutores Motivação Prof. Sérgio Faustino Compiladores Conhecimento das estruturas e algoritmos usados na implementação de linguagens: noções importantes sobre uso de memória, eficiência, etc. Aplicabilidade freqüente

Leia mais

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

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

Leia mais

Lembrando análise semântica. Compiladores. Implementação de esquemas de tradução L-atribuídos. Exemplo de implementação top-down (1)

Lembrando análise semântica. Compiladores. Implementação de esquemas de tradução L-atribuídos. Exemplo de implementação top-down (1) Lembrando análise semântica Compiladores Geração de código intermediário (1) Parser Bottom-up: squema S-atribuído sem problema Apenas atributos sintetizados squema L-atribuído: ok, mas deve-se usar variáveis

Leia mais

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

Análise sintática. Prof. Thiago A. S. Pardo. Análise sintática ascendente Análise sintática Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo

Leia mais

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

INE5318 Construção de Compiladores. AULA 4: Análise Sintática INE5318 Construção de Compiladores AULA 4: Análise Sintática Ricardo Azambuja Silveira INE CTC UFSC E Mail: silveira@inf.ufsc.br URL: www.inf.ufsc.br/~silveira Definições preliminares Parser (Analisador

Leia mais

Linguagens Formais e Autômatos P. Blauth Menezes

Linguagens Formais e Autômatos P. Blauth Menezes Linguagens Formais e Autômatos P. Blauth Menezes blauth@inf.ufrgs.br Departamento de Informática Teórica Instituto de Informática / UFRGS Linguagens Formais e Autômatos - P. Blauth Menezes 1 Linguagens

Leia mais

Prof. Adriano Maranhão COMPILADORES

Prof. Adriano Maranhão COMPILADORES Prof. Adriano Maranhão COMPILADORES LINGUAGENS: INTERPRETADAS X COMPILADAS Resumo: Linguagem compilada: Se o método utilizado traduz todo o texto do programa, para só depois executar o programa, então

Leia mais

Compiladores. Análise Sintática

Compiladores. Análise Sintática Compiladores Análise Sintática Cristiano Lehrer, M.Sc. Introdução (1/3) A análise sintática constitui a segunda fase de um tradutor. Sua função é verificar se as construções usadas no programa estão gramaticalmente

Leia mais

Compiladores. Análise lexical. Plano da aula. Motivação para análise lexical. Vocabulário básico. Estrutura de um compilador

Compiladores. Análise lexical. Plano da aula. Motivação para análise lexical. Vocabulário básico. Estrutura de um compilador Estrutura de um compilador programa fonte Compiladores Análise lexical () Expressões Regulares analisador léxico analisador sintático analisador semântico análise gerador de código intermediário otimizador

Leia mais

Lex Adaptação da obra original de Tom Niemann

Lex Adaptação da obra original de Tom Niemann LEX Lex Adaptação da obra original de Tom Niemann Durante a primeira fase, o compilador lê a entrada e converte as strings na origem para os tokens. Com expressões regulares, podemos especificar padrões

Leia mais

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

Reduce: reduz o que está imediatamente à esquerda do foco usando uma produção Shift e reduce Shift: move o foco uma posição à direita A B C x y z A B C x y z é uma ação shift Reduce: reduz o que está imediatamente à esquerda do foco usando uma produção Se A x y é uma produção, então

Leia mais

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

Disciplina: LINGUAGENS FORMAIS, AUTÔMATOS E COMPUTABILIDADE Prof. Jefferson Morais UNIVERSIDADE FEDERAL DO PARÁ INSTITUTO DE CIÊNCIAS EXATAS E NATURAIS FACULDADE DE COMPUTAÇÃO CURSO DE BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO Disciplina: LINGUAGENS FORMAIS, AUTÔMATOS E COMPUTABILIDADE Prof.

Leia mais

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

Análise Sintática I. Eduardo Ferreira dos Santos. Abril, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 42 Análise Sintática I Eduardo Ferreira dos Santos Ciência da Computação Centro Universitário de Brasília UniCEUB Abril, 2017 1 / 42 Sumário 1 Introdução 2 Derivações 3 Ambiguidade 4 Análise sintática descendente

Leia mais

IV Gramáticas Livres de Contexto

IV Gramáticas Livres de Contexto IV Gramáticas Livres de Contexto Introdução Definições de GLC 1 G = (Vn, Vt, P, S) onde P = {A α A Vn α (Vn Vt) + } 2 GLC ε - LIVRE : S ε pode pertencer a P, desde que: S seja o símbolo inicial de G S

Leia mais

Linguagens de Programação Aula 5

Linguagens de Programação Aula 5 Aula 5 Celso Olivete Júnior olivete@fct.unesp.br Na aula anterior Ambiguidade Análise léxica Exercício calculadora 2/@ Na aula anterior AF calculadora 3/@ Na aula de hoje Análise léxica implementação Gramática

Leia mais

Compiladores Análise Semântica

Compiladores Análise Semântica Compiladores Análise Semântica Fabio Mascarenhas - 2013.2 http://www.dcc.ufrj.br/~fabiom/comp Árvores Sintáticas Abstratas (ASTs) A árvore de análise sintática tem muita informação redundante Separadores,

Leia mais

Análise Sintática (Cap. 04) Análise Sintática Ascendente Analisador Sintático LR

Análise Sintática (Cap. 04) Análise Sintática Ascendente Analisador Sintático LR Análise Sintática (Cap. 04) Análise Sintática Ascendente Analisador Sintático LR Análise Sintática LR Analisadores sintáticos LR(k): L, verificação da entrada da esquerda para direita R, constrói a derivação

Leia mais

Compiladores I. Caracterizar um método de análise bottom-up. Compreender os mecanismos básicos envolvidos no processo de análise LR.

Compiladores I. Caracterizar um método de análise bottom-up. Compreender os mecanismos básicos envolvidos no processo de análise LR. Compiladores I Gerson Geraldo Homrich Cavalheiro Caracterizar um método de análise bottom-up Compreender oecanismos básicos envolvidos no processo de análise LR Oferecer as bases para utilização de uma

Leia mais

FACULDADE LEÃO SAMPAIO

FACULDADE LEÃO SAMPAIO FACULDADE LEÃO SAMPAIO Paradigmas de Programação Curso de Análise e Desenvolvimento de Sistemas Turma: 309-5 Semestre - 2014.2 Paradigmas de Programação Prof. MSc. Isaac Bezerra de Oliveira. 1 PARADIGMAS

Leia mais

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

LFA Aula 09. Gramáticas e Linguagens Livres de Contexto 18/01/2016. Linguagens Formais e Autômatos. Celso Olivete Júnior. LFA Aula 09 Gramáticas e Linguagens Livres de Contexto (Hopcroft, 2002) 18/01/2016 Celso Olivete Júnior olivete@fct.unesp.br www.fct.unesp.br/docentes/dmec/olivete/lfa 1 Classes Gramaticais Linguagens

Leia mais

Tokens, Padroes e Lexemas

Tokens, Padroes e Lexemas O Papel do Analisador Lexico A analise lexica e a primeira fase de um compilador e tem por objetivo fazer a leitura do programa fonte, caracter a caracter, e traduzi-lo para uma sequencia de símbolos lexicos

Leia mais

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

Linguagens e Programação Gramáticas. Paulo Proença Linguagens e Programação Gramáticas Gramáticas Ferramenta para a descrição e análise de linguagens; Baseada num conjunto de regras que especificam o modo de construção das frases válidas na linguagem;

Leia mais

Programação: Vetores

Programação: Vetores Programação de Computadores I Aula 09 Programação: Vetores José Romildo Malaquias Departamento de Computação Universidade Federal de Ouro Preto 2011-1 1/62 Motivação Problema Faça um programa que leia

Leia mais

Linguagens de Programação Aula 4

Linguagens de Programação Aula 4 Aula 4 Celso Olivete Júnior olivete@fct.unesp.br Na aula passada... Autômatos finitos AF:exemplos... Cadeia de caracteres a,b,c 2/82 Na aula passada... Autômatos finitos AF:exemplos... Números inteiros(com

Leia mais

Análise Sintática LL(1)

Análise Sintática LL(1) FACULDADE ANGLO AMERICANO FOZ DO IGUAÇU Curso de Ciência da Computação 7º Periodo Disciplina: Compiladores Prof. Erinaldo Sanches Nascimento Análise Sintática LL(1) Análise Sintática Descendente Introdução

Leia mais

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

COMPILADORES. Revisão Linguagens formais Parte 02. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Revisão Linguagens formais Parte 02 Prof. geovanegriesang@unisc.br Legenda: = sigma (somatório) = delta ε = epsilon λ =

Leia mais

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

Parsing Preditivo. Antes de ser abordado o Parsing Preditivo, será apresentado o Analisador Sintático Descendente Recursivo. UPE Caruaru Sistemas de Informação Disciplina: Compiladores Prof.: Paulemir G. Campos Parsing Preditivo Antes de ser abordado o Parsing Preditivo, será apresentado o Analisador Sintático Descendente Recursivo.

Leia mais

Introdução Análise Sintática Descendente Análise Sintática Ascendente. Aula Prática. Fernando Antônio Asevedo Nóbrega

Introdução Análise Sintática Descendente Análise Sintática Ascendente. Aula Prática. Fernando Antônio Asevedo Nóbrega Análise Sintática Aula Prática Fernando Antônio Asevedo Nóbrega Instituto de Ciências Matemáticas e de Computação USP SCC-206 Introdução à Compilação 9 de maio de 2012 1 / 16 Agenda 1 Introdução 2 Análise

Leia mais

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

Análise sintática. Análise sintática ascendente. Bottom-up, ascendente ou redutiva. Analisadores de precedência de operadores Analisadores LR Análise sintática Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo

Leia mais

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

COMPILADORES. Análise semântica. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise semântica Tradução dirigida pela sintaxe Parte 02 Prof. geovanegriesang@unisc.br Sumário Data 18/11/2013 Análise

Leia mais

Compiladores. Análise Sintática

Compiladores. Análise Sintática 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

Leia mais

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

INE5317 Linguagens Formais e Compiladores AULA 9: Propriedades e Reconhecimento das Linguagens Livres do Contexto INE5317 Linguagens Formais e Compiladores AULA 9: Propriedades e Reconhecimento das Linguagens Livres do Contexto baseado em material produzido pelo prof Paulo Bauth Menezes e pelo prof Olinto José Varela

Leia mais

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

Construção de Compiladores Aula 16 - Análise Sintática Construção de Compiladores Aula 16 - Análise Sintática Bruno Müller Junior Departamento de Informática UFPR 25 de Setembro de 2014 1 Introdução Hierarquia de Chomsky Reconhecedores Linguagens Livres de

Leia mais

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

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 30. Instituto de C ompiladores Análise Sintática Bruno Lopes Bruno Lopes ompiladores 1 / 30 Front-end Lida com a linguagem de entrada Teste de pertinência: código fonte linguagem fonte? Programa está bem formado? Sintaticamente?

Leia mais

Como construir um compilador utilizando ferramentas Java

Como construir um compilador utilizando ferramentas Java Como construir um compilador utilizando ferramentas Java p. 1/2 Como construir um compilador utilizando ferramentas Java Aula 6 Análise Sintática Prof. Márcio Delamaro delamaro@icmc.usp.br Como construir

Leia mais

Compiladores 02 Analise léxica

Compiladores 02 Analise léxica Compiladores 02 Analise léxica Sumário Análise Léxica Definição: Lexema, tokens Tabela símbolos Expressões regulares, automatos Relembrando O compilador é dividido em duas etapas Análise Síntese Análise

Leia mais

Compiladores Aula 4. Celso Olivete Júnior.

Compiladores Aula 4. Celso Olivete Júnior. Aula 4 Celso Olivete Júnior olivete@fct.unesp.br Na aula de hoje... Revisão: gramáticas Relações em uma gramática: Cabeça, Último, Primeiro (First) e Seguinte (Follow) Capítulo 4 (seção 4.4.2) do livro

Leia mais

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

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise sintática Parte 05 Prof. geovanegriesang@unisc.br Data Conteúdo 23/09/2013 3. Análise Sintática: 3.1 analisadores

Leia mais

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

Construção de Compiladores Aula 17 - Análise Sintática Descendente Construção de Compiladores Aula 17 - Análise Sintática Descendente Bruno Müller Junior Departamento de Informática UFPR 3 de Novembro de 2014 1 Análise Sintática Descendente Eliminação de retrocessos Converter

Leia mais

Compiladores - Gramáticas

Compiladores - Gramáticas Compiladores - Gramáticas Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Análise Sintática A análise sintática agrupa os tokens em uma árvore sintática de acordo com a estrutura do programa

Leia mais

Compiladores. Parser LL 10/13/2008

Compiladores. Parser LL 10/13/2008 Compiladores Fabiano Baldo Usa uma pilha explícita ao invés de chamadas recursivas para realizar a análise sintática. LL(k) parsing significa que ktokensà frente são utilizados. O primeiro L significa

Leia mais

1 d=

1 d= O que faz/o que é Como usar / Como funciona Formato geral do Arquivo Submetido ao Lex ER estendidas / Exemplos The Lex & YACC page: http://dinosaur.compilertools.net/ Flex: versão livre http://simplesamples.info/c++/flex.php

Leia mais

Compiladores Análise Semântica

Compiladores Análise Semântica Compiladores Análise Semântica Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Árvores Sintáticas Abstratas (ASTs) A árvore de análise sintática tem muita informação redundante Separadores,

Leia mais

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. 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 Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo

Leia mais

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

Construção de Compiladores Aula 18 - Análise Sintática Ascendente Construção de Compiladores Aula 18 - Análise Sintática Ascendente Bruno Müller Junior Departamento de Informática UFPR 10 de Novembro de 2014 Bruno Müller 5 Implementação Junior Departamento de Informática

Leia mais

Compiladores - Gramáticas

Compiladores - Gramáticas Compiladores - Gramáticas Fabio Mascarenhas 2018.1 http://www.dcc.ufrj.br/~fabiom/comp Análise Sintática A análise sintática agrupa os tokens em uma árvore sintática de acordo com a estrutura do programa

Leia mais

Compiladores - Especificando Sintaxe

Compiladores - Especificando Sintaxe Compiladores - Especificando Sintaxe Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Análise Sintática A análise sintática agrupa os tokens em uma árvore sintática de acordo com a estrutura

Leia mais

Algoritmos e Programação

Algoritmos e Programação Algoritmos e Programação Aula 3 Introdução a Linguagem C Profa. Marina Gomes marinagomes@unipampa.edu.br 1 Aula de Hoje - Criar programas simples em C utilizando a estrutura básica; - Declarar variáveis;

Leia mais

Análise Sintática. Fabiano Baldo

Análise Sintática. Fabiano Baldo Compiladores Análise Sintática Fabiano Baldo Gramáticas Livre de Contexto (GLC) É utilizada na especificação formal lda sintaxe de uma linguagem de programação. É um conjunto de produções ou regras gramaticais

Leia mais

3. Linguagem de Programação C

3. Linguagem de Programação C Introdução à Computação I IBM1006 3. Linguagem de Programação C Prof. Renato Tinós Departamento de Computação e Matemática (FFCLRP/USP) 1 Principais Tópicos 3.2. Estrutura de Programas e Representação

Leia mais

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

INE5416 Paradigmas de Programação. Ricardo Azambuja Silveira INE CTC UFSC E Mail: URL: INE5416 Paradigmas de Programação Ricardo Azambuja Silveira INE CTC UFSC E Mail: silveira@inf.ufsc.br URL: www.inf.ufsc.br/~silveira Conceitos Léxica estudo dos símbolos que compõem uma linguagem Sintaxe

Leia mais

Gramáticas Livres de Contexto Parte 1

Gramáticas Livres de Contexto Parte 1 Universidade Estadual de Feira de Santana Engenharia de Computação Gramáticas Livres de Contexto Parte 1 EXA 817 Compiladores Prof. Matheus Giovanni Pires O papel do Analisador Sintático É responsável

Leia mais

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

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise sintática Parte 04 Prof. geovanegriesang@unisc.br Data Conteúdo 23/09/2013 3. Análise Sintática: 3.1 analisadores

Leia mais

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

Análise Sintática (Cap. 04) Análise Sintática Descendente (Cap. 04) Análise Sintática Descendente Análise Sintática Análise sintática descendente Constrói a árvore de derivação de cima para baixo, da raíz para as folhas, criando os nós da árvore em pré ordem

Leia mais

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

COMPILADORES. Análise semântica. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise semântica Parte 01 Prof. geovanegriesang@unisc.br Sumário Data 18/11/2013 Análise sintática Parte 01 25/11/2013

Leia mais

Conceitos de Linguagens de Programação

Conceitos de Linguagens de Programação Conceitos de Linguagens de Programação Aula 04 Sintaxe e Semântica Edirlei Soares de Lima Sintaxe e Semântica A descrição de uma linguagem de programação envolve dois aspectos principais:

Leia mais

Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES. Introdução. Geovane Griesang

Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES. Introdução. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Introdução geovanegriesang@unisc.br Processadores de linguagem Linguagens de programação são notações para se descrever

Leia mais

Programação de Computadores II

Programação de Computadores II Programação de Computadores II 1. Programação Básica 2019.1 Slides adaptados do material de Karina Mochetti Problema, Algoritmo, Programa Um programa de computador é a implementação de um algoritmo para

Leia mais

13 a Aula - Instruções Condicionais. Ciclos. Pré-processador. Variáveis de ambiente. Mestrado em Engenharia Física Tecnológica

13 a Aula - Instruções Condicionais. Ciclos. Pré-processador. Variáveis de ambiente. Mestrado em Engenharia Física Tecnológica 13 a Aula - Instruções Condicionais. Ciclos. Pré-processador. Variáveis de ambiente. Programação Mestrado em Engenharia Física Tecnológica Samuel M. Eleutério sme@tecnico.ulisboa.pt Departamento de Física

Leia mais

CP Compiladores I Prof. Msc.. Carlos de Salles

CP Compiladores I Prof. Msc.. Carlos de Salles CP 5017.9 Prof. Msc.. Carlos de Salles 1 - EMENTA O Processo de Compilação. Deteção e Recuperação de Erros. Introdução à geração de Código Intermediário. Geração de Código de Máquina. Otimização. Uma visão

Leia mais

Papel do analisador léxico: ler o arquivo fonte em busca de unidades significativas (os tokens) instanciadas por lexemas ou átomos.

Papel do analisador léxico: ler o arquivo fonte em busca de unidades significativas (os tokens) instanciadas por lexemas ou átomos. Análise Léxica Análise Léxica Papel do analisador léxico: ler o arquivo fonte em busca de unidades significativas (os tokens) instanciadas por lexemas ou átomos. Também denominado de scanner, porque varre

Leia mais

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

Análise Sintática II. Eduardo Ferreira dos Santos. Outubro, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 34 Análise Sintática II Eduardo Ferreira dos Santos Ciência da Computação Centro Universitário de Brasília UniCEUB Outubro, 2016 1 / 34 Sumário 1 Introdução 2 Ambiguidade 3 Análise sintática descendente 4

Leia mais

Compiladores I Prof. Ricardo Santos (cap 1)

Compiladores I Prof. Ricardo Santos (cap 1) Compiladores I Prof. Ricardo Santos (cap 1) Compiladores Linguagens de programação são notações que permitem descrever como programas devem executar em uma máquina Mas, antes do programa executar, deve

Leia mais

Compiladores 04 Analise léxica Jflex. Prof José Rui

Compiladores 04 Analise léxica Jflex. Prof José Rui Compiladores 04 Analise léxica Jflex Prof José Rui Sumário Análise Léxica Definição: Lexema, tokens Tabela símbolos Expressões regulares, automatos JFlex Análise léxica Exemplo Soma = a + b * 40;

Leia mais

Compiladores. Prof. Bruno Moreno Aula 8 02/05/2011

Compiladores. Prof. Bruno Moreno Aula 8 02/05/2011 Compiladores Prof. Bruno Moreno Aula 8 02/05/2011 RECONHECIMENTO DE TOKENS Reconhecimento de Tokens Até aqui aprendemos a identificar tokens Para reconhecimento, a única abordagem utilizada foi árvores

Leia mais

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

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise sintática Parte 01 Prof. geovanegriesang@unisc.br Continuação... Próxima aula 2 Análise léxica x Análise sintática

Leia mais