Initialize Tizen 2.3
[external/ragel.git] / test / cppscan3.rl
1 /*
2  * @LANG: c++
3  */
4
5 #include <iostream>
6 #include <string.h>
7 using namespace std;
8
9 #define TK_Dlit 192
10 #define TK_Slit 193
11 #define TK_Float 194
12 #define TK_Id 195
13 #define TK_NameSep 197
14 #define TK_Arrow 211
15 #define TK_PlusPlus 212
16 #define TK_MinusMinus 213
17 #define TK_ArrowStar 214
18 #define TK_DotStar 215
19 #define TK_ShiftLeft 216
20 #define TK_ShiftRight 217
21 #define TK_IntegerDecimal 218
22 #define TK_IntegerOctal 219
23 #define TK_IntegerHex 220
24 #define TK_EqualsEquals 223
25 #define TK_NotEquals 224
26 #define TK_AndAnd 225
27 #define TK_OrOr 226
28 #define TK_MultAssign 227
29 #define TK_DivAssign 228
30 #define TK_PercentAssign 229
31 #define TK_PlusAssign 230
32 #define TK_MinusAssign 231
33 #define TK_AmpAssign 232
34 #define TK_CaretAssign 233
35 #define TK_BarAssign 234
36 #define TK_DotDotDot 240
37 #define TK_Whitespace 241
38 #define TK_Comment 242
39
40 #define BUFSIZE 4096
41
42 char buf[BUFSIZE];
43
44 struct Scanner
45 {
46         int cs, act;
47         const char *ts, *te;
48
49         void token( int tok );
50         void run();
51
52         void init( );
53         void execute( const char *data, int len );
54         int finish( );
55 };
56
57 %%{
58         machine Scanner;
59
60         main := |*
61
62         # Single and double literals.
63         ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) 
64                 => { token( TK_Slit );};
65         ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) 
66                 => { token( TK_Dlit );};
67
68         # Identifiers
69         ( [a-zA-Z_] [a-zA-Z0-9_]* ) 
70                 =>{ token( TK_Id );};
71
72         # Floating literals.
73         fract_const = digit* '.' digit+ | digit+ '.';
74         exponent = [eE] [+\-]? digit+;
75         float_suffix = [flFL];
76
77         ( fract_const exponent? float_suffix? |
78                 digit+ exponent float_suffix? ) 
79                 => { token( TK_Float );};
80         
81         # Integer decimal. Leading part buffered by float.
82         ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) 
83                 => { token( TK_IntegerDecimal );};
84
85         # Integer octal. Leading part buffered by float.
86         ( '0' [0-9]+ [ulUL]{0,2} ) 
87                 => { token( TK_IntegerOctal );};
88
89         # Integer hex. Leading 0 buffered by float.
90         ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) 
91                 => { token( TK_IntegerHex );};
92
93         # Only buffer the second item, first buffered by symbol. */
94         '::' => {token( TK_NameSep );};
95         '==' => {token( TK_EqualsEquals );};
96         '!=' => {token( TK_NotEquals );};
97         '&&' => {token( TK_AndAnd );};
98         '||' => {token( TK_OrOr );};
99         '*=' => {token( TK_MultAssign );};
100         '/=' => {token( TK_DivAssign );};
101         '%=' => {token( TK_PercentAssign );};
102         '+=' => {token( TK_PlusAssign );};
103         '-=' => {token( TK_MinusAssign );};
104         '&=' => {token( TK_AmpAssign );};
105         '^=' => {token( TK_CaretAssign );};
106         '|=' => {token( TK_BarAssign );};
107         '++' => {token( TK_PlusPlus );};
108         '--' => {token( TK_MinusMinus );};
109         '->' => {token( TK_Arrow );};
110         '->*' => {token( TK_ArrowStar );};
111         '.*' => {token( TK_DotStar );};
112
113         # Three char compounds, first item already buffered. */
114         '...' => { token( TK_DotDotDot );};
115
116         # Single char symbols.
117         ( punct - [_"'] ) => { token( ts[0] );};
118
119         action comment {
120                 token( TK_Comment );
121         }
122
123         # Comments and whitespace.
124         '/*' ( any* $0 '*/' @1 ) => comment;
125         '//' ( any* $0 '\n' @1 ) => comment;
126         ( any - 33..126 )+ => { token( TK_Whitespace );};
127
128         *|;
129 }%%
130
131 %% write data;
132
133 void Scanner::init( )
134 {
135         %% write init;
136 }
137
138 /* Returns the count of bytes still in the buffer 
139  * (shifted to the biginning) */
140 void Scanner::execute( const char *data, int len )
141 {
142         const char *p = data;
143         const char *pe = data + len;
144         const char *eof = pe;
145
146         %% write exec;
147
148         cout << "P: " << (p - data) << endl;
149 }
150
151 int Scanner::finish( )
152 {
153         if ( cs == Scanner_error )
154                 return -1;
155         if ( cs >= Scanner_first_final )
156                 return 1;
157         return 0;
158 }
159
160
161 void Scanner::token( int tok )
162 {
163         const char *data = ts;
164         int len = te - ts;
165         cout << "<" << tok << "> ";
166         for ( int i = 0; i < len; i++ )
167                 cout << data[i];
168         cout << '\n';
169 }
170
171 void test( const char *buf )
172 {
173         int len = strlen( buf );
174         std::ios::sync_with_stdio(false);
175         Scanner scanner;
176         scanner.init();
177
178         scanner.execute( buf, len );
179         if ( scanner.cs == Scanner_error ) {
180                 /* Machine failed before finding a token. */
181                 cout << "PARSE ERROR" << endl;
182         }
183
184         /* FIXME: Last token may get lost. */
185         scanner.finish();
186 }
187
188 int main()
189 {
190         test(
191                 "\"\\\"hi\" /*\n"
192                 "*/\n"
193                 "44 .44\n"
194                 "44. 44\n"
195                 "44 . 44\n"
196                 "44.44\n"
197                 "_hithere22"
198         );
199
200         test(
201                 "'\\''\"\\n\\d'\\\"\"\n"
202                 "hi\n"
203                 "99\n"
204                 ".99\n"
205                 "99e-4\n"
206                 "->*\n"
207                 "||\n"
208                 "0x98\n"
209                 "0x\n"
210                 "//\n"
211                 "/* * */"
212         );
213
214         test(
215                 "'\n"
216                 "'\n"
217         );
218
219 }
220
221 #ifdef _____OUTPUT_____
222 <192> "\"hi"
223 <241>  
224 <242> /*
225 */
226 <241> 
227
228 <218> 44
229 <241>  
230 <194> .44
231 <241> 
232
233 <194> 44.
234 <241>  
235 <218> 44
236 <241> 
237
238 <218> 44
239 <241>  
240 <46> .
241 <241>  
242 <218> 44
243 <241> 
244
245 <194> 44.44
246 <241> 
247
248 <195> _hithere22
249 P: 51
250 <193> '\''
251 <192> "\n\d'\""
252 <241> 
253
254 <195> hi
255 <241> 
256
257 <218> 99
258 <241> 
259
260 <194> .99
261 <241> 
262
263 <194> 99e-4
264 <241> 
265
266 <214> ->*
267 <241> 
268
269 <226> ||
270 <241> 
271
272 <220> 0x98
273 <241> 
274
275 <218> 0
276 <195> x
277 <241> 
278
279 <242> //
280
281 <242> /* * */
282 P: 55
283 P: 1
284 PARSE ERROR
285 #endif