Files
kraken/deprecated_compiler/src/StringReader.cpp

167 lines
4.8 KiB
C++
Raw Normal View History

2013-05-20 19:34:15 -04:00
#include "StringReader.h"
#include <cassert>
2013-05-20 19:34:15 -04:00
StringReader::StringReader()
{
str_pos = 0;
}
StringReader::StringReader(std::string inputString)
{
str_pos = 0;
setString(inputString);
}
StringReader::~StringReader()
{
//dtor
}
void StringReader::setString(std::string inputString)
{
rd_string = inputString;
end_reached = false;
}
std::string StringReader::word(bool truncateEnd)
{
std::string result = getTokens(" \n\t", truncateEnd);
2013-05-20 19:34:15 -04:00
while (result == " " || result == "\n" || result == "\t")
{
result = getTokens(" \n\t", truncateEnd);
2013-05-20 19:34:15 -04:00
}
return(result);
}
std::string StringReader::line(bool truncateEnd)
{
return getTokens("\n", truncateEnd);
2013-05-20 19:34:15 -04:00
}
std::string StringReader::getTokens(const char *stop_chars, bool truncateEnd)
2013-05-20 19:34:15 -04:00
{
if (str_pos >= rd_string.size())
return "";
size_t found_pos = rd_string.find_first_of(stop_chars, str_pos);
2013-05-20 19:34:15 -04:00
if (rd_string[str_pos] == '\"') {
//Find the next quote
found_pos = rd_string.find("\"", str_pos+1);
//Check to see if the quote is escaped
int numBackslashes = 0;
int countBack = 1;
while (found_pos >= countBack && rd_string[found_pos-countBack] == '\\') {
numBackslashes++;
countBack++;
}
//While the quote is escaped
while (numBackslashes % 2 == 1) {
//find the next quote
found_pos = rd_string.find("\"", found_pos+1);
//Check to see if it's escaped
numBackslashes = 0;
countBack = 1;
while (found_pos >= countBack && rd_string[found_pos-countBack] == '\\') {
numBackslashes++;
countBack++;
}
}
}
2013-05-20 19:34:15 -04:00
if (found_pos == str_pos) //We are at the endline
{
std::string stop_char(1, rd_string[str_pos]);
2013-05-20 19:34:15 -04:00
str_pos++;
return stop_char;
} else if (found_pos == std::string::npos) //We are at the end of the file
{
//End of String
end_reached = true;
//std::cout << "Reached end of file!\n";
2013-05-20 19:34:15 -04:00
return "";
} else {
if (truncateEnd) //If we want to get rid of the delimiting character, which is the default, don't add the last char. Note we have to increase str_pos by one manually later
found_pos -= 1;
if (rd_string[str_pos] == '\"')
found_pos++;
std::string string_section = rd_string.substr(str_pos, found_pos - str_pos + 1);
str_pos = found_pos + 1;
2013-05-20 19:34:15 -04:00
if (truncateEnd) //Ok, we didn't add the last char, but str_pos now points at that char. So we move it one ahead.
str_pos++;
return string_section;
}
}
void StringReader::test()
{
{
StringReader reader("\"x\"");
assert(reader.word() == "\"x\"");
assert(reader.word() == "");
}
{
StringReader reader("\"y\" ;\n");
assert(reader.word() == "\"y\"");
assert(reader.word() == ";");
assert(reader.word() == "");
}
{
StringReader reader("Goal = greeting ;\n"
"greeting = \"hello\" | greeting \"world\" ;\n");
assert(reader.word() == "Goal");
assert(reader.word() == "=");
assert(reader.word() == "greeting");
assert(reader.word() == ";");
assert(reader.word() == "greeting");
assert(reader.word() == "=");
assert(reader.word() == "\"hello\"");
assert(reader.word() == "|");
assert(reader.word() == "greeting");
assert(reader.word() == "\"world\"");
assert(reader.word() == ";");
assert(reader.word() == "");
}
{
StringReader reader("one # pretend this is a comment\n"
" two\n");
assert(reader.word() == "one");
assert(reader.word() == "#");
assert(reader.line() == "pretend this is a comment");
assert(reader.word() == "two");
assert(reader.word() == "");
}
2013-10-25 02:17:02 -07:00
{
// Quoted strings can span lines.
StringReader reader("x = \"\n \" ;\n");
assert(reader.word() == "x");
assert(reader.word() == "=");
assert(reader.word() == "\"\n \"");
assert(reader.word() == ";");
assert(reader.word() == "");
}
{
// Strings may contain backslash-escaped quote characters.
StringReader reader( "\"abc\\\"def\\\\\\\\\\\" \"\n");
assert(reader.word() == "\"abc\\\"def\\\\\\\\\\\" \"");
assert(reader.word() == "");
}
{
// A backslash-escaped backslash can be the last character in a string.
StringReader reader( "\"\\\\\" \n");
assert(reader.word() == "\"\\\\\"");
assert(reader.word() == "");
}
std::cout << "StringReader tests pass\n";
}