0

-2^2 (infix notation) should translate to -2 2 ^ (postfix notation). It does as expected however when evaluating that postfix it evaluates to 4 not -4 which is what is expected.

I'm using Lua and here's my precedence & associativity tables:

-- Precedence table for different operators
local PRECEDENCE = {
    [Token.Type.MINUS] = 0,
    [Token.Type.PLUS] = 0,
    [Token.Type.ASTERIK] = 1,
    [Token.Type.SLASH] = 1,
    [Token.Type.CARET] = 2,
    [Token.Type.UMINUS] = 3
}

-- Associativity table for different operators
-- 0 = LTR (Left To Right)
-- 1 = RTL (Right To Left)
local ASSOCIATIVITY = {
    [Token.Type.MINUS] = 0,
    [Token.Type.PLUS] = 0,
    [Token.Type.ASTERIK] = 0,
    [Token.Type.SLASH] = 0,
    [Token.Type.CARET] = 1,
    [Token.Type.UMINUS] = 1
}

When trying to evaluate -2^2 my output queue looks like this:

{
  2,
  UMINUS,
  2,
  CARET
}

Here's my parser. It's worth noting that queue and stack are "classes" with their respective functionality.

--[[
    Parse tokens
]]
function Parser:parse()
    self:preprocess() -- Convert valid MINUS tokens into UMINUS
    
    while (self.token) do
        local token = self.token
        
        if (token.type == Token.Type.NUMBER) then
            self.queue:enqueue(tonumber(token.value))
        elseif (isOperator(token)) then -- PLUS, MINUS, SLASH, ASTERIK, UMINUS, CARET
            while (not self.stack:isEmpty()
                and ASSOCIATIVITY[token.type]
                and PRECEDENCE[token.type]
                and ASSOCIATIVITY[self.stack:top().type]
                and PRECEDENCE[self.stack:top().type]
                and ((ASSOCIATIVITY[token.type] == 0 and PRECEDENCE[token.type] <= PRECEDENCE[self.stack:top().type])
                    or (ASSOCIATIVITY[token.type] == 1 and PRECEDENCE[token.type] < PRECEDENCE[self.stack:top().type]))) do
                self.queue:enqueue(self.stack:pop())
            end
            self.stack:push(token)
        elseif (token.type == Token.Type.LPAREN) then
            self.stack:push(token)
        elseif (token.type == Token.Type.RPAREN) then
            while (self.stack:top().type ~= Token.Type.LPAREN) do
                self.queue:enqueue(self.stack:pop())
            end
            self.stack:pop()
        end
        self:next() -- Move to the next token
    end
    while (not self.stack:isEmpty()) do
        self.queue:enqueue(self.stack:pop())
    end
    return self.queue
end

What am I doing wrong? I tried an online calculator here and I also get 4 yet I know the correct output should be -4 for that expression.

1 Answer 1

0

To get the result you expect, the carat must have a higher precedence than unary minus. That's how it works in Lua's operator precedence. The postfix notation for -2^2 should actually be 2 2 ^ UMINUS. Remember that the square of any real number is always positive. You could just swap the precedence levels:

[Token.Type.CARET] = 3,
[Token.Type.UMINUS] = 2,
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.