Search code examples
javaparsinglexermathematical-expressions

Control if a String is a mathematical expression


I'm searching a way to check if a String is a mathematical expression as i.e.

x + y -sin(1) * 99k

i don't wanna evaluate the expression, but understand if the String is written in the right way.

There is some Java library for do that?

UPDATE: I'm sorry, is not an equation but only an expression (nothing '='). I have think about a possible solution:

  1. Specify the variables used
  2. replace all the variables with '1'
  3. evaluate the new String with JEval
  4. if the program raise an Exception, the expression is wrong

What you think about that?

Thanks


Solution

  • Try ANTLR. You could write a grammar like:

    grammar Expr;       
    
    expr:   FuncitonName '(' expr ')'
        |   '-' expr
        |   '(' expr ')'
        |   expr '*' expr
        |   expr '+' expr
        |   expr '-' expr
        |   expr '/' expr
        |   Const
        |   Variable
        ;
    
    FuncitonName : [a-z] + ; 
    Variable : [a-zA-Z] + ;
    Const : [0-9] +;
    
    WS  :  [ \t\r\n\u000C]+ -> skip;
    

    You should define the grammar more properly depending on which expression are allowed and which are not. Save it in the file Expr.g4 and execute antlr4 Expr.g4 to get your ExprLexer.java and ExprParser.java files. Then you could use them to check if a sentence is an arithmetic expression :

    import org.antlr.v4.runtime.ANTLRInputStream;
    import org.antlr.v4.runtime.BailErrorStrategy;
    import org.antlr.v4.runtime.CommonTokenStream;
    import org.antlr.v4.runtime.misc.ParseCancellationException;
    
    public static boolean isExpr(String exp) {
    
        ExprLexer lexer = new ExprLexer(new ANTLRInputStream(exp));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ExprParser parser = new ExprParser(tokens);
    
        parser.removeErrorListeners();
        parser.setErrorHandler(new BailErrorStrategy());
    
        try {
            parser.expr();
            return true;
        }  catch (ParseCancellationException e) {
            return false;
        }
    
    }
    

    and finally test:

    System.out.println(isExpr("x + y -sin(1) * 99 * k")); //true
    System.out.println(isExpr("x + y +")); //false
    

    You could refer to this question.