Last active
August 24, 2016 20:35
-
-
Save quickgrid/ad9ef3ec50b2cc82d02527006f4d6dfa to your computer and use it in GitHub Desktop.
This is a simple compiler symbol table with name and class type entries. Inserts new strings through hashing, search for an element in appropriate chain using hashing, delete and update given element properties and show the chains.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Author: Asif Ahmed | |
* Description: Compiler Symbol table creation. | |
* Site: https://quickgrid.blogspot.com | |
* If there is any problem first try the solution below: | |
* 1. Change char pointers inside to fixed size array. | |
* 2. In the insert function use strcpy() function instead of -> | |
*/ | |
#include<bits/stdc++.h> | |
using namespace std; | |
// It has been seen if chain length is < 50 then some space is underutilized, | |
// Theoretically seen if > 50, prime number is taken then chain takes moderate space. | |
// So thats why 53 is used. | |
#define CHAIN_LENGTH 53 | |
#define M 128 | |
// Two columns of the symbol table with name and class type. | |
struct symbol_info{ | |
char *name; | |
char *classtype; | |
struct symbol_info *next; | |
} *block[CHAIN_LENGTH]; | |
// Hashing position is calculated using sum of all character ascii values | |
// Then performing Modulo operation to go to any bucket from 0 to CHAIN_LENGTH | |
int cHash(char* name){ | |
int idx = 0; | |
for(int i = 0; name[i]; ++i){ | |
idx = idx + name[i]; | |
} | |
return (idx % CHAIN_LENGTH); | |
} | |
// If there is no element in the chain then new element is added in front, | |
// otherwise through hashing if we reach a chain or, bucket that contains an | |
// element then we insert the new element at the beginning of the chain and | |
// the rest of the elements is lniked to the end of new node. | |
void cInsert(char* name, char* classtype){ | |
int pos = cHash(name); | |
if( block[pos] == NULL ){ | |
block[pos] = new symbol_info(); | |
block[pos]->name = name; | |
block[pos]->classtype = classtype; | |
block[pos]->next = NULL; | |
} | |
else{ | |
symbol_info* newNode = new symbol_info(); | |
newNode->name = name; | |
newNode->classtype = classtype; | |
// pointer swap | |
symbol_info* nextNode = block[pos]; | |
block[pos] = newNode; | |
newNode->next = nextNode; | |
} | |
} | |
// Go to certain chain through hashing since we know others will not contain the searched value. | |
// Next in that chain do a linear search on all element to see if it is there. | |
bool cSearch(char* name, char* classtype){ | |
// Implement | |
int pos = cHash(name); | |
symbol_info* temp = block[pos]; | |
while( temp != NULL ){ | |
if( !strcmp( temp->name, name ) && !strcmp( temp->classtype, classtype ) ){ | |
return true; | |
} | |
temp = temp->next; | |
} | |
return false; | |
} | |
// If the name and class type both matches then delete the element. | |
void cDelete(char* name, char* classtype){ | |
int pos = cHash(name); | |
symbol_info* temp = block[pos]; | |
if(temp == NULL) return; | |
// At head but no one to follow | |
if( temp->next == NULL && !strcmp( temp->name, name ) && !strcmp( temp->classtype, classtype ) ){ | |
block[pos] = NULL; | |
} | |
// At head has followers | |
else if( !strcmp( temp->name, name ) && !strcmp( temp->classtype, classtype ) ){ | |
block[pos] = temp->next; | |
} | |
else{ | |
while( temp->next != NULL ){ | |
if ( !strcmp( temp->next->name, name ) && !strcmp( temp->next->classtype, classtype ) ){ | |
printf("FOUND IT %s : %s\n", temp->name, temp->classtype ); | |
break; | |
} | |
temp = temp->next; | |
} | |
if( temp != NULL ){ | |
symbol_info* found = temp->next; | |
temp->next = found->next; | |
delete(found); | |
} | |
} | |
} | |
// Update an old class type with a new one. Change based on your need. | |
void cUpdate(char* name, char* classtype, char* updatedClasstype){ | |
int pos = cHash(name); | |
symbol_info* temp = block[pos]; | |
while( temp != NULL ){ | |
if( !strcmp( temp->name, name ) && !strcmp( temp->classtype, classtype ) ){ | |
temp->classtype = updatedClasstype; | |
return; | |
} | |
temp = temp->next; | |
} | |
} | |
// Print the symbol table chain wise. | |
void showSymbolTable(){ | |
// Implement | |
for(int i = 0; i < CHAIN_LENGTH; ++i){ | |
printf("%d:", i); | |
// Do not modify the head | |
symbol_info* temp = block[i]; | |
while( temp != NULL ){ | |
printf("->[%s|%s]", temp->name, temp->classtype); | |
temp = temp->next; | |
} | |
printf("\n"); | |
} | |
} | |
int showMenu(){ | |
cout << "Menu:\n"; | |
cout << "=====\n"; | |
string message = "Enter 1 to insert(name, class type)\n" | |
"Enter 2 to update(name, class type, new class type)\n" | |
"Enter 3 to search(name, class type)\n" | |
"Enter 4 to delete(name, class type)\n" | |
"Enter 5 to show the symbol table\n"; | |
cout << message << "\n"; | |
cout << "User Choice: "; | |
int choice; | |
scanf("%d", &choice); | |
return choice; | |
} | |
int main(){ | |
//take input from a file | |
//freopen("input.txt", "r", stdin); | |
//freopen("output.txt", "w", stdout); | |
int choice = showMenu(); | |
while( 1 ){ | |
char *name = new char[M]; | |
char *classtype = new char[M]; | |
switch(choice){ | |
case 1: | |
{ | |
cout << "Insert Selected:\n"; | |
scanf("%s%s", name, classtype); | |
// Omit the comma character | |
int pos = strlen(name) - 1; | |
if( name[ pos ] == ',' ){ | |
name[ pos ] = '\0'; | |
} | |
printf("%s %s\n", name, classtype); | |
printf("%d\n", cHash(name) ); | |
cInsert(name, classtype); | |
} | |
break; | |
case 2: | |
{ | |
cout << "Update Selected:\n"; | |
char* updatedClasstype = new char[M]; | |
scanf("%s%s%s", name, classtype, updatedClasstype); | |
// Omit the comma character | |
int pos = strlen(name) - 1; | |
if( name[ pos ] == ',' ){ | |
name[ pos ] = '\0'; | |
} | |
pos = strlen(classtype) - 1; | |
if( classtype[ pos ] == ',' ){ | |
classtype[ pos ] = '\0'; | |
} | |
printf("%s %s\n", name, classtype); | |
printf("%d\n", cHash(name) ); | |
cUpdate(name, classtype, updatedClasstype); | |
} | |
break; | |
case 3: | |
{ | |
cout << "Search Selected:\n"; | |
scanf("%s%s", name, classtype); | |
// Omit the comma character | |
int pos = strlen(name) - 1; | |
if( name[ pos ] == ',' ){ | |
name[ pos ] = '\0'; | |
} | |
printf("%s %s\n", name, classtype); | |
printf("%d\n", cHash(name) ); | |
if( cSearch(name, classtype) ){ | |
printf("FOUND\n"); | |
}else{ | |
printf("NOT FOUND\n"); | |
} | |
} | |
break; | |
case 4: | |
{ | |
cout << "Delete Selected:\n"; | |
scanf("%s%s", name, classtype); | |
// Omit the comma character | |
int pos = strlen(name) - 1; | |
if( name[ pos ] == ',' ){ | |
name[ pos ] = '\0'; | |
} | |
printf("%s %s\n", name, classtype); | |
printf("%d\n", cHash(name) ); | |
cDelete(name, classtype); | |
} | |
break; | |
case 5: | |
cout << "Show Selected\n"; | |
showSymbolTable(); | |
break; | |
default: | |
return 0; | |
}; | |
choice = showMenu(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment