具有功能调试的分流码算法

时间:2015-02-18 21:11:29

标签: function vbscript shunting-yard

我想在运算符旁边的分流码算法中实现“函数”,并从生成的算法中做一个小解释器但是 默认算法会忽略语法错误使用的标记。

有没有人写过翻译 (或不)想帮助我? 这将有助于很多人坚持这个问题!

这里列出了一些测试,shunting-yard函数忽略了函数调用中令牌的错误用法和/或缺少运算符/操作数:

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!"

[编辑] 我希望我的解释器的语法几乎与BASIC编程语言完全相同。

类似BASIC的表达示例:     a + b *(c / func(x,y,func(z))) - d

语法错误表达式的示例:     1 + 2 + + 3 3 func(,1,(,2))()

我的目标: 调车场算法的输出应该是正确的顺序, 如果遇到语法问题,应该有一个错误: 空括号“()”或相互之后的多个运算符/函数/整数或函数调用中的错误括号不允许...

到目前为止,函数,整数和运算符的顺序是正确的 如果你以正确的方式输入表达式!

如果它在vbscript本身中有效,它应该适用于这个算法, 如果没有那么它不应该在这个脚本以太工作,你得到一个错误... 这就是我想在这里做的事情..

我希望语法如何:(在“[]”之间表示可选,“;”是注释,“##”之间是指向该标题的描述的链接...)

#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...]]]

0 个答案:

没有答案