File: generate_operators_precedence.php

package info (click to toggle)
php-twig 3.22.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,396 kB
  • sloc: php: 24,892; makefile: 111; sh: 43
file content (97 lines) | stat: -rw-r--r-- 5,938 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php

/*
 * This file is part of Twig.
 *
 * (c) Fabien Potencier
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Twig\Environment;
use Twig\ExpressionParser\ExpressionParserDescriptionInterface;
use Twig\ExpressionParser\ExpressionParserType;
use Twig\ExpressionParser\InfixAssociativity;
use Twig\ExpressionParser\InfixExpressionParserInterface;
use Twig\Loader\ArrayLoader;

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+------------+------------------+---------+---------------+".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';
    $previousAssociativity = $previous ? ($previous instanceof InfixExpressionParserInterface ? (InfixAssociativity::Left === $previous->getAssociativity() ? 'Left' : 'Right') : 'n/a') : 'n/a';
    if ($previousPrecedence !== $precedence) {
        $previous = null;
    }
    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 : '',
        !$previous || $previousAssociativity !== $associativity ? $associativity : '',
        $expressionParser instanceof ExpressionParserDescriptionInterface ? $expressionParser->getDescription() : '',
    )));
    $previous = $expressionParser;
}
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+------------+------------------+---------+---------------+".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();
    $bPrecedence = $b->getPrecedenceChange() ? $b->getPrecedenceChange()->getNewPrecedence() : $b->getPrecedence();

    return $bPrecedence - $aPrecedence;
});

$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';
    $previousAssociativity = $previous ? ($previous instanceof InfixExpressionParserInterface ? (InfixAssociativity::Left === $previous->getAssociativity() ? 'Left' : 'Right') : 'n/a') : 'n/a';
    if ($previousPrecedence !== $precedence) {
        $previous = null;
    }
    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 : '',
        !$previous || $previousAssociativity !== $associativity ? $associativity : '',
        $expressionParser instanceof ExpressionParserDescriptionInterface ? $expressionParser->getDescription() : '',
    )));
    $previous = $expressionParser;
}
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");

fclose($output);