Domanda

Sono solo curioso di sapere se v'è un linguaggio di programmazione che ha macchine a stati (simili a boost :: Statechart) come costrutto lingua principale.

Le analogie - c # ha delegati in cui Java utilizza il modello osservatore e C ha callback. Perl e Python sono dotati di hash, mentre C ++ e Java ha bisogno di una biblioteca.

Aggiornamento:

Questo dovrebbe essere linguaggio di programmazione generale nel senso di C ++, C #, Java, Lisp ...

Voglio dire macchine a stati "maturi", con tutte le campane e fischi sul livello di Harel formalismo o diagrammi di stato UML o boost :: statechart.

È stato utile?

Soluzione

Ragel è un linguaggio macchina a stati. IOW, non è un linguaggio che anche supporta macchine a stati, è un linguaggio che solo supporta macchine a stati. Il che significa, ovviamente, che non è Turing-completo, ma chi ne ha bisogno?

Più precisamente, Ragel è una macchina compilatore stato, che richiede una descrizione di una macchina a stati in un linguaggio regexp simile e genera un'implementazione di tale macchina a stati in C, C ++, Objective-C, D, Java o Ruby. (Pensate yacc ma per macchine a stati, invece di LALR (1) parser di tabella.) Lo scopo primario di Ragel è l'analisi protocolli binari (come protocolli di rete o anche su disco formati di file), ma può benissimo essere utilizzato per il testo .

Un famoso esempio di utilizzo Ragel è il web server Mongrel per Ruby: il suo kernel HTTP è scritto in Ragel, il che lo rende molto veloce e sicuro. Il kernel HTTP è così buono, infatti, che è stato riutilizzato un certo numero di volte in diverse applicazioni: sottile, Unicorn e arcobaleni sono server web anche, e di fatto concorrenti scalo a Mongrel. Ebb è un proxy HTTP inverso. RFuzz è uno strumento di test fuzz per le applicazioni web. Inoltre, alcuni strumenti di sicurezza usano.

Ragel permette anche incorporare codice nella lingua del paese ospitante nella macchina dello stato, rendendo così Turing-completo, e in grado di non solo riconoscono ma anche interpretano protocolli.

In generale, ogni lingua con supporto per il controllo del flusso definito dall'utente advanced via sia coroutine (es Lua) o continuazioni (es Scala) o GOTO (es PHP) o chiamate coda appropriate (ad esempio Scheme) può essere utilizzato per facilmente attuare macchine a stati. (Generatori (Python) aka iteratori (C #), che sono fondamentalmente "coroutine schifose" potrebbe o non potrebbe funzionare, a seconda della definizione di "lavoro"). E qualsiasi linguaggio che ha la sintassi flessibile (ad esempio Ruby) o sostenga astrazione metasyntactic ( es Clojure) può essere usato per descrivere macchine a stati. (Supporto per gli identificatori non ASCII aiuta, anche, in modo che è possibile utilizzare le frecce effettivi per la vostra macchina a stati.)

Il che significa che se si combinare i due, e utilizzare un linguaggio che supporta sia chiamate di coda e astrazione metasyntactic, si ottiene molto bello macchine a stati, senza richiedere il supporto della lingua nativo. Shriram Krishnamurthi ha dato un ora (in) famoso discorso dal titolo "The Swine prima di Perl" al inaugurale Leggero Lingue Conferenza, in cui ha dimostrato un'implementazione FSM nello Schema. (Ecco la rel="noreferrer"> , un la registrazione audio e un carta che spiega il codice ). Il codice stesso è una macro 26 linea (linee molto brevi, in realtà), che permette di scrivere codice come questo:

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

Questa è una specifica macchina stato corrispondente al normale c(a|d)*r espressione. E non è solo una specifica, ma anche un programma eseguibile attuazione che macchina statale.

posso chiamare in questo modo:

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

E in questo caso ottenere il #t risultato (che è Scheme-parlare per true).

Altri suggerimenti

C'è un nuovo linguaggio macchina W3C basato su XML stato chiamato SCXML , sulla base di David Harel del Statechart formalismo (che supporta macchine a stati gerarchici e parallele).

Apache Commons ha un Java implementazione basata su SCXML :

  

scorta SCXML è un'implementazione volto a creare e mantenere un motore Java SCXML grado di eseguire una macchina a stati definiti utilizzando un documento SCXML, mentre astraendo le interfacce ambiente.

SMC è un compilatore per un semplice linguaggio specifico del dominio che genererà macchine a stati per molti linguaggi popolari. L'ho usato per generare macchine a stati mantenibili per una grande varietà di cose come le interfacce utente complesse e protocolli di rete personalizzate.

Il linguaggio di programmazione Plaid introdurre "Programmazione Typestate-oriented, un paradigma che si estende programmazione orientata agli oggetti con typestates."

Ecco il doc: http://www.cs.cmu.edu/~ Aldrich / plaid /

per esempio:

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]
        { ... }
}

Ho trovato una: ASML (Abstract State Machine Language) .
Ecco l' con più informazioni su di esso in CodePlex.

abbastanza interessante, si è sviluppato da Microsoft.

OTP di Erlang supporta statali costrutti macchina via 'gen_fsm'. E 'stato un paio di anni dall'ultima volta che ho guardato, quindi sono un po' arrugginito, ma si può Google per 'Erlang gen_fsm' e trovare un sacco di materiale di riferimento

Non proprio, ma v'è un modulo di macchina a stati per Python che consente di utilizzare i decoratori per sostenere l'attuazione Harel diagrammi di stato in stile, tra cui contesti con più stati, sottostati nidificazione con e senza storia. Il codice si snoda fino alla ricerca qualcosa di simile qui di seguito. Modulo è a 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()

In C #, iteratori (con 'ritorno resa' e 'rompere resa') sono un costrutto del linguaggio che traduce direttamente alle macchine a stati. Non ho in realtà mai usato come tale, ma io in realtà penso che potrebbe essere utilizzabile nella pratica.

Non ci sembra essere una domanda StackOverflow su di esso qui . La risposta più alto votato scoraggia, però ...

A parte Ragel v'è un linguaggio tecnicamente interessante, ma piuttosto oscura chiamato SL1. Vedere http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber= 1095580 . E 'stato creato da Iskratel in Slovenia al fine di sviluppare sistemi di telecomunicazione in cui le macchine a stati sono gli elementi di base.

Shriram Krishnamurthi ha un discorso e di un documento su utilizzo di macro per aggiungere un sottolingua embedded per automi a Scheme . Non sono sicuro se eventuali piani includono i suoi macro come una libreria standard, però.

Microsoft Research ha recentemente rilasciato il rel="nofollow"> P lingua PSharp quadro che fornisce una libreria di estensione C # e una sintassi di alto livello con il compilatore per il linguaggio.

Non vedo l'ora di provarlo.

Ecco una parte da uno dei loro esempi per le estensioni C #:

internal class Server : Machine
{
    MachineId Client;

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

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

    ...

Ecco una parte della loro sintassi di alto livello:

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

  ...

Sono quasi un decennio in ritardo alla festa, ma di recente mi sono imbattuto in un linguaggio oscuro che prende in prestito idee da FSM chiamati Hume

Non sono sicuro se è ancora attivamente mantenuto, ma si può almeno scaricare il compilatore e giocare con essa. L'informazione è difficile da trovare, ma c'è un paio di documenti e articoli online che mostrano gli elementi essenziali.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top