12 #define TK_NameSep 197
14 #define TK_PlusPlus 212
15 #define TK_MinusMinus 213
16 #define TK_ArrowStar 214
17 #define TK_DotStar 215
18 #define TK_ShiftLeft 216
19 #define TK_ShiftRight 217
20 #define TK_IntegerDecimal 218
21 #define TK_IntegerOctal 219
22 #define TK_IntegerHex 220
23 #define TK_EqualsEquals 223
24 #define TK_NotEquals 224
27 #define TK_MultAssign 227
28 #define TK_DivAssign 228
29 #define TK_PercentAssign 229
30 #define TK_PlusAssign 230
31 #define TK_MinusAssign 231
32 #define TK_AmpAssign 232
33 #define TK_CaretAssign 233
34 #define TK_BarAssign 234
35 #define TK_DotDotDot 240
36 #define TK_Whitespace 241
37 #define TK_Comment 242
42 char buf[BUFSIZE], *tokstart, *tokend;
43 void token( char *data, int len );
50 // Initialize the machine. Invokes any init statement blocks. Returns 0
51 // if the machine begins in a non-accepting state and 1 if the machine
52 // begins in an accepting state.
55 // Execute the machine on a block of data. Returns -1 if after processing
56 // the data, the machine is in the error state and can never accept, 0 if
57 // the machine is in a non-accepting state and 1 if the machine is in an
59 int execute( char *data, int len );
61 // Indicate that there is no more data. Returns -1 if the machine finishes
62 // in the error state and does not accept, 0 if the machine finishes
63 // in any other non-accepting state and 1 if the machine finishes in an
71 # Single and double literals.
72 slit = ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) @{tok = TK_Slit;};
73 dlit = ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) @{tok = TK_Dlit;};
76 id = ( [a-zA-Z_] [a-zA-Z0-9_]* ) @{tok = TK_Id;};
79 fract_const = digit* '.' digit+ | digit+ '.';
80 exponent = [eE] [+\-]? digit+;
81 float_suffix = [flFL];
83 ( fract_const exponent? float_suffix? |
84 digit+ exponent float_suffix? ) @{tok = TK_Float;};
86 # Integer decimal. Leading part buffered by float.
87 integer_decimal = ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) @{tok = TK_IntegerDecimal;};
89 # Integer octal. Leading part buffered by float.
90 integer_octal = ( '0' [0-9]+ [ulUL]{0,2} ) @{tok = TK_IntegerOctal;};
92 # Integer hex. Leading 0 buffered by float.
93 integer_hex = ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) @{tok = TK_IntegerHex;};
95 # Only buffer the second item, first buffered by symbol. */
96 namesep = '::' @{tok = TK_NameSep;};
97 deqs = '==' @{tok = TK_EqualsEquals;};
98 neqs = '!=' @{tok = TK_NotEquals;};
99 and_and = '&&' @{tok = TK_AndAnd;};
100 or_or = '||' @{tok = TK_OrOr;};
101 mult_assign = '*=' @{tok = TK_MultAssign;};
102 div_assign = '/=' @{tok = TK_DivAssign;};
103 percent_assign = '%=' @{tok = TK_PercentAssign;};
104 plus_assign = '+=' @{tok = TK_PlusAssign;};
105 minus_assign = '-=' @{tok = TK_MinusAssign;};
106 amp_assign = '&=' @{tok = TK_AmpAssign;};
107 caret_assign = '^=' @{tok = TK_CaretAssign;};
108 bar_assign = '|=' @{tok = TK_BarAssign;};
109 plus_plus = '++' @{tok = TK_PlusPlus;};
110 minus_minus = '--' @{tok = TK_MinusMinus;};
111 arrow = '->' @{tok = TK_Arrow;};
112 arrow_star = '->*' @{tok = TK_ArrowStar;};
113 dot_star = '.*' @{tok = TK_DotStar;};
115 # Three char compounds, first item already buffered. */
116 dot_dot_dot = '...' @{tok = TK_DotDotDot;};
119 compound = namesep | deqs | neqs | and_and | or_or | mult_assign |
120 div_assign | percent_assign | plus_assign | minus_assign |
121 amp_assign | caret_assign | bar_assign | plus_plus | minus_minus |
122 arrow | arrow_star | dot_star | dot_dot_dot;
124 # Single char symbols.
125 symbol = ( punct - [_"'] ) @{tok = fc;};
131 # Comments and whitespace.
132 commc = '/*' @discard ( any* $0 '*/' @1 ) @{tok = TK_Comment;};
133 commcc = '//' @discard ( any* $0 '\n' @1 ) @{tok = TK_Comment;};
134 whitespace = ( any - 33..126 )+ >discard @{tok = TK_Whitespace;};
136 # All outside code tokens.
138 id | slit | dlit | float | integer_decimal |
139 integer_octal | integer_hex | compound | symbol |
140 commc | commcc | whitespace );
146 if ( tok == TK_Comment || tok == TK_Whitespace ) {
147 /* Reset comment status, don't send. */
150 /* Restart right at the error point if consuming whitespace or
151 * a comment. Consume may have spanned multiple buffers. */
155 /* Send the token. */
156 token( tokstart, tokend - tokstart + 1 );
158 /* Restart right after the token. */
168 main := tokens >{tokstart=fpc;} @{tokend=fpc;} $!onError;
183 int Scanner::execute( char *data, int len )
186 char *pe = data + len;
190 if ( cs == Scanner_error )
192 if ( cs >= Scanner_first_final )
197 int Scanner::finish( )
200 if ( cs == Scanner_error )
202 if ( cs >= Scanner_first_final )
208 void token( char *data, int len )
210 cout << "<" << tok << "> ";
211 for ( int i = 0; i < len; i++ )
216 void test( char * data )
220 scanner.execute( data, strlen(data) );
222 if ( tok != 0 && tok != TK_Comment && tok != TK_Whitespace )
223 token( tokstart, tokend - tokstart + 1 );
234 "/* Move ranges to the singles list. */\n"
235 "void RedFsmAp::move( RedStateAp *state )\n"
237 " RedTranst &range = state->outRange;\n"
238 " for ( int rpos = 0; rpos < range.length(); ) {\n"
239 " if ( can( range, rpos ) ) {\n"
240 " while ( range[rpos].value != range[rpos+1].value ) {\n"
241 " single.append( range[rpos+1] );\n"
244 " range[rpos].highKey = range[rpos+1].highKey;\n"
246 " else if ( keyOps->span( range[rpos].lowKey, range[rpos].highKey ) == 1 ) {\n"
247 " single.append( range[rpos] );\n"
263 #ifdef _____OUTPUT_____