Interpreter
Catégorie
Pattern comportemental
Problème
Étant donné un langage, définir une représentation de sa grammaire ainsi qu’un interpréteur qui utilise cette représentation pour interpréter des phrases du langage. Utile pour les grammaires simples ou les DSL.
Solution
- Définir la grammaire comme une hiérarchie de classes (chaque règle est une classe)
- Chaque classe implémente une méthode
interpret() - Construire un arbre de syntaxe abstraite représentant la phrase
- Appeler
interpret()sur le nœud racine pour évaluer la phrase
Structure
- AbstractExpression : Déclare une méthode
interpret() - TerminalExpression : Implémente
interpret()pour les règles de grammaire terminales - NonterminalExpression : Implémente
interpret()pour les règles non-terminales ; contient des expressions enfants - Context : Contient les informations globales nécessaires à l’interpréteur
- Client : Construit l’arbre de syntaxe abstraite représentant une phrase du langage
Avantages clés
- Facile de changer/étendre la grammaire — Les nouvelles règles sont de nouvelles classes
- Représentation claire de la grammaire — La grammaire est exprimée sous forme de classes
Compromis
- Performance — L’interprétation peut être lente par rapport au code compilé
- Évolutivité — La complexité de la grammaire croît de manière quadratique avec le nombre de règles
Quand l’utiliser
- La grammaire est suffisamment simple pour être implémentée manuellement
- La performance n’est pas un critère critique
- Vous avez besoin de représenter un langage sous forme de modèle d’objets
Exemples
- Les analyseurs de requêtes SQL interprètent la grammaire SQL
- Les moteurs de regex interprètent la grammaire des expressions régulières
- Python
etexec()` comme interpréteurs - Les analyseurs de fichiers de configuration (YAML, JSON, XML)
- Les langages spécifiques au domaine dans Ruby On Rails