programming languages - machine - ¿Existe un lenguaje de programación con construcción de máquina de estado integrada?
machine state in c (12)
Acabo de encontrar uno: AsmL (lenguaje de máquina de estado abstracto) .
Aquí está la página con más información en CodePlex.
Bastante interesante, está desarrollado por Microsoft.
Solo tengo curiosidad si hay un lenguaje de programación que tiene máquinas de estado (similar a boost :: statechart) como construcción de lenguaje primario.
Analogías: c # tiene delegados donde java usa el patrón de observador y C tiene devoluciones de llamada. Perl y python tienen hashes incorporados, mientras que C ++ y java necesitan una biblioteca.
Actualizar:
Este debería ser un lenguaje de programación general en el sentido de C ++, C #, Java, Lisp ...
Me refiero a máquinas de estado "maduras" con todas las campanas y silbidos en el nivel de formalismo de Harel o diagramas de estado UML o boost :: statechart.
Aparte de Ragel hay un lenguaje técnicamente interesante, pero bastante oscuro llamado SL1. Consulte http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=1095580 . Fue creado por Iskratel en Eslovenia para desarrollar sistemas de telecomunicaciones donde las máquinas estatales son los bloques básicos.
El lenguaje de programación Plaid presenta "Programación orientada a la tipografía, un paradigma que amplía la programación orientada a objetos con la tipografía".
Aquí está el documento: http://www.cs.cmu.edu/~aldrich/plaid/
P.ej:
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]
{ ... }
}
En C #, los iteradores (con ''rendimiento de rendimiento'' y ''rendimiento de rendimiento'') son una construcción de lenguaje que se traduce directamente en máquinas de estados. En realidad nunca lo he usado como tal, pero en realidad creo que podría ser útil en la práctica.
Sucede que hay una pregunta de sobre esto here . La respuesta más votada lo desalienta aunque ...
Existe un nuevo lenguaje de máquina de estado basado en XML del W3C llamado SCXML , basado en el formalismo de StateChart David Harel (que admite máquinas de estado jerárquicas y paralelas).
Apache Commons tiene una implementación basada en Java de SCXML :
Commons SCXML es una implementación dirigida a crear y mantener un motor Java SCXML capaz de ejecutar una máquina de estados definida usando un documento SCXML, mientras se abstraen las interfaces del entorno.
La OTP de Erlang admite construcciones de máquinas de estado a través de ''gen_fsm''. Han pasado un par de años desde la última vez que lo vi, así que estoy un poco oxidado, pero puedes buscar en Google "Erlang gen_fsm" y encontrar un montón de material de referencia.
Llego casi una década tarde a la fiesta, pero recientemente me topé con un lenguaje oscuro que toma ideas de FSMs llamadas Hume
No estoy seguro de si todavía se mantiene activamente, pero al menos puedes descargar el compilador y jugar con él. La información es difícil de obtener, pero hay algunos artículos y artículos en línea que muestran lo esencial.
Microsoft Research lanzó recientemente el lenguaje P en GitHub. También tienen el marco PSharp que proporciona una biblioteca de extensión C # y una sintaxis de alto nivel con compilador para el lenguaje.
Estoy deseando probarlo.
Aquí hay una parte de uno de sus ejemplos para las extensiones de C #:
internal class Server : Machine
{
MachineId Client;
[Start]
[OnEntry(nameof(InitOnEntry))]
class Init : MachineState { }
void InitOnEntry()
{
...
this.Goto(typeof(Active));
}
...
Aquí hay una parte de su sintaxis de alto nivel:
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;
}
...
No del todo, pero hay un módulo de máquina de estado para Python que le permite usar decoradores para admitir la implementación de gráficos de estado de estilo Harel, incluidos contextos con varios estados, anidando subestados con y sin historial. El código termina mirando algo como abajo. El módulo se encuentra en 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()
Shriram Krishnamurthi tiene una charla y un documento sobre el uso de macros para agregar un sublenguaje incorporado para autómatas al esquema . Sin embargo, no estoy seguro de si alguno de los Esquemas incluye sus macros como una biblioteca estándar.
Ragel es un lenguaje de máquina de estado. IOW, no es un lenguaje que también admita máquinas de estados, es un lenguaje que solo admite máquinas de estados. Lo que obviamente significa que no es Turing completo, pero ¿quién necesita eso?
Más precisamente, Ragel es un compilador de máquina de estado, que toma una descripción de una máquina de estado en un lenguaje similar a expresiones regulares y genera una implementación de esa máquina de estado en C, C ++, Objective-C, D, Java o Ruby. (Piense yacc
pero para máquinas de estado en lugar de analizadores de tablas LALR (1)). El propósito principal de Ragel es analizar protocolos binarios (como protocolos de red o también formatos de archivos en disco), pero también puede usarse para texto .
Un ejemplo famoso del uso de Ragel es el servidor web mestizo para Ruby: su núcleo HTTP está escrito en Ragel, lo que lo hace extremadamente rápido y seguro. El kernel HTTP es tan bueno, de hecho, que se ha reutilizado varias veces en diferentes aplicaciones: Thin, Unicorn y Rainbows también son servidores web, y de hecho son competidores directos de Mongrel. Ebb es un proxy HTTP inverso. RFuzz es una herramienta de prueba de fuzz para aplicaciones web. Además, algunas herramientas de seguridad lo utilizan.
Ragel también permite insertar código en el lenguaje principal en la máquina de estado, lo que lo hace Turing-complete, y es capaz de no solo reconocer sino también interpretar protocolos.
En general, todos los idiomas compatibles con el flujo de control avanzado definido por el usuario a través de coroutines (por ejemplo, Lua) o continuaciones (por ejemplo, Scala) o GOTO
(por ejemplo, PHP) o llamadas de cola (por ejemplo, Esquema) se pueden usar para implementar fácilmente las máquinas de estado . (Los generadores (Python), también conocidos como iteradores (C #), que son básicamente "mentiras maliciosas" podrían o no funcionar, dependiendo de su definición de "trabajo". por ejemplo, Clojure) se puede usar para describir máquinas de estados. (El soporte para identificadores no ASCII también ayuda, de modo que puede usar flechas reales para su máquina de estado).
Lo que significa que si combina los dos y usa un lenguaje que admita tanto las llamadas de cola como la abstracción metasintáctica, obtendrá máquinas de estado muy agradables, sin necesidad de soporte de idioma nativo. Shriram Krishnamurthi dio una famosa (ahora) charla titulada "The Swine before Perl" en la conferencia inaugural de Lightweight Languages, en la que demostró una implementación de FSM en Scheme. (Aquí están las slides , una grabación de audio y un documento que explica el código ). El código en sí es una macro de 26 líneas (líneas muy cortas, en realidad), que te permite escribir código como este:
(define my-regex
(automaton init
[init : (c → more)]
[more : (a → more)
(d → more)
(r → end)]
[end : accept]))
Esta es una especificación de la máquina de estados correspondiente a la expresión regular c(a|d)*r
. Y no es solo una especificación, sino también un programa ejecutable que implementa esa máquina de estados.
Puedo llamarlo así:
(my-regex ''(c a d a d d r))
Y en este caso, obtenga el resultado #t
(que es Scheme-speak para true
).
SMC es un compilador para un lenguaje simple específico del dominio que generará máquinas de estado para muchos idiomas populares. Lo he usado para generar máquinas de estado mantenibles para una gran variedad de cosas, como interfaces de usuario complejas y protocolos de red personalizados.