#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "token.h"
#include "pila.h"
#include "lista.h"
#include "posfija.h"
void imprimir(void *a)
{
printf("Token: %s [%s]\n",strToken[((TToken *)a)->tipo],((TToken *)a)->token);
}
void imprimirVar(void* a) {
printf("memoria\n");
}
int main()
{
system("clear");
system("cls");
char cadena[256], * actual;
double resultado=0;
TToken *p;
TLista *listaPosfija = nuevaLista(sizeof(TToken));
TLista *listaInfija = nuevaLista(sizeof(TToken));
TLista *memoria = nuevaLista(sizeof(TVariable));
printf("Uso: \nIntroduzca una expresion aritmetica\nPor ejemplo: x = -2+20^(2/23+2)+36.56\n");
printf("Operadores validos: + - * / ^ =\nAcepta expresiones parentizadas() y variables\n");
printf("vars: muestra la memoria\nexit: termina el programa\n\n");
while (1)
{
printf(">>");
fgets(cadena, 256, stdin);
actual = cadena;
while ((*actual == ' ') || (*actual == '\n') || (*actual == '\t'))
actual++;
if (*actual == '\0')
continue;
printf("(main) Actual: %s", actual);
if (strcmp(cadena, "exit\n") == 0) {
printf("Adios\n");
break;
}
if (strcmp(cadena, "vars\n") == 0) {
if (listaVacia(memoria)==0)
printf("Memoria vacia\n\n");
else {
itera(memoria, imprimirVar);
printf("Bucle-Memoria\n\n");
}
}
else {
p = token(cadena);
while (p != NULL) {
agregarNodo(listaInfija, p);
p = token(NULL);
}
printf("Lista Infija:\n");
itera(listaInfija, imprimir);
listaPosfija = posfija(listaInfija);
printf("Lista Posfija:\n");
itera(listaPosfija, imprimir);
resolver(listaPosfija,memoria);
liberar(listaInfija);
liberar(listaPosfija);
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "posfija.h"
#include "token.h"
#include "pila.h"
#include "lista.h"
//POSTFIX.C
int precedencia(char *c)
{
if (*c == '^')
{
return 4;
}
if (*c == '*' || *c == '/')
{
return 3;
}
if (*c == '-' || *c == '+')
{
return 2;
}
return 0;
}
TLista* posfija(TLista* lis) {
TPila* s = nuevaPila(sizeof(TToken), 60);
TLista* listaposfija = nuevaLista(sizeof(TToken));
TToken* info, * tope, * info2;
TNodo* p = lis->h;
info = malloc(lis->tamInfo);
tope = malloc(sizeof(TToken));
info2 = malloc(lis->tamInfo);
while (p != NULL) {
memcpy((void*)info, p->dato, lis->tamInfo);
if (info->tipo == numero || info->tipo == variable)
agregarNodo(listaposfija, (void*)info);
else if (*(info->token) == '(')
push(s, (void*)info);
else if (*(info->token) == ')') {
top(s, (void*)tope);
while (*(tope->token) != '(') {
pop(s, (void*)info);
agregarNodo(listaposfija, (void*)info);
top(s, (void*)tope);
}
if (*(tope->token) == '(') {
pop(s, (void*)info);
}
else {
printf("Se ha detectado un error"); //Error
exit(0);
}
}
else if (info->tipo == operador) {
top(s, (void*)tope);
while (!vacia(s) && *(tope->token) != '(' && precedencia(tope->token) >= precedencia(info->token)) {
pop(s, (void*)info2);
agregarNodo(listaposfija, (void*)info2);
top(s, (void*)tope);
}
push(s, (void*)info);
}
p = p->sig;
}
while (!vacia(s)) {
pop(s, (void*)info);
agregarNodo(listaposfija, (void*)info);
}
return listaposfija;
}
TPila* resolver(TLista* listaPosfija,TLista* memoria) {
TPila* pila = nuevaPila((sizeof(TToken)), 9999);
TNodo* q = listaPosfija->h;
char *ax1 = malloc(20), *ax2 = malloc(20);
char* guarda, * temp;
char j[20];
double d1, d2;
static double r;
while (q!=NULL) {
if (((TToken*)(q->dato))->tipo == variable || ((TToken*)(q->dato))->tipo == numero) {
guarda = (char*)(((TToken*)(q->dato)))->token;
push(pila, guarda);
}
if (((TToken*)(q->dato))->tipo == operador) {
temp = (char*)(((TToken*)(q->dato)))->token;
if (*((TToken*)(q->dato))->token == '+') {
pop(pila, ax1);
strcpy(j, ax1);
d1 = atof(j);
pop(pila, ax2);
strcpy(j, ax2);
d2 = atof(j);
r = d2 + d1;
sprintf(j, "%f", r);
//printf("d2,d1,r: %lf + %lf = %lf\n", d2, d1, r);
push(pila, j);
}
if (*((TToken*)(q->dato))->token == '-') {
pop(pila, ax1);
strcpy(j, ax1);
d1 = atof(j);
pop(pila, ax2);
strcpy(j, ax2);
d2 = atof(j);
r = d2 - d1;
sprintf(j, "%f", r);
//printf("d2,d1,r: %lf - %lf = %lf\n", d2, d1, r);
push(pila, j);
}
if (*((TToken*)(q->dato))->token == '*') {
pop(pila, ax1);
strcpy(j, ax1);
d1 = atof(j);
pop(pila, ax2);
strcpy(j, ax2);
d2 = atof(j);
r = d2 * d1;
sprintf(j, "%f", r);
//printf("d2,d1,r: %lf * %lf = %lf\n", d2, d1, r);
push(pila, j);
}
if (*((TToken*)(q->dato))->token == '/') {
pop(pila, ax1);
strcpy(j, ax1);
d1 = atof(j);
pop(pila, ax2);
strcpy(j, ax2);
d2 = atof(j);
r = d2 / d1;
sprintf(j, "%f", r);
//printf("d2,d1,r: %lf / %lf = %lf\n", d2, d1, r);
push(pila, j);
}
if (*((TToken*)(q->dato))->token == '^') {
pop(pila, ax1);
strcpy(j, ax1);
d1 = atof(j);
pop(pila, ax2);
strcpy(j, ax2);
d2 = atof(j);
r = pow(d2, d1);
sprintf(j, "%f", r);
//printf("d2,d1,r: %lf ^ %lf = %lf\n", d2, d1, r);
push(pila, j);
}
}
q=q->sig;
}
printf("Resultado= %lf\n", r);
return pila;
}
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include "nodo.h"
//NODE.C
TNodo *creaNodo(void *dato,int tam) //Create Node
{
TNodo *n;
n = malloc(sizeof(TNodo)*tam);
n->dato=malloc(tam);
memcpy(n->dato,dato,tam);
n->sig = NULL;
return n;
}
void liberaNodo(TNodo *nodo) //Free node
{
free(nodo->dato);
free(nodo);
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "pila.h"
// STACK.C
TPila* nuevaPila(int tamDato, int maxDatos) //new stack
{
int k;
TPila *p = malloc(sizeof(TPila));
p->tos = -1;
p->tamDato = tamDato;
p->maxDatos = maxDatos;
p->pila = malloc(maxDatos * sizeof(void*));
for (k = 0; k < p->maxDatos; k++)
p->pila[k] = malloc(tamDato);
p->tos = -1;
return p;
}
int vacia(TPila *pila) //empty (stack)
{
if (pila->tos == -1)
return 1;
return 0;
}
int llena(TPila* pila) //full (stack)
{
return pila->tos >= pila->maxDatos-1;
}
void push(TPila* pila, void* valor) //push (stack)
{
if (!llena(pila)) {
pila->tos = pila->tos+1;
memcpy(pila->pila[pila->tos],valor,pila->tamDato);
return ;
}else if(llena(pila)){
printf("Stack overflow: ERROR\n");
exit(0);
}
return ;
}
void pop(TPila* pila, void* dato) //pop (stack)
{
if (!vacia(pila)) {
pila->tos = pila->tos -1;
memcpy(dato,pila->pila [pila->tos+1],pila->tamDato);
return;
}else if(vacia(pila)){
printf("Error: Stack underflow\n");
exit(2);
}
}
void top(TPila* pila, void* tope) //top (stack)
{
if (vacia(pila) == 1)
return;
memcpy(tope, pila->pila[pila->tos], pila->tamDato);
}
void liberaPila(TPila* pila) //free (stack)
{
int k;
for (k = 0; k < pila->maxDatos; k++)
free(pila->pila[k]);
free(pila);
}
void imprimePila(TPila* pila, void (*funcion)(void* intfo)) //printStack
{
int k;
printf("\ntope = %d \n",pila->tos); //peek
printf("Tam. de la informacion %d (bytes)\n", pila->tamDato); //info size
printf("Tam. de la pila: %d (elementos)\n", pila->maxDatos); //elements (stack)
for (k = 0; k < (pila->tos+1); k++) {
printf("[%3d] = ", k);
funcion(pila->pila[k]);
printf("\n");
}
printf("\n");
}
#include<stdio.h>
#include"lista.h"
#include<stdlib.h>
#include <string.h>
//list.c
TLista *nuevaLista(int tamInfo) //new list
{
TLista* lista;
lista = malloc(sizeof(TLista)*tamInfo);
lista->h = lista->t = NULL;
lista->tamInfo=tamInfo;
return lista;
}
void agregarNodo(TLista *lis, void *info) //add node
{
TNodo* q = NULL;
q=creaNodo(info,lis->tamInfo);
if (listaVacia(lis) == 0) {
lis->h = lis->t = q;
return;
}
lis->t->sig=q;
lis->t = q;
}
void retirarNodo(TLista *lis, void *info) //remove node
{
TNodo *p;
if(lis->h == NULL){
return;
}
if (lis->h == lis->t) {
free(lis->h);
lis->h = lis->t= NULL;
return;
}
p = lis->h;
lis->h = lis->h->sig;
free(p);
p= NULL;
return ;
}
int listaVacia(TLista *lis) //empty list
{
if (lis->h==NULL){
return 0;
}
return 1;
}
void itera(TLista *lis,void (*funcion)(void *info) ) //iterate
{
TNodo* p = NULL;
p=lis->h;
while(p!=NULL){
funcion(p->dato);
p=p->sig;
}
}
void liberar(TLista* lis) //free
{
free(lis->h->dato);
lis->h = NULL;
}
//search node (for variables, not fully implemented yet)
void *buscarNodo(TLista *lis, void *info,int (*compara)(void *a, void *b) )
{
TNodo *p;
p = lis->h;
while (p != NULL){
if (compara(p->dato, info)==0)
return p->dato;
p = p->sig;
}
return 0;
}
#ifndef PILA_H_INCLUDED
#define PILA_H_INCLUDED
//stack.h
typedef struct { //struct for TStack
void **pila;
int maxDatos;
int tamDato;
int tos;
} TPila;
TPila *nuevaPila(int tamDato, int maxDatos); //newStack
int vacia(TPila *pila); //empty
int llena(TPila *pila); //full
void pop(TPila *pila, void *dato);
void push(TPila *pila, void *valor);
void top(TPila* pila, void* tope);
void liberaPila(TPila* pila); //freeStack
void imprimePila(TPila* pila, void (*funcion)(void* intfo)); //printStack
#endif // PILA_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "token.h"
char strToken[][11] = {"Variable", "Parentesis","Operador", "Numero","Unario"};
int esOperador(char c)
{
int k;
static char operadores[] = "+-*/^";
int l = strlen(operadores);
for (k=0; k<l; k++)
if (c == operadores[k])
return 1;
return 0;
}
int esParentesis(char c)
{
if (c=='(' || c==')')
return 1;
return 0;
}
TToken *token(char *s)
{
static char cadena[1000];
static char* actual, *auxiliar;
int k;
char res[1000], st='0';
int a=-1;
TToken *unToken=NULL;
a++;
if (s != NULL) {
strcpy(cadena,s);
actual = cadena;
}
while ((*actual == ' ') || (*actual =='\n') || (*actual=='\t'))
actual++;
if (*actual == '\0')
return NULL;
/*
int sz = strlen(cadena);
char* aux = (char*)malloc(sz + 2);
strncpy(aux, st,2);
aux[2] = '\0';
strcat(aux, cadena);
printf("aux:'%s'\n", aux);
*/
printf("******actual: %s | cadena: %s*****\n", actual,cadena);
//Este funciona a veces cuando hay paréntesis antes del menos: (-3+4) por ejemplo, A VECES FUNCIONA BIEN.
//En expresiones más largas no llega a funcionar del todo como (-2-2*(-2)) :/
if (actual[a] == '-' || actual[0] == '-') {
printf("**************************menos encontrado\n\n");
if (actual[a - 1] == '(') {
actual[a - 1] = '0';
actual = cadena;
}
if (!actual[a-1]) {
printf("***********************principio....\n");
actual[a] = '0';
auxiliar = cadena;
actual[a + 1] = '-';
actual = cadena;
// printf("actual[a]: %c\nactual[a-1]: %c\n\n", actual[a], actual[a - 1]);
}
}
/*
if (actual[a] == '-' && (isdigit(actual[a + 1])))
if (!actual[a - 1]) {
strcpy(auxiliar, actual);
printf("11********\nauxiliar: %s\nactual: %s\n\n", auxiliar, actual);
cadena[0] = '0';
cadena[1] = *auxiliar;
printf("********\nauxiliar: %s\nactual: %s\n\n",auxiliar,cadena);
}
*/
if ( (esOperador(*actual) == 1) ) {
res[0] = *actual;
res[1] = '\0';
unToken=malloc(sizeof(TToken));
unToken->tipo=operador;
strcpy(unToken->token,res);
actual = actual + 1;
return unToken;
} else if ( (esParentesis(*actual) == 1) ) {
res[0] = *actual;
res[1] = '\0';
unToken=malloc(sizeof(TToken));
unToken->tipo=parentesis;
strcpy(unToken->token,res);
actual = actual + 1;
return unToken;
} else if (isdigit(*actual) || (*actual=='.')) {
k = 0;
while ( (*actual != '\0') && (isdigit(*actual) || *actual == '.' ) ) {
res[k] = *actual;
actual = actual + 1;
k = k+1;
}
res[k] = '\0';
unToken=malloc(sizeof(TToken));
unToken->tipo=numero;
strcpy(unToken->token,res);
return unToken;
} else if (isalpha(*actual)) {
k = 0;
while ( (*actual != '\0') && isalpha(*actual)) {
res[k] = *actual;
actual = actual + 1;
k = k+1;
}
res[k] = '\0';
unToken=malloc(sizeof(TToken));
unToken->tipo=variable;
strcpy(unToken->token,res);
return unToken;
}
printf("Error: expresion incorrecta\n");
printf("Programa detenido");
exit(0);
}
#ifndef TOKENS_H_INCLUDED
#define TOKENS_H_INCLUDED
extern char strToken[][11];
//variable, parenthesis, operator, number, unary. Tokentype
typedef enum {variable, parentesis,operador, numero,unario} tipoToken;
typedef struct{
tipoToken tipo;
char token[20];
} TToken;
typedef struct {
char nombre[20];
double valor;
}TVariable;
TToken *token(char *s);
int esOperador(char c);
int esParentesis(char c);
#endif // TOKEN
#include "lista.h"
#include"token.h"
#include"pila.h"
//postfix.h
TLista *posfija(TLista * lis); //postfix
int precedencia(char* c); //precedence
TPila* resolver(TLista* listaPosfija, TLista* memoria); //resolve
#ifndef NODO_H_INCLUDED
#define NODO_H_INCLUDED
//node.h
struct TNodo{
void *dato;
struct TNodo *sig;
};
typedef struct TNodo TNodo;
TNodo *creaNodo(void *dato,int tam); //createNode
void liberaNodo(TNodo *nodo); //freeNode
#endif
#ifndef LISTA_H_INCLUDED
#define LISTA_H_INCLUDED
#include "nodo.h"
typedef struct{
TNodo *h;
TNodo *t;
int tamInfo;
}TLista;
TLista * nuevaLista (int tamInfo);
void agregarNodo (TLista * lis, void *info);
void retirarNodo (TLista * lis, void *info);
int listaVacia (TLista * lis);
void itera(TLista *lis,void (*funcion)(void *info) );
void liberar(TLista* lis);
void *buscarNodo (TLista * lis, void *info,int (*compara) (void *a, void *b));
#endif // LISTA_H_INCLUDED