Comment faire une indentation de type python avec flex / bison
je veux que ma langue ait deux caractéristiques qui font Python
un tel bien formaté langue:
- une déclaration par ligne
- les blocs commencent par un autre niveau d'indentation et continuent jusqu'à la fin
flex/bison
outils? Une telle fonctionnalité de bloc oblige l'utilisateur à écrire du code lisible.
3 réponses
je pense qu'il n'y a aucun moyen de faire un analyseur de syntaxe de type python avec seulement lex/yacc, parce que lex/yacc ne peut traiter que la grammaire libre du contexte, mais une syntaxe de type python est sensible au contexte.
La raison en est, si vous voulez savoir si un énoncé et le précédent est dans le même bloc, vous devriez laisser cette déclaration sait le retrait de la précédente, c'est le contexte.
je vous suggère de faire de la logique supplémentaire en plus de la lex/yacc à accomplir, et qui ne seront pas si difficile. Vous pourriez lire des codes ici, dans les modules "grammar".
la clé est de laisser lex / yacc part analyser une seule déclaration, avec un niveau d'indentation, et d'écrire quelque chose d'empaquetage des déclarations en blocs.
vous pouvez essayer de suivre le niveau d'indentation dans le lexer, et ajouter des pseudo-tokens pour indent et unindent. Vous aurez besoin de garder une pile de niveaux d'indentation déjà vu, et devez vous soucier des lignes vides/commentaire-seulement différemment. Mais je crains qu'à la fin, le lexer ne devienne un gâchis irréalisable et que vous ayez aussi un état spécifique à une parse (la pile d'indentation) dans votre lexer.
Matt Might a écrit un article sur standalone parsers, avec une façon de gérer les espaces blancs significatifs en utilisant "unput":
http://matt.might.net/articles/standalone-lexers-with-lex/
(l'exemple est au milieu de la page.)