Reputation: 1
I am working on writing a compiler for a school project, and this assignment calls for me to print the tokens of a text file to the console window. I want to make it clear I do not want my homework done for me.
I have been working with this stupid function that iterates through the file, and concatenates a char or a c-string value (my tutor was vague on this part of his instructions...) to a string variable named "token." I can work through the first line of the file fine, which is "main()", but when I try and access the next line I get 1 of two errors. The first is a string subscript out of range error, though I think this was because I was trying to access part of a string array that didn't exist. The most prevalent error I am getting is a debug assertion error:
Debug Assertion Failed Final.exe File:f:\dd\vctools\crt_bld\self_x86\crt\src\isctype.c Expression: (unsigned)(c+1) <= 256
I have included my function and its associated header file. Nothing is going on in main except a function call. If at all possible, could you see what I am failing to see. I realize that my code structure is poor, I won't lie (I am in school after all). So, any comments, criticism, and suggestions are very welcome. And always,thank you for any and all time.
.CPP File (As it is now)
#include <iostream>
#include <string>
using namespace std;
void tokenWork::openFile()
{
fileName = "test.txt";
source.open(fileName);
if(!source.is_open())
{
cout << "Cannot find file " << endl;
}
}
void tokenWork::traveseLine()
{
pos = 0;
while (!source.eof())
{
getline(source,myLine);
int length = myLine.length();
letters = new char[length];
myLine.copy(letters,length);
c = letters[pos];
if (isalpha(c))
token = token + myLine[pos];
else if (isdigit(c))
token = token + letters;
else
{
cout << token << endl;
token = "";
}
if (c == '{' || c == '}' || c == '+' || c == '=' || myLine[pos] == '(' || c == ')' || c == ';')
cout << myLine[pos] << endl;
c = letters[pos++];
}
}
.h file
#ifndef H_LEX
#define H_LEX
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class tokenWork
{
public:
std::string fileName;
std::string myLine;
std::string token;
int pos;
int length;
int c;
char *letters;
ifstream source;
void openFile();
void traveseLine();
void closeFile();
};
#endif
Upvotes: 0
Views: 4488
Reputation: 679
you forgot to
#include <cctype>
in order to use isdigit() and isalpha()
and this
c = letters[pos++];
looks like the source of a bug. pos always increments, but does it ever stop? what happens if it gets to the last character (letters.length()-1) and you hit this line: increments? array out of bounds I suspect.
Upvotes: 1
Reputation:
It's kind of hard to point at particular place in the code - it has so many problems...
The error you see most probably results from
token = token + letters;
letters is not null-terminated (string::copy does not provide null-termination, and you do not reserve a space for null anyway), so +
operator falls off the end and encounters something nasty.
Besides that, it looks like you increment pos
about once per getline
and never reset it. Your code looks like there should have been an inner loop, but I don't see any.
Upvotes: 0
Reputation: 35901
That debug assertion error originates from the call to std::isalpha/isdigit
when you pass it an argument with a value > 255, which is the maximum value the type char
(which you should probably be using instead of int
here) can hold. I can't tell you the exact origin though as you don't provide the source file, but you should be able to figure it out yourself quite easily: run the program under the debugger, it will break at the assert. Move up in the call stack and inspect the values of your variables, that should give you a clue.
a couple of tips:
Upvotes: 2
Reputation: 19032
If you just want to print the tokens on each given line, I'm exceedingly confused by all the extra work you're doing. Shrinking your function down (and a small change) should get you a start:
// note, poorly named function, it traverses the whole file
void tokenWork::traveseLine()
{
pos = 0;
while (!source.eof())
{
getline(source,myLine);
int len = myLine.size();
// NOTE: This was missing from your code, it traverses the line
// that was read in with getline() above.
for(int x = 0; x < len; ++x)
{
// NOTE: This is (in my opinion) a slightly more readable
// version of your if() statement above on tokens
// It doesn't have all your tokens, additional ones
// can be added by adding a case for them above the
// line that prints them out. Since there is no break
// statement, the functionality for all the cases above
// fall through so they all get printed out.
switch(myLine[x])
{
case '{':
case '}':
case '+':
case '=':
// add additional tokens as case statements as necessary
cout << myLine[x] << endl; // print it out
break;
default: // not a token
break;
}
}
}
Upvotes: 1