The strangest behavior with C++ iostream I've ever seen
Posted: Wed May 11, 2022 10:04 am
So, I'm posting this here because this is behavior that I've never seen exhibited by any libstdc++ ever. As you guys know, I'm taking a course in compiler design. I haven't touched my lexer in months -- this semester has almost entirely focused on the parser side of things -- and my lexer has worked up until this point (and of course it had to fail now because, of course, its finals week). The strange problem is, its not failing on my computer, but on my professors when he tries to validate my code. I'm on Linux and he's on Windows, which may have something to do with it, but on the previous assignments he never experienced this problem, and we're both stumped. (For reference, the parser/compiler is a miniature version of Pascal.)
The problem occurs when my lexer goes to read in a token:
Specifically, the problem he's having is that this line (pascal):
Breaks after it parses the space after "program". It reads "program", a space, and then immediately hits end-of-file and refuses to parse anything else. The file though contains much more; my copy, for example, contains this test code:
I'm completely baffled because this doesn't happen on my machine and its never happened before with any prior assignment. I did update the zip file that I was going to submit for code-formatting reasons, so maybe that did something, but both of our editors are showing that the test code does in fact contain a lot more than just "program " and so the lexer should see the same. Is there something really weird going on between my libstdc++ and his? Is this just a weird Windows thing?
The problem occurs when my lexer goes to read in a token:
Code: Select all
while (true) {
auto pos = in.tellg();
std::uint8_t c = 0;
in >> std::noskipws >> c; // problem occurs on this line...
// Figure out what we've got
if (STATE_TBL[c][static_cast<std::uint64_t>(state)] ==
DfaState::Accept ||
!c) {
in.seekg(pos);
if (!trim(str).empty()) {
// Store token...
}
if (c == 0) {
break;
}
str.clear();
prev_state = DfaState::Whitespace;
state = DfaState::Whitespace;
continue;
}
if (STATE_TBL[c][static_cast<std::uint64_t>(state)] ==
DfaState::Error) {
std::stringstream ss;
ss << "Invalid token at position " << in.tellg()
<< ": was parsing char " << unsigned(c) << " in state "
<< unsigned(state) << "; got " << str
<< "\nTransitional state: " << unsigned(c)
<< ", transitions to state "
<< unsigned(STATE_TBL[c][static_cast<std::uint64_t>(state)])
<< " from state " << unsigned(prev_state) << " and "
<< unsigned(state);
throw std::runtime_error(ss.str());
} else {
str += static_cast<unsigned char>(c);
prev_state = state;
state = STATE_TBL[c][static_cast<std::uint64_t>(state)];
}
}
Code: Select all
program code;
Code: Select all
program code;
var x,y,sum:integer;
var A:integer;
procedure SumAvg(P1,P2:integer; var Avg:integer);
var s:integer;
begin
s:=P1+P2;
sum:=s;
Avg:=sum/2;
end;
begin
x:=5;
y:=7;
SumAvg(x,y,A);
end.