J'ai une grammaire simple. En fait, la grammaire que j'utilise est plus complexe, mais c'est le plus petit sous-ensemble qui illustre ma question.Produire des expressions à partir de cette grammaire avec la descente récursive
Expr ::= Value Suffix
| "(" Expr ")" Suffix
Suffix ::= "->" Expr
| "<-" Expr
| Expr
| epsilon
Value
identificateurs de matchs, des chaînes, des nombres, et cetera. La règle Suffix
est là pour éliminer la récursivité gauche. Cela correspond à des expressions telles que:
a -> b (c -> (d) (e))
C'est un graphique où a
va à la fois b
et le résultat de (c -> (d) (e))
et c
va d
et e
. J'essaie de produire un arbre de syntaxe abstraite pour ces expressions, mais je rencontre des difficultés car tous les opérateurs peuvent accepter n'importe quel nombre d'opérandes de chaque côté. Je préfère garder la logique de production de l'AST dans les méthodes d'analyse par descente récursives, car cela évite d'avoir à dupliquer la logique d'extraction d'une expression. Ma stratégie actuelle est la suivante:
Si un
Value
apparaît, pousser à la sortie.Si un
From
ouTo
apparaît:sortie un séparateur.
Obtenez le suivant
Expr
.Créez un noeud
Link
.Faites apparaître le premier ensemble d'opérandes à partir de la sortie dans le
Link
jusqu'à ce qu'un séparateur apparaisse.Effacez le séparateur découvert.
Pop le deuxième ensemble d'opérandes dans le
Link
jusqu'à un séparateur.Poussez le
Link
vers la sortie.
Si je lance ce à travers sans obéir les étapes 2.3 – 2.7, je reçois une liste des valeurs et des séparateurs.Pour l'expression citée plus haut, a -> b (c -> (d) (e))
, la sortie doit être:
A sep_1 B sep_2 C sep_3 D E
En appliquant la règle To
alors le rendement:
A sep_1 B sep_2 (link from C to {D, E})
Et ensuite:
(link from A to {B, (link from C to {D, E})})
La chose importante à noter est que sep_2
, crucial pour délimiter les opérandes gauche de la deuxième ->
, n'apparaît pas, de sorte que l'analyseur estime que l'expression a été écrit:
a -> (b c -> (d) (e))
Afin de résoudre avec ma stratégie actuelle, il me faudrait un moyen de produire un séparateur entre les expressions adjacentes, mais seulement si l'expression actuelle est une expression From
ou To
enfermé dans parenthèses. Si c'est possible, alors je ne le vois pas et la réponse devrait être simple. Cependant, s'il y a une meilleure façon de procéder, n'hésitez pas à me le faire savoir!
Ah ah! Tu as raison. Je vais essayer d'ajouter une autre règle de production. En règle générale, je n'utilise pas la descente récursive parce que je n'aime pas refactoriser des grammaires complexes, c'est donc quelque chose d'une expérience d'apprentissage pour moi. –
Tous ensemble! Merci de votre aide. –