Prévia do material em texto
11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 1/40 COMPILADORESCOMPILADORES ÁRVORE DE DERIVAÇÃOÁRVORE DE DERIVAÇÃO E GRAMÁTICAS LIVRESE GRAMÁTICAS LIVRES DE CONTEXTODE CONTEXTO Au to r ( a ) : D r. J o ã o C a r l o s L o p e s Fe r n a n d e s R ev i s o r : Ed i l s o n J o s é R o d r i g u e s Tempo de leitura do conteúdo estimado em 1hora e 15 minutos. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 2/40 Introdução Caro(a) estudante, para podermos criar uma árvore de derivação, também conhecida como árvore de análise, precisamos fazer uso de alguns parâmetros. Além disso, sempre teremos como resultado uma árvore que possui sua raiz ordenada representando, gra�camente, as descrições semânticas de strings que foram derivadas da gramática livre de contexto, ou GLC. A derivação e/ou rendimento de uma GLC resultará em uma string �nal, que será obtida na concatenação dos rótulos que indicam as folhas da árvore seguindo o sentido da esquerda para a direita. Também é importante notar que os valores nulos sempre serão ignorados. No caso de todas as folhas serem nulas, a derivação também será nula. Já quando estamos tratando de uma linguagem formal, ela pode ser considerada como livre do contexto, caso as regras utilizadas em sua produção possam ser aplicadas independentemente do contexto simbólico a ser utilizado. Um abraço e bom estudo! 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 3/40 Você já ouviu falar sobre “geração de árvore de derivação”? Vamos estudar um pouco mais a fundo o que ela signi�ca? Antes, vamos para a de�nição formal da GLC, que é “G = (V, T, P, S)”, sendo: (V) – conjunto de não terminais; (T) – conjunto de terminais; (P) – conjunto de produções; e (S) – não terminal inicial; em que qualquer regra de produção é da forma “A → α”, sendo “A” a variável de V e “α” a palavra de (V ∪ T)*. Dessa forma, uma Linguagem Livre de Contexto (LLC), ou Tipo 2, é gerada por uma gramática livre de contexto, em que G: GERA(G) = {w ∈ T * | S ⇒ + w}. Sendo assim, qualquer linguagem regular pode ser livre de contexto. Uma árvore de derivação é a principal forma de representar a derivação de uma sentença a partir de uma GLC, sendo extremamente útil em algumas aplicações, como nos compiladores. Nela, possuímos a raiz, que é o símbolo de partida da Geração de Árvore de derivação a partir de Gramáticas Livres de Contexto 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 4/40 GLC, os nós internos, que são símbolos de V, e os nós folha, que são símbolos de T (ou λ). As gramáticas livres de contexto auxiliam na construção de gramáticas atuais das linguagens de programação, como Python, Java, C++, entre outras, e de compiladores. O compilador precisa validar se uma determinada cadeia de caracteres escrita em um arquivo pertence ou não a uma linguagem de programação. (BARBOSA et al., 2021, p. 34). Uma produção (P) é um par de um “não terminal” e uma cadeia de terminais, que, possivelmente, estará vazia. Dessa forma, podemos considerar as produções como regras em que o não terminal é o lado esquerdo e a cadeia, o lado direito. Inclusive, é muito comum escreverem gramáticas usando apenas as produções, pois os conjuntos de terminais, não terminais e não terminal inicial podem ser facilmente deduzidos com o auxílio de algumas convenções tipográ�cas. Como se pode observar na Figura 1.1, a Raiz é o símbolo inicial da gramática e os vértices interiores são as variáveis, sendo “A” o vértice interior e X1, X2,…,Xn os "�lhos" de “A”. Dessa forma, A → X1, X2…Xn é uma produção da gramática, X1, X2,…,Xn, em que são ordenados da esquerda para a direita. O Vértice folha, ou simplesmente folha, é a terminação e/ou o símbolo vazio. Se estiver vazio, signi�ca que tem um único �lho de seu pai (A → ε). 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 5/40 Figura 1.1 – De�nição de uma árvore de derivação Fonte: Adaptada de Menezes (2011). #PraCegoVer: a imagem apresenta três colunas. Na coluna central, em sua extremidade superior, está escrito “Vértice interior”. Logo abaixo, aparece uma seta apontando para baixo, direcionada a uma letra “A”. Dessa letra saem três setas, que apontam para X1, X2 e Xn. Na coluna à direita, há duas setas para baixo, uma indicando para a letra “a” e outra para o símbolo “ε”. Na extremidade da seta que aponta para “ε”, há a letra “A” e, logo abaixo, há a palavra “Folhas”. Na coluna da esquerda, em sua extremidade, há a palavra “Raiz” e, abaixo, a letra “S”. Dela saem três setas que apontam para baixo, sem nenhum valor em suas extremidades. Para criarmos uma árvore de derivação para a sentença “x+x*x” a partir de uma sequência GLC, devemos seguir os seguintes passos: 1. E → E+E 2. E → E*E 3. E → (E) 4. E → x 1 4 2 4 4 E ⇒ E+E ⇒ x+E ⇒ x+E*E ⇒ x+x*E ⇒ x+x*x Essa sequência resultou na descrição grá�ca apresentada a seguir, na Figura 1.2. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 6/40 Figura 1.2 – Árvore de derivação para a sentença “x+x*x” Fonte: Adaptada de Menezes (2011). #PraCegoVer: a imagem apresenta, em sua parte superior, a letra “E”, apontando para três linhas perpendiculares, que possuem, em suas extremidades, da direita para a esquerda, a letra “E”, o símbolo “+” e outra letra “E”. A letra “E” da esquerda é seguida pela letra “X”, que está marcada por um círculo vermelho e possui uma seta vermelha que aponta para o símbolo “+”. A outra letra “E” aponta para três linhas perpendiculares que possuem, em suas extremidades, da direita para a esquerda, a letra “E”, o símbolo “*” e outra letra “E”. As duas letras “E” têm, no �nal de suas linhas, a letra “X”, com círculos vermelhos ao seu redor. A letra “X” da direita recebe uma seta do sinal de “+” (seta vermelha) e aponta uma seta vermelha para o símbolo “*”, que também tem ao seu redor um círculo vermelho. Por �m, o sinal “*” aponta uma seta vermelha para a letra “X”, que está à direita da imagem. Para que todas essas operações sejam possíveis, é necessário conhecer bem os conceitos da GLC e, assim, otimizar a função dos compiladores, que é o foco de nossa disciplina. Revisar os conceitos de Gramática Livre de Contexto (GLC) Você sabia que a GLC possui várias categorias? Elas devem ser analisadas para que a análise sintática utilizada seja correspondente e, assim, o melhor resultado seja alcançado pelo compilador. As gramáticas livres de contexto são divididas em várias categorias que determinam o tipo de algoritmo que pode ser usado na análise sintática das linguagens correspondentes. As principais categorias são LL(k), LR(k). O primeiro «L» indica o sentido de leitura (left-right, da 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 7/40 esquerda para a direita). O segundo «L» é devido ao fato de a análise sintática ser feita usando sempre as derivações mais à esquerda. (LANGLOIS; SANTOS, 2018, p. 34). A análise sintática é o processo para determinar se uma cadeia de tokens, isto é, o programa já analisado por um analisador léxico, pode gerar uma gramática. Essa prática tem como objetivo a construção de uma árvore sintática ou apenas decidir se a cadeia fornecida é uma sentença gramatical que de�ne a linguagem. Categoria LL(k) Um analisador sintático da categoria LL(k) é um algoritmo que realizaa análise sintática em subconjuntos de gramáticas livres de contexto. Ele é um analisador sintático descendente (top-down) por sua característica em tentar deduzir as produções da gramática a partir da raiz. Além disso, ele analisa o texto da esquerda para a direita, criando derivações mais à esquerda. Por esse motivo, ele recebe o nome LL (left-left). 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 8/40 Os analisadores sintáticos operam em cadeias de texto de determinadas gramáticas formais, que consistem, no mínimo, em um buffer para entrada, em uma pilha onde são armazenados os símbolos gramaticais que ainda não foram analisados e em uma tabela para análise, que indicará a regra gramatical a ser utilizada e o próximo token a ser tratado. Toda vez que o analisador é iniciado, a pilha recebe dois símbolos: S e $, em que $ é o terminador especial para indicar o �nal da pilha, ou seja, o �m da entrada de dados, e o S é o símbolo que indica a entrada da gramatical. O analisador sintático sempre vai tentar reescrever o conteúdo da pilha interpretando a entrada de texto, mas ele apenas irá manter o que ainda deve ser tratado. Categoria LR(k) Um analisador sintático da categoria LR(k), também conhecido como parser LR, é um algoritmo utilizado no tratamento das gramáticas livres de contexto. Ele é diferente do LL(k) e realiza a leitura da entrada de texto da esquerda para a direita, produzindo uma derivação mais à direita. Por esse motivo, LR (left-right). Ele também é conhecido como analisador sintático LR(k), em que k se refere à quantidade de símbolos posteriores ao símbolo atual, que ainda não foram consumidos da entrada e que serão utilizados para tomar decisões na análise. O analisador sintático LR é um analisador ascendente (bottom-up), pois tenta deduzir as produções da gramática a partir das folhas da árvore. Muitas são as linguagens de programação que utilizam a gramática LR, ou pelo menos uma parecida. Por esse motivo, os analisadores LR são, normalmente, utilizados pelos compiladores na realização da análise sintática do código fonte. Uma exceção é a linguagem de programação C++. Acesse o Saiba mais a seguir para se aprofundar no assunto. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiUp… 9/40 O analisador sintático LR possui algumas variações dependendo da forma que foi gerada a tabela, podendo ser chamado de SLR (simples), LALR (quando há análise de símbolos posteriores) e canônico LR(0), que podem manipular mais tipos gramaticais que os analisadores LALR e SLR. Árvores de derivação 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 10/40 Em uma árvore de derivação, os “nós” internos são denominados símbolos não terminais e as folhas são chamadas de símbolos terminais. Além disso, todos os programas responsáveis pela produção de árvores de derivação são denominados analisadores sintáticos. A estrutura da árvore sintática depende da estrutura sintática especí�ca da linguagem. Essa árvore é, em geral, de�nida como uma estrutura de dados dinâmica, em que cada nó é composto por um registro cujos campos contêm os atributos requeridos para o restante do processo de compilação (ou seja, não apenas os computados pelo analisador sintático). (LOUDEN, 2004, p. 96). As árvores de derivação podem possuir ambiguidade, mas um requisito importante das linguagens de programação é que elas não sejam ambíguas ou, pelo menos, que isso seja evidente ou facilmente evitado. Ambiguidade Uma gramática será ambígua quando existir alguma cadeia com mais de uma árvore sintática, ou seja, caso exista mais de uma derivação à esquerda e/ou à direita para uma cadeia. A ambiguidade é muito ruim nas linguagens de programação, pois pode ocasionar interpretações inconsistentes entre diferentes compiladores. Infelizmente, não há, atualmente, algoritmos capazes de detectar se uma gramática é ambígua, mas, com a utilização das heurísticas, é possível veri�car se há uma regra misturando recursão à esquerda e/ou à direita. Uma gramática é considerada ambígua, e consequentemente não é executável por processos determinísticos, como as gramáticas LALR(1) usadas pela ferramenta yacc, se uma mesma sequência de entrada for reconhecível por meio de derivações distintas. Em resumo, uma gramática não ambígua reconhece uma sequência de entrada (arquivo com a linguagem) com uma e somente uma sequência de derivações. (LANGLOIS; SANTOS, 2018, p. 159). 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 11/40 Para evitarmos a ambiguidade, podemos introduzir prioridades e associatividades nas regras, caso re�itam os objetivos da linguagem. De forma mais genérica, as regras devem ser reescritas para que o analisador consiga identi�cá-las com apenas k símbolos de antevisão. Quando estiver nessa fase, o analisador realiza seu processamento sem erros em todas as sequências de entrada, bem como rejeita todas as incorretas (LANGLOIS; SANTOS, 2018). Agora, estudaremos um pouco mais sobre a precedência entre os operadores. É importante destacar que elas podem ser ditadas pela estrutura das regras. Além disso, os níveis de precedência podem ser de�nidos por um encadeamento de regras, introduzindo símbolos não terminais adicionais: E → E + T | T T → T * F | F F → id F → (E) As sequências id * id + id e id + id * id nos conduzirão a duas árvores sintáticas distintas, em que a multiplicação será sempre calculada em primeiro lugar. As árvores sintáticas obtidas são: 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 12/40 Figura 1.3 – Árvores sintáticas Fonte: Langlois; Santos (2018, p. 41). #PraCegoVer: a imagem apresenta, no lado direito, uma letra “E” com três linhas, com ângulos de 45º equidistantes. Na extremidade mais à direita, há outra letra “E”, no centro, o símbolo “+” e, na outra extremidade, a letra “T”. Em um nível abaixo, a letra “E” aponta para uma letra “T”, que deriva em três linhas com ângulos de 45º equidistantes. A mais à direita tem a letra “T”, com uma linha vertical apontando para uma letra “F”, que aponta para “id”. No centro, há o símbolo da multiplicação, e na linha da esquerda tem a letra “F”, apontando para “id”. Do lado esquerdo, na mesma altura do lado direito, tem a letra “E” com três linhas, com ângulos de 45º equidistantes. Na extremidade mais à direita, há outra letra “E”, no centro, o símbolo “+” e, na outra extremidade, a letra “T”. Abaixo dessa letra “T”, há três linhas com ângulos de 45º equidistantes. Na extremidade direita tem a letra “T” apontando para uma letra “F” (linha), que aponta para “id”. Ao centro, o símbolo de multiplicação e, à esquerda, a letra “F”, que tem uma seta vertical apontando para “id”. A outra letra “E”, que se encontra à direita do símbolo “+”, aponta na vertical para uma letra “T”, que aponta para uma letra “F”, que aponta para “id”. Se a ambiguidade está na gramática, e não na linguagem, a melhor forma para tentar eliminá-la é encontrar a fonte da ambiguidade e reescrever a gramática. Para os casos de ambiguidade na gramática de expressões e/ou operadores, a sua fonte não leva em conta as regras de associatividade e precedência dos operadores. Isso, porque, na gramática de expressões, cada nível de precedência deve ganhar seu próprio não terminal. Dessa forma, os operadores à esquerda precisam usar recursão à esquerda, e os associativos à direita precisam de recursão à direita. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU…13/40 Conhecimento Teste seus Conhecimentos (Atividade não pontuada) Para que os programas realizem as suas funções, é preciso que eles sejam traduzidos em código de máquina. Para isso, será necessária a utilização dos compiladores. Analise as afirmativas a seguir: I. A memória sempre fica ocupada pelo compilador para executar os processos de compilação dos programas, independente do estágio em que estejam. II. A memória somente é utilizada e carrega o compilador quando é realizado o processo de compilação dos programas. III. No processo de compilação, o(s) programa(s) é(são) traduzido(s) completamente apenas uma vez. IV. Os programas, para serem executados, precisam ser traduzidos antes. V. As funções e a execução dos compiladores são sempre bem rápidas. VI. Um programa compilado sempre se torna mais lento quando for executado. AHO, A. V. et al. Compiladores: princípios, técnicas e ferramentas. São Paulo: Pearson, 2008. Está correto o que se afirma em: 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 14/40 a) I, apenas. b) I e VI, apenas. c) I, II, III e V, apenas. d) II, III e V, apenas. e) IV e VI, apenas. Os compiladores devem levar em consideração a interação entre os algoritmos e as estruturas de dados, que são os responsáveis pelo suporte nas fases de compilação. O compilador deve implementar os algoritmos da forma mais e�ciente possível, ou seja, devem evitar muita complexidade. Sendo assim, um compilador deverá ser capaz de compilar os programas em espaços de tempo proporcionais ao tamanho do código fonte do programa, em tempo O(n), em que n mede o tamanho do programa (normalmente, o número de caracteres). Estrutura de um compilador – Parte I 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 15/40 O compilador recebe na entrada o programa fonte modi�cado e pode produzir como saída um programa em uma linguagem simbólica como assembly, considerada mais fácil de ser gerada como saída e mais fácil de depurar. A linguagem simbólica é então processada por um programa chamado Montador (assembler), que produz código de máquina relocável como sua saída. (AHO et al., 2008, p. 3). Como em alguns casos o processo de compilação pode ser bem complexo, há uma estrutura básica que faz a divisão dos processos em fases, que são representadas em duas tarefas básicas, a análise e a síntese. A tarefa de síntese, conhecida como back-end, é responsável por construir o programa objeto a partir das representações criadas na análise. A Figura 1.4 apresenta, de forma sintetizada, um processo de compilação e suas etapas. Fonte: yurich84 / 123RF. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 16/40 Figura 1.4 – Processo de compilação e suas etapas Fonte: Marangon (2022, on-line). #PraCegoVer: a imagem apresenta um �uxograma das etapas de compilação. Na parte superior, há a palavra “Programa Fonte”, com uma seta para baixo, que aponta para palavras dentro de um retângulo hachurado com as seguintes palavras no interior dos retângulos: “Analisador Léxico”, “Analisador Sintático” e “Analisador Semântico”, com setas entre elas indicando uma sequência lógica. Entre as palavras “Analisador Léxico” e “Analisador Sintático”, há a palavra “Tokens” fora de um retângulo e dentro do retângulo hachurado. Entre as palavras “Analisador Sintático” e “Analisador Semântico”, há a palavra “Árvore Sintática" fora de um retângulo, mas dentro do retângulo hachurado. Logo abaixo, há outro retângulo hachurado interligado com o de cima por uma seta, e a palavra “Árvore Sintática” entre eles. Dentro do retângulo hachurado de baixo, há as seguintes palavras no interior dos retângulos: “Gerador de Código Intermediário”, “Otimizador de Código” e “Gerador de Código”. Entre as palavras “Gerador de Código Intermediário” e “Otimizador de Código”, há a palavra “Representação Intermediária”. Entre as palavras “Otimizador de Código” e “Gerador de Código”, há a palavra “Representação Intermediária”, que está fora dos retângulos, mas dentro do retângulo hachurado. Fora desse segundo retângulo hachurado, há uma seta interligando-o com a palavra “Código de Máquina Alvo”. Do lado esquerdo dos retângulos tracejados, temos as palavras “Tabela de Símbolos” no interior de um retângulo que possui setas interligando-o com todas as palavras que estão entre os retângulos dentro dos dois retângulos tracejados. Do lado direito, perto do retângulo hachurado, há a palavra “Análise (front-end compiler)” e, logo abaixo, a palavra “Tratamento de Erros”, no interior de um retângulo com setas, que interliga as palavras dos retângulos “Analisador Léxico”, “Analisador Sintático” e “Analisador Semântico”. Por �m, próximo ao retângulo hachurado de baixo, há a palavra “Síntese (back-end compiler)”. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 17/40 O processo de compilação começa no analisador léxico, que examina, de forma minuciosa, o programa fonte (texto) e o transforma em um �uxo de tokens. É nessa fase que é criada a tabela de símbolos. Depois, tem início a análise sintática, que tem como função ler o �uxo de cada token e validar a estrutura do programa, criando uma árvore sintática. Na terceira fase, ocorre a análise semântica, responsável por garantir as regras (semânticas). Todas essas fases fazem parte da tarefa de análise e são superimportantes. A quarta fase diz respeito à geração de código intermediário, que cria a abstração do código. Na próxima fase, ocorre a otimização do código e, �nalmente, a geração do código objeto, que tem a função de gerar o código de baixo nível, baseando-se na arquitetura do equipamento. Todas essas fases fazem parte da tarefa de síntese. Evolução e geração dos compiladores Para realizar a construção de um compilador, várias áreas de estudo relacionadas a ciências da computação são utilizadas, como as de algoritmos, linguagens de programação e arquitetura de computadores, além das ligadas à engenharia de software. O primeiro compilador foi escrito por Grace Hopper, em 1952, para a linguagem de programação A-0. Antes de 1957, foram reunidos esforços e várias contribuições no desenvolvimento de linguagens de alto nível. Um compilador é uma ferramenta complexa que há alguns anos atrás exigia um esforço signi�cativo, na ordem das centenas de pessoas/mês. Inicialmente, tal como os assemblers e outras ferramentas, os compiladores eram codi�cados em binário e armazenados em memórias ROM. O primeiro compilador de FORTRAN desenvolvido pela IBM nos anos 1950 requereu um esforço estimado de 18 pessoas/ano. (LANGLOIS; SANTOS, 2018, p. 5). 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 18/40 Ao longo dos anos, as linguagens de programação e a arquitetura dos computadores mudaram bastante. Essas mudanças impuseram alterações nos projetos de compilação, ou seja, na criação de novos algoritmos que possuam mais e�ciência e desempenho na hora de utilizar a memória e o processador. Sendo assim, conhecer as arquiteturas dos computadores, os sistemas operacionais, as linguagens de programação disponíveis e as técnicas de engenharia de software é essencial na criação de novos compiladores. Front-End Vamos conhecer mais sobre o front-end? O front-end, em um processo de compilação, é o responsável pela varredura do sistema, pela análise sintática, pela análise semântica e pela geração do código intermediário. As demais funções são de responsabilidade do back-end, como a geração e a otimização do código alvo. A parte da análise é chamada, na maioria das vezes, de front-end do compilador.Aqui, o programa de origem é dividido em partes constituintes, impondo uma estrutura gramatical a elas. Depois disso, essa estrutura é utilizada na hora de criar uma representação intermediária do programa de origem. (BARBOSA et al., 2021, p. 18). No front-end, o agrupamento das fases e/ou as suas partes dependem, exclusivamente, da linguagem fonte utilizada, pois são independentes do código de máquina. Além das análises citadas, ele pode ajudar na otimização do código intermediário e na manipulação dos erros que surgem ao longo de cada fase da compilação, pois também é realizada a veri�cação de alguns tipos de erro que possam prejudicar o funcionamento dos programas. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 19/40 Caso o programa possua erros que podem ser detectados em tempo de compilação, o front-end pode produzir mensagens, apontando onde eles estão, e, dependendo da situação, indicar uma possível solução. Conhecimento 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 20/40 Teste seus Conhecimentos (Atividade não pontuada) Compilar é um processo que traduz uma codificação realizada em uma linguagem de programação e faz com que ela seja entendida pelo equipamento independente de sua arquitetura (RISC, CISC ou ARM). Para que essa transformação aconteça, o programa (código fonte) é submetido, normalmente, a algumas fases: I. Essa fase identifica sequências dos caracteres da entrada e, posteriormente, produz a sequência de todos os elementos da saída, que são conhecidos como tokens. Essa fase também identifica se os caracteres do arquivo fonte pertencem à linguagem. Para isso, identifica os tokens e ignora todos os comentários e espaços em branco da codificação. Cada token possui a sua classe de símbolos, que são as palavras reservadas, seus delimitadores, identificadores, dentre outros. II. Nessa fase, se identifica a sequência dos símbolos da estrutura, além de englobar as expressões e comandos. Isso é realizado com um processo de varredura, ou parsing, no programa fonte. Depois, é construída a estrutura da árvore de derivação. III. Essa fase verifica a estrutura para a busca de erros, ou seja, a existência de algum erro que seja significativo. Ela verifica se os identificadores declarados possuem compatibilidade com os operadores de expressões, por exemplo. AHO, A. V. et al. Compiladores: princípios, técnicas e ferramentas. São Paulo: Pearson, 2008. Analise os itens I, II e III, referentes às fases de compilação, e escolha a alternativa correta. a) Debug − Análise sintática − Busca binária. b) Código fonte − Análise léxica − Análise sintática. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 21/40 c) Análise sintática − Análise léxica − Debug. d) Código fonte − Análise estrutural − Debug. e) Análise léxica − Análise sintática − Análise semântica. Um compilador é um modelo de análise-e-síntese. Dessa forma, podemos considerar que os módulos iniciais (front-end) são os responsáveis pela tradução de um programa fonte para uma representação (linguagem) intermediária, e os responsáveis pelos módulos �nais (back-end) criam o código objeto �nal. Não podemos esquecer que, para a geração de um código intermediário, é necessário um passo a mais para realizar a tradução. Isso, normalmente, torna o processo mais lento. Mesmo que o programa fonte possa ser traduzido de Estrutura de um compilador – Parte II 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 22/40 forma direta para uma linguagem objeto, a utilização de representações intermediárias, independentemente do tipo de máquina, tem algumas vantagens, como o reaproveitamento de código, que facilita o transporte do compilador para diversas plataformas de hardware diferentes. Sendo assim, apenas os módulos �nais precisam ser refeitos cada vez que forem transportados, pois o otimizador de código é independente da máquina e pode ser usado no código intermediário, em uma máquina abstrata. Quando falamos em representação intermediária, ele deve possuir duas importantes propriedades: facilidade de produção e tradução do programa alvo. A principal diferença entre o código intermediário e o objeto �nal é que não são especi�cados detalhes da máquina alvo, como registradores a serem utilizados, endereços de memória referenciados, dentre outros. Para transformarmos nosso código-fonte em algum código de máquina legível por computador em um formato binário, precisaremos contar com tradutores para nos ajudar a tornar nosso texto-fonte compreensível para nossas máquinas. O compilador é uma espécie de tradutor. (BARBOSA et al., 2021, p. 18). Há tipos de código intermediário que atendem a diversas necessidades de compilação, veja no infográ�co a seguir. Tipos de Código Intermediário 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 23/40 Fonte: alinakvaratskhelia / 123RF. #PraCegoVer: o infográ�co interativo, intitulado “Tipos de Código Intermediário”, apresenta três botões interativos e uma ilustração, todos alinhados verticalmente. O primeiro botão interativo, intitulado “HIR – High Intermediate Representation (Representação Intermediária Alta)”, ao ser clicado, apresenta o texto “É uma linguagem derivada de noções abstratas de línguas imperativas, atualmente predominantes, como C, Fortran, Pascal, Java etc. Existem algumas noções comuns a essas linguagens, como atribuição, declarações, expressões aritméticas, expressões lógicas e assim por diante”. O segundo botão interativo, intitulado “MIR – Medium Intermediate Representation (Representação Intermediária Média)”, ao ser clicado, apresenta o texto “Possui a base para geração de códigos e�cientes, expressa todas as características das linguagens de programação de maneira independente das linguagens de programação (representação de variáveis, arquivos temporários, registradores etc.)”. O terceiro botão interativo, intitulado “LIR - Low Intermediate Representation (Representação Intermediária Baixa)”, ao ser clicado, apresenta o texto “É a representação de uma linguagem que mais se aproxima da linguagem de máquina, linguagem esta que é inteiramente dependente da máquina”. A �gura abaixo dos botões interativos apresenta a ilustração de três pessoas, uma em pé com óculos de realidade virtual, clicando em botões virtuais à sua frente, 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 24/40 além de duas pessoas sentadas, uma com um notebook e a outra interagindo com botões virtuais, também à sua frente. Os códigos intermediários são mais próximos da “linguagem objeto” e permitem a manipulação de forma mais simples do que se fossem códigos assembly e/ou código de máquina. Back-End Você sabia que, no back-end, a árvore sintática é processada para permitir a geração do código alvo e/ou interpretação? Já existem várias linguagens intermediárias implementadas com otimizações e back-ends para diferentes arquiteturas. Nele, o programa destino é construído com base na representação intermediária e nas informações na tabela de símbolos. Alguns compiladores possuem uma fase de otimização entre o front- end e o back-end, independente da máquina. Essa fase tem o intuito de realizar mudanças na representação intermediária, de modo que o back-end possa produzir um programa de destino melhor do que teria produzido de uma representação intermediária não otimizada. (BARBOSA et al., 2021, p. 21). Vale a pena ressaltar que a fase de otimização é opcional e, porisso, pode variar entre os diferentes tipos de compiladores (AHO et al., 2008). A otimização do código é uma passagem opcional do back-end que consiste na geração de códigos para máquinas destino especí�cas. Alguns compiladores foram criados considerando representações intermediárias cuidadosamente projetadas para que permitissem que o front-end de uma linguagem especí�ca �zesse interface com o back-end de uma determinada máquina de destino. A partir disso, é possível produzir compiladores de diferentes linguagens de origem para uma máquina de destino, combinando diferentes front-ends com back-ends. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 25/40 Sendo assim, se várias linguagens de alto nível precisam ser compiladas, apenas a tradução para o código intermediário precisa ser escrita para cada uma das linguagens utilizadas, já que todas podem compartilhar o mesmo back-end. Estudo de caso completo da estrutura de um compilador Para esse estudo de caso, examinaremos a saída de código de montagem produzida por dois diferentes compiladores comerciais para processadores distintos. O primeiro foi o compilador Borland C versão 3.0 (processadores Intel 80×86). O segundo foi o compilador Sun C versão 2.0 (SparcStations). O estudo mostra a saída de montagem dos compiladores para os mesmos exemplos de código, para existir um padrão correto de comparação entre a conversão de código intermediário para o código-alvo (LOUDEN, 2004). A saída dos dois compiladores deve resolver: (x=x+3)+4, assumindo que a variável x será armazenada localmente na pilha. O código de montagem para essa expressão, conforme produzido pelo compilador Borland 3.0 para Intel 80×86, �cou (LOUDEN, 2004, p. 445): mov ax,word ptr [bp-2] add ax,3 mov word ptr [bp-2],ax add ax,4 O código gerado pelo compilador Sun �cou (LOUDEN, 2004, p. 450): ld [%fp+-0x4],%o1 add %o1,0x3,%o1 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 26/40 st %o1,[%fp+-0x4] ld [%fp+-0x4],%o2 add %o2,0x4,%o3 Analisando os códigos gerados, percebemos que, caso seja necessário reconstruir os aplicativos (código fonte), os conjuntos de instruções da CPU SPARC e x86 são bem diferentes. Agora, quando for necessário construir novos aplicativos, a aplicação terá tratamento diferente com a CPU SPARC e/ou X86. Isso poderá ser resolvido com uma compilação cruzada. Compilador x interpretador Você já se perguntou qual a diferença entre um compilador e um interpretador? Enquanto os compiladores analisam todo o código para realizar a tradução de uma só vez, obtendo como resultado, muitas vezes, arquivos executáveis e/ou uma biblioteca, o interpretador realiza esse trabalho de conversão aos poucos, sempre que uma declaração e/ou função é executada, por exemplo. Enquanto um interpretador produz um resultado de um programa, um compilador produz um programa escrito em linguagem Assembly. Dessa forma, o montador (assembler) de arquitetura transforma o programa resultante em código binário. A linguagem Assembly varia para cada computador individual, dependendo de sua arquitetura. (BARBOSA et al., 2021, p. 15). Uma das vantagens dos compiladores é a sua velocidade na execução, pois ele realiza a tradução de todo o código de uma só vez, não necessitando efetuar a conversão toda vez que o sistema é executado, como em um interpretador. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 27/40 A interpretação, por sua vez, pode rodar programas em tempo de execução e de forma independente, por exemplo, não importa se o sistema operacional é Linux e/ou Mac, apenas será necessário possuir o Python instalado na máquina para ela rodar um código em Python. Além disso, a execução em runtime permite examinar e modi�car a estrutura do programa em tempo de execução, que é uma característica básica do PHP. Modi�car o código de uma linguagem interpretada também é mais simples, pois basta abrir o arquivo e modi�cá-lo. Fonte: venimo / 123RF. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 28/40 Dessa forma, para de�nir o uso de linguagens compiladas e/ou interpretadas, é necessário levar em consideração a aplicabilidade que se deseja do programa antes de realizar a escolha (engenharia de software). Veja, na Figura 1.5, as etapas que um programa realiza ao ser compilado e depois executado. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 29/40 Figura 1.5 – Etapas da compilação de um programa Fonte: Adaptada de Etapas (2022, on-line). #PraCegoVer: a �gura apresenta, na parte superior, em um retângulo azul, as palavras “Processador”, “RAM” e “HD” interligadas por uma linha com a palavra “Computador”, que se encontra em um retângulo azul. Do lado esquerdo, há uma retângulo na vertical com o seguinte texto: “Código-fonte é um conjunto de comandos escritos em linguagem de programação que compõem um software, geralmente escrito. Ele funciona como uma lista de tarefas que o desenvolvedor manda o software fazer, onde cada linha escrita de�ne o que e como deve ser feito, seja em um aplicativo, site ou sistema web”. Esse texto aponta para um retângulo azul que �ca dentro do contorno de um quadrado e possui as palavras “Programa fonte”. Do “Programa fonte” sai uma seta que aponta para o retângulo com a palavra “Computador”. Em seguida, há a seguinte sequência de retângulos com setas, indicando para os losangos com as palavras “Há erros?” “Não”, “Programa Objeto”, para outro retângulo com a palavra “Computador”, e para um retângulo azul escrito “Relatório de resultados”, que aponta para um losango com o texto “Análise dos resultados (manual)”. Este, por sua vez, aponta para um quadrado com o texto “Correção de erros de lógica”, estando interligado ao retângulo com a palavra “Código-fonte” por uma linha tracejada. No losango “Há erros?”, há uma derivação para baixo com uma seta para um retângulo azul com as palavras “Relatório de erros”, que aponta para outro retângulo azul com a frase “Correção de erros de sintaxe (manual)”, que possui uma linha tracejada interligando-o ao retângulo “Código-fonte”. Entre os retângulos “Programa Objeto” e “Computador”, há uma seta que vem de um quadro azul com a palavra “Dados do programa”. No losango “Análise dos resultados (manual)”, há uma seta para baixo saindo do quadro, apontado para um retângulo azul com a palavra “Resultado .exe ou .com”. A compilação e/ou interpretação têm muito mais por trás além da conversão do código para a linguagem de máquina. Não há uma “linguagem compilada” ou 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 30/40 “linguagem interpretada” literalmente, apenas algumas possuem essa especi�cação, mas, de forma geral, todas podem passar por esses dois processos. praticar Vamos Praticar Codifique, compile e execute. O CodeChef aceita códigos de mais de trinta e cinco linguagens de programação. Antes de tudo, ele é um site de competição para programadores. Você pode participar dos desafios da competição e/ou praticar nos diversos níveis disponíveis (beginner, easy, medium, hard, challenge e peer). E você ainda consegue desafiar os colegas de sua turma. Compile e execute códigos com o IDE online CodeChef. Esse compilador online suporta várias linguagens de programação, como Python, C++, C, Kotlin, NodeJS, dentre muitas outras. E, após compilar, você consegue baixar o código fonte para fazer a documentação. Vamos praticar, digite o código em Python descritoabaixo na interface do CodeChef. Após inseri-lo (figura a seguir), observe o comportamento do compilador e descreva, no final, o resultado e suas conclusões. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 31/40 #!/usr/bin/python # 20140824 import random dados = [ 'Biclicleta','Televisor','Meia furada' ] print print 'SORTEIO' print print 'Vamos ver o que você ganhou: ' + dados [ random.randrange ( len ( dados ))] Local para inserção do código: https://www.codechef.com/ide https://www.codechef.com/ide 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 32/40 Figura – Tela para digitação de código fonte Fonte: Elaborada pelo autor. #PraCegoVer: a imagem apresenta uma tela da web. Do lado direito, há a palavra “Ide”, e logo abaixo, um box em que se escolhe a linguagem que vamos utilizar. No nosso caso, devemos escolher a palavra “PYTH”. Na mesma linha do box de escolha, há quatro ícones. O primeiro da direita para a esquerda possui a letra i dentro de um círculo e tem a função de informações, o próximo ícone tem uma seta apontando para baixo e, em sua extremidade inferior, um arquivo, que tem a função de baixar o arquivo digitado. O próximo ícone possui uma seta para cima e outra para baixo, que estão na transversal e possuem a função de expandir a tela para a versão full. O último ícone é uma engrenagem e tem como função permitir alterações nas con�gurações. Logo abaixo, há um quadro branco com números na lateral direita, onde se deve inserir o código-fonte. Fora do quadrado, abaixo, há dois retângulos pretos, um com a palavra “Open File” do lado direito e outro, do lado esquerdo, com a palavra “Run”. Você pode digitar o código diretamente na interface ou carregar de um arquivo pela opção “Open File”. Depois, você deve acionar a função “Run” e verificar o resultado na interface “Output” (figura a seguir): 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 33/40 Figura – Tela de resposta Fonte: Elaborada pelo autor. #PraCegoVer: a imagem apresenta um retângulo superior com a frase “Note: Your program will be run with no input”. Abaixo, há outro retângulo com as frases: “Status Successfully executed”, “Date 2022-02-19 17:06:17”, “Time 0,020707 sec”, “Mem 9.472 kB”. Abaixo, há um retângulo maior, na cor amarela, com o cabeçalho à direita com a palavra “Output”. Caso exista algum erro, você pode observá-lo em “Compile Info” e corrigi-lo (figura a seguir): Figura – Tela de erro Fonte: Elaborada pelo autor. #PraCegoVer: a imagem apresenta um retângulo superior com a frase “Note: Your program will be run with no input”. Abaixo, há outro retângulo com as frases “Status Runtime error”, “Date 2022-02-26 22:16:51”, “Time 0,04554 sec”, “Mem 61.492 kB”. Abaixo, há um retângulo maior, na cor amarela, com um cabeçalho à esquerda escrito “Runtime error”, e em seu interior há a palavra “NZEC”. Abaixo, há um retângulo amarelo com um cabeçalho à esquerda escrito “Error”, e dentro dele há a frase “File ‘prog.py’, line 9 print 'SORTEIO^ SyntaxError: EOL while scanning string literal”. 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 34/40 Você pode utilizar a linguagem de programação que mais “domine” e realizar vários testes de compilação. Mãos à obra! 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 35/40 Material Complementar L I V R O Compiladores Autores: Cynthia da Silva Barbosa, Maikon Lucian Lenz, Paulo Sérgio Pádua de Lacerda, Ricardo César Ribeiro dos Santos, Victor de Andrade Machado, Carlos Estevão Bastos Sousa, Nicolli Souza Rios Alves, Rafael Leal Martins, Renata Junges Padilha, Roque Maitino Neto e Vinícius Meyer Editora: Sagah Capítulo: 13 – Organização de memória Ano: 2021 ISBN: 978-65-5690-290-6 Comentário: a memória RAM é um meio-termo entre os registradores que possuem acesso rápido e encontram-se 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 36/40 próximos ao processador e do disco rígido, que armazena de forma persistente os dados, mas que, apesar da grande quantidade de espaço, é muito mais lento. Identi�car a necessidade do processo de alocação e reserva de registros de memória é um fator importante para a compilação. Esse capítulo descreve o processo de alocação estática e dinâmica e diferencia a alocação de memória em stack versus heap. Disponível na Minha Biblioteca. W E B Piratas da Informática: Piratas do Vale do Silício (1999) – Crítica Rápida Ano: 2016 Comentário: assista a uma crítica rápida sobre esse �lme que apresenta como nasceu a informática doméstica. Nele, somos apresentados à criação do primeiro PC (Personal Computer) e à história de desavenças entre a Microsoft, com suas versões do Windows, e a Apple, com seus Macintosh. Esse �lme deixa bem clara a evolução das tecnologias, tanto de hardware como de software, sendo o conteúdo fundamental para os iniciantes na área de programação. ACESSAR https://www.youtube.com/watch?v=VULq1mXJY2E 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 37/40 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 38/40 Conclusão Caro(a) estudante, a construção de um compilador não é uma tarefa simples, ela requer muito estudo e conhecimento técnico especí�co. Para se obter bons resultados, as limitações das máquinas também devem ser levadas em consideração, mesmo que algumas possam ser resolvidas pelo software. Atualmente, há diversas formas de se implementar um compilador, e uma vasta bibliogra�a sobre a gramática das linguagens como C, SQL e Java, dentre outras ferramentas que possibilitam uma imersão direta no mundo dos compiladores a nível das arquiteturas computacionais, melhorando a qualidade de software produzido. Dessa forma, o conhecimento gerado pela implementação de um compilador é um diferencial para os pro�ssionais de tecnologia. Referências AHO, A. V. et al. Compiladores: princípios, técnicas e ferramentas. São Paulo: Pearson, 2008. BARBOSA, C. R. S. C.; FARIA, C. R.; CAMPANO JUNIOR, M. M. Análise de ferramentas de compiladores em ambientes virtualizados. Revista Brasileira de Informática na Educação, 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 39/40 Porto Alegre, v. 29, p. 1262-1290, 2021. Disponível em: https://www.br- ie.org/pub/index.php/rbie/article/view/9368. Acesso em: 28 fev. 2022. BARBOSA, C. S. et al. Compiladores. Porto Alegre: Sagah, 2021. CODE, Compile & Run. Codechef, [2022]. Disponível em: https://www.codechef.com/ide. Acesso em: 15 fev. 2022. ETAPAS de processamento de um programa. Departamento de Informática e Estatística – UFSC, [2022]. Disponível em: https://www.inf.ufsc.br/~j.barreto/cca/arquitet/arq5.htm. Acesso em 15 fev. 2022. FERREIRA, C. A. Linguagem e compilador para o paradigma orientado a noti�cações (PON): avanços e comparações. Orientador: Jean Marcelo Simão. 2015. 245 f. Dissertação (Mestrado em Computação Aplicada) – Universidade Tecnológica Federal do Paraná, Curitiba, 2015. LANGLOIS, T.; SANTOS, P. R. Compiladores: da teoria à prática. Rio de Janeiro: LTC, 2018. LOUDEN, K. C. Compiladores: princípios e práticas. São Paulo: Cengage Learning, 2004. MARANGON, J. D. Compiladores para humanos.GitBook, [2022]. Disponível em: https://johnidm.gitbooks.io/compiladores-para-humanos/content/. Acesso em: 12 fev. 2022. MENEZES, P. B. Linguagens formais e autômatos. Porto Alegre: Bookman, 2011. PIRATAS da Informática: Piratas do Vale do Silício (1999) – Crítica Rápida. [S. l.: s. n.], 2016. 1 vídeo (4 min.). Publicado pelo canal Carlo Chim. Disponível em: https://www.youtube.com/watch?v=VULq1mXJY2E. Acesso em: 22 mar. 2022. https://www.br-ie.org/pub/index.php/rbie/article/view/9368 https://www.codechef.com/ide https://www.inf.ufsc.br/~j.barreto/cca/arquitet/arq5.htm https://johnidm.gitbooks.io/compiladores-para-humanos/content/ https://www.youtube.com/watch?v=VULq1mXJY2E 11/06/2023, 19:17 E-book https://student.ulife.com.br/ContentPlayer/Index?lc=e6IUL5ncVpNnpafasMtHtw%3d%3d&l=1OdIzZ8xcachsr3pzfvcBA%3d%3d&cd=euiSKCRHJrkiU… 40/40