tokstart => ts and tokend => te
[ragel.git] / test / cppscan5.rl
blob057725a5b38d95288eed1e655e4133d9241e27fb
1 /*
2  * @LANG: d
3  */
5 /*
6  * Test in and out state actions.
7  */
9 import std.c.stdio;
10 import std.string;
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;
43 class Scanner 
45         int cs, act;
46         char *ts, te;
48         void token( int tok )
49         {
50                 char *data = ts;
51                 int len = te - ts;
52                 printf( "<%i> ", tok );
53                 for ( int i = 0; i < len; i++ )
54                         printf( "%c", data[i] );
55                 printf( "\n" );
56         }
58         %%{
60         machine Scanner;
62         main := |*
64         # Single and double literals.
65         ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) 
66                 => { token( TK_Slit );};
67         ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) 
68                 => { token( TK_Dlit );};
70         # Identifiers
71         ( [a-zA-Z_] [a-zA-Z0-9_]* ) 
72                 =>{ token( TK_Id );};
74         # Floating literals.
75         fract_const = digit* '.' digit+ | digit+ '.';
76         exponent = [eE] [+\-]? digit+;
77         float_suffix = [flFL];
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 );};
87         # Integer octal. Leading part buffered by float.
88         ( '0' [0-9]+ [ulUL]{0,2} ) 
89                 => { token( TK_IntegerOctal );};
91         # Integer hex. Leading 0 buffered by float.
92         ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) 
93                 => { token( TK_IntegerHex );};
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 );};
115         # Three char compounds, first item already buffered. */
116         '...' => { token( TK_DotDotDot );};
118         # Single char symbols.
119         ( punct - [_"'] ) => { token( ts[0] );};
121         action comment {
122                 token( TK_Comment );
123         }
125         # Comments and whitespace.
126         '/*' ( any* $0 '*/' @1 ) => comment;
127         '//' ( any* $0 '\n' @1 ) => comment;
128         ( any - 33..126 )+ => { token( TK_Whitespace );};
130         *|;
132         }%%
134         %% write data noprefix;
136         void init( )
137         {
138                 %% write init;
139         }
141         void execute( char* data, int len )
142         {
143                 char *p = data;
144                 char *pe = data + len;
145                 char *eof = pe;
147                 %% write exec;
148         }
150         // Indicate that there is no more data. Returns -1 if the machine finishes
151         // in the error state and does not accept, 0 if the machine finishes
152         // in any other non-accepting state and 1 if the machine finishes in an
153         // accepting state.
154         int finish( )
155         {
156                 if ( cs == error )
157                         return -1;
158                 if ( cs >= first_final )
159                         return 1;
160                 return 0;
161         }
164 static const int BUFSIZE = 12;
166 void test( char buf[] )
168         Scanner scanner = new Scanner();
169         scanner.init();
171         scanner.execute( buf.ptr, buf.length );
172         if ( scanner.cs == Scanner.error ) {
173                 /* Machine failed before finding a token. */
174                 printf("PARSE ERROR\n");
175         }
176         scanner.finish();
177         return 0;
180 int main()
182         test(
183                 "\"\\\"hi\" /*\n"
184                 "*/\n"
185                 "44 .44\n"
186                 "44. 44\n"
187                 "44 . 44\n"
188                 "44.44\n"
189                 "_hithere22"
190         );
192         test(
193                 "'\\''\"\\n\\d'\\\"\"\n"
194                 "hi\n"
195                 "99\n"
196                 ".99\n"
197                 "99e-4\n"
198                 "->*\n"
199                 "||\n"
200                 "0x98\n"
201                 "0x\n"
202                 "//\n"
203                 "/* * */"
204         );
206         test(
207                 "'\n"
208                 "'\n"
209         );
211         return 0;
214 /+ _____OUTPUT_____
215 <192> "\"hi"
216 <241>  
217 <242> /*
219 <241> 
221 <218> 44
222 <241>  
223 <194> .44
224 <241> 
226 <194> 44.
227 <241>  
228 <218> 44
229 <241> 
231 <218> 44
232 <241>  
233 <46> .
234 <241>  
235 <218> 44
236 <241> 
238 <194> 44.44
239 <241> 
241 <195> _hithere22
242 <193> '\''
243 <192> "\n\d'\""
244 <241> 
246 <195> hi
247 <241> 
249 <218> 99
250 <241> 
252 <194> .99
253 <241> 
255 <194> 99e-4
256 <241> 
258 <214> ->*
259 <241> 
261 <226> ||
262 <241> 
264 <220> 0x98
265 <241> 
267 <218> 0
268 <195> x
269 <241> 
271 <242> //
273 <242> /* * */
274 PARSE ERROR
275 +++++++++++++++++++/