13 #define TK_NameSep 197
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
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
47 char *tokstart, *tokend;
49 void token( int tok );
53 void execute( char *data, int len );
62 # Single and double literals.
63 ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" )
64 => { token( TK_Slit );};
65 ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' )
66 => { token( TK_Dlit );};
69 ( [a-zA-Z_] [a-zA-Z0-9_]* )
73 fract_const = digit* '.' digit+ | digit+ '.';
74 exponent = [eE] [+\-]? digit+;
75 float_suffix = [flFL];
77 ( fract_const exponent? float_suffix? |
78 digit+ exponent float_suffix? )
79 => { token( TK_Float );};
81 # Integer decimal. Leading part buffered by float.
82 ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} )
83 => { token( TK_IntegerDecimal );};
85 # Integer octal. Leading part buffered by float.
86 ( '0' [0-9]+ [ulUL]{0,2} )
87 => { token( TK_IntegerOctal );};
89 # Integer hex. Leading 0 buffered by float.
90 ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) )
91 => { token( TK_IntegerHex );};
93 # Only buffer the second item, first buffered by symbol. */
94 '::' => {token( TK_NameSep );};
95 '==' => {token( TK_EqualsEquals );};
96 '!=' => {token( TK_NotEquals );};
97 '&&' => {token( TK_AndAnd );};
98 '||' => {token( TK_OrOr );};
99 '*=' => {token( TK_MultAssign );};
100 '/=' => {token( TK_DivAssign );};
101 '%=' => {token( TK_PercentAssign );};
102 '+=' => {token( TK_PlusAssign );};
103 '-=' => {token( TK_MinusAssign );};
104 '&=' => {token( TK_AmpAssign );};
105 '^=' => {token( TK_CaretAssign );};
106 '|=' => {token( TK_BarAssign );};
107 '++' => {token( TK_PlusPlus );};
108 '--' => {token( TK_MinusMinus );};
109 '->' => {token( TK_Arrow );};
110 '->*' => {token( TK_ArrowStar );};
111 '.*' => {token( TK_DotStar );};
113 # Three char compounds, first item already buffered. */
114 '...' => { token( TK_DotDotDot );};
116 # Single char symbols.
117 ( punct - [_"'] ) => { token( tokstart[0] );};
123 # Comments and whitespace.
124 '/*' ( any* $0 '*/' @1 ) => comment;
125 '//' ( any* $0 '\n' @1 ) => comment;
126 ( any - 33..126 )+ => { token( TK_Whitespace );};
133 void Scanner::init( )
138 /* Returns the count of bytes still in the buffer
139 * (shifted to the biginning) */
140 void Scanner::execute( char *data, int len )
143 char *pe = data + len;
148 int Scanner::finish( )
151 if ( cs == Scanner_error )
153 if ( cs >= Scanner_first_final )
159 void Scanner::token( int tok )
161 const char *data = tokstart;
162 int len = tokend - tokstart;
163 cout << "<" << tok << "> ";
164 for ( int i = 0; i < len; i++ )
169 void test( char *buf )
171 int len = strlen( buf );
172 std::ios::sync_with_stdio(false);
176 scanner.execute( buf, len );
177 if ( scanner.cs == Scanner_error ) {
178 /* Machine failed before finding a token. */
179 cout << "PARSE ERROR" << endl;
182 /* FIXME: Last token may get lost. */
200 "'\\''\"\\n\\d'\\\"\"\n"
220 #ifdef _____OUTPUT_____