Is this a compiler or logic bug?

Programming, for all ages and all languages.
Post Reply
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Is this a compiler or logic bug?

Post by Ethin »

For my CS degree I have to take a class on interpreter and compiler design. This semester we're doing the compiler portion, and we're designing a mini-pascal top-down compiler. Part of that includes determining whether a datatype is a valid datatype among the possibilities of integer, char, and boolean. We're doing it as a top-down compiler, so I designed my datatype() function like so:

Code: Select all

void Parser::datatype() {
    if (token->index() == Word) {
        if (auto dtype = std::get<0>(*token);
            dtype != "integer" || dtype != "char" || dtype != "boolean") {
            throw std::runtime_error("Bad code: unknown data type");
        }
    }
}
(As a side-note, this is C++20 with the token type being an std::variant of four strings. I could probably do away with the std::variant altogether and just use a string, but I decided not to. Also, the token member variable is an std::optional<std::variant<...>> to solve the possibility of no tokens remaining in the token stream.) The problem I'm facing is that when the parser encounters this line of pascal:

Code: Select all

var x, y, z : integer;
It bails out on the "integer" part. Using gdb I've determined that, yes, the token being scanned is "integer", all lower-case, and without any whitespace or other invalidating characteristics. However, the function still throws the exception, despite the condition (in all three cases) being false (which should cause it to immediately return as though it were an epsilon). I've compiled this using clang, but I'm curious if this is a logic error on my part or a bug in the compiler? I doubt the "bug in the compiler" case but I'm utterly flummoxed as to why the exception is being triggered when its condition is false, and therefore, it should not be triggering. Do you guys have any advice to solving problems like this that appear to be utterly nonsensical?
If you require more code, I can publish this on GH, but I admit that the code is not the cleanest and probably not the most efficient, and if this were production code I'd write it at a much higher quality and standard. And if I were allowed to use parser generators like any sane person, I'd happily do that, but my professor says "no" to parser generators or a library like PEGTL, so... Anyway, I'm stuck on this issue, and can't find what's actually causing it, because everything appears to be fine in a debugger.
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

Re: Is this a compiler or logic bug?

Post by Minoto »

Code: Select all

dtype != "integer" || dtype != "char" || dtype != "boolean"
Isn't this always going to be true?
Those who understand Unix are doomed to copy it, poorly.
thewrongchristian
Member
Member
Posts: 425
Joined: Tue Apr 03, 2018 2:44 am

Re: Is this a compiler or logic bug?

Post by thewrongchristian »

Ethin wrote:

Code: Select all

void Parser::datatype() {
    if (token->index() == Word) {
        if (auto dtype = std::get<0>(*token);
            dtype != "integer" || dtype != "char" || dtype != "boolean") {
            throw std::runtime_error("Bad code: unknown data type");
        }
    }
}
Aren't you after something more like:

Code: Select all

void Parser::datatype() {
    if (token->index() == Word) {
        auto dtype = std::get<0>(*token);
        if (dtype != "integer" || dtype != "char" || dtype != "boolean") {
            throw std::runtime_error("Bad code: unknown data type");
        }
    }
}
Your "auto dtype = std::get<0>(*token);" is within the "if (...)", and I suspect the assignment is resulting in the if condition being true, and so you throw your exception.
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: Is this a compiler or logic bug?

Post by Ethin »

thewrongchristian wrote:
Ethin wrote:

Code: Select all

void Parser::datatype() {
    if (token->index() == Word) {
        if (auto dtype = std::get<0>(*token);
            dtype != "integer" || dtype != "char" || dtype != "boolean") {
            throw std::runtime_error("Bad code: unknown data type");
        }
    }
}
Aren't you after something more like:

Code: Select all

void Parser::datatype() {
    if (token->index() == Word) {
        auto dtype = std::get<0>(*token);
        if (dtype != "integer" || dtype != "char" || dtype != "boolean") {
            throw std::runtime_error("Bad code: unknown data type");
        }
    }
}
Your "auto dtype = std::get<0>(*token);" is within the "if (...)", and I suspect the assignment is resulting in the if condition being true, and so you throw your exception.
I don't think so. According to this page, the C++ standard (in C++17/20) allows an init-statement in a conditional statement, which is identical to what you posted, but scoped within the if statement.
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: Is this a compiler or logic bug?

Post by Ethin »

Minoto wrote:

Code: Select all

dtype != "integer" || dtype != "char" || dtype != "boolean"
Isn't this always going to be true?
I mean... Maybe... I'm aiming for "if the data type is not either integer or char or boolean" or something along those lines. I could've created a container and then used something like

Code: Select all

if (!dtypes.contains(dtype)) {...}
but that seemed like a bit much for a simple check like this.
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: Is this a compiler or logic bug?

Post by Octocontrabass »

Use "&&" instead of "||" and it will work.
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: Is this a compiler or logic bug?

Post by Ethin »

Octocontrabass wrote:Use "&&" instead of "||" and it will work.
Oops? Pretty amateurish mistake, I suppose, but then again I guess we all do that. Thanks for all the help guys!
Post Reply