2008-12-10 8 views
9

Comment définiriez-vous vos règles d'analyseur et de lexeur pour analyser un langage qui utilise l'indentation pour définir la portée.Comment voulez-vous analyser l'indentation (style python)?

J'ai déjà googlé et trouvé une approche astucieuse pour l'analyser en générant des jetons INDENT et DEDENT dans la lexer.

Je vais aller plus loin sur ce problème et poster une réponse si je viens à quelque chose d'intéressant, mais je voudrais voir d'autres approches du problème.

EDIT: Comme Charlie l'a signalé, there is already another thread very similar if not the same. Mon message doit-il être supprimé?

Répondre

1

Vous pouvez également suivre quelque part dans lexer le nombre d'éléments d'identification qui sont précédés de la première ligne et les transmettre au parseur. La partie la plus intéressante serait d'essayer de la passer correctement à l'analyseur :) Si votre analyseur utilise lookahead (ici, je veux dire que l'analyseur peut interroger le nombre variable de jetons avant qu'il ne corresponde vraiment à un seul) être très mauvaise idée (parce que lexer peut glisser sur la ligne suivante et changer la valeur du compteur de retrait tandis que l'analyseur essaie toujours d'analyser la ligne précédente). De plus, les globals sont mauvais dans beaucoup d'autres cas;) Marquer le jeton «réel» de la première ligne d'une façon ou d'une autre avec un marqueur d'indentation est plus raisonnable. Je ne peux pas vous donner d'exemple exact (je ne sais même pas quels générateurs d'analyseur et de lexeurs allez-vous utiliser ...) mais quelque chose comme stocker des données sur des jetons de première ligne (ça pourrait être non confortable si vous le pouvez t obtenir facilement un tel jeton de l'analyseur) ou enregistrer des données personnalisées (carte qui lie les jetons à indent, tableau où chaque ligne du code source en tant qu'index et valeur de retrait en tant que valeur de l'élément) semble être suffisante. Un inconvénient de cette approche est la complexité supplémentaire de l'analyseur qui devra faire la distinction entre les valeurs ident et changer son comportement en fonction de cela. Quelque chose comme LOOKAHEAD ({yourConditionInJava}) pour JavaCC peut fonctionner ici mais c'est pas une très bonne idée. Beaucoup de jetons supplémentaires dans votre approche semble être moins mauvaise chose à utiliser :)

Comme une autre alternative, je suggère est de mélanger ces deux approches. Vous pouvez générer des jetons supplémentaires uniquement lorsque le compteur de retrait modifie sa valeur sur la ligne suivante. C'est comme un BEGIN artificiel et un jeton END. De cette façon, vous pouvez réduire le nombre de jetons 'artificiels' dans votre flux alimenté dans l'analyseur de lexer. Seul votre grammaire de l'analyseur doit être ajusté pour comprendre des jetons supplémentaires ...

Je ne l'ai pas essayé ce (ont aucune expérience réelle avec ces langues d'analyse syntaxique), le partage juste mes pensées sur les solutions possibles. La vérification des parseurs déjà construits pour ce genre de langues pourrait être d'une grande valeur pour vous. Open source est votre ami;)

10

C'est un peu hypothétique, car elle dépend de ce que la technologie que vous avez pour votre lexer et parser, mais la meilleure façon semble être d'avoir des jetons BEGINBLOCK et ENDBLOC analogues à bretelles en C. En utilisant le "offsides rule" votre lexer doit suivre une pile de niveaux d'indendtation. Lorsque le niveau d'indentation augmente, émettre un BEGINBLOCK pour l'analyseur; Lorsque le niveau d'indentation diminue, émettez ENDBLOCK et éloignez les niveaux de la pile.

Here's another discussion de ce sur le SO, btw.

Questions connexes