Validating a string mathematical expression

℡╲_俬逩灬. 提交于 2019-12-11 06:30:11

问题


Guys I am working on a system that evaluates string mathematical expression.

my class to carry out the calculation

public Double Calculate(string argExpression)
{
    //get the user passed string
    string ExpressionToEvaluate = argExpression;

    //pass string in the evaluation object declaration.
    Expression z = new Expression(ExpressionToEvaluate);

    //command to evaluate the value of the **************string expression
    var result = z.Evaluate();
    Double results = Convert.ToDouble(result.ToString());

    return results;
}

And my calling codes.

Double Finalstat = calculator.Calculate(UserQuery); 

Till now my expression were as

4 + 5 + 69 * (100*3)

However during testing I found that the expression may also be distorted(as it is user built). To things like

45+99abs - 778anv

So I wanted to know if there is a way of validating the user-built(expression) before sending it to be evaluated in the class ?


回答1:


I'd suggest you to use CodeDom as it can perfectly do validation:

            CodeDomProvider provider = CSharpCodeProvider.CreateProvider("C#");
            CompilerParameters options = new CompilerParameters();
            options.GenerateExecutable = false;
            options.GenerateInMemory = true;
            // create code
            string source = "using System;namespace Expression{public static class Expression{public static void Test() {\n";
            source += expression; // your expression
            source +=";}}}";
            // compile
            var result = provider.CompileAssemblyFromSource(options, source);
            if (result.Errors.HasErrors)
                foreach (CompilerError error in result.Errors)
                    ; // use error.Column and .Row to get where error was, use .ErrorText to get actuall message, to example "Unknown variable aaa"

Have to leave now, hope I didn't make mistakes (if I did, someone should correct me ^^).. till Monday..




回答2:


Parsing mathematical expressions initially seems easy but becomes tricky very quickly, especially when you use regular expressions (this is a reference to your other questions).

It's easier to create a simple parser using ANTLR to validate and eventually execute your expressions. ANTLR is a very popular parser generator that is even used in ASP.NET MVC.

There are many dialects available and several great tutorials, but the answer to this SO question actually shows how to create a mathematical expression parser that eventually evaluates its input.

You can check the (surprisingly small) grammar file in the answer, but the actual usage is quite simple:

  string expression = "(12.5 + 56 / -7) * 0.5";
  ANTLRStringStream Input = new ANTLRStringStream(expression);  
  ExpressionLexer Lexer = new ExpressionLexer(Input);
  CommonTokenStream Tokens = new CommonTokenStream(Lexer);
  ExpressionParser Parser = new ExpressionParser(Tokens);
  Console.WriteLine(expression + " = " + Parser.parse());

The question dates to 2010 when you needed java to create your parser files from the grammar. Later versions of ANTLR removed this requirement.




回答3:


With regexes you will have a problem due to simple fact you have to validate parentheses:

abs(sin(log(...)))

You should parse the expression, not just match it against some pattern. Writing parser rules is also much cleaner and easier to understand. As a bonus you will get not only validation but also evaluation of the expression. My suite NLT contains everything you need for C# (there is already simple calculator included), and say you would like to enhance it by adding abs.

You can omit lexer section, and go right to parser:

expr -> "abs" "(" e:expr ")"  // pattern
        { Math.Abs(e) };      // action

assuming expr is already defined with sum, subtraction, and so on.

For curious soul -- not "abs(" because in such case as abs ( 5 )would give error (invalid expression).



来源:https://stackoverflow.com/questions/20422853/validating-a-string-mathematical-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!