I'm writing a translator for a lisp-like language. The input file is read in token-by-token. I'm controlling it with an std::fstream
at the top level like this:
...
std::fstream fin(path, std::fstream::in);
symtable table; // aliased map<>
while (!fin.eof()) {
try {
std::cout << "file still has contents!" << std::endl;
parse(fin, symbol_table);
} catch (LexException le) {
std::cout << le.what() << std::endl;
} catch (ParseException pe) {
std::cout << le.what() << std::endl;
}
}
In my lexer, I handle leading whitespace and count lines like this:
char ch;
while (fin >> std::noskipws >> ch) {
if (ch == '\n') {
line++;
continue;
} else if (isspace(ch)) {
continue;
}
break;
}
if (ch <= 32) {
// return the "empty" token, as there's nothing grab from the file anymore
return std::make_tuple("", -500);
}
// The rest is code which builds a token
This is also the area where things are getting weird.
When I pass in this as an input: ()
, it's fine, and produces exactly what I want.
When I pass in this as input: (
, I get an infinite loop.
When I debug, I see that (
is indeed read in as a token. My code then goes through, reads in the newline that Vim inserts, and then enters an infinite loop because EOF
is never read. Furthermore, my std::cout
statement is never printed.
Why is this the case? Why does it work just fine with ()
, but fails on (
?
Edit: The full source is too large for one post, but is available on my github.