• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 220
  • Last Modified:

evaluating string as numerical expression

Is there a built in function which will evaluate a string to  it's numerical/logical equivalent?  Or will I just have to write a parser to do the work myself?  I would like to be able to take a string (i.e. "5 + 1 <= 10 / 2") and have it return true or false appropriately.
0
cwirrgan
Asked:
cwirrgan
  • 2
  • 2
  • 2
  • +2
1 Solution
 
VbmasterCommented:
Nopz, you will have to do something on your own.
0
 
VbmasterCommented:
Hmm apparently not.
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
VBGuruCommented:
ya, these are only pointer not exact solution. You can develop on these
0
 
mark2150Commented:
In the old DOS days, the INPUT statement used to be able to do this sort of thing. You could put "2+3" in response to an "Input X" statement and the thing would give you "5" as the result. Don't think that will work anymore in the Visual world - so much for progress.

M

0
 
cwirrganAuthor Commented:
The links provided definitely give me a start.  I'll have to add the logical operators, but these samples will really help out.
0
 
deightonCommented:
VERSION 4.00
Begin VB.Form Form1
   Caption         =   "Form1"
   ClientHeight    =   5880
   ClientLeft      =   1140
   ClientTop       =   1545
   ClientWidth     =   6690
   Height          =   6450
   Left            =   1080
   LinkTopic       =   "Form1"
   ScaleHeight     =   5880
   ScaleWidth      =   6690
   Top             =   1035
   Width           =   6810
   Begin VB.TextBox Text1
      Height          =   375
      Left            =   3240
      TabIndex        =   1
      Top             =   240
      Width           =   2655
   End
   Begin VB.CommandButton Command1
      Caption         =   "Calculate"
      Height          =   375
      Left            =   2520
      TabIndex        =   0
      Top             =   960
      Width           =   1455
   End
   Begin VB.Label Label3
      Height          =   375
      Left            =   3240
      TabIndex        =   4
      Top             =   1680
      Width           =   2295
   End
   Begin VB.Label Label2
      Alignment       =   1  'Right Justify
      Caption         =   "Value ="
      Height          =   375
      Left            =   840
      TabIndex        =   3
      Top             =   1680
      Width           =   2295
   End
   Begin VB.Label Label1
      Alignment       =   1  'Right Justify
      Caption         =   "Expression : "
      Height          =   375
      Left            =   840
      TabIndex        =   2
      Top             =   240
      Width           =   2295
   End
End
Attribute VB_Name = "Form1"
Attribute VB_Creatable = False
Attribute VB_Exposed = False
Option Explicit
Dim e_input As String     ' Expression input string.
Dim e_tok As String       ' Current token kind.
Dim e_spelling As String  ' Current token spelling.
Dim e_error As Integer    ' Tells if syntax error occurred.

Function e_eval(ByVal s As String, value As Double) As Integer
   ' Initialize.
   e_error = 0
   e_input = s
   Call e_nxt
 
   ' Evaluate.
   value = e_prs(1)
 
   ' Check for unrecognized input.
   If e_tok <> "" And Not e_error Then
      MsgBox "syntax error, token = '" + e_spelling + "'"
   e_error = -1
   End If
 
   e_eval = Not e_error
End Function
 
' e_prs
'   Parse an expression, allowing operators of a specified
'   precedence or higher. The lowest precedence is 1.
'   This function gets tokens with e_nxt and recursively
'   applies operator precedence rules.
Function e_prs(p As Integer) As Double
   Dim n As Double    ' Return value.
   Dim fun As String  ' Function name.
 
   ' Parse expression that begins with a token (precedence 12).
   If e_tok = "num" Then
      ' number.
      n = Val(e_spelling)
      Call e_nxt
   ElseIf e_tok = "-" Then
      ' unary minus.
      Call e_nxt
      n = -e_prs(11)    ' Operand precedence 11.
   ElseIf e_tok = "not" Then
      ' logical NOT.
      Call e_nxt
      n = Not e_prs(6)  ' Operand precedence 6.
   ElseIf e_tok = "(" Then
      ' parentheses.
      Call e_nxt
      n = e_prs(1)
      Call e_match(")")
   ElseIf e_tok = "id" Then
      ' Function call.
      fun = e_spelling
      Call e_nxt
      Call e_match("(")
      n = e_prs(1)
      Call e_match(")")
      n = e_function(fun, n)
   Else
      If Not e_error Then
         MsgBox "syntax error, token = '" + e_spelling + "'"
         e_error = -1
      End If
   End If
 
   ' Parse binary operators.
Do While Not e_error
  If 0 Then  ' To allow ElseIf .
  ElseIf p <= 11 And e_tok = "^" Then: Call e_nxt: n = n ^ e_prs(12)
  ElseIf p <= 10 And e_tok = "*" Then: Call e_nxt: n = n * e_prs(11)
  ElseIf p <= 10 And e_tok = "/" Then: Call e_nxt: n = n / e_prs(11)
  ElseIf p <= 9 And e_tok = "\" Then: Call e_nxt: n = n \ e_prs(10)
  ElseIf p <= 8 And e_tok = "mod" Then: Call e_nxt: n = n Mod e_prs(9)
  ElseIf p <= 7 And e_tok = "+" Then: Call e_nxt: n = n + e_prs(8)
  ElseIf p <= 7 And e_tok = "-" Then: Call e_nxt: n = n - e_prs(8)
  ElseIf p <= 6 And e_tok = "=" Then: Call e_nxt: n = n = e_prs(7)
  ElseIf p <= 6 And e_tok = "<" Then: Call e_nxt: n = n < e_prs(7)
  ElseIf p <= 6 And e_tok = ">" Then: Call e_nxt: n = n > e_prs(7)
  ElseIf p <= 6 And e_tok = "<>" Then: Call e_nxt: n = n <> e_prs(7)
  ElseIf p <= 6 And e_tok = "<=" Then: Call e_nxt: n = n <= e_prs(7)
  ElseIf p <= 6 And e_tok = ">=" Then: Call e_nxt: n = n >= e_prs(7)
  ElseIf p <= 5 And e_tok = "and" Then: Call e_nxt: n = n And e_prs(6)
  ElseIf p <= 4 And e_tok = "or" Then: Call e_nxt: n = n Or e_prs(5)
  ElseIf p <= 3 And e_tok = "xor" Then: Call e_nxt: n = n Xor e_prs(4)
  ElseIf p <= 2 And e_tok = "eqv" Then: Call e_nxt: n = n Eqv e_prs(3)
  ElseIf p <= 1 And e_tok = "imp" Then: Call e_nxt: n = n Imp e_prs(2)
  Else
       Exit Do
  End If
 Loop
 
   e_prs = n
