- 积分
- 10513
- 明经币
- 个
- 注册时间
- 2002-6-3
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
花了两天时间,终于将一个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 partialResult As 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 partialResult As 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
|
|