Je joue avec l'écriture d'une aventure de boue / texte (s'il vous plaît ne riez pas) à Ruby. Quelqu'un peut-il me donner des pointeurs vers une solution élégante et basée sur OOP pour analyser le texte d'entrée? p>
Nous ne parlons de rien de plus complexe que "Mettre la baguette sur la table", ici. Mais tout doit être doux; Je veux prolonger la commande définie sans douleur, plus tard. p>
Mes pensées actuelles, légèrement simplifiées: p>
Chaque classe d'articles (boîte, table, pièce, joueur) sait reconnaître une commande qui "appartient". p> li>
La classe de jeu comprend une sorte d'une langue spécifique à un domaine impliquant des actions telles que "Déplacer l'objet X Intérieur de l'objet Y", "Afficher la description de l'objet X", etc. P> Li>
La classe de jeu demande à chaque élément de la pièce s'il reconnaît la commande d'entrée. D'abord dire oui gagne. p> li>
Il transmet ensuite le contrôle à une méthode de la classe d'élément qui gère la commande. Cette méthode reformule la commande dans la DSL, le repasse à l'objet de jeu pour le faire se produire. P> LI> ol>
Il doit y avoir des moyens bien usés et élégants de faire ce genre de choses. Ne peut rien sembler google, cependant. P>
5 Réponses :
the modèle de conception interpréteur est le plus orienté objet em> Approche pour analyser que je suis au courant, mais je suis sûr que les experts du compilateur signalent des algorithmes plus puissants. P>
Je suis des ordures aux motifs de design et mon googling n'avait pas vu celui-ci. Je vais certainement regarder cela, ta.
En effet, le motif d'interprète ressemble à un arbre d'expression dans un processus de compilation! agréable. Cela semble être une implémentation de Straighforward pour un compilateur. (après l'analyse du jeton à cordes)
Je me lance toujours pour appliquer ce modèle à mon projet, mais cela ressemble plutôt à ce que c'était l'idée que je cultirait. Ce qu'il part non dit, c'est la manière dont la chaîne de commande est analysée.
diviser en jetons alors que le format sera toujours:
[Commande] [Object1] ([référence] [Objet2]) P>
Vous pouvez appeler la méthode [commande] sur [Object1] dans votre chambre et transmettre le [Objet2], le cas échéant. P>
C'est tellement très tentant. Mais "tourner dessus". Ou, dans ce domaine, il serait vraiment agréable de pouvoir accepter «tourner sur la lumière».
Vous pouvez le faire en supprimant simplement ce que l'on appelle généralement des mots «stops mots» de la chaîne. Mots comme "le", "an", "on". Dans ce cas, tout ce qui reste de la phrase ", allume maintenant cette lumière là" serait "tourner à feu". Bien sûr, cela pourrait être trop i> beaucoup, mais dans ce cas particulier, l'absence i> du mot "off" vous dit tout ce que vous devez savoir.
@Jorg: En fait, c'est à peu près ce que fait mon approche actuelle, sauf qu'il détecte "les mots de départ" à la place. Donc (pour simplifier quelque peu) la classe de lumière recherche /light.*(on|off )/. Peut-être que vous l'avez la bonne façon, et je ne le fais pas, cependant.
Le concept de "Mots d'arrêt" provient des moteurs de recherche, où ce sont des mots qui ne contribuent tout simplement rien d'utile. Donc, ils sont généralement filtrés à la fois de l'index et de la requête de recherche. Il faudra certainement être modifié ici. Vous pourriez jeter un coup d'œil à l'analyseur de date de la langue naturelle du système de contrôle de la version GIT. Il a l'air i> comme ça peut analyser des expressions très compliquées comme "environ une heure il y a", mais ce que cela fait vraiment, je jette simplement tout ce qu'il ne comprend pas, alors ça finit avec "heure" qui est simplement défini pour être 3600 code> et c'est tout. Fonctionne bien.
Pour les interprètes de commandement, je suis plutôt friand de ce simple modèle élégant. Les modèles de langues dynamiques ont tendance à impliquer moins de boîtes et de lignes que des motifs GOF.
class Thing # Handle a command by calling the method "cmd_" + command. # Raise BadCommand exception if there is no method for that command. def handle_command(command, args) method_name = "cmd_#{command}" raise BadCommand, command unless respond_to?(method_name) send(method_name, args) end def cmd_quit(args) # the code for command "quit" end def cmd_list(args) # the code for command "list" end ... end
Ceci regarde le premier squint comme un trois voies à trois voies entre visiteur, stratégie et commandement, mais comme vous l'avez dit: dans un langage expressif (je n'ai pas acheté la partie "dynamique" que i> beaucoup, ça serait Il est probablement assez élégant dans Scala, F # ou Haskell) Ce n'est tout simplement pas si gros problème. Rappelez-vous: un motif n'est qu'un programme que vous souhaitez écrire, mais votre langue ne vous laisse pas. Eh bien, Ruby fait i> vous laisse.
@Jorg, bien dit. Je creuse cette définition d'un motif. Est-ce à vous?
Je ne le pense pas. Ce libellé précis pourrait être le mien, mais l'idée est générale. En fait, si vous ouvrez votre copie du GOF à la page 4 et lisez le dernier paragraphe de la section 1.1, il est effectivement épelé là-bas. Le rant classique sur ceci est blog.plover.com/prog/design-patterns.html < / a> Avec cette réponse CincomsMallTalk.com/userblogs/alph/blogview?entry= 333580339 6 , puis ce blog.plover.com/prog/johnson.html < / a>. Et bien sûr, la célèbre présentation Norvig: norvig.com/design-Patterns
@JOG, c'est une cornucopie de grands liens. Merci!
OK. Donc, vous avez besoin d'une sémantique? (Turn est une action, allume un objet, sur un argument ... (je concerne votre commentaire à dbemerlin)). P>
Pourquoi ne pas définir une grammaire? Humm ... Je suppose que lex et yacc ne sont pas une option? (Comme il n'est pas du tout du tout, mais ce que vous voulez faire est de "compiler" la saisie de l'utilisateur pour produire quelque chose - exécuter un code qui modifie les données de la pièce et génère un résultat) p>
Vous pouvez avoir une conception OOP pour votre objet et son action (comme, tous les objets ont une méthode .Describe () ..), et à côté de cela, un peser d'entrée + compilateur. P>
Suis-je complètement hors du sujet? P>
Edit: Après avoir regardé le modèle d'interpréteur indiqué par Marc Semonan, il semble être le moyen d'aller dans vous le souhaitez dans OOP. (Mais vous allez quelque peu réinventer la roue) p>
J'ai regardé Lex et Yacc. Mais ils font mal à ma tête, et cela est censé être un projet amusant. De plus, si je comprends bien, ils m'attachent à une grammaire beaucoup plus stricte que la langue anglaise. Je suppose que ma cible d'or est que l'utilisateur soit capable de taper "sur la table Mettez la baguette" à être compris ... ou à tout le moins, essayez le jeu d'essayer de mettre la table sur la baguette;)
On dirait que vous avez besoin d'un analyseur. P>
diviser la chaîne d'entrée en jetons (mots). Nourrissez ensuite les jetons, un à la fois, à une machine à états. Je trouve que l'automate push-down est un moyen plutôt intuitif et puissant d'écrire une telle STM. P>
Toute suggestion sur la manière dont je commence à étudier le concept de machines d'état? L'entrée de Wikipedia est une donnée, bien sûr.
Je prends le commentaire Wikipedia. La page sur Pushdown Automata a l'air fascinante, mais elle est écrite en mathématiques élevées.
@Shadow: Stackoverflow.com/Questtions/1669/Learning- TO-Write-A-Compile R est la page canonique pour les ressources du compilateur. Mais vous avez besoin est spécialisé et peut ne pas être bien traité. Cette réponse est techniquement correcte, mais pas très utile car le traitement des langues naturelles est notoirement difficile et a sa propre culture et sa langue.
En tant que note de bas de page, le bit velu avec mon plan actuel met en œuvre des actions impliquant deux objets.
Vous pouvez commencer par Stackoverflow.com/questions/tagged/natural-language et voir où cela conduit.
Ta! Je viens d'ajouter cette balise à la question.
Ma première tick! :) Je vais regarder à la fois des machines d'état fini et du modèle d'interprète. Il me semble que ce dernier correspond plutôt à ma pensée actuelle. Mais le diable sera dans le détail, c'est-à-dire la analyse. Je suis parti avec des tonnes d'idées. Merci à tout le monde.