b6df2258ccfb6c4f47baafa3f8fa1cbff01b6acb
[external/ragel.git] / test / tokstart1.rl
1 /*
2  * @LANG: c++
3  */
4
5 #include <iostream>
6 #include <string.h>
7 using namespace std;
8
9 extern char buf[];
10
11 struct Scanner
12 {
13         int cs, act;
14         char *tokstart, *tokend;
15
16         // Initialize the machine. Invokes any init statement blocks. Returns 0
17         // if the machine begins in a non-accepting state and 1 if the machine
18         // begins in an accepting state.
19         void init( );
20
21         // Execute the machine on a block of data. Returns -1 if after processing
22         // the data, the machine is in the error state and can never accept, 0 if
23         // the machine is in a non-accepting state and 1 if the machine is in an
24         // accepting state.
25         int execute( char *data, int len );
26
27         // Indicate that there is no more data. Returns -1 if the machine finishes
28         // in the error state and does not accept, 0 if the machine finishes
29         // in any other non-accepting state and 1 if the machine finishes in an
30         // accepting state.
31         int finish( );
32 };
33
34 %%{
35         machine Scanner;
36
37         action to_act { 
38                 cout << "to:   fc = ";
39                 if ( fc == '\'' )
40                         cout << (int)fc;
41                 else
42                         cout << fc;
43                 cout << " tokstart = " << ( tokstart == 0 ? -1 : tokstart-buf ) << endl;
44         } 
45         action from_act {
46                 cout << "from: fc = ";
47                 if ( fc == '\'' )
48                         cout << (int)fc;
49                 else
50                         cout << fc;
51                 cout << " tokstart = " << ( tokstart == 0 ? -1 : tokstart-buf ) << endl;
52         }
53
54         c_comm := ( any* $0 '*/' @1 @{ fgoto main; } ) $~to_act $*from_act;
55         cxx_comm := ( any* $0 '\n' @1 @{ fgoto main; } ) $~to_act $*from_act;
56
57         main := |*
58
59         # Single and double literals.
60         ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) $~ to_act $* from_act;
61         ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) $~ to_act $* from_act;
62
63         # Identifiers
64         ( [a-zA-Z_] [a-zA-Z0-9_]* ) $~ to_act $* from_act;
65
66         # Floating literals.
67         fract_const = digit* '.' digit+ | digit+ '.';
68         exponent = [eE] [+\-]? digit+;
69         float_suffix = [flFL];
70
71         ( fract_const exponent? float_suffix? |
72                 digit+ exponent float_suffix? ) $~ to_act $* from_act;
73         
74         # Integer decimal. Leading part buffered by float.
75         ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) $~ to_act $* from_act
76
77         # Integer octal. Leading part buffered by float.
78         ( '0' [0-9]+ [ulUL]{0,2} ) $~ to_act $* from_act;
79
80         # Integer hex. Leading 0 buffered by float.
81         ( '0x' [0-9a-fA-F]+ [ulUL]{0,2} ) $~ to_act $* from_act;
82
83         # Three char compounds, first item already buffered. */
84         ( '...' ) $~ to_act $* from_act;
85
86         # Single char symbols.
87         ( punct - [_"'] ) $~ to_act $* from_act;
88
89         # Comments and whitespace.
90         ( '/*' ) $~ to_act $* from_act { fgoto c_comm; };
91         ( '//' ) $~ to_act $* from_act { fgoto cxx_comm; };
92
93         ( any - 33..126 )+ $~ to_act $* from_act;
94
95         *|;
96 }%%
97
98 %% write data;
99
100 void Scanner::init( )
101 {
102         %% write init;
103 }
104
105 int Scanner::execute( char *data, int len )
106 {
107         char *p = data;
108         char *pe = data + len;
109
110         %% write exec;
111
112         int have = 0;
113         if ( tokstart != 0 ) {
114                 have = pe - tokstart;
115                 memmove( data, tokstart, have );
116         }
117         return have;
118 }
119
120 int Scanner::finish( )
121 {
122         %% write eof;
123         if ( cs == Scanner_error )
124                 return -1;
125         if ( cs >= Scanner_first_final )
126                 return 1;
127         return 0;
128 }
129
130 void test( )
131 {
132         int len = strlen( buf );
133         Scanner scanner;
134
135         scanner.init();
136         scanner.execute( buf, len );
137         if ( scanner.cs == Scanner_error ) {
138                 /* Machine failed before finding a token. */
139                 cout << "PARSE ERROR" << endl;
140         }
141         scanner.finish();
142 }
143
144 char buf[4096];
145
146 int main()
147 {
148         strcpy( buf, 
149                 "a b 0.98 /*\n"
150                 "9 */'\\''//hi\n"
151                 "there\n"
152         );
153         test();
154         return 0;
155 }
156
157 #ifdef _____OUTPUT_____
158 from: fc = a tokstart = 0
159 to:   fc = a tokstart = 0
160 from: fc =   tokstart = 0
161 to:   fc = a tokstart = -1
162 from: fc =   tokstart = 1
163 to:   fc =   tokstart = 1
164 from: fc = b tokstart = 1
165 to:   fc =   tokstart = -1
166 from: fc = b tokstart = 2
167 to:   fc = b tokstart = 2
168 from: fc =   tokstart = 2
169 to:   fc = b tokstart = -1
170 from: fc =   tokstart = 3
171 to:   fc =   tokstart = 3
172 from: fc = 0 tokstart = 3
173 to:   fc =   tokstart = -1
174 from: fc = 0 tokstart = 4
175 to:   fc = 0 tokstart = 4
176 from: fc = . tokstart = 4
177 to:   fc = . tokstart = 4
178 from: fc = 9 tokstart = 4
179 to:   fc = 9 tokstart = 4
180 from: fc = 8 tokstart = 4
181 to:   fc = 8 tokstart = 4
182 from: fc =   tokstart = 4
183 to:   fc = 8 tokstart = -1
184 from: fc =   tokstart = 8
185 to:   fc =   tokstart = 8
186 from: fc = / tokstart = 8
187 to:   fc =   tokstart = -1
188 from: fc = / tokstart = 9
189 to:   fc = / tokstart = 9
190 from: fc = * tokstart = 9
191 to:   fc = * tokstart = -1
192 from: fc = 
193  tokstart = -1
194 to:   fc = 
195  tokstart = -1
196 from: fc = 9 tokstart = -1
197 to:   fc = 9 tokstart = -1
198 from: fc =   tokstart = -1
199 to:   fc =   tokstart = -1
200 from: fc = * tokstart = -1
201 to:   fc = * tokstart = -1
202 from: fc = / tokstart = -1
203 to:   fc = / tokstart = -1
204 from: fc = 39 tokstart = 16
205 to:   fc = 39 tokstart = 16
206 from: fc = \ tokstart = 16
207 to:   fc = \ tokstart = 16
208 from: fc = 39 tokstart = 16
209 to:   fc = 39 tokstart = 16
210 from: fc = 39 tokstart = 16
211 to:   fc = 39 tokstart = -1
212 from: fc = / tokstart = 20
213 to:   fc = / tokstart = 20
214 from: fc = / tokstart = 20
215 to:   fc = / tokstart = -1
216 from: fc = h tokstart = -1
217 to:   fc = h tokstart = -1
218 from: fc = i tokstart = -1
219 to:   fc = i tokstart = -1
220 from: fc = 
221  tokstart = -1
222 to:   fc = 
223  tokstart = -1
224 from: fc = t tokstart = 25
225 to:   fc = t tokstart = 25
226 from: fc = h tokstart = 25
227 to:   fc = h tokstart = 25
228 from: fc = e tokstart = 25
229 to:   fc = e tokstart = 25
230 from: fc = r tokstart = 25
231 to:   fc = r tokstart = 25
232 from: fc = e tokstart = 25
233 to:   fc = e tokstart = 25
234 from: fc = 
235  tokstart = 25
236 to:   fc = e tokstart = -1
237 from: fc = 
238  tokstart = 30
239 to:   fc = 
240  tokstart = 30
241 #endif