PageRenderTime 172ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/lexer.h

http://github.com/pikelang/Pike
C Header | 1418 lines | 1201 code | 114 blank | 103 comment | 238 complexity | efc8c75249da8ae34c99b957fe48109c MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception
  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. /* Allow triple (or more) underscore for the user, and make sure we
  590. * don't get false matches below for wide strings.
  591. */
  592. if((INDEX_CHARP(buf, 2, SHIFT) == '_') ||
  593. (INDEX_CHARP(buf, len-3, SHIFT) == '_') ||
  594. (INDEX_CHARP(buf, len-2, SHIFT) != '_') ||
  595. (INDEX_CHARP(buf, len-1, SHIFT) != '_') ||
  596. (INDEX_CHARP(buf, 0, SHIFT) != '_') ||
  597. (INDEX_CHARP(buf, 1, SHIFT) != '_')) break;
  598. {
  599. /* Double underscore before and after is reserved for keywords. */
  600. #if (SHIFT == 0)
  601. struct pike_string *tmp = make_shared_binary_string(buf, len);
  602. #else /* SHIFT != 0 */
  603. #if (SHIFT == 1)
  604. struct pike_string *tmp = make_shared_binary_string1((p_wchar1 *)buf,
  605. len);
  606. #else /* SHIFT != 1 */
  607. struct pike_string *tmp = make_shared_binary_string2((p_wchar2 *)buf,
  608. len);
  609. #endif /* SHIFT == 1 */
  610. #endif /* SHIFT == 0 */
  611. yylval->n=mkstrnode(tmp);
  612. /* - But only for lower case US-ASCII.
  613. * - Upper case is used for symbols intended for #if constant().
  614. */
  615. if (tmp->size_shift) {
  616. free_string(tmp);
  617. return TOK_IDENTIFIER;
  618. }
  619. if(ISWORD("__args__")) {
  620. free_string(tmp);
  621. return TOK_IDENTIFIER;
  622. }
  623. while(len--) {
  624. int c = tmp->str[len];
  625. if ((c >= 'A') && (c <= 'Z')) {
  626. free_string(tmp);
  627. return TOK_IDENTIFIER;
  628. }
  629. }
  630. free_string(tmp);
  631. }
  632. return TOK_RESERVED;
  633. }
  634. }
  635. {
  636. #if (SHIFT == 0)
  637. struct pike_string *tmp = make_shared_binary_string(buf, len);
  638. #else /* SHIFT != 0 */
  639. #if (SHIFT == 1)
  640. struct pike_string *tmp = make_shared_binary_string1((p_wchar1 *)buf,
  641. len);
  642. #else /* SHIFT != 1 */
  643. struct pike_string *tmp = make_shared_binary_string2((p_wchar2 *)buf,
  644. len);
  645. #endif /* SHIFT == 1 */
  646. #endif /* SHIFT == 0 */
  647. yylval->n=mkstrnode(tmp);
  648. free_string(tmp);
  649. return TOK_IDENTIFIER;
  650. }
  651. }
  652. /* Note that 0 <= c <= 255 at this point. */
  653. switch(c)
  654. {
  655. case 0:
  656. lex->pos -= (1<<SHIFT);
  657. if(lex->end != lex->pos)
  658. yyerror("Illegal character (NUL)");
  659. #ifdef TOK_LEX_EOF
  660. return TOK_LEX_EOF;
  661. #else /* !TOK_LEX_EOF */
  662. return 0;
  663. #endif /* TOK_LEX_EOF */
  664. case '\n':
  665. lex->current_line++;
  666. continue;
  667. case 0x1b: case 0x9b: /* ESC or CSI */
  668. /* Assume ANSI/DEC escape sequence.
  669. * Format supported:
  670. * <ESC>[\040-\077]+[\100-\177]
  671. * or
  672. * <CSI>[\040-\077]*[\100-\177]
  673. */
  674. while ((c = LOOK()) && (c == ((c & 0x1f)|0x20))) {
  675. SKIP();
  676. }
  677. if (c == ((c & 0x3f)|0x40)) {
  678. SKIP();
  679. } else {
  680. /* FIXME: Warning here? */
  681. }
  682. continue;
  683. case '#':
  684. SKIPSPACE();
  685. READBUF(!wide_isspace(C));
  686. switch(len>0?INDEX_CHARP(buf, 0, SHIFT):0)
  687. {
  688. case 'l':
  689. if (ISWORD("line"))
  690. {
  691. SKIPSPACE();
  692. if (LOOK() < '0' || LOOK() > '9') goto unknown_directive;
  693. READBUF(!wide_isspace(C));
  694. } else goto unknown_directive;
  695. /* FALLTHRU */
  696. case '0': case '1': case '2': case '3': case '4':
  697. case '5': case '6': case '7': case '8': case '9':
  698. lex->current_line = lex_strtol(buf, NULL, 10)-1;
  699. SKIPSPACE();
  700. if(GOBBLE('"'))
  701. {
  702. struct pike_string *tmp=readstring(lex);
  703. free_string(lex->current_file);
  704. lex->current_file = dmalloc_touch(struct pike_string *, tmp);
  705. }
  706. if (Pike_compiler->compiler_pass == COMPILER_PASS_FIRST &&
  707. !Pike_compiler->new_program->num_linenumbers) {
  708. /* A nested program will always get an entry right away in
  709. * language.yacc. */
  710. store_linenumber(0, lex->current_file);
  711. #ifdef DEBUG_MALLOC
  712. if(strcmp(lex->current_file->str,"-"))
  713. debug_malloc_name(Pike_compiler->new_program, lex->current_file->str, 0);
  714. #endif
  715. }
  716. break;
  717. case 'p':
  718. if(ISWORD("pragma"))
  719. {
  720. SKIPSPACE();
  721. READBUF(!wide_isspace(C));
  722. if (ISWORD("all_inline"))
  723. {
  724. lex->pragmas |= ID_INLINE;
  725. }
  726. else if (ISWORD("all_final"))
  727. {
  728. lex->pragmas |= ID_FINAL;
  729. }
  730. else if (ISWORD("strict_types"))
  731. {
  732. lex->pragmas |= ID_STRICT_TYPES;
  733. }
  734. else if (ISWORD("no_strict_types"))
  735. {
  736. lex->pragmas &= ~ID_STRICT_TYPES;
  737. }
  738. else if (ISWORD("save_parent"))
  739. {
  740. lex->pragmas |= ID_SAVE_PARENT;
  741. }
  742. else if (ISWORD("dont_save_parent"))
  743. {
  744. lex->pragmas |= ID_DONT_SAVE_PARENT;
  745. }
  746. else if (ISWORD("no_deprecation_warnings"))
  747. {
  748. lex->pragmas |= ID_NO_DEPRECATION_WARNINGS;
  749. }
  750. else if (ISWORD("deprecation_warnings"))
  751. {
  752. lex->pragmas &= ~ID_NO_DEPRECATION_WARNINGS;
  753. }
  754. else if (ISWORD("disassemble"))
  755. {
  756. lex->pragmas |= ID_DISASSEMBLE;
  757. }
  758. else if (ISWORD("no_disassemble"))
  759. {
  760. lex->pragmas &= ~ID_DISASSEMBLE;
  761. }
  762. else if (ISWORD("dynamic_dot"))
  763. {
  764. lex->pragmas |= ID_DYNAMIC_DOT;
  765. }
  766. else if (ISWORD("no_dynamic_dot"))
  767. {
  768. lex->pragmas &= ~ID_DYNAMIC_DOT;
  769. }
  770. else
  771. {
  772. if( Pike_compiler->compiler_pass == COMPILER_PASS_FIRST )
  773. yywarning("Unknown #pragma directive.");
  774. }
  775. break;
  776. }
  777. if(ISWORD("pike"))
  778. {
  779. int minor;
  780. int major;
  781. SKIPSPACE();
  782. READBUF(C!='.' && C!='\n');
  783. major=lex_atoi(buf);
  784. if(!GOBBLE('.'))
  785. {
  786. yyerror("Missing '.' in #pike directive.");
  787. minor=0;
  788. }else{
  789. READBUF(C!='\n' && C!='.');
  790. minor=lex_atoi(buf);
  791. if(GOBBLE('.'))
  792. yyerror("Build numbers not supported in #pike directive.");
  793. READBUF(C!='\n');
  794. change_compiler_compatibility(major, minor);
  795. }
  796. break;
  797. }
  798. /* FALLTHRU */
  799. default:
  800. unknown_directive:
  801. if (len < 256) {
  802. #if (SHIFT == 0)
  803. struct pike_string *dir =
  804. make_shared_binary_string(buf, len);
  805. #elif (SHIFT == 1)
  806. struct pike_string *dir =
  807. make_shared_binary_string1((p_wchar1 *)buf, len);
  808. #elif (SHIFT == 2)
  809. struct pike_string *dir =
  810. make_shared_binary_string2((p_wchar2 *)buf, len);
  811. #endif
  812. my_yyerror("Unknown preprocessor directive %S.", dir);
  813. free_string(dir);
  814. } else {
  815. yyerror("Unknown preprocessor directive.");
  816. }
  817. SKIPUPTO('\n');
  818. continue;
  819. }
  820. continue;
  821. case ' ':
  822. case '\t':
  823. case '\r':
  824. continue;
  825. case '\'':
  826. {
  827. unsigned int l = 0;
  828. struct svalue res = svalue_int_zero;
  829. MP_INT bigint;
  830. while(1)
  831. {
  832. INT32 tmp;
  833. switch( (tmp=GETC()) )
  834. {
  835. case 0:
  836. lex->pos -= (1<<SHIFT);
  837. yyerror("Unexpected end of file\n");
  838. goto return_char;
  839. case '\\':
  840. tmp = char_const(lex);
  841. /* fallthrough. */
  842. default:
  843. l++;
  844. if( l == sizeof(INT_TYPE)-1 )
  845. {
  846. /* overflow possible. Switch to bignums. */
  847. mpz_init(&bigint);
  848. mpz_set_ui(&bigint,res.u.integer);
  849. TYPEOF(res) = PIKE_T_OBJECT;
  850. }
  851. if( l >= sizeof(INT_TYPE)-1 )
  852. {
  853. mpz_mul_2exp(&bigint,&bigint,8);
  854. mpz_add_ui(&bigint,&bigint,tmp);
  855. }
  856. else
  857. {
  858. res.u.integer <<= 8;
  859. res.u.integer |= tmp;
  860. }
  861. break;
  862. case '\'':
  863. if( l == 0 )
  864. yyerror("Zero-length character constant.");
  865. goto return_char;
  866. }
  867. }
  868. return_char:
  869. if( TYPEOF(res) == PIKE_T_OBJECT )
  870. {
  871. push_bignum( &bigint );
  872. mpz_clear(&bigint);
  873. reduce_stack_top_bignum();
  874. res = *--Pike_sp;
  875. }
  876. debug_malloc_pass( yylval->n=mksvaluenode(&res) );
  877. free_svalue( &res );
  878. return TOK_NUMBER;
  879. }
  880. UNREACHABLE(break);
  881. case '"':
  882. {
  883. struct pike_string *s=readstring(lex);
  884. yylval->n=mkstrnode(s);
  885. free_string(s);
  886. return TOK_STRING;
  887. }
  888. case ':':
  889. if(GOBBLE(':')) return TOK_COLON_COLON;
  890. return c;
  891. case '.':
  892. if(GOBBLE('.'))
  893. {
  894. if(GOBBLE('.')) return TOK_DOT_DOT_DOT;
  895. return TOK_DOT_DOT;
  896. }
  897. if (((c = INDEX_CHARP(lex->pos, 0, SHIFT)) <= '9') &&
  898. (c >= '0')) {
  899. lex->pos -= (1<<SHIFT);
  900. goto read_float;
  901. }
  902. return '.';
  903. case '0':
  904. {
  905. int base = 0;
  906. if(GOBBLE('b') || GOBBLE('B'))
  907. {
  908. base = 2;
  909. goto read_based_number;
  910. }
  911. else if(GOBBLE('x') || GOBBLE('X'))
  912. {
  913. struct svalue sval;
  914. base = 16;
  915. read_based_number:
  916. SET_SVAL(sval, PIKE_T_INT, NUMBER_NUMBER, integer, 0);
  917. safe_wide_string_to_svalue_inumber(&sval,
  918. lex->pos,
  919. &lex->pos,
  920. base,
  921. 0,
  922. SHIFT);
  923. dmalloc_touch_svalue(&sval);
  924. yylval->n = mksvaluenode(&sval);
  925. free_svalue(&sval);
  926. return TOK_NUMBER;
  927. }
  928. }
  929. /* FALLTHRU */
  930. case '1': case '2': case '3': case '4':
  931. case '5': case '6': case '7': case '8': case '9':
  932. {
  933. char *p1, *p2;
  934. FLOAT_TYPE f;
  935. long l;
  936. struct svalue sval;
  937. lex->pos -= (1<<SHIFT);
  938. if(INDEX_CHARP(lex->pos, 0, SHIFT)=='0')
  939. for(l=1;INDEX_CHARP(lex->pos, l, SHIFT)<='9' &&
  940. INDEX_CHARP(lex->pos, l, SHIFT)>='0';l++)
  941. if(INDEX_CHARP(lex->pos, l, SHIFT)>='8')
  942. my_yyerror("Illegal octal digit '%c'.",
  943. INDEX_CHARP(lex->pos, l, SHIFT));
  944. read_float:
  945. f=lex_strtod(lex->pos, &p1);
  946. SET_SVAL(sval, PIKE_T_INT, NUMBER_NUMBER, integer, 0);
  947. safe_wide_string_to_svalue_inumber(&sval,
  948. lex->pos,
  949. &p2,
  950. 0,
  951. 0,
  952. SHIFT);
  953. if(p1>p2)
  954. {
  955. /* Floating point or version. */
  956. if ((TYPEOF(sval) == PIKE_T_INT) &&
  957. (INDEX_CHARP(p2, 0, SHIFT) == '.')) {
  958. int major = sval.u.integer;
  959. char *p3 = p2;
  960. p2 += (1<<SHIFT);
  961. dmalloc_touch_svalue(&sval);
  962. sval.u.integer = 0;
  963. safe_wide_string_to_svalue_inumber(&sval,
  964. p2,
  965. &p3,
  966. 0,
  967. 0,
  968. SHIFT);
  969. dmalloc_touch_svalue(&sval);
  970. if ((TYPEOF(sval) == PIKE_T_INT) && (p3 > p2)) {
  971. for (l=0; wide_isspace(INDEX_CHARP(p3, l, SHIFT)); l++)
  972. ;
  973. if ((INDEX_CHARP(p3, l, SHIFT) == ':') &&
  974. (INDEX_CHARP(p3, l+1, SHIFT) == ':')) {
  975. /* Version prefix. */
  976. lex->pos = p3;
  977. yylval->n = mkversionnode(major, sval.u.integer);
  978. return TOK_VERSION;
  979. }
  980. }
  981. }
  982. free_svalue(&sval);
  983. yylval->fnum=f;
  984. #if 0
  985. fprintf(stderr, "LEX: \"%.8s\" => %"PRINTPIKEFLOAT"f\n",
  986. (char *)lex->pos, f);
  987. #endif /* 0 */
  988. lex->pos=p1;
  989. if (lex_isidchar (LOOK())) {
  990. my_yyerror ("Invalid char '%c' in constant.", LOOK());
  991. do SKIP(); while (lex_isidchar (LOOK()));
  992. }
  993. return TOK_FLOAT;
  994. }else{
  995. dmalloc_touch_svalue(&sval);
  996. yylval->n = mksvaluenode(&sval);
  997. free_svalue(&sval);
  998. debug_malloc_touch(yylval->n);
  999. lex->pos=p2;
  1000. if (lex_isidchar (LOOK()))
  1001. {
  1002. if( GOBBLE('b') )
  1003. if( GOBBLE( 'i' ) )
  1004. if( GOBBLE( 't' ) )
  1005. {
  1006. GOBBLE('s');
  1007. return TOK_BITS;
  1008. }
  1009. my_yyerror ("Invalid char '%c' in constant.", LOOK());
  1010. do SKIP(); while (lex_isidchar (LOOK()));
  1011. }
  1012. return TOK_NUMBER;
  1013. }
  1014. }
  1015. case '-':
  1016. if(GOBBLE('=')) return TOK_SUB_EQ;
  1017. if(GOBBLE('>')) {
  1018. if(GOBBLE('?') ) /* ->? */
  1019. return TOK_SAFE_INDEX;
  1020. else
  1021. return TOK_ARROW;
  1022. }
  1023. if(GOBBLE('-')) return TOK_DEC;
  1024. return '-';
  1025. case '+':
  1026. if(GOBBLE('=')) return TOK_ADD_EQ;
  1027. if(GOBBLE('+')) return TOK_INC;
  1028. return '+';
  1029. case '&':
  1030. if(GOBBLE('=')) return TOK_AND_EQ;
  1031. if(GOBBLE('&')) return TOK_LAND;
  1032. return '&';
  1033. case '|':
  1034. if(GOBBLE('=')) return TOK_OR_EQ;
  1035. if(GOBBLE('|')) return TOK_LOR;
  1036. return '|';
  1037. case '^':
  1038. if(GOBBLE('=')) return TOK_XOR_EQ;
  1039. return '^';
  1040. case '*':
  1041. if(GOBBLE('=')) return TOK_MULT_EQ;
  1042. if(GOBBLE('*'))
  1043. {
  1044. if(GOBBLE('=')) return TOK_POW_EQ;
  1045. return TOK_POW;
  1046. }
  1047. return '*';
  1048. case '%':
  1049. if(GOBBLE('=')) return TOK_MOD_EQ;
  1050. return '%';
  1051. case '/':
  1052. if(GOBBLE('=')) return TOK_DIV_EQ;
  1053. return '/';
  1054. case '=':
  1055. if(GOBBLE('=')) return TOK_EQ;
  1056. return '=';
  1057. case '<':
  1058. if(GOBBLE('<'))
  1059. {
  1060. if(GOBBLE('=')) return TOK_LSH_EQ;
  1061. return TOK_LSH;
  1062. }
  1063. if(GOBBLE('=')) return TOK_LE;
  1064. return '<';
  1065. case '>':
  1066. if(GOBBLE(')')) return TOK_MULTISET_END;
  1067. if(GOBBLE('=')) return TOK_GE;
  1068. if(GOBBLE('>'))
  1069. {
  1070. if(GOBBLE('=')) return TOK_RSH_EQ;
  1071. return TOK_RSH;
  1072. }
  1073. return '>';
  1074. case '!':
  1075. if(GOBBLE('=')) return TOK_NE;
  1076. return TOK_NOT;
  1077. case '(':
  1078. if(GOBBLE('<')) return TOK_MULTISET_START;
  1079. if(GOBBLE('?') ) /* (? */
  1080. return TOK_SAFE_APPLY;
  1081. return '(';
  1082. case '?':
  1083. if(GOBBLE(':'))
  1084. return TOK_LOR;
  1085. if(GOBBLE('-') )
  1086. {
  1087. if( GOBBLE( '>' ) ) { /* ?-> */
  1088. yywarning(" ?-> safe indexing is deprecated, use ->?");
  1089. return TOK_SAFE_INDEX;
  1090. }
  1091. SKIPN(-1); /* Undo GOBBLE('-') above */
  1092. }
  1093. if (GOBBLE('='))
  1094. return TOK_ATOMIC_GET_SET;
  1095. /* FALLTHRU */
  1096. case ']':
  1097. case ',':
  1098. case '~':
  1099. case '@':
  1100. case ')':
  1101. case '{':
  1102. case ';':
  1103. case '}': return c;
  1104. case '[':
  1105. if( GOBBLE('?' ) )
  1106. return TOK_SAFE_START_INDEX;
  1107. return c;
  1108. case '`':
  1109. {
  1110. char *tmp;
  1111. int offset=2;
  1112. if(GOBBLE('`')) {
  1113. offset--;
  1114. if(GOBBLE('`')) {
  1115. offset--;
  1116. }
  1117. }
  1118. switch(c = GETC())
  1119. {
  1120. case '/': tmp="```/"; break;
  1121. case '%': tmp="```%"; break;
  1122. case '*':
  1123. if( GOBBLE('*') )
  1124. tmp="```**";
  1125. else
  1126. tmp="```*";
  1127. break;
  1128. case '&': tmp="```&"; break;
  1129. case '|': tmp="```|"; break;
  1130. case '^': tmp="```^"; break;
  1131. case '~': tmp="```~"; break;
  1132. case '+':
  1133. if(GOBBLE('=')) { tmp="```+="; break; }
  1134. tmp="```+";
  1135. break;
  1136. case '<':
  1137. if(GOBBLE('<')) { tmp="```<<"; break; }
  1138. if(GOBBLE('=')) { tmp="```<="; break; }
  1139. tmp="```<";
  1140. break;
  1141. case '>':
  1142. if(GOBBLE('>')) { tmp="```>>"; break; }
  1143. if(GOBBLE('=')) { tmp="```>="; break; }
  1144. tmp="```>";
  1145. break;
  1146. case '!':
  1147. if(GOBBLE('=')) { tmp="```!="; break; }
  1148. tmp="```!";
  1149. break;
  1150. case '=':
  1151. if(GOBBLE('=')) { tmp="```=="; break; }
  1152. tmp="```=";
  1153. break;
  1154. case '(':
  1155. tmp="```()";
  1156. if(GOBBLE(')'))
  1157. {
  1158. break;
  1159. }
  1160. yyerror("Illegal ` identifier. Expected `().");
  1161. break;
  1162. case '-':
  1163. if(GOBBLE('>'))
  1164. {
  1165. if ((offset == 2) && lex_isidchar(LOOK())) {
  1166. /* Getter/setter (old-style)
  1167. *
  1168. * Either
  1169. * `->symbol
  1170. * Or
  1171. * `->symbol=
  1172. */
  1173. char *buf;
  1174. size_t len;
  1175. struct pike_string *s;
  1176. READBUF(lex_isidchar(C));
  1177. if (GOBBLE('=')) len += 1;
  1178. /* Adjust for the prefix (`->). */
  1179. len += 3;
  1180. buf -= 3<<SHIFT;
  1181. #if (SHIFT == 0)
  1182. s = make_shared_binary_string(buf, len);
  1183. #else /* SHIFT != 0 */
  1184. #if (SHIFT == 1)
  1185. s = make_shared_binary_string1((p_wchar1 *)buf, len);
  1186. #else /* SHIFT != 1 */
  1187. s = make_shared_binary_string2((p_wchar2 *)buf, len);
  1188. #endif /* SHIFT == 1 */
  1189. #endif /* SHIFT == 0 */
  1190. yylval->n = mkstrnode(s);
  1191. free_string(s);
  1192. return TOK_IDENTIFIER;
  1193. }
  1194. tmp="```->";
  1195. if(GOBBLE('=')) tmp="```->=";
  1196. }else{
  1197. tmp="```-";
  1198. }
  1199. break;
  1200. case '[':
  1201. tmp="```[]";
  1202. if(GOBBLE(']'))
  1203. {
  1204. if(GOBBLE('=')) tmp="```[]=";
  1205. break;
  1206. }
  1207. if (GOBBLE ('.') && GOBBLE ('.') && GOBBLE (']')) {
  1208. tmp = "```[..]";
  1209. break;
  1210. }
  1211. yyerror("Illegal ` identifier. Expected `[], `[]= or `[..].");
  1212. break;
  1213. default:
  1214. if (offset==2 && lex_isidchar(c)) {
  1215. /* Getter/setter (new-style)
  1216. *
  1217. * Either
  1218. * `symbol
  1219. * Or
  1220. * `symbol=
  1221. */
  1222. char *buf;
  1223. size_t len;
  1224. struct pike_string *s;
  1225. READBUF(lex_isidchar(C));
  1226. if (GOBBLE('=')) len += 1;
  1227. /* Adjust for the prefix (`c). */
  1228. len += 2;
  1229. buf -= 2<<SHIFT;
  1230. #if (SHIFT == 0)
  1231. s = make_shared_binary_string(buf, len);
  1232. #else /* SHIFT != 0 */
  1233. #if (SHIFT == 1)
  1234. s = make_shared_binary_string1((p_wchar1 *)buf, len);
  1235. #else /* SHIFT != 1 */
  1236. s = make_shared_binary_string2((p_wchar2 *)buf, len);
  1237. #endif /* SHIFT == 1 */
  1238. #endif /* SHIFT == 0 */
  1239. yylval->n = mkstrnode(s);
  1240. free_string(s);
  1241. return TOK_IDENTIFIER;
  1242. }
  1243. yyerror("Illegal ` identifier.");
  1244. lex->pos -= (1<<SHIFT);
  1245. tmp="```";
  1246. break;
  1247. }
  1248. {
  1249. struct pike_string *s=make_shared_string(tmp+offset);
  1250. yylval->n=mkstrnode(s);
  1251. free_string(s);
  1252. return TOK_IDENTIFIER;
  1253. }
  1254. }
  1255. default:
  1256. {
  1257. if (c > 31) {
  1258. my_yyerror("Illegal character '%c' (0x%02x)", c, c);
  1259. } else {
  1260. my_yyerror("Illegal character 0x%02x", c);
  1261. }
  1262. return ' ';
  1263. }
  1264. }
  1265. }
  1266. }
  1267. /*
  1268. * Clear the defines for the next pass
  1269. */
  1270. #undef WCHAR
  1271. #undef LOOK
  1272. #undef GETC
  1273. #undef SKIP
  1274. #undef SKIPN
  1275. #undef GOBBLE
  1276. #undef SKIPSPACE
  1277. #undef SKIPWHITE
  1278. #undef SKIPUPTO
  1279. #undef READBUF
  1280. #undef TWO_CHAR
  1281. #undef ISWORD
  1282. #undef low_isword
  1283. #undef parse_esc_seq
  1284. #undef char_const
  1285. #undef readstring
  1286. #undef yylex
  1287. #undef low_yylex
  1288. #undef lex_atoi
  1289. #undef lex_strtol
  1290. #undef lex_strtod
  1291. #undef lex_isidchar