1 / 28

Descrição da Sintaxe

Sintaxe – Forma das. Expressões Instruções Unidades. Expressões Instruções Unidades. Semântica – Significado das. Exemplo: Comando if do C. Semântica: “Se o valor de expressão for verdadeiro...”. Sintaxe: if (<expressão>) <instrução>.

terri
Télécharger la présentation

Descrição da Sintaxe

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. Sintaxe – Forma das Expressões Instruções Unidades Expressões Instruções Unidades Semântica – Significado das Exemplo: Comando if do C Semântica: “Se o valor de expressão for verdadeiro...” Sintaxe: if (<expressão>) <instrução> Sintaxe: mais fácil de descrever que a semântica. Existe uma notação concisa e universalmente aceita para a descrição da sintaxe, mas não ainda para a semântica Descrição da Sintaxe

  2. Lexemas – Unidades sintáticas Descrição dada por uma especificação léxica, em nível mais baixo que a descrição sintática Exemplo: Palavras reservadas, identificadores, literais, operadores... Tokens Categorias de lexemas Às vezes um token tem somente um lexema possível, às vezes “infinitos” Exemplo: index = 2*count + 17 “index” e “count” são lexemas que pertencem à categoria “identificador”

  3. Formas de definir as linguagens, através de: Reconhecedores de Linguagens Dispositivos para verificar se certa sentença está na linguagem Geradores de Linguagens Dispositivos para gerar sentenças da linguagem BNF – Backus Naur Form Notação mais usada para descrever formalmente as linguagens de programação “Metalinguagem ” ( linguagem usada para descrever linguagens) para linguagens de programação Gramática é o conjunto de regras que produz a linguagem

  4. <if_stmt> if <expr_lógica> then <stmt> <if_stmt> if <expr_lógica> then <stmt> else<stmt> <if_stmt> if <expr_lógica> then <stmt> | if <expr_lógica> then <stmt> else<stmt> <lista_ident> <ident> | <ident> , <lista_ident> <ident> <letra> <seq> | <letra> <letra> A|B|C ... |Z <seq> <letra> <seq> | <dígito><seq> | <letra> | <dígito> <dígito> 0|1|2 ... |9 BNF Exemplo: comando “if ” do Pascal ou Exemplo: listas e recursividade

  5. <programa> begin <lista_stmt> end <lista_stmt> <stmt> | <stmt> ; <lista_stmt> <expressão> <var>+ <var> | <var> - <var> | <var> <programa> begin <lista_stmt> end begin <stmt> ; <lista_stmt> end begin <var> := <expressão> ; <lista_stmt> end begin A := <expressão> ; <lista_stmt> end begin A := <var> + <var> ; <lista_stmt> end begin A := B + <var> ; <lista_stmt> end begin A := B + C ; <lista_stmt> end begin A := B + C ; <stmt> end begin A := B + C ; <var> := <expressão> end begin A := B + C ; B := <expressão> end begin A := B + C ; B := <var> end begin A := B + C ; B := C end Gramática para uma pequena linguagem <stmt> <var> := <expressão> <var> A | B | C Exemplo de derivação:

  6. <atribuição> <id> := <expressão> <expressão> <id>+ <expressão> | <id> * <expressão> | ( <expressão> ) | <id> <atribuição> <id> := <expressão> A := <expressão> A := <id> * <expressão> A :=B * <expressão> A :=B * ( <expressão> ) A :=B * ( <id> + <expressão> ) A :=B * (A+ <expressão> ) A :=B * (A+ <id> ) A :=B * (A+ C) Gramática para instruções de atribuição <id> A | B| C Exemplo: derivar A := B * ( A + C )

  7. <atribuição> := <id> <expressão> * A <id> <expressão> ( B ) <expressão> + <id> <expressão> A <id> C Árvores de Análise ( “Parse Trees” ) Exemplo: A := B * ( A + C )

  8. <atribuição> <id> := <expressão> <expressão> <expressão>+ <expressão> | <expressão> * <expressão> | ( <expressão> ) | <id> 1º) <atribuição> := <id> <expressão> <expressão> + <expressão> A <expressão> <expressão> * <id> <id> <id> B A C Exemplo de Gramática Ambígua <id> A | B| C Exemplo: construir duas árvores diferentes para A := B * ( A + C )

  9. 2º) <atribuição> <atribuição> <id> := <expressão> := <id> <expressão> <expressão> * <expressão> A <expressão> <expressão> + <id> <expressão> <expressão>+ <expressão> | <termo> <id> A <id> C B <id> A | B| C <termo> <termo>* <fator> | <fator> <fator> ( <expressão> ) | <id> “Consertando” a Gramática

  10. <atribuição> <id> := <expressão> <id> A | B| C <expressão> <expressão>+ <expressão> | <termo> <termo> <termo>* <fator> | <fator> <fator> ( <expressão> ) | <id> Descrição da Sintaxe Gramática não ambígua para expressões Associatividade de operadores de mesma precedência <atribuição> := <id> <expressão> Operador de adição esquerdo mais baixo que o direito. É a ordem correta se queremos associatividade à esquerda + <expressão> <termo> A + <termo> <expressão> <fator> <fator> <termo> <id> <fator> A <id> <id> C B

  11. <expressão> ( <expressão> ) | <id> <id> A | B| C Exemplo: A ^ B ^ C = A ^ ( B C ) ^ <fator> <expressão> ^ <fator> <fator> <expressão>^ <fator> | <expressão> <fator> <expressão> ^ <id> <expressão> <id> A B <id> C Regra recursiva à esquerda LHS aparece no início do RHS ( vide gramática anterior ) Regra recursiva à direita LHS aparece no final do RHS Exemplo: operador de exponenciação geralmente é associativo à direita

  12. <if_stmt> if <exp_lógica> then <stmt> | if <exp_lógica> then <stmt> else <stmt> <stmt> <if_stmt> <if_stmt> <exp_lógica> else if then <stmt> <stmt> <if_stmt> <exp_lógica> if then <stmt> if <exp> then if <exp> then <stmt> else <stmt> Ambigüidade em if – then – else Árvore de análise I

  13. <if_stmt> <exp_lógica> else if then <stmt> <stmt> <if_stmt> <exp_lógica> if then <stmt> if <exp> then if <exp> then <stmt> else <stmt> Árvore de análise II

  14. <stmt> <coincidente> | <livre> <coincidente> if <exp_lógica> then <coincidente> else <coincidente> | qualquer instrução não if É necessário ? Sim! Não é possível fazer if <exp_lógica> then if <exp_lógica> then <algo> else <algo> Fica obrigatório derivar <stmt> <livre> if <exp_lógica> then <stmt> if <exp_lógica> then <coincidente> ... “Consertando” a Gramática Regra Geral: o else pertence sempre ao then mais próximo e entre um then-else, não pode haver if sem else <livre> if <exp_lógica> then <stmt> if <exp_lógica> then <coincidente> else <livre> |

  15. repetido indefinidamente omitido completamente <for_stmt> for <var> := <expressão> (to|downto) <expressão> do <stmt> BNF Estendida Extensões não aumentam o poder descritivo da BNF apenas melhoram sua legibilidade e capacidade de escrita 1) Denotar parte opcional dentro de colchetes em RHS <seleção> if ( <exp_lógica> ) <instrução> [else <instrução>] 2) Uso de chaves em RHS para indicar que o que está contido nelas pode ser: a) <lista_iden> <identificador> {, <identificador>} b) <comp> begin <stmt> {<stmt>} end 3) Lidar com opções de múltipla escolha não são terminais

  16. BNF <expr> <expr> + <termo> | <expr> - <termo> | <termo> <termo> <termo> * <fator> | <termo> / <fator> | <fator> EBNF <expr> <termo> {(+ | -)<termo>} <termo> <fator> {(* | /)<fator>} Comparação entre BNF e EBNF

  17. if_stmt if then condição stmts end_if else_if else stmts else_if elsif then condição stmts Grafo Sintático ( grafo de sintaxe) Exemplo: Instrução if em ADA <if_stmt> if <condição> then <stmts> {<else_if>} [else <stmts>] end_if <else_if> elsif <condição> then <stmts> Legenda: não-terminais terminais

  18. top – down (descendente) bottom – up (ascendente) Parsers – Analisadores sintáticos para linguagens de programação yacc: um dos mais usados (yet another compiler compiler) Parsers: Análise Sintática Descendente Recursiva Exemplo: <expr> <termo> {(+ | -)<termo>} <termo> <fator> {(* | /)<fator>} <fator> <id> | (<expr>) Chama uma rotina para cada não terminal void expr ( ){ termo ( ); while ( prox_token == “+” || prox_token == “-” ){ lexical ( ); termo ( ); } } lexical coloca o próximo token de entrada em prox_token( var global)

  19. void termo ( ){ fator ( ); while ( prox_token == “*” || prox_token == “/” ){ lexical ( ); fator ( ); } } void fator ( ){ if (prox_token == ident ){ lexical ( ); return; } else if (prox_token == “(” ){ lexical ( ); expr( ); if (prox_token ==“)”{ lexical( ); return; } else error ( ); } else error( ); }

  20. Problema para parsers descendentes recursivos: recursão à esquerda. Ex: < A > < A > + < B > (A discussão das características que autorizam o uso de parsers descendentes recursivos para uma gramática particular não será feita aqui) Gramática de atributos Dispositivos para descrever mais detalhes da estrutura das linguagens de programação do que é possível com (a BNF) uma gramática livre de contexto Existem características da estrutura das linguagens de programação difíceis/impossíveis de descrever com A BNF Exemplos: “todas as variáveis devem ser declaradas antes de serem referenciadas” “end de uma subrotina em ADA seguido de um nome deve coincidir com o nome da subrotina” Semântica Estática Análise necessária para verificar essas especificações. Pode ser feita em tempo de compilação Mais relacionada ainda com a sintaxe

  21. Símbolo gramatical X A(X) = S(X)  H(X) Conjunto de atributos associados a X Atributos Herdados  Atributos Sintetizados  Atributos “Variáveis” associadas a símbolos gramaticais Funções de computação de atributos Associadas a regras para especificar como os valores dos atributos são computados Funções Predicadas “Filhos” na árvore de análise Regra: X0 X1 ... Xn S(X0) = f ( A(X1),...,A(Xn) ) H(Xj) = f ’ ( A(X0), A(X1),...,A(Xj-1) ) depende dos filhos depende do pai e irmãos “menores” 1 j  n

  22. Função predicada: g ( A(X0),..., A(Xn) ) expressão booleana Se todos os valore de atributos em uma árvore de análise tiverem sido computados ela é totalmente atribuída Atributos intrínsecos atributos sintetizados de vértices folhas, cujos valores são calculados fora da árvore de análise usados para distinguir as 2 ocorrências do mesmo não-terminal Exemplo: Ada Regra sintática: <def_proc> procedure <nome_da_proc>[1] <corpo_da_proc> end <nome_da_proc>[2] Regra semântica: <nome_da_proc>[1].string = <nome_da_proc>[2].string

  23. Legenda Regra 1 Regra 2 Regra 3 Regra 4 Passos da construção 3 1 2 4 5 1 2 3 3 4 5 Exemplo: Compatibilidade de Tipos <atribuição> <expressão> tipo_esperado tipo_efetivo := <var> + <var> tipo_efetivo <var> string tipo_efetivo string string A A B tipo_efetivo

  24. Operacional Axiomática Denotacional Semântica Dinâmica Semântica propriamente dita, significado das expressões / instruções / unidades do programa Semântica Semântica Operacional - descreve o significado de um programa através da execução de suas instruções numa máquina ( real ou simulada,virtual ). Alterações no estado da máquina ao executar determinada instrução definem o significado desta instrução Estado S Estado S’ Estado  valores de todos os registros ( células de memória )

  25. Tradução para linguagem De baixo nível “Rodar” o programa na máquina virtual Exemplo: Instrução for do C for ( expr1 ; expr2 ; expr3 ){ ... } Semântica Operacional expr1; loop: if expr2 = 0 goto out ... expr3; goto loop; out: Qual computador usar ? Hardware de um computador específico interpretador puro de sua linguagem de máquina Complicado usar uma máquina real específica Usar um computador de baixo nível, implementado como uma simulação de software Semântica Operacional Depende de algoritmos, não de matemática

  26. Exemplo: <num_bin> 0 | 1 | <num_bin> 0 | <num_bin> 1 Semântica Axiomática - baseia-se na lógica matemática Associada a um método para provar. Correção de programas que mostra a computação descrita por sua especificação. ( limitada e de aplicação difícil ) Semântica Denotacional – dentre os métodos mais empregados, é o de maior rigor matemático. Baseia-se solidamente na teoria das funções recursivas. • Idéia: Associar para cada entidade da linguagem um objeto matemático e uma função que os relacione (entidade e objeto ) • Há maneiras rigorosas para manipular objetos matemáticos, mas não construções de Linguagens de Programação • Os objetos denotam o significado das entidades sintáticas que lhes correspondem

  27. Árvore para 110 = 6 <num_bin> 6 <num_bin> ‘0’ 0 3 <num_bin> ‘1’ 1 ‘1’ 1 Função Semântica Mbin– associa os números binários aos inteiros decimais não-negativos Mbin( ‘0’ ) = 0 Mbin( ‘1’ ) = 1 Mbin( <num_bin> ‘0’ ) = 2 * Mbin( <num_bin> ) + Mbin( ‘0’ ) Mbin( <num_bin> ‘1’ ) = 2 * Mbin( <num_bin> ) + Mbin( ‘1’ ) Exemplo: <num_dec>  0|1|2| ... |9 | <num_dec> (0|1|2| ... |9 ) Mbin( ‘0’ ) = 0 ,... , Mbin( ‘9’ ) = 9 Mbin( <num_dec> ‘0’ ) = 10 * Mbin( <num_bin> ) + 0 Mbin( <num_dec> ‘9’ ) = 10 * Mbin( <num_bin> ) + 9 ...

  28. ij  nome da variável j vj  valor da variável j ( pode ser undef ) Estado de um programa S = { <i1 , v1>,...,<in ,vn> } VARMAP ( i , j ) = vj Me ( <expr> , s ) = devolve o valor de <expr> no estado s ( Me ( <expr> , s )   {error} ) Ma ( x = E, s ) = devolve o estado do programa após a execução da instrução x = E Ms1 ( K, s ) = devolve o estado do programa após a execução da lista de instruções K lista de instruções

More Related