Related
I want to evaluate a math expression which the user enters in a textbox. I have done this so far
string equation, finalString;
equation = textBox1.Text;
StringBuilder stringEvaluate = new StringBuilder(equation);
stringEvaluate.Replace("sin", "math.sin");
stringEvaluate.Replace("cos", "math.cos");
stringEvaluate.Replace("tan", "math.tan");
stringEvaluate.Replace("log", "math.log10");
stringEvaluate.Replace("e^", "math.exp");
finalString = stringEvaluate.ToString();
StringBuilder replaceI = new StringBuilder(finalString);
replaceI.Replace("x", "i");
double a;
for (int i = 0; i<5 ; i++)
{
a = double.Parse(finalStringI);
if(a<0)
break;
}
when I run this program it gives an error "Input string was not in a correct format." and highlights a=double.Parse(finalStringI);
I used a pre defined expression a=i*math.log10(i)-1.2 and it works, but when I enter the same thing in the textbox it doesn't.
I did some search and it came up with something to do with compiling the code at runtime.
any ideas how to do this?
i'm an absolute beginner.
thanks :)
The issue is within your stringEvaluate StringBuilder. When you're replacing "sin" with "math.sin", the content within stringEvaluate is still a string. You've got the right idea, but the error you're getting is because of that fact.
Math.sin is a method inside the Math class, thus it cannot be operated on as you are in your a = double.Parse(finalStringI); call.
It would be a pretty big undertaking to accomplish your goal, but I would go about it this way:
Create a class (perhaps call it Expression).
Members of the Expression class could include Lists of operators and operands, and perhaps a double called solution.
Pass this class the string at instantiation, and tear it apart using the StringBuilder class. For example, if you encounter a "sin", add Math.sin to the operator collection (of which I'd use type object).
Each operator and operand within said string should be placed within the two collections.
Create a method that evaluates the elements within the operator and operand collection accordingly. This could get sticky for complex calculations with more than 2 operators, as you would have to implement a PEMDAS-esque algorithm to re-order the collections to obey the order of operations (and thus achieve correct solutions).
Hope this helps :)
The .Parse methods (Int.Parse, double.Parse, etc) will only take a string such as "25" or "3.141" and convert it to the matching value type (int 25, or double 3.141). They will not evaluate math expressions!
You'll pretty much have to write your own text-parser and parse-tree evaluator, or explore run-time code-generation, or MSIL code-emission.
Neither topic can really be covered in the Q&A format of StackOverflow answers.
Take a look at this blog post:
http://www.c-sharpcorner.com/UploadFile/mgold/CodeDomCalculator08082005003253AM/CodeDomCalculator.aspx
It sounds like it does pretty much what you're trying to do. Evaluating math expressions is not as simple as just parsing a double (which is really only going to work for strings like "1.234", not "1 + 2.34"), but apparently it is possible.
You can use the eval function that the framework includes for JScript.NET code.
More details: http://odetocode.com/code/80.aspx
Or, if you're not scared to use classes marked "deprecated", it's really easy:
static string EvalExpression(string s)
{
return Microsoft.JScript.Eval.JScriptEvaluate(s, null, Microsoft.JScript.Vsa.VsaEngine.CreateEngine()).ToString();
}
For example, input "Math.cos(Math.PI / 3)" and the result is "0.5" (which is the correct cosine of 60 degrees)
I am looking for a very simple - basic - no hardcore programming mumbo jumbo, simply put a generalized overview of a Lambda Expression in layman's terms.
A lambda expression is, simply put, a re-useable expression which takes a number of arguments:
x => x + 1;
The above expression reads "for a given x, return x + 1".
In .NET, this is powerful, because it can be compiled into an anonymous delegate, a nameless function you can declare inline with your code and evaluate to get a value:
int number = 100;
Func<int, int> increment = x => x + 1;
number = increment(number); // Calls the delegate expression above.
However, the real power of a lambda expression is that it can be used to initialize an in-memory representation of the expression itself.
Expression<Func<int, int>> incrementExpression = x => x + 1;
This means that you can give that expression to something like LINQ to SQL and it can understand what the expression means, translating it into a SQL statement that has the same meaning. This is where lambdas are very different from normal methods and delegates, and normally where the confusion begins.
Lambda Expressions are inline functions that have a different syntax to regular functions.
Example Lambda Expression for squaring a number.
x => x * x
A small unnamed inline method. Is that basic enough for you? I'm not sure what you are looking for exactly.
You also said in "layman's" terms - I presume that you have some level of software development experience (so not a complete layman)
In non functional programming languages expressions (that act on variables) perform calculations and they perform those calculations once.
Lambda expressions allow you to define (in an expression) via different syntax code that can work on a list and can conceptually be considered a function.
You could simplify this to say "They let you define functions in expressions".
Does not quite get to the "why". The why is the more interesting, in my opinion. Lambda expression allow for the manipulation of functions and partial functions.
When checking if a integer is the same or above a current number.. so I type
if (5 => 6) { //Bla }
but it shows this as a error. Why? Isn't it exactly the same as
if (5 >= 6) { //Bla }
The reason why it does not work is because => is not equivalent to >=.
=> is used in a lambda expression. Like :
(int x, string s) => s.Length > x
I do agree it is annoying. Before lambda expressions I used to get it wrong sometimes. Now I always know that one (=>) is a lambda expression and and other (>=) is the greater than equal to sign
Because the operator is >= not =>.
The writers of the language could have chosen either syntax, but had to choose one. Having two operators meaning the same thing would be confusing at best.
However, the operator is read "greater than or equal to" so it does make sense that the > symbol is first.
Also => is now used for Lambda expressions.
Because => is meant for lambda expressions:
Action<object> print = o => Console.WriteLine(o);
print(123);
Besides, you don't say "equal to or greater than", which is what => would have been pronounced as otherwise.
The confusion here is that you're assuming >= is two operators smooshed together. In fact, it's only one operator with two characters, much the same as tons of other operators (+=, *=, -=, etc).
Why should it be? =! is not the same as != either. This is a part of the languages syntax.
In this specific case, => is also used for lambda expressions so it has another purpose.
Because it is called greater or equal to. Not equal or greater than. Simple uh?
In C# the greater than or less than sign must come BEFORE the equal sign. It is just part of the syntax of the language.
Because => stands for Lambda expressions in c#.
>= stands for greater than or equal to, as you already know.
The syntax is such that you have to use >= while comparing two entities. Also just additionally you can notice that even a space between them will give errors - > =
No, it is not this same. Correct operator in c# is >= for comparission and => for lambda expression.
#Barry's answer is probably the most insightful of the lot here. A single operator does not mean a single character; the fact that > and = combine to form >= does not mean that it's doing both > and =; it's doing a single operation. The fact that the defined operator for that operation includes the characters for two other similar operations is irrelevent.
I suppose if you really wanted to you could override it so that both >= and => worked the same way -- C# does allow operator overrides. But it would be a bad idea because as others have already said, => is actually in use for other purposes.
I am looking for a parser that can operate on a query filter. However, I'm not quite sure of the terminology so it's proving hard work. I hope that someone can help me. I've read about 'Recursive descent parsers' but I wonder if these are for full-blown language parsers rather than the logical expression evaluation that I'm looking for.
Ideally, I am looking for .NET code (C#) but also a similar parser that works in T-SQL.
What I want is for something to parse e.g.:
((a=b)|(e=1))&(c<=d)
Ideally, the operators can be definable (e.g. '<' vs 'lt', '=' vs '==' vs 'eq', etc) and we can specify function-type labels (e.g. (left(x,1)='e')). The parser loads this, obeys order precedence (and ideally handles the lack of any brackets) and then calls-back to my code with expressions to evaluate to a boolean result - e.g. 'a=b'?). I wouldn't expect the parser to understand the custom functions in the expression (though some basic ones would be useful, like string splitting). Splitting the expression (into left- and right-hand parts) would be nice.
It is preferable that the parser asks the minimum number of questions to have to work out the final result - e.g. if one side of an AND is false, there is no point evaluating the other side, and to evaluate the easiest side first (i.e. in the above expression, 'c<=d' should be assumed to be quicker and thus evaluated first.
I can imagine that this is a lot of work to do, however, fairly common. Can anyone give me any pointers? If there aren't parsers that are as flexible as above, are there any basic parsers that I can use as a start?
Many Thanks
Lee
Take a look at this. ANTLR is a good parser generator and the linked-to article has working code which you may be able to adapt to your needs.
You could check out Irony. With it you define your grammar in C# code using a syntax which is not to far from bnf. They even have a simple example on their site (expression evaluator) which seems to be quite close to what you want to achieve.
Edit: There's been a talk about Irony at this year's Lang.Net symposium.
Hope this helps!
Try Vici.Parser: download it here (free) , it's the most flexible expression parser/evaluator I've found so far.
If it's possible for you, use .Net 3.5 expressions.
Compiler parses your expression for you and gives you expression tree that you can analyze and use as you need. Not very simple but doable (actually all implementations of IQueryable interface do exactly this).
You can use .NET expression trees for this. And the example is actually pretty simple.
Expression<Func<int, int, int, int, bool>> test = (int a, int b, int c, int d) => ((a == b) | (c == 1)) & (c <= d);
And then just look at "test" in the debugger. Everything is already parsed for you, you can just use it.
The only problem is that in .NET 3.5 you can have only up to 4 arguments in Func. So, I changed "e" to "c" in one place. In 4.0 this limit is changed to 16.
What is the best was to evaluate an expression like the following:
(A And B) Or (A And C) Or (Not B And C)
or
(A && B) || (A && C) || (!B && C)
At runtime, I was planning on converting the above expressions to the following:
(True And False) Or (True And False) Or (Not False And True)
or
(True && False) || (True && False) || (! False && True)
Conditions:
1) The logical expression is not known until runtime.
2) The number variable and their values are not known until runtime.
3) Variable values are never null.
I know I could create a simple assemble with a class and a method that I generate at runtime based on the inputs, but is there a better way.
I have done this before. Use a string builder to write the code, then call the compiler. After that, you load the assembly and call the method.
Suggestions?
Thanks.
If you're using .NET3.5 then you can parse the text and create an abstract sytax tree using the Expression classes. Then create a suitable LambdaExpression instance and compile it into a delegate, which you can then execute.
Constructing a parser and syntax tree builder for this kind of fairly simple grammer is quite an interesting exercise, and will execute somewhat faster than invoking the compiler (and it's neater in my view as well).
If you're not using .NET3.5, then it's also not complicated to implement an interpreted abstract syntax tree yourself.
Be warned: the two final conditions you're talking about are not necessarily equivalent. The && operators in C# will use short-circuit evalution, while the logical And operator in VB does not. If you want to be sure the statements are equivalent, translate a user And to AndAlso and a user Or to OrElse.
For simple expresssions you probably won't notice a difference. But if the conditions can have side effects or if the performance difference between the two is a concern, this can be important.
You can use https://github.com/mrazekv/logicalparser
Its simply library to write logical expression (evaulated with precenednce table, allows to OR, NOT, AND operator and >, >=, <=, < on integer variables and = on string variables)
You can do this easily with:
a parser generator (like ANTLR, mentioned above) that takes boolean expressions as input and produces an infix list and
code to evaluate a Reverse Polish Notation stack.
The grammar looks something like this:
program: exprList ;
exprList: expr { Append($1); }
| expr OR exprList { Append(OR); }
| expr AND exprList { Append(AND); }
| NOT exprList { Append(NOT); }
| ( exprList ) { /* Do nothing */ }
;
expr: var { Append($1); }
| TRUE { Append(True); }
| FALSE { Append(False); }
;
To evaluate, you do this:
for each item in list
if item is symbol or truth value, push onto RPN stack
else if item is AND, push (pop() AND pop())
else if item is OR, push (pop() OR pop())
else if item is NOT, push (NOT pop())
result = pop()
For symbols, you have to substitute the truth value at runtime.
You can write a simple interpreter/parser. Use something like ANTLR and reuse existing grammars.
If you are using .NET 3.5, you can create a Lambda Expression. Then you can create a delegate from it and call as standard delegate/method.
On the internet is a lot of samples about Lambda Expressions.
One solution would be to assemble the expression as a string, and then send it SQL Server, or whatever your database is for evaluation. Replace the actual variables with 1=1 or 0=1 for True and False respectively, and you would end up with a query like this:
SELECT 1 WHERE (1=1 And 0=1) Or (1=1 And 1=1) Or (Not 0=1 And 1=1)
Then when you run the query, you get a 1 back when the result is true. May not be the most elegant solution, but it will work. A lot of people will probably advise against this, but I'm just going to throw it out there as a possible solution anyway.
This will not be the best answer, but I myself had this problem some time ago.
Here is my old code:
VB.Net - no warranty at all!
https://cloud.downfight.de/index.php/s/w92i9Qq1Ia216XB
Dim BoolTermParseObjekt As New BoolTermParse
MsgBox(BoolTermParseObjekt.parseTerm("1 und (((0 oder 1 und (0 oder 4))) oder 2)").ToString)
This code eats a String with multiple '(', ')', 'and', 'or' plus 'other things' and breaks down the logic to a boolean by replacing the things with boolean values.
therefore:
Whatever 'other things' I wanted to evaluate I had to put in Function resolveTerm()
at the comment "'funktionen ausführen und zurückgeben, einzelwert!"
in page 2.
There the only evaluation rightnow is "If number is > 1"
Greetings
Take a look at my library, Proviant. It's a .NET Standard library using the Shunting Yard algorithm to evaluate boolean expressions.
It could also generate a truth-table for your expressions.
You could also implement your own grammar.