![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Hobbyist Programmer
Join Date: Feb 2006
Posts: 155
Rep Power: 3
![]() |
output - 842150451?
i have a hash table that i am using to store tokens (entries being the token name and token code being the attribute) ... if it sees an error token or identifier, then it inserts it into the symbol table
so i am reading from a text file whose first two lines have [HTML] begin if y=2 then z := 1 else if y=1 then z := 0 else even(y-2) end;[/HTML] ^^^bolded stuff is the problem area ideally, it should have given me Int and id respectively but they both give me - 842150451 .... after tracing it down in my code, what i think the problem is my program ends up finding 1 and z in my hash table which makes sense because it inserted these values when it found them earlier in the text ... what does not make sense is why 842150451 as attribute?? when clearly the attributes of 1 and z had been entered as int and id respectively? #include <string>
#include <math.h>
using namespace std;
const int TableSize = 137;
enum Token {program, var, procedure, // both token and
begin, end, integer, // token type
read, writeln, then,
If, // if is the token
Else, // else is the token
scln, // ; is the token
cln, // : is the token
cma, // , is the token
asgn, // := is the token
plus, // + is the token
minus, // - is the token
mult, // * is the token
Div, // div is the token
eql, // = is the token
neq, // <> is the token
lss, // < is the token
gtr, // > is the token
lp, // ( is the token
rp, // ) is the token
id, Int, String, error, eof};
template <class Attributes>
class item {
public:
item (string s) {
name = s;
}
string getName (void) {return name;}
struct AT{Token type; int value;} theStruct;
private:
string name;
};
//template <class Attributes>
template <class Attributes>
struct HashNode
{
item<Attributes> * info;
HashNode<Attributes> *Next;
};
template <class Attributes>
class SymTab
{
public:
SymTab<Attributes>(); //initializes to the empty table
item<Attributes> * find(string s);//returns item pointer or null
item<Attributes> * insert(string s); //inserts if necessary and returns item pointer
void init_table(string token, Token code);
private:
int Hash(string s)
{
int i = s.length();
//if (i<0) i = 0;
unsigned long string_value = 0;
for (int pos = 0; pos < i; pos++)
string_value = string_value + int(s[pos]) * pow(10,pos);
return string_value%TableSize;
}
HashNode<Attributes> * hashtable[TableSize];
};
template <class Attributes>
void SymTab<Attributes>::init_table(string token, Token code)
{
item <string> *b;
b = insert(token);
b->theStruct.type = code;
//cout <<b->theStruct.type <<flush;
}
template <class Attributes>
item<Attributes> * SymTab<Attributes>::find(string s)
{
int pos = Hash(s);
//cout << pos <<flush;
if (hashtable[pos] == NULL) return NULL; //Symbol not found
HashNode<Attributes> *Current = hashtable[pos];
if (Current != NULL)
{while(Current != NULL)
{
if (Current->info->getName().compare(s) == 0)
return Current->info;
Current = Current->Next;
}}
return NULL;
}
template <class Attributes>
SymTab<Attributes>::SymTab()
{
for (int i = 0; i<TableSize; i++)
{
hashtable[i] = new HashNode<Attributes>;
hashtable[i] = NULL;
}
init_table("program", program);
init_table("var", var);
init_table("procedure", procedure);
init_table("begin", begin);
init_table("end", end);
init_table("integer", integer);
init_table("read", read);
init_table("writeln", writeln);
init_table("then", then);
init_table("if", If);
init_table("else", Else);
init_table(";", scln);
init_table(":", cln);
init_table(",", cma);
init_table(":=", asgn);
init_table(",", cma);
init_table("+", plus);
init_table("-", minus);
init_table("*", mult);
init_table("/", Div);
init_table("=", eql);
init_table("<>", neq);
init_table("<", lss);
init_table(">", gtr);
init_table("(", lp);
init_table(")", rp);
//init_table("eof", eof);
}
template <class Attributes>
item <Attributes> * SymTab <Attributes>::insert(string s)
{
int pos = Hash(s);
if (pos < 1) cout << "skdjk" <<flush;
if (hashtable[pos] == NULL) // Row is empty
{
hashtable[pos] = new HashNode<Attributes>;
hashtable[pos]->info = new item<Attributes>(s);
hashtable[pos]->Next = NULL;
return hashtable[pos]->info;
}
else
{
HashNode<Attributes> *Current = hashtable[pos];
HashNode<Attributes> *nNode;
if (Current != NULL)
{while(Current != NULL && Current->Next != NULL) Current = Current->Next;}
nNode = new HashNode<Attributes>;
nNode->info = new item<Attributes>(s);
nNode->Next = NULL;
Current->Next = nNode;
return Current->info;
}
}
template <class Attributes>
class Scanner {
public:
Scanner(string s) // s is the name of the input file
{
fin.open (s.c_str());
if (fin.fail())
{
cout<<"Couldn't open file"<<endl;
exit(1);
}
}
//bool eof(item<string> *l)
//{return fin.eof;}
item<Attributes>* cget();
void sync ()
{fin.sync();}
private:
item<string>* x;
item<string>* y;
SymTab <string> ST1;
ifstream fin; // opened by the constructor scanner
int remWS() // result is first non-white space char
{int c;
do{ c = fin.get();} while(isspace(c)); return c;
}
void appnd(char c, string & s) // appends c to the end of s
{string s1;
s1 = c;
s.append(s1);}
};
template <class Attributes>
item<Attributes>* Scanner<Attributes>::cget() // returns next token
{ //fin.sync();
int c;
string s;
c = fin.get();
cout <<"C:"<< c<< endl;
if (c== -1)
{cout <<"rightbefore" <<endl;
x = ST1.insert("end of file");
x->theStruct.type = eof;
return x;}
else if(c==10)
{
c = remWS();
s = c;
cout << "new line"<<endl;
}
else if (c==32)
{
c = remWS();
s = c;
}
if(c==60)
{c = fin.get () ;
if (c==62)
{x = ST1.find ("<>"); return x;}
else {x = ST1.find ("<"); fin.putback(c); cout <<"NF"<<endl; return x;}
}
else if (c==58)
{c = fin.get () ;
if (c==61)
{x = ST1.find (":="); return x;}
else {x = ST1.find (":"); fin.putback(c); return x;}
}
else if (c==34)
{int count = 0;
while (c != 34 && c != 10)
{c = fin.get (); appnd (c, s); count++;}
if (c == 34) { x = ST1.insert(s); x->theStruct.type = String; return x;}
else {while (count > 0)
{fin.putback(c); count--;}
string interesting = "interesting" ;
x = ST1.insert(interesting);
x -> theStruct.type = error;
return x; }}
else if (c==47)
{
c = fin.get();
if (c!=47)
{ x = ST1.find ("/"); fin.putback(c);
return x;
}
else
{ while (c != 10 && c != -1) {c = fin.get(); } fin.putback(c);}
}
s = c;
cout<< "need to sddddd" << s << "DDD"
x = ST1.find(s);
if (x != NULL){cout<< "need to sddddd" << s << "DDD" ; return x;}
else { string listen;
y = NULL;
c = fin.get();
listen = c;
y = ST1.find (listen);
if ((y == NULL) && (c != -1) && (c != 32) && (c != 10))
{while ((y == NULL) && (c != -1) && (c != 32) && (c != 10))
{
appnd (c, s);
c = fin.get();
listen = c;
x = ST1.find (s);
y = ST1.find (listen);} fin.putback(c);}
else fin.putback (c);
cout << "need to sddddd" << s << "DDD"<< endl;
if (x != NULL)
{return x; }
else { int size = s.length();
cout << "size"<< size << endl;
int sum = 0;
char g = s[sum];
if (isdigit(g))
{
while (sum < size && isdigit(g))
{sum++; g = s[sum];}
if (sum==size)
{ cout <<"int" << endl;
x = ST1.insert (s);
x->theStruct.type = Int;
x->theStruct.value = atoi(s.c_str());
return x;}
else { x = ST1.insert(s);
x->theStruct.type = error;
return x;}}
else
{int sum = 0;
//cout << "id:" <<endl;
char h = s[sum];
while ((isdigit(h)|isalpha(h)) && sum < size)
{sum++; h = s[sum];}
if (sum== size)
{
x = ST1.insert(s);
x->theStruct.type = id;
return x;}
else {
x = ST1.insert(s);
x->theStruct.type = error;
return x;
} }}}} |
|
|
|
|
|
#2 |
|
Hobbyist
Join Date: Sep 2005
Posts: 266
Rep Power: 4
![]() |
I don't have a clue what your code is supposed to be doing, but following is almost certainly an error:
while ((isdigit(h)|isalpha(h)) && sum < size) I think you mean: while ( (isdigit(h) || isalpha(h)) && (sum < size) ) |
|
|
|
|
|
#3 | |
|
Hobbyist Programmer
Join Date: Feb 2006
Posts: 155
Rep Power: 3
![]() |
Quote:
|
|
|
|
|
|
|
#4 |
|
Expert Programmer
Join Date: Jun 2005
Posts: 893
Rep Power: 4
![]() |
In the insert function:
template <class Attributes>
item <Attributes> * SymTab <Attributes>::insert(string s)
{
int pos = Hash(s);
if (pos < 1) cout << "skdjk" <<flush;
if (hashtable[pos] == NULL) // Row is empty
{
hashtable[pos] = new HashNode<Attributes>;
hashtable[pos]->info = new item<Attributes>(s);
hashtable[pos]->Next = NULL;
return hashtable[pos]->info;
}
else
{
HashNode<Attributes> *Current = hashtable[pos];
HashNode<Attributes> *nNode;
if (Current != NULL)
{while(Current != NULL && Current->Next != NULL) Current = Current->Next;}
nNode = new HashNode<Attributes>;
nNode->info = new item<Attributes>(s);
nNode->Next = NULL;
Current->Next = nNode;
return Current->info;
}
}Look at the red line at the end of the function. You are returning the info of the previous entry in the has table, not the newly created one. Change the line to return nNode->info; Also, you should fix your indenting, how can you work out what is going on when all the ifs and whiles are all jumbled up like that? |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|