1 / 105

Compiladores

Bibliografia Recomendada. COMPILADORES Princ

iona
Download Presentation

Compiladores

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


    1. Compiladores Cristiano Damiani Vasconcellos damiani@joinville.udesc.br

    2. Bibliografia Recomendada

    3. Introdução (Construção de um Executável)

    4. Introdução (Fases de um Compilador)

    5. Introdução

    6. Introdução

    7. Análise Léxica O Analisador Léxico (scanner) examina o programa fonte caractere por caractere agrupando-os em conjuntos com um significado coletivo (tokens): palavras chave (if, else, while, int, etc), operadores (+, -, *, /, ^, &&, etc), constantes (1, 1.0, ‘a’, 1.0f, etc), literais (“Projeto Mono”, etc), símbolos de pontuação (; , {, }, etc), labels.

    8. Análise Léxica constanteInt ? digito digito* constanteDouble ? digito digito*. digito* digito ? {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    9. Análise Sintática Verifica se as frases obedecem as regras sintáticas da linguagem: Por exemplo, uma expressão pode ser definida como: expressão + expressão expressão – expressão (expressão) constante

    10. Gramáticas Livres de Contexto Definidas por uma quádrupla (VN, VT, S, P), onde: VN é um conjunto de símbolos não terminais (representam as construções sintáticas da linguagem). VT é um conjunto de símbolos terminais (tokens da linguagem). S ? VN é o símbolo inicial da gramática. P é um conjunto de regras de produção, pares ordenados representados na forma ? ? ?, onde ? ? VN e ? ? (VN ? VT)*.

    11. Gramáticas Livres de Contexto <expr> ? <expr> + <expr> | <expr> – <expr> | (<expr>) | <const> <const> ? <const><const> | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9

    12. Derivação Verificar se uma frase faz parte da linguagem gerada pela gramática, envolve sucessivas substituições dos símbolos que ocorrem do lado esquerdo da produção pela sua construção sintática correspondente. Essa substituição é chamada derivação sendo normalmente denotada pelo símbolo ?. E deve iniciar a partir do símbolo inicial da gramática.

    13. Derivação

    14. Árvore de Derivação

    15. Gramáticas Ambíguas

    16. Gramáticas <expr> ? <expr> + <termo> | <expr> - <termo> | <termo> <termo> ? (<expr>) | <const> <expr> <expr> + <termo> <expr> - <termo> + <termo> <termo> - <termo> + <termo> 10 – 2 + 3

    17. Gramáticas <expr> ? <expr> + <termo> | <expr> - <termo> | <termo> <termo> ? <termo> * <fator> | <termo> / <fator> | <fator> <fator> ? (<expr>) | <const>

    18. Gramáticas <expr> ? <expr> + <termo> | <expr> - <termo> | <termo> <termo> ? <termo> * <fator> | <termo> / <fator> | <fator> <fator> ? (<expr>) | <const>

    19. Tradução Dirigida pela Sintaxe

    20. Gramáticas - Exercícios Considerando a gramática apresentada anteriormente derive as expressões e apresente a árvore sintática correspondente: (1 + 2) * 3 (1 – 2) + 3 * 4 Altere a gramática para incluir o operador unário -, esse operador deve ter precedência maior que todos os outros operadores. Altere a gramática para que os operadores de adição, subtração, multiplicação e divisão tenham associatividade da direita para a esquerda. Defina uma gramática para expressões aritméticas (operadores +, -, *, /) pós fixadas.

    21. Gramáticas Dados 2 conjuntos independentes de símbolos: VT – Símbolos terminais. VN – Símbolos não terminais. Uma gramática é definida como a quádrupla: (VN, VT, S, P) Onde, S ? VN é o símbolo inicial da gramática. P é um conjunto de regras de reescrita na forma: ? ? ?, sendo: ? ? (VN ? VT)* VN (VN ? VT)* ? ? (VN ? VT)*

    22. Classificação de Gramáticas Irrestritas – nenhuma restrição é imposta Sensíveis ao Contexto - |?| ? |?| Livres de Contexto - ? ? VN ? ? (VN ? VT)+ Regulares - ? ? VN ? tem a forma a ou aB, onde a ? VT e B ? VN

    23. Gramáticas Regulares Uma gramática regular gera uma linguagem regular. C ? 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 0C | 1C | 2C | 3C | 4C | 5C | 7C | 8C | 9C

    24. Linguagens Regulares Geradas a partir de uma gramática regular; Podem ser representadas através de uma expressão regular; Podem ser reconhecidas por Autômatos Finitos. Considerando linguagens compostas por símbolos 0 e 1 podemos afirmar: a linguagem L1 ={0n1n | n ? 1} não é regular; a linguagem L2 ={0n1m | n ? 1, m ? 1} é regular;

    25. Expressões Regulares Maneira compacta de representar linguagens regulares. É composta de 3 operações. Sendo e1 e e2 expressões que geram respectivamente duas linguagens regulares L1 e L2:

    26. Expressões Regulares Exemplos: identificador ? (letra | _) (letra | digito | _)* letra ? a | b | ... | z | A | B | ... | Z digito ? 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 constInt ? digito digito* constDouble ? digito digito*.digito* | . digito digito*

    27. Autômato Finito A linguagem gerada por uma gramática regular pode ser reconhecida por um autômato finito. Um autômato finito consiste em:

    28. Autômato Finito

    29. Autômato Finito

    30. Autômato Finito Implementação

    31. Geradores de Analisadores Léxicos

    32. Análise Léxica - Exercícios Escreva uma gramática, expressão regular e AFD que defina os números binários terminados em zero. Mostre uma expressão regular e o AFD correspondente a gramática abaixo: S ? aS B ? bC C ? aC | aB | a Escreva uma expressão regular para as constantes double da linguagem C.

    33. Especificação Análise Léxica – expressões regulares. Análise Sintática – gramáticas livres de contexto. Análise Semântica – sistema de tipos (regras de inferência), semântica denotacional, semântica operacional, semântica de ações. Geração/Otimização de Código – linguagens para descrição de arquiteturas.

    34. Analisador Sintático

    35. Métodos top-down

    36. Método Descendente Recursivo

    37. Método Descendente Recursivo

    38. Analisadores Sintáticos Preditivos

    39. Fatoração a Esquerda

    40. Fatoração a Esquerda

    41. Eliminação da Recursividade a Esquerda

    42. Eliminação da Recursividade a Esquerda

    43. Análise Sintática Preditiva não Recursiva LL(1)

    44. Analisador Sintático LL(1)

    45. Analisador Sintático LL(1)

    46. Construção da Tabela LL(1)

    47. Construção da Tabela LL(1)

    48. Construção da Tabela LL(1)

    49. Construção da Tabela LL(1)

    50. Métodos bottom-up

    51. Métodos LR(k)

    52. Métodos LR

    53. Algoritmo LR(1)

    64. Tabelas SLR(1)

    65. Construção da Tabela Sintática SLR(1)

    66. Construção da Tabela Sintática SLR(1)

    67. Construção da Tabela Sintática SLR(1)

    68. Construção da Tabela Sintática SLR(1)

    69. Construção da Tabela Sintática SLR(1)

    70. Construção da Tabela Sintática SLR(1)

    71. Construção da Tabela Sintática SLR(1)

    72. Construção da Tabela Sintática SLR(1)

    73. Construção da Tabela Sintática LR(1)

    74. Construção da Tabela Sintática LR(1)

    75. LALR – lookahead LR

    76. Construção da Tabela Sintática LALR(1)

    77. Hierarquia de Gramáticas Livres de Contexto

    78. Uso de Gramáticas Ambíguas

    79. Lex delim [ \t] ws {delim}+ digito [0-9] num {digito}+(\.{digito}*(E[+-]?{digito}+)?)? %% {ws} {} "+" {return TADD;} "-" {return TSUB;} "*" {return TMUL;} "/" {return TDIV;} "(" {return TAPAR;} ")" {return TFPAR;} \n {return TFIM;} {num} {yylval=atof(yytext); return TNUM;}

    80. yacc %{ #include <stdio.h> #include <stdlib.h> #define YYSTYPE double %} %token TADD TMUL TSUB TDIV TAPAR TFPAR TNUM TFIM %%

    81. yacc Linha :Expr TFIM {printf("Resultado:%lf\n", $1);exit(0);} ; Expr: Expr TADD Termo {$$ = $1 + $3;} | Expr TSUB Termo {$$ = $1 - $3;} | Termo ; Termo: Termo TMUL Fator {$$ = $1 * $3;} | Termo TDIV Fator {$$ = $1 / $3;} | Fator ; Fator: TNUM | TAPAR Expr TFPAR {$$ = $2;} ; %%

    82. yacc int yyerror (char *str) { printf("%s - antes %s\n", str, yytext); } int yywrap() { return 1; }

    83. Programa #include <stdio.h> extern FILE *yyin; int main() { yyin = stdin; printf("Digite uma expressão:"); yyparse(); return 0; }

    84. Definição Dirigida pela Sintaxe

    85. Definição Dirigida pela Sintaxe

    86. Árvores Sintáticas E ? E1 + T {E.ptr = criarNo (‘+’, E1.ptr, T.ptr)} E ? T {E.ptr = T.ptr} T ? T1 * F {T.ptr = criarNo (‘*’, T1.ptr, F.ptr)} T ? F {T.ptr = F.ptr} F ? (E) {F.ptr = E.ptr} F ? const {F.ptr = criarFolha(const.lexval)}

    87. DAG Grafo Direcionado Acíclico Identifica as subexpressões comuns. Exemplo: DAG que representa a expressão: a * b + c + a *b.

    88. Código de 3 endereços Uma sequência de enunciados na forma: x = y op z Onde x, y e z são nomes, constantes ou dados temporários (criados pelo compilador) e op representa uma operação qualquer. Uma versão linearizada da árvore sintática, é assim chamado por cada instrução poder conter até três endereços, dois para os operandos e um para o resultado. Bastante semelhante a linguagem de montagem.

    89. Código de 3 endereços Exemplo: a = 2 * b + c t1 = 2 * b t2 = t1 + c a = t2

    90. Código de 3 endereços S ? id = E {S.cod = E.cod ++ gerar(id.lexval = E.local)} E ? E1 + T {E.local = novoTemporario(); E.cod = E1.cod ++T.cod ++ gerar(E.local = E1.local + T.local)} E ? T {E.local = T.local; E.cod = T.cod} T ? T1 * F {T.local = novoTemporario(); T.cod = T1.cod ++ F.cod ++ gerar(T.local = T1.local * F.local)} T ? F {T.local = F.local; T.cod = F.cod} F ? (E) {F.local = E.local; F.cod = E.cod} F ? id {F.local = id.lexval; F.cod =“”} F ? const {F.local = const.lexval; F.cod =“”}

    91. Código de 3 endereços Alguns enunciados comumente usados:

    92. Código de 3 endereços n = 1; f = 1; while (n < 10) { f = f * n; n = n + 1; }

    93. Código de 3 endereços n = 1; f = 1; while (n < 10) { f = f * n; n = n + 1; }

    94. Definições S-atribuídas Definições dirigidas pela sintaxe que possuem apenas atributos sintetizados.

    95. Definições L-atribuídas Uma definição dirigida pela sintaxe é L-atribuída se cada atributo herdado de Xj, 1 ? j ? n, do lado direito de uma produção, A ? X1X2...Xn depende somente:

    96. Tradução Top-Down S ? E {imprimir (E.val)} E ? T {E’.h = T.val} E’ {E.val = E’.s} E’ ? +T {E’1.h = E’.h + T.val} E1 {E’.s = E’1.s} E’ ? ? {E’.s = E’.h} T ? F {T’.h = F.val} T’ {T.val = T’.s} T’ ? * F{T’1.h = T’.h * F.val} T’ {T’.s = T1’.s} T’ ? ? {T’.s = T’.h} F ? const {F.val = const.lexval} F ?({push(T’.h); push(E’.h)} E {E’.h = pop(); T’.h = pop()})

    97. Análise Semântica D ? var S S ? id L {atribuirTipo(id.lexval, L.tipo)} S ? S id L {atribuirTipo(id.lexval, L.tipo)} L ? , id L1 {atribuirTipo(id.lexval, L.tipo); L.tipo = L1.tipo} L ? :T {L.tipo = T.tipo} T ? integer {T.tipo = integer} T ? string {T.tipo = string}

    98. Análise Semântica E ? E1 + T {if (E1.tipo = T.tipo) then E.tipo = E1.tipo else error()} E ? T {E.tipo = T.tipo} T ? T1 * F {if (T1.tipo = F.tipo) then T.tipo = T1.tipo else error()} T ? F {T.tipo = F.tipo} F ? id {F.tipo = consultaTipo(id.lexval);} F ? constInt {F.tipo = Inteiro} F ? constReal {F.tipo = Real} Obs: Em uma situação real as regras semânticas devem implementar a coerção dos tipos.

    99. Expressões Lógicas e Relacionais B ? B1 or M C {corrigir(B1.listaf, M.label); B.listav = merge(B1.listav, C.listav); B.listaf = C.listaf;} B ? B1 and M C {corrigir(B1.listav, M.label); B.listaf = merge(B1.listaf, T.listaf); B.listav = C.listav;} B ? C {B.listav = C.listav; B.listaf = C.listaf;} C ? not C1 {C.listav = C1.listaf; C.listaf = C1.listav;} C ? (B) {C.listav = B.listav; C.listaf = B.listaf;} C ? E1 rel E2 {C.listav = criaLista(proxInst); C.listf = criaLista(proxInst+1);} gerar(if E1.local rel E2.local goto _); gerar (goto _); M ? ? {M.label = novolabel()}

    100. Comandos de Seleção e Repetição S ? if (B) then M S {corrigir (B.listav, M.label); corrigir(B.listaf, novolabel();} S ? if (B) then M1 S N else M2 S {corrigir(B.listav, M1.label); corrigir(B.listf, M2.label); corrigir(N.listav, novoLabel();} S ? while M1 (B) M2 S {corrigir(B.listav, M2.label); gerar(goto M1.label); corrigir(B.listaf, novolabel();} N ? ? {N.listav = criarLista(ProxInstr); gerar(goto _);}

    101. Organização da Memória

    102. Dados Estáticos A área de memória é reservada no início da execução do programa e liberada apenas no fim de sua execução (e.g. variáveis globais e variáveis locais declaradas com o modificador static em linguagem C).

    103. Dados Dinâmicos Pilha – Área de armazenamento temporário onde é armazenado o registro de ativação das funções. Heap – Área reservada para alocação dinâmica, permite ao programador alocar e liberar espaços de memória quando necessário (e.g. funções malloc e free em linguagem C).

    104. Registro de Ativação As informações necessárias para execução de uma função/procedimento são gerenciadas utilizando um bloco de memória chamado registro de ativação, fazem parte do registro de ativação: parâmetros, endereço de retorno e variáveis locais.

    105. Chamadas de Funções/Procedimentos int fat (int n) { if (n >= 1) return 1; return n * fat(n-1); } fat: pushl %ebp movl %esp, %ebp movl 8(%ebp), %ebx cmpl $1, %ebx jl L1: movl $1, %eax movl %ebp, %esp popl %ebp ret L1: subl $1, %ebx pushl %ebx call fat subl $4, %esp movl 8(%ebp), %ebx imull %ebx, %eax movl %ebp, %esp popl %ebp ret

    106. Chamadas de Funções/Procedimentos int fat (int n) { if (n >= 1) return 1; return n * fat(n-1); } Int main() { int x; x = fat(3); }

More Related