Comment dois-je implémenter une application de traitement de commandes?

9

Je veux créer une application simple de preuve de concept (REPL) qui prend un nombre et traite ensuite les commandes sur ce nombre.

Exemple: je commence par 1. Ensuite j'écris " add 2", ça me donne 3. Puis j'écris " multiply 7", ça me donne 21. Ensuite je veux savoir si c'est premier, alors j'écris " is prime" (sur le nombre courant - 21), cela me donne de faux. " is odd" me donnerait raison. Etc.

Maintenant, pour une application simple avec peu de commandes, même une simple switchsuffirait pour le traitement des commandes. Mais si je veux une extensibilité, comment aurais-je besoin d'implémenter la fonctionnalité? Dois-je utiliser le modèle de commande? Dois-je créer un analyseur / interprète simple pour la langue? Et si je veux des commandes plus complexes, comme " multiply 5 until >200"? Quel serait un moyen simple de l'étendre (ajouter de nouvelles commandes) sans recompiler?

Edit: pour clarifier certaines choses, mon objectif final ne serait pas de faire quelque chose de similaire à WolframAlpha, mais plutôt un processeur de liste (de nombres). Mais je veux commencer lentement au début (sur des numéros simples).

Je pense à quelque chose de similaire à la façon dont on utiliserait Haskell pour traiter les listes, mais une version très simple. Je me demande si quelque chose comme le modèle de commande (ou équivalent) suffirait, ou si je dois créer un nouveau mini-langage et un analyseur pour qu'il atteigne mes objectifs?

Edit2: Merci pour toutes les réponses, toutes m'ont été très utiles, mais celles d'Emmad Kareem m'ont le plus aidé, alors je vais le choisir comme réponse. Merci encore!

Nini Michaels
la source
2
Je ne reçois pas les downvotes. Veuillez indiquer votre raison afin que je puisse mieux formuler ma question la prochaine fois.
Nini Michaels
2
J'aime vraiment cette question. Au plaisir de voir ce que les gens proposent. Recherchez-vous spécifiquement une conception orientée objet (vous mentionnez le modèle de commande, qui est un modèle OO)?
Bjarke Freund-Hansen
merci :) oui, je préférerais la POO, mais cela ne me dérangera pas si d'autres méthodes sont suggérées!
Nini Michaels
2
Cela semble être une implémentation de la notation polonaise inversée , un sujet de programmation très cool!
Alberto De Caro
2
Vous ne respectez probablement pas la clause du livre de Quel genre de questions ne devrais-je pas poser ici? dans la FAQ, c'est-à-dire si vous pouvez imaginer un livre entier qui répond à votre question, vous en demandez trop .
Mark Booth

Réponses:

5

Cela ressemble à un interprète. Il semble que vous vous inquiétiez plus de l'implémentation que des fonctionnalités détaillées (je ne fais que deviner ici). Ce projet, s'il est étendu, n'est pas une tâche triviale. Assurez-vous d'étudier clairement la portée car cela nécessite une approche d'ingénierie et non une approche de développement ad hoc pour obtenir un produit fiable plutôt qu'un produit avec 1000 correctifs qui ne fonctionne parfois que.

Décidez d'une syntaxe et soyez prêt à l'analyser et à effectuer les vérifications de syntaxe nécessaires. Ce lien peut vous aider avec ceci: Créez votre propre analyseur .

Jetez un œil à: ce sujet car il touche à différents aspects du travail, il existe également de bons liens qui peuvent vous aider (en particulier la réponse de RMK).: Création d'un interprète de langue . Vous voudrez peut-être voir un exemple d'un beau projet qui est quelque peu similaire à: Ultimate Programmable Scientific Calculator . Vous pouvez trouver le code source et le programme de travail d'un interpréteur C # en ligne de commande ici Command-Line-Implementation-of-C # -Made-for-Teaching . Utiliser le compilateur pour effectuer les tâches complexes pour vous comme l'analyse et le typage de variables, etc. peut être un moyen intelligent d'échapper à la complexité de l'écriture de tout cela vous-même. En outre, il existe l'option Mono qui fournit une fonctionnalité de shell charp que vous voudrez peut-être consulter: CsharpRepl .

Aucune chance
la source
Merci, vos liens sont vraiment utiles! Je suppose donc qu'un interprète serait le meilleur choix si je veux l'étendre facilement.
Nini Michaels du
Merci pour vos commentaires, je suppose que commencer par le lien vers CodeProject peut être une bonne idée.
NoChance
2

