Especificação x Compilação
de Linguagens
“Rendei graças ao Senhor, porque ele é bom, porque sua misericórdia dura para sempre” (Salmo 118:1)
Introdução
Nesta aula, veremos, a correspondência entre:
a especificação de uma linguagem de alto nível e as etapas da compilaçãoCompilador
Definição mais abrangente:
É um programa que traduz um texto escrito em uma
linguagem computacional (fonte) para um texto
equivalente em outra linguagem computacional (alvo)
Entrada: código fonte (na linguagem fonte) Saída: código alvo (na linguagem alvo)
Especificação de Linguagens
de Alto Nível
O Que Especificar?
Dois aspectos principais precisam ser
especificados:
Sintaxe
Semântica
Sintaxe
Diz respeito ao formato dos códigos da
linguagem
Quais símbolos podem ser usados em cada situação
Exemplos informais:
Um declaração é um tipo seguindo de um nome Todo comando termina em “;”
Semântica
Diz respeito ao significado do código
O que ele faz quando executado (após compilação
ou interpretação)
Exemplo informal – comando while:
Primeiro ele avalia a expressão de teste Se for positiva, executa o comando do corpo do while
e volta para a primeira etapa
Restrições Contextuais
Tratam o que não pode ser especificado na
sintaxe facilmente, pois depende do contexto
Regras de escopo Regras de tipo
Etapas da Compilação
Análise Léxica Análise Sintática Analise Semântica Geração de Código Intermediário Geração de Código Final código fonte código alvoCompilação x Especificação
Análise Léxica Análise Sintática Analise Semântica Geração de Código Intermediário Geração de Código FinalLida com SINTAXE
Lida com SEMÂNTICA
Lida com RESTR. CONTEXTUAIS
Como Especificar?
Sintaxe
Especificada formalmente
Formalismos vistos em Teoria da Computação
Semântica
Lidando com a Sintaxe
(parte 1)
Compilação
Como funciona a Análise Léxica nos
compiladores
Lê o fluxo de caracteres do código fonte
Agrupa-os em seqüências significativas
Análise Léxica
Exemplo de código fonte
pos = initial + rate * 60;
Exemplo de saída
<IDENTIFIER, “pos”> <EQ> <IDENTIFIER, “initial”> <ADD> <IDENTIFIER,“rate”> <MUL>
Análise Léxica
Lexema: seqüência de caracteres com
significado interligado
Token: classificação dada ao lexema
Geralmente retornado junto com o próprio lexema ou
outro atributo, como um ponteiro
Especificando Tokens
Podem ser especificados com expressões
regulares
Cada token é associada a uma expressão
regular que representa seus lexemas válidos
Padrão que representa várias palavras
Especificando Tokens
Expressões Regulares
Padrão Palavras que casam com o padrão
abc apenas “abc” (a|bcd) “a” ou “bcd”
[adfg] qualquer dos caracteres presentes nos colchetes: “a” ou “d” ou “f” ou “g”
[a-z] qualquer caractere entre “a” e “z”
[a-z0-9] qualquer caractere entre “a” e “z” ou entre “0” e “9” [^a-z] qualquer caractere menos os que estão na faixa
Especificando Tokens
Expressões Regulares
Padrão Palavras que casam com o padrão
(ab)* zero ou mais ocorrências: “” (vazio), “ab”, “abab”, ... (ab)+ uma ou mais ocorrências: “ab”, “abab”, ...
(ab)? zero ou uma ocorrência: “” ou “ab”
(ab){2-5} duas a cinco ocorrências: “abab” ou “ababab” ... (c|s)aia? “caia” ou “cai” ou “saia” ou “sai”
[a-z][0-9]? “a”, “a0”, “a1”, “a2”, ..., “b”, “b0”, ... \(a\.b\\c\) “(a.b\c)”
Especificando Tokens
Tokens são, geralmente, especificados na forma
de definições regulares
Atribui nomes a expressões regulares
Uma definição pode usar “nomes” anteriores
letra → [a-zA-Z]
dígito → [0-9]
letra_ → (letra|_) dois_dígt → [1-9][0-9]?
Linguagem Xpress-1
Usada para exemplos da disciplina
ABRE_PAR → ( FECHA_PAR → ) ADD → + MULT → * NUM_LITERAL → [0-9]+ PT_VG → ; WHITESPACE → [ \t\n\r]+
Especificando Tokens
A maioria das linguagens definem tokens para
os seguintes elementos:
Tokens para os operadores, em grupo ou
separadamente
Um só token para todos os identificadores (nomes) Tokens diferentes para cada palavra-chave
Tokens diferentes para valores literais diversos Tokens para cada símbolo de pontuação
Alguns Tokens
Valores literais
Tokens para expressar valores explícitos
Não é exatamente o mesmo que “constantes”
Contrastar com “variáveis constantes”,
(como aquelas definidas com “final” em Java)
Exemplos em Java
10 - literal inteiro “Hello World” - literal string 3.14f - literal float
Alguns Tokens
Identificadores
São os nomes que podem ser dados a variáveis,
funções, classes, etc.
Alguns Tokens
Palavras-chave
“Parecem” identificadores, mas têm significados
especiais
Exemplos de Java:
Alguns Tokens
Palavras reservadas
São palavras-chaves que não podem ser usadas
como identificadores
A palavras-chave não pode ser usadas para dar nome a
variáveis, etc.
Considerar todas as palavras-chaves como palavras
reservadas é muito comum
Exemplo
Linguagem PL/I, onde palavras-chave não são
palavras reservadas
IF (THEN) THEN THEN = ELSE; ELSE
Alguns Tokens
Espaços em branco
Caracteres que devem ser ignorados
Na verdade, é um “não-token”
Exemplo de definição
A primeira etapa do compilador simplesmente não
retorna token para esse padrão
Lidando com a Sintaxe
(parte 2)
Compilação
Como funciona a Análise Sintática de um
compilador
Lê a seqüência de tokens (do analisador léxico)
Monta uma organização lógica deles na forma de
Análise Sintática
Analogia com análises feitas na língua
portuguesa...
Exemplo no quadro: análise na língua portuguesa x
compiladores
Como especificar as regras da linguagem que
Especificando Sintaxe
Pensar na organização dos tokens em “frases”
Uma declaração é um tipo seguido de umidentificador seguido de ponto-e-vírgula
Um tipo pode ser os tokens INT ou CHAR
Produções – “regras de formação”
declaração → tipo ID ; tipo → INT
Especificando Sintaxe
São usadas gramáticas livres de contexto,
que possuem quatro elementos:
Símbolos terminais
Símbolos não-terminais Símbolo inicial
Especificando Sintaxe
Elementos das gramáticas livres de contexto:
Símbolos terminais:
Símbolos assumidos como atômicos, indivisíveis Assumiremos os tokens como terminais
Símbolos não-terminais:
Especificando Sintaxe
Elementos das gramáticas livres de contexto:
Símbolo inicial: Não-terminal que será a raiz (topo) da árvore
Geralmente é um não-terminal chamado programa
Produções:
São as regras de formação
Especificando Sintaxe
Notações comuns para as produções
BNF (Backus-Naur Form)
BNF (Backus-Naur Form)
Não-terminais entre “<“ e “>”
Terminas entre aspas ou sem delimitadores Usa “::=“ ao invés de “→”
<bloco> ::= BEGIN <comando-l> END <comando-l> ::= <comando>
| <comando> <comando-l>
EBNF (Extended BNF)
Existem diversas variações...
Em uma boa especificação, devem vir anotações sobre
quais as extensões assumidas
A característica mais comum é que não-terminais
aparecem sem delimitador
bloco = BEGIN comando* END
EBNF (Extended BNF)
Outras características típicas
Chaves ou “*” significam repetições
Colchetes ou “?” significam opcional (zero ou um)
Oferecer expressões regulares, permitindo que os tokens
sejam especificados como não-terminais
Identifier = [a-zA-Z]+
Equals = “=“
Exemplo
Linguagens Xpress-n (versões 0, 1, 2, etc)
Uma linguagem simples para criar expressões Apenas dois comandos:
Definir um nome para alguma expressão (constante) Avaliar uma expressão
Exemplo
Linguagem Xpress-1
<program> ::= <comand>*
<comand> ::= “def” IDENTIFER “=” <expr> “;” | “eval” <expr> “;”
<expr> ::= <expr> “+” <expr> | <expr> “*” <expr> | <exprBasic>
<exprBasic> :: = “(” <expr> “)” | NUM_LITERAL
Especificando Sintaxe
Gramáticas livres de contexto podem
representar tudo que expressões regulares
representam
E algo mais...
Por isso, em alguns casos uma gramática em
EBNF é usada para especificar tudo
Exemplo
Especificação de Java 7
https://docs.oracle.com/javase/specs/jls/se7/html/inde x.html
Lidando com a Semântica
Na especificação de linguagens
Geralmente, é feita informalmente (com texto escrito)
Especificações formais são de interesse mais
acadêmico, ainda
Na compilação
Veremos alguns conceitos e técnicas
Mas técnicas são menos estruturadas do que as que
Restante da Disciplina