6:04 1 < Expert Q&A Token is a succession of characters that can be treated as a solitary consistent substance, (for exa
Posted: Sat May 14, 2022 3:47 pm
I need help rewriting a parse.c program in c language so it can work with my hash.c program. The information that is needed to help me with this problem is in the documents below. sorry for the blurriness.
This is the parse.c file
This is the hash.c file
6:04 1 < Expert Q&A Token is a succession of characters that can be treated as a solitary consistent substance, (for example, identifier, administrators, catchphrases, constants and so forth.). Model: Input String: c = a +b.3 Tokens: id = id2 + id3 . 3 2. Grammar Analysis: In this stage, the grammar analyzer takes the token delivered by lexical analyzer as info and produces a parse tree as result. In language structure examination stage, the parser makes sure that the articulation made by the token is linguistically right or not, as indicated by the standards that characterize the grammar of the source language. Model: 3. Semantic Analysis: In this stage, the semantic analyzer checks the source program for semantic mistakes and gathers the sort data the program syntactically and semantically correct then intermediate code generator generates a simple machine independent intermediate language. The intermediate code should be generated in such a way that it can easily translated into the target machine code Exampl t1 = 3. t2 = id3 t t3 = id2+t id=t 5. Code Optimizatio It is used to improve the intermediate code so that the output of the program could run faster and takes less space. It removes the unnecessary lines of the co and arranges the sequence of statements in order to speed up the program execution without DO Tools Home Courses Folder
6:04 1 < Expert Q&A Token is a succession of characters that can be treated as a solitary consistent substance, (for example, identifier, administrators, catchphrases, constants and so forth.). Model: Input String: c = a +b.3 Tokens: id = id2 + id3 . 3 2. Grammar Analysis: In this stage, the grammar analyzer takes the token delivered by lexical analyzer as info and produces a parse tree as result. In language structure examination stage, the parser makes sure that the articulation made by the token is linguistically right or not, as indicated by the standards that characterize the grammar of the source language. Model: 3. Semantic Analysis: In this stage, the semantic analyzer checks the source program for semantic mistakes and gathers the sort data the program syntactically and semantically correct then intermediate code generator generates a simple machine independent intermediate language. The intermediate code should be generated in such a way that it can easily translated into the target machine code Exampl t1 = 3. t2 = id3 t t3 = id2+t id=t 5. Code Optimizatio It is used to improve the intermediate code so that the output of the program could run faster and takes less space. It removes the unnecessary lines of the co and arranges the sequence of statements in order to speed up the program execution without DO Tools Home Courses Folder
6:04 1 く Expert Q&A Exampl t2 = id3 * 3. id = id2 +t 6. Code Generatio Code generation is the final stage of the compilation process. It takes the optimized intermediate code as input and maps it to the target machine languag Exampl MOV R1, i MUL R1, #3 MOV R2, i ADD R1, MOVid1, Symbol Tab Symbol tables are data structures that are used by compilers to hold information about source- program constructs. The information is collect incrementally by the analysis phase of compiler and used by the synthesis phases to generate the target code. Entries in the symbol table contain information abou an identifier such as its type, its position in storage, and any other relevant information Error Handling Whenever an error is ng.tedleR1R2d2.0d3e:e.n:2;0;e:.den:3;2;1;0;e:. Code Generation: Code generation is the final stage of the compilation process. It takes the optimized intermediate code as input and maps it to the target machine language. Example: MOV R1, id3 MUL R1, #3.0 MOV R2, id2 ADD R1, R2 MOVid1, R1 Symbol Table Symbol tables are data structures that are used by compilers to hold information about source- program constructs. The information is collected incrementally by the analysis phase of compiler DO Tools Home Courses Folder
6:04 1 く Expert Q&A Example: MOV R1, id3 MUL R1, #3.0 MOV R2, id2 ADD R1, R2 MOV id1, R1 Symbol Table Symbol tables are data structures that are used by compilers to hold information about source- program constructs. The information is collected incrementally by the analysis phase of compiler and used by the synthesis phases to generate the target code. Entries in the symbol table contain information about an identifier such as its type, its position in storage, and any other relevant information. Error Handling Whenever an error is encountered during the compilation of the source program, an error handler is invoked. Error handler generates a suitable error reporting message regarding the error encountered. Way of Flow is --- struct Node { enum class Type { Variable, Condition, Statement, Mutator, }; Node* m_parent; Node.m_next; Node* m_child; Type m_type; string m_file; size_t m_lineNo; }; struct VariableMutatorNode : public Node { enum class Mutation { Const }; Mutation m_mutation; // ... }; struct VariableNode{ VariableMutatorNode* m_mutators; II ... }; struct VariableMutatorNode : public Node { Plz upvote DO Tools Home Courses Folder
2.1 parse.c First, you are to rewrite the parse.c program discussed in class (see handout #15) to use your hash table ADT. Your new parse.c program should replace the "dictionary" and "frequency" arrays with a hash table that keeps track of the words encountered thus far. The hash table you create should contain 1000 buckets. (For this application, we will not use the resizing feature of your ADT). The user-defined data record stored by the hash table should include two items: the word in the dictionary (a string of length WORD SIZE characters), and a single counter that keeps track of the number of times (frequency) the associated word has been encountered. The word stored in each data record is also the key for that data record. You should create a print function that is installed into the hash table ADT when call- ing "new_hash." The print function you implement should simply print the word and frequency counter contained in the user-defined data record if the frequency counter is greater than 1. (If the frequency counter is equal to 1, the print function should just return). Once you have created the hash table ADT and the print function, you should modify the parse.c program to use them. At the beginning of the parse program, you should create a hash table as described above. In the parse loop, instead of calling "insert.word," you will call "insert_hash." Instead of calling "find word," you will call "find_hash." Lastly, in the "dump dictionary" function, you should first call "stat hash" and print the 3 statistics values returned by that function. Then, you should call "dump_hash” to print the contents of the hash table.
if (!find word (word, dictionary, frequency, dictionary size)) { insert_word (word, dictionary, frequency, kdictionary_size); char_index = 0; num,words++; } } else { /* Continue assembling word */ word (char index++] = 0; printf("There were nd words; Xd unique words. \n", num_words, dictionary_size); dump_dictionary (dictionary, frequency. dictionary size): ) void lover_case_word(char *v) { int i = 0; while (w [1] "0"){ w = tolower(w); } 3 int find_word (char av, char d (DICTIONARY_SIZE) (WORD_SIZE], int *f, int d_size) { int i; for (i = 0; i < d size; 1++) { 1f (!strcmp(d(1), w)) { f++; return TRUE; ) return FALSE; ) void insert_word (char *v, char d[DICTIONARY_SIZE] [WORD_SIZE). int f (DICTIONARY_SIZE], int *d_size) 2
1 parse.c #include <stdio.h> #include <ctype.h> #include <string.h> #define WORD_SIZE 40 #define DICTIONARY_SIZE 1000 #define TRUE 1 #define FALSE O void lower_case_word (char *); int find_word (char*, char (DICTIONARY_SIZE] [WORD_SIZE], int *, int); void insert_word (char*, char (DICTIONARY_SIZE) (WORD_SIZE), int *, int *); void dump_dictionary (char (DICTIONARY_SIZE) (WORD_SIZE], int *, int); int main(void) { char c, word (WORD_SIZE), dictionary (DICTIONARY_SIZE] [WORD_SIZE]: int frequency (DICTIONARY_SIZE]: int char_index = 0, dictionary_size = 0, num_words = 0, i; printf ("Parsing input ... \n"); /* Read in characters until end is reached */ while ((c = getchar()) != EOF) { if (c ) II (c ==, il (c == ',') 11 (c == "") 11 (c == "") 11 (c --:) || (c == '\n')) { /* End of a word / if (char_index) { /* Word is not empty / word [char_index] = '\0'; lower_case_word(word); 1
{ strcpy(d[*d_size), w); f[id_size] = 1; (*d_size)++; ) void dump_dictionary (char d[DICTIONARY_SIZE) (WORD_SIZE], int *f, int d_size) { int i; for (i = 0; i < d_size; i++) if (f [1] > 1) printf("%s:%d\n", a, f); }
hash.h typedef struct hash_entry void data; char keyi atruet haah entry next Shash entry typedef struct hash_table_ * A structure definition goes here / hash entry table int is int nun, worst_search, non search, total_search; vold ("print_fane) (void) > haah_table. Phash_table Phash_table new_hashint site, void *print_fune) void >> void free_hasht Phash_table tables: void inserthashPhash_table table, char *key, void data) void find_hash Phash_table table, char key) void stat_hash(Thash_table table, int nom, float avg_search, int worst search: void dump_hash(Thash_table table) void resize_hashPhash_table table, int size) hash.cpp (no change) include catdio.h> include <stdlib.h> Sinclude <ctype.h include <string.h> include "hash. Phash_table ned_haabeint tite, void *print_urey(void 1/define hash table Phash table new tables new table - Phash table alloc(sizeof hash_table)); new_table-size- new table->table that entrymalloc(size . sizeof(hash_entry": //loop variable intii //loop to make all the buckets NULL tor (-0 i < site: new_table-table] - NULL new_table->print_rune - print_func; initialize all stat variables torero new_table - 0 new table-worst search - 0; nev_table->m_search- 0 new table->total_search - 0; return new table: > unsigned int hashchar key. Phash_table table) runsigned variable so there's no unexpected behavior unsigned int acom //variable to keep track of key string length int keyten - strlen(key) int 13 // converts the string into its proper key for 1-0 keylon 1++) accum- keyti 11 << 1) 1/ return the hash key to the function returnaceustable-side) > void insert_hashPhash_table table, char *key, void data) // calculate the hash key int Index - hashey, table); //allocate data for the new hash_entry and key haah_entry new_entry-thash_entry alloc(sizeof(hash_entry)
void insert_hash(Phash_table table char key. void data //calculate the hash key int index hash (key, table) //allocate data for the new hoah_entry and key hash_entry "new_entry hash_entry alloc(sizeof(hash_entry) new_entry->data data; new entry->key - (char* malloc(sizeof(char)strlen(key)-1); strepynew_entry->key, key) // initialize pointer for head insertion hash_entry eur_head - table-Stable Index: 1/complete head insertion new_entry->next - cor_head: table-tablet Lindex new entry: //nan is incremented for every time inert_hash is ontled table-num-table-num+ 11 > void find_hash(Phash_table table, chat kay //ptr for linked list traversal haah entry cura 1/variables for loop travernal and hash-key caleslation int 1, Index 1/ptr for linked list hash entry data // initialize index as key Index - hash key, table) //tracker variable for worst search int trckr - 0 //loop to find speelfie hash value based on key for (car-table-tableIndex), 1 - 0; ear: eur - eur->next) { 1++ trekre table-stotal_search-table-total_search + 1; if (atropeur->key, key) - 0) break; 1 > //this loop is supposed to keep track of the larger verst search for //every find_hash call IF(trek > table-worst search table-vorat_search trckr // increment non search table->m_search - table search + 17 11 (cur) return our data > else return NULL; > > void stat_hashiphash_table table, int nun, float evg_search, in oret_search 1/set all variables squired through function incrementations as equal to the fact 1/pointer parameters nun-table-su; avg_search - table->total_search/table-num_search; "worst search - table-Sworst search: //It's a really simple function all things considered. > void dump_hash(Phash_table table> //variable used to run through the hash table int 11 //pointer uned to travers the bucket hash_entry Cu! /rute through the hash table and prints out the data for (i = 0; i < table-size: 5++) { for fear - table-stable[1]: cur; cur cor->next) table-Sprint_funcur->data) 1
//variable used to run through the hash table int i; //pointer used to traverse the buckets hash_entry *cur; /*runs through the hash table and prints out the data/ for (i = 0; i < table->size; i++) { for (cur - table->tableli); cur; cur - cur->next) { table->print_func(cur->data); > > 2 void resize_bash(Phash_table table, int size) { //variable to store old table in hash_entry "cur; //variable for looping through hash indeces int i; //swap variable to use later hash_table swap //use new hash to produce new hash table //allocate memory for the new table Phash_table new_table - new_hash(size, table->print_func): for(i - 0; i < table->size; i++) { for(eur - table->tableti); cur 10; cur - cur->next) { insert_hash(new_table, cur->key, cur->data); > // swap the old and new table variables and free the data swap - *table; *table - new table; * new_table - swap: free hash(new_table); > void free_hash(Phash_table table) { //Might actually all be right
// driver seems to respond well to it... //definition of cur and next hash_entry "cur; hash entry *next; !/initialize loop variable int i; //loop that frees the various parts of the hash table's data for(i - 0; i < table->size; i++) { for(eur = table->table; cur != 0; cur = next) { next - cur->next; free(cur); > //free the table header and table last free(table->table); free(table):
This is the parse.c file
This is the hash.c file
6:04 1 < Expert Q&A Token is a succession of characters that can be treated as a solitary consistent substance, (for example, identifier, administrators, catchphrases, constants and so forth.). Model: Input String: c = a +b.3 Tokens: id = id2 + id3 . 3 2. Grammar Analysis: In this stage, the grammar analyzer takes the token delivered by lexical analyzer as info and produces a parse tree as result. In language structure examination stage, the parser makes sure that the articulation made by the token is linguistically right or not, as indicated by the standards that characterize the grammar of the source language. Model: 3. Semantic Analysis: In this stage, the semantic analyzer checks the source program for semantic mistakes and gathers the sort data the program syntactically and semantically correct then intermediate code generator generates a simple machine independent intermediate language. The intermediate code should be generated in such a way that it can easily translated into the target machine code Exampl t1 = 3. t2 = id3 t t3 = id2+t id=t 5. Code Optimizatio It is used to improve the intermediate code so that the output of the program could run faster and takes less space. It removes the unnecessary lines of the co and arranges the sequence of statements in order to speed up the program execution without DO Tools Home Courses Folder
6:04 1 < Expert Q&A Token is a succession of characters that can be treated as a solitary consistent substance, (for example, identifier, administrators, catchphrases, constants and so forth.). Model: Input String: c = a +b.3 Tokens: id = id2 + id3 . 3 2. Grammar Analysis: In this stage, the grammar analyzer takes the token delivered by lexical analyzer as info and produces a parse tree as result. In language structure examination stage, the parser makes sure that the articulation made by the token is linguistically right or not, as indicated by the standards that characterize the grammar of the source language. Model: 3. Semantic Analysis: In this stage, the semantic analyzer checks the source program for semantic mistakes and gathers the sort data the program syntactically and semantically correct then intermediate code generator generates a simple machine independent intermediate language. The intermediate code should be generated in such a way that it can easily translated into the target machine code Exampl t1 = 3. t2 = id3 t t3 = id2+t id=t 5. Code Optimizatio It is used to improve the intermediate code so that the output of the program could run faster and takes less space. It removes the unnecessary lines of the co and arranges the sequence of statements in order to speed up the program execution without DO Tools Home Courses Folder
6:04 1 く Expert Q&A Exampl t2 = id3 * 3. id = id2 +t 6. Code Generatio Code generation is the final stage of the compilation process. It takes the optimized intermediate code as input and maps it to the target machine languag Exampl MOV R1, i MUL R1, #3 MOV R2, i ADD R1, MOVid1, Symbol Tab Symbol tables are data structures that are used by compilers to hold information about source- program constructs. The information is collect incrementally by the analysis phase of compiler and used by the synthesis phases to generate the target code. Entries in the symbol table contain information abou an identifier such as its type, its position in storage, and any other relevant information Error Handling Whenever an error is ng.tedleR1R2d2.0d3e:e.n:2;0;e:.den:3;2;1;0;e:. Code Generation: Code generation is the final stage of the compilation process. It takes the optimized intermediate code as input and maps it to the target machine language. Example: MOV R1, id3 MUL R1, #3.0 MOV R2, id2 ADD R1, R2 MOVid1, R1 Symbol Table Symbol tables are data structures that are used by compilers to hold information about source- program constructs. The information is collected incrementally by the analysis phase of compiler DO Tools Home Courses Folder
6:04 1 く Expert Q&A Example: MOV R1, id3 MUL R1, #3.0 MOV R2, id2 ADD R1, R2 MOV id1, R1 Symbol Table Symbol tables are data structures that are used by compilers to hold information about source- program constructs. The information is collected incrementally by the analysis phase of compiler and used by the synthesis phases to generate the target code. Entries in the symbol table contain information about an identifier such as its type, its position in storage, and any other relevant information. Error Handling Whenever an error is encountered during the compilation of the source program, an error handler is invoked. Error handler generates a suitable error reporting message regarding the error encountered. Way of Flow is --- struct Node { enum class Type { Variable, Condition, Statement, Mutator, }; Node* m_parent; Node.m_next; Node* m_child; Type m_type; string m_file; size_t m_lineNo; }; struct VariableMutatorNode : public Node { enum class Mutation { Const }; Mutation m_mutation; // ... }; struct VariableNode{ VariableMutatorNode* m_mutators; II ... }; struct VariableMutatorNode : public Node { Plz upvote DO Tools Home Courses Folder
2.1 parse.c First, you are to rewrite the parse.c program discussed in class (see handout #15) to use your hash table ADT. Your new parse.c program should replace the "dictionary" and "frequency" arrays with a hash table that keeps track of the words encountered thus far. The hash table you create should contain 1000 buckets. (For this application, we will not use the resizing feature of your ADT). The user-defined data record stored by the hash table should include two items: the word in the dictionary (a string of length WORD SIZE characters), and a single counter that keeps track of the number of times (frequency) the associated word has been encountered. The word stored in each data record is also the key for that data record. You should create a print function that is installed into the hash table ADT when call- ing "new_hash." The print function you implement should simply print the word and frequency counter contained in the user-defined data record if the frequency counter is greater than 1. (If the frequency counter is equal to 1, the print function should just return). Once you have created the hash table ADT and the print function, you should modify the parse.c program to use them. At the beginning of the parse program, you should create a hash table as described above. In the parse loop, instead of calling "insert.word," you will call "insert_hash." Instead of calling "find word," you will call "find_hash." Lastly, in the "dump dictionary" function, you should first call "stat hash" and print the 3 statistics values returned by that function. Then, you should call "dump_hash” to print the contents of the hash table.
if (!find word (word, dictionary, frequency, dictionary size)) { insert_word (word, dictionary, frequency, kdictionary_size); char_index = 0; num,words++; } } else { /* Continue assembling word */ word (char index++] = 0; printf("There were nd words; Xd unique words. \n", num_words, dictionary_size); dump_dictionary (dictionary, frequency. dictionary size): ) void lover_case_word(char *v) { int i = 0; while (w [1] "0"){ w = tolower(w); } 3 int find_word (char av, char d (DICTIONARY_SIZE) (WORD_SIZE], int *f, int d_size) { int i; for (i = 0; i < d size; 1++) { 1f (!strcmp(d(1), w)) { f++; return TRUE; ) return FALSE; ) void insert_word (char *v, char d[DICTIONARY_SIZE] [WORD_SIZE). int f (DICTIONARY_SIZE], int *d_size) 2
1 parse.c #include <stdio.h> #include <ctype.h> #include <string.h> #define WORD_SIZE 40 #define DICTIONARY_SIZE 1000 #define TRUE 1 #define FALSE O void lower_case_word (char *); int find_word (char*, char (DICTIONARY_SIZE] [WORD_SIZE], int *, int); void insert_word (char*, char (DICTIONARY_SIZE) (WORD_SIZE), int *, int *); void dump_dictionary (char (DICTIONARY_SIZE) (WORD_SIZE], int *, int); int main(void) { char c, word (WORD_SIZE), dictionary (DICTIONARY_SIZE] [WORD_SIZE]: int frequency (DICTIONARY_SIZE]: int char_index = 0, dictionary_size = 0, num_words = 0, i; printf ("Parsing input ... \n"); /* Read in characters until end is reached */ while ((c = getchar()) != EOF) { if (c ) II (c ==, il (c == ',') 11 (c == "") 11 (c == "") 11 (c --:) || (c == '\n')) { /* End of a word / if (char_index) { /* Word is not empty / word [char_index] = '\0'; lower_case_word(word); 1
{ strcpy(d[*d_size), w); f[id_size] = 1; (*d_size)++; ) void dump_dictionary (char d[DICTIONARY_SIZE) (WORD_SIZE], int *f, int d_size) { int i; for (i = 0; i < d_size; i++) if (f [1] > 1) printf("%s:%d\n", a, f); }
hash.h typedef struct hash_entry void data; char keyi atruet haah entry next Shash entry typedef struct hash_table_ * A structure definition goes here / hash entry table int is int nun, worst_search, non search, total_search; vold ("print_fane) (void) > haah_table. Phash_table Phash_table new_hashint site, void *print_fune) void >> void free_hasht Phash_table tables: void inserthashPhash_table table, char *key, void data) void find_hash Phash_table table, char key) void stat_hash(Thash_table table, int nom, float avg_search, int worst search: void dump_hash(Thash_table table) void resize_hashPhash_table table, int size) hash.cpp (no change) include catdio.h> include <stdlib.h> Sinclude <ctype.h include <string.h> include "hash. Phash_table ned_haabeint tite, void *print_urey(void 1/define hash table Phash table new tables new table - Phash table alloc(sizeof hash_table)); new_table-size- new table->table that entrymalloc(size . sizeof(hash_entry": //loop variable intii //loop to make all the buckets NULL tor (-0 i < site: new_table-table] - NULL new_table->print_rune - print_func; initialize all stat variables torero new_table - 0 new table-worst search - 0; nev_table->m_search- 0 new table->total_search - 0; return new table: > unsigned int hashchar key. Phash_table table) runsigned variable so there's no unexpected behavior unsigned int acom //variable to keep track of key string length int keyten - strlen(key) int 13 // converts the string into its proper key for 1-0 keylon 1++) accum- keyti 11 << 1) 1/ return the hash key to the function returnaceustable-side) > void insert_hashPhash_table table, char *key, void data) // calculate the hash key int Index - hashey, table); //allocate data for the new hash_entry and key haah_entry new_entry-thash_entry alloc(sizeof(hash_entry)
void insert_hash(Phash_table table char key. void data //calculate the hash key int index hash (key, table) //allocate data for the new hoah_entry and key hash_entry "new_entry hash_entry alloc(sizeof(hash_entry) new_entry->data data; new entry->key - (char* malloc(sizeof(char)strlen(key)-1); strepynew_entry->key, key) // initialize pointer for head insertion hash_entry eur_head - table-Stable Index: 1/complete head insertion new_entry->next - cor_head: table-tablet Lindex new entry: //nan is incremented for every time inert_hash is ontled table-num-table-num+ 11 > void find_hash(Phash_table table, chat kay //ptr for linked list traversal haah entry cura 1/variables for loop travernal and hash-key caleslation int 1, Index 1/ptr for linked list hash entry data // initialize index as key Index - hash key, table) //tracker variable for worst search int trckr - 0 //loop to find speelfie hash value based on key for (car-table-tableIndex), 1 - 0; ear: eur - eur->next) { 1++ trekre table-stotal_search-table-total_search + 1; if (atropeur->key, key) - 0) break; 1 > //this loop is supposed to keep track of the larger verst search for //every find_hash call IF(trek > table-worst search table-vorat_search trckr // increment non search table->m_search - table search + 17 11 (cur) return our data > else return NULL; > > void stat_hashiphash_table table, int nun, float evg_search, in oret_search 1/set all variables squired through function incrementations as equal to the fact 1/pointer parameters nun-table-su; avg_search - table->total_search/table-num_search; "worst search - table-Sworst search: //It's a really simple function all things considered. > void dump_hash(Phash_table table> //variable used to run through the hash table int 11 //pointer uned to travers the bucket hash_entry Cu! /rute through the hash table and prints out the data for (i = 0; i < table-size: 5++) { for fear - table-stable[1]: cur; cur cor->next) table-Sprint_funcur->data) 1
//variable used to run through the hash table int i; //pointer used to traverse the buckets hash_entry *cur; /*runs through the hash table and prints out the data/ for (i = 0; i < table->size; i++) { for (cur - table->tableli); cur; cur - cur->next) { table->print_func(cur->data); > > 2 void resize_bash(Phash_table table, int size) { //variable to store old table in hash_entry "cur; //variable for looping through hash indeces int i; //swap variable to use later hash_table swap //use new hash to produce new hash table //allocate memory for the new table Phash_table new_table - new_hash(size, table->print_func): for(i - 0; i < table->size; i++) { for(eur - table->tableti); cur 10; cur - cur->next) { insert_hash(new_table, cur->key, cur->data); > // swap the old and new table variables and free the data swap - *table; *table - new table; * new_table - swap: free hash(new_table); > void free_hash(Phash_table table) { //Might actually all be right