[VBA]公式解析源代码,仅包含四则运算部分。
花了两天时间,终于将一个C#编写的公式解析程序转化为VB的代码,不过还有很多东西没有实现,比如函数和变量功能的实现,有兴趣的可以自己研究,也可以参考编译原理这本书。Enum tokTypes
tokNONE = 0
tokDELIMITER = 1
tokVARIABLE = 2
tokFUNCTION = 3
tokNumber = 4
tokString = 5
End Enum
Dim exp As String
Dim expIdx As Integer
Dim token As String
Dim tokType As tokTypes
' 判断是否指定的分隔符
Function IsDelim(ByVal c As String) As Boolean
If InStr("+-*/&()", c) Then IsDelim = True
End Function
' 判断是否是字母
Function IsLetter(ByVal c As String) As Boolean
If Asc(c) >= 65 And Asc(c) <= 90 Then
IsLetter = True
ElseIf Asc(c) >= 97 And Asc(c) <= 122 Then
IsLetter = True
End If
End Function
'判断是否是数字
Function IsDigit(ByVal c As String) As Boolean
If Asc(c) >= 48 And Asc(c) <= 57 Then IsDigit = True
End Function
'判断是否是空格
Function IsWhiteSpace(ByVal c As String) As Boolean
If c = " " Then IsWhiteSpace = True
End Function
'取计算单元标记
Sub GetToken()
tokType = tokNONE
token = ""
If expIdx > Len(exp) Then Exit Sub
'忽略前置空格
Do While (expIdx <= Len(exp) And IsWhiteSpace(Mid(exp, expIdx, 1)))
expIdx = expIdx + 1
If expIdx > Len(exp) Then Exit Sub
Loop
'分隔符
If (IsDelim(Mid(exp, expIdx, 1))) Then
token = token + Mid(exp, expIdx, 1)
expIdx = expIdx + 1
tokType = tokDELIMITER
'函数或者变量
ElseIf (IsLetter(Mid(exp, expIdx, 1))) Then
token = token + Mid(exp, expIdx, 1)
expIdx = expIdx + 1
If expIdx > Len(exp) Then Exit Sub
Do While (IsLetter(Mid(exp, expIdx, 1)) And IsDigit(Mid(exp, expIdx, 1)))
token = token + Mid(exp, expIdx, 1)
expIdx = expIdx + 1
If expIdx > Len(exp) Then Exit Do
Loop
tokType = tokFUNCTION
'数字
ElseIf (IsDigit(Mid(exp, expIdx, 1))) Then
Do While Not (IsDelim(Mid(exp, expIdx, 1)))
token = token + Mid(exp, expIdx, 1)
expIdx = expIdx + 1
If expIdx > Len(exp) Then Exit Do
Loop
tokType = tokNumber
'字符串
ElseIf (Mid(exp, expIdx, 1) = """") Then
expIdx = expIdx + 1
Do While (Mid(exp, expIdx, 1) <> """")
token = token + Mid(exp, expIdx, 1)
expIdx = expIdx + 1
If expIdx > Len(exp) Then Exit Do
Loop
expIdx = expIdx + 1
tokType = tokString
End If
End Sub
Function Evaluate(ByVal expstr As String)
exp = expstr
expIdx = 1
GetToken
If (tokType = tokNONE And token = """") Then MsgBox ("No Expression Present!")
Evaluate = EvalExp2()
MsgBox Evaluate
End Function
'处理加法或减法
Function EvalExp2() As String
Dim result As String
Dim op As String
Dim partialResult As String
EvalExp2 = EvalExp3()
op = token
Do While (op = "+" Or op = "-" Or op = "&")
GetToken
partialResult = EvalExp3()
Select Case op
Case "-":
EvalExp2 = CDbl(EvalExp2) - CDbl(partialResult)
Case "+":
EvalExp2 = CDbl(EvalExp2) + CDbl(partialResult)
Case "&":
EvalExp2 = EvalExp2 + partialResult
End Select
op = token
Loop
End Function
'处理乘法或除法
Function EvalExp3() As String
Dim op As String
Dim partialResultAs String
EvalExp3 = EvalExp5
op = token
Do While (op = "*" Or op = "/")
GetToken
partialResult = EvalExp5
Select Case op
Case "*":
EvalExp3 = CDbl(EvalExp3) * CDbl(partialResult)
Case "/":
EvalExp3 = CDbl(EvalExp3) / CDbl(partialResult)
End Select
op = token
Loop
End Function
'处理一元
Function EvalExp5() As String
Dim op As String
Dim partialResultAs String
op = ""
If ((tokType = tokDELIMITER) And (token = "+" Or token = "-")) Then
op = token
GetToken
End If
EvalExp5 = EvalExp6
If (op = "-") Then EvalExp5 = -1 * EvalExp5
End Function
'处理括号
Function EvalExp6() As String
If ((token = "(")) Then
GetToken
EvalExp6 = EvalExp2()
GetToken
Else
EvalExp6 = Atom()
End If
End Function
'处理数字或字符串
Function Atom() As String
Select Case tokType
Case tokNumber:
Atom = token
GetToken
Case tokString:
Atom = token
GetToken
End Select
End Function
Sub main()
Evaluate "3+5*(2.5+7.5)-8/2"
End Sub
附上它的代码分析程序,是C#格式,可以参考。
没接触过C#的编程,可能转化的过程当中有些不是处理的很好,另外错误分析的部分也没处理。
附件是用WinRAR3.20版本压缩的,如果打不开,请下载新的版本。
好东西啊~~送花一朵!
好程序呀
好程序呀! 确实很好啊.谢谢啊. <strong>不错</strong> 谢谢 <p>好东西大家分享</p> <p>为啥看不到呢?</p><p>\</p> <p>在哪里啊</p><p></p>
页:
[1]
2