Jump to content
  • Advertisement
Sign in to follow this  

help with symbol table C++

This topic is 3122 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Here I have a simple parser program, and I am trying to add a symbol table to it so basically when it reads int, double or char it will store that as a tokenType and then I want it to read the name afterwords so say i then it will store that in tokenName. I have it storing the type, but I can't seem to wrap my head around having it read the next token without making it hardcoded to be a certain name like how I did int, double and char... any input would be very helpful, thank you. Here is my code so far:
int main(int argc, char* argv[])
{
	//input object
	ifstream source;

	//variables to store line, token, and
	//boolean to determine end of line read
	string myline;
	string token = "";
	bool done = false;

	//Structure for symbol table
	struct item
	{
		string tokenType;
		string tokenName;
	}table[1000];

	//position in line read
	int pos = 0;
	int i = 0;

	//Open source file
	//source.open(argv[0]);
	source.open("input.txt");
	if(!source.is_open())
	{
		cout << "cant open file!";
		return 0;
	}

	//Read til end of file
	do
	{
		done = false;
		
		//get line from input file
		getline(source, myline);

		if(!source.eof())
		{
			//do... while until line is read
			do
			{
				char c = myline[pos++];
				if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
				{
					token = token + c;
				}
				else if(c == '(' || c == ')' || c == '{' || c == '}' || c == ';'
					|| c == '=' || c == '+' || c >= 0 || c <= 0)
				{
					if(token == "int" || token == "double" || token == "char")
					{
						table.tokenType = token;
						i++;
					}
					cout << token << endl;
					token = "";
					cout << c << endl;
				}
				if (pos >= myline.length())
				{
					done = true;
					pos = 0;
				}
			}while(!done);
		}
	}while(!source.eof());

	//close input file
	source.close();

	//table format
	cout << "Type      Variable Name\n";

	//loop to display each of the symbol tables data
	for(int j = 0; j < i; j++)
	{
		cout << table[j].tokenType << "        " << table[j].tokenName << endl;
	}

	system("pause");

	return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
After you read the token type, assuming there's some sort of whitespace following, can't you just read in the remainder of the line (or until ';' or some other terminator is reached, etc.) and store whatever occurs?

FYI, if you have it, you may want to look at some of the "is" routines in the C run-time library: isalpha, isalnum, etc.

Share this post


Link to post
Share on other sites
I thought that something like this would work, but nothing seems to be happening or at least that I see... anyone have any ideas here?

Here is my code so far:


int main(int argc, char* argv[])
{
//input object
ifstream source;

//variables to store line, token, and
//boolean to determine end of line read
string myline;
string token = "";
string tName = "";
bool done = false;

//Structure for symbol table
struct item
{
string tokenType;
string tokenName;
}table[1000];

//position in line read
int pos = 0;
int i = 0;

//Open source file
//source.open(argv[0]);
source.open("input.txt");
if(!source.is_open())
{
cout << "cant open file!";
return 0;
}

//Read til end of file
do
{
done = false;

//get line from input file
getline(source, myline);

if(!source.eof())
{
//do... while until line is read
do
{
char c = myline[pos++];
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
token = token + c;
}
else if(c == '(' || c == ')' || c == '{' || c == '}' || c == ';'
|| c == '=' || c == '+' || c >= 0 || c <= 0)
{
if(token == "int" || token == "double" || token == "char")
{
table.tokenType = token;
c = myline[pos++];
if(c == ' ')
{
if(c != ';')
{
c = myline[pos++];
tName = tName + c;
}
}
table.tokenName = tName;
i++;
}
cout << token << endl;
token = "";
cout << c << endl;
}
if (pos >= myline.length())
{
done = true;
pos = 0;
}
}while(!done);
}
}while(!source.eof());

//close input file
source.close();

//table format
cout << "Type Variable Name\n";

//loop to display each of the symbol tables data
for(int j = 0; j < i; j++)
{
cout << table[j].tokenType << " " << table[j].tokenName << endl;
}

system("pause");

return 0;
}

Share this post


Link to post
Share on other sites
What's up with:

else if(c == '(' || c == ')' || c == '{' || c == '}' || c == ';'
|| c == '=' || c == '+' || c >= 0 || c <= 0)
and..

