/* 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"); }