fb:porticula NoPaste
FSM mit State Pattern
Uploader: | St_W |
Datum/Zeit: | 18.03.2013 20:13:58 |
/'
"test.input" sample file:
a
b
ab
aa
bb
aba
abba
abb
abbabbbaaba
'/
#Define FALSE 0
#Define TRUE (Not FALSE)
#if Not __FB_MIN_VERSION__(0, 25, 0)
#error fbc must be at least version 0.25.0 to compile this module
#EndIf
Type StateObjFW As StateObj
Type StateCtx extends Object
Private:
Dim curState As StateObjFW Ptr
Public:
Declare Constructor()
Declare Destructor()
Declare Function setState(As StateCtx Ptr) As StateCtx Ptr
Declare Sub nav(As String)
Declare Function isFinal() As Integer
End Type
Type StateObj extends Object
Declare abstract Sub nav(As StateCtx Ptr, As String)
End Type
Type StateA1 extends StateObj
Declare Sub nav(As StateCtx Ptr, As String)
End Type
Type StateB1 extends StateObj
Declare Sub nav(As StateCtx Ptr, As String)
End Type
Type StateC1C2 extends StateObj
Declare Sub nav(As StateCtx Ptr, As String)
End Type
Type StateC1C3 extends StateObj
Declare Sub nav(As StateCtx Ptr, As String)
End Type
Type StateC1 extends StateObj
Declare Sub nav(As StateCtx Ptr, As String)
End Type
Type StateEmpty extends StateObj
Declare Sub nav(As StateCtx Ptr, As String)
End Type
Sub StateA1.nav(ctx As StateCtx Ptr, a As String)
Select Case a
Case "a": Delete ctx->setState(New StateB1)
Case Else: Delete ctx->setState(New StateEmpty)
End Select
End Sub
Sub StateB1.nav(ctx As StateCtx Ptr, a As String)
Select Case a
Case "b": Delete ctx->setState(New StateC1C2)
Case Else: Delete ctx->setState(New StateEmpty)
End Select
End Sub
Sub StateC1C2.nav(ctx As StateCtx Ptr, a As String)
Select Case a
Case "a": Delete ctx->setState(New StateC1C3)
Case "b": Delete ctx->setState(New StateC1C2)
End Select
End Sub
Sub StateC1C3.nav(ctx As StateCtx Ptr, a As String)
Select Case a
Case "a": Delete ctx->setState(New StateC1)
Case "b": Delete ctx->setState(New StateC1C2)
End Select
End Sub
Sub StateC1.nav(ctx As StateCtx Ptr, a As String)
Select Case a
Case "a": Delete ctx->setState(New StateC1)
Case "b": Delete ctx->setState(New StateC1C2)
End Select
End Sub
Sub StateEmpty.nav(ctx As StateCtx Ptr, a As String)
Delete ctx->setState(New StateEmpty)
End Sub
Constructor StateCtx ()
this.curState = New StateA1
End Constructor
Destructor StateCtx()
Delete this.curState
End Destructor
Function StateCtx.setState(s As StateCtx Ptr) As StateCtx Ptr
Dim tmp As StateCtx Ptr = this.curState
this.curState = s
Return tmp
End Function
Sub StateCtx.nav(s As String)
this.curState->nav(@This, s)
End Sub
Function StateCtx.isFinal() As Integer
If *this.curState Is StateC1C3 Then Return TRUE
Return FALSE
End Function
'Open "test.input" For Input As #1
Open Cons For Input As #1
Dim s As String
Do
Dim sc As StateCtx
Line Input #1, s
If Eof(1) Then Exit Do
For q As Integer = 0 To Len(s)-1
sc.nav(Chr(s[q]))
Next
Print """"; s; """ "; *IIf(sc.isFinal, @"ACCEPT", @"REJECT")
Loop