if(c == ' ')
{
if(c != ';')
?

That said, I might have misunderstood your intentions, but does this help:

#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <cctype>

struct Item
{
std::string tokenType, tokenName;

Item(std::string tokenType, std::string tokenName)
: tokenType(tokenType), tokenName(tokenName) {}
};

std::ostream& operator<<(std::ostream& os, const Item& item)
{
return os << item.tokenType << "\t" << item.tokenName;
}

typedef std::vector<Item> Table;

bool DelimPred(char c)
{
return !std::isalpha(c);
}

int main()
{
Table table;

//Open source file
std::ifstream source("input.txt");
if(!source)
{
std::cerr << "cant open file!" << std::endl;
return 0;
}

//Read til end of file
while(source.good())
{
//get line from input file
std::string line;
std::getline(source, line);

std::string::iterator it = std::find_if(line.begin(), line.end(), DelimPred);
if(it == line.end())
{
std::cerr << "Malformed line: " << line << std::endl;
continue;
}

table.push_back(Item(std::string(line.begin(), it), std::string(it + 1, line.end())));
}

//table format
std::cout << "Type\tVariable Name" << std::endl;

// display each of the symbol tables data
std::copy(table.begin(), table.end(), std::ostream_iterator<Item>(std::cout, "\n"));
}


Share this post


Link to post
Share on other sites
All those are the characters I want to read only. All of that reads fine the ' ' and ';' are ones I want to cancel the reading on the type and variable name. Basically what I want the symbol table to look like would be this, if I input a file that has

main()
{
int num;
return 0;
}


Aside from the parser it would output the following...

Type Variable Name
int num


so far I got it doing all but the num part, any ideas on this?

Share this post


Link to post
Share on other sites
Okay I got it reading the variable name after the type and displaying it properly except for one minor problem it is adding the ; in there as well, I have to look at my confusing jumble of mess to see if I can find the problem, if you see it please feel free to point it out to me, thank you.

Here is my code now:

int main(int argc, char* argv[])
{
//input object
ifstream source;

//variables to store line, token, and
//boolean to determine end of line read
string myline;
string token = "";
string tName = "";
bool done = false;

//Structure for symbol table
struct item
{
string tokenType;
string tokenName;
}table[1000];

//position in line read
int pos = 0;
int i = 0;

//Open source file
//source.open(argv[0]);
source.open("input.txt");
if(!source.is_open())
{
cout << "cant open file!";
return 0;
}

//Read til end of file
do
{
done = false;

//get line from input file
getline(source, myline);

if(!source.eof())
{
//do... while until line is read
do
{
char c = myline[pos++];
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
token = token + c;
}
else if(c == '(' || c == ')' || c == '{' || c == '}' || c == ';'
|| c == '=' || c == '+' || c >= 0 || c <= 0)
{
if(token == "int" || token == "double" || token == "char")
{
table.tokenType = token;
while(c != ';')
{
c = myline[pos++];
tName = tName + c;
}
table.tokenName = tName;
i++;
}
cout << token << endl;
if(tName != "")
{
cout << tName << endl;
}
token = "";
tName = "";
cout << c << endl;
}
if (pos >= myline.length())
{
done = true;
pos = 0;
}
}while(!done);
}
}while(!source.eof());

//close input file
source.close();

//table format
cout << "Type Variable Name\n";

//loop to display each of the symbol tables data
for(int j = 0; j < i; j++)
{
cout << table[j].tokenType << " " << table[j].tokenName << endl;
}

system("pause");

return 0;
}




This is what my output looks like for the symbol table now,


Type Variable Name
int num;


**EDIT figured out that semi-colon problem so far it is running almost perfect, I need it to loop that process if a ',' is found.

Share this post


Link to post
Share on other sites
You should really really tokenize your input _before_ you parse it. That'll simplify your code considerably. Your code as it is demonstrates a rather weird and incorrect idea of what a token is.

Share this post


Link to post
Share on other sites
Quote:
Original post by wicked357
*** Source Snippet Removed ***
mattd's point was that your else condition is always true:

else if(c == '(' || c == ')' || c == '{' || c == '}' || c == ';' || c == '=' || c == '+' || c >= 0 || c <= 0)

Note the last two clauses - c must always be either <= or >= zero (because those two cases include all possible numbers). Thus, you can replace that massive else if(...) with a simple else statement.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!