/* OPERACIONES CON CONJUNTOS */
/* ==================================================*/
/* === Programa: 1.yac ===*/
/* === TEcnica: Dirigida por la sintAxis ===*/
/* === Programador: J. Rafael R. ochoa ===*/
/* ==================================================*/
%{
struct lista // almacena el contenido de listas
{
char *dato; // elemento de la lista
struct lista *sig; // apuntador al siguiente nodo
};
struct vars
{
char *nombre;
struct lista *inicio;
struct vars *sig;
};
struct vars *todo; // todas las variables
%}
%union
{
char str[80];
struct lista *list;
}
%token PRINT UNION INTER COMA PLEFT PRIGHT IGUAL LINEA
%token CLEFT CRIGHT SALIR
%token <str> CAD
%type <list> items conjunto valor oper ciclo
%%
/* producciones de la gramatica */
lineas : linea
| linea lineas
| error LINEA {printf("\n:-) ");} lineas
;
linea : asig LINEA {printf("\n:-) ");}
| PRINT oper LINEA {muestra($2); printf("\n:-) ");}
| SALIR {return;}
;
oper : valor {$$ = $1;}
| valor UNION oper {$$ = lista_une($1,$3);}
| valor INTER oper {$$ = interseccion($1,$3);}
| ciclo UNION oper {$$ = lista_une($1,$3);}
| ciclo INTER oper {$$ = interseccion($1,$3);}
| ciclo {$$ = $1;}
;
ciclo : PLEFT oper PRIGHT {$$ = $2;}
;
asig : CAD IGUAL oper {asigna($1,$3);}
;
valor : CAD {$$ = cont($1);}
| conjunto {$$ = $1;}
;
conjunto : CLEFT items CRIGHT {$$ = $2;}
;
items : CAD {$$ = nodo($1);}
| CAD COMA items {$$ = lista_une(nodo($1),$3);}
;
%%
/* funciones auxiliares */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void muestra(struct lista *);
struct lista *nodo(char *);
extern int yylex(); /* Liga con la funcion yylex generada por LEX */
extern int yynerrs;
int yyparse();
void main(void)
{
todo = NULL;
printf("\n\n");
printf("=========================================\n");
printf("Las variables empiezan con v\n");
printf("Por ejemplo vb=[1,2,3]\n");
printf("terminar con \"salir\"\n");
printf("===================================INICIO\n\n");
printf(":-) ");
yyparse();
printf("\nok\n");
}
yyerror(char *mess) /* llamado por yyparse() cuando ocurra */
{ /* un error */
printf("\n [error...%s] \n",mess);
return 1;
}
struct vars *existe_var(char *var)
{
struct vars *variables = todo;
while(variables)
{
if(strncmp(variables->nombre,var,strlen(var))==0)
return variables;
variables = variables->sig;
}
return NULL;
}
void asigna(char *var, struct lista *datos)
{
struct vars *nodo = NULL;
struct vars *aux = NULL;
struct vars *ant = NULL;
struct vars *ya_esta = NULL;
if((ya_esta = existe_var(var)))
{
ya_esta->inicio = datos;
muestra(nodo->inicio);
return;
}
nodo = (struct vars *)malloc(sizeof(struct vars));
nodo->nombre = strdup(var);
nodo->inicio = datos;
nodo->sig = NULL;
if (!todo) todo = nodo;
else
{
aux = todo;
while(aux)
{ ant = aux; aux=aux->sig; }
ant->sig = nodo;
}
muestra(nodo->inicio);
}
struct lista *cont(char *var)
{
struct vars *temp = NULL;
temp = todo;
while(temp)
{
if(strncmp(temp->nombre,var,strlen(var))==0) return temp->inicio;
temp = temp->sig;
}
printf("No existe la variable %s\n",var);
return NULL;
}
struct lista *copia(struct lista *list)
{
struct lista *nueva = NULL;
struct lista *nodo_new = NULL;
struct lista *actual = NULL;
if (!list) return NULL;
while(list)
{
nodo_new = nodo(list->dato);
if(!nueva) {nueva = nodo_new; actual = nodo_new;}
else {actual->sig = nodo_new; actual = nodo_new;}
list = list->sig;
}
return nueva;
}
struct lista *nodo(char *cad)
{
struct lista *nodo_nuevo=NULL;
nodo_nuevo = (struct lista *)malloc(sizeof(struct lista));
nodo_nuevo->dato = strdup(cad);
nodo_nuevo->sig = NULL;
return nodo_nuevo;
}
int existe(char *nom, struct lista *contenido)
{
while(contenido)
{
if (strncmp(contenido->dato,nom,strlen(nom))==0) return 1;
contenido = contenido->sig;
}
return 0;
}
struct lista *interseccion(struct lista *cont1, struct lista *cont2)
{
struct lista *salida = NULL;
struct lista *nuevo = NULL;
struct lista *actual = NULL;
if(!cont1 && !cont2) return NULL;
if(!cont1) return NULL;
if(!cont2) return NULL;
while(cont1)
{
if (existe(cont1->dato,cont2))
{
nuevo = nodo(cont1->dato);
if(!salida) {salida = nuevo; actual = nuevo;}
else {actual->sig = nuevo; actual = nuevo;}
}
cont1 = cont1->sig;
}
return salida;
}
struct lista *lista_une(struct lista *l1, struct lista *l2)
{
struct lista *salida = NULL;
struct lista *ant = NULL;
struct lista *nuevo = NULL;
if(!l1 && !l2) return NULL;
if(!l2) return l1;
if(!l1) return l2;
salida = copia(l2);
while(l1)
{
if (!existe(l1->dato,salida))
{
nuevo = nodo(l1->dato);
nuevo->sig = salida; salida = nuevo;
}
l1 = l1->sig;
}
return salida;
}
void muestra(struct lista *ini)
{
printf("\n");
while(ini)
{
printf("%s ",ini->dato);
ini = ini->sig;
}
printf("\n");
}