Czy istnieje język programowania z wbudowaną konstrukcją maszyny stanowej?

Jestem po prostu ciekaw, czy istnieje język programowania, który ma Maszyny stanowe (podobne do boost:: statechart) jako podstawową konstrukcję języka.

Analogies-c# ma delegatów, gdzie java używa wzorca observer, A C ma wywołania zwrotne. Perl i python mają wbudowane hasze, podczas gdy C++ i java potrzebują biblioteki.

Update:

Powinien to być ogólny język programowania w sensie C++, C#, Java, Lisp ...

Mam na myśli "Dojrzałe" maszyny państwowe z wszystkimi na poziomie formalizmu Harela lub diagramów stanu UML lub boost:: statechart.

Author: Andreas Huber, 2009-11-25

12 answers

Ragel jest językiem maszynowym Stanów. IOW, to nie jest język, który również obsługuje maszyny stanowe, to język, który tylko obsługuje maszyny stanowe. Co oczywiście oznacza, że nie jest Turing-kompletny, ale kto tego potrzebuje?

Ragel jest kompilatorem maszyn stanowych, który pobiera Opis Maszyny stanowej w języku przypominającym regexp i generuje implementację tej maszyny stanowej w językach C, C++, Objective-C, D, Java lub Ruby. (Myśl yacc ale dla maszyn stanowych zamiast parserów LALR(1).) Podstawowym celem Ragela jest parsowanie protokołów binarnych (takich jak protokoły sieciowe czy też formaty plików na dysku), ale równie dobrze może być używany do tekstu.

Jednym ze znanych przykładów użycia Ragel jest serwer WWW Kundel dla Ruby: jego jądro HTTP jest napisane w Ragel, co czyni go niezwykle szybkim i bezpiecznym. Jądro HTTP jest tak dobre, że było wielokrotnie używane w różnych aplikacje: cienki, Jednorożec i tęcza są również webserverami, a w rzeczywistości kierują konkurentów do Kundla. Ebb jest odwrotnym proxy HTTP. RFuzz to narzędzie do testowania fuzz dla aplikacji internetowych. Również niektóre narzędzia zabezpieczające go używają.

Ragel pozwala również na osadzenie kodu w języku hosta w maszynie stanowej, dzięki czemu jest on kompletny i zdolny nie tylko rozpoznać , ale także zinterpretować protokoły.

