Function 具有功能调试的调车场算法

Function 具有功能调试的调车场算法,function,vbscript,shunting-yard,Function,Vbscript,Shunting Yard,我想在操作员旁边实现调车场算法中的“函数”,并对结果算法进行一些解释,但是 默认算法会忽略标记的语法错误用法 有人写过翻译吗 (或不)想帮助我? 这将帮助很多陷入这个问题的人 下面列出了一些测试,调车场函数忽略了函数调用中令牌的错误使用和/或缺少运算符/操作数: func(,1) func(2,) func(,,,,,) () (((()))()()) func((),(,)) func(1,2(3,4)) etc... 我读到的一些研究: http://www.reedbeta.com/bl

我想在操作员旁边实现调车场算法中的“函数”,并对结果算法进行一些解释,但是 默认算法会忽略标记的语法错误用法

有人写过翻译吗 (或不)想帮助我? 这将帮助很多陷入这个问题的人

下面列出了一些测试,调车场函数忽略了函数调用中令牌的错误使用和/或缺少运算符/操作数:

func(,1)
func(2,)
func(,,,,,)
()
(((()))()())
func((),(,))
func(1,2(3,4))
etc...
我读到的一些研究:

http://www.reedbeta.com/blog/2011/12/11/the-shunting-yard-algorithm/
http://en.wikipedia.org/wiki/Shunting-yard_algorithm
http://rosettacode.org/wiki/Parsing/Shunting-yard_algorithm
解释我的代码(vbscript)以测试此功能,并进行一些改进:

it allows usage of functions(beta)
it gives an error with most of the incorrect syntax
functions can be nested
如果有人想分享这些改进或有任何好的想法,那么 请让我知道

我的代码:

Function Is_Empty(Stack)
If UBound(Stack) > - 1 Then
Is_Empty = False
Else
Is_Empty = True
End If
End Function
Function Peek(Stack)
If UBound(Stack) > - 1 Then
Peek = Stack(UBound(Stack))
End If
End Function
Function Pop(ByRef Stack)
If UBound(Stack) > - 1 Then
Pop = Stack(UBound(Stack))
ReDim Preserve Stack(UBound(Stack) - 1)
End If
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
Set Prec = CreateObject("scripting.dictionary")
With Prec
.Add "+", 1
.Add "-", 1
.Add "*", 2
.Add "/", 2
End With
Function Is_Operator(Op)
Is_Operator = Prec.Exists(Op)
End Function

Set Re = New RegExp
Re.Pattern = "[a-z0-9]+|[+\-/*,()]"
Re.Global = True
Set X = Re.Execute("func (1,1(1,1))")'//here the test code

Stack = Array() : Queue = Array() : Level = 0

For Each Token In X
Select Case Token
Case "func"
Call Push(Token, Stack)
Case "("
If Peek(Stack) = "func" Then
Level = Level + 1
Call Push("#", Queue)
End If
Call Push(Token, Stack)
Case ")"
Do While Not(Peek(Stack) = "(")
If Is_Empty(Stack) Then MsgBox "error: (", 48 : WScript.Quit
Call Push(Pop(Stack), Queue)
Loop
Discard = Pop(Stack)
If Peek(Stack) = "func" Then
Level = Level - 1
If Peek(Queue) = "," Then MsgBox "error: ,", 48 : WScript.Quit
Call Push(Pop(Stack), Queue)
End If
Case ","
If Level = 0 Then MsgBox "error: ,", 48 : WScript.Quit
If Peek(Queue) = "#" Then MsgBox "error: ,", 48 : WScript.Quit
If Peek(Queue) = "," Then MsgBox "error: ,", 48 : WScript.Quit
Do While Not(Peek(Stack) = "(")
If Is_Empty(Stack) Then MsgBox "error: ( or ,", 48 : WScript.Quit
Call Push(Pop(Stack), Queue)
Loop
Call Push(Token, Queue)
Case "+", "-", "*", "/"
A = Token
Do While Is_Operator(Peek(Stack))
B = Peek(Stack)
If Prec(A) < Prec(B) Then
Call Push(Pop(Stack), Queue)
Else
Exit Do
End If
Loop
If Peek(Queue) = "," Then MsgBox "error: wrong operator", 48 : WScript.Quit
Call Push(A, Stack)
Case Else
Call Push(Token, Queue)
End Select
Next
For I = 0 To UBound(Stack)
If Peek(Stack) = "(" Then MsgBox "error: )", 48 : WScript.Quit
Call Push(Pop(Stack), Queue)
Next

MsgBox Join(Queue, "|"),, Level
stack = array()

For Counter = 0 To UBound(Queue)
select case queue(counter)
case "func"
do while not(peek(stack) = "#")
if peek(stack) = "," then
l = l + 1
discart = pop(stack)
elseif is_empty(stack) then
exit do
else
F = F + INT(pop(stack))
end if
loop
discart = pop(stack)
call push(F, stack)
case "+","-","*","/"
B = pop(stack)
if is_empty(stack) then MsgBox "error: not enough values", 48 : WScript.Quit
A = pop(stack)
if not(isnumeric(a) and isnumeric(b)) then MsgBox "error: not numeric", 48 : WScript.Quit
select case queue(Counter)
case "+"
C = int(a) + int(b)
case "-"
C = int(a) - int(b)
case "*"
C = int(a) * int(b)
case "/"
C = int(a) / int(b)
case else
MsgBox "error: " & queue(Counter), 48 : WScript.Quit
end select
call push(c, stack)
case else
Call Push(queue(Counter), Stack)
end select
next
If UBound(Stack) > 0 Then MsgBox "too many values", 48 : WScript.Quit
If is_empty(Stack) Then MsgBox "error: not enough values", 48 : WScript.Quit

msgbox stack(0),0,"result!"

此外,“11+”也被接受,我认为还有很多其他问题我没有提到。在每种情况下,期望的行为是什么。准确定义输出是编写解析器的第一步。@Salix alba,请查看编辑。。你是不是在寻找一些关于我希望这个程序的语法如何的图解说明?也谢谢你的回答我也试着让问题更清晰易读,我不是英国人,所以问这种复杂的问题并不容易。。。道歉!这是使用调车场算法的常见问题。”1 + 2' = '+ 1 2' = '1 2 +'. 该算法接受比有效中缀符号更广泛的语法。
#function#:
func([#expression#[, #expression#[, #expression#...]]]) ; 

#number#:
(0-9)+ ; integers from 0 to ...

#operator#:
( ; open bracket, can be a function grouping or part of an expression
) ; closing bracket (see open bracket for details)
  ; bracket rules: must start with an open and stop with a closed bracket,
  ; can be nested but there must be something inside them!
, ; function argument seperator
+ ; plus
- ; minus
* ; multiply (higher prec than + and -)
/ ; divide (same prec as multiply)

#operand#:
#number# or #function#

#expression#:
#operand# [#operator# #operand#[ #operator# #operand#[ and so on...]]]