Search the Community
Showing results for tags 'shuntingyard'.
-
Hi everyone Learned a lot about programming languages and how they work the last days In my previous post I had a question about RPN calculators and how they evaluate unary symbols, now i have a question about the Shunting Yard algorithm The script I'll post here has 2 bugs in it, the firs one is a nasty small bug that i can't trace.. The last "push(pop(stack),queue)" call always pushes a "0" to the stack and I don't know why. edit: [gray text solved by JohnOne] The second problem: I don't know if I did this right but I wanted to modify this algorithm to work with functions as well. here is the pseudo-code explanation that i followed: http://en.wikipedia.org/wiki/Shunting-yard_algorithm did I do this right? Because at the moment the algorithm allows wrong usage of "(" and ")" example: function((10,20,)30) is allowed but it is clearly not the right way to call a function.. #INCLUDE <ARRAY.AU3> FUNC MSG($WHAT) IF ISARRAY($WHAT) THEN MSGBOX(0,"ARRAY",_ARRAYTOSTRING($WHAT)) ELSE MSGBOX(64,"MESSAGE",$WHAT) ENDIF ENDFUNC FUNC PUSH($ITEM, BYREF $STACK) LOCAL $UBOUND = UBOUND($STACK) IF $UBOUND > 0 THEN REDIM $STACK[$UBOUND + 1] $STACK[$UBOUND] = $ITEM ELSE DIM $STACK[] = [$ITEM] ENDIF ENDFUNC FUNC PEEK($STACK) LOCAL $UBOUND = UBOUND($STACK) IF $UBOUND > 0 THEN RETURN $STACK[$UBOUND - 1] ENDIF ENDFUNC FUNC POP(BYREF $STACK) LOCAL $UBOUND = UBOUND($STACK) LOCAL $RETURN IF $UBOUND > 0 THEN $RETURN = $STACK[$UBOUND - 1] REDIM $STACK[$UBOUND - 1] ENDIF ENDFUNC FUNC STACKISEMPTY($STACK) IF UBOUND($STACK) > 0 THEN RETURN FALSE ELSE RETURN TRUE ENDIF ENDFUNC FUNC ASSOCIATIVITY($OPERATOR) IF $OPERATOR = "^" THEN RETURN "RIGHT" ELSE RETURN "LEFT" ENDIF ENDFUNC FUNC PRECEDENCE($OPERATOR) SWITCH $OPERATOR CASE "^" RETURN 3 CASE "*","/" RETURN 2 CASE ELSE RETURN 1 ENDSWITCH ENDFUNC FUNC ISOPERATOR($OPERATOR) RETURN STRINGINSTR("+-*/^",$OPERATOR) <> 0 ENDFUNC ;################################################################################################### FUNC SHUNTINGYARD($INPUT) Local $queue[0] Local $stack[0] Local $token, $operator_a, $operator_b For $token = 0 To UBound($input) - 1 Switch $input[$token] Case "(" push($input[$token], $stack) Case ")" While Not(peek($stack) = "(") push(pop($stack), $queue) If stackisempty($stack) Then msg("Can't find a matching ""("".") WEnd POP($stack) Case "," While Not(peek($stack) = "(") push(pop($stack), $queue) If stackisempty($stack) Then msg("Can't find a matching function ""("".") WEnd Case "+","-","*","/","^" $operator_a = $input[$token] 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 push(pop($stack), $queue) Else ExitLoop EndIf WEnd push($operator_a, $stack) Case "function" push("function", $stack) Case Else push($input[$token], $queue) EndSwitch Next for $itemcount = 0 to ubound($stack) - 1 if peek($stack) = "(" then msg("can't find a matching "")"".") push(pop($stack), $queue) next Return $queue ENDFUNC ;################################################################################################### GLOBAL $input = ["function","(","1",",","2",")"] msg($input) $shuntingYard = shuntingyard($input) msg($shuntingYard) ;################################################################################################### any help would be appreciated! TheAutomator