fix the rst syntax of the operator precedence table

This commit is contained in:
Christian Flothmann
2025-02-16 22:31:07 +01:00
parent 576b4126a6
commit a544dc8b33
2 changed files with 208 additions and 110 deletions
+18 -10
View File
@@ -21,19 +21,24 @@ require_once \dirname(__DIR__).'/vendor/autoload.php';
$output = fopen(\dirname(__DIR__).'/doc/operators_precedence.rst', 'w');
$twig = new Environment(new ArrayLoader([]));
$descriptionLength = 11;
$expressionParsers = [];
foreach ($twig->getExpressionParsers() as $expressionParser) {
$expressionParsers[] = $expressionParser;
$descriptionLength = max($descriptionLength, $expressionParser instanceof ExpressionParserDescriptionInterface ? strlen($expressionParser->getDescription()) : '');
}
fwrite($output, "\n=========== ================ ======= ============= ===========\n");
fwrite($output, "Precedence Operator Type Associativity Description\n");
fwrite($output, '=========== ================ ======= ============= ===========');
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");
fwrite($output, "| Precedence | Operator | Type | Associativity | Description".str_repeat(' ', $descriptionLength - 11)." |\n");
fwrite($output, '+============+==================+=========+===============+'.str_repeat('=', $descriptionLength + 2).'+');
usort($expressionParsers, fn ($a, $b) => $b->getPrecedence() <=> $a->getPrecedence());
$previous = null;
foreach ($expressionParsers as $expressionParser) {
if (null !== $previous) {
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2).'+');
}
$precedence = $expressionParser->getPrecedence();
$previousPrecedence = $previous ? $previous->getPrecedence() : \PHP_INT_MAX;
$associativity = $expressionParser instanceof InfixExpressionParserInterface ? (InfixAssociativity::Left === $expressionParser->getAssociativity() ? 'Left' : 'Right') : 'n/a';
@@ -41,7 +46,7 @@ foreach ($expressionParsers as $expressionParser) {
if ($previousPrecedence !== $precedence) {
$previous = null;
}
fwrite($output, rtrim(\sprintf("\n%-11s %-16s %-7s %-13s %s\n",
fwrite($output, rtrim(\sprintf("\n| %-10s | %-16s | %-7s | %-13s | %-{$descriptionLength}s |\n",
(!$previous || $previousPrecedence !== $precedence ? $precedence : '').($expressionParser->getPrecedenceChange() ? ' => '.$expressionParser->getPrecedenceChange()->getNewPrecedence() : ''),
'``'.$expressionParser->getName().'``',
!$previous || ExpressionParserType::getType($previous) !== ExpressionParserType::getType($expressionParser) ? ExpressionParserType::getType($expressionParser)->value : '',
@@ -50,14 +55,14 @@ foreach ($expressionParsers as $expressionParser) {
)));
$previous = $expressionParser;
}
fwrite($output, "\n=========== ================ ======= ============= ===========\n");
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");
fwrite($output, "\nWhen a precedence will change in 4.0, the new precedence is indicated by the arrow ``=>``.\n");
fwrite($output, "\nHere is the same table for Twig 4.0 with adjusted precedences:\n");
fwrite($output, "\n=========== ================ ======= ============= ===========\n");
fwrite($output, "Precedence Operator Type Associativity Description\n");
fwrite($output, '=========== ================ ======= ============= ===========');
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");
fwrite($output, "| Precedence | Operator | Type | Associativity | Description".str_repeat(' ', $descriptionLength - 11)." |\n");
fwrite($output, '+============+==================+=========+===============+'.str_repeat('=', $descriptionLength + 2).'+');
usort($expressionParsers, function ($a, $b) {
$aPrecedence = $a->getPrecedenceChange() ? $a->getPrecedenceChange()->getNewPrecedence() : $a->getPrecedence();
@@ -68,6 +73,9 @@ usort($expressionParsers, function ($a, $b) {
$previous = null;
foreach ($expressionParsers as $expressionParser) {
if (null !== $previous) {
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2).'+');
}
$precedence = $expressionParser->getPrecedenceChange() ? $expressionParser->getPrecedenceChange()->getNewPrecedence() : $expressionParser->getPrecedence();
$previousPrecedence = $previous ? ($previous->getPrecedenceChange() ? $previous->getPrecedenceChange()->getNewPrecedence() : $previous->getPrecedence()) : \PHP_INT_MAX;
$associativity = $expressionParser instanceof InfixExpressionParserInterface ? (InfixAssociativity::Left === $expressionParser->getAssociativity() ? 'Left' : 'Right') : 'n/a';
@@ -75,7 +83,7 @@ foreach ($expressionParsers as $expressionParser) {
if ($previousPrecedence !== $precedence) {
$previous = null;
}
fwrite($output, rtrim(\sprintf("\n%-11s %-16s %-7s %-13s %s\n",
fwrite($output, rtrim(\sprintf("\n| %-10s | %-16s | %-7s | %-13s | %-{$descriptionLength}s |\n",
!$previous || $previousPrecedence !== $precedence ? $precedence : '',
'``'.$expressionParser->getName().'``',
!$previous || ExpressionParserType::getType($previous) !== ExpressionParserType::getType($expressionParser) ? ExpressionParserType::getType($expressionParser)->value : '',
@@ -84,6 +92,6 @@ foreach ($expressionParsers as $expressionParser) {
)));
$previous = $expressionParser;
}
fwrite($output, "\n=========== ================ ======= ============= ===========\n");
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");
fclose($output);
+190 -100
View File
@@ -1,106 +1,196 @@
=========== ================ ======= ============= ===========
Precedence Operator Type Associativity Description
=========== ================ ======= ============= ===========
512 ``...`` prefix n/a Spread operator
=> 300 ``|`` infix Left Twig filter call
``(`` Twig function call
``.`` Get an attribute on a variable
``[`` Array access
500 ``-`` prefix n/a
``+``
300 => 5 ``??`` infix Right Null coalescing operator (a ?? b)
250 ``=>`` infix Left Arrow function (x => expr)
200 ``**`` infix Right Exponentiation operator
100 ``is`` infix Left Twig tests
``is not`` Twig tests
60 ``*`` infix Left
``/``
``//`` Floor division
``%``
50 => 70 ``not`` prefix n/a
40 => 27 ``~`` infix Left
30 ``+`` infix Left
``-``
25 ``..`` infix Left
20 ``==`` infix Left
``!=``
``<=>``
``<``
``>``
``>=``
``<=``
``not in``
``in``
``matches``
``starts with``
``ends with``
``has some``
``has every``
18 ``b-and`` infix Left
17 ``b-xor`` infix Left
16 ``b-or`` infix Left
15 ``and`` infix Left
12 ``xor`` infix Left
10 ``or`` infix Left
5 ``?:`` infix Right Elvis operator (a ?: b)
``?:`` Elvis operator (a ?: b)
0 ``(`` prefix n/a Explicit group expression (a)
``literal`` A literal value (boolean, string, number, sequence, mapping, ...)
``?`` infix Left Conditional operator (a ? b : c)
=========== ================ ======= ============= ===========
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| Precedence | Operator | Type | Associativity | Description |
+============+==================+=========+===============+===================================================================+
| 512 | ``...`` | prefix | n/a | Spread operator |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| => 300 | ``|`` | infix | Left | Twig filter call |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``(`` | | | Twig function call |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``.`` | | | Get an attribute on a variable |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``[`` | | | Array access |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 500 | ``-`` | prefix | n/a | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``+`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 300 => 5 | ``??`` | infix | Right | Null coalescing operator (a ?? b) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 250 | ``=>`` | infix | Left | Arrow function (x => expr) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 200 | ``**`` | infix | Right | Exponentiation operator |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 100 | ``is`` | infix | Left | Twig tests |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``is not`` | | | Twig tests |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 60 | ``*`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``/`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``//`` | | | Floor division |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``%`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 50 => 70 | ``not`` | prefix | n/a | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 40 => 27 | ``~`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 30 | ``+`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``-`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 25 | ``..`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 20 | ``==`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``!=`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``<=>`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``<`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``>`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``>=`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``<=`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``not in`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``in`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``matches`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``starts with`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``ends with`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``has some`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``has every`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 18 | ``b-and`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 17 | ``b-xor`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 16 | ``b-or`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 15 | ``and`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 12 | ``xor`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 10 | ``or`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 5 | ``?:`` | infix | Right | Elvis operator (a ?: b) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``?:`` | | | Elvis operator (a ?: b) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 0 | ``(`` | prefix | n/a | Explicit group expression (a) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``literal`` | | | A literal value (boolean, string, number, sequence, mapping, ...) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``?`` | infix | Left | Conditional operator (a ? b : c) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
When a precedence will change in 4.0, the new precedence is indicated by the arrow ``=>``.
Here is the same table for Twig 4.0 with adjusted precedences:
=========== ================ ======= ============= ===========
Precedence Operator Type Associativity Description
=========== ================ ======= ============= ===========
512 ``...`` prefix n/a Spread operator
``(`` infix Left Twig function call
``.`` Get an attribute on a variable
``[`` Array access
500 ``-`` prefix n/a
``+``
300 ``|`` infix Left Twig filter call
250 ``=>`` infix Left Arrow function (x => expr)
200 ``**`` infix Right Exponentiation operator
100 ``is`` infix Left Twig tests
``is not`` Twig tests
70 ``not`` prefix n/a
60 ``*`` infix Left
``/``
``//`` Floor division
``%``
30 ``+`` infix Left
``-``
27 ``~`` infix Left
25 ``..`` infix Left
20 ``==`` infix Left
``!=``
``<=>``
``<``
``>``
``>=``
``<=``
``not in``
``in``
``matches``
``starts with``
``ends with``
``has some``
``has every``
18 ``b-and`` infix Left
17 ``b-xor`` infix Left
16 ``b-or`` infix Left
15 ``and`` infix Left
12 ``xor`` infix Left
10 ``or`` infix Left
5 ``??`` infix Right Null coalescing operator (a ?? b)
``?:`` Elvis operator (a ?: b)
``?:`` Elvis operator (a ?: b)
0 ``(`` prefix n/a Explicit group expression (a)
``literal`` A literal value (boolean, string, number, sequence, mapping, ...)
``?`` infix Left Conditional operator (a ? b : c)
=========== ================ ======= ============= ===========
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| Precedence | Operator | Type | Associativity | Description |
+============+==================+=========+===============+===================================================================+
| 512 | ``...`` | prefix | n/a | Spread operator |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``(`` | infix | Left | Twig function call |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``.`` | | | Get an attribute on a variable |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``[`` | | | Array access |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 500 | ``-`` | prefix | n/a | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``+`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 300 | ``|`` | infix | Left | Twig filter call |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 250 | ``=>`` | infix | Left | Arrow function (x => expr) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 200 | ``**`` | infix | Right | Exponentiation operator |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 100 | ``is`` | infix | Left | Twig tests |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``is not`` | | | Twig tests |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 70 | ``not`` | prefix | n/a | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 60 | ``*`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``/`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``//`` | | | Floor division |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``%`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 30 | ``+`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``-`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 27 | ``~`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 25 | ``..`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 20 | ``==`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``!=`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``<=>`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``<`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``>`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``>=`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``<=`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``not in`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``in`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``matches`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``starts with`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``ends with`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``has some`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``has every`` | | | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 18 | ``b-and`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 17 | ``b-xor`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 16 | ``b-or`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 15 | ``and`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 12 | ``xor`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 10 | ``or`` | infix | Left | |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 5 | ``??`` | infix | Right | Null coalescing operator (a ?? b) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``?:`` | | | Elvis operator (a ?: b) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``?:`` | | | Elvis operator (a ?: b) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| 0 | ``(`` | prefix | n/a | Explicit group expression (a) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``literal`` | | | A literal value (boolean, string, number, sequence, mapping, ...) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
| | ``?`` | infix | Left | Conditional operator (a ? b : c) |
+------------+------------------+---------+---------------+-------------------------------------------------------------------+