0% found this document useful (0 votes)
40 views

Compiler Design Lab-Journal-8

This lab journal document from Bahria University discusses a lab assignment on symbol tables for a compiler construction course. The document outlines 4 tasks for students to update the symbol creation function in a lexer class to insert different types of symbols into a symbol table, including variables, functions, classes, and statements. It also includes source code for implementing a symbol table using linked lists, with functions for inserting, finding, deleting, and modifying symbols.

Uploaded by

Abdullah Arshad
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views

Compiler Design Lab-Journal-8

This lab journal document from Bahria University discusses a lab assignment on symbol tables for a compiler construction course. The document outlines 4 tasks for students to update the symbol creation function in a lexer class to insert different types of symbols into a symbol table, including variables, functions, classes, and statements. It also includes source code for implementing a symbol table using linked lists, with functions for inserting, finding, deleting, and modifying symbols.

Uploaded by

Abdullah Arshad
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

Bahria University, Lahore Campus

Department of Computer Sciences


Lab Journal 08
(Spring 2022)

Course: Compiler Construction Date:


Course Code: CSCL-323 Max Marks: 40
Faculty’s Name: Mr. Nadeem Lab Engineer: Mr. Shoaib Khan

Name: __Abdullah Arshad___________________________


Enroll No: __________03-134201-030_____________

Objective(s):

 Symbol Table Introduction | Construction of symbol table using Dictionary |


Understanding Usage in DFA and CFG construction Step

Lab Tasks: Deadline: 22/05/22


Task 1: You are required to update SymbolCreation function in Lexer class to insert a new
variable/identifier in the symbol table defined in the SymbolTable Class.
Task 2: You are required to update SymbolCreation function in Lexer class to add a new
function name along with its return type in the in the symbol table defined in the
SymbolTable Class. Also add new entry for each of its parameter.
Task 3: You are required to update SymbolCreation function in Lexer class to insert a new
class name in the symbol table defined in the SymbolTable Class.
Task 4: You are required to update SymbolCreation function in Lexer class to insert a new
variable/identifier in the symbol table for the following statements.

 Loop Statement
o Loop
o For
o While
 Conditional
o if
o else if
o else
o switch

Department of Computer Sciences, BULC Lab- 1


Code:
#include<iostream>

#include<fstream>

#include<vector>

#include<string>

const int MAX = 100;

using namespace std;


vector < string > keywords;
vector < string > dataTypes;
vector < string > constants;
vector < string > operators;
vector < string > identifiers;
vector < string > mInstruction;
vector < string > invalidToken;
void writeToFile() {
fstream fileObj;
fileObj.open("newFile.txt", fstream::out);
fileObj << "for ( int i = 0 ; i < 10 ; i++ ) { int ss = 0 ; }\nwhile ( p < 1 ) { int pp = 0; }\nif ( p < 1 ) {
int tt = 0; }\nint func ( int para ){ int i = 0; } \nint variable ;\nfloat flt_num = 55 ;\nclass
myclass { } ;";
fileObj.close();
}

