
TSI – Informatique Commune Année scolaire 2026/2027
Expressions correctes. Une liste de lexèmes peut ne pas représenter une expression correcte :
par exemple 3 + 4 (un opérateur manque d’opérandes) ou 3 4 5 + (il reste deux valeurs dans la
pile). On note hkla hauteur qu’aurait la pile après la lecture des kpremiers lexèmes, avec h0= 0 :
• si le k-ième lexème est un nombre ou la variable x, alors hk=hk−1+ 1 ;
• si c’est un opérateur, alors hk=hk−1−1(il dépile deux valeurs et en empile une).
On admet qu’une liste de Llexèmes est une expression postxée correcte si et seulement si hk≥1
pour tout k∈J1, LKet hL= 1.
□Q3 – Écrire une fonction est_correcte(lex:list)->bool qui teste cette condition sans
construire de pile, en un seul parcours de lex. Par exemple, est_correcte("3 + 4".split())
et est_correcte("3 4 5 +".split()) renvoient False, et est_correcte("2 3 + 7 4 -
*".split()) renvoie True.
□Q4 – Écrire une fonction taille_pile_max(lex:list)->int qui renvoie la plus grande des
hauteurs h1, . . . , hL, c’est-à-dire le nombre maximal de valeurs présentes simultanément dans la pile
lors de l’évaluation de l’expression correcte lex. Par exemple, taille_pile_max("5 1 2 + 4 * +
3 -".split()) renvoie 3.
Les expressions 1234+++et 12+3+4+représentent la même somme. Dessiner leurs
deux arbres, puis donner la valeur de taille_pile_max pour chacune. Laquelle des deux écritures
est préférable lorsque la pile est de taille limitée, comme sur une calculatrice ?
Construction de l’arbre. On remplace maintenant la pile de valeurs par une pile d’arbres : un
nombre ou la variable xdonne une feuille que l’on empile ; un opérateur dépile deux arbres dpuis
get empile l’arbre [op, g, d].
□Q5 – Écrire une fonction construire_arbre(lex:list) qui renvoie l’arbre syntaxique de
l’expression postxée (correcte) lex, qui peut contenir la variable x. Par exemple :
construire_arbre(['3', '4', '+', '2', '*']) renvoie
['*', ['+', [3, [], []], [4, [], []]], [2, [], []]]
2 Algorithmes récursifs sur l’arbre syntaxique
□Q6 – Écrire une fonction récursive evaluer(a, x:float)->float qui renvoie la valeur
de l’expression représentée par l’arbre alorsque la variable vaut x. Par exemple, si a =
construire_arbre("x x * 2 -".split()), alors evaluer(a, 3) renvoie 7. Justier que sa
complexité est linéaire en le nombre Nde nœuds de l’arbre.
□Q7 – Écrire une fonction récursive postfixe(a)->list qui renvoie la liste des lexèmes de
l’expression postxée représentée par l’arbre a(les constantes sont converties en chaînes avec str).
Sur l’arbre E1, elle renvoie ['5', '1', '2', '+', '4', '*', '+', '3', '-']. À quel parcours
de l’arbre correspond-elle ?
□Q8 – Écrire une fonction récursive infixe(a)->str qui renvoie l’écriture usuelle de l’expression,
chaque opération étant entourée de parenthèses. Sur l’arbre E1, elle renvoie '((5+((1+2)*4))-3)'.
Simplication. Les expressions produites automatiquement (en particulier par la dérivation)
contiennent souvent des calculs inutiles. On les simplie de bas en haut : on simplie d’abord les
deux sous-arbres d’un opérateur, puis on applique au nœud obtenu la première règle applicable
parmi les suivantes (edésigne une expression quelconque) :
R1 les deux opérandes sont des constantes c1et c2on remplace par la constante c1op c2
R2 e+ 0,0 + e,e−0,e×1,1×eon remplace par e
R3 e×0,0×eon remplace par la constante 0
© LEM6 - CASABLANCA 3Y.Kharbane