Neste tutorial estarei abordando a implementação de um interpretador de brainfuck, tendo ênfase em abrir arquivos, interpretar argumentos da linha de comando e interpretar comandos de byte único de uma linguagem, usando a linguagem C/C++ (será compatível com ambas as linguagens). O código fonte foi testado no Linux e no Windows, e provavelmente também funcionará em outros sistemas.
Introdução
Este é meu primeiro tutorial para o meu blog, e tentarei explicar passo-a-passo a implementação de um interpretador simples, ainda que completo. Eu escolhi a linguagem brainfuck por ser uma linguagem conhecida e simples. Estarei usando o compilador GCC/MinGW e um editor de texto simples. Caso esteja usando o Windows e não saiba como instalar um compilador, baixe o Code::Blocks, um ambiente de desenvolvimento integrado que já vem com o MinGW pronto para uso.
Etapa 1
Abra um editor de texto não-formatado de sua preferência (como o Bloco de Notas do Windows, ou o Code::Blocks) e, comece escrevendo a função principal:
int main()
{
}
Depois disso, declare os parâmetros da função main()
, o contador (argc
) e a sequência de argumentos (argv
), e adicione a função getchar()
, para impedir que o programa se encerre automaticamente (isso não será necessário se você estiver usando o Code::Blocks), seguido do comando de retorno (return
). Não esqueça de incluir a biblioteca stdio.h, onde se encontra a declaração da função getchar()
. Ficará assim:
#include <stdio.h>
int main(int argc, char *argv[])
{
int c;
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 0;
}
O parâmetro argc
é um inteiro que conta quantos argumentos existem na linha de comando, incluindo o endereço do programa, e o argv
é uma matriz com todos os argumentos da linha de comando. Se argc
for igual a 2, o argv
será {"programa", "argumento 2"}
. Se argc
for igual a 1, o argv
será {"programa"}
.
O loop "do" repete até uma determinada condição ser atingida, que neste caso é o usuário retornar uma quebra-de-linha ('\n'
, pressionando Enter) ou fim-de-arquivo (EOF
, pressionando Ctrl+Z).
Por fim, o comando return
retorna um valor inteiro para o sistema, que determina se o programa terminou bem (se retornar um valor igual a zero) ou não (se retornar um valor diferente de zero). Por convenção, é sempre deixada uma nova linha vazia, depois de fechar a função principal, mas isso não é obrigatório.
Agora que a base do programa está pronta, podemos começar. Declare um ponteiro do tipo FILE
, chamado de arquivo. Adicione uma condição, para verificar a quantidade de argumentos e, dentro da condição, use a função fopen()
para abrir o arquivo especificado pela linha de comando. Em seguida, adicione uma condição para verificar se o arquivo foi aberto com sucesso.
#include <stdio.h>
int main(int argc, char *argv[])
{
int c;
FILE *arquivo; // Deve-se usar o asterisco aqui, por ser ponteiro
if (argc >= 2) // Se tiver 2 ou mais argumentos
{
arquivo = fopen(argv[1], "rb"); // Abre o arquivo especificado
if (arquivo == NULL) // Se não conseguir abrir o arquivo
{
puts("ERRO: Não foi possível abrir o arquivo!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1; // Encerra o programa
}
}
else
{
return 0; // Encerra o programa
}
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 0;
}
É muito importante verificar se o programa conseguiu abrir o arquivo, pois se não verificado, pode gerar problemas e fazer o programa encerrar de forma abrupta. Eu instruí o programa a abrir o arquivo indicado pelo segundo item da matriz argv
(em C, o primeiro item é indicado por zero, o segundo por um, o terceiro por dois, e daí por diante). O primeiro item dessa matriz é o endereço do programa.
0 comentários:
Postar um comentário