update(add) packaging directory and spec file from OBSTF:Private, OBS
[external/ragel.git] / test / lmgoto.rl
1 /*
2  * @LANG: c++
3  */
4
5 #include <iostream>
6 #include <string.h>
7 using namespace std;
8
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
39
40 struct Scanner
41 {
42         int cs, act;
43         const char *ts, *te;
44         bool isCxx;
45
46         void token( int tok );
47         void run( const char *buf );
48 };
49
50
51 %%{
52         machine Scanner;
53
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                 };
64
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 := |*
78
79         # Single and double literals.
80         ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) { token( TK_Slit );};
81         ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) { token( TK_Dlit );};
82
83         # Identifiers
84         ( [a-zA-Z_] [a-zA-Z0-9_]* ) { token( TK_Id ); };
85
86         # Floating literals.
87         fract_const = digit* '.' digit+ | digit+ '.';
88         exponent = [eE] [+\-]? digit+;
89         float_suffix = [flFL];
90
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 );};
96
97         # Integer octal. Leading part buffered by float.
98         ( '0' [0-9]+ [ulUL]{0,2} ) { token( TK_IntegerOctal );};
99
100         # Integer hex. Leading 0 buffered by float.
101         ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) { token( TK_IntegerHex );};
102
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 );};
122
123         # Three char compounds, first item already buffered. */
124         '...' { token( TK_DotDotDot );};
125
126         # Single char symbols.
127         ( punct - [_"'] ) { token( ts[0] );};
128
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; };
133
134         ( any - 33..126 )+ { token( TK_Whitespace );};
135
136         *|;
137 }%%
138
139 %% write data nofinal;
140
141 void Scanner::token( int tok )
142 {
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';
151 }
152
153 void Scanner::run( const char *buf )
154 {
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;
161
162         if ( cs == Scanner_error ) {
163                 /* Machine failed before finding a token. */
164                 cout << "PARSE ERROR" << endl;
165         }
166 }
167
168 int main()
169 {
170         Scanner scanner;
171         scanner.run(
172                 "//hello*/\n"
173                 "/*hi there*/ hello 0x88"
174         );
175         return 0;
176 }
177
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