Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Exécuter directement un arbre syntaxique (interpréteur)

Après cette leçon: Je peux exécuter directement un arbre syntaxique.

Leçon de 50 min7 commandesLab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Une règle de prix tapée par la gérante

Un loueur de vélos laisse sa gérante taper une règle de prix, comme tarif * jours + caution, dans une page de réglages. La règle change chaque semaine.

Personne ne veut recompiler et relancer le site à chaque fois. Le site garde donc l’arbre syntaxique de la règle et le calcule, nœud par nœud, à chaque réservation.

À la fin de cette leçon

Remarque

Je peux exécuter directement un arbre syntaxique.

Mots-clés

MotCe que ça veut direExemple
Interpréteurun programme qui en exécute un autre sans produire de code machine
Nœudun point de l’arbreBinOp
Évaluercalculer la valeur d’un nœud
Feuilleun nœud sans rien en dessousConstant(value=8)
Environnementles noms accessibles et leurs valeurs{'prix': 4}
Liaisonun nom associé à sa valeur

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Python vous montre son arbre

Python est aussi un compilateur. Avant d’exécuter une ligne, il la découpe en jetons et en fait un arbre syntaxique. Le module ast affiche cet arbre pour une ligne reçue par un tube. --mode eval précise que la ligne est une seule expression.

Chaque nœud a un nom. Une feuille n’a rien en dessous. Comparez les trois arbres affichés.

L’arbre de 8 - 2 - 1

Commande
echo "8 - 2 - 1" | python3 -m ast --mode eval

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un arbre avec des noms

Commande
echo "remise * (prix - 3)" | python3 -m ast --mode eval

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un moins placé devant

Commande
echo "-solde" | python3 -m ast --mode eval

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Exemple travaillé : les nœuds affichés par Python

NœudCe que c’estSa valeur vient de
Constant(value=8)Une feuille qui contient un nombreLe nombre lui-même
Name(id='prix')Une feuille qui contient un nomLa recherche du nom
BinOp(left, op, right)Une opération à deux côtésLes deux côtés, puis l’opération
UnaryOp(op, operand)Une opération à un seul côtéCe côté, puis l’opération
Sub(), Mult(), USub()Quelle opérationRien : c’est une étiquette

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Les enfants d’abord, puis le nœud

Un interpréteur qui parcourt l’arbre est une fonction qui évalue un nœud. Une feuille qui contient un nombre rend ce nombre. Une opération évalue d’abord son enfant gauche et son enfant droit. Elle fait ensuite son propre calcul sur les deux réponses.

Comme un enfant peut être un arbre entier, la fonction s’appelle elle-même. La démo traite + et * sur des nombres.

Un évaluateur qui parcourt l’arbre

Code: python
# Évaluer un arbre : un nombre, ou [signe, gauche, droite].
def evaluer(arbre):
    if type(arbre) == int:
        return arbre
    signe = arbre[0]
    # On calcule d'abord les deux côtés : c'est la récursion.
    gauche = evaluer(arbre[1])
    droite = evaluer(arbre[2])
    if signe == "+":
        return gauche + droite
    if signe == "*":
        return gauche * droite
    return None


arbre = ["*", ["+", 2, 3], 4]
print(evaluer(arbre))
# Remplacez l'arbre par ["+", 2, ["*", 3, 4]], puis relancez.

Erreur fréquente

Attention

Beaucoup de gens pensent qu’un interpréteur traduit l’arbre en code machine en secret, puis le lance. Un interpréteur qui parcourt l’arbre ne le fait jamais. Il visite les nœuds et fait le travail en passant, de nouveau à chaque exécution. C’est pourquoi il est plus lent qu’un code compilé, et pourquoi il démarre tout de suite.

Les noms se cherchent dans un environnement

Une feuille qui contient un nom a besoin d’une valeur. L’interpréteur tient un environnement : chaque nom accessible, avec sa valeur. Chaque paire est une liaison.

La fonction eval de Python reçoit l’environnement sous forme de dictionnaire. Donnez-lui un second dictionnaire, et Python le fouille en premier. C’est ainsi qu’une portée intérieure cache un nom extérieur.

Évaluer avec un environnement

Commande
python3 -c "print(eval('prix * qte', {'prix': 4, 'qte': 5}))"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Oublier un nom

Commande
python3 -c "print(eval('prix * qte', {'prix': 4}))"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un environnement intérieur qui change qte

Commande
python3 -c "print(eval('prix * qte', {'prix': 4, 'qte': 5}, {'qte': 2}))"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un environnement intérieur qui change prix

Commande
python3 -c "print(eval('prix * qte', {'prix': 4, 'qte': 5}, {'prix': 10}))"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Exemple travaillé : chercher prix * qte

Runprix trouvé dansqte trouvé dansAffiché
Le premierLe seul dictionnaire : 4Le seul dictionnaire : 520
Le deuxièmeLe seul dictionnaire : 4Nulle partNameError
Le troisièmeL’extérieur : 4L’intérieur : 28
Le quatrièmeL’intérieur : 10L’extérieur : 550

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Pour aller plus loin

Ajoutez un nœud si à votre évaluateur : ["si", test, alors, sinon]. Évaluez le test. S’il ne vaut pas 0, évaluez alors, sinon évaluez sinon.

Vérifiez qu’une seule des deux branches est évaluée. Écrivez un test qui le prouve, avec une branche qui lèverait NameError si elle s’exécutait.

À propos de ce labo et de sa source: Lab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.