Pergunta

Estou apenas curioso para saber se existe uma linguagem de programação que possui máquinas de estado (semelhantes a boost::statechart) como construção de linguagem primária.

Analogias - c# possui delegados onde java usa o padrão observador e C possui retornos de chamada.Perl e python possuem hashes integrados, enquanto C++ e java precisam de uma biblioteca.

Atualizar:

Esta deve ser uma linguagem de programação geral no sentido de C++, C#, Java, Lisp ...

Quero dizer máquinas de estado "maduras" com todos os recursos no nível do formalismo de Harel ou diagramas de estado UML ou boost::statechart.

Foi útil?

Solução

Ragel é uma linguagem de máquina de estado. Iow, não é uma linguagem que também suporta máquinas de estado, é um idioma que Suporta máquinas de estado. O que obviamente significa que não é completo, mas quem precisa disso?

Mais precisamente, o Ragel é um compilador de máquinas de estado, que leva uma descrição de uma máquina de estado em uma linguagem do tipo regexp e gera uma implementação dessa máquina de estado em C, C ++, Objective-C, D, Java ou Ruby. (Acho yacc mas para máquinas de estado em vez de analisadores de tabela LALR (1).) O objetivo principal do RAGEL é analisar protocolos binários (como protocolos de rede ou também formatos de arquivo no disco), mas também pode ser usado para texto.

Um exemplo famoso de usar Ragel é o servidor da web do MonGrel para Ruby: seu kernel HTTP está escrito em Ragel, o que o torna extremamente rápido e seguro. O kernel HTTP é tão bom, de fato, que foi reutilizado várias vezes em diferentes aplicações: fino, unicórnio e arco -íris também são servidores da web e, de fato, os concorrentes diretos para MonGrel. O EBB é um proxy HTTP reverso. O Rfuzz é uma ferramenta de teste de fuzz para aplicativos da Web. Além disso, algumas ferramentas de segurança o usam.

Ragel também permite incorporar código no idioma host na máquina do estado, tornando-a completa e capaz de não apenas reconhecer mas também interpretar protocolos.

No geral, todo Idioma com suporte para fluxo de controle avançado definido pelo usuário via coroutines (por exemplo, Lua) ou continuações (por exemplo, scala) ou GOTO (por exemplo, php) ou chamadas de cauda adequadas (por exemplo, esquema) podem ser usadas para facilmente implemento máquinas de estado. (Geradores (python) também conhecido como iteradores (c#), que são basicamente "coroutinas ruins" podem ou não funcionar, dependendo da sua definição de "trabalho".) E qualquer idioma que tenha sintaxe flexível (por exemplo, rubi) ou suporta a abstração metassintática ( por exemplo, clojure) pode ser usado para descrever máquinas de estado. (O suporte a identificadores não-ASCII também ajuda, para que você possa usar setas reais para sua máquina de estado.)

O que significa que se você combinar os dois e use um idioma que suporta Ambas chamadas de cauda e Abstração metassintática, você obtém máquinas de estado muito boas, sem exigindo suporte à linguagem nativa. Shriram Krishnamurthi deu uma palestra agora (em) famosa intitulada "The Swine Before Perl" na conferência inaugural de idiomas leves, na qual ele demonstrou uma implementação do FSM no esquema. (Aqui está o slides, um gravação de áudio e a artigo explicando o código). O código em si é uma macro de 26 linhas (linhas muito curtas, na verdade), que permite escrever código como este:

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

Esta é uma especificação da máquina de estado correspondente à expressão regular c(a|d)*r. E não é apenas uma especificação, mas também um programa executável implementação aquela máquina de estado.

Eu posso chamá -lo assim:

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

E, neste caso, obtenha o resultado #t (que é o Esquema Speak for true).

Outras dicas

Há uma nova linguagem de máquina estadual baseada em XML W3C chamada Scxml, com base no de David Harel Statechart formalismo (que suporta máquinas de estado hierárquico e paralelo).

Apache Commons tem um Implementação baseada em Java de SCXML:

O Commons SCXML é uma implementação destinada a criar e manter um mecanismo Java SCXML capaz de executar uma máquina de estado definida usando um documento SCXML, abstraindo as interfaces do ambiente.

SMC é um compilador para uma linguagem simples de domínio específico que irá gerar máquinas de estado para muitas linguagens populares.Eu o usei para gerar máquinas de estado sustentáveis ​​para uma ampla variedade de coisas, como interfaces de usuário complexas e protocolos de rede personalizados.

A linguagem de programação xadrez introduz "Programação orientada para o tipo, um paradigma que estende a programação orientada a objetos com o tipo de tipo".

Aqui está o documento: http://www.cs.cmu.edu/~aldrich/plaid/

Por exemplo:

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

Acabei de encontrar um: ASML (linguagem de máquina de estado abstrata).
Aqui está o página com mais informações nele no codeplex.

Interessante o suficiente, é desenvolvido pela Microsoft.

O OTP de Erlang suporta construções de máquina de estado via 'gen_fsm'. Faz alguns anos que eu olhei pela última vez, então estou um pouco enferrujado, mas você pode pesquisar no Google para 'erlang gen_fsm' e encontrar um monte de material de referência

Não é exatamente, mas existe um módulo de máquina de estado para o Python que permite usar os decoradores para apoiar a implementação do estilo Harel StateCharts, incluindo contextos com vários estados, subestados de nidificação com e sem história. O código acaba parecendo algo abaixo. Módulo está em 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()

Em C#, os iteradores (com 'Retorno de rendimento' e 'Break Break') são um construto de idioma que se traduz diretamente em máquinas de estado. Na verdade, nunca o usei como tal, mas realmente acho que poderia ser utilizável na prática.

Acontece que haverá uma pergunta de StackOverflow sobre isso aqui. A resposta mais alta de votos desencoraja -a ...

Além de Ragel, há uma linguagem tecnicamente interessante, mas bastante obscura, chamada SL1. Ver http://ieeexplore.ieee.org/xpl/freebs_all.jsp?arnumber=1095580. Foi criado pela ISKRATEL na Eslovênia para desenvolver sistemas de telecomunicações onde as máquinas de estado são os blocos básicos.

Shriram Krishnamurthi tem uma palestra e um artigo sobre Usando macros para adicionar uma subblangura incorporada para autômatos para esquema. Não tenho certeza se algum esquema inclui suas macros como uma biblioteca padrão.

A Microsoft Research lançou recentemente o P idioma no github. Eles também têm o PSharp estrutura que fornece uma biblioteca de extensão C# e uma sintaxe de alto nível com o compilador para o idioma.

Estou ansioso para experimentá -lo.

Aqui está uma parte de um de seus exemplos para as extensões C#:

internal class Server : Machine
{
    MachineId Client;

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

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

    ...

Aqui está uma parte de sua sintaxe de alto nível:

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

  ...

Estou quase uma década atrasada para a festa, mas recentemente tropecei em uma linguagem obscura que empresta idéias do FSMS chamadas Hume

Não tenho certeza se ainda é mantido ativamente, mas você pode pelo menos baixar o compilador e brincar com ele. É difícil encontrar informações, mas existem alguns artigos e artigos on -line que mostram o essencial.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top