Question

Je suis juste curieux de savoir s'il y a un langage de programmation qui a des machines d'état (similaires à boost ::) en tant que construction d'états-transitions de la langue principale.

Analogies - c # a des délégués où java utilise le modèle d'observateur et C a callbacks. Perl et Python ont intégré hash en C ++ et java a besoin d'une bibliothèque.

Mise à jour:

Cela devrait être le langage de programmation générale dans le sens de C ++, C #, Java, Lisp ...

Je veux dire des machines d'état « matures » avec toutes les cloches et de sifflets au niveau du formalisme Harel ou des diagrammes d'état UML ou boost :: statechart.

Était-ce utile?

La solution

Ragel est un langage de machine d'état. OIEau, ce n'est pas une langue que aussi prend en charge les machines d'état, il est une langue que uniquement prend en charge les machines d'état. Ce qui signifie évidemment que ce n'est pas Turing-complet, mais qui a besoin de cela?

Plus précisément, Ragel est un compilateur machine d'état, qui prend une description d'une machine d'état dans une langue comme expression rationnelle et génère une mise en œuvre de cette machine d'état en C, C ++, Objective-C, D, Java ou Ruby. (Pensez yacc mais pour machines d'état au lieu de LALR (1) parseurs de table.) L'objectif principal de Ragel est l'analyse des protocoles binaires (tels que les réseaux de protocoles ou également les formats de fichiers sur le disque), mais il peut tout aussi bien être utilisé pour le texte .

Un exemple célèbre d'utiliser Ragel est le serveur web Mongrel pour Ruby: son noyau HTTP est écrit dans Ragel, ce qui en fait très rapide et sécurisé. Le noyau HTTP est si bon, en fait, qu'il a été réutilisé plusieurs fois dans différentes applications: mince, Unicorn et Rainbows sont également Webservers, et en fait des concurrents directs à Mongrel. Ebb est un proxy inverse HTTP. RFuzz est un outil de fuzzing pour les applications web. En outre, certains outils de sécurité utilisent.

Ragel permet également code d'intégration dans la langue hôte dans la machine d'état, ce qui rend Turing-complet, et capable non seulement reconnaissent mais aussi interpréter protocoles.

En général, tous langue avec le soutien pour le contrôle de flux défini par l'utilisateur avancé soit par coroutines (par exemple Lua) ou continuations (par exemple Scala) ou GOTO (par exemple PHP) ou des appels de queue appropriés (par exemple Scheme) peut être utilisé facilement outil machines d'état. (générateurs (Python) aka itérateurs (C #), qui sont essentiellement « merdiques coroutines » pourraient ou pourraient ne pas fonctionner, selon votre définition de « travail ».) Et toute langue qui a une syntaxe flexible (par exemple, Ruby) ou prend en charge l'abstraction metasyntactic ( par exemple Clojure) peut être utilisé pour décrire machines d'état. (Prise en charge des identificateurs non-ASCII aide, aussi, de sorte que vous pouvez utiliser les flèches réelles pour votre machine d'état.)

Ce qui signifie que si vous combiner les deux, et utiliser une langue qui prend en charge à la fois appels arrière et abstraction metasyntactic, vous obtenez très agréable machines d'état, sans nécessitant un soutien de la langue maternelle. Shriram Krishnamurthi a un moment (dans) célèbre discours intitulé « Le porc avant Perl » à la conférence inaugurale Langues légère, dans laquelle il a fait preuve d'une mise en œuvre EFM dans le schéma. (Voici les diapositives rel="noreferrer"> , un enregistrement audio et papier expliquant le code ). Le code lui-même est une ligne 26 (lignes très courtes, en fait) macro, qui vous permet d'écrire du code comme ceci:

(define my-regex
  (automaton init
             [init : (c → more)]
             [more : (a → more)
                     (d → more)
                     (r → end)]
             [end : accept]))

Ceci est une spécification de la machine d'état correspondant à la c(a|d)*r d'expression régulière. Et il est non seulement une spécification, mais aussi un programme runnable la mise en œuvre que la machine d'état.

Je peux l'appeler comme ceci:

(my-regex '(c a d a d d r))

Et dans ce cas obtenir le résultat #t (ce qui est le schéma-parole pour true).

Autres conseils

Il y a un nouveau langage machine d'état XML du W3C appelé SCXML , basé sur David Harel de formalisme de Statechart (qui prend en charge des machines à états hiérarchiques et parallèles).

Apache Commons a une implémentation Java de base SCXML :

  

communes SCXML est une mise en œuvre visant à créer et à maintenir un moteur Java SCXML capable d'exécuter une machine d'état défini à l'aide d'un document de SCXML, tandis que les interfaces abstraire de l'environnement.

SMC est un compilateur pour un simple domaine un langage spécifique qui va générer des machines d'état pour de nombreuses langues populaires. Je l'ai utilisé pour générer des machines d'état maintenable pour une grande variété de choses telles que les interfaces utilisateurs complexes et des protocoles de réseau personnalisés.

La programmation Plaid Language introduction « programmation orientée Typestate, un paradigme qui étend la programmation orientée objet avec typestates. »

Voici le doc: http://www.cs.cmu.edu/~ aldrich / carreaux /

par exemple:

state File {
    public final String filename;
}

state OpenFile extends File {
    private CFilePtr filePtr;
    public int read() { ... }
    public void close() [OpenFile>>ClosedFile]
        { ... }
}

state ClosedFile extends File {
    public void open() [ClosedFile>>OpenFile]
        { ... }
}

Je viens de trouver un: Asml (Résumé État Machine Language) .
Voici la avec plus d'infos sur elle à CodePlex.

Assez intéressant, il est développé par Microsoft.

OTP d'Erlang prend en charge des constructions de machine d'état par l'intermédiaire de 'gen_fsm. Cela fait deux ans que je l'ai regardé, donc je suis un peu rouillé, mais vous pouvez Google pour « Erlang gen_fsm » et trouver des charges de matériel de référence

Pas tout à fait, mais il y a un module de machine d'état pour Python qui vous permet d'utiliser les décorateurs pour soutenir la mise en œuvre statecharts de style Harel, y compris avec des contextes multiples états, et avec imbrication sous-états sans histoire. Le code serpente à chercher quelque chose comme ci-dessous. Le module est à http://wiki.python.org/moin/State%20Machine% 20via% 20Decorators

 #!/bin/env/python
"""
This example now works. The state pattern module
allows defining states which are their their own context for 
implementing substates.  Substate Medium (class Medium) shows this here.
"""
"""
Example with 5 buttons. Two ,'up','down' cause state to rotate among the
several states.  The other three, bx,by,bz, invoke state dependent behavior.

Switching into a state causes the labels of the three buttons bx,by,bz to
change.  Pressing one of the buttons causes associated text to appear in
corresponding static text box. An 'onEnter' method changes the text.
"""
import wx
import DecoratorStateMachine as dsm

class MyFrame(wx.Frame, dsm.ContextBase):

   xtable = dsm.TransitionTable('pstate')


   def __init__(self):
      MyFrame.xtable.initialize(self)

      wx.Frame.__init__(self, None, -1, "My Frame", size=(470,220))

      family = wx.SWISS
      style = wx.NORMAL
      weight = wx.BOLD
      font = wx.Font(11,family,style,weight, False, "Verdana")
      self.SetFont(font)

      panel = wx.Panel(self, -1)

      b = wx.Button(panel, -1, "Up", pos=(50,20), size=(80,35))
      self.Bind(wx.EVT_BUTTON, self.OnUp, b)
      b.SetDefault()

      b = wx.Button(panel, -1, "Down", pos=(50,60), size=(80,35))
      self.Bind(wx.EVT_BUTTON, self.OnDown, b)

      self.bx = wx.Button(panel, -1, "xxx", pos=(50,100), size=(110,35))
      self.Bind(wx.EVT_BUTTON, self.OnBA, self.bx)
      self.tx = wx.StaticText(panel, -1, "", pos=(50,140), size=(110,35))

      self.by = wx.Button(panel, -1, "yyy", pos=(180,100), size=(110,35))
      self.Bind(wx.EVT_BUTTON, self.OnBB, self.by)
      self.ty = wx.StaticText(panel, -1, "", pos=(180,140), size=(110,35))

      self.bz = wx.Button(panel, -1, "zzz", pos=(310,100), size=(110,35))
      self.Bind(wx.EVT_BUTTON, self.OnBC, self.bz )
      self.tz = wx.StaticText(panel, -1, "", pos=(310,140), size=(110,35))


   @dsm.transition(xtable)
   def OnUp(self, event):
      pass

   @dsm.transition(xtable)
   def OnDown(self, event):
      pass

   @dsm.event(xtable)
   def OnBA(self, event):
      pass

   @dsm.event(xtable)
   def OnBB(self, event):
      pass

   @dsm.event(xtable)
   def OnBC(self, event):
      self.tz.SetLabel("Bossy")


class Off(MyFrame):
   "This is state Off "

   def onEnter(self):
      self.bx.SetLabel("Chase")
      self.by.SetLabel("Onry")
      self.bz.SetLabel("Cow")

   def OnBA(self, event):
      self.tx.SetLabel("Chase the")

   def OnBB(self, event):
      self.ty.SetLabel("Onry")


class Low(MyFrame):
   "This is state Low "
   items = ["Walk", "Green", "Llama"]

    def onEnter(self):
      self.bx.SetLabel(self.items[0])
      self.by.SetLabel(self.items[1])
      self.bz.SetLabel(self.items[2])

   def OnBA(self, event):
      self.tx.SetLabel("Walk the ")

   def OnBB(self, event):
      self.ty.SetLabel(self.items[1])

   def OnBC(self, event):
      self.tz.SetLabel(self.items[2])


class Medium(MyFrame):
   "This is state Medium "
   ytable = dsm.TransitionTable('qstate')

   def onEnter(self):
      if not hasattr(self, 'qstate'):    #unconditionally initialize for no history
         self.ytable.initialize(self)
      self.doEnter()

   @dsm.event(ytable)
   def doEnter(): pass

   @dsm.transitionevent(ytable)
   def OnBA(self, event):
      pass

   @dsm.transitionevent(ytable)
   def OnBB(self, event):
      pass

   @dsm.transitionevent(ytable)
   def OnBC(self, event):
      pass


class High(Low):
   "This is state High "

   items = ["Pet","Tame", "Dog"]

   def OnBA(self, event):
      self.tx.SetLabel("Pet his")

class MedBlue(Medium):
   """State med blu"""

   items = ["Med BLue","Checkered", "Tractor"]

   def onEnter(self):
      self.bx.SetLabel(self.items[0])
      self.by.SetLabel(self.items[1])
      self.bz.SetLabel(self.items[2])

   def doEnter(self):
      self.onEnter()

   def OnBA(self, event):
      self.tx.SetLabel("Med Blue")
   def OnBB(self, event):
      self.ty.SetLabel("Chekered")
   def OnBC(self, event):
      self.tz.SetLabel("Tractor")


class MedRed(Medium):
   """State med red"""

   items = ["Med Red","Striped", "Combine"]

   def onEnter(self):
      self.bx.SetLabel(self.items[0])
      self.by.SetLabel(self.items[1])
      self.bz.SetLabel(self.items[2])

   def doEnter(self):
      self.onEnter()

   def OnBA(self, event):
      self.tx.SetLabel("Med Red")
   def OnBB(self, event):
      self.ty.SetLabel("Striped")
   def OnBC(self, event):
      self.tz.SetLabel("Combine")


MyFrame.xtable.nextStates(Low, (Medium,Off))
MyFrame.xtable.nextStates(Medium, (High,Low))
MyFrame.xtable.nextStates(High, (Off,Medium))
MyFrame.xtable.nextStates(Off, (Low,High))
MyFrame.xtable.initialstate = Off

Medium.ytable.nextStates(MedBlue, (MedBlue, MedRed, MedRed))
Medium.ytable.nextStates(MedRed,  (MedBlue, MedBlue, MedRed))
Medium.ytable.initialstate = MedBlue


if __name__=='__main__':
   app = wx.PySimpleApp()
   frame = MyFrame()
   frame.Show(True)
   app.MainLoop()

En C #, itérateurs (avec « retour de rendement » et « rupture de rendement ») sont une construction linguistique qui se traduit directement par des machines d'état. Je ne l'ai pas fait jamais utilisé comme tel, mais je pense que cela pourrait être utile dans la pratique.

Il arrive à une question stackoverflow à ce sujet ici . La réponse le plus voté décourage si ...

En dehors de Ragel il y a une langue intéressante sur le plan technique, mais tout à fait obscure appelée SL1. Voir http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber= 1095580 . Il a été créé par Iskratel en Slovénie afin de développer des systèmes de télécommunications où les machines d'état sont les blocs de base.

Shriram Krishnamurthi a un entretien et un article sur en utilisant des macros pour ajouter un sous-langage intégré pour les automates au schéma . Je ne sais pas si des systèmes comprennent ses macros comme bibliothèque standard, cependant.

Microsoft Research a récemment publié le P langue sur GitHub. Ils ont aussi le cadre PSharp qui fournit une bibliothèque d'extension C # et une syntaxe de haut niveau avec le compilateur pour le langage.

Je suis impatient de l'essayer.

Voici une partie d'un de leurs exemples pour les extensions C #:

internal class Server : Machine
{
    MachineId Client;

    [Start]
    [OnEntry(nameof(InitOnEntry))]
    class Init : MachineState { }

    void InitOnEntry()
    {
        ...
        this.Goto(typeof(Active));
    }

    ...

Voici une partie de leur syntaxe de haut niveau:

using System;

namespace TheStateMachine
{
  internal machine Client
  {
    private machine Server;
    private start state Init
    {
      entry
      {
        this.Server = (trigger as Config).target;
        jump(Playing);
      }
    }

    private state Playing
    {
      entry
      {
        //execute logic
      }
      on AnotherEvent goto AnotherState;
      on SomeEvent do ProcessSomeLogic;
    }

  ...

Je suis près d'une décennie en retard à la fête, mais je suis tombé sur récemment une langue obscure qui emprunte des idées de FSMs appelées Hume

Je ne sais pas si elle est toujours maintenu activement, mais vous pouvez au moins télécharger le compilateur et jouer avec elle. L'information est difficile à trouver, mais il y a quelques papiers et articles en ligne qui montrent l'essentiel.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top