#include #include #include #define TK_Dlit 256 #define TK_Slit 257 #define TK_Float 258 #define TK_Id 259 #define TK_NameSep 260 #define TK_Arrow 261 #define TK_PlusPlus 262 #define TK_MinusMinus 263 #define TK_ArrowStar 264 #define TK_DotStar 265 #define TK_ShiftLeft 266 #define TK_ShiftRight 267 #define TK_IntegerDecimal 268 #define TK_IntegerOctal 269 #define TK_IntegerHex 270 #define TK_EqualsEquals 271 #define TK_NotEquals 272 #define TK_AndAnd 273 #define TK_OrOr 274 #define TK_MultAssign 275 #define TK_DivAssign 276 #define TK_PercentAssign 277 #define TK_PlusAssign 278 #define TK_MinusAssign 279 #define TK_AmpAssign 280 #define TK_CaretAssign 281 #define TK_BarAssign 282 #define TK_DotDotDot 283 #define TK_Whitespace 284 #define TK_Comment 285 int line = 1, col = 1; void token( int tok, char *data, int len ) { printf( "<%i> ", tok ); for ( int i = 0; i < len; i++ ) fputc( data[i], stdout ); fputc( '\n', stdout ); /* Count newlines and columns. This code is here mainly for having some * code in the token routine when commenting out the above output during * performance testing. */ for ( int i = 0; i < len; i ++ ) { if ( data[i] == '\n' ) { line += 1; col = 1; } else { col += 1; } } } #define BUFSIZE 8192 char buf[BUFSIZE]; void fill( int n ) { printf("fill(%i)\n", n); exit(1); } int main() { char *start, *p = buf, *lim = buf, *marker; int len, have, want, shift; int done = 0; #define YYCTYPE char #define YYCURSOR p #define YYLIMIT lim #define YYMARKER marker #define YYFILL(n) { \ if ( ! done ) { \ have = lim-start; \ if ( start > buf ) { \ shift = start-buf; \ memmove( buf, start, have ); \ start -= shift; \ p -= shift; \ lim -= shift; \ marker -= shift; \ } \ want = BUFSIZE - have - 1; \ len = fread( lim, 1, want, stdin ); \ lim += len; \ if ( len < want ) { \ *lim++ = 0; \ done = 1; \ } \ } \ } again: start = p; /*!re2c ANY = [\000-\377]; FRACTCONST = ( [0-9]* "." [0-9]+ ) | [0-9]+ "."; EXPONENT = [eE] [+\-]? [0-9]+; FLOATSUFFIX = [flFL]; "L"? "\'" ( ANY \ [\'\\\n] | "\\" ANY )* "\'" { token( TK_Slit, start, p-start ); goto again; } "L"? "\"" ( ANY \ [\"\\\n] | "\\" ANY )* "\"" { token( TK_Dlit, start, p-start ); goto again; } [a-zA-Z_][a-zA-Z0-9_]* { token( TK_Id, start, p-start ); goto again; } ( FRACTCONST EXPONENT? FLOATSUFFIX? ) | ( [0-9]+ EXPONENT FLOATSUFFIX? ) { token( TK_Float, start, p-start ); goto again; } ( "0" | [1-9][0-9]* ) [ulUL]* { token( TK_IntegerDecimal, start, p-start ); goto again; } "0" [0-9]+ [ulUL]* { token( TK_IntegerOctal, start, p-start ); goto again; } "0x" [0-9a-fA-F]+[ulUL]* { token( TK_IntegerHex, start, p-start ); goto again; } "::" { token( TK_NameSep, start, p-start ); goto again; } "==" { token( TK_EqualsEquals, start, p-start ); goto again; } "!=" { token( TK_NotEquals, start, p-start ); goto again; } "&&" { token( TK_AndAnd, start, p-start ); goto again; } "||" { token( TK_OrOr, start, p-start ); goto again; } "*=" { token( TK_MultAssign, start, p-start ); goto again; } "/=" { token( TK_DivAssign, start, p-start ); goto again; } "%=" { token( TK_PercentAssign, start, p-start ); goto again; } "+=" { token( TK_PlusAssign, start, p-start ); goto again; } "-=" { token( TK_MinusAssign, start, p-start ); goto again; } "&=" { token( TK_AmpAssign, start, p-start ); goto again; } "^=" { token( TK_CaretAssign, start, p-start ); goto again; } "|=" { token( TK_BarAssign, start, p-start ); goto again; } "++" { token( TK_PlusPlus, start, p-start ); goto again; } "--" { token( TK_MinusMinus, start, p-start ); goto again; } "->" { token( TK_Arrow, start, p-start ); goto again; } "->*" { token( TK_ArrowStar, start, p-start ); goto again; } ".*" { token( TK_DotStar, start, p-start ); goto again; } "..." { token( TK_DotDotDot, start, p-start ); goto again; } "/*" { goto comment; } "//" (ANY\"\n")* "\n" { goto again; } [\001-\040\177]+ { goto again; } [\041-\057\072-\100\133-\140\173-\176] { token( *start, start, p-start ); goto again; } "\000" { return 0; } */ comment: /*!re2c "*/" { goto again; } ANY { goto comment; } */ }