0% found this document useful (0 votes)
86 views20 pages

Lab-Journal Compiler Construction

The document discusses symbol tables which are data structures used by compilers to store information about variables, functions, classes and other entities in a program. It describes how symbol tables can be implemented using different data structures like lists and hash tables. The objective of the lab is to introduce symbol tables and how they are constructed using dictionaries to understand their usage in constructing DFAs and CFGs. The tasks involve adding functions to identify declarations, definitions and declaration-definitions by parsing code from a file.

Uploaded by

Abdullah Arshad
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
86 views20 pages

Lab-Journal Compiler Construction

The document discusses symbol tables which are data structures used by compilers to store information about variables, functions, classes and other entities in a program. It describes how symbol tables can be implemented using different data structures like lists and hash tables. The objective of the lab is to introduce symbol tables and how they are constructed using dictionaries to understand their usage in constructing DFAs and CFGs. The tasks involve adding functions to identify declarations, definitions and declaration-definitions by parsing code from a file.

Uploaded by

Abdullah Arshad
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Bahria University, Lahore Campus

Department of Computer Sciences


Lab Journal 06
(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-30______________________

Objective(s):

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


Understanding Usage in DFA and CFG construction Step

Inst -> Declaration | Definition | DeclarationDefinition | Assigment | Block | Loop | Switch

Declaration -> DataType Space VN Space SemiColon

Definition -> VN Space EqualTo Space Value|VN Space SemiColon

DeclarationDefinition -> DataType Space VN Space EqualTo Space Value|VN Space SemiColon

VN -> Aplha Digit | Alpha UnderScore | UnderScore Alpha | UnderScore Alpha Digit |
UnderScore Digit Alpha | UnderScore Digit | Aplha Digit UnderScore | UnderScore
Alpha UnderScore

DataType -> int | bool | char | char* | string | double | float

Space -> Space " " Space | empty

EqualTO -> =

UnderScore -> _

Alpha -> a-z | A-Z

Digit -> 0-9

Department of Computer Sciences, BULC Lab- 1


SemiColon -> ;

Lab Tasks:
Task 1: You are required to add a new function to identify that an instruction is
declaration.
void Declaration() {

fstream obj;
string str, str1;
obj.open("New.txt", ios:: in );
if (obj.is_open()) {
while (!obj.eof()) {
obj >> str;

if (isKeyWord(str)) {

Decleration.push_back(str);
obj >> str;
if (isIdentifier(str)) {

Decleration.push_back(str);
obj >> str;
if (str == ";") {

Decleration.push_back(str);

} else {
Decleration.pop_back();
Decleration.pop_back();
}

}
}

}
cout << "\t------[Decleration]------" << endl;
cout << endl;
cout << endl;
for (int i = 0; i < Decleration.size(); i++) {
if (Decleration[i] == ";") {
cout << Decleration[i] << " ";
cout << endl;
} else
cout << Decleration[i] << " ";
}
cout << "\n\n\n" << endl;
}
OUTPUT:

Task 2: You are required to add a new function to identify that an instruction is definition.
void Definitions() {

fstream obj;
string str, str1;
obj.open("New.txt", ios:: in );
if (obj.is_open()) {
while (!obj.eof()) {
obj >> str;

if (isIdentifier(str)) {
Definition.push_back(str);
obj >> str;
if (str == "=") {
Definition.push_back(str);
obj >> str;
if (isConstant(str) || isIdentifier(str)) {
Definition.push_back(str);
obj >> str;
if (str == ";") {
Definition.push_back(str);
} else {

Definition.pop_back();
}
}
} else {
Definition.pop_back();

}
}
}

}
cout << "\t------[Definition]------" << endl;
cout << endl;
cout << endl;
for (int i = 0; i < Definition.size(); i++) {
if (Definition[i] == ";") {
cout << Definition[i] << " ";
cout << endl;
} else
cout << Definition[i] << " ";

}
cout << "\n\n\n" << endl;
}

OUTPUT:

Task 3: You are required to add a new function to identify that an instruction is
DeclarationDefinition.

void DefinitionsDeclaration() {

fstream obj;
string str, str1;
obj.open("New.txt", ios:: in );
if (obj.is_open()) {
while (!obj.eof()) {
obj >> str;
if (isKeyWord(str)) {
DeclerationDefinition.push_back(str);
obj >> str;
if (isIdentifier(str)) {
DeclerationDefinition.push_back(str);
obj >> str;
if (str == "=") {
DeclerationDefinition.push_back(str);
obj >> str;
if (isConstant(str) || isIdentifier(str)) {
DeclerationDefinition.push_back(str);
obj >> str;
if (str == ";") {
DeclerationDefinition.push_back(str);
} else {

DeclerationDefinition.pop_back();
}
}
} else {
DeclerationDefinition.pop_back();
DeclerationDefinition.pop_back();
}
}
}
}

}
cout << "\t------[DefinitionsDeclaration]------" << endl;
cout << endl;
cout << endl;
for (int i = 0; i < DeclerationDefinition.size(); i++) {
if (DeclerationDefinition[i] == ";") {
cout << DeclerationDefinition[i] << " ";
cout << endl;
} else
cout << DeclerationDefinition[i] << " ";

}
cout << "\n\n\n" << endl;
}
OUTPUT:

Lab Grading Sheet :

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

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