src/sim/mathexpr.cc
/**
 * This function parses a string expression into an expression tree.
 * It will look for operators in priority order to recursively build the
 * tree, respecting parenthesization.
 * Constants can be expressed in any format accepted by std::stod, whereas
 * variables are essentially [A-Za-z0-9\.$\\]+
 */
This function parses a string expression into an expression tree.
It will look for operators in priority order to recursively build the
tree, respecting parenthesization.
Constants can be expressed in any format accepted by std::stod, whereas
variables are essentially [A-Za-z0-9\.$\\]+
This function parses a string expression into an expression tree . It will look for operators in priority order to recursively build the tree respecting parenthesization . Constants can be expressed in any format accepted by std :: stod whereas variables are essentially [ A - Za - z0 - 9 \ . $ \\ ] +
MathExpr::Node *
MathExpr::parse(std::string expr) {
    if (expr.size() == 0)
        return NULL;
    int par = 0;
    for (unsigned p = 0; p < MAX_PRIO; p++) {
        for (int i = expr.size() - 1; i >= 0; i--) {
            if (expr[i] == ')')
                par++;
            if (expr[i] == '(')
                par--;
            if (par < 0) return NULL;
            if (par > 0) continue;
            for (unsigned opt = 0; opt < ops.size(); opt++) {
                if (ops[opt].priority != p) continue;
                if (ops[opt].c == expr[i]) {
                    Node *l = NULL;
                    if (ops[opt].binary)
                        l = parse(expr.substr(0, i));
                    Node *r = parse(expr.substr(i + 1));
                    if ((l && r) || (!ops[opt].binary && r)) {
                        Node *n = new Node();
                        n->op = ops[opt].op;
                        n->l = l;
                        n->r = r;
                        return n;
                    }
                }
            }
        }
    }
    if (expr.size() >= 2 && expr[0] == '(' && expr[expr.size() - 1] == ')')
        return parse(expr.substr(1, expr.size() - 2));
    {
        char *sptr;
        double v = strtod(expr.c_str(), &sptr);
        if (sptr != expr.c_str()) {
            Node *n = new Node();
            n->op = sValue;
            n->value = v;
            return n;
        }
    }
    {
        bool contains_non_alpha = false;
        for (auto & c: expr)
            contains_non_alpha = contains_non_alpha or
                !( (c >= 'a' && c <= 'z') ||
                   (c >= 'A' && c <= 'Z') ||
                   (c >= '0' && c <= '9') ||
                   c == '$' || c == '\\' || c == '.' || c == '_');
        if (!contains_non_alpha) {
            Node * n = new Node();
            n->op = sVariable;
            n->variable = expr;
            return n;
        }
    }
    return NULL;
}
MathExpr :: Node * MathExpr :: parse ( std :: string expr ) { if ( expr . size ( ) == 0 ) return NULL ; int par = 0 ; for ( unsigned p = 0 ; p < MAX_PRIO ; p ++ ) { for ( int i = expr . size ( ) - 1 ; i >= 0 ; i -- ) { if ( expr [ i ] == ' ' ) par ++ ; if ( expr [ i ] == ' ' ) par -- ; if ( par < 0 ) return NULL ; if ( par > 0 ) continue ; for ( unsigned opt = 0 ; opt < ops . size ( ) ; opt ++ ) { if ( ops [ opt ] . priority != p ) continue ; if ( ops [ opt ] . c == expr [ i ] ) { Node * l = NULL ; if ( ops [ opt ] . binary ) l = parse ( expr . substr ( 0 , i ) ) ; Node * r = parse ( expr . substr ( i + 1 ) ) ; if ( ( l && r ) || ( ! ops [ opt ] . binary && r ) ) { Node * n = new Node ( ) ; n -> op = ops [ opt ] . op ; n -> l = l ; n -> r = r ; return n ; } } } } } if ( expr . size ( ) >= 2 && expr [ 0 ] == ' ' && expr [ expr . size ( ) - 1 ] == ' ' ) return parse ( expr . substr ( 1 , expr . size ( ) - 2 ) ) ; { char * sptr ; double v = strtod ( expr . c_str ( ) , & sptr ) ; if ( sptr != expr . c_str ( ) ) { Node * n = new Node ( ) ; n -> op = sValue ; n -> value = v ; return n ; } } { bool contains_non_alpha = false ; for ( auto & c : expr ) contains_non_alpha = contains_non_alpha or ! ( ( c >= ' ' && c <= ' ' ) || ( c >= ' ' && c <= ' ' ) || ( c >= ' ' && c <= ' ' ) || c == ' ' || c == ' \\ ' || c == ' ' || c == ' ' ) ; if ( ! contains_non_alpha ) { Node * n = new Node ( ) ; n -> op = sVariable ; n -> variable = expr ; return n ; } } return NULL ; }
This function parses a string expression into an expression tree.
This function parses a string expression into an expression tree .
// From low to high priority // Try to parse each side // Match! // Remove trivial parenthesis // Match a number // Match a variable