cb99a20354fc3a9c6ad3918aa18b5d0e5a71998c
[external/ragel.git] / examples / statechart / statechart.rl
1 /*
2  * Demonstrate the use of labels, the epsilon operator, and the join operator
3  * for creating machines using the named state and transition list paradigm.
4  * This implementes the same machine as the atoi example.
5  */
6
7 #include <iostream>
8 #include <stdlib.h>
9 #include <stdio.h>
10
11 using namespace std;
12
13 struct StateChart
14 {
15         bool neg;
16         int val;
17         int cs;
18
19         int init( );
20         int execute( const char *data, int len );
21         int finish( );
22 };
23
24 %%{
25         machine StateChart;
26
27         action begin {
28                 neg = false;
29                 val = 0;
30         }
31
32         action see_neg {
33                 neg = true;
34         }
35
36         action add_digit { 
37                 val = val * 10 + (fc - '0');
38         }
39
40         action finish {
41                 if ( neg )
42                         val = -1 * val;
43         }
44
45         atoi = (
46                 start: (
47                         '-' @see_neg ->om_num | 
48                         '+' ->om_num |
49                         [0-9] @add_digit ->more_nums
50                 ),
51
52                 # One or more nums.
53                 om_num: (
54                         [0-9] @add_digit ->more_nums
55                 ),
56
57                 # Zero ore more nums.
58                 more_nums: (
59                         [0-9] @add_digit ->more_nums |
60                         '' -> final
61                 )
62         ) >begin %finish;
63
64         main := ( atoi '\n' @{ cout << val << endl; } )*;
65 }%%
66
67 %% write data;
68
69 int StateChart::init( )
70 {
71         %% write init;
72         return 1;
73 }
74
75 int StateChart::execute( const char *data, int len )
76 {
77         const char *p = data;
78         const char *pe = data + len;
79
80         %% write exec;
81
82         if ( cs == StateChart_error )
83                 return -1;
84         if ( cs >= StateChart_first_final )
85                 return 1;
86         return 0;
87 }
88
89 int StateChart::finish( )
90 {
91         %% write eof;
92         if ( cs == StateChart_error )
93                 return -1;
94         if ( cs >= StateChart_first_final )
95                 return 1;
96         return 0;
97 }
98
99
100 #define BUFSIZE 1024
101
102 int main()
103 {
104         char buf[BUFSIZE];
105
106         StateChart atoi;
107         atoi.init();
108         while ( fgets( buf, sizeof(buf), stdin ) != 0 ) {
109                 atoi.execute( buf, strlen(buf) );
110         }
111         if ( atoi.finish() <= 0 )
112                 cerr << "statechart: error: parsing input" << endl;
113         return 0;
114 }