25Fermer27
Kevin KoflerLe 19/04/2009 à 00:34
Brunni (./22) :
Je vais peut être paraître un peu con mais j'ai beaucoup de peine à voir comment je pourrais caser la construction de mon arbre syntaxique pendant l'analyse syntaxique :/

Ton problème est exactement celui que j'ai écrit dans le ./20.
Brunni (./24) :
En fait vu que ma grammaire est LL(1), comme le dit Kevin c'est impossible de décrire des expressions "complexes" (avec des priorités et tout).

C'est possible de le décrire, mais tu dois le faire en spécifiant l'ordre d'associativité en dehors de la grammaire et il faut travailler plus pour construire ton arbre syntaxique (parce qu'effectivement l'arbre de parsage ne correspond pas).

Faut-il absolument que tu parses ça en LL(1)? Je sais bien que c'est le plus intuitif à coder parce qu'il y a la descente récursive (ce que tu fais), mais ce n'est pas très pratique pour construire les arbres syntaxiques corrects.

Ce que tu peux faire, c'est de, quand tu remontes dans ton algorithme par récurrence (donc quand tu as construit quelque chose), "retourner" ton arbre de parsage pour les opérations associatives à gauche (donc la plupart), bref, si tu as:
  -
 / \
A   -
   / \
  B   C

tu le changes en:
    -
   / \
  -   C
 / \
A   B

De même:
  -
 / \
A   -
   / \
  -   D
 / \
B   C

(qui a déjà subi la première transformation quand l'arbre a été construit pour la sous-expression) en:
      -
     / \
    -   D
   / \
  -   C
 / \
A   B

(Tu vois à l'aide de ces exemples qu'il faut retirer le 'A' de la racine et le rattacher au nœud tout en bas à gauche à la place.) Il faut juste faire attention à ne pas oublier les parenthèses dans tout ça.

Il y a certainement aussi d'autres moyens d'arriver au même résultat.

Zephyr (./25) :
J'aurais tendance à partir dans ce sens-là en tout cas. Plutôt que de se borner à respecter telle ou telle grammaire (LL(1) c'est quand même sacrément limitatif), profite du fait que tu écris ton parseur à la main et utilises les techniques qui te semblent les plus efficaces.

Je signale quand-même que les parseurs codés à la main sont presque toujours à descente récursive et donc en LL(1), on contourne les limitations en codant une construction de l'arbre syntaxique qui ne correspond pas à l'arbre de parsage. Le LR(1) ou LALR(1) est beaucoup moins évident à coder à la main, donc on passe par un générateur de tables de parsage (genre Yacc, Bison etc.).