Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need advanced string parser, evaluate user formula.

Status
Not open for further replies.

gnewitall

Programmer
Sep 15, 2005
6
I need to create a form that allows users to enter a formula then parses and evaluates it to return a 1 or 0 on the backend. I am struggling with the logic of how to evaluate the string by storing the contents of the inner most parenthesis first, pair it with the appropriate operator then continue this process until the formula is evaluated. I guess there will be an if statement, but not sure how to put it together. I will need to call some custom functions as indicated below with sin[y], cos[z], f[x]. Please help guide me.

Given a user entered string like,
$formula = "((a > (2 * b)) and (sin[y] < cos[z])) or (f[x] >= 1)";

BTW, I know I will need error checking for unmatched parenthesis and allow only certain characters for security reasons. I feel I can do this part of the program, no problem.
 
normally you want to control user input into form fields as much as possible, so can you make each variable of the problem a seperate form field and then plug those values into the equation instead of trying to parse a string and pull out stuff from the string?
 
The usual way of processing infix notation as this is know is to convert it to reverse polish notation first. It's normally done with stacks but it's been ages since I've done it.
Give google a go with things like "reverse polish notation" and "expression evaluation".


Trojan.
 
I agree with Kevin, the more you can control the way they enter the formula, the better off you are. Assuming that all your variables are going to be single letters, this might give you a start.

Code:
my ($a, $b, $x, $y, $z) = (1,2,3,4,5);
my $formula = '((a > (2 * b)) and (sin[y] < cos[z])) or (f[x] >= 1);';

$formula =~ s/(?<!\w)([A-Za-z])(?![\w\[])/\$$1/g;  #Change var (a) into $var ($a)
$formula =~ s/(?<!\w)([A-Za-z])(?=\[)/\&$1/g;      #Modify functions f[x] into &f[x]
$formula =~ s/\[/\(/g;                          #Change [ into (
$formula =~ s/\]/\)/g;                          #Change ] into )

my $results = eval $formula;
if ($@) {
    print $@, "\n";
} else {
    print $results;
}

sub f {
    return $_[0]+1;
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top