Add a script to update operator precedence documentation

This commit is contained in:
Fabien Potencier
2025-01-26 15:19:24 +01:00
parent 42c82e1e9b
commit 9334a7064a
3 changed files with 122 additions and 28 deletions
+64
View File
@@ -0,0 +1,64 @@
<?php
use Twig\Environment;
use Twig\Loader\ArrayLoader;
use Twig\Operator\OperatorArity;
use Twig\Operator\OperatorAssociativity;
require_once dirname(__DIR__).'/vendor/autoload.php';
function printOperators($output, array $operators, bool $withAssociativity = false)
{
if ($withAssociativity) {
fwrite($output, "\n=========== =========== =============\n");
fwrite($output, "Precedence Operator Associativity\n");
fwrite($output, "=========== =========== =============\n");
} else {
fwrite($output, "\n=========== ===========\n");
fwrite($output, "Precedence Operator\n");
fwrite($output, "=========== ===========\n");
}
usort($operators, function($a, $b) {
$aPrecedence = $a->getPrecedenceChange() ? $a->getPrecedenceChange()->getNewPrecedence() : $a->getPrecedence();
$bPrecedence = $b->getPrecedenceChange() ? $b->getPrecedenceChange()->getNewPrecedence() : $b->getPrecedence();
return $bPrecedence - $aPrecedence;
});
$current = \PHP_INT_MAX;
foreach ($operators as $operator) {
$precedence = $operator->getPrecedenceChange() ? $operator->getPrecedenceChange()->getNewPrecedence() : $operator->getPrecedence();
if ($precedence !== $current) {
$current = $precedence;
if ($withAssociativity) {
fwrite($output, \sprintf("\n%-11d %-11s %s", $precedence, $operator->getOperator(), OperatorAssociativity::Left === $operator->getAssociativity() ? 'Left' : 'Right'));
} else {
fwrite($output, \sprintf("\n%-11d %s", $precedence, $operator->getOperator()));
}
} else {
fwrite($output, "\n".str_repeat(' ', 12).$operator->getOperator());
}
}
fwrite($output, "\n");
}
$output = fopen(dirname(__DIR__).'/doc/operators_precedence.rst', 'w');
$twig = new Environment(new ArrayLoader([]));
$unaryOperators = [];
$notUnaryOperators = [];
foreach ($twig->getOperators() as $operator) {
if ($operator->getArity()->value == OperatorArity::Unary->value) {
$unaryOperators[] = $operator;
} else {
$notUnaryOperators[] = $operator;
}
}
fwrite($output, "Unary operators precedence:\n");
printOperators($output, $unaryOperators);
fwrite($output, "\nBinary and Ternary operators precedence:\n");
printOperators($output, $notUnaryOperators, true);
fclose($output);
+56
View File
@@ -0,0 +1,56 @@
Unary operators precedence:
=========== ===========
Precedence Operator
=========== ===========
500 -
+
70 not
0 (
Binary and Ternary operators precedence:
=========== =========== =============
Precedence Operator Associativity
=========== =========== =============
300 | Left
.
[
(
250 => Left
200 ** Right
100 is Left
is not
60 * Left
/
//
%
30 + Left
-
27 ~ Left
25 .. Left
20 == Left
!=
<=>
<
>
>=
<=
not in
in
matches
starts with
ends with
has some
has every
18 b-and Left
17 b-xor Left
16 b-or Left
15 and Left
12 xor Left
10 or Left
5 ?: Right
??
0 ? Left
+2 -28
View File
@@ -1033,35 +1033,9 @@ Understanding the precedence of these operators is crucial for writing correct
and efficient Twig templates.
The operator precedence rules are as follows, with the lowest-precedence
operators listed first:
operators listed first.
============================= =================================== =====================================================
Operator Score of precedence Description
============================= =================================== =====================================================
``?:`` 0 Ternary operator, conditional statement
``or`` 10 Logical OR operation between two boolean expressions
``xor`` 12 Logical XOR operation between two boolean expressions
``and`` 15 Logical AND operation between two boolean expressions
``b-or`` 16 Bitwise OR operation on integers
``b-xor`` 17 Bitwise XOR operation on integers
``b-and`` 18 Bitwise AND operation on integers
``==``, ``!=``, ``<=>``, 20 Comparison operators
``<``, ``>``, ``>=``,
``<=``, ``not in``, ``in``,
``matches``, ``starts with``,
``ends with``, ``has some``,
``has every``
``..`` 25 Range of values
``+``, ``-`` 30 Addition and subtraction on numbers
``~`` 40 String concatenation
``not`` 50 Negates a statement
``*``, ``/``, ``//``, ``%`` 60 Arithmetic operations on numbers
``is``, ``is not`` 100 Tests
``**`` 200 Raises a number to the power of another
``??`` 300 Default value when a variable is null
``+``, ``-`` 500 Unary operations on numbers
``|``,``[]``,``.`` - Filters, sequence, mapping, and attribute access
============================= =================================== =====================================================
.. include:: operators_precedence.rst
Without using any parentheses, the operator precedence rules are used to
determine how to convert the code to PHP: