Compilador de LP3 para C3E e P3 Luı́s Gil1 13 de Junho de 2005 1 estudante de Ciências Informáticas no Instituto Superior Técnico 1 Introdução Este relatório descreve a sintaxe e a semântica da Linguagem de Programação LP3, uma linguagem académica utilizada no estudo dos Compiladores e Processadores de Linguagens, e a utilização de um compilador desta linguagem que gera código intermédio C3E ou assembly para o processador, também pedagógico, P3. Parte deste compilador foi feito no âmbito do projecto da disciplina de Compiladores em conjunto com o colega Carlos Tamulonis, enquanto que o gerador de assembly para o P3 resulta de um trabalho extra-curricular meu. Este documento é uma adaptação do relatório original do projecto de Compiladores, limitando-se apenas à descrição da linguagem LP3 e ao uso do compilador. 2 Linguagem LP3 2.1 Breve Descrição A linguagem LP3 é muito simples e a sua utilidade é limitada a fins académicos. Permite programar apenas dentro do paradigma imperativo e a estrutura dum programa pode ser visto informalmente como a declaração de variáveis seguida por uma sequência de instruções que pode incluir comandos de diferimento e de ciclo. A definição de funções/procedimentos não é suportada, logo só se podem usar as (os) funções (operadores) primitivas (os) da linguagem. A linguagem suporta apenas os tipos de dados inteiro e cadeia de caracteres e só os inteiros podem ser usados em expressões e atribuı́dos a variáveis. As cadeias de caracteres são utilizadas apenas para output para o ecrã. Não é possı́vel definir novas estruturas de dados. A linguagem LP3 disponibiliza as operações de soma, subtracção, produto e quociente. Estas expressões são representadas pelos operadores +, -, * e / respectivamente. São suportados os testes de igualdade, diferença, maior, menor, maior ou igual e menor ou igual, por =, <>, >, <, ≤, ≥ respectivamente. O valor lógico ’verdadeiro’ é representado por ’1’, e o falso por qualquer inteiro diferente de ’1’. 2.2 Instruções • Atribuição de uma expressão (aritmétrica ou relacional) a uma variável, denotada pelo operador ’<-’. • Troca dos valores de duas variáveis através do operador ’<->’. • Leitura de valores numéricos a partir do teclado para uma variável, através da instrução ’RD’. • Escrita para o ecrã de valores de variáveis e de cadeias de caracteres. As cadeias de caracteres devem estar limitadas por pontos de exclamação, através da instrução WRT. Para escrever o ponto de exclamação usa-se !! • Ciclo de repetição representado por ’WHILE (expressão) código’. 1 • Execução condicional ’IF expressão THEN código ELSE código’. A instrução ELSE existe sempre, podendo o código desta ser a instrução nula. • Bloco de código representado por ’CODE código END’. • Instrução nula, correspondente simplesmente ao ponto e vı́rgula. • Comentários até ao fim da linha iniciados por ’--’. Acima, código denota uma instrução ou um bloco de instruções 2.3 Estrutura de um programa Um programa possui a estrutura Cabeçalho Corpo Fim. O Cabeçalho consiste na palavra chave PROGRAM seguida de um identificador a indicar o seu nome e o sinal de pontuação dois pontos (:). Este identificador vai ser o nome do ficheiro de saı́da com o código compilado. De seguida declaram-se as variáveis (se existirem) utilizadas através da palavra chave VAR, cujos nomes são separados por uma vı́rgula. O Corpo consiste numa sequência de instruções delimitada pelas palavras chave CODE e END, e cada instrução termina com um ponto e vı́rgula. O Fim consiste simplesmente num ponto final. 2.4 Exemplos O clássico Hello World PROGRAM HelloWorld: --Cabeçalho CODE WRT !Hello world!; --Corpo END. --fim 2 Programa que calcula a raiz quadrada inteira de um número: PROGRAM RaizInteira: VAR n, z, i, op CODE -- isto é um comentário. É ignorado tudo até ao fim da linha -- A raiz quadrada inteira é computável -- A raiz quadrada é o maior inteiro menor ou igual à raiz -- SQRT(n)=z ==> (z+1)^2 > n -- SQRT(n) = menor z < n tal que (z+1)^2 > n op <- 1; --opcao para sair do programa. O programa termina quando op n~ ao valer 1 WHILE (op) CODE WRT !Calculo da raiz quadrada inteira!; WRT !Introduza o numero:!; RD n; IF n >= 0 THEN CODE i<-0; WHILE(i < n)CODE IF (i+1)*(i+1) > n THEN CODE z <- i; -- encontramos o resultado i <- n+1; -- para sair do ciclo END; ELSE i <- i + 1; END; -- fim do while WRT !A raiz inteira de !, n, ! = !, z; END; --fim do then ELSE ; --n~ ao diz nada se o n for menor que 0 WRT !Outra conta (1) ou Sair (0)!; RD op; END; -- Fim do WHILE exterior END. 3 Cálculo do factorial de um número: PROGRAM factorial: VAR num, i, fact, op CODE op<-1; WHILE(op) CODE fact <- 1; WRT !Introduza o valor!; RD num; --olá olá olá olá i<-num; WHILE (i>1) CODE fact<- fact*i; i<- i-1; END; WRT !Factorial de !, num, ! = !, fact; WRT !Outra conta (1) ou Sair (0)!; RD op; END; END. 3 Compilador O compilador é para o sistema operativo Linux. Antes de utilizar o programa há que descompactá-lo através do comando tar: tar xf LP3.tar Depois compile-o fazendo make É criado um executável chamado LP3. Para compilar um ficheiro basta digitar na linha de comandos: ./LP3 ficheiro [-p3] A opção -p3 é usada quando se pretende que o resultado seja um ficheiro com o assembly do processador P3. Se esta opção não for indicada, o resultado será um ficheiro com código C3E. 4 Execução dos programas compilados Para executar os programas gerados pelo compilador há que proceder da seguinte maneira: 4.1 Código C3E Para executar um ficheiro com código C3E, basta invocar o interpretador c3e e passar como argumento o nome do ficheiro: c3e ficheiro 4 4.2 Código para P3 Para executar o código no simulador do P3, há que compilar o ficheiro com o assembler p3as (p3as ficheiro) de modo a obter um ficheiro de extensão .exe que contém o código máquina. Depois inicie o simulador digitando p3SimTcl p3sim na linha de comandos e carregue o ficheiro executável. Figura 1: Abertura de ficheiro executável De seguida abra a janela de texto no menu Ver, mande correr o programa pressionando Corre e seleccione de novo a anterior janela, para interagir com este. 5 Figura 2: Janela de Input-Output Algumas notas acerca da leitura de números: Após escrever o número pressione a tecla Enter para confirmar a introdução. Não é possı́vel corrigir os valores dados. Cada número pode ter no máximo cinco algarismos e está limitado superiormente por 65535 e inferiormente por 0. Caso o número introduzido tenha cinco dı́gitos a leitura termina automáticamente sem necessitar de teclar Enter. Figura 3: Uso do programa 6