PpHd, voilà les messages clés de Kevin qui posent la problématique. Mon parseur marche, et le tien marche de la même manière. Et ceci, pour Kevin, n'est pas conforme :
Kevin Kofler (./100) :
C'est le problème avec le parsage LL(1), les opérations "associatives à gauche" (le plus courant) posent problème.
Kevin Kofler (./102) :
Normalement, + et - doivent avoir la même priorité!
Donc tu as 2 opérations de la même priorité:
x OP y OP z
On dit que l'opération ou la famille d'opérations (genre + et -) OP est associative à gauche si:
x OP y OP z = (x OP y) OP z
On dit que l'opération ou la famille d'opérations (genre + et -) OP est associative à droite si:
x OP y OP z = x OP (y OP z)
L'associativité à gauche ou à droite est une question de conventions, pas une propriété intrinsèque de l'opération, mais la convention courante est que {+,-} est associatif à gauche.
On dit que l'opération ou la famille d'opérations (genre + et -) OP est associative si:
(x OP y) OP z = x OP (y OP z)
(Là, c'est une propriété intrinsèque de l'opération.) On peut donc noter:
(x OP y) OP z = x OP (y OP z) = x OP y OP z
et par conséquent l'opération sera à la fois associative à gauche et associative à droite.
+ est associatif, mais - ne l'est pas, donc la famille {+,-} non plus! Donc si tu parses de manière associative à droite, le résultat ne correspondra pas aux conventions (associativité à gauche).
Le problème, c'est que si tu parses top-down de gauche à droite (LL), tu construis toujours des arbres associatifs à droite. Les arbres associatifs à gauche demandent une récursion (un appel récurrent) à gauche et ce n'est pas possible en parsage LL (tu tombes en une récurrence infinie). Il existe différentes bidouilles pour corriger ça, mais la méthode la plus propre est de parser en LR (bottom-up de gauche à droite). Mais pour ça, il faut construire une table, tu ne peux pas le faire avec un parseur écrit directement à la main.
Kevin Kofler (./104) :
3-2+1 = (3-2)+1. L'algorithme de Martial donne 3-(2+1), ce qui est totalement faux.
Kevin Kofler (./108) :
Thibaut, c'était du parsage par découpage, peut-être, ton truc? (C'est essentiellement du bottom-up, ça, et c'est la manière de laquelle je codais intuitivement le parsage avant d'avoir appris le parsing.) Ce que j'appelle "parsage par découpage", c'est: on veut découper "x+y-z", donc on recherche + et -, en partant de la droite parce que c'est associatif à gauche. Donc on coupe en "x+y" et "z". Le problème, c'est que ça coupe les chaînes en 2 à chaque découpage, donc soit tu copies, soit tu détruis l'original en remplaçant l'opération par des \0. Et tu traverses les chaînes plusieurs fois aussi, donc l'efficacité n'est pas top. Et en plus, tu dois bidouiller quand il y a autre chose que des opérateurs, genre des parenthèses, sinon tu feras des bêtises là aussi.
Cela dit, ce que fait Folco m'a l'air de ressembler à ça, donc dans ce cas c'est facile de corriger la priorité. (Il faut rechercher à partir de la droite quand on découpe pour un opérateur associatif à gauche.)
Qu'en penses-tu ? Notre manière de faire est fondamentalement fausse et il faut corriger ?