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