Changements apportés par l'arbre de syntaxe abstraite (AST) de PHP7

藏色散人
Libérer: 2023-04-05 17:28:01
avant
3788 Les gens l'ont consulté

Changements apportés par l'arbre de syntaxe abstraite (AST) de PHP7

Qu'est-ce qu'un arbre syntaxique abstrait ?

L'arbre de syntaxe abstraite (AST) est une représentation arborescente de la structure syntaxique abstraite du code source. Chaque nœud de l'arborescence représente une structure dans le code source, il est donc abstrait car la syntaxe abstraite. L'arbre ne représente pas tous les détails de la grammaire réelle. Par exemple, les crochets imbriqués sont implicites dans la structure de l'arbre et ne sont pas présentés sous forme de nœuds. L'arbre syntaxique abstrait ne dépend pas de la grammaire de la langue source, ce qui signifie que la grammaire hors contexte utilisée dans l'étape d'analyse syntaxique [La grammaire est les règles formelles utilisées pour décrire la structure grammaticale d'une langue. Chaque langage a sa propre grammaire, qu’il s’agisse du langage machine ou du langage naturel. 】, car lors de l'écriture de la grammaire, des transformations équivalentes sont souvent effectuées sur la grammaire (élimination de la récursion à gauche, retour en arrière, ambiguïté, etc.), ce qui introduira des composants redondants dans l'analyse grammaticale, affectera négativement les étapes suivantes, et même rendra le toute la scène est déroutante. Pour cette raison, de nombreux compilateurs doivent souvent construire des arbres d'analyse syntaxique indépendamment afin d'établir une interface claire pour le front-end et le back-end

La page d'accueil du projet PHP-Parser est https://github.com/nikic/ PHP-Parseur. Il peut parfaitement analyser plusieurs versions de PHP et générer un arbre de syntaxe abstrait.

Nouveau processus d'exécution

Un changement important dans le cœur de PHP7 est l'ajout d'AST. En PHP5, le processus d'exécution des scripts php en opcodes est :

1.Lexing : analyse lexicale, conversion des fichiers sources en flux de jetons

2.Parsing : analyse syntaxique, les tableaux d'opérations sont ; généré à ce stade.

En PHP7, les tableaux op ne sont plus directement générés lors de la phase d'analyse syntaxique, mais AST est généré en premier, il y a donc une étape supplémentaire dans le processus :

1. analyse, conversion du fichier source en flux de jetons ;

2.Parsing : analyse syntaxique, génération d'un arbre de syntaxe abstrait à partir du flux de jetons

3.Compilation : génération de tableaux d'opérations à partir d'un arbre de syntaxe abstrait ;

Temps d'exécution et consommation de mémoire

D'après les étapes ci-dessus, il s'agit d'une étape de plus que le processus précédent, donc selon le bon sens, cela augmentera l'exécution du programme utilisation du temps et de la mémoire. Mais en fait, l'utilisation de la mémoire a effectivement augmenté, mais le temps d'exécution a diminué.

Les résultats suivants sont obtenus en testant trois scripts : petit (environ 100 lignes de code), moyen (environ 700 lignes) et grand (environ 2800 lignes) Script de test : https://gist.github). .com/nikic/289b0c7538b46c2220bc.

Temps d'exécution de la compilation de chaque fichier 100 fois (à noter que le résultat du test de l'article date d'il y a 14 ans, lorsque PHP7 s'appelait encore PHP-NG) :

Changements apportés par larbre de syntaxe abstraite (AST) de PHP7

Pic de mémoire dans une seule compilation :

Changements apportés par larbre de syntaxe abstraite (AST) de PHP7

Les résultats des tests d'une seule compilation peuvent ne pas représenter l'utilisation réelle de PhpParser. Les résultats du test complet du projet :

Changements apportés par larbre de syntaxe abstraite (AST) de PHP7

Le test montre qu'après avoir utilisé AST, le temps d'exécution global du programme est amélioré d'environ 10% à 15%, mais le la consommation de mémoire est également augmentée, l'augmentation est évidente dans une seule compilation de fichiers volumineux, mais ce n'est pas un problème sérieux pendant toute l'exécution du projet.

Notez également que les résultats ci-dessus sont tous sans Opcache. Lorsque Opcache est activé dans un environnement de production, l'augmentation de la consommation de mémoire n'est pas un gros problème.

Changements sémantiques

S'il ne s'agit que d'une optimisation temporelle, cela ne semble pas être une raison suffisante pour utiliser AST. En fait, la mise en œuvre d’AST ne repose pas sur des considérations d’optimisation du temps, mais sur la résolution de problèmes de syntaxe. Jetons un coup d'œil à quelques changements de sémantique.

yield ne nécessite pas de parenthèses

