Implementing Tracery in C using linked lists.

hzxlove
Lab4-Starter-Code-2.zip

Lab4-Starter-Code/list.h

#ifndef CMPS12B_LIST #define CMPS12B_LIST typedef struct node_type{ /* * TODO 1 */ /* * TODO 1 */ } Node; typedef struct { /* * TODO 1 */ /* * TODO 1 */ } List; Node* make_node(void* data, Node* next); List* make_list(); void free_node(Node* node); void free_list(List* list); void add(List* list, int index, void* data); void* get(List* list, int index); void set(List* list, int index, void* data); #endif

Lab4-Starter-Code/tracery_recursion.c

#include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <assert.h> //UNCOMMENT THIS ONCE YOU HAVE IMPLEMENTED LIST //#include "list.h" //#include "helpers.h" //UNCOMMENT THIS ONCE YOU HAVE IMPLEMENTED RULE //#include "rule.h" struct string{ char* characters; int length; }; int main(int argc, char** argv){ /* LIST TEST CODE List* list = make_list(); List* reversed = make_list(); for (int ii = 0; ii < argc; ii++){ add(list,list->size,copy_string(argv[ii])); add(reversed,0,copy_string(argv[ii])); } printf("The list size is %d\n",list->size); for (int ii = 0; ii < argc; ii++){ printf("%s\n", (char*) get(list,ii)); } for (int ii = 0; ii < argc; ii++){ printf("%s\n", (char*) get(reversed,ii)); } free_list(list); free_list(reversed); */ /* GRAMMAR TEST CODE List* grammar = read_grammar("grammar-story.txt"); print_grammar(grammar); */ /* * BONUS TODO List* grammar = read_grammar("grammar-story.txt"); if (argc == 1){ srand(time(NULL)); } else{ srand(atoi(argv[1])); } char* expansion = expand("#origin#",grammar); printf("%s\n",expansion); free(expansion); for (int ii = grammar->size-1 ; ii >= 0; ii--){ free_rule( (Rule*) get(grammar,ii)); set(grammar,ii,NULL); } free_list(grammar); * BONUS TODO */ return 0; }

Lab4-Starter-Code/rule.c

#include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" #include "rule.h" #include "helpers.h" Rule* make_rule(char* key){ /* TODO 3 */ return NULL; // replace this /* TODO 3 */ } void free_rule(Rule* rule){ /* TODO 3 */ /* TODO 3 */ } List* read_grammar(char* filename){ /* * TODO 4A */ //Construct a new List* called grammar that we will fill up in the following code /* * TODO 4A */ FILE* input_file = fopen(filename,"r"); char buffer[1000]; int number_of_expansions = 0; int buffer_index = 0; int number_of_rules = 0; for (char current = fgetc(input_file); current != EOF; current = fgetc(input_file)){ if (current == ':'){ char* key = calloc(buffer_index+1,sizeof(char)); memcpy(key,buffer,buffer_index); /* * TODO 4B */ //Construct a new Rule* and add it to grammar /* * TODO 4B */ buffer_index = 0; } else if (current == ',' || current == '\n'){ char* expansion = calloc(buffer_index+1,sizeof(char)); memcpy(expansion,buffer,buffer_index); /* * TODO 4C */ //Get the last Rule* inserted into grammar and add expansion to it /* * TODO 4C */ buffer_index = 0; } else { buffer[buffer_index] = current; buffer_index++; } } fclose(input_file); /* * TODO 4D */ return NULL; // replace this to return the grammar we just filled up /* * TODO 4D */ } char* expand(char* text, List* grammar){ /* * BONUS TODO */ /* * BONUS TODO */ } //Iterates through a grammar list and prints out all of the rules void print_grammar(List* grammar){ for (int ii = 0; ii < grammar->size; ii++){ Rule* rule = get(grammar,ii); for (int jj = 0; jj < rule->expansions->size; jj++){ printf("A potential expansion of rule '%s' is '%s'\n",rule->key, (char*) get(rule->expansions,jj)); } } }

Lab4-Starter-Code/list.c

#include <stdlib.h> #include "list.h" #include <stdio.h> Node* make_node(void* data, Node* next){ /* * TODO 2 */ return NULL; // replace this /* * TODO 2 */ } List* make_list(){ /* * TODO 2 */ return NULL; // replace this /* * TODO 2 */ } void free_node(Node* node){ /* * TODO 2 */ /* * TODO 2 */ } void free_list(List* list) { /* * TODO 2 */ /* * TODO 2 */ } void add(List* list, int index, void* data) { /* * TODO 2 */ /* * TODO 2 */ } void* get(List* list, int index){ /* * TODO 2 */ return NULL; // replace this /* * TODO 2 */ } void set(List* list, int index, void* data) { /* * TODO 2 */ /* * TODO 2 */ }

Lab4-Starter-Code/rule.h

#ifndef TRACERY_HELPERS_H #define TRACERY_HELPERS_H #include "list.h" typedef struct { /* * TODO 0 */ // define the things a rule struct needs /* * TODO 0 */ } Rule; Rule* make_rule(char* key); void free_rule(Rule* rule); List* read_grammar(char* filename); char* expand(char* rule, List* grammar); void print_grammar(List* grammar); #endif

Lab4-Starter-Code/grammar-story.txt

animal:cat,emu,okapi emotion:happy,sad,elated,curious,sleepy color:red,green,blue name:emily,luis,otavio,anna,charlie character:#name# the #adjective# #animal# place:school,the beach,the zoo,Burning Man adjective:#color#,#emotion# origin:once #character# and #character# went to #place#

Lab4-Starter-Code/helpers.h

#ifndef CMPS12B_LAB4_HELPERS_H #define CMPS12B_LAB4_HELPERS_H #include "list.h" List* split(char* string, char* delimiters); char* join(List* string_array); char* copy_string(char* string); void* get_random(List* list); #endif

Lab4-Starter-Code/helpers.c

#include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" char* copy_string(char* string){ char* new_string = calloc(strlen(string)+1,sizeof(char)); strcpy(new_string,string); return new_string; } char *strtok_new(char * string, char const * delimiter){ static char *source = NULL; char *p, *riturn = 0; if(string != NULL) source = string; if(source == NULL) return NULL; if((p = strpbrk (source, delimiter)) != NULL) { *p = 0; riturn = source; source = ++p; } return riturn; } List* split(char* string, char* delimiters){ char* temp = calloc(strlen(string)+2,sizeof(char)); strncpy(temp,string,strlen(string)); temp[strlen(string)] = delimiters[0]; char * pch; pch = strtok_new(temp,delimiters); int count = 0; List* list = make_list(); while (pch) { char* element = copy_string(pch); add(list,list->size,element); pch = strtok_new(NULL, delimiters); } free(temp); return list; } char* join(List* string_list){ int total_size = 0; for (int ii = 0; ii < string_list->size; ii++){ total_size += strlen((char*) get(string_list,ii)); } char* concatenated_string = calloc(total_size + 1, sizeof(char)); int sentinel = 0; for (int ii = 0; ii < string_list->size; ii++){ int jj = 0; while ( ((char*)get(string_list,ii))[jj] != '\0'){ concatenated_string[sentinel] = ((char*)get(string_list,ii))[jj]; sentinel++; jj++; } } return concatenated_string; } void* get_random(List* list){ return get(list,rand() %list->size); }