You've not said where in the hierarchy you're adding the minus
method, but it looks like you're adding it above plus
and making it the root.
You need to put it at last if you want unary -
to have a higher precedence than +
and *
.
In your pseudocode, something like this should work:
method times
minus()
while(consume(times_t))
minus()
end
end
method minus
if(consume(minus_t))
// next number should have a unary minus attached
number()
else
number()
end
end
I'm learning about parsers these days, so I wrote a complete parser based on your pseudocode, it's in LiveScript, but should be easy to follow.
Edit: Running example on jsfiddle.net - http://jsfiddle.net/Dogbert/7Pmwc/
parse = (string) ->
index = 0
is-digit = (d) -> '0' <= d <= '9'
plus = ->
str = times()
while consume "+"
str = "(+ #{str} #{times()})"
str
times = ->
str = unary-minus()
while consume "*"
str = "(* #{str} #{unary-minus()})"
str
unary-minus = ->
if consume "-"
"(- #{number()})"
else
number()
number = ->
if is-digit peek()
ret = peek()
advance()
while is-digit peek()
ret += peek()
advance()
ret
else
throw "expected number at index = #{index}, got #{peek()}"
peek = ->
string[index]
advance = ->
index++
consume = (what) ->
if peek() == what
advance()
true
plus()
console.log parse "4+5*6"
console.log parse "-4+5"
console.log parse "-4*-5+-4"
Output:
(+ 4 (* 5 6))
(+ (- 4) 5)
(+ (* (- 4) (- 5)) (- 4))
PS: you may want to look at Operator-precedence Parsers for parsing complex precedence/associativity relatively easily.