PHP code example of sterzik / expression

1. Go to this page and download the library: Download sterzik/expression library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

sterzik / expression example snippets


use Sterzik\Expression\Parser;


use Sterzik\Expression\Parser;

$parser = new Parser();

#quotes are part of the string, backslash must be double encoded
#because of the php string syntax
$expr = $parser->parse('"Hello world!\\n"'); 
echo $expr->evaluate();

$parser = new Parser();
$expression = $parser->parse("1+2*3");

$value = $expression->evaluate();

$expr = $parser->parse("a+b*(c+d)");
$vars = ["a" => 1, "b" => 2, "c" => 3, "d" => 4];
$result = $expr->evaluate($vars);

$defaultParserSettings = ParserSettings::get("default");
$emptyParserSettings = ParserSettings::get("empty");

$ps = ParserSettings::get("empty");
$ps->opPriority(1);
$ps->opArity("L");
$ps->addOp("+");
$ps->addOp("*");

$ps->addOp("plus");

$ps->addOp("+");
$ps->addOp("plus", "+");

$parser = new Parser($parserSettings);

$expr = $parser->parse("1 plus 2");

$oldDefault = $parserSettings->setDefault();
$parser = new Parser(); #this parser uses $parserSettings as parser settings
$oldDefault->setDefault();
$parser2 = new Parser(); #this parser uses the original parser settings 

$parserSettings->addConstant("true", true);

$parserSettings->addPrefixOp("++");
$parserSettings->addPostfixOp("--");

$parserSettings->addPrefixOp("++x", "++");
$parserSettings->addPostfixOp("x++", "++");

$parserSettings->addMultinaryOp("?:", "?", ":");

$parserSettings->addVariadicOp(",");

$parserSettings->addParenthesis("()", "(", ")", false);

$parserSettings->addPostfixIndex("fn()", "(", ")", true);

$parserSettings->addPrefixIndex("<<>>", "<<", ">>", false);

$parser = new Parser($parserSettings, false); #creates a parser NOT throwing exceptions
$expr = $parser->parse($expressionString);
if ($expr === null) {
    echo "parser error: " . $parser->getLastError() . "\n";
    return;
} 

$parser = new Parser($parserSettings, true); #creates a parser in exception throwing mode
try {
    $expr = $parser->parse($expressionString);
} catch(ParserException $e) {
    echo "parser error: " . $e->getMessage() . "\n";
    return;
}

$parser = new Parser($parserSettings);
$parser->throwExceptions(true); #parser in exception throwing mode
$parser->throwExceptions(false); #parser in "return null" mode

if ($expr->type() == "const") {
    $value = $expr->value();
    echo "The expression represents a constant with a value of: " . $value . "\n";
}

if ($expr->type() == "var") {
    $name = $expr->name();
    echo "The expression represents a variable with a name: ".$name."\n";
}

if ($expr->type() == "op") {
    $identifier = $expr->op();
    $arguments = $expr->arguments();
    #easy accessing arguments:
    foreach ($expr as $argument) {
        #do something with each argument
    }

}

$constant = Expression::create("const", 15);
$variable = Expression::create("var", "abc");
$operation = Expression::create("op", "+", $constant, $variable); #alternative #1
$operation = Expression::create("op", "+", [$constant, $variable]); #alternative #2

$dataStruct = $expr->dump();       #dumps as a php structure without objects (serializable to json) 
$dataJson   = $expr->dumpJson();   #dumps into a json encoded  string
$dataB64    = $expr->dumpBase64(); #dumps into a base64 encoded string

$expr = Expression::restore($dataStruct);
$expr = Expression::restoreJson($dataJson);
$expr = Expression::restoreBase64($dataB64);

 # obtain the default evaluator
 # (able to evaluate all operations from the default parser)
 $evaluator = Evaluator::get("default"); 
 
 # obtain the empty evaluator
 # (no operations are defined there)
 $evaluator = Evaluator::get("empty");

$result = $expr->evaluate($varObject, $evaluator);

$oldEvaluator = $evaluator->setDefault();
$expr->evaluate($varObject); # $evaluator need not be passed, because it is default now

$evaluator->defConstant(function ($const) {
    return $const;
});

