Removed the write eof command.
[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         if ( cs == Scanner_error )
123                 return -1;
124         if ( cs >= Scanner_first_final )
125                 return 1;
126         return 0;
127 }
128
129 void test( )
130 {
131         int len = strlen( buf );
132         Scanner scanner;
133
134         scanner.init();
135         scanner.execute( buf, len );
136         if ( scanner.cs == Scanner_error ) {
137                 /* Machine failed before finding a token. */
138                 cout << "PARSE ERROR" << endl;
139         }
140         scanner.finish();
141 }
142
143 char buf[4096];
144
145 int main()
146 {
147         strcpy( buf, 
148                 "a b 0.98 /*\n"
149                 "9 */'\\''//hi\n"
150                 "there\n"
151         );
152         test();
153         return 0;
154 }
155
156 #ifdef _____OUTPUT_____
157 from: fc = a tokstart = 0
158 to:   fc = a tokstart = 0
159 from: fc =   tokstart = 0
160 to:   fc = a tokstart = -1
161 from: fc =   tokstart = 1
162 to:   fc =   tokstart = 1
163 from: fc = b tokstart = 1
164 to:   fc =   tokstart = -1
165 from: fc = b tokstart = 2
166 to:   fc = b tokstart = 2
167 from: fc =   tokstart = 2
168 to:   fc = b tokstart = -1
169 from: fc =   tokstart = 3
170 to:   fc =   tokstart = 3
171 from: fc = 0 tokstart = 3
172 to:   fc =   tokstart = -1
173 from: fc = 0 tokstart = 4
174 to:   fc = 0 tokstart = 4
175 from: fc = . tokstart = 4
176 to:   fc = . tokstart = 4
177 from: fc = 9 tokstart = 4
178 to:   fc = 9 tokstart = 4
179 from: fc = 8 tokstart = 4
180 to:   fc = 8 tokstart = 4
181 from: fc =   tokstart = 4
182 to:   fc = 8 tokstart = -1
183 from: fc =   tokstart = 8
184 to:   fc =   tokstart = 8
185 from: fc = / tokstart = 8
186 to:   fc =   tokstart = -1
187 from: fc = / tokstart = 9
188 to:   fc = / tokstart = 9
189 from: fc = * tokstart = 9
190 to:   fc = * tokstart = -1
191 from: fc = 
192  tokstart = -1
193 to:   fc = 
194  tokstart = -1
195 from: fc = 9 tokstart = -1
196 to:   fc = 9 tokstart = -1
197 from: fc =   tokstart = -1
198 to:   fc =   tokstart = -1
199 from: fc = * tokstart = -1
200 to:   fc = * tokstart = -1
201 from: fc = / tokstart = -1
202 to:   fc = / tokstart = -1
203 from: fc = 39 tokstart = 16
204 to:   fc = 39 tokstart = 16
205 from: fc = \ tokstart = 16
206 to:   fc = \ tokstart = 16
207 from: fc = 39 tokstart = 16
208 to:   fc = 39 tokstart = 16
209 from: fc = 39 tokstart = 16
210 to:   fc = 39 tokstart = -1
211 from: fc = / tokstart = 20
212 to:   fc = / tokstart = 20
213 from: fc = / tokstart = 20
214 to:   fc = / tokstart = -1
215 from: fc = h tokstart = -1
216 to:   fc = h tokstart = -1
217 from: fc = i tokstart = -1
218 to:   fc = i tokstart = -1
219 from: fc = 
220  tokstart = -1
221 to:   fc = 
222  tokstart = -1
223 from: fc = t tokstart = 25
224 to:   fc = t tokstart = 25
225 from: fc = h tokstart = 25
226 to:   fc = h tokstart = 25
227 from: fc = e tokstart = 25
228 to:   fc = e tokstart = 25
229 from: fc = r tokstart = 25
230 to:   fc = r tokstart = 25
231 from: fc = e tokstart = 25
232 to:   fc = e tokstart = 25
233 from: fc = 
234  tokstart = 25
235 to:   fc = e tokstart = -1
236 from: fc = 
237  tokstart = 30
238 to:   fc = 
239  tokstart = 30
240 #endif