diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..759adc1 --- /dev/null +++ b/.gdb_history @@ -0,0 +1,40 @@ +q +file AT +break geraTabela +r 'abcdefghijklmnopqrstuvwxyzABCDEFGH' +n +n +n +n +c +r 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL' +n +n +n +n +n +n +n +n +n +n +n +n +n +q +file AT +break imprimeArcos +r 'abcdefghijklmnopqrstuvwxyzABCDEFGH' +n +break transicoes.c:19 +c +n +c +c +n +q +c +c +n +q +q diff --git a/Makefile b/Makefile index 42e45f5..fc006d1 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ else endif CC := gcc -CFLAGS := -Wall -Wextra -std=c11 -Isrc +CFLAGS := -Wall -Wextra -std=c11 -Isrc $(ARQUIVO): transicoes.o eval.o parser.o main.o inputproc.o $(CC) $^ -o $@ $(LIBS) diff --git a/README.md b/README.md index 4b17a15..2619157 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,17 @@ # AT -Calculadora de arcos de transição desenvolvida em C. +Calculadora de arcos de transição desenvolvida em C. Inclui um parser e um avaliador de expressão booleana. +A entrada deve ser uma soma de produtos, composta por caracteres maiúsculos ou minúsculos do alfabeto latino. Exemplo: `'a*b + !a*c'` +Observação: o programa não verifica limites teóricos de execução, porém, observe que armazenar uma tabela verdade requer espaço `2^n` bytes, em que `n` representa a quantidade de variáveis atômicas. ## Como utilizar ### No Linux é necessário ter o `git` e o `gcc` instalados -1) faça `clone` do repositório +1) faça `clone` do repositório e acesse o diretório `AT` ``` $ git clone https://github.com/gckneip/AT.git +$ cd AT ``` 2) compile ``` @@ -16,16 +19,17 @@ $ make ``` 3) execute o programa, passando a expressão booleana como argumento de execução -**OBS:** utilize aspas simples +**OBS:** utilize aspas simples para evitar o processamento indevido do caracter "!" ``` $ ./AT 'a*b+!a*c' ``` ### No Windows é necessário ter o `git` e o `minGW` instalados e configurados na variavel `PATH` do sistema -1) faça `clone` do repositório +1) faça `clone` do repositório e acesse a pasta `AT` ``` $ git clone https://github.com/gckneip/AT.git +$ cd AT ``` 2) compile ``` @@ -33,7 +37,7 @@ $ mingw32-make ``` 3) execute o programa, passando a expressão booleana como argumento de execução -**OBS:** utilize aspas simples +**OBS:** utilize aspas simples para evitar o processamento indevido do caracter "!" ``` $ ./AT 'a*b+!a*c' ``` diff --git a/gdb-split.sh b/gdb-split.sh new file mode 100755 index 0000000..3c43376 --- /dev/null +++ b/gdb-split.sh @@ -0,0 +1,11 @@ +#!/bin/zsh + +gdb-tmux() { + local id="$(tmux split-pane -hPF "#D" "tail -f /dev/null")" + tmux last-pane + local tty="$(tmux display-message -p -t "$id" '#{pane_tty}')" + gdb -ex "dashboard -output $tty" "$@" + tmux kill-pane -t "$id" +} + +gdb-tmux diff --git a/src/eval.c b/src/eval.c index 1c29ca3..ec8feac 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1,12 +1,21 @@ #include "eval.h" #include "estruturas.h" #include +#include unsigned char *geraTabela(Nodo *arvore, int quantasEntradas, char *entradas) { - unsigned long int tamanhoVetor = 1 << quantasEntradas; + unsigned long int tamanhoVetor = 1ULL << quantasEntradas; unsigned char *tabelaVerdade = calloc((tamanhoVetor),sizeof(unsigned char)); // inicia o vetor de resultados com 2^n - for (unsigned int i = 0; i < tamanhoVetor; i++) { + if (tabelaVerdade == NULL) { + puts("Falha na alocação da tabela verdade."); + exit(-1); + } + + // FOR DEBUGGING PURPOSES ONLY: retornar o vetor com antecedência pra fazer um ablubluble no transicoes.c + // return tabelaVerdade; + + for (unsigned long int i = 0; i < tamanhoVetor; i++) { tabelaVerdade[i] = percorreArvore(arvore, entradas, quantasEntradas, i); } @@ -29,7 +38,7 @@ unsigned char procuraZero(Nodo *raiz, char *variaveis, int quantasEntradas, unsi int i, j; unsigned long int bit; for (i = 0; i < raiz->quantosFilhos; i++) { - if (raiz->filhos[i]->conteudo >= 'a' && raiz->filhos[i]->conteudo <= 'z') { + if ((raiz->filhos[i]->conteudo >= 'a' && raiz->filhos[i]->conteudo <= 'z') || (raiz->filhos[i]->conteudo >= 'A' && raiz->filhos[i]->conteudo <= 'Z')) { for (j = 0; j < quantasEntradas; j++) { if (variaveis[j] == raiz->filhos[i]->conteudo) { bit = quantasEntradas - j - 1; diff --git a/src/inputproc.c b/src/inputproc.c index 52236a9..b69f304 100644 --- a/src/inputproc.c +++ b/src/inputproc.c @@ -22,7 +22,7 @@ int processaVariaveis(char *entrada, char ** saidaLista) { char c; Lista *itemAnterior, *novoItem; for (i = 0; ((c = entrada[i]) != '\0'); i++) { - if (c >= 'a' && c <= 'z') { + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { for (itemAnterior = lista; ((itemAnterior->proximo != NULL) && (itemAnterior->proximo->conteudo < c)); itemAnterior = itemAnterior->proximo); diff --git a/src/main.c b/src/main.c index 8cd0c58..d212e01 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,4 @@ int main(int argc, char *argv[]) { free(tabelaVerdade); } return EXIT_SUCCESS; - - return 0; } diff --git a/src/parser.c b/src/parser.c index 8fe814c..636ad33 100644 --- a/src/parser.c +++ b/src/parser.c @@ -94,7 +94,7 @@ Nodo* criaArvore(char * entrada){ pilhaPush(operadores, novoNodo); } - if (c >='a' && c <= 'z'){ + if ((c >='a' && c <= 'z') || (c >= 'A' && c <= 'Z')){ novoNodo = criaNodo(c); if (operadores->tamanho > 0 && operadores->nodos[operadores->tamanho-1]->conteudo == '!'){ adicionaFilho(operadores->nodos[operadores->tamanho-1], novoNodo); diff --git a/src/transicoes.c b/src/transicoes.c index c912058..55f9f45 100644 --- a/src/transicoes.c +++ b/src/transicoes.c @@ -4,29 +4,32 @@ void imprimeArcos (unsigned char * tabelaVerdade, char * operandos, int quantosOperandos){ - int peso, i, j, k, l = 0; - long unsigned int indiceTabela = 0; + unsigned long int peso, i, j, l = 0; + int k; + unsigned long int indiceTabela = 0, indiceTabelaArco; + unsigned long int tamanhoVetor = quantosOperandos - 1ULL; - char *arco = calloc(sizeof(char), quantosOperandos+1); + char *arco = calloc(sizeof(char), quantosOperandos+1ULL); if (arco == NULL){ fputs("Nao foi possivel alocar memoria para a tabela verdade", stderr); exit(EXIT_FAILURE); } - for (i = 0; i < quantosOperandos; i++) { - for (j = 0; j < (1 << (quantosOperandos - 1)); j++) { - for (k = quantosOperandos-1; k >= 0; k--) { - peso = (quantosOperandos - 1) - k; - if (k != i) { - indiceTabela += ((j & 1 << l) >> l) * (1 << peso); //faz o l - arco[k] = '0' + ((j & 1 << l) >> l); + for (i = 0; i < (unsigned long int)quantosOperandos; i++) { + for (j = 0; j < (unsigned long int)(1ULL << tamanhoVetor); j++) { + for (k = quantosOperandos - 1; k >= 0; k--) { + peso = (quantosOperandos - 1ULL) - k; + if ((unsigned int)k != i) { + indiceTabela += ((j & 1ULL << l) >> l) * (1ULL << peso); //faz o (UL)l + arco[k] = '0' + ((j & 1ULL << l) >> l); l++; continue; } arco[k]=operandos[i]; } - if(tabelaVerdade[indiceTabela] != tabelaVerdade[indiceTabela + (1 << ((quantosOperandos - 1) - i))]){ + indiceTabelaArco = indiceTabela + (unsigned long int)(1ULL << (tamanhoVetor - i)); + if(tabelaVerdade[indiceTabela] != tabelaVerdade[indiceTabelaArco]){ printf("%s\n", arco); } l = 0;