}, 'exp_a -> T_LP exp_a T_RP' => function (&$info) {
    $info = $info[1];
}, 'exp_a -> T_SQRT T_LP exp_a T_RP' => function (&$info) {
    $info = sqrt($info[2]);
}, 'exp_a -> T_NUM' => function (&$info) {
    $info = intval($info[0]->value());
}]);
/**
 * Tokens definition.
 */
$tokens = ['\\*' => 'T_MUL', '\\/' => 'T_DIV', '\\+' => 'T_PLS', '\\-' => 'T_SUB', 'sqrt' => 'T_SQRT', '[0-9]+' => 'T_NUM', '\\(' => 'T_LP', '\\)' => 'T_RP', '\\s+|\\n+|\\t+' => ''];
/**
 * Startup the parser.
 */
$lexer = new Lexer($tokens);
$grammar = new Grammar($productions);
$parser = new Parser($lexer, $grammar);
/**
 * Configure tokens precedence.
 */
$grammar->prec('T_MUL', 4);
$grammar->prec('T_DIV', 3);
$grammar->prec('T_SUB', 2);
$grammar->prec('T_PLS', 1);
/**
 * The expression to parse.
 */
$exp = '50 + 20 * 3 / 2 - 1';
/**
 * Run the parser.
 */
}, 'exp_a -> T_LP exp_a T_RP' => function (&$info) {
    $info = $info[1];
}, 'exp_a -> T_SQRT T_LP exp_a T_RP' => function (&$info) {
    $info = sqrt($info[2]);
}, 'exp_a -> T_NUM' => function (&$info) {
    $info = intval($info[0]->value());
}]);
/**
 * Tokens definition.
 */
$tokens = ['\\*' => 'T_MUL', '\\+' => 'T_PLS', '\\-' => 'T_SUB', '\\/' => 'T_DIV', 'sqrt' => 'T_SQRT', '[0-9]+' => 'T_NUM', '\\(' => 'T_LP', '\\)' => 'T_RP', '\\s+|\\n+|\\t+' => ''];
/**
 * Startup the parser.
 */
$lexer = new Lexer($tokens);
$grammar = new Grammar($productions);
$parser = new Parser($lexer, $grammar);
/**
 * The expression to parse.
 */
$exp = '50 + (20 * 2) + 1 - (1 / 2) + sqrt(90)';
/**
 * Run the parser.
 */
$parser->run($exp);
/**
 * Print some debug information.
 */
echo "<code><p><b>{$exp}</b> = {$RESULT}</p></code><hr/>";
echo "<h2>Paser trace:</h2>";
debug($parser->trace());
use Phparser\Lexer\Lexer;
use Phparser\Parser\Parser;
use Phparser\Rule\LR0\RulesCollection;
/**
 * Boolean language definition.
 */
$productions = new RulesCollection(['S -> exp_b', 'exp_b -> exp_b exp_b', 'exp_b -> exp_b T_OR exp_b', 'exp_b -> exp_b T_AND exp_b', 'exp_b -> T_NOT exp_b', 'exp_b -> T_LP exp_b T_RP', 'exp_b -> expression', 'expression -> statement', 'expression -> command', 'statement -> T_LITERAL', 'statement -> T_WORD', 'command -> T_WORD T_CMD command_arg', 'command_arg -> T_LITERAL', 'command_arg -> T_WORD']);
/**
 * Tokens definition.
 */
$tokens = ['and' => 'T_AND', 'or' => 'T_OR', '\\-' => 'T_NOT', '"[^"]+"' => 'T_LITERAL', '\\w+' => 'T_WORD', '\\(' => 'T_LP', '\\)' => 'T_RP', ':' => 'T_CMD', '\\s+|\\n+|\\t+' => ''];
/**
 * Startup the parser.
 */
$lexer = new Lexer($tokens);
$grammar = new Grammar($productions);
$parser = new Parser($lexer, $grammar);
/**
 * Configure tokens precedence.
 */
$grammar->prec('T_NOT', 3);
$grammar->prec('T_AND', 2);
$grammar->prec('T_OR', 1);
/**
 * The expression to parse.
 */
$exp = 'A and B or C and -negated';
/**
 * Run the parser.
 */
$parser->run($exp);