31

プライマリ言語構造としてステート マシン (boost::statechart に類似) を持つプログラミング言語があるかどうか、私はただ興味があります。

類推 - c# にはデリゲートがあり、java にはオブザーバー パターンが使用され、C にはコールバックがあります。Perl と Python には組み込みのハッシュがありますが、C++ と Java にはライブラリが必要です。

アップデート:

これは、C++、C#、Java、Lisp などの一般的なプログラミング言語である必要があります。

私は、Harel 形式や UML 状態図、boost::statechart のレベルですべての機能を備えた「成熟した」状態マシンを意味します。

4

14 に答える 14

51

Ragelはステート マシン言語です。IOW、それはステート マシンもサポートする言語ではなく、ステート マシンのみをサポートする言語です。これは明らかにチューリング完全ではないことを意味しますが、誰がそれを必要としますか?

より正確には、Ragel はステート マシン コンパイラであり、正規表現のような言語でステート マシンの記述を取得し、そのステート マシンの実装を C、C++、Objective-C、D、Java、または Ruby で生成します。yacc(ただし、LALR(1) テーブル パーサーではなく、ステート マシンの場合を考えてください。) Ragel の主な目的は、バイナリ プロトコル (ネットワーク プロトコルやディスク上のファイル形式など) を解析することですが、テキストにも同様に使用できます。

Ragel を使用した有名な例の 1 つは、Ruby の Mongrel Web サーバーです。その HTTP カーネルは Ragel で記述されているため、非常に高速で安全です。実際、HTTP カーネルは非常に優れているため、さまざまなアプリケーションで何度も再利用されています。Thin、Unicorn、Rainbows も Web サーバーであり、実際には Mongrel の直接の競合相手です。Ebb はリバース HTTP プロキシです。RFuzz は、Web アプリケーション用のファズ テスト ツールです。また、一部のセキュリティ ツールで使用されます。

Ragel では、ホスト言語のコードをステート マシンに埋め込むこともできるため、チューリング完全であり、プロトコルを認識するだけでなく解釈することもできます。

一般に、コルーチン (Lua など) または継続 (Scala など) または (PHP など) または適切な末尾呼び出し (Scheme など) を介した高度なユーザー定義の制御フローをサポートするすべての言語を使用して、ステート マシンGOTOを簡単に実装できます。(ジェネレーター (Python) 別名イテレーター (C#) は、基本的に「くだらないコルーチン」であり、「作業」の定義に応じて、機能する場合と機能しない場合があります。) また、柔軟な構文 (Ruby など) を持つか、メタシンタックス抽象化をサポートする言語 ( Clojure など) を使用してステート マシンを記述できます。(非 ASCII 識別子のサポートも役立つため、ステート マシンに実際の矢印を使用できます。)

つまり、この 2 つを組み合わせて、テール コールとメタ構文の抽象化の両方をサポートする言語を使用すると、ネイティブ言語のサポートを必要とせずに、非常に優れたステート マシンが得られます。Shriram Krishnamurthi 氏は、第 1 回 Lightweight Languages Conference で "The Swine before Perl" というタイトルの講演を行い、Scheme での FSM 実装を実演しました。(スライド音声記録、およびコードを説明する論文があります)。コード自体は 26 行 (実際には非常に短い行) のマクロであり、次のようなコードを記述できます。

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

正規表現に対応したステートマシンの仕様ですc(a|d)*r。そして、それは仕様であるだけでなく、そのステート マシンを実装する実行可能なプログラムでもあります。

次のように呼び出すことができます。

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

そして、この場合、結果を取得します#t(これは、Scheme で言えば ですtrue)。

于 2009-11-25T07:23:23.993 に答える
10

SCXMLと呼ばれる新しい W3C XML ベースのステート マシン言語があります。これは、David Harel のStateChartフォーマリズム (階層型および並列ステート マシンをサポートする) に基づいています。

Apache Commons には、SCXML の Java ベースの実装があります

Commons SCXML は、環境インターフェイスを抽象化しながら、SCXML ドキュメントを使用して定義されたステート マシンを実行できる Java SCXML エンジンを作成および維持することを目的とした実装です。

于 2009-11-24T23:47:28.710 に答える
5

Plaid プログラミング言語は、「型状態指向プログラミング、オブジェクト指向プログラミングを型状態で拡張するパラダイム」を導入しています。

ドキュメントは次のとおりです。 http://www.cs.cmu.edu/~aldrich/plaid/

例えば:

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]
        { ... }
}
于 2012-05-14T07:44:38.670 に答える
4

SMCは、多くの一般的な言語のステート マシンを生成する単純なドメイン固有言語のコンパイラです。私はこれを使用して、複雑なユーザー インターフェイスやカスタム ネットワーク プロトコルなど、さまざまなものに対して保守可能なステート マシンを生成しました。

于 2011-03-11T23:54:36.877 に答える
3

AsmL (Abstract State Machine Language) という1 つを見つけました。CodePlex の詳細
について は、こちらのページを参照してください。

興味深いことに、これはマイクロソフトによって開発されています。

于 2009-11-24T22:59:57.817 に答える
3

Erlang の OTP は、「gen_fsm」を介してステート マシン構造をサポートします。最後に調べてから数年経っているので、少し錆びていますが、「Erlang gen_fsm」をグーグルで検索すると、参考資料がたくさん見つかります

于 2009-11-25T00:42:12.250 に答える
2

完全ではありませんが、デコレーターを使用して Harel スタイルのステートチャートの実装をサポートできる Python 用のステート マシン モジュールがあります。これには、複数のステートを持つコンテキスト、履歴の有無にかかわらずサブステートのネストが含まれます。コードは次のようになります。モジュールは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()
于 2010-11-15T18:50:20.013 に答える
1

Ragel とは別に、SL1 と呼ばれる、技術的には興味深いが非常にあいまいな言語があります。http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=1095580を参照してください。ステート マシンが基本ブロックであるテレコム システムを開発するために、スロベニアの Iskratel によって作成されました。

于 2011-03-13T12:06:56.227 に答える
1

C# では、反復子 ('yield return' と 'yield break' を含む) は、ステート マシンに直接変換される言語構造です。実際に使ったことはありませんが、実際には使えると思います。

hereについてのスタックオーバーフローの質問があります。最も投票数の多い回答はそれを思いとどまらせます...

于 2009-11-24T23:58:34.797 に答える
1

Shriram Krishnamurthi は、マクロを使用してオートマトン用の埋め込みサブ言語を Scheme に追加することについての講演と論文を持っています。ただし、標準ライブラリとして彼のマクロが含まれているスキームがあるかどうかはわかりません。

于 2012-01-26T03:45:33.210 に答える
1

私はパーティーにほぼ 10 年遅れていますが、最近、ヒュームと呼ばれる FSM からアイデアを借用したあいまいな言語に出くわしました。

まだ積極的にメンテナンスされているかどうかはわかりませんが、少なくともコンパイラをダウンロードして、いじってみることができます。情報を入手するのは困難ですが、オンライン上には、要点を示す論文や記事がいくつかあります。

于 2018-09-17T16:59:09.253 に答える