Dans l'implémentation PHP5, si vous utilisez rendement dans un contexte d'expression (comme sur le côté droit d'une expression d'affectation), vous Vous devez utiliser des parenthèses des deux côtés de la déclaration de rendement :

<?php
$result = yield fn();   // 不合法的
$result = (yield fn()); // 合法的
Copier après la connexion

Ce comportement est uniquement dû aux limitations d'implémentation de PHP5. En PHP7, les parenthèses ne sont plus nécessaires. Par conséquent, les méthodes d'écriture suivantes sont également légales :

<?php
$result = yield;
$result = yield $v;
$result = yield $k => $v;
Copier après la connexion

Bien sûr, vous devez suivre les scénarios d'application du rendement.

Les crochets n'affectent pas le comportement

En PHP5,

<?php
($foo)[&#39;bar&#39;] = &#39;baz&#39;;
# PHP Parse error: Syntax error, unexpected &#39;[&#39; on line 1
Copier après la connexion

Mais en PHP7, les deux méthodes d'écriture signifient la même chose.

De même, si les paramètres de la fonction sont mis entre parenthèses, il y a un problème avec la vérification de type. Ce problème a également été résolu en PHP7 :

<?php
function func() {
    return [];
}

function byRef(array &$a) {
}

byRef((func()));
Copier après la connexion

Le code ci-dessus ne le sera pas. alert en PHP5 à moins d'utiliser byRef(func()) pour appeler, mais en PHP7, l'erreur suivante se produira, qu'il y ait ou non des parenthèses des deux côtés de func() :

PHP Strict standards:  Only variables should be passed by reference ...
Copier après la connexion

Modifications dans la liste()

list 关键字的行为改变了很多。list 给变量赋值的顺序(等号左右同时的顺序)以前是从右至左,现在是从左到右:

<?php
list($array[], $array[], $array[]) = [1, 2, 3];
var_dump($array);
// PHP5: $array = [3, 2, 1]
// PHP7: $array = [1, 2, 3]
# 注意这里的左右的顺序指的是等号左右同时的顺序,
# list($a, $b) = [1, 2] 这种使用中 $a == 1, $b == 2 是没有疑问的。
Copier après la connexion

产生上面变化的原因正是因为在 PHP5 的赋值过程中,3 会最先被填入数组,1 最后,但是现在顺序改变了。

同样的变化还有:

<?php
$a = [1, 2];
list($a, $b) = $a;
// PHP5: $a = 1, $b = 2
// PHP7: $a = 1, $b = null + "Undefined index 1"
Copier après la connexion

这是因为在以前的赋值过程中 $b 先得到 2,然后 $a 的值才变成1,但是现在 $a 先变成了 1,不再是数组,所以 $b 就成了null。

list 现在只会访问每个偏移量一次

<?php
list(list($a, $b)) = $array;
// PHP5:
$b = $array[0][1];
$a = $array[0][0];
// PHP7:
// 会产生一个中间变量,得到 $array[0] 的值
$_tmp = $array[0];
$a = $_tmp[0];
$b = $_tmp[1];
Copier après la connexion

空的 list 成员现在是全部禁止的,以前只是在某些情况下:

<?php
list() = $a;           // 不合法
list($b, list()) = $a; // 不合法
foreach ($a as list()) // 不合法 (PHP5 中也不合法)
Copier après la connexion

引用赋值的顺序

引用赋值的顺序在 PHP5 中是从右到左的,现在时从左到右:

<?php
$obj = new stdClass;
$obj->a = &$obj->b;
$obj->b = 1;
var_dump($obj);
// PHP5:
object(stdClass)#1 (2) {
 ["b"] => &int(1)
  ["a"] => &int(1)
}
// PHP7:
object(stdClass)#1 (2) {
 ["a"] => &int(1)
  ["b"] => &int(1)
}
Copier après la connexion

__clone 方法可以直接调用

现在可以直接使用 $obj->__clone() 的写法去调用 __clone 方法。 __clone 是之前唯一一个被禁止直接调用的魔术方法,之前你会得到一个这样的错误:

Fatal error:Cannot call __clone() method on objects -use &#39;clone $obj&#39; instead in...
Copier après la connexion

变量语法一致性

AST 也解决了一些语法一致性的问题,这些问题是在另外一个 RFC 中被提出的:https://wiki.php.net/rfc/uniform_variable_syntax.

在新的实现上,以前的一些语法表达的含义和现在有些不同,具体的可以参照下面的表格:

Changements apportés par larbre de syntaxe abstraite (AST) de PHP7

整体上还是以前的顺序是从右到左,现在从左到右,同时也遵循括号不影响行为的原则。这些复杂的变量写法是在实际开发中需要注意的。

相关推荐:《PHP教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:uckendo
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!