8be02e260e3e2a950790c9b3a98597dd4b4f05fa
[external/ragel.git] / test / union.rl
1 /*
2  * @LANG: c++
3  * Show off concurrent abilities.
4  */
5
6 #include <iostream>
7 #include <stdlib.h>
8 #include <stdio.h>
9
10 using namespace std;
11
12 #define BUFSIZE 2048
13
14 struct Concurrent
15 {
16         int cur_char;
17         int start_word;
18         int start_comment;
19         int start_literal;
20
21         int cs;
22
23         // Initialize the machine. Invokes any init statement blocks. Returns 0
24         // if the machine begins in a non-accepting state and 1 if the machine
25         // begins in an accepting state.
26         void init( );
27
28         // Execute the machine on a block of data. Returns -1 if after processing
29         // the data, the machine is in the error state and can never accept, 0 if
30         // the machine is in a non-accepting state and 1 if the machine is in an
31         // accepting state.
32         void execute( const char *data, int len );
33
34         // Indicate that there is no more data. Returns -1 if the machine finishes
35         // in the error state and does not accept, 0 if the machine finishes
36         // in any other non-accepting state and 1 if the machine finishes in an
37         // accepting state.
38         int finish( );
39 };
40
41 %%{
42         machine Concurrent;
43
44         action next_char {
45                 cur_char += 1;
46         }
47
48         action start_word {
49                 start_word = cur_char;
50         }
51         action end_word {
52                 cout << "word: " << start_word << 
53                                 " " << cur_char-1 << endl;
54         }
55
56         action start_comment {
57                 start_comment = cur_char;
58         }
59         action end_comment {
60                 cout << "comment: " << start_comment <<
61                                 " " << cur_char-1 << endl;
62         }
63
64         action start_literal {
65                 start_literal = cur_char;
66         }
67         action end_literal {
68                 cout << "literal: " << start_literal <<
69                                 " " << cur_char-1 << endl;
70         }
71
72         # Count characters.
73         chars = ( any @next_char )*;
74
75         # Words are non-whitespace. 
76         word = ( any-space )+ >start_word %end_word;
77         words = ( ( word | space ) $1 %0 )*;
78
79         # Finds C style comments. 
80         comment = ( '/*' any* $0 '*/'@1 ) >start_comment %end_comment;
81         comments = ( ( comment | any ) $1 %0 )*;
82
83         # Finds single quoted strings. 
84         literalChar = ( any - ['\\] ) | ( '\\' . any );
85         literal = ('\'' literalChar* '\'' ) >start_literal %end_literal;
86         literals = ( ( literal | (any-'\'') ) $1 %0 )*;
87
88         main := chars | words | comments | literals;
89 }%%
90
91 %% write data;
92
93 void Concurrent::init( )
94 {
95         cur_char = 0;
96         %% write init;
97 }
98
99 void Concurrent::execute( const char *data, int len )
100 {
101         const char *p = data;
102         const char *pe = data + len;
103         const char *eof = pe;
104
105         %% write exec;
106 }
107
108 int Concurrent::finish( )
109 {
110         if ( cs == Concurrent_error )
111                 return -1;
112         if ( cs >= Concurrent_first_final )
113                 return 1;
114         return 0;
115 }
116
117 void test( char *buf )
118 {
119         Concurrent concurrent;
120         concurrent.init();
121         concurrent.execute( buf, strlen(buf) );
122         if ( concurrent.finish() > 0 )
123                 cout << "ACCEPT" << endl;
124         else
125                 cout << "FAIL" << endl;
126 }
127
128 int main()
129 {
130         test( 
131                 "/* in a comment,\n"
132                 " * ' and now in a literal string\n"
133                 " */ \n"
134                 " \n"
135                 "the comment has now ended but the literal string lives on\n"
136                 "\n"
137                 "' comment closed\n" );
138         test( "/* * ' \\' */ \\' '\n" );
139         test( "/**/'\\''/*/*/\n" );
140         return 0;
141 }
142
143 #ifdef _____OUTPUT_____
144 word: 1 2
145 word: 4 5
146 word: 7 7
147 word: 9 16
148 word: 19 19
149 word: 21 21
150 word: 23 25
151 word: 27 29
152 word: 31 32
153 word: 34 34
154 word: 36 42
155 word: 44 49
156 word: 52 53
157 comment: 1 53
158 word: 58 60
159 word: 62 68
160 word: 70 72
161 word: 74 76
162 word: 78 82
163 word: 84 86
164 word: 88 90
165 word: 92 98
166 word: 100 105
167 word: 107 111
168 word: 113 114
169 word: 117 117
170 literal: 21 117
171 word: 119 125
172 word: 127 132
173 ACCEPT
174 word: 1 2
175 word: 4 4
176 word: 6 6
177 word: 8 9
178 word: 11 12
179 comment: 1 12
180 word: 14 15
181 word: 17 17
182 literal: 6 17
183 ACCEPT
184 comment: 1 4
185 literal: 5 8
186 word: 1 13
187 comment: 9 13
188 ACCEPT
189 #endif