string isSpace(string & stringFromFile) {


string newString;
int countSpaces = 0;
for (int i = 0; i < stringFromFile.length(); i++) {
if (stringFromFile[i] == ' ') {
countSpaces++;
} else {
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Spaces = " << countSpaces << endl;
return newString;
}
string isEndl(string & stringFromFile) {
string newString = "";
int countEndl = 0;
for (int i = 0; i < stringFromFile.length(); i++) {
if (stringFromFile[i] == '\n') {
countEndl++;
} else {
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Endl = " << countEndl << endl;
return newString;
}
string isTab(string & stringFromFile) {
string newString = "";
int countTabs = 0;
for (int i = 0; i < stringFromFile.length(); i++) {
if (stringFromFile[i] == '\t') {
countTabs++;
} else {
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Tabs = " << countTabs << endl;
return newString;
}
string isComma(string & stringFromFile) {
string newString = "";
int countComma = 0;
for (int i = 0; i < stringFromFile.length(); i++) {
if (stringFromFile[i] == ',') {
countComma++;
} else {
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Commas = " << countComma << endl;
return newString;
}
string isParanthesis(string & stringFromFile) {
string newString = "";
int countPar = 0;
for (int i = 0; i < stringFromFile.length(); i++) {
if (stringFromFile[i] == '(' || stringFromFile[i] == ')') {
countPar++;
} else {
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Paranthesis = " << countPar << endl;
return newString;
}
string isBracket(string & stringFromFile) {
string newString = "";
int countBracket = 0;
for (int i = 0; i < stringFromFile.length(); i++) {
if (stringFromFile[i] == '{' || stringFromFile[i] == '}') {
countBracket++;
} else {
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Bracket = " << countBracket << endl;
return newString;
}
string isSemiColon(string & stringFromFile) {
string newString = "";
int countSemiColon = 0;
for (int i = 0; i < stringFromFile.length(); i++) {
if (stringFromFile[i] == ';') {
countSemiColon++;
} else {
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of SemiColon = " << countSemiColon << endl;
return newString;
}
bool isOperator(string stringFromFile) {
if (stringFromFile == "+" || stringFromFile == "-" || stringFromFile == "" || stringFromFile
== "/" || stringFromFile == "%" || stringFromFile == "++" || stringFromFile == "--" ||
stringFromFile == "/=" || stringFromFile == "=" || stringFromFile == "-=" || stringFromFile ==
"==" || stringFromFile == ">=" || stringFromFile == "<=" || stringFromFile == ">" ||
stringFromFile == "<") {
return true;
}
return false;
}

bool isConstant(string stringFromFile) {


int i = 0;
while (i < stringFromFile.length()) {
if (isdigit(stringFromFile[i])) {
if (i == stringFromFile.length() - 1) {
return true;
}
}
i++;
}
return false;
}
bool isDataType(string pTok) {
vector < string > dataTypes {
"double",
"int",
"long",
"char",
"char*",
"float",
"void",
"bool"
};
for (int i = 0; i < dataTypes.size(); i++) {
if (pTok == dataTypes[i]) {
return true;
}
}
return false;
}
bool isKeyWord(string pTok) {
vector < string > keywords {
"auto",
"struct",
"break",
"else",
"long",
"switch",
"case",
"enum",
"register",
"typedef",
"extern",
"return",
"union",
"const",
"short",
"unsigned",
"continue",
"for",
"signed",
"default",
"goto",
"sizeof",
"voltile",
"do",
"if",
"static",
"while",
"class",
"false",
"true",
"cout",
"<<"
};
for (int i = 0; i < keywords.size(); i++) {
if (pTok == keywords[i]) {
return true;
}
}
return false;
}
bool isIdentifier(string stringFromFile) {
if (stringFromFile[0] == '_' || (stringFromFile[0] >= 65 && stringFromFile[0] <= 90) ||
(stringFromFile[0] >= 97 && stringFromFile[0] <= 122)) {
for (int i = 0; i < stringFromFile.length(); i++) {
string temp(1, stringFromFile[i]);
if (isKeyWord(stringFromFile) || stringFromFile[i] == '=' || stringFromFile[i] == '!' ||
stringFromFile[i] == '@' || stringFromFile[i] == '"' || stringFromFile[i] == '\'' ||
stringFromFile[i] == '#' || stringFromFile[i] == isOperator(temp)) {
return false;
} else if (i == stringFromFile.length()) {
return true;
}
}
return true;
}
return false;
}
bool Check_DFA_VN(int current_state, int current_index, string token) {
if (current_state == 0 && (isalpha(token[current_index]) || token[current_index] == '_')) {
current_state = 1;
if (current_index + 1 < token.length()) {
return Check_DFA_VN(current_state, current_index + 1, token);
} else {
return true;
}
} else if (current_state == 1 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_')) {
current_state = 2;
if (current_index + 1 < token.length()) {
return Check_DFA_VN(current_state, current_index + 1, token);
} else {
return true;
}
} else if (current_state == 2 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_')) {
current_state = 3;
if (current_index + 1 < token.length()) {
return Check_DFA_VN(current_state, current_index + 1, token);
} else {
return true;
}
} else if (current_state == 3 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_')) {
current_state = 4;
if (current_index + 1 < token.length()) {
return Check_DFA_VN(current_state, current_index + 1, token);
} else {
return true;
}
} else if (current_state == 4 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_')) {
current_state = 5;
if (current_index + 1 < token.length() && token[current_index + 1] != NULL) {
return false;
} else {
return true;
}
} else {
return false;
}
}

class Node {
string identifier, scope, type;
int lineNo;
Node * next;

public:
Node() {
next = NULL;
}
Node(string key, string value, string type, int lineNo) {
this -> identifier = key;
this -> scope = value;
this -> type = type;
this -> lineNo = lineNo;
next = NULL;
}
void print() {
cout << "Identifier's Name:" << identifier <<
"\nType:" << type <<
"\nScope: " << scope <<
"\nLine Number: " << lineNo << endl;
}
friend class SymbolTable;
};
class SymbolTable {
Node * head[MAX];
public:
SymbolTable() {
for (int i = 0; i < MAX; i++)
head[i] = NULL;
}
int hashf(string id); // hash function
bool insert(string id, string scope, string Type, int lineno);
string find(string id);
bool deleteRecord(string id);
bool modify(string id, string scope, string Type, int lineno);
void show();
};
void SymbolTable::show() {
for (int i = 0; i < MAX; i++) {
Node * start = head[i];
while (start != NULL) {
cout << "\nName = " << start -> identifier << " Scope = " <<
start -> scope << " Type = " << start -> type <<
" Line No = " << start -> lineNo << "\n ";
start = start -> next;
}

}
}
// Function to modify an identifier
bool SymbolTable::modify(string id, string s, string t, int l) {
int index = hashf(id);
Node * start = head[index];

if (start == NULL)
return "-1";

while (start != NULL) {


if (start -> identifier == id) {
start -> scope = s;
start -> type = t;
start -> lineNo = l;
return true;
}
start = start -> next;
}

return false; // id not found


}

// Function to delete an identifier


bool SymbolTable::deleteRecord(string id) {
int index = hashf(id);
Node * tmp = head[index];
Node * par = head[index];

// no identifier is present at that index


if (tmp == NULL) {
return false;
}
// only one identifier is present
if (tmp -> identifier == id && tmp -> next == NULL) {
tmp -> next = NULL;
delete tmp;
return true;
}
while (tmp -> identifier != id && tmp -> next != NULL) {
par = tmp;
tmp = tmp -> next;
}
if (tmp -> identifier == id && tmp -> next != NULL) {
par -> next = tmp -> next;
tmp -> next = NULL;
delete tmp;
return true;
}

// delete at the end


else {
par -> next = NULL;
tmp -> next = NULL;
delete tmp;
return true;
}
return false;
}

// Function to find an identifier


string SymbolTable::find(string id) {
int index = hashf(id);
Node * start = head[index];

if (start == NULL)
return "-1";

while (start != NULL) {

if (start -> identifier == id) {


start -> print();
return start -> scope;
}

start = start -> next;


}
return "-1"; // not found
}

// Function to insert an identifier


bool SymbolTable::insert(string id, string scope, string Type, int lineno) {
int index = hashf(id);
Node * p = new Node(id, scope, Type, lineno);

if (head[index] == NULL) {
head[index] = p;
cout << "\n" <<
id << " inserted";
return true;
} else {
Node * start = head[index];
while (start -> next != NULL)
start = start -> next;

start -> next = p;


cout << "\n" <<
id << " inserted";

return true;
}

return false;
}

int SymbolTable::hashf(string id) {


int asciiSum = 0;

for (int i = 0; i < id.length(); i++) {


asciiSum = asciiSum + id[i];
}

return (asciiSum % 100);


}

class Token {
string token;
bool validToken;
bool isDeclared;
public:
Token() {

}
Token(string token, bool validation) {
this -> token = token;
this -> validToken = validation;
}
string getToken() {
return this -> token;
}
bool getValidation() {
return this -> validToken;
}
bool getDeclaration() {
return this -> isDeclared;
}
};
vector < Token > tokenizeInstruction(string mData) {
vector < Token > tokens;
string token = "";
for (auto x: mData) {
if (x == ' ') {
Token t = Token(token, false);
tokens.push_back(t);
token = "";
} else {
token = token + x;
}
}
Token t = Token(token, false);
tokens.push_back(t);
return tokens;
}

class Lexer {
vector < string > data;
public:
Lexer(vector < string > data) {
this -> data = data;
}

void symbolTableCreation(vector < string > pInstruction) {


SymbolTable st;
vector < Token > insTok;

for (int i = 0; i < pInstruction.size(); i++) {


insTok = tokenizeInstruction(pInstruction[i]);
if (isDataType(insTok[0].getToken())) {
if (isIdentifier(insTok[1].getToken())) {
if (insTok[2].getToken() == "(") {
if (st.insert(insTok[1].getToken(), "function", insTok[0].getToken(), i)) {
cout << "\nAdded" << endl;
}
}
}
}
if (isDataType(insTok[0].getToken())) {
if (isIdentifier(insTok[1].getToken())) {
if (insTok[2].getToken() == "(") {
if (isDataType(insTok[3].getToken())) {
if (isIdentifier(insTok[4].getToken())) {
if (st.insert(insTok[4].getToken(), "parameter", insTok[0].getToken(), i)) {
cout << "\nAdded" << endl;
}
}
}
}
}
}

if (isDataType(insTok[0].getToken())) {
if (isIdentifier(insTok[1].getToken())) {
if (insTok[2].getToken() == ";") {
if (st.insert(insTok[1].getToken(), "global local", insTok[0].getToken(), i)) {
cout << "\nAdded" << endl;
}
} else if (insTok[2].getToken() == "=") {
if (isConstant(insTok[3].getToken())) {
if (insTok[4].getToken() == ";") {
if (st.insert(insTok[1].getToken(), "global local", insTok[0].getToken(), i)) {
cout << "\nAdded" << endl;
}
}
}
}
}
}

if (insTok[0].getToken() == "else if") {


if (insTok[1].getToken() == "(") {
int i = 2;
while (insTok[i].getToken() != ")") {
i++;
}
if (insTok[i].getToken() == ")") {
if (insTok[i + 1].getToken() == "{") {
for (int i = 0; i < insTok.size(); i++) {
if (isIdentifier(insTok[i].getToken())) {
if (isDataType(insTok[i - 1].getToken())) {
if (st.insert(insTok[i].getToken(), "else if local", insTok[i - 1].getToken(), i)) {
cout << "\n\n It Is Inserted";
}
}
}
}
}
}
}
}
if (insTok[0].getToken() == "else") {
if (insTok[1].getToken() == "{") {
for (int i = 0; i < insTok.size(); i++) {
if (isIdentifier(insTok[i].getToken())) {
if (isDataType(insTok[i - 1].getToken())) {

if (st.insert(insTok[i].getToken(), "else local", insTok[i - 1].getToken(), i)) {


cout << "\n\n It Is Inserted";
}
}
}
}
}
}
if (insTok[0].getToken() == "if") {
if (insTok[1].getToken() == "(") {
int i = 2;
while (insTok[i].getToken() != ")") {
i++;
}
if (insTok[i].getToken() == ")") {
if (insTok[i + 1].getToken() == "{") {
for (int i = 0; i < insTok.size(); i++) {
if (isIdentifier(insTok[i].getToken())) {
if (isDataType(insTok[i - 1].getToken())) {
if (st.insert(insTok[i].getToken(), "if local", insTok[i - 1].getToken(), i)) {
cout << "\n\n It Is Inserted";
}
}
}
}
}
}
}
}
if (insTok[0].getToken() == "for") {
if (insTok[1].getToken() == "(") {
int i = 2;
while (insTok[i].getToken() != ")") {
i++;
}
if (insTok[i].getToken() == ")") {
if (insTok[i + 1].getToken() == "{") {
for (int i = 0; i < insTok.size(); i++) {
if (isIdentifier(insTok[i].getToken())) {
if (isDataType(insTok[i - 1].getToken())) {
if (st.insert(insTok[i].getToken(), "for local", insTok[i - 1].getToken(), i)) {
cout << "\n\n It Is Inserted";
}
}
}
}
}
}
}
}
if (insTok[0].getToken() == "while") {
if (insTok[1].getToken() == "(") {
int i = 2;
while (insTok[i].getToken() != ")") {
i++;
}
if (insTok[i].getToken() == ")") {
if (insTok[i + 1].getToken() == "{") {
for (int i = 0; i < insTok.size(); i++) {
if (isIdentifier(insTok[i].getToken())) {
if (isDataType(insTok[i - 1].getToken())) {
if (st.insert(insTok[i].getToken(), "while local", insTok[i - 1].getToken(), i)) {
cout << "\n\n It Is Inserted";
}
}
}
}
}
}
}
}
}
st.show();
}
};
void readFromFile() {
fstream fileObj;
bool comment = false, multiComment = false;
string newString = "", temp = "";
int i = 0;
fileObj.open("newFile.txt", ios:: in );
if (fileObj.is_open()) {
while (!fileObj.eof()) {
multiComment = false;
comment = false;
getline(fileObj, temp); //READ LINE BY LINE
//fileObj >> temp;//reading word by word will remove the spaces from file
//REMOVE COMMENTS
if (temp[0] == '/') {
if (temp[1] == '/') {
comment = true;
//getline(fileObj, temp);
} else if (temp[1] == '*') {
multiComment = true;
getline(fileObj, temp);
while (temp[temp.length() - 2] != '*' && temp[temp.length() - 1] != '/') {
//fileObj >> temp;
getline(fileObj, temp);
}
}
}
if (!comment && !multiComment) {
newString += temp;
mInstruction.push_back(temp);
}
}
}
Lexer obj(mInstruction);
obj.symbolTableCreation(mInstruction);
}
int main() {
string stringFromFile = "";
writeToFile();
readFromFile();
cout << "\n\n\n\t\t Instructions In Vector\n\n\n";
for (int i = 0; i < mInstruction.size(); i++) {
cout << mInstruction[i] << " " << endl;
}
cout << "\n\n\n";
return 0;
}
}
Helping Code:
// CC_Lab 07.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
// C++ program to implement Symbol Table
#include <iostream>
#include<fstream>
#include<vector>
#include<string>
using namespace std;

const int MAX = 100;

vector<string> keywords;
vector<string> dataTypes;
vector<string> constants;
vector<string> operators;
vector<string> identifiers;
vector<string> mInstruction;
vector<string> invalidToken;
string isSpace(string& stringFromFile)
{
string newString;
int countSpaces = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == ' ')
{
countSpaces++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Spaces = " << countSpaces << endl;
return newString;
}
string isEndl(string& stringFromFile)
{
string newString = "";
int countEndl = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == '\n')
{
countEndl++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Endl = " << countEndl << endl;
return newString;
}
string isTab(string& stringFromFile)
{
string newString = "";
int countTabs = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == '\t')
{
countTabs++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Tabs = " << countTabs << endl;
return newString;
}
string isComma(string& stringFromFile)
{
string newString = "";
int countComma = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == ',')
{
countComma++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Commas = " << countComma << endl;
return newString;
}
string isParanthesis(string& stringFromFile)
{
string newString = "";
int countPar = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == '(' || stringFromFile[i] == ')')
{
countPar++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Paranthesis = " << countPar << endl;
return newString;
}
string isBracket(string& stringFromFile)
{
string newString = "";
int countBracket = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == '{' || stringFromFile[i] == '}')
{
countBracket++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Bracket = " << countBracket << endl;
return newString;
}
string isSemiColon(string& stringFromFile)
{
string newString = "";
int countSemiColon = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == ';')
{
countSemiColon++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of SemiColon = " << countSemiColon << endl;
return newString;
}
bool isOperator(string stringFromFile)
{
if (stringFromFile == "+" || stringFromFile == "-" || stringFromFile ==
"" || stringFromFile == "/" || stringFromFile == "%" || stringFromFile == "++"
|| stringFromFile == "--" || stringFromFile == "/=" || stringFromFile == "=" ||
stringFromFile == "-=" || stringFromFile == "==" || stringFromFile == ">=" ||
stringFromFile == "<=" || stringFromFile == ">" || stringFromFile == "<")
{
return true;
}
return false;
}
bool isIdentifier(string stringFromFile)
{
if (stringFromFile[0] == '_' || (stringFromFile[0] >= 65 &&
stringFromFile[0] <= 90) || (stringFromFile[0] >= 97 && stringFromFile[0] <=
122))
{
for (int i = 0; i < stringFromFile.length(); i++)
{
string temp(1, stringFromFile[i]);
if (stringFromFile[i] == '=' || stringFromFile[i] == '!'
|| stringFromFile[i] == '@' || stringFromFile[i] == '"' || stringFromFile[i] ==
'\'' || stringFromFile[i] == '#' || stringFromFile[i] == isOperator(temp))
{
return false;
}
else if (i == stringFromFile.length())
{
return true;
}
}
return true;
}
return false;
}
bool isConstant(string stringFromFile)
{
int i = 0;
while (i < stringFromFile.length())
{
if (isdigit(stringFromFile[i]))
{
if (i == stringFromFile.length() - 1)
{
return true;
}
}
i++;
}
return false;
}
bool isDataType(string pTok){
vector<string> dataTypes{ "double", "int", "long", "char", "char*",
"float", "void", "bool" };
for (int i = 0; i < dataTypes.size(); i++)
{
if (pTok == dataTypes[i])
{
return true;
}
}
return false;
}
bool isKeyWord(string pTok)
{
vector<string> keywords{ "auto", "struct", "break", "else", "long",
"switch", "case", "enum", "register", "typedef",
"extern", "return", "union", "const", "short",
"unsigned", "continue", "for", "signed", "default",
"goto", "sizeof", "voltile", "do", "if", "static", "while",
"class", "false", "true"
};
for (int i = 0; i < keywords.size(); i++)
{
if (pTok == keywords[i])
{
return true;
}
}
return false;
}
bool Check_DFA_VN(int current_state, int current_index, string token)
{
if (current_state == 0 && (isalpha(token[current_index]) ||
token[current_index] == '_'))
{
current_state = 1;
if (current_index + 1 < token.length())
{
return Check_DFA_VN(current_state, current_index + 1,
token);
}
else
{
return true;
}
}
else if (current_state == 1 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_'))
{
current_state = 2;
if (current_index + 1 < token.length())
{
return Check_DFA_VN(current_state, current_index + 1,
token);
}
else
{
return true;
}
}
else if (current_state == 2 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_'))
{
current_state = 3;
if (current_index + 1 < token.length())
{
return Check_DFA_VN(current_state, current_index + 1,
token);
}
else
{
return true;
}
}
else if (current_state == 3 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_'))
{
current_state = 4;
if (current_index + 1 < token.length())
{
return Check_DFA_VN(current_state, current_index + 1,
token);
}
else
{
return true;
}
}
else if (current_state == 4 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_'))
{
current_state = 5;
if (current_index + 1 < token.length() && token[current_index +
1] != NULL)
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}
void writeToFile()
{
fstream fileObj;
fileObj.open("file.txt", fstream::out);
fileObj << "float identifier = 10000 ; //initialized a float\n
identifier = 10 + 12 ; ";
fileObj.close();
}
class Token {
string token;
bool validToken;
bool isDeclared;
public:
Token()
{

}
Token(string token, bool validation)
{
this->token = token;
this->validToken = validation;
}
string getToken()
{
return this->token;
}
bool getValidation()
{
return this->validToken;
}
bool getDeclaration(){ return this->isDeclared; }
};
vector<Token> tokenizeInstruction(string mData){
vector<Token> tokens;
string token = "";
for (auto x : mData)
{
if (x == ' ')
{
Token t = Token(token, false);
tokens.push_back(t);
token = "";
}
else {
token = token + x;
}
}
Token t = Token(token, false);
tokens.push_back(t);
return tokens;
}

class Node {
string identifier, scope, type;
int lineNo;
Node* next;

public:
Node(){
next = NULL;
}
Node(string key, string value, string type, int lineNo){
this->identifier = key;
this->scope = value;
this->type = type;
this->lineNo = lineNo;
next = NULL;
}
void print(){
cout << "Identifier's Name:" << identifier
<< "\nType:" << type
<< "\nScope: " << scope
<< "\nLine Number: " << lineNo << endl;
}
friend class SymbolTable;
};
class SymbolTable {
Node* head[MAX];
public:
SymbolTable(){
for (int i = 0; i < MAX; i++)
head[i] = NULL;
}
int hashf(string id); // hash function
bool insert(string id, string scope, string Type, int lineno);
string find(string id);
bool deleteRecord(string id);
bool modify(string id, string scope, string Type, int lineno);
};
class Lexer {
vector<string> data;
public:
Lexer(vector<string> data)
{
this->data = data;
}
void scanningInstruction()
{
vector<Token> insTok;
for (int i = 0; i < data.size(); i++)
{
insTok = tokenizeInstruction(data[i]);
for (int i = 0; i < insTok.size(); i++){
string strTok = insTok[i].getToken();
if (isKeyWord(strTok)){
keywords.push_back(strTok);
}
else if (isDataType(strTok)){
dataTypes.push_back(strTok);
}
else if (isOperator(strTok)){
operators.push_back(strTok);
}
else if (isConstant(strTok)){
constants.push_back(strTok);
}
else if (isIdentifier(strTok)){
identifiers.push_back(strTok);
}
else{
invalidToken.push_back(strTok);
}
}
}
}
void symbolTableCreation(vector<string> pInstruction){
SymbolTable st;
vector<Token> tokens;
for (int i = 0; i < pInstruction.size(); i++){
tokens = tokenizeInstruction(pInstruction[i]);
for (int j = 0; j < tokens.size(); j++){
string t = tokens[j].getToken();
//a new Token Insertion
//Function
//returnType Name(DataType Parameter1, DataType
Parameter2)

//Function Parameters

//Declaration

//Assignment OR Expression
//Definition of Identifier

//Already Defined Identifier

//Loop Statement
//Loop
//For
//While
//Conditional
//if
//else if
//else
//switch

//Class
//ClassKeyword Name

//Already defined token occured!.

}
}
}
};
// Function to modify an identifier
bool SymbolTable::modify(string id, string s, string t, int l){
int index = hashf(id);
Node* start = head[index];

if (start == NULL)
return "-1";

while (start != NULL) {


if (start->identifier == id) {
start->scope = s;
start->type = t;
start->lineNo = l;
return true;
}
start = start->next;
}

return false; // id not found


}

// Function to delete an identifier


bool SymbolTable::deleteRecord(string id){
int index = hashf(id);
Node* tmp = head[index];
Node* par = head[index];

// no identifier is present at that index


if (tmp == NULL) {
return false;
}
// only one identifier is present
if (tmp->identifier == id && tmp->next == NULL) {
tmp->next = NULL;
delete tmp;
return true;
}

while (tmp->identifier != id && tmp->next != NULL) {


par = tmp;
tmp = tmp->next;
}
if (tmp->identifier == id && tmp->next != NULL) {
par->next = tmp->next;
tmp->next = NULL;
delete tmp;
return true;
}

// delete at the end


else {
par->next = NULL;
tmp->next = NULL;
delete tmp;
return true;
}
return false;
}

// Function to find an identifier


string SymbolTable::find(string id){
int index = hashf(id);
Node* start = head[index];

if (start == NULL)
return "-1";

while (start != NULL) {


if (start->identifier == id) {
start->print();
return start->scope;
}

start = start->next;
}

return "-1"; // not found


}

// Function to insert an identifier


bool SymbolTable::insert(string id, string scope, string Type, int lineno){
int index = hashf(id);
Node* p = new Node(id, scope, Type, lineno);

if (head[index] == NULL) {
head[index] = p;
cout << "\n"
<< id << " inserted";

return true;
}

else {
Node* start = head[index];
while (start->next != NULL)
start = start->next;

start->next = p;
cout << "\n"
<< id << " inserted";

return true;
}

return false;
}

int SymbolTable::hashf(string id){


int asciiSum = 0;

for (int i = 0; i < id.length(); i++) {


asciiSum = asciiSum + id[i];
}

return (asciiSum % 100);


}

void readFromFile()
{
fstream fileObj;
bool comment = false, multiComment = false;
string newString = "", temp = "";
int i = 0;
fileObj.open("newFile.txt", ios::in);
if (fileObj.is_open())
{
while (!fileObj.eof())
{
multiComment = false;
comment = false;
getline(fileObj, temp); //READ LINE BY LINE
//fileObj >> temp;//reading word by word will remove the
spaces from file
//REMOVE COMMENTS
if (temp[0] == '/') {
if (temp[1] == '/') {
comment = true;
//getline(fileObj, temp);
}
else if (temp[1] == '*')
{
multiComment = true;
getline(fileObj, temp);
while (temp[temp.length() - 2] != '*' &&
temp[temp.length() - 1] != '/')
{
//fileObj >> temp;
getline(fileObj, temp);
}
}
}
if (!comment && !multiComment)
{
newString += temp;
mInstruction.push_back(temp);
}
}
}
Lexer obj(mInstruction);
//Scanning
obj.scanningInstruction();
//Symbol Table Creation
obj.symbolTableCreation(mInstruction);
}

// Driver code
int main()
{
SymbolTable st;
string check;
cout << "**** SYMBOL_TABLE ****\n";

// insert 'if'
if (st.insert("if", "local", "keyword", 4))
cout << " -successfully";
else
cout << "\nFailed to insert.\n";

// insert 'number'
if (st.insert("number", "global", "variable", 2))
cout << " -successfully\n\n";
else
cout << "\nFailed to insert\n";

// find 'if'
check = st.find("if");
if (check != "-1")
cout << "Identifier Is present\n";
else
cout << "\nIdentifier Not Present\n";
// delete 'if'
if (st.deleteRecord("if"))
cout << "if Identifier is deleted\n";
else
cout << "\nFailed to delete\n";

// modify 'number'
if (st.modify("number", "global", "variable", 3))
cout << "\nNumber Identifier updated\n";

// find and print 'number'


check = st.find("number");
if (check != "-1")
cout << "Identifier Is present\n";
else
cout << "\nIdentifier Not Present";

return 0;
}

Lab Grading Sheet :

Max Obtained
Task Comments(if any)
Marks Marks
1. 10

2. 10

3. 10

Note : Attempt all tasks and get them checked by your Lab Instructor

Lab 6: Introduction to Symbol Table

Objective:
 Symbol Table Introduction | Construction of symbol table using Dictionary |
Understanding Usage in DFA and CFG construction Step
Tools Used:
 Visual Studio 2010/2013
Context Free Grammar

Symbol table is an important data structure created and maintained by


compilers in order to store information about the occurrence of various
entities such as variable names, function names, objects, classes, interfaces,
etc. Symbol table is used by both the analysis and the synthesis parts of a
compiler.
A symbol table may serve the following purposes depending upon the
language in hand:
 To store the names of all entities in a structured form at one place.
 To verify if a variable has been declared.
 To implement type checking, by verifying assignments and expressions in the
source code are semantically correct.
 To determine the scope of a name (scope resolution).

If a compiler is to handle a small amount of data, then the symbol table can
be implemented as an unordered list, which is easy to code, but it is only
suitable for small tables only. A symbol table can be implemented in one of
the following ways:

 Linear (sorted or unsorted) list


 Binary Search Tree
 Hash table
Among all, symbol tables are mostly implemented as hash tables, where the
source code symbol itself is treated as a key for the hash function and the
return value is the information about the symbol

// CC_Lab 06.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<vector>
#include<string>
using namespace std;
vector<string> keywords;
vector<string> dataTypes;
vector<string> constants;
vector<string> operators;
vector<string> identifiers;
vector<string> mInstruction;
vector<string> invalidToken;
string isSpace(string& stringFromFile)
{
string newString;
int countSpaces = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == ' ')
{
countSpaces++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Spaces = " << countSpaces << endl;
return newString;
}
string isEndl(string& stringFromFile)
{
string newString = "";
int countEndl = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == '\n')
{
countEndl++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Endl = " << countEndl << endl;
return newString;
}
string isTab(string& stringFromFile)
{
string newString = "";
int countTabs = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == '\t')
{
countTabs++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Tabs = " << countTabs << endl;
return newString;
}
string isComma(string& stringFromFile)
{
string newString = "";
int countComma = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == ',')
{
countComma++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Commas = " << countComma << endl;
return newString;
}
string isParanthesis(string& stringFromFile)
{
string newString = "";
int countPar = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == '(' || stringFromFile[i] == ')')
{
countPar++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Paranthesis = " << countPar << endl;
return newString;
}
string isBracket(string& stringFromFile)
{
string newString = "";
int countBracket = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == '{' || stringFromFile[i] == '}')
{
countBracket++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of Bracket = " << countBracket << endl;
return newString;
}
string isSemiColon(string& stringFromFile)
{
string newString = "";
int countSemiColon = 0;
for (int i = 0; i < stringFromFile.length(); i++)
{
if (stringFromFile[i] == ';')
{
countSemiColon++;
}
else
{
newString += stringFromFile[i];
}
}
cout << "\n\n Number Of SemiColon = " << countSemiColon << endl;
return newString;
}
bool isOperator(string stringFromFile)
{
if (stringFromFile == "+" || stringFromFile == "-" || stringFromFile == "" ||
stringFromFile == "/" || stringFromFile == "%" || stringFromFile == "++" || stringFromFile ==
"--" || stringFromFile == "/=" || stringFromFile == "=" || stringFromFile == "-=" ||
stringFromFile == "==" || stringFromFile == ">=" || stringFromFile == "<=" || stringFromFile
== ">" || stringFromFile == "<")
{
return true;
}
return false;
}
bool isIdentifier(string stringFromFile)
{
if (stringFromFile[0] == '_' || (stringFromFile[0] >= 65 && stringFromFile[0] <= 90) ||
(stringFromFile[0] >= 97 && stringFromFile[0] <= 122))
{
for (int i = 0; i < stringFromFile.length(); i++)
{
string temp(1, stringFromFile[i]);
if (stringFromFile[i] == '=' || stringFromFile[i] == '!' ||
stringFromFile[i] == '@' || stringFromFile[i] == '"' || stringFromFile[i] == '\'' ||
stringFromFile[i] == '#' || stringFromFile[i] == isOperator(temp))
{
return false;
}
else if (i == stringFromFile.length())
{
return true;
}
}
return true;
}
return false;
}
bool isConstant(string stringFromFile)
{
int i = 0;
while (i < stringFromFile.length())
{
if (isdigit(stringFromFile[i]))
{
if (i == stringFromFile.length() - 1)
{
return true;
}
}
i++;
}
return false;
}
bool isDataType(string pTok){
vector<string> dataTypes{ "double", "int", "long", "char", "char*","float", "void",
"bool"};
for (int i = 0; i < dataTypes.size(); i++)
{
if (pTok == dataTypes[i])
{
return true;
}
}
return false;
}
bool isKeyWord(string pTok)
{
vector<string> keywords{ "auto", "struct", "break", "else", "long",
"switch", "case", "enum", "register", "typedef",
"extern", "return", "union", "const", "short",
"unsigned", "continue", "for", "signed", "default",
"goto", "sizeof", "voltile", "do", "if", "static", "while", "class", "false", "true"
};
for (int i = 0; i < keywords.size(); i++)
{
if (pTok == keywords[i])
{
return true;
}
}
return false;
}
bool Check_DFA_VN(int current_state, int current_index, string token)
{
if (current_state == 0 && (isalpha(token[current_index]) || token[current_index] ==
'_'))
{
current_state = 1;
if (current_index + 1 < token.length())
{
return Check_DFA_VN(current_state, current_index + 1, token);
}
else
{
return true;
}
}
else if (current_state == 1 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_'))
{
current_state = 2;
if (current_index + 1 < token.length())
{
return Check_DFA_VN(current_state, current_index + 1, token);
}
else
{
return true;
}
}
else if (current_state == 2 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_'))
{
current_state = 3;
if (current_index + 1 < token.length())
{
return Check_DFA_VN(current_state, current_index + 1, token);
}
else
{
return true;
}
}
else if (current_state == 3 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_'))
{
current_state = 4;
if (current_index + 1 < token.length())
{
return Check_DFA_VN(current_state, current_index + 1, token);
}
else
{
return true;
}
}
else if (current_state == 4 && (isalpha(token[current_index]) ||
isdigit(token[current_index]) || token[current_index] == '_'))
{
current_state = 5;
if (current_index + 1 < token.length() && token[current_index + 1] != NULL)
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}
void writeToFile()
{
fstream fileObj;
fileObj.open("file.txt", fstream::out);
fileObj << "float identifier = 10000 ; //initialized a float\n identifier = 10 + 12 ; ";
fileObj.close();
}
void processInstruction(string pInstruction){
}
class Token {
string token;
bool validToken;
bool isDeclared;
public:
Token()
{

}
Token(string token, bool validation)
{
this->token = token;
this->validToken = validation;
}
string getToken()
{
return this->token;
}
bool getValidation()
{
return this->validToken;
}
bool getDeclaration(){ return this->isDeclared; }
};
vector<Token> tokenizeInstruction(string mData){
vector<Token> tokens;
string token = "";
for (auto x : mData)
{
if (x == ' ')
{
Token t = Token(token, false);
tokens.push_back(t);
token = "";
}
else {
token = token + x;
}
}
Token t = Token(token, false);
tokens.push_back(t);
return tokens;
}
class Lexer {
vector<string> data;
public:
Lexer(vector<string> data)
{
this->data = data;
}
void scanningInstruction()
{
vector<Token> insTok;
for (int i = 0; i < data.size(); i++)
{
insTok = tokenizeInstruction(data[i]);
for (int i = 0; i < insTok.size(); i++){
string strTok = insTok[i].getToken();
if (isKeyWord(strTok)){
keywords.push_back(strTok);
}else if (isDataType(strTok)){
dataTypes.push_back(strTok);
}
else if (isOperator(strTok)){
operators.push_back(strTok);
}
else if (isConstant(strTok)){
constants.push_back(strTok);
}
else if (isIdentifier(strTok)){
identifiers.push_back(strTok);
}
else{
invalidToken.push_back(strTok);
}
}
}
}
};
void readFromFile()
{
fstream fileObj;
bool comment = false, multiComment = false;
string newString = "", temp = "";
int i = 0;
fileObj.open("newFile.txt", ios::in);
if (fileObj.is_open())
{
while (!fileObj.eof())
{
multiComment = false;
comment = false;
getline(fileObj, temp); //READ LINE BY LINE
//fileObj >> temp;//reading word by word will remove the spaces
from file
//REMOVE COMMENTS
if (temp[0] == '/') {
if (temp[1] == '/') {
comment = true;
//getline(fileObj, temp);
}
else if (temp[1] == '*')
{
multiComment = true;
getline(fileObj, temp);
while (temp[temp.length() - 2] != '*' &&
temp[temp.length() - 1] != '/')
{
//fileObj >> temp;
getline(fileObj, temp);
}
}
}
if (!comment && !multiComment)
{
newString += temp;
mInstruction.push_back(temp);
}
}
}
Lexer obj(mInstruction);
//Scanning
obj.scanningInstruction();
//cout << "\n\n String After Removing Comments And Spaces : " << newString <<
endl;
}
int main()
{
string stringFromFile = "";
//writeToFile();
readFromFile();
cout << "\n\n\n List Of Keywords : ";
for (int i = 0; i < keywords.size(); i++) {
cout << keywords[i] << " ";
}
cout << "\n\n\n List Of Data Types : ";
for (int i = 0; i < dataTypes.size(); i++) {
cout << dataTypes[i] << " ";
}

stringFromFile = isComma(stringFromFile);
stringFromFile = isSemiColon(stringFromFile);
stringFromFile = isParanthesis(stringFromFile);
stringFromFile = isBracket(stringFromFile);

cout << "\n\n List Of Identifiers : ";


for (int i = 0; i < identifiers.size(); i++) {
cout << identifiers[i] << " ";
}
cout << "\n\n\n List Of Constants and Numbers : ";
for (int i = 0; i < constants.size(); i++) {
cout << constants[i] << " ";
}

cout << "\n\n\n List Of Operators : ";


for (int i = 0; i < operators.size(); i++) {
cout << operators[i] << " ";
}

cout << "\n\n\n Whole Instruction In Vector : ";


for (int i = 0; i < mInstruction.size(); i++) {
cout << mInstruction[i] << " "<<endl;
}
cout << "\n\n\n";
return 0;
}

You might also like