Some cleanup and fixes to the runtests script. The -P option will be changing.
[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         char *tokstart, *tokend;
48
49         void token( int tok );
50         void run();
51
52         void init( );
53         void execute( 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( tokstart[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( char *data, int len )
141 {
142         char *p = data;
143         char *pe = data + len;
144
145         %% write exec;
146 }
147
148 int Scanner::finish( )
149 {
150         %% write eof;
151         if ( cs == Scanner_error )
152                 return -1;
153         if ( cs >= Scanner_first_final )
154                 return 1;
155         return 0;
156 }
157
158
159 void Scanner::token( int tok )
160 {
161         const char *data = tokstart;
162         int len = tokend - tokstart;
163         cout << "<" << tok << "> ";
164         for ( int i = 0; i < len; i++ )
165                 cout << data[i];
166         cout << '\n';
167 }
168
169 void test( char *buf )
170 {
171         int len = strlen( buf );
172         std::ios::sync_with_stdio(false);
173         Scanner scanner;
174         scanner.init();
175
176         scanner.execute( buf, len );
177         if ( scanner.cs == Scanner_error ) {
178                 /* Machine failed before finding a token. */
179                 cout << "PARSE ERROR" << endl;
180         }
181
182         /* FIXME: Last token may get lost. */
183         scanner.finish();
184 }
185
186 int main()
187 {
188         test(
189                 "\"\\\"hi\" /*\n"
190                 "*/\n"
191                 "44 .44\n"
192                 "44. 44\n"
193                 "44 . 44\n"
194                 "44.44\n"
195                 "_hithere22\n"
196                 "\n"
197         );
198
199         test(
200                 "'\\''\"\\n\\d'\\\"\"\n"
201                 "hi\n"
202                 "99\n"
203                 ".99\n"
204                 "99e-4\n"
205                 "->*\n"
206                 "||\n"
207                 "0x98\n"
208                 "0x\n"
209                 "//\n"
210                 "/* * */\n"
211         );
212
213         test(
214                 "'\n"
215                 "'\n"
216         );
217
218 }
219
220 #ifdef _____OUTPUT_____
221 <192> "\"hi"
222 <241>  
223 <242> /*
224 */
225 <241> 
226
227 <218> 44
228 <241>  
229 <194> .44
230 <241> 
231
232 <194> 44.
233 <241>  
234 <218> 44
235 <241> 
236
237 <218> 44
238 <241>  
239 <46> .
240 <241>  
241 <218> 44
242 <241> 
243
244 <194> 44.44
245 <241> 
246
247 <195> _hithere22
248 <193> '\''
249 <192> "\n\d'\""
250 <241> 
251
252 <195> hi
253 <241> 
254
255 <218> 99
256 <241> 
257
258 <194> .99
259 <241> 
260
261 <194> 99e-4
262 <241> 
263
264 <214> ->*
265 <241> 
266
267 <226> ||
268 <241> 
269
270 <220> 0x98
271 <241> 
272
273 <218> 0
274 <195> x
275 <241> 
276
277 <242> //
278
279 <242> /* * */
280 PARSE ERROR
281 #endif