Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

evaluating string as numerical expression

Posted on 1999-07-22
9
Medium Priority
?
218 Views
Last Modified: 2010-04-30
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
Comment
Question by:cwirrgan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
  • 2
  • +2
9 Comments
 
LVL 7

Expert Comment

by:Vbmaster
ID: 1526822
Nopz, you will have to do something on your own.
0
 
LVL 6

Accepted Solution

by:
VBGuru earned 150 total points
ID: 1526823
0
 
LVL 7

Expert Comment

by:Vbmaster
ID: 1526824
Hmm apparently not.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:VBGuru
ID: 1526825
ya, these are only pointer not exact solution. You can develop on these
0
 
LVL 12

Expert Comment

by:mark2150
ID: 1526826
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
 

Author Comment

by:cwirrgan
ID: 1526827
The links provided definitely give me a start.  I'll have to add the logical operators, but these samples will really help out.
0
 
LVL 18

Expert Comment

by:deighton
ID: 1526828
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
 

Author Comment

by:cwirrgan
ID: 1526829
thanks deighton.  It looks like a lot of work was put into that.  I'll have to give this a try.
0
 
LVL 18

Expert Comment

by:deighton
ID: 1526830
Yes but I didn't do much of the work!  I got it from a VB site.
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question