End Function
 
' e_function.
'   Evaluate a function. This is a helper function to simplify
'   e_prs.
Function e_function(fun As String, 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)
   
   
   'New functions
   Case "arccos": n = arccos(arg)
   Case "arcsin": n = arcsin(arg)
   
   Case "arcsec": n = arcsec(arg)
   Case "arccosec": n = arccosec(arg)
   Case "arccot": n = arccot(arg)
   
   Case "cot": n = cot(arg)
   Case "cosec": n = cosec(arg)
   Case "sec": n = sec(arg)
   
   Case "sinh": n = sinh(arg)
   Case "cosh": n = cosh(arg)
   Case "tanh": n = tanh(arg)
   
   Case "arcsinh": n = arcsinh(arg)

   Case "coth": n = coth(arg)
   Case "cosech": n = cosech(arg)
   Case "sech": n = sech(arg)


   Case Else
      If Not e_error Then
         MsgBox "undefined function '" + fun + "'"
         e_error = -1
      End If
   End Select
 
   e_function = n
End Function


Private Function arccos(ByVal x As Double) As Double
   
    If Abs(x) = 1 Then
   
        If x = 1 Then arccos = 0 Else arccos = Atn(1) * 4
   
    Else
   
        arccos = Atn(-x / Sqr(-x * x + 1)) + 2 * Atn(1)

    End If
   
End Function
   
Private Function arcsec(ByVal x As Double) As Double
   
    arcsec = arccos(1 / x)
   
End Function

Private Function arcsinh(ByVal x As Double) As Double
   
    arcsinh = Log(x + Sqr(x * x + 1))
       
End Function

Private Function arccosec(ByVal x As Double) As Double
   
    arccosec = arcsin(1 / x)
   
End Function

Private Function arccot(ByVal x As Double) As Double
   
    arccot = Atn(1 / x)

   
End Function

Private Function sec(ByVal x As Double) As Double
   
    sec = 1 / Cos(x)
       
End Function

Private Function cot(ByVal x As Double) As Double
   
    cot = 1 / Tan(x)
       
End Function

Private Function cosec(ByVal x As Double) As Double
   
     cosec = 1 / Sin(x)
       
End Function


Private Function sinh(ByVal x As Double) As Double
   
    sinh = (Exp(x) - Exp(-x)) / 2
           
End Function

Private Function cosh(ByVal x As Double) As Double
   
    cosh = (Exp(x) + Exp(-x)) / 2
           
End Function

Private Function tanh(ByVal x As Double) As Double
   
    tanh = sinh(x) / cosh(x)
           
End Function

Private Function coth(ByVal x As Double) As Double
   
    coth = 1 / tanh(x)
           
End Function

Private Function sech(ByVal x As Double) As Double
   
    sech = 1 / cosh(x)
           
End Function

Private Function cosech(ByVal x As Double) As Double
   
    cosech = 1 / sinh(x)
           
End Function

Private Function arcsin(ByVal x As Double) As Double
   
    If Abs(x) = 1 Then
   
        arcsin = Atn(1) * 2 * Sgn(x)
   
    Else
   
        arcsin = Atn(x / Sqr(-x * x + 1))

    End If
   
End Function
   
   
 
' e_nxt
'   Get the next token into e_tok and e_spelling and remove the
'   token from e_input.
'   This function groups the input into "words" like numbers,
'   operators and function names.
Sub e_nxt()
   Dim is_keyword As Integer
   Dim c As String  ' Current input character.
   Dim is_id As Integer
 
   e_tok = ""
   e_spelling = ""
 
   ' Skip whitespace.
   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)
 
   ' Number constant. Modify this to support hexadecimal, etc.
   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
 
   ' Identifier or keyword.
   Case "a" To "z", "_"
      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
 
      ' Check for keyword.
      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
 
   ' Check for <=, >=, <>.
   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
 
   ' Single character token.
   Case Else
      e_tok = c
   End Select
 
    If e_spelling = "" Then
       e_spelling = e_tok
   End If
End Sub
 
' e_match
'   Check the current token and skip past it.
'   This function helps with syntax checking.
Sub e_match(token As String)
   If Not e_error And e_tok <> token Then
      MsgBox "expected " + token + ", got '" + e_spelling + "'"
      e_error = -1
   End If
   Call e_nxt
End Sub
Private Sub Command1_Click()
   
       Dim n As Double
 
       If e_eval(Text1.Text, n) Then
         Label3.Caption = Format$(n)
       End If
   
End Sub



0
 
cwirrganAuthor Commented:
thanks deighton.  It looks like a lot of work was put into that.  I'll have to give this a try.
0
 
deightonCommented:
Yes but I didn't do much of the work!  I got it from a VB site.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 2
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now