$evaluator->defVar(function ($var, $varObject) {
    return $varObject[$var];
});

$evaluator->defOp("+", function ($a, $b) {
    return $a + $b;
});

$evaluator->defOp("-", function ($a, $b) {
    return $a-$b;
});
$evaluator->defOp("-", function ($a) {
    return - $a;
});

$evaluator->defOpDefault(function ($operation, ...$arguments) {
    #do something with the operation and theirs arguments
    return $result
});

$evaluator->defOp("-", function ($op, $a, $b) {
    #do something depending on $op
    return $result;
}, true);

$evaluator->defOpEx("?:", function ($cond, $ifTrue, $ifFalse) {
    return $cond->value() ? $ifTrue->value() : $ifFalse->value();
});

 function createVariableLValue($varName, $varObject)
 {
     $builder = new LValueBuilder();
     $builder->value(function () use ($varName, $varObject) {
         return $varObject[$varName];
     });
     $builder->assign(function ($value) use ($varName, $varObject) {
         $varObject[$varName] = $value;
     });
     
     return $builder->getLValue();
     
 }

$evaluator->defVar(function ($var, $varObject) {
    return createVariableLValue($varName, $varObject);
});

$varObject = new Variables(["a" => 1, "b" => 2, "c" => 3]);
$varObject["a"] = 2;
unset($varObject["c"]);
foreach($varObject as $variable => $value) {
    #do something for all variables and its values
}
$varArray = $varObject->asArray(); #convert back to an ordinary array

$evaluator->defOpEx("=", function ($a, $b) {
    $a->assign($b->value());
});

#piece #1
$evaluator->defOpEx("some_unary_operator", function ($arg) {
    return $arg->value() + $arg->value();
});
#piece #2
$evaluator->defOpEx("someoperator", function ($arg) {
    $arg = $arg->lvalue();
    return $arg->value() + $arg->value();
});


$evaluator->defNotLvalue(function () {
    throw new Exception("LValue 

function createVariableLValue($varName, $varObject)
{
    $builder = new LValueBuilder();
    $builder->value(function () use ($varName, $varObject) {
        return $varObject[$varName];
    });
    $builder->assign(function ($value) use ($varName, $varObject) {
        $varObject[$varName] = $value;
    });

    $builder->setDefaultCallback(function ($method) {
        throw new Exception("Method ".$method." is not supported for that L-value");
    });

    return $builder->getLValue();
}


$parserSettings->addParenthesis('()', '(', ')');
$parserSettings->setPostprocessOp('()', function ($expr, $op) {
    return $expr[0];
});

$parserSettings->addPostfixIndex('fn()', '(', ')', true);
#ensure the op ',' will have the lowest priority
$parserSettings->opPriority('0');
$parserSettings->addVariadicOp(',');
$parserSettings->setPostprocessOp('fn()', function ($expr, $op) {
    # count($expr) is the number of arguments of the 'fn()' operation
    # possibilities for the number of arguments:
    # 0 - impossible
    # 1 - fncall without any argument
    # 2 - fncall with one or more arguments
    # 3 or more - impossible
    if (count($expr) != 2) {
        return $expr;
    }
    $arg = $expr[1];
    #if the second argument is not the ',' operator, we don't need to postprocess anything
    if ($arg->type() != "op" || $arg->op() != ",") {
        return $expr;
    }
    $newArguments = array_merge([$expr[0]], $arg->arguments());
    return Expression::create("op", "fn()", $newArguments);
});

#convert all variables "parent" to some variable depending on the current context
$parserSettings->setPostprocessVar(function ($expr) {
    if ($expr->name() == "parent") {
        $parentVar = getCurrentParentName(); #obtain somehow the current parent name
        return Expression::create("var", $parentVar);
    }
    return null;
});

#convert all non-string constants to strings
$parserSettings->setPostprocessConst(function ($expr) {
    if (!is_string($expr->value())) {
        return Expression::create("const", (string)$expr->value());
    }
    return null;
});

$parserSettings->setDefaultPostprocessOp(function ($expr, $op) {
    return Expression::create("op", "postprocessed:$op", $expr->arguments());
});
dump()
function lvalue()
function fncall($arguments)