PageRenderTime 67ms CodeModel.GetById 36ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lexer.h

https://github.com/pikelang/Pike
C Header | 1428 lines | 1211 code | 114 blank | 103 comment | 239 complexity | 284aec86a6eeb78ea4a30a0376c96602 MD5 | raw file
  1. /*
  2. || This file is part of Pike. For copyright information see COPYRIGHT.
  3. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
  4. || for more information.
  5. */
  6. /*
  7. * Lexical analyzer template.
  8. */
  9. #ifndef SHIFT
  10. #error Internal error: SHIFT not defined
  11. #endif
  12. /*
  13. * Definitions
  14. */
  15. /* Generic */
  16. #define GOBBLE(c) (LOOK()==c?(SKIP(),1):0)
  17. #define SKIPSPACE() do { while(wide_isspace(LOOK()) && LOOK()!='\n') SKIP(); }while(0)
  18. #define SKIPWHITE() do { while(wide_isspace(LOOK())) SKIP(); }while(0)
  19. #define SKIPUPTO(X) do { while(LOOK()!=(X) && LOOK()) SKIP(); }while(0)
  20. #if (SHIFT == 0)
  21. #define WCHAR p_wchar0
  22. #define LOOK() EXTRACT_UCHAR(lex->pos)
  23. #define GETC() EXTRACT_UCHAR(lex->pos++)
  24. #define SKIP() lex->pos++
  25. #define SKIPN(N) (lex->pos += (N))
  26. #define READBUF(X) do { \
  27. int C; \
  28. buf = lex->pos; \
  29. while((C = LOOK()) && (X)) \
  30. lex->pos++; \
  31. len = (size_t)(lex->pos - buf); \
  32. } while(0)
  33. #define TWO_CHAR(X,Y) ((X)<<8)+(Y)
  34. #define ISWORD(X) ((len == CONSTANT_STRLEN(X)) && !memcmp(buf,X,len))
  35. /*
  36. * Function renaming
  37. */
  38. #define parse_esc_seq parse_esc_seq0
  39. #define yylex yylex0
  40. #define low_yylex low_yylex0
  41. #define lex_atoi atoi
  42. #define lex_strtol strtol
  43. #define lex_strtod my_strtod
  44. #define lex_isidchar isidchar
  45. #else /* SHIFT != 0 */
  46. #define LOOK() INDEX_CHARP(lex->pos,0,SHIFT)
  47. #define SKIP() (lex->pos += (1<<SHIFT))
  48. #define SKIPN(N) (lex->pos += (N) < 0 ? -(-(N) << SHIFT) : ((N)<<SHIFT))
  49. #define GETC() (SKIP(),INDEX_CHARP(lex->pos-(1<<SHIFT),0,SHIFT))
  50. #define READBUF(X) do { \
  51. int C; \
  52. buf = lex->pos; \
  53. while((C = LOOK()) && (X)) \
  54. SKIP(); \
  55. len = (size_t)((lex->pos - buf) >> SHIFT); \
  56. } while(0)
  57. #define TWO_CHAR(X,Y) ((X)<<8)+(Y)
  58. #define ISWORD(X) ((len == strlen(X)) && low_isword(buf, X, len))
  59. #if (SHIFT == 1)
  60. #define WCHAR p_wchar1
  61. /* Function renaming */
  62. #define low_isword low_isword1
  63. #define parse_esc_seq parse_esc_seq1
  64. #define char_const char_const1
  65. #define readstring readstring1
  66. #define yylex yylex1
  67. #define low_yylex low_yylex1
  68. #define lex_atoi lex_atoi1
  69. #define lex_strtol lex_strtol1
  70. #define lex_strtod lex_strtod1
  71. #else /* SHIFT != 1 */
  72. #define WCHAR p_wchar2
  73. /* Function renaming */
  74. #define low_isword low_isword2
  75. #define parse_esc_seq parse_esc_seq2
  76. #define char_const char_const2
  77. #define readstring readstring2
  78. #define yylex yylex2
  79. #define low_yylex low_yylex2
  80. #define lex_atoi lex_atoi2
  81. #define lex_strtol lex_strtol2
  82. #define lex_strtod lex_strtod2
  83. #endif /* SHIFT == 1 */
  84. #define lex_isidchar(X) wide_isidchar(X)
  85. static int low_isword(char *buf, char *X, size_t len)
  86. {
  87. while(len--) {
  88. if (INDEX_CHARP(buf, len, SHIFT) != ((unsigned char *)X)[len]) {
  89. return 0;
  90. }
  91. }
  92. return 1;
  93. }
  94. static int lex_atoi(char *buf)
  95. {
  96. /* NOTE: Cuts at 63 digits */
  97. char buff[64];
  98. int i=0;
  99. int c;
  100. while(((c = INDEX_CHARP(buf, i, SHIFT))>='0') && (c <= '9') && (i < 63)) {
  101. buff[i++] = c;
  102. }
  103. buff[i] = 0;
  104. return atoi(buff);
  105. }
  106. static long lex_strtol(char *buf, char **end, int base)
  107. {
  108. PCHARP foo;
  109. long ret;
  110. ret=STRTOL_PCHARP(MKPCHARP(buf,SHIFT),&foo,base);
  111. if(end) end[0]=(char *)foo.ptr;
  112. return ret;
  113. }
  114. static FLOAT_TYPE lex_strtod(char *buf, char **end)
  115. {
  116. PCHARP foo;
  117. #if SIZEOF_FLOAT_TYPE > SIZEOF_DOUBLE
  118. FLOAT_TYPE ret;
  119. ret=STRTOLD_PCHARP(MKPCHARP(buf,SHIFT),&foo);
  120. #else
  121. double ret;
  122. ret=STRTOD_PCHARP(MKPCHARP(buf,SHIFT),&foo);
  123. #endif
  124. if(end) end[0]=(char *)foo.ptr;
  125. return ret;
  126. }
  127. #endif /* SHIFT == 0 */
  128. /*** Lexical analyzing ***/
  129. /* String escape sequences
  130. *
  131. * Sequence Character
  132. * \\ backslash
  133. * \[0-7]* octal escape
  134. * \a alert (BEL)
  135. * \b backspace (BS)
  136. * \d[0-9]* decimal escape
  137. * \e escape (ESC)
  138. * \f form-feed (FF)
  139. * \n newline (LF)
  140. * \r carriage-return (CR)
  141. * \t tab (HT)
  142. * \v vertical-tab (VT)
  143. * \x[0-9a-fA-F]* hexadecimal escape
  144. * \u+[0-9a-fA-F]{4,4} 16 bit unicode style escape
  145. * \U+[0-9a-fA-F]{8,8} 32 bit unicode style escape
  146. *
  147. * If there are more than one u or U in the unicode style escapes, one
  148. * is removed and the escape remains otherwise intact.
  149. */
  150. int parse_esc_seq (WCHAR *buf, p_wchar2 *chr, ptrdiff_t *len)
  151. /* buf is assumed to be after the backslash. Return codes:
  152. * 0: All ok. The char's in *chr, consumed length in *len.
  153. * 1: Found a literal \r at *buf.
  154. * 2: Found a literal \n at *buf.
  155. * 3: Found a literal \0 at *buf.
  156. * 4: Too large octal escape. *len is gobbled to the end of it all.
  157. * 5: Too large hexadecimal escape. *len is gobbled to the end of it all.
  158. * 6: Too large decimal escape. *len is gobbled to the end of it all.
  159. * 7: Not 4 digits in \u escape. *len is up to the last found digit.
  160. * 8: Not 8 digits in \U escape. *len is up to the last found digit. */
  161. {
  162. ptrdiff_t l = 1;
  163. p_wchar2 c;
  164. int of = 0;
  165. switch ((c = *buf))
  166. {
  167. case '\r': return 1;
  168. case '\n': return 2;
  169. case 0: return 3;
  170. case 'a': c = 7; break; /* BEL */
  171. case 'b': c = 8; break; /* BS */
  172. case 't': c = 9; break; /* HT */
  173. case 'n': c = 10; break; /* LF */
  174. case 'v': c = 11; break; /* VT */
  175. case 'f': c = 12; break; /* FF */
  176. case 'r': c = 13; break; /* CR */
  177. case 'e': c = 27; break; /* ESC */
  178. case '0': case '1': case '2': case '3':
  179. case '4': case '5': case '6': case '7': {
  180. unsigned INT32 n = c-'0';
  181. for (l = 1; buf[l] >= '0' && buf[l] < '8'; l++) {
  182. if (DO_UINT32_MUL_OVERFLOW(n, 8, &n))
  183. of = 1;
  184. else
  185. n += buf[l] - '0';
  186. }
  187. if (of) {
  188. *len = l;
  189. return 4;
  190. }
  191. c = (p_wchar2)n;
  192. break;
  193. }
  194. case '8': case '9':
  195. if( Pike_compiler->compiler_pass == COMPILER_PASS_FIRST )
  196. yywarning("%c is not a valid octal digit.", c);
  197. break;
  198. case 'x': {
  199. unsigned INT32 n=0;
  200. for (l = 1;; l++) {
  201. switch (buf[l]) {
  202. case '0': case '1': case '2': case '3': case '4':
  203. case '5': case '6': case '7': case '8': case '9':
  204. if (DO_UINT32_MUL_OVERFLOW(n, 16, &n))
  205. of = 1;
  206. else
  207. n += buf[l] - '0';
  208. continue;
  209. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  210. if (DO_UINT32_MUL_OVERFLOW(n, 16, &n))
  211. of = 1;
  212. else
  213. n += buf[l] - 'a' + 10;
  214. continue;
  215. case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  216. if (DO_UINT32_MUL_OVERFLOW(n, 16, &n))
  217. of = 1;
  218. else
  219. n += buf[l] - 'A' + 10;
  220. continue;
  221. }
  222. break;
  223. }
  224. if (of) {
  225. *len = l;
  226. return 5;
  227. }
  228. c = (p_wchar2)n;
  229. break;
  230. }
  231. case 'd': {
  232. unsigned INT32 n=0;
  233. for (l = 1;; l++) {
  234. switch (buf[l]) {
  235. case '0': case '1': case '2': case '3': case '4':
  236. case '5': case '6': case '7': case '8': case '9':
  237. if (DO_UINT32_MUL_OVERFLOW(n, 10, &n) || DO_UINT32_ADD_OVERFLOW(n, buf[l] - '0', &n)) {
  238. of = 1;
  239. }
  240. continue;
  241. }
  242. break;
  243. }
  244. if (of) {
  245. *len = l;
  246. return 6;
  247. }
  248. c = (p_wchar2)n;
  249. break;
  250. }
  251. case 'u':
  252. case 'U': {
  253. /* FIXME: Do we need compat goo to turn this off? */
  254. /* Note: Code dup in gobble_identifier in preprocessor.h. */
  255. unsigned INT32 n = 0;
  256. int stop, longq;
  257. l = 1;
  258. if (buf[1] == c) {
  259. /* A double-u quoted escape. Convert the "\u" or "\U" to "\",
  260. * thereby shaving off a "u" or "U" from the escape
  261. * sequence. */
  262. /* Don't check that there's a valid number of hex digits in
  263. * this case, since the encoding code that can produce them
  264. * doesn't check that. */
  265. c = '\\';
  266. break;
  267. }
  268. if (c == 'u') {
  269. stop = l + 4;
  270. longq = 0;
  271. }
  272. else {
  273. stop = l + 8;
  274. longq = 1;
  275. }
  276. for (; l < stop; l++)
  277. switch (buf[l]) {
  278. case '0': case '1': case '2': case '3': case '4':
  279. case '5': case '6': case '7': case '8': case '9':
  280. n = 16 * n + buf[l] - '0';
  281. break;
  282. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  283. n = 16 * n + buf[l] - 'a' + 10;
  284. break;
  285. case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  286. n = 16 * n + buf[l] - 'A' + 10;
  287. break;
  288. default:
  289. *len = l;
  290. return longq ? 8 : 7;
  291. }
  292. c = (p_wchar2)n;
  293. break;
  294. }
  295. case '\\': case '\'': case '\"':
  296. break;
  297. default:
  298. /* Warn about this as it is commonly due to broken escaping,
  299. * and to be forward compatible with adding future new escapes.
  300. */
  301. if (Pike_compiler->compiler_pass == COMPILER_PASS_FIRST) {
  302. yywarning("Redundant backslash-escape: \'\\%c\'.", c);
  303. }
  304. break;
  305. }
  306. *len = l;
  307. *chr = c;
  308. return 0;
  309. }
  310. static p_wchar2 char_const(struct lex *lex)
  311. {
  312. p_wchar2 c;
  313. ptrdiff_t l;
  314. switch (parse_esc_seq ((WCHAR *)lex->pos, &c, &l)) {
  315. case 0:
  316. break;
  317. case 1:
  318. SKIP();
  319. return '\r';
  320. case 2:
  321. SKIP();
  322. lex->current_line++;
  323. return '\n';
  324. case 3:
  325. yyerror("Unexpected end of file.");
  326. lex->pos -= (1<<SHIFT);
  327. return 0;
  328. case 4: case 5: case 6:
  329. if( Pike_compiler->compiler_pass == COMPILER_PASS_FIRST )
  330. yyerror ("Too large character value in escape.");
  331. c = -1;
  332. break;
  333. case 7:
  334. if( Pike_compiler->compiler_pass == COMPILER_PASS_FIRST )
  335. yyerror ("Too few hex digits in \\u escape.");
  336. return '\\';
  337. case 8:
  338. if( Pike_compiler->compiler_pass == COMPILER_PASS_FIRST )
  339. yyerror ("Too few hex digits in \\U escape.");
  340. return '\\';
  341. }
  342. SKIPN (l);
  343. return c;
  344. }
  345. static struct pike_string *readstring(struct lex *lex)
  346. {
  347. int c;
  348. struct string_builder tmp;
  349. #if (SHIFT != 0)
  350. PCHARP bufptr = { NULL, SHIFT };
  351. #endif /* SHIFT != 0 */
  352. init_string_builder(&tmp,0);
  353. while(1)
  354. {
  355. char *buf;
  356. size_t len;
  357. READBUF(((C > '\\') ||
  358. ((C != '"') && (C != '\\') && (C != '\n') && (C != '\r'))));
  359. if (len) {
  360. #if (SHIFT == 0)
  361. string_builder_binary_strcat(&tmp, buf, len);
  362. #else /* SHIFT != 0 */
  363. bufptr.ptr = (p_wchar0 *)buf;
  364. string_builder_append(&tmp, bufptr, len);
  365. #endif /* SHIFT == 0 */
  366. }
  367. switch(c=GETC())
  368. {
  369. case 0:
  370. lex->pos -= (1<<SHIFT);
  371. yyerror("End of file in string.");
  372. break;
  373. case '\n': case '\r':
  374. lex->current_line++;
  375. yyerror("Newline in string.");
  376. break;
  377. case '\\':
  378. string_builder_putchar(&tmp, char_const(lex));
  379. continue;
  380. case '"':
  381. break;
  382. default:
  383. #ifdef PIKE_DEBUG
  384. Pike_fatal("Default case in readstring() reached. c:%d\n", c);
  385. #endif /* PIKE_DEBUG */
  386. break;
  387. }
  388. break;
  389. }
  390. return dmalloc_touch(struct pike_string *, finish_string_builder(&tmp));
  391. }
  392. #if LEXDEBUG>4
  393. static int low_yylex(struct lex *lex, YYSTYPE *);
  394. #endif /* LEXDEBUG>4 */
  395. int yylex(struct lex *lex, YYSTYPE *yylval)
  396. #if LEXDEBUG>4
  397. {
  398. int t;
  399. #if LEXDEBUG>8
  400. fprintf(stderr, "YYLEX:\n");
  401. #endif /* LEXDEBUG>8 */
  402. t=low_yylex(lex, yylval);
  403. if(t<256)
  404. {
  405. fprintf(stderr,"YYLEX: '%c' (%d) at %s:%d\n",t,t,lex.current_file->str,lex.current_line);
  406. }else{
  407. fprintf(stderr,"YYLEX: token #%d at %s:%d\n",t,lex.current_file->str,lex.current_line);
  408. }
  409. return t;
  410. }
  411. static int low_yylex(struct lex *lex, YYSTYPE *yylval)
  412. #endif /* LEXDEBUG>4 */
  413. {
  414. INT32 c;
  415. size_t len;
  416. char *buf;
  417. #ifdef __CHECKER__
  418. memset(yylval,0,sizeof(YYSTYPE));
  419. #endif
  420. #ifdef MALLOC_DEBUG
  421. check_sfltable();
  422. #endif
  423. while(1)
  424. {
  425. c = GETC();
  426. if((c>'9') && lex_isidchar(c))
  427. {
  428. lex->pos -= (1<<SHIFT);
  429. READBUF(lex_isidchar(C));
  430. PIKE_MEM_WO_RANGE (yylval, sizeof (YYSTYPE));
  431. if(len>1 && len<16)
  432. {
  433. /* NOTE: TWO_CHAR() will generate false positives with wide strings,
  434. * but that doesn't matter, since ISWORD() will fix it.
  435. */
  436. switch(TWO_CHAR(INDEX_CHARP(buf, 0, SHIFT),
  437. INDEX_CHARP(buf, 1, SHIFT)))
  438. {
  439. case TWO_CHAR('a','r'):
  440. if(ISWORD("array")) return TOK_ARRAY_ID;
  441. break;
  442. case TWO_CHAR('a','w'):
  443. if (ISWORD("await")) {
  444. if (Pike_compiler->compiler_pass == COMPILER_PASS_FIRST) {
  445. yywarning("await will soon be a reserved keyword.");
  446. }
  447. break;
  448. }
  449. break;
  450. case TWO_CHAR('a','u'):
  451. if(ISWORD("auto")) return TOK_AUTO_ID;
  452. break;
  453. case TWO_CHAR('b','r'):
  454. if(ISWORD("break")) return TOK_BREAK;
  455. break;
  456. case TWO_CHAR('c','a'):
  457. if(ISWORD("case")) return TOK_CASE;
  458. if(ISWORD("catch")) return TOK_CATCH;
  459. break;
  460. case TWO_CHAR('c','l'):
  461. if(ISWORD("class")) return TOK_CLASS;
  462. break;
  463. case TWO_CHAR('c','o'):
  464. if(ISWORD("constant")) return TOK_CONSTANT;
  465. if(ISWORD("continue")) return TOK_CONTINUE;
  466. if(ISWORD("const")) {
  467. if (Pike_compiler->compiler_pass == COMPILER_PASS_FIRST) {
  468. yywarning("const will soon be a reserved keyword.");
  469. }
  470. break;
  471. }
  472. break;
  473. case TWO_CHAR('d','e'):
  474. if(ISWORD("default")) return TOK_DEFAULT;
  475. break;
  476. case TWO_CHAR('d','o'):
  477. if(ISWORD("do")) return TOK_DO;
  478. break;
  479. case TWO_CHAR('e','l'):
  480. if(ISWORD("else")) return TOK_ELSE;
  481. break;
  482. case TWO_CHAR('e','n'):
  483. if(ISWORD("enum")) return TOK_ENUM;
  484. break;
  485. case TWO_CHAR('e','x'):
  486. if(ISWORD("extern")) return TOK_EXTERN;
  487. break;
  488. case TWO_CHAR('f','i'):
  489. if(ISWORD("final")) return TOK_FINAL_ID;
  490. break;
  491. case TWO_CHAR('f','l'):
  492. if(ISWORD("float")) return TOK_FLOAT_ID;
  493. break;
  494. case TWO_CHAR('f','o'):
  495. if(ISWORD("for")) return TOK_FOR;
  496. if(ISWORD("foreach")) return TOK_FOREACH;
  497. break;
  498. case TWO_CHAR('f','u'):
  499. if(ISWORD("function")) return TOK_FUNCTION_ID;
  500. break;
  501. case TWO_CHAR('g','a'):
  502. if(ISWORD("gauge")) return TOK_GAUGE;
  503. break;
  504. case TWO_CHAR('g','l'):
  505. if (ISWORD("global")) return TOK_GLOBAL;
  506. break;
  507. case TWO_CHAR('i','f'):
  508. if(ISWORD("if")) return TOK_IF;
  509. break;
  510. case TWO_CHAR('i','m'):
  511. if(ISWORD("import")) return TOK_IMPORT;
  512. break;
  513. case TWO_CHAR('i','n'):
  514. if(ISWORD("int")) return TOK_INT_ID;
  515. if(ISWORD("inherit")) return TOK_INHERIT;
  516. if(ISWORD("inline")) return TOK_INLINE;
  517. break;
  518. case TWO_CHAR('l','a'):
  519. if(ISWORD("lambda")) return TOK_LAMBDA;
  520. break;
  521. case TWO_CHAR('l','o'):
  522. if(ISWORD("local")) return TOK_LOCAL_ID;
  523. break;
  524. case TWO_CHAR('m','a'):
  525. if(ISWORD("mapping")) return TOK_MAPPING_ID;
  526. break;
  527. case TWO_CHAR('m','i'):
  528. if(ISWORD("mixed")) return TOK_MIXED_ID;
  529. break;
  530. case TWO_CHAR('m','u'):
  531. if(ISWORD("multiset")) return TOK_MULTISET_ID;
  532. break;
  533. case TWO_CHAR('o','b'):
  534. if(ISWORD("object")) return TOK_OBJECT_ID;
  535. break;
  536. case TWO_CHAR('o','p'):
  537. if(ISWORD("optional")) return TOK_OPTIONAL;
  538. break;
  539. case TWO_CHAR('p','r'):
  540. if(ISWORD("program")) return TOK_PROGRAM_ID;
  541. if(ISWORD("predef")) return TOK_PREDEF;
  542. if(ISWORD("private")) return TOK_PRIVATE;
  543. if(ISWORD("protected")) return TOK_PROTECTED;
  544. break;
  545. case TWO_CHAR('p','u'):
  546. if(ISWORD("public")) return TOK_PUBLIC;
  547. break;
  548. case TWO_CHAR('r','e'):
  549. if(ISWORD("return")) return TOK_RETURN;
  550. break;
  551. case TWO_CHAR('s','s'):
  552. if(ISWORD("sscanf")) return TOK_SSCANF;
  553. break;
  554. case TWO_CHAR('s','t'):
  555. if(ISWORD("string")) return TOK_STRING_ID;
  556. if(ISWORD("static")) return TOK_STATIC;
  557. break;
  558. case TWO_CHAR('s','w'):
  559. if(ISWORD("switch")) return TOK_SWITCH;
  560. break;
  561. case TWO_CHAR('t','y'):
  562. if(ISWORD("typedef")) return TOK_TYPEDEF;
  563. if(ISWORD("typeof")) return TOK_TYPEOF;
  564. break;
  565. case TWO_CHAR('v','a'):
  566. if(ISWORD("variant")) return TOK_VARIANT;
  567. break;
  568. case TWO_CHAR('v','o'):
  569. if(ISWORD("void")) return TOK_VOID_ID;
  570. break;
  571. case TWO_CHAR('w','h'):
  572. if(ISWORD("while")) return TOK_WHILE;
  573. break;
  574. case TWO_CHAR('_','S'):
  575. if(ISWORD("_Static_assert")) return TOK_STATIC_ASSERT;
  576. break;
  577. case TWO_CHAR('_','_'):
  578. if(len < 5) break;
  579. if(ISWORD("__attribute__"))
  580. return TOK_ATTRIBUTE_ID;
  581. if(ISWORD("__deprecated__"))
  582. return TOK_DEPRECATED_ID;
  583. if(ISWORD("__func__"))
  584. return TOK_FUNCTION_NAME;
  585. if(ISWORD("__weak__"))
  586. return TOK_WEAK;
  587. if(ISWORD("__unused__"))
  588. return TOK_UNUSED;
  589. if(ISWORD("__unknown__"))
  590. return TOK_UNKNOWN;
  591. /* Allow triple (or more) underscore for the user, and make sure we
  592. * don't get false matches below for wide strings.
  593. */
  594. if((INDEX_CHARP(buf, 2, SHIFT) == '_') ||
  595. (INDEX_CHARP(buf, len-3, SHIFT) == '_') ||
  596. (INDEX_CHARP(buf, len-2, SHIFT) != '_') ||
  597. (INDEX_CHARP(buf, len-1, SHIFT) != '_') ||
  598. (INDEX_CHARP(buf, 0, SHIFT) != '_') ||
  599. (INDEX_CHARP(buf, 1, SHIFT) != '_')) break;
  600. {
  601. /* Double underscore before and after is reserved for keywords. */
  602. #if (SHIFT == 0)
  603. struct pike_string *tmp = make_shared_binary_string(buf, len);
  604. #else /* SHIFT != 0 */
  605. #if (SHIFT == 1)
  606. struct pike_string *tmp = make_shared_binary_string1((p_wchar1 *)buf,
  607. len);
  608. #else /* SHIFT != 1 */
  609. struct pike_string *tmp = make_shared_binary_string2((p_wchar2 *)buf,
  610. len);
  611. #endif /* SHIFT == 1 */
  612. #endif /* SHIFT == 0 */
  613. yylval->n=mkstrnode(tmp);
  614. /* - But only for lower case US-ASCII.
  615. * - Upper case is used for symbols intended for #if constant().
  616. */
  617. if (tmp->size_shift) {
  618. free_string(tmp);
  619. return TOK_IDENTIFIER;
  620. }
  621. if(ISWORD("__args__")) {
  622. free_string(tmp);
  623. return TOK_IDENTIFIER;
  624. }
  625. while(len--) {
  626. int c = tmp->str[len];
  627. if ((c >= 'A') && (c <= 'Z')) {
  628. free_string(tmp);
  629. return TOK_IDENTIFIER;
  630. }
  631. }
  632. free_string(tmp);
  633. }
  634. return TOK_RESERVED;
  635. }
  636. }
  637. {
  638. #if (SHIFT == 0)
  639. struct pike_string *tmp = make_shared_binary_string(buf, len);
  640. #else /* SHIFT != 0 */
  641. #if (SHIFT == 1)
  642. struct pike_string *tmp = make_shared_binary_string1((p_wchar1 *)buf,
  643. len);
  644. #else /* SHIFT != 1 */
  645. struct pike_string *tmp = make_shared_binary_string2((p_wchar2 *)buf,
  646. len);
  647. #endif /* SHIFT == 1 */
  648. #endif /* SHIFT == 0 */
  649. yylval->n=mkstrnode(tmp);
  650. free_string(tmp);
  651. return TOK_IDENTIFIER;
  652. }
  653. }
  654. /* Note that 0 <= c <= 255 at this point. */
  655. switch(c)
  656. {
  657. case 0:
  658. lex->pos -= (1<<SHIFT);
  659. if(lex->end != lex->pos)
  660. yyerror("Illegal character (NUL)");
  661. #ifdef TOK_LEX_EOF
  662. return TOK_LEX_EOF;
  663. #else /* !TOK_LEX_EOF */
  664. return 0;
  665. #endif /* TOK_LEX_EOF */
  666. case '\n':
  667. lex->current_line++;
  668. continue;
  669. case 0x1b: case 0x9b: /* ESC or CSI */
  670. /* Assume ANSI/DEC escape sequence.
  671. * Format supported:
  672. * <ESC>[\040-\077]+[\100-\177]
  673. * or
  674. * <CSI>[\040-\077]*[\100-\177]
  675. */
  676. while ((c = LOOK()) && (c == ((c & 0x1f)|0x20))) {
  677. SKIP();
  678. }
  679. if (c == ((c & 0x3f)|0x40)) {
  680. SKIP();
  681. } else {
  682. /* FIXME: Warning here? */
  683. }
  684. continue;
  685. case '#':
  686. SKIPSPACE();
  687. READBUF(!wide_isspace(C));
  688. switch(len>0?INDEX_CHARP(buf, 0, SHIFT):0)
  689. {
  690. case 'l':
  691. if (ISWORD("line"))
  692. {
  693. SKIPSPACE();
  694. if (LOOK() < '0' || LOOK() > '9') goto unknown_directive;
  695. READBUF(!wide_isspace(C));
  696. } else goto unknown_directive;
  697. /* FALLTHRU */
  698. case '0': case '1': case '2': case '3': case '4':
  699. case '5': case '6': case '7': case '8': case '9':
  700. lex->current_line = lex_strtol(buf, NULL, 10)-1;
  701. SKIPSPACE();
  702. if(GOBBLE('"'))
  703. {
  704. struct pike_string *tmp=readstring(lex);
  705. free_string(lex->current_file);
  706. lex->current_file = dmalloc_touch(struct pike_string *, tmp);
  707. }
  708. if (Pike_compiler->compiler_pass == COMPILER_PASS_FIRST &&
  709. !Pike_compiler->new_program->num_linenumbers) {
  710. /* A nested program will always get an entry right away in
  711. * language.yacc. */
  712. store_linenumber(0, lex->current_file);
  713. #ifdef DEBUG_MALLOC
  714. if(strcmp(lex->current_file->str,"-"))
  715. debug_malloc_name(Pike_compiler->new_program, lex->current_file->str, 0);
  716. #endif
  717. }
  718. break;
  719. case 'p':
  720. if(ISWORD("pragma"))
  721. {
  722. SKIPSPACE();
  723. READBUF(!wide_isspace(C));
  724. if (ISWORD("all_inline"))
  725. {
  726. lex->pragmas |= ID_INLINE;
  727. }
  728. else if (ISWORD("all_final"))
  729. {
  730. lex->pragmas |= ID_FINAL;
  731. }
  732. else if (ISWORD("strict_types"))
  733. {
  734. lex->pragmas |= ID_STRICT_TYPES;
  735. }
  736. else if (ISWORD("no_strict_types"))
  737. {
  738. lex->pragmas &= ~ID_STRICT_TYPES;
  739. }
  740. else if (ISWORD("save_parent"))
  741. {
  742. lex->pragmas |= ID_SAVE_PARENT;
  743. }
  744. else if (ISWORD("dont_save_parent"))
  745. {
  746. lex->pragmas |= ID_DONT_SAVE_PARENT;
  747. }
  748. else if (ISWORD("no_deprecation_warnings"))
  749. {
  750. lex->pragmas |= ID_NO_DEPRECATION_WARNINGS;
  751. }
  752. else if (ISWORD("deprecation_warnings"))
  753. {
  754. lex->pragmas &= ~ID_NO_DEPRECATION_WARNINGS;
  755. }
  756. else if (ISWORD("disassemble"))
  757. {
  758. lex->pragmas |= ID_DISASSEMBLE;
  759. }
  760. else if (ISWORD("no_disassemble"))
  761. {
  762. lex->pragmas &= ~ID_DISASSEMBLE;
  763. }
  764. else if (ISWORD("dynamic_dot"))
  765. {
  766. lex->pragmas |= ID_DYNAMIC_DOT;
  767. }
  768. else if (ISWORD("no_dynamic_dot"))
  769. {
  770. lex->pragmas &= ~ID_DYNAMIC_DOT;
  771. }
  772. else if (ISWORD("compiler_trace"))
  773. {
  774. lex->pragmas |= ID_COMPILER_TRACE;
  775. }
  776. else if (ISWORD("no_compiler_trace"))
  777. {
  778. lex->pragmas &= ~ID_COMPILER_TRACE;
  779. }
  780. else
  781. {
  782. if( Pike_compiler->compiler_pass == COMPILER_PASS_FIRST )
  783. yywarning("Unknown #pragma directive.");
  784. }
  785. break;
  786. }
  787. if(ISWORD("pike"))
  788. {
  789. int minor;
  790. int major;
  791. SKIPSPACE();
  792. READBUF(C!='.' && C!='\n');
  793. major=lex_atoi(buf);
  794. if(!GOBBLE('.'))
  795. {
  796. yyerror("Missing '.' in #pike directive.");
  797. minor=0;
  798. }else{
  799. READBUF(C!='\n' && C!='.');
  800. minor=lex_atoi(buf);
  801. if(GOBBLE('.'))
  802. yyerror("Build numbers not supported in #pike directive.");
  803. READBUF(C!='\n');
  804. change_compiler_compatibility(major, minor);
  805. }
  806. break;
  807. }
  808. /* FALLTHRU */
  809. default:
  810. unknown_directive:
  811. if (len < 256) {
  812. #if (SHIFT == 0)
  813. struct pike_string *dir =
  814. make_shared_binary_string(buf, len);
  815. #elif (SHIFT == 1)
  816. struct pike_string *dir =
  817. make_shared_binary_string1((p_wchar1 *)buf, len);
  818. #elif (SHIFT == 2)
  819. struct pike_string *dir =
  820. make_shared_binary_string2((p_wchar2 *)buf, len);
  821. #endif
  822. my_yyerror("Unknown preprocessor directive %S.", dir);
  823. free_string(dir);
  824. } else {
  825. yyerror("Unknown preprocessor directive.");
  826. }
  827. SKIPUPTO('\n');
  828. continue;
  829. }
  830. continue;
  831. case ' ':
  832. case '\t':
  833. case '\r':
  834. continue;
  835. case '\'':
  836. {
  837. unsigned int l = 0;
  838. struct svalue res = svalue_int_zero;
  839. MP_INT bigint;
  840. while(1)
  841. {
  842. INT32 tmp;
  843. switch( (tmp=GETC()) )
  844. {
  845. case 0:
  846. lex->pos -= (1<<SHIFT);
  847. yyerror("Unexpected end of file\n");
  848. goto return_char;
  849. case '\\':
  850. tmp = char_const(lex);
  851. /* fallthrough. */
  852. default:
  853. l++;
  854. if( l == sizeof(INT_TYPE)-1 )
  855. {
  856. /* overflow possible. Switch to bignums. */
  857. mpz_init(&bigint);
  858. mpz_set_ui(&bigint,res.u.integer);
  859. TYPEOF(res) = PIKE_T_OBJECT;
  860. }
  861. if( l >= sizeof(INT_TYPE)-1 )
  862. {
  863. mpz_mul_2exp(&bigint,&bigint,8);
  864. mpz_add_ui(&bigint,&bigint,tmp);
  865. }
  866. else
  867. {
  868. res.u.integer <<= 8;
  869. res.u.integer |= tmp;
  870. }
  871. break;
  872. case '\'':
  873. if( l == 0 )
  874. yyerror("Zero-length character constant.");
  875. goto return_char;
  876. }
  877. }
  878. return_char:
  879. if( TYPEOF(res) == PIKE_T_OBJECT )
  880. {
  881. push_bignum( &bigint );
  882. mpz_clear(&bigint);
  883. reduce_stack_top_bignum();
  884. res = *--Pike_sp;
  885. }
  886. debug_malloc_pass( yylval->n=mksvaluenode(&res) );
  887. free_svalue( &res );
  888. return TOK_NUMBER;
  889. }
  890. UNREACHABLE(break);
  891. case '"':
  892. {
  893. struct pike_string *s=readstring(lex);
  894. yylval->n=mkstrnode(s);
  895. free_string(s);
  896. return TOK_STRING;
  897. }
  898. case ':':
  899. if(GOBBLE(':')) return TOK_COLON_COLON;
  900. return c;
  901. case '.':
  902. if(GOBBLE('.'))
  903. {
  904. if(GOBBLE('.')) return TOK_DOT_DOT_DOT;
  905. return TOK_DOT_DOT;
  906. }
  907. if (((c = INDEX_CHARP(lex->pos, 0, SHIFT)) <= '9') &&
  908. (c >= '0')) {
  909. lex->pos -= (1<<SHIFT);
  910. goto read_float;
  911. }
  912. return '.';
  913. case '0':
  914. {
  915. int base = 0;
  916. if(GOBBLE('b') || GOBBLE('B'))
  917. {
  918. base = 2;
  919. goto read_based_number;
  920. }
  921. else if(GOBBLE('x') || GOBBLE('X'))
  922. {
  923. struct svalue sval;
  924. base = 16;
  925. read_based_number:
  926. SET_SVAL(sval, PIKE_T_INT, NUMBER_NUMBER, integer, 0);
  927. safe_wide_string_to_svalue_inumber(&sval,
  928. lex->pos,
  929. &lex->pos,
  930. base,
  931. 0,
  932. SHIFT);
  933. dmalloc_touch_svalue(&sval);
  934. yylval->n = mksvaluenode(&sval);
  935. free_svalue(&sval);
  936. return TOK_NUMBER;
  937. }
  938. }
  939. /* FALLTHRU */
  940. case '1': case '2': case '3': case '4':
  941. case '5': case '6': case '7': case '8': case '9':
  942. {
  943. char *p1, *p2;
  944. FLOAT_TYPE f;
  945. long l;
  946. struct svalue sval;
  947. lex->pos -= (1<<SHIFT);
  948. if(INDEX_CHARP(lex->pos, 0, SHIFT)=='0')
  949. for(l=1;INDEX_CHARP(lex->pos, l, SHIFT)<='9' &&
  950. INDEX_CHARP(lex->pos, l, SHIFT)>='0';l++)
  951. if(INDEX_CHARP(lex->pos, l, SHIFT)>='8')
  952. my_yyerror("Illegal octal digit '%c'.",
  953. INDEX_CHARP(lex->pos, l, SHIFT));
  954. read_float:
  955. f=lex_strtod(lex->pos, &p1);
  956. SET_SVAL(sval, PIKE_T_INT, NUMBER_NUMBER, integer, 0);
  957. safe_wide_string_to_svalue_inumber(&sval,
  958. lex->pos,
  959. &p2,
  960. 0,
  961. 0,
  962. SHIFT);
  963. if(p1>p2)
  964. {
  965. /* Floating point or version. */
  966. if ((TYPEOF(sval) == PIKE_T_INT) &&
  967. (INDEX_CHARP(p2, 0, SHIFT) == '.')) {
  968. int major = sval.u.integer;
  969. char *p3 = p2;
  970. p2 += (1<<SHIFT);
  971. dmalloc_touch_svalue(&sval);
  972. sval.u.integer = 0;
  973. safe_wide_string_to_svalue_inumber(&sval,
  974. p2,
  975. &p3,
  976. 0,
  977. 0,
  978. SHIFT);
  979. dmalloc_touch_svalue(&sval);
  980. if ((TYPEOF(sval) == PIKE_T_INT) && (p3 > p2)) {
  981. for (l=0; wide_isspace(INDEX_CHARP(p3, l, SHIFT)); l++)
  982. ;
  983. if ((INDEX_CHARP(p3, l, SHIFT) == ':') &&
  984. (INDEX_CHARP(p3, l+1, SHIFT) == ':')) {
  985. /* Version prefix. */
  986. lex->pos = p3;
  987. yylval->n = mkversionnode(major, sval.u.integer);
  988. return TOK_VERSION;
  989. }
  990. }
  991. }
  992. free_svalue(&sval);
  993. yylval->fnum=f;
  994. #if 0
  995. fprintf(stderr, "LEX: \"%.8s\" => %"PRINTPIKEFLOAT"f\n",
  996. (char *)lex->pos, f);
  997. #endif /* 0 */
  998. lex->pos=p1;
  999. if (lex_isidchar (LOOK())) {
  1000. my_yyerror ("Invalid char '%c' in constant.", LOOK());
  1001. do SKIP(); while (lex_isidchar (LOOK()));
  1002. }
  1003. return TOK_FLOAT;
  1004. }else{
  1005. dmalloc_touch_svalue(&sval);
  1006. yylval->n = mksvaluenode(&sval);
  1007. free_svalue(&sval);
  1008. debug_malloc_touch(yylval->n);
  1009. lex->pos=p2;
  1010. if (lex_isidchar (LOOK()))
  1011. {
  1012. if( GOBBLE('b') )
  1013. if( GOBBLE( 'i' ) )
  1014. if( GOBBLE( 't' ) )
  1015. {
  1016. GOBBLE('s');
  1017. return TOK_BITS;
  1018. }
  1019. my_yyerror ("Invalid char '%c' in constant.", LOOK());
  1020. do SKIP(); while (lex_isidchar (LOOK()));
  1021. }
  1022. return TOK_NUMBER;
  1023. }
  1024. }
  1025. case '-':
  1026. if(GOBBLE('=')) return TOK_SUB_EQ;
  1027. if(GOBBLE('>')) {
  1028. if(GOBBLE('?') ) /* ->? */
  1029. return TOK_SAFE_INDEX;
  1030. else
  1031. return TOK_ARROW;
  1032. }
  1033. if(GOBBLE('-')) return TOK_DEC;
  1034. return '-';
  1035. case '+':
  1036. if(GOBBLE('=')) return TOK_ADD_EQ;
  1037. if(GOBBLE('+')) return TOK_INC;
  1038. return '+';
  1039. case '&':
  1040. if(GOBBLE('=')) return TOK_AND_EQ;
  1041. if(GOBBLE('&')) return TOK_LAND;
  1042. return '&';
  1043. case '|':
  1044. if(GOBBLE('=')) return TOK_OR_EQ;
  1045. if(GOBBLE('|')) return TOK_LOR;
  1046. return '|';
  1047. case '^':
  1048. if(GOBBLE('=')) return TOK_XOR_EQ;
  1049. return '^';
  1050. case '*':
  1051. if(GOBBLE('=')) return TOK_MULT_EQ;
  1052. if(GOBBLE('*'))
  1053. {
  1054. if(GOBBLE('=')) return TOK_POW_EQ;
  1055. return TOK_POW;
  1056. }
  1057. return '*';
  1058. case '%':
  1059. if(GOBBLE('=')) return TOK_MOD_EQ;
  1060. return '%';
  1061. case '/':
  1062. if(GOBBLE('=')) return TOK_DIV_EQ;
  1063. return '/';
  1064. case '=':
  1065. if(GOBBLE('=')) return TOK_EQ;
  1066. return '=';
  1067. case '<':
  1068. if(GOBBLE('<'))
  1069. {
  1070. if(GOBBLE('=')) return TOK_LSH_EQ;
  1071. return TOK_LSH;
  1072. }
  1073. if(GOBBLE('=')) return TOK_LE;
  1074. return '<';
  1075. case '>':
  1076. if(GOBBLE(')')) return TOK_MULTISET_END;
  1077. if(GOBBLE('=')) return TOK_GE;
  1078. if(GOBBLE('>'))
  1079. {
  1080. if(GOBBLE('=')) return TOK_RSH_EQ;
  1081. return TOK_RSH;
  1082. }
  1083. return '>';
  1084. case '!':
  1085. if(GOBBLE('=')) return TOK_NE;
  1086. return TOK_NOT;
  1087. case '(':
  1088. if(GOBBLE('<')) return TOK_MULTISET_START;
  1089. if(GOBBLE('?') ) /* (? */
  1090. return TOK_SAFE_APPLY;
  1091. return '(';
  1092. case '?':
  1093. if(GOBBLE(':'))
  1094. return TOK_LOR;
  1095. if(GOBBLE('-') )
  1096. {
  1097. if( GOBBLE( '>' ) ) { /* ?-> */
  1098. yywarning(" ?-> safe indexing is deprecated, use ->?");
  1099. return TOK_SAFE_INDEX;
  1100. }
  1101. SKIPN(-1); /* Undo GOBBLE('-') above */
  1102. }
  1103. if (GOBBLE('='))
  1104. return TOK_ATOMIC_GET_SET;
  1105. /* FALLTHRU */
  1106. case ']':
  1107. case ',':
  1108. case '~':
  1109. case '@':
  1110. case ')':
  1111. case '{':
  1112. case ';':
  1113. case '}': return c;
  1114. case '[':
  1115. if( GOBBLE('?' ) )
  1116. return TOK_SAFE_START_INDEX;
  1117. return c;
  1118. case '`':
  1119. {
  1120. char *tmp;
  1121. int offset=2;
  1122. if(GOBBLE('`')) {
  1123. offset--;
  1124. if(GOBBLE('`')) {
  1125. offset--;
  1126. }
  1127. }
  1128. switch(c = GETC())
  1129. {
  1130. case '/': tmp="```/"; break;
  1131. case '%': tmp="```%"; break;
  1132. case '*':
  1133. if( GOBBLE('*') )
  1134. tmp="```**";
  1135. else
  1136. tmp="```*";
  1137. break;
  1138. case '&': tmp="```&"; break;
  1139. case '|': tmp="```|"; break;
  1140. case '^': tmp="```^"; break;
  1141. case '~': tmp="```~"; break;
  1142. case '+':
  1143. if(GOBBLE('=')) { tmp="```+="; break; }
  1144. tmp="```+";
  1145. break;
  1146. case '<':
  1147. if(GOBBLE('<')) { tmp="```<<"; break; }
  1148. if(GOBBLE('=')) { tmp="```<="; break; }
  1149. tmp="```<";
  1150. break;
  1151. case '>':
  1152. if(GOBBLE('>')) { tmp="```>>"; break; }
  1153. if(GOBBLE('=')) { tmp="```>="; break; }
  1154. tmp="```>";
  1155. break;
  1156. case '!':
  1157. if(GOBBLE('=')) { tmp="```!="; break; }
  1158. tmp="```!";
  1159. break;
  1160. case '=':
  1161. if(GOBBLE('=')) { tmp="```=="; break; }
  1162. tmp="```=";
  1163. break;
  1164. case '(':
  1165. tmp="```()";
  1166. if(GOBBLE(')'))
  1167. {
  1168. break;
  1169. }
  1170. yyerror("Illegal ` identifier. Expected `().");
  1171. break;
  1172. case '-':
  1173. if(GOBBLE('>'))
  1174. {
  1175. if ((offset == 2) && lex_isidchar(LOOK())) {
  1176. /* Getter/setter (old-style)
  1177. *
  1178. * Either
  1179. * `->symbol
  1180. * Or
  1181. * `->symbol=
  1182. */
  1183. char *buf;
  1184. size_t len;
  1185. struct pike_string *s;
  1186. READBUF(lex_isidchar(C));
  1187. if (GOBBLE('=')) len += 1;
  1188. /* Adjust for the prefix (`->). */
  1189. len += 3;
  1190. buf -= 3<<SHIFT;
  1191. #if (SHIFT == 0)
  1192. s = make_shared_binary_string(buf, len);
  1193. #else /* SHIFT != 0 */
  1194. #if (SHIFT == 1)
  1195. s = make_shared_binary_string1((p_wchar1 *)buf, len);
  1196. #else /* SHIFT != 1 */
  1197. s = make_shared_binary_string2((p_wchar2 *)buf, len);
  1198. #endif /* SHIFT == 1 */
  1199. #endif /* SHIFT == 0 */
  1200. yylval->n = mkstrnode(s);
  1201. free_string(s);
  1202. return TOK_IDENTIFIER;
  1203. }
  1204. tmp="```->";
  1205. if(GOBBLE('=')) tmp="```->=";
  1206. }else{
  1207. tmp="```-";
  1208. }
  1209. break;
  1210. case '[':
  1211. tmp="```[]";
  1212. if(GOBBLE(']'))
  1213. {
  1214. if(GOBBLE('=')) tmp="```[]=";
  1215. break;
  1216. }
  1217. if (GOBBLE ('.') && GOBBLE ('.') && GOBBLE (']')) {
  1218. tmp = "```[..]";
  1219. break;
  1220. }
  1221. yyerror("Illegal ` identifier. Expected `[], `[]= or `[..].");
  1222. break;
  1223. default:
  1224. if (offset==2 && lex_isidchar(c)) {
  1225. /* Getter/setter (new-style)
  1226. *
  1227. * Either
  1228. * `symbol
  1229. * Or
  1230. * `symbol=
  1231. */
  1232. char *buf;
  1233. size_t len;
  1234. struct pike_string *s;
  1235. READBUF(lex_isidchar(C));
  1236. if (GOBBLE('=')) len += 1;
  1237. /* Adjust for the prefix (`c). */
  1238. len += 2;
  1239. buf -= 2<<SHIFT;
  1240. #if (SHIFT == 0)
  1241. s = make_shared_binary_string(buf, len);
  1242. #else /* SHIFT != 0 */
  1243. #if (SHIFT == 1)
  1244. s = make_shared_binary_string1((p_wchar1 *)buf, len);
  1245. #else /* SHIFT != 1 */
  1246. s = make_shared_binary_string2((p_wchar2 *)buf, len);
  1247. #endif /* SHIFT == 1 */
  1248. #endif /* SHIFT == 0 */
  1249. yylval->n = mkstrnode(s);
  1250. free_string(s);
  1251. return TOK_IDENTIFIER;
  1252. }
  1253. yyerror("Illegal ` identifier.");
  1254. lex->pos -= (1<<SHIFT);
  1255. tmp="```";
  1256. break;
  1257. }
  1258. {
  1259. struct pike_string *s=make_shared_string(tmp+offset);
  1260. yylval->n=mkstrnode(s);
  1261. free_string(s);
  1262. return TOK_IDENTIFIER;
  1263. }
  1264. }
  1265. default:
  1266. {
  1267. if (c > 31) {
  1268. my_yyerror("Illegal character '%c' (0x%02x)", c, c);
  1269. } else {
  1270. my_yyerror("Illegal character 0x%02x", c);
  1271. }
  1272. return ' ';
  1273. }
  1274. }
  1275. }
  1276. }
  1277. /*
  1278. * Clear the defines for the next pass
  1279. */
  1280. #undef WCHAR
  1281. #undef LOOK
  1282. #undef GETC
  1283. #undef SKIP
  1284. #undef SKIPN
  1285. #undef GOBBLE
  1286. #undef SKIPSPACE
  1287. #undef SKIPWHITE
  1288. #undef SKIPUPTO
  1289. #undef READBUF
  1290. #undef TWO_CHAR
  1291. #undef ISWORD
  1292. #undef low_isword
  1293. #undef parse_esc_seq
  1294. #undef char_const
  1295. #undef readstring
  1296. #undef yylex
  1297. #undef low_yylex
  1298. #undef lex_atoi
  1299. #undef lex_strtol
  1300. #undef lex_strtod
  1301. #undef lex_isidchar