À moins que vous ne soyez spécifiquement intéressé par l'écriture de l'analyseur réel pour vous-même, je vous suggère de jeter un œil à l'un des cadres du générateur d'analyseur. Pour C, vous avez YACC ou Bison , mais il devrait y avoir d'autres alternatives pour d'autres langues si vous préférez.

Cela élimine la complexité de l'analyse syntaxique de grammaires complexes et vous permet de vous concentrer sur la tâche que vous souhaitez effectuer. Bien sûr, cela peut être exagéré pour la grammaire que vous suggérez dans la question, mais puisque vous mentionnez avoir la possibilité d'étendre à une grammaire plus complexe plus tard, cela vaut au moins la peine de s'inspirer de ces cadres.

harald
la source
1
Le problème avec la plupart des générateurs d'analyseurs est que leurs artefacts sont statiques et ne se prêtent pas facilement à l'extension. Je pense que OP serait mieux servi avec quelque chose de plus comme un moteur de règles, où les "règles" (mots-clés et syntaxe) sont stockées dans une structure de données flexible et évaluées après chaque entrée.
TMN
2

Ce que vous décrivez est très proche d'un langage de pile .

Par exemple, dans Factor, ce que vous décrivez se ferait comme

1
2 +
7 *
even? not

Ou vous pouvez définir vos propres mots, puis les utiliser, comme

: add ( x y -- sum ) + ;
: multiply ( x y -- product ) * ;
: odd? ( n -- ? ) even? not ;

Avec ces définitions, l'exemple ci-dessus devient

1
2 add
7 multiply
odd?

Habituellement, les langues de pile sont triviales à analyser car elles utilisent des mots uniques séparés par des espaces. Je vous suggère de jeter un œil à Factor - il peut être exactement ce que vous voulez. Il devrait être facile de définir les mots qui font le traitement dont vous avez besoin.

EDIT : Si vous voulez réellement concevoir un langage similaire, je vous suggère de jouer avec l'un d'eux de toute façon. L'analyse d'un langage de pile est triviale - vous vous divisez sur des espaces vides et une implémentation naïve du traitement est facile: il vous suffit de prendre soin de ce qui se passe sur une pile.

Andrea
la source
Cela semble assez facile et c'est un bon point de départ. Merci!
Nini Michaels
1

Mais si je veux une extensibilité, comment aurais-je besoin d'implémenter la fonctionnalité?

Tu ne devrais pas. L'extensibilité crée beaucoup de complexité pour très peu de gain. Cela dit, vous devrez fournir un raccordement à l'état existant. Une façon de voir l'état, de modifier l'état et de fournir un mécanisme pour renvoyer d'autres résultats (imprimer à l'écran). Vous aurez besoin d'un moyen pour le code principal de découvrir les modules, de les charger et de leur envoyer des commandes.

Dois-je utiliser le modèle de commande?

Vous pouvez, mais ce n'est probablement pas approprié.

Vous n'allez pas prendre l'intégralité de l'entrée et l'envoyer pour traitement, mais analysez plutôt l'entrée, envoyez-la au gestionnaire approprié et laissez-la faire son travail. La commande ne varie pas dans cette communication; donc pas de modèle de commande.

Dois-je créer un analyseur / interprète simple pour la langue?

Vous aurez besoin de quelque chose pour gérer la décomposition de l'entrée en jetons. Pour une solution extensible, vous n'en ferez probablement pas beaucoup plus. Pour une solution bien définie, disposer d'un arbre d'analyse complet offrira de meilleures performances, une meilleure gestion des erreurs et une capacité de débogage.

mais plutôt un processeur de liste (de nombres)

Ensuite, vous devriez peut-être vous pencher sur le langage de traitement LISt . La juxtaposition de code et de données devrait correspondre à ce que vous décrivez.

Telastyn
la source
Merci pour les suggestions. Quant au LISP, je le connais, et encore plus familier avec Haskell, qui m'a inspiré cette idée. Cependant, même si je réinvente un peu la roue, je veux me salir les mains avec le traitement des commandes et leur interprétation. Donc, il a également un but éducatif en plus du "traitement de liste" :)
Nini Michaels
@NiniMichaels certes, mais en ce qui concerne la conception d'extensibilité, utiliser l'organisation / l'enchaînement de code / données de lisp n'est pas une mauvaise option.
Telastyn