Somebody posted this a few years ago.
I think it is derived from visual basic .
(I added a few extra functions).
Code: Select all
'============== PARSER START ==================================
Dim Shared e_input As String
Dim Shared e_tok As String
Dim Shared e_spelling As String
Dim Shared e_error As Integer
Function SEC(Byval x As Double) As Double
SEC = 1 / Cos(x)
End Function
Function COSEC(Byval x As Double) As Double
COSEC = 1 / Sin(x)
End Function
Function COT(Byval x As Double) As Double
COT = 1 / Tan(x)
End Function
Function ARCSEC(Byval x As Double) As Double
ARCSEC = Atn(x / Sqr(x * x - 1)) + Sgn((x) -1) * (2 * Atn(1))
End Function
Function ARCCOSEC(Byval x As Double) As Double
ARCCOSEC = Atn(x / Sqr(x * x - 1)) + (Sgn(x) - 1) * (2 * Atn(1))
End Function
Function ARCCOT(Byval x As Double) As Double
ARCCOT = Atn(x) + 2 * Atn(1)
End Function
Function sinh(Byval x As Double) As Double
sinh = (Exp(x) - Exp(-x)) / 2
End Function
Function cosh(Byval x As Double) As Double
cosh = (Exp(x) + Exp(-x)) / 2
End Function
Function tanh(Byval x As Double) As Double
tanh = (Exp(x) - Exp(-x)) / (Exp(x) + Exp(-x))
End Function
Function sech(Byval x As Double) As Double
sech = 2 / (Exp(x) + Exp(-x))
End Function
Function cosech(Byval x As Double) As Double
cosech = 2 / (Exp(x) - Exp(-x))
End Function
Function coth(Byval x As Double) As Double
coth = (Exp(x) + Exp(-x)) / (Exp(x) - Exp(-x))
End Function
Function arcsinh(Byval x As Double) As Double
arcsinh = Log(x + Sqr(x * x + 1))
End Function
Function arccosh(Byval x As Double) As Double
arccosh = Log(x + Sqr(x * x - 1))
End Function
Function arctanh(Byval x As Double) As Double
arctanh = Log((1 + x) / (1 - x)) / 2
End Function
Function arcsech(Byval x As Double) As Double
arcsech = Log((Sqr(-x * x + 1) + 1) / x)
End Function
Function arccosech(Byval x As Double) As Double
arccosech = Log((Sgn(x) * Sqr(x * x + 1) +1) / x)
End Function
Function arccoth(Byval x As Double) As Double
arccoth = Log((x + 1) / (x - 1)) / 2
End Function
Function HAVERSINE(Byval x As Double) As Double
HAVERSINE = (Sin(x/2))^2
End Function
Function e_function(byref fun As String,byval arg As Double) As Double
Dim n As Double
Select Case Lcase(fun)
Case "abs": n = Abs(arg)
Case "atn": n = Atn(arg)
Case "cos": n = Cos(arg)
Case "exp": n = Exp(arg)
Case "fix": n = Fix(arg)
Case "int": n = Int(arg)
Case "log": n = Log(arg)
Case "rnd": n = Rnd(arg)
Case "sgn": n = Sgn(arg)
Case "sin": n = Sin(arg)
Case "sqr": n = Sqr(arg)
Case "tan": n = Tan(arg)
Case "haversine":n=haversine(arg)
Case "cosec":n=cosec(arg)
Case "sec":n=sec(arg)
Case "cot": n=cot(arg)
Case "asin":n=asin(arg)
Case "acos":n=acos(arg)
Case "atn":n=atn(arg)
Case "arcsec":n=arcsec(arg)
Case "arccosec":n=arccosec(arg)
Case "arccot":n=arccot(arg)
Case "sinh":n=sinh(arg)
Case "cosh":n=cosh(arg)
Case "tanh":n=tanh(arg)
Case "sech":n=sech(arg)
Case "cosech":n=cosech(arg)
Case "coth":n=coth(arg)
Case "arcsinh":n=arcsinh(arg)
Case "arccoth":n=arccoth(arg)
Case "arctanh":n=arctanh(arg)
Case "arcsech":n=arcsech(arg)
Case "arccosech":n=arccosech(arg)
Case "arccoth":n=arccoth(arg)
Case Else
If Not e_error Then
locate 1,1
Print "UNDEFINED FUNCTION " + fun
e_error = -1
End If
End Select
e_function = n
End Function
Sub e_nxt()
Dim is_keyword As Integer
Dim c As String
e_tok = ""
e_spelling = ""
Do
c = left(e_input, 1)
e_input = Mid(e_input, 2)
Loop While c = " " Or c = Chr(9) Or c = Chr(13) Or c = Chr(10)
Select Case Lcase(c)
Case "0" To "9", "."
e_tok = "num"
Do
e_spelling = e_spelling + c
c = left(e_input, 1)
e_input = Mid(e_input, 2)
Loop While (c >= "0" And c <= "9") Or c = "."
e_input = c + e_input
Case "a" To "z", "_"
Dim As Integer is_id
e_tok = "id"
Do
e_spelling = e_spelling + c
c = Lcase(left(e_input, 1))
e_input = Mid(e_input, 2)
is_id = (c >= "a" And c <= "z")
is_id = is_id Or c = "_" Or (c >= "0" And c <= "9")
Loop While is_id
e_input = c + e_input
is_keyword = -1
Select Case Lcase(e_spelling)
Case "and"
Case "eqv"
Case "imp"
Case "mod"
Case "not"
Case "or"
Case "xor"
Case Else: is_keyword = 0
End Select
If is_keyword Then
e_tok = Lcase(e_spelling)
End If
Case "<", ">"
e_tok = c
c = left(e_input, 1)
If c = "=" Or c = ">" Then
e_tok = e_tok + c
e_input = Mid(e_input, 2)
End If
Case Else
e_tok = c
End Select
If e_spelling = "" Then
e_spelling = e_tok
End If
End Sub
Sub e_match (byref token As String)
If Not e_error And e_tok <> token Then
locate 1,1
Print "EXPECTED " + token + ", got '" + e_spelling + "'"
e_error = -1
End If
e_nxt()
End Sub
Function e_prs (byval p As Integer) As Double
Dim n As Double
Dim fun As String
If e_tok = "num" Then
n = Val(e_spelling)
e_nxt()
Elseif e_tok = "-" Then
e_nxt()
n = -e_prs(11)
Elseif e_tok = "not" Then
e_nxt()
n = Not e_prs(6)
Elseif e_tok = "(" Then
e_nxt()
n = e_prs(1)
e_match(")")
Elseif e_tok = "id" Then
fun = e_spelling
e_nxt()
e_match("(")
n = e_prs(1)
e_match(")")
n = e_function(fun, n)
Else
If Not e_error Then
locate 1,1
Print "syntax error, at '" + e_spelling + "'"
e_error = -1
End If
End If
Do While Not e_error
If p <= 11 And e_tok = "^" Then
e_nxt(): n = n ^ e_prs(12)
Elseif p <= 10 And e_tok = "*" Then
e_nxt(): n = n * e_prs(11)
Elseif p <= 10 And e_tok = "/" Then
e_nxt(): n = n / e_prs(11)
Elseif p <= 9 And e_tok = "\" Then
e_nxt(): n = n \ e_prs(10)
Elseif p <= 8 And e_tok = "mod" Then
e_nxt(): n = n Mod e_prs(9)
Elseif p <= 7 And e_tok = "+" Then
e_nxt(): n = n + e_prs(8)
Elseif p <= 7 And e_tok = "-" Then
e_nxt(): n = n - e_prs(8)
Elseif p <= 6 And e_tok = "=" Then
e_nxt(): n = n = e_prs(7)
Elseif p <= 6 And e_tok = "<" Then
e_nxt(): n = n < e_prs(7)
Elseif p <= 6 And e_tok = ">" Then
e_nxt(): n = n > e_prs(7)
Elseif p <= 6 And e_tok = "<>" Then
e_nxt(): n = n <> e_prs(7)
Elseif p <= 6 And e_tok = "<=" Then
e_nxt(): n = n <= e_prs(7)
Elseif p <= 6 And e_tok = ">=" Then
e_nxt(): n = n >= e_prs(7)
Elseif p <= 5 And e_tok = "and" Then
e_nxt(): n = n And e_prs(6)
Elseif p <= 4 And e_tok = "or" Then
e_nxt(): n = n Or e_prs(5)
Elseif p <= 3 And e_tok = "xor" Then
e_nxt(): n = n Xor e_prs(4)
Elseif p <= 2 And e_tok = "eqv" Then
e_nxt(): n = n Eqv e_prs(3)
Elseif p <= 1 And e_tok = "imp" Then
e_nxt(): n = n Imp e_prs(2)
Else
Exit Do
End If
Loop
e_prs = n
End Function
Function eval(Byref sp as string ) As double
dim as double value
e_error = 0
e_input = sp
e_nxt()
value = e_prs(1)
if not e_error then return value
End Function
'======
Function FindAndReplace(byref instring As String,byref ReplaceThis As String,byref WithThis As String) As String
var lens1=Len(ReplaceThis),lens2=Len(WithThis)
If lens1=lens2 Then lens1=0
dim as string s=instring
Dim As Integer position=Instr(s,ReplaceThis)
While position>0
If lens1 Then
s=Left(s,position-1) & WithThis & Mid(s,position+Lens1)
Else
Mid(s,position) = WithThis
End If
position=Instr(position+Lens2,s,ReplaceThis)
Wend
Function=s
End Function
'=================== END OF PARSER =======================
'===============================================================================
dim as string e
dim as double f
e = " 13^(1/3)*(cos(20 )*asin(.5)^3*21*log(123)/2.5)*atn(123)*A_1* B_1+Arccot(2)"
'A_1 and B_1 are variables in the string
e= FindAndReplace(e,"A_1","10")
e= FindAndReplace(e,"B_1","10.345")
f = Eval(e)
print
print "Input = " ; e
print
print "Answer = " ; f
print "FB Answer = " ; (13^(1/3)) * (cos( 20 )*asin(.5)^3 * 21 * log(123) / 2.5 ) * atn(123) * 10 * 10.345+arccot(2)
print
sleep
If you want to use variables in the string, call them something which won't clash with function/operator names.