1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
/*
* @LANG: obj-c
*/
#include <stdio.h>
#include <objc/Object.h>
struct LangEl
{
int key;
char *name;
};
@interface Fsm : Object
{
@public
int cs;
};
// Initialize the machine. Invokes any init statement blocks. Returns 0
// if the machine begins in a non-accepting state and 1 if the machine
// begins in an accepting state.
- (int) initFsm;
// Execute the machine on a block of data. Returns -1 if after processing
// the data, the machine is in the error state and can never accept, 0 if
// the machine is in a non-accepting state and 1 if the machine is in an
// accepting state.
- (int) executeWithData:( struct LangEl *)data len:(int)len;
// Indicate that there is no more data. Returns -1 if the machine finishes
// in the error state and does not accept, 0 if the machine finishes
// in any other non-accepting state and 1 if the machine finishes in an
// accepting state.
- (int) finish;
@end;
@implementation Fsm
%%{
machine Fsm;
alphtype int;
getkey fpc->key;
action a1 {}
action a2 {}
action a3 {}
main := ( 1 2* 3 )
${printf("%s\n", fpc->name);}
%/{printf("accept\n");};
}%%
%% write data;
- (int) initFsm;
{
%% write init;
return 0;
}
- (int) executeWithData:( struct LangEl *)_data len:(int)_len;
{
struct LangEl *p = _data;
struct LangEl *pe = _data + _len;
struct LangEl *eof = pe;
%% write exec;
if ( self->cs == Fsm_error )
return -1;
return ( self->cs >= Fsm_first_final ) ? 1 : 0;
}
- (int) finish;
{
if ( self->cs == Fsm_error )
return -1;
return ( self->cs >= Fsm_first_final ) ? 1 : 0;
}
@end
int main()
{
static Fsm *fsm;
static struct LangEl lel[] = {
{1, "one"},
{2, "two-a"},
{2, "two-b"},
{2, "two-c"},
{3, "three"}
};
fsm = [[Fsm alloc] init];
[fsm initFsm];
[fsm executeWithData:lel len:5];
[fsm finish];
return 0;
}
@interface Fsm2 : Object
{
// The current state may be read and written to from outside of the
// machine. From within action code, curs is -1 and writing to it has no
// effect.
@public
int cs;
@protected
}
// Execute the machine on a block of data. Returns -1 if after processing
// the data, the machine is in the error state and can never accept, 0 if
// the machine is in a non-accepting state and 1 if the machine is in an
// accepting state.
- (int)
executeWithElements:(int) elements
length:(unsigned)length;
@end
@implementation Fsm2
- (int)
executeWithElements:(int)elements
length:(unsigned)length;
{
return 0;
}
@end
#ifdef _____OUTPUT_____
one
two-a
two-b
two-c
three
accept
#endif
|