1.

Solve : Found a bug in the ShuntingYard function(with functions)!?

Answer»

Hi everyone ,
Found out while implementing the Shunting Yard algorithm in VB that functions with argument separators can be used wrong:

This line of pseudo-code for example is accepted by this algorithm but it's not the wright way to use parenthesis right?

functionName((2000,)500)

more info about the algorithm:
http://en.wikipedia.org/wiki/Shunting-yard_algorithm

does anyone know a simple way to solve this bug?
Thanks in advance
TomA lot of views but no reply,
Did i say something wrong? or is this question placed in the wrong section of the forum?
Going to upload the code anyway for those who maybe are interested.. maybe i did something wrong in the code?

(its in vbscript btw)

Code: [Select]input = split("function ( 1 ( , 2 ) )")
msgbox shuntingyard(input)

function shuntingyard(input)

Queue = array()
Stack = array()

for Counter = 0 to ubound(input)
select case input(Counter)
case "("
call push(input(Counter), Stack)

case ")"
do while not(peek(Stack) = "(")
if stackisempty(Stack) then MsgBox"can't find a matching ""(""."
call push(pop(Stack), Queue)
loop
discard = pop(Stack)

case "+","-","*","/","%","^"
operator_a = input(Counter)
do while isOperator(peek(Stack))
operator_b = peek(Stack)
if (associativity(operator_b) = "left" and precedence(operator_a) = precedence(operator_b)) or (precedence(operator_a) < precedence(operator_b)) then
call push(pop(Stack), Queue)
else
exit do
END if
loop
call push(operator_a, Stack)

case "function"
call push(input(Counter), Stack)

case ","'function seperator
'until the token at the top of the stack is a left parenthesis,
'pop operators off the stack onto the output queue.
'if no left parentheses are encountered,
'either the separator was MISPLACED or parentheses were mismatched.
do while not(peek(Stack) = "(")
if stackisempty(Stack) then MsgBox"can't find a matching ""("" for a function."
call push(pop(Stack), Queue)
loop

case else'"number"
call push(input(Counter), Queue)

end select
next

for itemcount = 0 to ubound(Stack)
if peek(Stack) = "(" then MsgBox"can't find a matching "")""."
call push(pop(Stack), Queue)
next

shuntingyard = join(Queue," ")
end function

function isoperator(item)
isoperator = len(item) = 1 and instr("+-*/%^",item)
end function
set precedence = createobject("scripting.dictionary")
with precedence
.add "^",10'[right]
.add "*",8
.add "/",8
.add "%",8
.add "+",7
.add "-",7
end with
function associativity(assoc)
select case lcase(assoc)
case "^","\"
associativity = "right"
case else
associativity = "left"
end select
end function

SUB PUSH(ITEM,BYREF STACK)
IF UBOUND(STACK) > -1 THEN
REDIM PRESERVE STACK(UBOUND(STACK) + 1)
STACK(UBOUND(STACK)) = ITEM
ELSE
STACK = ARRAY(ITEM)
END IF
END SUB
FUNCTION POP(STACK)
IF UBOUND(STACK) > -1 THEN
POP = STACK(UBOUND(STACK))
REDIM PRESERVE STACK(UBOUND(STACK) - 1)
END IF
END FUNCTION
FUNCTION STACKISEMPTY(STACK)
IF UBOUND(STACK) > -1 THEN
STACKISEMPTY = FALSE
ELSE
STACKISEMPTY = TRUE
END IF
END FUNCTION
FUNCTION PEEK(STACK)
IF UBOUND(STACK) > -1 THEN
PEEK = STACK(UBOUND(STACK))
END IF
END FUNCTION
At the comma it finds a ( immediately so never executes the loop body.

it also throws a subscript out of range error when POP() is called and the array only has ONE item. In this case the exception occurs when only "function" is left on the stack. It occurs while draining said stack in the "for itemcount..." loop.BC_Programmer,
thanks for the reply

Quote

"At the comma it finds a ( immediately so never executes the loop body."

so is this my mistake or did i followed the example from Wikipedia right?:

Quote
If the token is a right parenthesis:
Until the token at the top of the stack is a left parenthesis, pop operators off the stack onto the output queue.
Pop the left parenthesis from the stack, but not onto the output queue.
If the token at the top of the stack is a function token, pop it onto the output queue.
If the stack runs out without finding a left parenthesis, then there are mismatched parentheses.

Quote
it also throws a subscript out of range error when POP() is called and the array only has one item.

tried it with just one item and it works fine here:
input = split("function")


Discussion

No Comment Found