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