The "tokstart" and "tokend" variables were changed to "ts" and "te".
[ragel.git] / test / lmgoto.rl
blobe8e82a8cbc044139e34ed42e754ebe3c8eeb59f2
1 /*
2  * @LANG: c++
3  */
5 #include <iostream>
6 #include <string.h>
7 using namespace std;
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
40 struct Scanner
42         int cs, act;
43         const char *ts, *te;
44         bool isCxx;
46         void token( int tok );
47         void run( const char *buf );
51 %%{
52         machine Scanner;
54         # Process all comments, relies on isCxx being set.
55         comment := |*
56                 '*/' {
57                         if ( ! isCxx )
58                                 fgoto main;
59                         else {
60                                 cout << "comm char: " << ts[0] << endl;
61                                 cout << "comm char: " << ts[1] << endl;
62                         }
63                 };
65                 '\n' {
66                         if ( isCxx )
67                                 fgoto main;
68                         else
69                                 cout << "comm char: " << ts[0] << endl;
70                 };
71                 
72                 any {
73                         cout << "comm char: " << ts[0] << endl;
74                 };
75         *|;
76         
77         main := |*
79         # Single and double literals.
80         ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) { token( TK_Slit );};
81         ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) { token( TK_Dlit );};
83         # Identifiers
84         ( [a-zA-Z_] [a-zA-Z0-9_]* ) { token( TK_Id ); };
86         # Floating literals.
87         fract_const = digit* '.' digit+ | digit+ '.';
88         exponent = [eE] [+\-]? digit+;
89         float_suffix = [flFL];
91         ( fract_const exponent? float_suffix? |
92                 digit+ exponent float_suffix? ) { token( TK_Float );};
93         
94         # Integer decimal. Leading part buffered by float.
95         ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) { token( TK_IntegerDecimal );};
97         # Integer octal. Leading part buffered by float.
98         ( '0' [0-9]+ [ulUL]{0,2} ) { token( TK_IntegerOctal );};
100         # Integer hex. Leading 0 buffered by float.
101         ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) { token( TK_IntegerHex );};
103         # Only buffer the second item, first buffered by symbol. */
104         '::' {token( TK_NameSep );};
105         '==' {token( TK_EqualsEquals );};
106         '!=' {token( TK_NotEquals );};
107         '&&' {token( TK_AndAnd );};
108         '||' {token( TK_OrOr );};
109         '*=' {token( TK_MultAssign );};
110         '/=' {token( TK_DivAssign );};
111         '%=' {token( TK_PercentAssign );};
112         '+=' {token( TK_PlusAssign );};
113         '-=' {token( TK_MinusAssign );};
114         '&=' {token( TK_AmpAssign );};
115         '^=' {token( TK_CaretAssign );};
116         '|=' {token( TK_BarAssign );};
117         '++' {token( TK_PlusPlus );};
118         '--' {token( TK_MinusMinus );};
119         '->' {token( TK_Arrow );};
120         '->*' {token( TK_ArrowStar );};
121         '.*' {token( TK_DotStar );};
123         # Three char compounds, first item already buffered. */
124         '...' { token( TK_DotDotDot );};
126         # Single char symbols.
127         ( punct - [_"'] ) { token( ts[0] );};
129         # Comments and whitespace. Handle these outside of the machine so that se
130         # don't end up buffering the comments.
131         '/*' { isCxx = false; fgoto comment; };
132         '//' { isCxx = true; fgoto comment; };
134         ( any - 33..126 )+ { token( TK_Whitespace );};
136         *|;
139 %% write data nofinal;
141 void Scanner::token( int tok )
143         const char *data = ts;
144         int len = te - ts;
145         cout << "<" << tok << "> ";
146         if ( data != 0 ) {
147                 for ( int i = 0; i < len; i++ )
148                         cout << data[i];
149         }
150         cout << '\n';
153 void Scanner::run( const char *buf )
155         int len = strlen( buf );
156         %% write init;
157         const char *p = buf;
158         const char *pe = buf + len;
159         const char *eof = pe;
160         %% write exec;
162         if ( cs == Scanner_error ) {
163                 /* Machine failed before finding a token. */
164                 cout << "PARSE ERROR" << endl;
165         }
168 int main()
170         Scanner scanner;
171         scanner.run(
172                 "//hello*/\n"
173                 "/*hi there*/ hello 0x88"
174         );
175         return 0;
178 #ifdef _____OUTPUT_____
179 comm char: h
180 comm char: e
181 comm char: l
182 comm char: l
183 comm char: o
184 comm char: *
185 comm char: /
186 comm char: h
187 comm char: i
188 comm char:  
189 comm char: t
190 comm char: h
191 comm char: e
192 comm char: r
193 comm char: e
194 <241>  
195 <195> hello
196 <241>  
197 <220> 0x88
198 #endif