Ogólnie rzecz biorąc, każdy język z obsługą dla do łatwego zaimplementowania maszyn stanowych można użyć zaawansowanego sterowania zdefiniowanego przez użytkownika-przepływ poprzez coroutiny (np. Lua) lub kontynuacje (np. Scala) lubGOTO (np. PHP) lub odpowiednie wywołania ogonowe (np. Scheme). (Generatory (Python) aka Iteratory (C#), które są w zasadzie "gównianymi koroutinami", mogą lub nie mogą działać, w zależności od twojej definicji"pracy".) I każdy język posiadający elastyczną składnię (np. Ruby) lub obsługujący abstrakcję metasyntaktyczną (np. Clojure) może być użyty do opisz maszyny państwowe. (Wsparcie dla identyfikatorów innych niż ASCII pomaga również, dzięki czemu można używać rzeczywistych strzałek dla maszyny stanowej.)

Co oznacza, że jeśli połączysz te dwa i użyjesz języka, który obsługuje zarówno wywołania ogonowe , jak i metasyntaktyczną abstrakcję, otrzymasz bardzo ładne maszyny stanowe, bez wymagającego obsługi języka ojczystego. W 2016 roku, w ramach projektu "the Swine before Perl", odbyła się premiera filmu "the Swine before Perl". Konferencji, na której zademonstrował implementację FSM w Scheme. (Oto slajdy, nagranie audio i papier wyjaśniający kod). Sam kod to makro 26-liniowe (w rzeczywistości bardzo krótkie linie), które pozwala na pisanie kodu w ten sposób:

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

Jest to specyfikacja maszyny stanowej odpowiadającej wyrażeniu regularnemu c(a|d)*r. I jest to nie tylko Specyfikacja, ale także uruchomiony program implementacja tej maszyny stanowej.

Mogę to tak nazwać:

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

I w tym przypadku uzyskaj wynik #t (który jest Scheme-speak dla true).

 39
Author: Jörg W Mittag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-25 07:23:23

Jest nowy język maszyn stanowych oparty na XML W3C o nazwie SCXML , oparty na formalizmie StateChart Davida Harela (który obsługuje hierarchiczne i równoległe maszyny stanowe).

Apache Commons ma implementację SCXML opartą na Javie:

Commons SCXML to implementacja mająca na celu stworzenie i utrzymanie Java scxml engine zdolnego do wykonywania maszyny stanowej zdefiniowanej za pomocą dokumentu SCXML, przy jednoczesnym wyodrębnieniu środowiska interfejsy.

 6
Author: Jim Ferrans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-24 23:47:28

SMC jest kompilatorem prostego języka specyficznego dla domeny, który generuje maszyny stanowe dla wielu popularnych języków. Używałem go do generowania utrzymywalnych maszyn stanowych dla wielu różnych rzeczy, takich jak złożone interfejsy użytkownika i niestandardowe protokoły sieciowe.

 4
Author: Todd Stout,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-11 23:54:36

OTP Erlanga wspiera konstrukcje maszyn stanowych poprzez 'gen_fsm'. Minęło kilka lat od ostatniego spojrzenia na to, więc jestem trochę zardzewiały, ale możesz wygooglować dla "Erlang gen_fsm" i znaleźć mnóstwo materiałów referencyjnych

 2
Author: monch1962,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-25 00:42:12

Nie do końca, ale istnieje moduł maszyny stanowej dla Pythona, który pozwala używać dekoratorów do obsługi implementacji kart stanu w stylu Harel, w tym kontekstów z wieloma stanami, zagnieżdżania podstat z historią i bez niej. Kod kończy się wyglądem jak poniżej. Moduł znajduje się w 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()
 2
Author: rldrenth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-15 19:15:39

Język programowania Plaid wprowadza " Programowanie Typestate-Oriented, paradygmat, który rozszerza programowanie obiektowe z typestates."

Oto doc: http://www.cs.cmu.edu / ~ aldrich /

Np:

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]
        { ... }
}
 2
Author: Olivier Henley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-20 09:12:32

Właśnie znalazłem jeden: AsmL (Abstract State Machine Language) .
Oto strona z Więcej informacji na jej temat w CodePlex.

Dość interesujące, jest rozwijany przez Microsoft.

 1
Author: Dmytrii Nagirniak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-24 22:59:57

W C# Iteratory (z 'Yield return' i 'Yield break') są konstrukcją języka, która bezpośrednio przekłada się na maszyny stanowe. Nigdy nie używałem go jako takiego, ale myślę, że może być użyteczny w praktyce.

Pojawia się pytanie o stackoverflow tutaj . Najwyżej głosowana odpowiedź zniechęca go jednak ...

 1
Author: Joren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:56
 1
Author: Daniel Voina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-13 12:06:56

Sriram Krishnamurthy ma raport i artykuł na temat używania makr do dodawania wbudowanego podjęzyka dla automatów do schematu. Nie jestem jednak pewien, czy jakieś Schematy zawierają jego makra jako standardową bibliotekę.

 1
Author: Ryan Culpepper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-26 03:45:33

Microsoft Research opublikował niedawno język P na Githubie. Mają również Framework PSharp, który zapewnia bibliotekę rozszerzeń C# i składnię wysokiego poziomu z kompilatorem dla języka.

Nie mogę się doczekać, żeby to wypróbować.

Oto fragment z jednego z ich przykładów dla rozszerzeń C#:

internal class Server : Machine
{
    MachineId Client;

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

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

    ...

Oto część składni wysokiego poziomu:

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;
    }

  ...
 1
Author: Fares,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-28 04:07:55

Jestem prawie dekadę spóźniony na imprezę, ale ostatnio natknąłem się na niejasny język, który zapożycza pomysły z FSMs o nazwie Hume

Nie jestem pewien, czy jest nadal aktywnie utrzymywany, ale możesz przynajmniej pobrać kompilator i pobawić się nim. Informacje są trudne do zdobycia, ale jest kilka gazet i artykułów online, które pokazują najważniejsze.

 0
Author: tiansivive,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-17 16:59:09