I'm doing some parsing work, too complex to get into details, but there's one simple thing I need to do (at least simple concept, maybe not simple answer). I might have a formula in a string such as the samples below. I need a function that will take a loosly-formatted formula string, parse it out, and calculate the result.
Sample:
(10 / 2)+(10/30)
5+(10/30)
5+3
8
Or:
(12.5 - (0.5 * 5)) / 2
(12.5 - 2.5) / 2
10 / 2
5
Rules:
- Spaces are to be ignored
- PEMDAS method must entirely apply
- Result shall be always a rounded Integer
- No variables will exist, already converted to numbers
- Decimal numbers might be part of the input
The existing parsing I already have working just gets one of these formula strings - but from there, I have no clue how to perform the actual calculations. What I'm doing specifically is doing a little line deliminated scripter to draw to a canvas, here's some sample script:
Var W 50
Var H 50
Pen Style Clear
Pen Color $000000
Pen Width 3
Brush Style Solid
Brush Color {FORM_COLOR}
Rect 0 0 {WIDTH} {HEIGHT}
Brush Color $501010
Ellipse @W @H 450 450
Brush Color $602020
Ellipse 100 100 400 400
Brush Color $703030
Ellipse 150 150 350 350
Brush Color $804040
Ellipse 200 200 300 300
EllipseG 200 200 300 300 6 2
Pen Style Solid
Pen Width 2
Pen Color {FONT_COLOR}
MoveTo 0 0
LineTo 500 500
MoveTo 0 500
LineTo 500 0
All that already works, but now I want to say for example...
Var W
Var H
Set W 50
Set H 50
Brush Color $602020
Ellipse(@W, @H, 500 - @W, 500 - @H
Set W 100
Set H 100
Brush Color $703030
Ellipse(@W, @H, 500 - @W, 500 - @H
Set W 150
Set H 150
Brush Color $804040
Ellipse(@W, @H, 500 - @W, 500 - @H
So the 500 - @W
I already convert it to 500 - 50
but now I need to send the string 500 - 50
into this function to get the result 450
.
EDIT: Solved
I'm using the parser10
as recommended, and it works perfectly for what I need to do. Here's a sample snippet of my script code:
Var S 4
Var D @S
Var L 0
Var T 0
Var R {WIDTH}
Var B {HEIGHT}
Pen Style Clear
Pen Color $00000000
Pen Width 3
Brush Style Solid
Brush Color {FORM_COLOR}
Rect 0 0 {WIDTH} {HEIGHT}
Set D @D+@S
Brush Color $00400000
Ellipse @L+@D @T+@D @R-(@D*2) @B-(@D*2)
Set D @D+@S
Brush Color $00501010
Ellipse @L+@D @T+@D @R-(@D*2) @B-(@D*2)
Set D @D+@S
Brush Color $00602020
Ellipse @L+@D @T+@D @R-(@D*2) @B-(@D*2)
Set D @D+@S
Brush Color $00703030
Ellipse @L+@D @T+@D @R-(@D*2) @B-(@D*2)
Set D @D+@S
Brush Color $00804040
Ellipse @L+@D @T+@D @R-(@D*2) @B-(@D*2)
Set D @D+@S
Brush Color $00905050
Ellipse @L+@D @T+@D @R-(@D*2) @B-(@D*2)
Set D @D+@S
Brush Color $00FB6060
Ellipse @L+@D @T+@D @R-(@D*2) @B-(@D*2)
Anything starting with an @ is a variable, which I do a StringReplace()
to convert all those based on what was declared in the Var
section.
Parser10, written originally by Renate Schaaf for Delphi 1 and later upgraded to Delphi2 and 3 by Alin Flaider and Stefan Hoffmeister, is a fairly simple math parser. It will do the job for simple expressions and can serve as a boilerplate for more complex work.
It is not built for speed though.
Update :
Hallvard Vassbotn made an update of Parser10 and added some documentation. Load it from here.
List of Parsers, Mathematical Expression Evaluators, Calculators: here
[Edit] Or a TBindExpression in Delphi XE2, not sure if its apply PEMDAS