| 1 | /*============================================================================= |
|---|
| 2 | Boost.Wave: A Standard compliant C++ preprocessor library |
|---|
| 3 | |
|---|
| 4 | Sample: IDL lexer |
|---|
| 5 | |
|---|
| 6 | http://www.boost.org/ |
|---|
| 7 | |
|---|
| 8 | Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost |
|---|
| 9 | Software License, Version 1.0. (See accompanying file |
|---|
| 10 | LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
|---|
| 11 | =============================================================================*/ |
|---|
| 12 | |
|---|
| 13 | #include <ctime> |
|---|
| 14 | #include <cstdlib> |
|---|
| 15 | #include <cstdio> |
|---|
| 16 | #include <cstring> |
|---|
| 17 | #include <sys/types.h> |
|---|
| 18 | #include <sys/stat.h> |
|---|
| 19 | #include <fcntl.h> |
|---|
| 20 | |
|---|
| 21 | #include <boost/config.hpp> |
|---|
| 22 | |
|---|
| 23 | #if defined(BOOST_HAS_UNISTD_H) |
|---|
| 24 | #include <unistd.h> |
|---|
| 25 | #else |
|---|
| 26 | #include <io.h> |
|---|
| 27 | #endif |
|---|
| 28 | |
|---|
| 29 | #include <boost/assert.hpp> |
|---|
| 30 | #include <boost/detail/workaround.hpp> |
|---|
| 31 | |
|---|
| 32 | // reuse the token ids and re2c helper functions from the default C++ lexer |
|---|
| 33 | #include <boost/wave/token_ids.hpp> |
|---|
| 34 | #include <boost/wave/cpplexer/re2clex/aq.hpp> |
|---|
| 35 | #include <boost/wave/cpplexer/re2clex/scanner.hpp> |
|---|
| 36 | |
|---|
| 37 | #include "idl_re.hpp" |
|---|
| 38 | |
|---|
| 39 | #if defined(_MSC_VER) && !defined(__COMO__) |
|---|
| 40 | #pragma warning (disable: 4101) // 'foo' : unreferenced local variable |
|---|
| 41 | #pragma warning (disable: 4102) // 'foo' : unreferenced label |
|---|
| 42 | #endif |
|---|
| 43 | |
|---|
| 44 | #define BSIZE 196608 |
|---|
| 45 | |
|---|
| 46 | #define YYCTYPE uchar |
|---|
| 47 | #define YYCURSOR cursor |
|---|
| 48 | #define YYLIMIT s->lim |
|---|
| 49 | #define YYMARKER s->ptr |
|---|
| 50 | #define YYFILL(n) {cursor = fill(s, cursor);} |
|---|
| 51 | |
|---|
| 52 | //#define RET(i) {s->cur = cursor; return (i);} |
|---|
| 53 | #define RET(i) \ |
|---|
| 54 | { \ |
|---|
| 55 | s->line += count_backslash_newlines(s, cursor); \ |
|---|
| 56 | s->cur = cursor; \ |
|---|
| 57 | return (i); \ |
|---|
| 58 | } \ |
|---|
| 59 | /**/ |
|---|
| 60 | |
|---|
| 61 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 62 | namespace boost { |
|---|
| 63 | namespace wave { |
|---|
| 64 | namespace idllexer { |
|---|
| 65 | namespace re2clex { |
|---|
| 66 | |
|---|
| 67 | #define RE2C_ASSERT BOOST_ASSERT |
|---|
| 68 | |
|---|
| 69 | int |
|---|
| 70 | get_one_char(boost::wave::cpplexer::re2clex::Scanner *s) |
|---|
| 71 | { |
|---|
| 72 | using namespace boost::wave::cpplexer::re2clex; |
|---|
| 73 | if (s->fd != -1) { |
|---|
| 74 | uchar val; |
|---|
| 75 | |
|---|
| 76 | if (read(s->fd, &val, sizeof(val))) |
|---|
| 77 | return val; |
|---|
| 78 | } |
|---|
| 79 | else if (0 != s->act) { |
|---|
| 80 | RE2C_ASSERT(s->first != 0 && s->last != 0); |
|---|
| 81 | RE2C_ASSERT(s->first <= s->act && s->act <= s->last); |
|---|
| 82 | if (s->act < s->last) |
|---|
| 83 | return *(s->act)++; |
|---|
| 84 | } |
|---|
| 85 | return -1; |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | std::ptrdiff_t |
|---|
| 89 | rewind_stream (boost::wave::cpplexer::re2clex::Scanner *s, int cnt) |
|---|
| 90 | { |
|---|
| 91 | if (s->fd != -1) { |
|---|
| 92 | return lseek(s->fd, cnt, SEEK_CUR); |
|---|
| 93 | } |
|---|
| 94 | else if (0 != s->act) { |
|---|
| 95 | RE2C_ASSERT(s->first != 0 && s->last != 0); |
|---|
| 96 | s->act += cnt; |
|---|
| 97 | RE2C_ASSERT(s->first <= s->act && s->act <= s->last); |
|---|
| 98 | return s->act - s->first; |
|---|
| 99 | } |
|---|
| 100 | return 0; |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | std::size_t |
|---|
| 104 | get_first_eol_offset(boost::wave::cpplexer::re2clex::Scanner* s) |
|---|
| 105 | { |
|---|
| 106 | if (!AQ_EMPTY(s->eol_offsets)) |
|---|
| 107 | { |
|---|
| 108 | return s->eol_offsets->queue[s->eol_offsets->head]; |
|---|
| 109 | } |
|---|
| 110 | else |
|---|
| 111 | { |
|---|
| 112 | return (unsigned int)-1; |
|---|
| 113 | } |
|---|
| 114 | } |
|---|
| 115 | |
|---|
| 116 | void |
|---|
| 117 | adjust_eol_offsets(boost::wave::cpplexer::re2clex::Scanner* s, |
|---|
| 118 | std::size_t adjustment) |
|---|
| 119 | { |
|---|
| 120 | boost::wave::cpplexer::re2clex::aq_queue q; |
|---|
| 121 | std::size_t i; |
|---|
| 122 | |
|---|
| 123 | if (!s->eol_offsets) |
|---|
| 124 | s->eol_offsets = boost::wave::cpplexer::re2clex::aq_create(); |
|---|
| 125 | |
|---|
| 126 | q = s->eol_offsets; |
|---|
| 127 | |
|---|
| 128 | if (AQ_EMPTY(q)) |
|---|
| 129 | return; |
|---|
| 130 | |
|---|
| 131 | i = q->head; |
|---|
| 132 | while (i != q->tail) |
|---|
| 133 | { |
|---|
| 134 | if (adjustment > q->queue[i]) |
|---|
| 135 | q->queue[i] = 0; |
|---|
| 136 | else |
|---|
| 137 | q->queue[i] -= adjustment; |
|---|
| 138 | ++i; |
|---|
| 139 | if (i == q->max_size) |
|---|
| 140 | i = 0; |
|---|
| 141 | } |
|---|
| 142 | if (adjustment > q->queue[i]) |
|---|
| 143 | q->queue[i] = 0; |
|---|
| 144 | else |
|---|
| 145 | q->queue[i] -= adjustment; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | int |
|---|
| 149 | count_backslash_newlines(boost::wave::cpplexer::re2clex::Scanner *s, |
|---|
| 150 | boost::wave::cpplexer::re2clex::uchar *cursor) |
|---|
| 151 | { |
|---|
| 152 | using namespace boost::wave::cpplexer::re2clex; |
|---|
| 153 | |
|---|
| 154 | std::size_t diff, offset; |
|---|
| 155 | int skipped = 0; |
|---|
| 156 | |
|---|
| 157 | /* figure out how many backslash-newlines skipped over unknowingly. */ |
|---|
| 158 | diff = cursor - s->bot; |
|---|
| 159 | offset = get_first_eol_offset(s); |
|---|
| 160 | while (offset <= diff && offset != (unsigned int)-1) |
|---|
| 161 | { |
|---|
| 162 | skipped++; |
|---|
| 163 | boost::wave::cpplexer::re2clex::aq_pop(s->eol_offsets); |
|---|
| 164 | offset = get_first_eol_offset(s); |
|---|
| 165 | } |
|---|
| 166 | return skipped; |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | bool is_backslash( |
|---|
| 170 | boost::wave::cpplexer::re2clex::uchar *p, |
|---|
| 171 | boost::wave::cpplexer::re2clex::uchar *end, int &len) |
|---|
| 172 | { |
|---|
| 173 | if (*p == '\\') { |
|---|
| 174 | len = 1; |
|---|
| 175 | return true; |
|---|
| 176 | } |
|---|
| 177 | else if (*p == '?' && *(p+1) == '?' && (p+2 < end && *(p+2) == '/')) { |
|---|
| 178 | len = 3; |
|---|
| 179 | return true; |
|---|
| 180 | } |
|---|
| 181 | return false; |
|---|
| 182 | } |
|---|
| 183 | |
|---|
| 184 | boost::wave::cpplexer::re2clex::uchar * |
|---|
| 185 | fill(boost::wave::cpplexer::re2clex::Scanner *s, |
|---|
| 186 | boost::wave::cpplexer::re2clex::uchar *cursor) |
|---|
| 187 | { |
|---|
| 188 | using namespace std; // some systems have memcpy etc. in namespace std |
|---|
| 189 | using namespace boost::wave::cpplexer::re2clex; |
|---|
| 190 | |
|---|
| 191 | if(!s->eof) |
|---|
| 192 | { |
|---|
| 193 | uchar* p; |
|---|
| 194 | std::ptrdiff_t cnt = s->tok - s->bot; |
|---|
| 195 | if(cnt) |
|---|
| 196 | { |
|---|
| 197 | memcpy(s->bot, s->tok, s->lim - s->tok); |
|---|
| 198 | s->tok = s->bot; |
|---|
| 199 | s->ptr -= cnt; |
|---|
| 200 | cursor -= cnt; |
|---|
| 201 | s->lim -= cnt; |
|---|
| 202 | adjust_eol_offsets(s, cnt); |
|---|
| 203 | } |
|---|
| 204 | |
|---|
| 205 | if((s->top - s->lim) < BSIZE) |
|---|
| 206 | { |
|---|
| 207 | uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar)); |
|---|
| 208 | if (buf == 0) |
|---|
| 209 | { |
|---|
| 210 | using namespace std; // some systems have printf in std |
|---|
| 211 | if (0 != s->error_proc) |
|---|
| 212 | (*s->error_proc)(s, "Out of memory!"); |
|---|
| 213 | else |
|---|
| 214 | printf("Out of memory!\n"); |
|---|
| 215 | |
|---|
| 216 | /* get the scanner to stop */ |
|---|
| 217 | *cursor = 0; |
|---|
| 218 | return cursor; |
|---|
| 219 | } |
|---|
| 220 | |
|---|
| 221 | memcpy(buf, s->tok, s->lim - s->tok); |
|---|
| 222 | s->tok = buf; |
|---|
| 223 | s->ptr = &buf[s->ptr - s->bot]; |
|---|
| 224 | cursor = &buf[cursor - s->bot]; |
|---|
| 225 | s->lim = &buf[s->lim - s->bot]; |
|---|
| 226 | s->top = &s->lim[BSIZE]; |
|---|
| 227 | free(s->bot); |
|---|
| 228 | s->bot = buf; |
|---|
| 229 | } |
|---|
| 230 | |
|---|
| 231 | if (s->fd != -1) { |
|---|
| 232 | if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE) |
|---|
| 233 | { |
|---|
| 234 | s->eof = &s->lim[cnt]; *(s->eof)++ = '\0'; |
|---|
| 235 | } |
|---|
| 236 | } |
|---|
| 237 | else if (s->act != 0) { |
|---|
| 238 | cnt = s->last - s->act; |
|---|
| 239 | if (cnt > BSIZE) |
|---|
| 240 | cnt = BSIZE; |
|---|
| 241 | memcpy(s->lim, s->act, cnt); |
|---|
| 242 | s->act += cnt; |
|---|
| 243 | if (cnt != BSIZE) |
|---|
| 244 | { |
|---|
| 245 | s->eof = &s->lim[cnt]; *(s->eof)++ = '\0'; |
|---|
| 246 | } |
|---|
| 247 | } |
|---|
| 248 | |
|---|
| 249 | /* backslash-newline erasing time */ |
|---|
| 250 | |
|---|
| 251 | /* first scan for backslash-newline and erase them */ |
|---|
| 252 | for (p = s->lim; p < s->lim + cnt - 2; ++p) |
|---|
| 253 | { |
|---|
| 254 | int len = 0; |
|---|
| 255 | if (is_backslash(p, s->lim + cnt, len)) |
|---|
| 256 | { |
|---|
| 257 | if (*(p+len) == '\n') |
|---|
| 258 | { |
|---|
| 259 | int offset = len + 1; |
|---|
| 260 | memmove(p, p + offset, s->lim + cnt - p - offset); |
|---|
| 261 | cnt -= offset; |
|---|
| 262 | --p; |
|---|
| 263 | aq_enqueue(s->eol_offsets, p - s->bot + 1); |
|---|
| 264 | } |
|---|
| 265 | else if (*(p+len) == '\r') |
|---|
| 266 | { |
|---|
| 267 | if (*(p+len+1) == '\n') |
|---|
| 268 | { |
|---|
| 269 | int offset = len + 2; |
|---|
| 270 | memmove(p, p + offset, s->lim + cnt - p - offset); |
|---|
| 271 | cnt -= offset; |
|---|
| 272 | --p; |
|---|
| 273 | } |
|---|
| 274 | else |
|---|
| 275 | { |
|---|
| 276 | int offset = len + 1; |
|---|
| 277 | memmove(p, p + offset, s->lim + cnt - p - offset); |
|---|
| 278 | cnt -= offset; |
|---|
| 279 | --p; |
|---|
| 280 | } |
|---|
| 281 | aq_enqueue(s->eol_offsets, p - s->bot + 1); |
|---|
| 282 | } |
|---|
| 283 | } |
|---|
| 284 | } |
|---|
| 285 | |
|---|
| 286 | /* FIXME: the following code should be fixed to recognize correctly the |
|---|
| 287 | trigraph backslash token */ |
|---|
| 288 | |
|---|
| 289 | /* check to see if what we just read ends in a backslash */ |
|---|
| 290 | if (cnt >= 2) |
|---|
| 291 | { |
|---|
| 292 | uchar last = s->lim[cnt-1]; |
|---|
| 293 | uchar last2 = s->lim[cnt-2]; |
|---|
| 294 | /* check \ EOB */ |
|---|
| 295 | if (last == '\\') |
|---|
| 296 | { |
|---|
| 297 | int next = get_one_char(s); |
|---|
| 298 | /* check for \ \n or \ \r or \ \r \n straddling the border */ |
|---|
| 299 | if (next == '\n') |
|---|
| 300 | { |
|---|
| 301 | --cnt; /* chop the final \, we've already read the \n. */ |
|---|
| 302 | boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets, |
|---|
| 303 | cnt + (s->lim - s->bot)); |
|---|
| 304 | } |
|---|
| 305 | else if (next == '\r') |
|---|
| 306 | { |
|---|
| 307 | int next2 = get_one_char(s); |
|---|
| 308 | if (next2 == '\n') |
|---|
| 309 | { |
|---|
| 310 | --cnt; /* skip the backslash */ |
|---|
| 311 | } |
|---|
| 312 | else |
|---|
| 313 | { |
|---|
| 314 | /* rewind one, and skip one char */ |
|---|
| 315 | rewind_stream(s, -1); |
|---|
| 316 | --cnt; |
|---|
| 317 | } |
|---|
| 318 | boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets, |
|---|
| 319 | cnt + (s->lim - s->bot)); |
|---|
| 320 | } |
|---|
| 321 | else if (next != -1) /* -1 means end of file */ |
|---|
| 322 | { |
|---|
| 323 | /* next was something else, so rewind the stream */ |
|---|
| 324 | lseek(s->fd, -1, SEEK_CUR); |
|---|
| 325 | } |
|---|
| 326 | } |
|---|
| 327 | /* check \ \r EOB */ |
|---|
| 328 | else if (last == '\r' && last2 == '\\') |
|---|
| 329 | { |
|---|
| 330 | int next = get_one_char(s); |
|---|
| 331 | if (next == '\n') |
|---|
| 332 | { |
|---|
| 333 | cnt -= 2; /* skip the \ \r */ |
|---|
| 334 | } |
|---|
| 335 | else |
|---|
| 336 | { |
|---|
| 337 | /* rewind one, and skip two chars */ |
|---|
| 338 | rewind_stream(s, -1); |
|---|
| 339 | cnt -= 2; |
|---|
| 340 | } |
|---|
| 341 | boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets, |
|---|
| 342 | cnt + (s->lim - s->bot)); |
|---|
| 343 | } |
|---|
| 344 | /* check \ \n EOB */ |
|---|
| 345 | else if (last == '\n' && last2 == '\\') |
|---|
| 346 | { |
|---|
| 347 | cnt -= 2; |
|---|
| 348 | boost::wave::cpplexer::re2clex::aq_enqueue(s->eol_offsets, |
|---|
| 349 | cnt + (s->lim - s->bot)); |
|---|
| 350 | } |
|---|
| 351 | } |
|---|
| 352 | |
|---|
| 353 | s->lim += cnt; |
|---|
| 354 | if (s->eof) /* eof needs adjusting if we erased backslash-newlines */ |
|---|
| 355 | { |
|---|
| 356 | s->eof = s->lim; |
|---|
| 357 | *(s->eof)++ = '\0'; |
|---|
| 358 | } |
|---|
| 359 | } |
|---|
| 360 | return cursor; |
|---|
| 361 | } |
|---|
| 362 | |
|---|
| 363 | boost::wave::token_id |
|---|
| 364 | scan(boost::wave::cpplexer::re2clex::Scanner *s) |
|---|
| 365 | { |
|---|
| 366 | using namespace boost::wave::cpplexer::re2clex; |
|---|
| 367 | |
|---|
| 368 | uchar *cursor = s->tok = s->cur; |
|---|
| 369 | |
|---|
| 370 | /*!re2c |
|---|
| 371 | any = [\t\v\f\r\n\040-\377]; |
|---|
| 372 | OctalDigit = [0-7]; |
|---|
| 373 | Digit = [0-9]; |
|---|
| 374 | HexDigit = [a-fA-F0-9]; |
|---|
| 375 | ExponentPart = [Ee] [+-]? Digit+; |
|---|
| 376 | FractionalConstant = (Digit* "." Digit+) | (Digit+ "."); |
|---|
| 377 | FloatingSuffix = [fF][lL]?|[lL][fF]?; |
|---|
| 378 | IntegerSuffix = [uU][lL]?|[lL][uU]?; |
|---|
| 379 | FixedPointSuffix = [dD]; |
|---|
| 380 | Backslash = [\\]|"??/"; |
|---|
| 381 | EscapeSequence = Backslash ([abfnrtv?'"] | Backslash | "x" HexDigit+ | OctalDigit OctalDigit? OctalDigit?); |
|---|
| 382 | HexQuad = HexDigit HexDigit HexDigit HexDigit; |
|---|
| 383 | UniversalChar = Backslash ("u" HexQuad | "U" HexQuad HexQuad); |
|---|
| 384 | Newline = "\r\n" | "\n" | "\r"; |
|---|
| 385 | PPSpace = ([ \t]|("/*"(any\[*]|Newline|("*"+(any\[*/]|Newline)))*"*"+"/"))*; |
|---|
| 386 | Pound = "#" | "??=" | "%:"; |
|---|
| 387 | */ |
|---|
| 388 | |
|---|
| 389 | /*!re2c |
|---|
| 390 | "/*" { goto ccomment; } |
|---|
| 391 | "//" { goto cppcomment; } |
|---|
| 392 | |
|---|
| 393 | "TRUE" { RET(T_TRUE); } |
|---|
| 394 | "FALSE" { RET(T_FALSE); } |
|---|
| 395 | |
|---|
| 396 | "{" { RET(T_LEFTBRACE); } |
|---|
| 397 | "}" { RET(T_RIGHTBRACE); } |
|---|
| 398 | "[" { RET(T_LEFTBRACKET); } |
|---|
| 399 | "]" { RET(T_RIGHTBRACKET); } |
|---|
| 400 | "#" { RET(T_POUND); } |
|---|
| 401 | "##" { RET(T_POUND_POUND); } |
|---|
| 402 | "(" { RET(T_LEFTPAREN); } |
|---|
| 403 | ")" { RET(T_RIGHTPAREN); } |
|---|
| 404 | ";" { RET(T_SEMICOLON); } |
|---|
| 405 | ":" { RET(T_COLON); } |
|---|
| 406 | "?" { RET(T_QUESTION_MARK); } |
|---|
| 407 | "." { RET(T_DOT); } |
|---|
| 408 | "+" { RET(T_PLUS); } |
|---|
| 409 | "-" { RET(T_MINUS); } |
|---|
| 410 | "*" { RET(T_STAR); } |
|---|
| 411 | "/" { RET(T_DIVIDE); } |
|---|
| 412 | "%" { RET(T_PERCENT); } |
|---|
| 413 | "^" { RET(T_XOR); } |
|---|
| 414 | "&" { RET(T_AND); } |
|---|
| 415 | "|" { RET(T_OR); } |
|---|
| 416 | "~" { RET(T_COMPL); } |
|---|
| 417 | "!" { RET(T_NOT); } |
|---|
| 418 | "=" { RET(T_ASSIGN); } |
|---|
| 419 | "<" { RET(T_LESS); } |
|---|
| 420 | ">" { RET(T_GREATER); } |
|---|
| 421 | "<<" { RET(T_SHIFTLEFT); } |
|---|
| 422 | ">>" { RET(T_SHIFTRIGHT); } |
|---|
| 423 | "==" { RET(T_EQUAL); } |
|---|
| 424 | "!=" { RET(T_NOTEQUAL); } |
|---|
| 425 | "<=" { RET(T_LESSEQUAL); } |
|---|
| 426 | ">=" { RET(T_GREATEREQUAL); } |
|---|
| 427 | "&&" { RET(T_ANDAND); } |
|---|
| 428 | "||" { RET(T_OROR); } |
|---|
| 429 | "++" { RET(T_PLUSPLUS); } |
|---|
| 430 | "--" { RET(T_MINUSMINUS); } |
|---|
| 431 | "," { RET(T_COMMA); } |
|---|
| 432 | |
|---|
| 433 | ([a-zA-Z_] | UniversalChar) ([a-zA-Z_0-9] | UniversalChar)* |
|---|
| 434 | { RET(T_IDENTIFIER); } |
|---|
| 435 | |
|---|
| 436 | (("0" [xX] HexDigit+) | ("0" OctalDigit*) | ([1-9] Digit*)) IntegerSuffix? |
|---|
| 437 | { RET(T_INTLIT); } |
|---|
| 438 | |
|---|
| 439 | ((FractionalConstant ExponentPart?) | (Digit+ ExponentPart)) FloatingSuffix? |
|---|
| 440 | { RET(T_FLOATLIT); } |
|---|
| 441 | |
|---|
| 442 | (FractionalConstant | Digit+) FixedPointSuffix |
|---|
| 443 | { RET(T_FIXEDPOINTLIT); } |
|---|
| 444 | |
|---|
| 445 | "L"? (['] (EscapeSequence|any\[\n\r\\']|UniversalChar)+ [']) |
|---|
| 446 | { RET(T_CHARLIT); } |
|---|
| 447 | |
|---|
| 448 | "L"? (["] (EscapeSequence|any\[\n\r\\"]|UniversalChar)* ["]) |
|---|
| 449 | { RET(T_STRINGLIT); } |
|---|
| 450 | |
|---|
| 451 | |
|---|
| 452 | Pound PPSpace "include" PPSpace "<" (any\[\n\r>])+ ">" |
|---|
| 453 | { RET(T_PP_HHEADER); } |
|---|
| 454 | |
|---|
| 455 | Pound PPSpace "include" PPSpace "\"" (any\[\n\r"])+ "\"" |
|---|
| 456 | { RET(T_PP_QHEADER); } |
|---|
| 457 | |
|---|
| 458 | Pound PPSpace "include" PPSpace |
|---|
| 459 | { RET(T_PP_INCLUDE); } |
|---|
| 460 | |
|---|
| 461 | Pound PPSpace "if" { RET(T_PP_IF); } |
|---|
| 462 | Pound PPSpace "ifdef" { RET(T_PP_IFDEF); } |
|---|
| 463 | Pound PPSpace "ifndef" { RET(T_PP_IFNDEF); } |
|---|
| 464 | Pound PPSpace "else" { RET(T_PP_ELSE); } |
|---|
| 465 | Pound PPSpace "elif" { RET(T_PP_ELIF); } |
|---|
| 466 | Pound PPSpace "endif" { RET(T_PP_ENDIF); } |
|---|
| 467 | Pound PPSpace "define" { RET(T_PP_DEFINE); } |
|---|
| 468 | Pound PPSpace "undef" { RET(T_PP_UNDEF); } |
|---|
| 469 | Pound PPSpace "line" { RET(T_PP_LINE); } |
|---|
| 470 | Pound PPSpace "error" { RET(T_PP_ERROR); } |
|---|
| 471 | Pound PPSpace "pragma" { RET(T_PP_PRAGMA); } |
|---|
| 472 | |
|---|
| 473 | Pound PPSpace "warning" { RET(T_PP_WARNING); } |
|---|
| 474 | |
|---|
| 475 | [ \t\v\f]+ |
|---|
| 476 | { RET(T_SPACE); } |
|---|
| 477 | |
|---|
| 478 | Newline |
|---|
| 479 | { |
|---|
| 480 | s->line++; |
|---|
| 481 | RET(T_NEWLINE); |
|---|
| 482 | } |
|---|
| 483 | |
|---|
| 484 | "\000" |
|---|
| 485 | { |
|---|
| 486 | if(cursor != s->eof) |
|---|
| 487 | { |
|---|
| 488 | using namespace std; // some systems have printf in std |
|---|
| 489 | if (0 != s->error_proc) |
|---|
| 490 | (*s->error_proc)(s, "'\\000' in input stream"); |
|---|
| 491 | else |
|---|
| 492 | printf("Error: 0 in file\n"); |
|---|
| 493 | } |
|---|
| 494 | RET(T_EOF); |
|---|
| 495 | } |
|---|
| 496 | |
|---|
| 497 | any |
|---|
| 498 | { |
|---|
| 499 | /* if (0 != s->error_proc) |
|---|
| 500 | (*s->error_proc)(s, "Unexpected character: '%c'", *s->tok); |
|---|
| 501 | else |
|---|
| 502 | printf("unexpected character: '%c'\n", *s->tok); |
|---|
| 503 | */ |
|---|
| 504 | RET(TOKEN_FROM_ID(*s->tok, UnknownTokenType)); |
|---|
| 505 | } |
|---|
| 506 | */ |
|---|
| 507 | |
|---|
| 508 | ccomment: |
|---|
| 509 | /*!re2c |
|---|
| 510 | "*/" { RET(T_CCOMMENT); } |
|---|
| 511 | Newline |
|---|
| 512 | { |
|---|
| 513 | /*if(cursor == s->eof) RET(T_EOF);*/ |
|---|
| 514 | /*s->tok = cursor; */ |
|---|
| 515 | s->line += count_backslash_newlines(s, cursor) +1; |
|---|
| 516 | goto ccomment; |
|---|
| 517 | } |
|---|
| 518 | |
|---|
| 519 | any { goto ccomment; } |
|---|
| 520 | |
|---|
| 521 | "\000" |
|---|
| 522 | { |
|---|
| 523 | using namespace std; // some systems have printf in std |
|---|
| 524 | if(cursor == s->eof) |
|---|
| 525 | { |
|---|
| 526 | if (s->error_proc) |
|---|
| 527 | (*s->error_proc)(s, "Unterminated comment"); |
|---|
| 528 | else |
|---|
| 529 | printf("Error: Unterminated comment\n"); |
|---|
| 530 | } |
|---|
| 531 | else |
|---|
| 532 | { |
|---|
| 533 | if (s->error_proc) |
|---|
| 534 | (*s->error_proc)(s, "'\\000' in input stream"); |
|---|
| 535 | else |
|---|
| 536 | printf("Error: 0 in file"); |
|---|
| 537 | } |
|---|
| 538 | /* adjust cursor such next call returns T_EOF */ |
|---|
| 539 | --YYCURSOR; |
|---|
| 540 | /* the comment is unterminated, but nevertheless its a comment */ |
|---|
| 541 | RET(T_CCOMMENT); |
|---|
| 542 | } |
|---|
| 543 | |
|---|
| 544 | */ |
|---|
| 545 | |
|---|
| 546 | cppcomment: |
|---|
| 547 | /*!re2c |
|---|
| 548 | Newline |
|---|
| 549 | { |
|---|
| 550 | /*if(cursor == s->eof) RET(T_EOF); */ |
|---|
| 551 | /*s->tok = cursor; */ |
|---|
| 552 | s->line++; |
|---|
| 553 | RET(T_CPPCOMMENT); |
|---|
| 554 | } |
|---|
| 555 | |
|---|
| 556 | any { goto cppcomment; } |
|---|
| 557 | |
|---|
| 558 | "\000" |
|---|
| 559 | { |
|---|
| 560 | using namespace std; // some systems have printf in std |
|---|
| 561 | if(cursor != s->eof) |
|---|
| 562 | { |
|---|
| 563 | if (s->error_proc) |
|---|
| 564 | (*s->error_proc)(s, "'\\000' in input stream"); |
|---|
| 565 | else |
|---|
| 566 | printf("Error: 0 in file"); |
|---|
| 567 | } |
|---|
| 568 | /* adjust cursor such next call returns T_EOF */ |
|---|
| 569 | --YYCURSOR; |
|---|
| 570 | /* the comment is unterminated, but nevertheless its a comment */ |
|---|
| 571 | RET(T_CPPCOMMENT); |
|---|
| 572 | } |
|---|
| 573 | */ |
|---|
| 574 | |
|---|
| 575 | } /* end of scan */ |
|---|
| 576 | |
|---|
| 577 | #undef RE2C_ASSERT |
|---|
| 578 | |
|---|
| 579 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 580 | } // namespace re2clex |
|---|
| 581 | } // namespace idllexer |
|---|
| 582 | } // namespace wave |
|---|
| 583 | } // namespace boost |
|---|