lex.c.2
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:36k
源码类别:

编译器/解释器

开发平台:

C/C++

  1.                         if (cp != closing)
  2.                             return 0;
  3.                         strlist_remove((Strlist **)rctable[i].ptr, namebuf);
  4.                     } else {
  5.                         if (!isspace(*cp) && *cp != '=')
  6.                             return 0;
  7.                         skipspc(cp);
  8.                         if (*cp == '=') {
  9.                             cp++;
  10.                             skipspc(cp);
  11.                         }
  12.                         if (chgmode == '=' || isspace(chgmode))
  13.                             strlist_remove((Strlist **)rctable[i].ptr, namebuf);
  14.                         sp = strlist_append((Strlist **)rctable[i].ptr, namebuf);
  15.                         if (tempopt)
  16.                             strlist_insert(&tempoptionlist, namebuf)->value = i;
  17.                         cp2 = namebuf;
  18.                         while (*cp && cp != closing && !isspace(*cp))
  19.                             *cp2++ = *cp++;
  20.                         *cp2++ = 0;
  21.                         skipspc(cp);
  22.                         if (cp != closing)
  23.                             return 0;
  24.                         sp->value = (long)stralloc(namebuf);
  25.                     }
  26.                     inbufptr = after;
  27.                     if (lex_initialized)
  28.                         handle_nameof();        /* as good a place to do this as any! */
  29.                     return 1;
  30.                 case 3:     /* Synonym parameter */
  31.     if (isspace(*cp) || *cp == '=' ||
  32. *cp == '+' || *cp == '-') {
  33. chgmode = *cp++;
  34. skipspc(cp);
  35. cp2 = namebuf;
  36. while (isalnum(*cp) || *cp == '_' ||
  37.        *cp == '$' || *cp == '%')
  38.     *cp2++ = *cp++;
  39. *cp2++ = 0;
  40. if (!*namebuf)
  41.     return 0;
  42. skipspc(cp);
  43. if (!pascalcasesens)
  44.     upc(namebuf);
  45. sym = findsymbol(namebuf);
  46. if (chgmode == '-') {
  47.     if (cp != closing)
  48. return 0;
  49.     sym->flags &= ~SSYNONYM;
  50.     inbufptr = after;
  51.     return 1;
  52. }
  53. if (*cp == '=') {
  54.     cp++;
  55.     skipspc(cp);
  56. }
  57. cp2 = namebuf;
  58. while (isalnum(*cp) || *cp == '_' ||
  59.        *cp == '$' || *cp == '%')
  60.     *cp2++ = *cp++;
  61. *cp2++ = 0;
  62. skipspc(cp);
  63. if (cp != closing)
  64.     return 0;
  65. sym->flags |= SSYNONYM;
  66. if (!pascalcasesens)
  67.     upc(namebuf);
  68. if (*namebuf)
  69.     strlist_append(&sym->symbolnames, "===")->value =
  70. (long)findsymbol(namebuf);
  71. else
  72.     strlist_append(&sym->symbolnames, "===")->value=0;
  73. inbufptr = after;
  74. return 1;
  75.     }
  76.     return 0;
  77.             }
  78.             return 0;
  79.     }
  80.     return 0;
  81. }
  82. Static void comment(starparen)
  83. int starparen;    /* 0={ }, 1=(* *), 2=C comments*/
  84. {
  85.     register char ch;
  86.     int nestcount = 1, startlnum = inf_lnum, trailing;
  87.     int i, cmtindent, cmtindent2;
  88.     char *cp;
  89.     cp = inbuf;
  90.     while (isspace(*cp))
  91. cp++;
  92.     trailing = (*cp != '{' && ((*cp != '(' && *cp != '/') || cp[1] != '*'));
  93.     cmtindent = inbufindent;
  94.     cmtindent2 = cmtindent + 1 + (starparen != 0);
  95.     cp = inbufptr;
  96.     while (isspace(*cp))
  97. cmtindent2++, cp++;
  98.     cp = curtokbuf;
  99.     for (;;) {
  100.         ch = *inbufptr++;
  101.         switch (ch) {
  102.             case '}':
  103.                 if ((!starparen || nestedcomments == 0) &&
  104.     starparen != 2 &&
  105.                     --nestcount <= 0) {
  106.                     *cp = 0;
  107.     if (!commenting_flag)
  108. commentline(trailing ? CMT_TRAIL : CMT_POST);
  109.                     return;
  110.                 }
  111.                 break;
  112.             case '{':
  113.                 if (nestedcomments == 1 && starparen != 2)
  114.                     nestcount++;
  115.                 break;
  116.             case '*':
  117.                 if ((*inbufptr == ((starparen == 2) ? '/' : ')') &&
  118.      (starparen || nestedcomments == 0)) &&
  119.                     --nestcount <= 0) {
  120.                     inbufptr++;
  121.                     *cp = 0;
  122.     if (!commenting_flag)
  123. commentline(trailing ? CMT_TRAIL : CMT_POST);
  124.                     return;
  125.                 }
  126.                 break;
  127.             case '(':
  128.                 if (*inbufptr == '*' && nestedcomments == 1 &&
  129.     starparen != 2) {
  130.     *cp++ = ch;
  131.     ch = *inbufptr++;
  132.                     nestcount++;
  133. }
  134.                 break;
  135.             case 0:
  136.                 *cp = 0;
  137.         if (commenting_flag)
  138.     saveinputcomment(inbufptr-1);
  139. else
  140.     commentline(CMT_POST);
  141. trailing = 0;
  142.                 getline();
  143. i = 0;
  144. for (;;) {
  145.     if (*inbufptr == ' ') {
  146. inbufptr++;
  147. i++;
  148.     } else if (*inbufptr == 't') {
  149. inbufptr++;
  150. i++;
  151. if (intabsize)
  152.     i = (i / intabsize + 1) * intabsize;
  153.     } else
  154. break;
  155. }
  156. cp = curtokbuf;
  157. if (*inbufptr) {
  158.     if (i == cmtindent2 && !starparen)
  159. cmtindent--;
  160.     cmtindent2 = -1;
  161.     if (i >= cmtindent) {
  162. *cp++ = '02';
  163. i -= cmtindent;
  164.     } else {
  165. *cp++ = '03';
  166.     }
  167.     while (--i >= 0)
  168. *cp++ = ' ';
  169. } else
  170.     *cp++ = '03';
  171.                 continue;
  172.             case EOFMARK:
  173.                 error(format_d("Runaway comment from line %d", startlnum));
  174.                 return;     /* unnecessary */
  175.         }
  176.         *cp++ = ch;
  177.     }
  178. }
  179. char *getinlinepart()
  180. {
  181.     char *cp, *buf;
  182.     for (;;) {
  183.         if (isspace(*inbufptr)) {
  184.             inbufptr++;
  185.         } else if (!*inbufptr) {
  186.             getline();
  187.         } else if (*inbufptr == '{') {
  188.             inbufptr++;
  189.             comment(0);
  190.         } else if (*inbufptr == '(' && inbufptr[1] == '*') {
  191.             inbufptr += 2;
  192.             comment(1);
  193.         } else
  194.             break;
  195.     }
  196.     cp = inbufptr;
  197.     while (isspace(*cp) || isalnum(*cp) ||
  198.            *cp == '_' || *cp == '$' || 
  199.            *cp == '+' || *cp == '-' ||
  200.            *cp == '<' || *cp == '>')
  201.         cp++;
  202.     if (cp == inbufptr)
  203.         return "";
  204.     while (isspace(cp[-1]))
  205.         cp--;
  206.     buf = format_s("%s", inbufptr);
  207.     buf[cp-inbufptr] = 0;     /* truncate the string */
  208.     inbufptr = cp;
  209.     return buf;
  210. }
  211. Static int getflag()
  212. {
  213.     int res = 1;
  214.     gettok();
  215.     if (curtok == TOK_IDENT) {
  216.         res = (strcmp(curtokbuf, "OFF") != 0);
  217.         gettok();
  218.     }
  219.     return res;
  220. }
  221. char getchartok()
  222. {
  223.     if (!*inbufptr) {
  224.         warning("Unexpected end of line [236]");
  225.         return ' ';
  226.     }
  227.     if (isspace(*inbufptr)) {
  228.         warning("Whitespace not allowed here [237]");
  229.         return ' ';
  230.     }
  231.     return *inbufptr++;
  232. }
  233. char *getparenstr(buf)
  234. char *buf;
  235. {
  236.     int count = 0;
  237.     char *cp;
  238.     if (inbufptr < buf)    /* this will get most bad cases */
  239.         error("Can't handle a line break here");
  240.     while (isspace(*buf))
  241.         buf++;
  242.     cp = buf;
  243.     for (;;) {
  244.         if (!*cp)
  245.             error("Can't handle a line break here");
  246.         if (*cp == '(')
  247.             count++;
  248.         if (*cp == ')')
  249.             if (--count < 0)
  250.                 break;
  251.         cp++;
  252.     }
  253.     inbufptr = cp + 1;
  254.     while (cp > buf && isspace(cp[-1]))
  255.         cp--;
  256.     return format_ds("%.*s", (int)(cp - buf), buf);
  257. }
  258. void leadingcomments()
  259. {
  260.     for (;;) {
  261.         switch (*inbufptr++) {
  262.             case 0:
  263.                 getline();
  264.                 break;
  265.             case ' ':
  266.             case 't':
  267.             case 26:
  268.                 /* ignore whitespace */
  269.                 break;
  270.             case '{':
  271.                 if (!parsecomment(1, 0)) {
  272.                     inbufptr--;
  273.                     return;
  274.                 }
  275.                 break;
  276.     case '(':
  277. if (*inbufptr == '*') {
  278.     inbufptr++;
  279.     if (!parsecomment(1, 1)) {
  280. inbufptr -= 2;
  281. return;
  282.     }
  283.     break;
  284. }
  285. /* fall through */
  286.             default:
  287.                 inbufptr--;
  288.                 return;
  289.         }
  290.     }
  291. }
  292. void get_C_string(term)
  293. int term;
  294. {
  295.     char *cp = curtokbuf;
  296.     char ch;
  297.     int i;
  298.     while ((ch = *inbufptr++)) {
  299.         if (ch == term) {
  300.             *cp = 0;
  301.             curtokint = cp - curtokbuf;
  302.             return;
  303.         } else if (ch == '\') {
  304.             if (isdigit(*inbufptr)) {
  305.                 i = (*inbufptr++) - '0';
  306.                 if (isdigit(*inbufptr))
  307.                     i = i*8 + (*inbufptr++) - '0';
  308.                 if (isdigit(*inbufptr))
  309.                     i = i*8 + (*inbufptr++) - '0';
  310.                 *cp++ = i;
  311.             } else {
  312.                 ch = *inbufptr++;
  313.                 switch (tolower(ch)) {
  314.                     case 'n':
  315.                         *cp++ = 'n';
  316.                         break;
  317.                     case 't':
  318.                         *cp++ = 't';
  319.                         break;
  320.                     case 'v':
  321.                         *cp++ = 'v';
  322.                         break;
  323.                     case 'b':
  324.                         *cp++ = 'b';
  325.                         break;
  326.                     case 'r':
  327.                         *cp++ = 'r';
  328.                         break;
  329.                     case 'f':
  330.                         *cp++ = 'f';
  331.                         break;
  332.                     case '\':
  333.                         *cp++ = '\';
  334.                         break;
  335.                     case ''':
  336.                         *cp++ = ''';
  337.                         break;
  338.                     case '"':
  339.                         *cp++ = '"';
  340.                         break;
  341.                     case 'x':
  342.                         if (isxdigit(*inbufptr)) {
  343.                             if (isdigit(*inbufptr))
  344.                                 i = (*inbufptr++) - '0';
  345.                             else
  346.                                 i = (toupper(*inbufptr++)) - 'A' + 10;
  347.                             if (isdigit(*inbufptr))
  348.                                 i = i*16 + (*inbufptr++) - '0';
  349.                             else if (isxdigit(*inbufptr))
  350.                                 i = i*16 + (toupper(*inbufptr++)) - 'A' + 10;
  351.                             *cp++ = i;
  352.                             break;
  353.                         }
  354.                         /* fall through */
  355.                     default:
  356.                         warning("Strange character in C string [238]");
  357.                 }
  358.             }
  359.         } else
  360.             *cp++ = ch;
  361.     }
  362.     *cp = 0;
  363.     curtokint = cp - curtokbuf;
  364.     warning("Unterminated C string [239]");
  365. }
  366. void begincommenting(cp)
  367. char *cp;
  368. {
  369.     if (!commenting_flag) {
  370. commenting_ptr = cp;
  371.     }
  372.     commenting_flag++;
  373. }
  374. void saveinputcomment(cp)
  375. char *cp;
  376. {
  377.     if (commenting_ptr)
  378. sprintf(curtokbuf, "%.*s", (int)(cp - commenting_ptr), commenting_ptr);
  379.     else
  380. sprintf(curtokbuf, "03%.*s", (int)(cp - inbuf), inbuf);
  381.     commentline(CMT_POST);
  382.     commenting_ptr = NULL;
  383. }
  384. void endcommenting(cp)
  385. char *cp;
  386. {
  387.     commenting_flag--;
  388.     if (!commenting_flag) {
  389. saveinputcomment(cp);
  390.     }
  391. }
  392. int peeknextchar()
  393. {
  394.     char *cp;
  395.     cp = inbufptr;
  396.     while (isspace(*cp))
  397. cp++;
  398.     return *cp;
  399. }
  400. #ifdef LEXDEBUG
  401. Static void zgettok();
  402. void gettok()
  403. {
  404.     zgettok();
  405.     if (tokentrace) {
  406.         printf("gettok() found %s", tok_name(curtok));
  407.         switch (curtok) {
  408.             case TOK_HEXLIT:
  409.             case TOK_OCTLIT:
  410.             case TOK_INTLIT:
  411.             case TOK_MININT:
  412.                 printf(", curtokint = %d", curtokint);
  413.                 break;
  414.             case TOK_REALLIT:
  415.             case TOK_STRLIT:
  416.                 printf(", curtokbuf = %s", makeCstring(curtokbuf, curtokint));
  417.                 break;
  418.     default:
  419. break;
  420.         }
  421.         putchar('n');
  422.     }
  423. }
  424. Static void zgettok()
  425. #else
  426. void gettok()
  427. #endif
  428. {
  429.     register char ch;
  430.     register char *cp;
  431.     char ch2;
  432.     char *startcp;
  433.     int i;
  434.     debughook();
  435.     for (;;) {
  436.         switch ((ch = *inbufptr++)) {
  437.             case 0:
  438.         if (commenting_flag)
  439.     saveinputcomment(inbufptr-1);
  440.                 getline();
  441. cp = curtokbuf;
  442. for (;;) {
  443.     inbufindent = 0;
  444.     for (;;) {
  445. if (*inbufptr == 't') {
  446.     inbufindent++;
  447.     if (intabsize)
  448. inbufindent = (inbufindent / intabsize + 1) * intabsize;
  449. } else if (*inbufptr == ' ')
  450.     inbufindent++;
  451. else if (*inbufptr != 26)
  452.     break;
  453. inbufptr++;
  454.     }
  455.     if (!*inbufptr && !commenting_flag) {   /* blank line */
  456. *cp++ = '01';
  457. getline();
  458.     } else
  459. break;
  460. }
  461. if (cp > curtokbuf) {
  462.     *cp = 0;
  463.     commentline(CMT_POST);
  464. }
  465.                 break;
  466.             case 't':
  467.             case ' ':
  468.             case 26:    /* ignore ^Z's in Turbo files */
  469.                 while (*inbufptr++ == ch) ;
  470.                 inbufptr--;
  471.                 break;
  472.             case '$':
  473. if (dollar_idents)
  474.     goto ident;
  475.                 if (dollar_flag) {
  476.                     dollar_flag = 0;
  477.                     curtok = TOK_DOLLAR;
  478.                     return;
  479. }
  480. startcp = inbufptr-1;
  481. while (isspace(*inbufptr))
  482.     inbufptr++;
  483. cp = inbufptr;
  484. while (isxdigit(*cp))
  485.     cp++;
  486. if (cp > inbufptr && cp <= inbufptr+8 && !isalnum(*cp)) {
  487.     while (isspace(*cp))
  488. cp++;
  489.     if (!isdigit(*cp) && *cp != ''') {
  490. cp = curtokbuf;    /* Turbo hex constant */
  491. while (isxdigit(*inbufptr))
  492.     *cp++ = *inbufptr++;
  493. *cp = 0;
  494. curtok = TOK_HEXLIT;
  495. curtokint = my_strtol(curtokbuf, NULL, 16);
  496. return;
  497.     }
  498.                 }
  499. dollar_flag++;     /* HP Pascal compiler directive */
  500. do {
  501.     gettok();
  502.     if (curtok == TOK_IF) {             /* $IF expr$ */
  503. Expr *ex;
  504. Value val;
  505. if (!skipping_module) {
  506.     if (!setup_complete)
  507. error("$IF$ not allowed at top of program");
  508.     /* Even though HP Pascal doesn't let these nest,
  509.        there's no harm in supporting it. */
  510.     if (if_flag) {
  511. skiptotoken(TOK_DOLLAR);
  512. if_flag++;
  513. break;
  514.     }
  515.     gettok();
  516.     ex = p_expr(tp_boolean);
  517.     val = eval_expr_consts(ex);
  518.     freeexpr(ex);
  519.     i = (val.type == tp_boolean && val.i);
  520.     free_value(&val);
  521.     if (!i) {
  522. if (curtok != TOK_DOLLAR) {
  523.     warning("Syntax error in $IF$ expression [240]");
  524.     skiptotoken(TOK_DOLLAR);
  525. }
  526. begincommenting(startcp);
  527. if_flag++;
  528. while (if_flag > 0)
  529.     gettok();
  530. endcommenting(inbufptr);
  531.     }
  532. } else {
  533.     skiptotoken(TOK_DOLLAR);
  534. }
  535.     } else if (curtok == TOK_END) {     /* $END$ */
  536. if (if_flag) {
  537.     gettok();
  538.     if (!wexpecttok(TOK_DOLLAR))
  539. skiptotoken(TOK_DOLLAR);
  540.     curtok = TOK_ENDIF;
  541.     if_flag--;
  542.     return;
  543. } else {
  544.     gettok();
  545.     if (!wexpecttok(TOK_DOLLAR))
  546. skiptotoken(TOK_DOLLAR);
  547. }
  548.     } else if (curtok == TOK_IDENT) {
  549. if (!strcmp(curtokbuf, "INCLUDE") &&
  550.      !if_flag && !skipping_module) {
  551.     char *fn;
  552.     gettok();
  553.     if (curtok == TOK_IDENT) {
  554. fn = stralloc(curtokcase);
  555. gettok();
  556.     } else if (wexpecttok(TOK_STRLIT)) {
  557. fn = stralloc(curtokbuf);
  558. gettok();
  559.     } else
  560. fn = "";
  561.     if (!wexpecttok(TOK_DOLLAR)) {
  562. skiptotoken(TOK_DOLLAR);
  563.     } else {
  564. if (handle_include(fn))
  565.     return;
  566.     }
  567. } else if (ignore_directives ||
  568.    if_flag ||
  569.    !strcmp(curtokbuf, "SEARCH") ||
  570.    !strcmp(curtokbuf, "REF") ||
  571.    !strcmp(curtokbuf, "DEF")) {
  572.     skiptotoken(TOK_DOLLAR);
  573. } else if (!strcmp(curtokbuf, "SWITCH_STRPOS")) {
  574.     switch_strpos = getflag();
  575. } else if (!strcmp(curtokbuf, "SYSPROG")) {
  576.     if (getflag())
  577. sysprog_flag |= 1;
  578.     else
  579. sysprog_flag &= ~1;
  580. } else if (!strcmp(curtokbuf, "MODCAL")) {
  581.     if (getflag())
  582. sysprog_flag |= 2;
  583.     else
  584. sysprog_flag &= ~2;
  585. } else if (!strcmp(curtokbuf, "PARTIAL_EVAL")) {
  586.     if (shortcircuit < 0)
  587. partial_eval_flag = getflag();
  588. } else if (!strcmp(curtokbuf, "IOCHECK")) {
  589.     iocheck_flag = getflag();
  590. } else if (!strcmp(curtokbuf, "RANGE")) {
  591.     if (getflag()) {
  592. if (!range_flag)
  593.     note("Range checking is ON [216]");
  594. range_flag = 1;
  595.     } else {
  596. if (range_flag)
  597.     note("Range checking is OFF [216]");
  598. range_flag = 0;
  599.     }
  600. } else if (!strcmp(curtokbuf, "OVFLCHECK")) {
  601.     if (getflag()) {
  602. if (!ovflcheck_flag)
  603.     note("Overflow checking is ON [219]");
  604. ovflcheck_flag = 1;
  605.     } else {
  606. if (ovflcheck_flag)
  607.     note("Overflow checking is OFF [219]");
  608. ovflcheck_flag = 0;
  609.     }
  610. } else if (!strcmp(curtokbuf, "STACKCHECK")) {
  611.     if (getflag()) {
  612. if (!stackcheck_flag)
  613.     note("Stack checking is ON [217]");
  614. stackcheck_flag = 1;
  615.     } else {
  616. if (stackcheck_flag)
  617.     note("Stack checking is OFF [217]");
  618. stackcheck_flag = 0;
  619.     }
  620. }
  621. skiptotoken2(TOK_DOLLAR, TOK_COMMA);
  622.     } else {
  623. warning("Mismatched '$' signs [241]");
  624. dollar_flag = 0;    /* got out of sync */
  625. return;
  626.     }
  627. } while (curtok == TOK_COMMA);
  628.                 break;
  629.             case '"':
  630. if (C_lex) {
  631.     get_C_string(ch);
  632.     curtok = TOK_STRLIT;
  633.     return;
  634. }
  635. goto stringLiteral;
  636.             case '#':
  637. if (modula2) {
  638.     curtok = TOK_NE;
  639.     return;
  640. }
  641. cp = inbufptr;
  642. while (isspace(*cp)) cp++;
  643. if (!strcincmp(cp, "INCLUDE", 7)) {
  644.     char *cp2, *cp3;
  645.     cp += 7;
  646.     while (isspace(*cp)) cp++;
  647.     cp2 = cp + strlen(cp) - 1;
  648.     while (isspace(*cp2)) cp2--;
  649.     if ((*cp == '"' && *cp2 == '"' && cp2 > cp) ||
  650. (*cp == '<' && *cp2 == '>')) {
  651. inbufptr = cp2 + 1;
  652. cp3 = stralloc(cp + 1);
  653. cp3[cp2 - cp - 1] = 0;
  654. if (handle_include(cp3))
  655.     return;
  656. else
  657.     break;
  658.     }
  659. }
  660. /* fall through */
  661.             case ''':
  662.                 if (C_lex && ch == ''') {
  663.                     get_C_string(ch);
  664.                     if (curtokint != 1)
  665.                         warning("Character constant has length != 1 [242]");
  666.                     curtokint = *curtokbuf;
  667.                     curtok = TOK_CHARLIT;
  668.                     return;
  669.                 }
  670.       stringLiteral:
  671.                 cp = curtokbuf;
  672. ch2 = (ch == '"') ? '"' : ''';
  673.                 do {
  674.                     if (ch == ch2) {
  675.                         while ((ch = *inbufptr++) != 'n' &&
  676.                                ch != EOF) {
  677.                             if (ch == ch2) {
  678.                                 if (*inbufptr != ch2 || modula2)
  679.                                     break;
  680.                                 else
  681.                                     inbufptr++;
  682.                             }
  683.                             *cp++ = ch;
  684.                         }
  685.                         if (ch != ch2)
  686.                             warning("Error in string literal [243]");
  687.                     } else {
  688.                         ch = *inbufptr++;
  689.                         if (isdigit(ch)) {
  690.                             i = 0;
  691.                             while (isdigit(ch)) {
  692.                                 i = i*10 + ch - '0';
  693.                                 ch = *inbufptr++;
  694.                             }
  695.                             inbufptr--;
  696.                             *cp++ = i;
  697.                         } else {
  698.                             *cp++ = ch & 0x1f;
  699.                         }
  700.                     }
  701.                     while (*inbufptr == ' ' || *inbufptr == 't')
  702.                         inbufptr++;
  703.                 } while ((ch = *inbufptr++) == ch2 || ch == '#');
  704.                 inbufptr--;
  705.                 *cp = 0;
  706.                 curtokint = cp - curtokbuf;
  707.                 curtok = TOK_STRLIT;
  708.                 return;
  709.             case '(':
  710.                 if (*inbufptr == '*' && !C_lex) {
  711.                     inbufptr++;
  712.     switch (commenting_flag ? 0 : parsecomment(0, 1)) {
  713.         case 0:
  714.                             comment(1);
  715.     break;
  716.         case 2:
  717.     return;
  718.     }
  719.                     break;
  720.                 } else if (*inbufptr == '.') {
  721.                     curtok = TOK_LBR;
  722.                     inbufptr++;
  723.                 } else {
  724.                     curtok = TOK_LPAR;
  725.                 }
  726.                 return;
  727.             case '{':
  728.                 if (C_lex || modula2) {
  729.                     curtok = TOK_LBRACE;
  730.                     return;
  731.                 }
  732.                 switch (commenting_flag ? 0 : parsecomment(0, 0)) {
  733.                     case 0:
  734.                         comment(0);
  735.                         break;
  736.                     case 2:
  737.                         return;
  738.                 }
  739.                 break;
  740.             case '}':
  741.                 if (C_lex || modula2) {
  742.                     curtok = TOK_RBRACE;
  743.                     return;
  744.                 }
  745. if (skipflag > 0) {
  746.     skipflag = 0;
  747. } else
  748.     warning("Unmatched '}' in input file [244]");
  749.                 break;
  750.             case ')':
  751.                 curtok = TOK_RPAR;
  752.                 return;
  753.             case '*':
  754. if (*inbufptr == (C_lex ? '/' : ')')) {
  755.     inbufptr++;
  756.     if (skipflag > 0) {
  757. skipflag = 0;
  758.     } else
  759. warning("Unmatched '*)' in input file [245]");
  760.     break;
  761. } else if (*inbufptr == '*' && !C_lex) {
  762.     curtok = TOK_STARSTAR;
  763.     inbufptr++;
  764. } else
  765.     curtok = TOK_STAR;
  766.                 return;
  767.             case '+':
  768.                 if (C_lex && *inbufptr == '+') {
  769.                     curtok = TOK_PLPL;
  770.                     inbufptr++;
  771.                 } else
  772.                     curtok = TOK_PLUS;
  773.                 return;
  774.             case ',':
  775.                 curtok = TOK_COMMA;
  776.                 return;
  777.             case '-':
  778.                 if (C_lex && *inbufptr == '-') {
  779.                     curtok = TOK_MIMI;
  780.                     inbufptr++;
  781.                 } else if (*inbufptr == '>') {
  782.                     curtok = TOK_ARROW;
  783.                     inbufptr++;
  784.                 } else
  785.                     curtok = TOK_MINUS;
  786.                 return;
  787.             case '.':
  788.                 if (*inbufptr == '.') {
  789.                     curtok = TOK_DOTS;
  790.                     inbufptr++;
  791.                 } else if (*inbufptr == ')') {
  792.                     curtok = TOK_RBR;
  793.                     inbufptr++;
  794.                 } else
  795.                     curtok = TOK_DOT;
  796.                 return;
  797.             case '/':
  798. if (C_lex && *inbufptr == '*') {
  799.     inbufptr++;
  800.     comment(2);
  801.     break;
  802. }
  803.                 curtok = TOK_SLASH;
  804.                 return;
  805.             case ':':
  806.                 if (*inbufptr == '=') {
  807.                     curtok = TOK_ASSIGN;
  808.                     inbufptr++;
  809. } else if (*inbufptr == ':') {
  810.                     curtok = TOK_COLONCOLON;
  811.                     inbufptr++;
  812.                 } else
  813.                     curtok = TOK_COLON;
  814.                 return;
  815.             case ';':
  816.                 curtok = TOK_SEMI;
  817.                 return;
  818.             case '<':
  819.                 if (*inbufptr == '=') {
  820.                     curtok = TOK_LE;
  821.                     inbufptr++;
  822.                 } else if (*inbufptr == '>') {
  823.                     curtok = TOK_NE;
  824.                     inbufptr++;
  825.                 } else if (*inbufptr == '<') {
  826.                     curtok = TOK_LTLT;
  827.                     inbufptr++;
  828.                 } else
  829.                     curtok = TOK_LT;
  830.                 return;
  831.             case '>':
  832.                 if (*inbufptr == '=') {
  833.                     curtok = TOK_GE;
  834.                     inbufptr++;
  835.                 } else if (*inbufptr == '>') {
  836.                     curtok = TOK_GTGT;
  837.                     inbufptr++;
  838.                 } else
  839.                     curtok = TOK_GT;
  840.                 return;
  841.             case '=':
  842. if (*inbufptr == '=') {
  843.     curtok = TOK_EQEQ;
  844.     inbufptr++;
  845. } else
  846.     curtok = TOK_EQ;
  847.                 return;
  848.             case '[':
  849.                 curtok = TOK_LBR;
  850.                 return;
  851.             case ']':
  852.                 curtok = TOK_RBR;
  853.                 return;
  854.             case '^':
  855.                 curtok = TOK_HAT;
  856.                 return;
  857.             case '&':
  858.                 if (*inbufptr == '&') {
  859.                     curtok = TOK_ANDAND;
  860.                     inbufptr++;
  861.                 } else
  862.                     curtok = TOK_AMP;
  863.                 return;
  864.             case '|':
  865.                 if (*inbufptr == '|') {
  866.                     curtok = TOK_OROR;
  867.                     inbufptr++;
  868.                 } else
  869.                     curtok = TOK_VBAR;
  870.                 return;
  871.             case '~':
  872.                 curtok = TOK_TWIDDLE;
  873.                 return;
  874.             case '!':
  875.                 if (*inbufptr == '=') {
  876.                     curtok = TOK_BANGEQ;
  877.                     inbufptr++;
  878.                 } else
  879.                     curtok = TOK_BANG;
  880.                 return;
  881.             case '%':
  882. if (C_lex) {
  883.     curtok = TOK_PERC;
  884.     return;
  885. }
  886. goto ident;
  887.             case '?':
  888.                 curtok = TOK_QM;
  889.                 return;
  890.             case '@':
  891. curtok = TOK_ADDR;
  892.                 return;
  893.             case EOFMARK:
  894.                 if (curtok == TOK_EOF) {
  895.                     if (inputkind == INP_STRLIST)
  896.                         error("Unexpected end of macro");
  897.                     else
  898.                         error("Unexpected end of file");
  899.                 }
  900.                 curtok = TOK_EOF;
  901.                 return;
  902.             default:
  903.                 if (isdigit(ch)) {
  904.     cp = inbufptr;
  905.     while (isxdigit(*cp))
  906. cp++;
  907.     if (*cp == '#' && isxdigit(cp[1])) {
  908. i = atoi(inbufptr-1);
  909. inbufptr = cp+1;
  910.     } else if (toupper(cp[-1]) == 'B' ||
  911.        toupper(cp[-1]) == 'C') {
  912.                         inbufptr--;
  913. i = 8;
  914.     } else if (toupper(*cp) == 'H') {
  915.                         inbufptr--;
  916. i = 16;
  917.     } else if ((ch == '0' && toupper(*inbufptr) == 'X' &&
  918. isxdigit(inbufptr[1]))) {
  919. inbufptr++;
  920. i = 16;
  921.     } else {
  922. i = 10;
  923.     }
  924.     if (i != 10) {
  925.                         curtokint = 0;
  926.                         while (isdigit(*inbufptr) ||
  927.        (i > 10 && isxdigit(*inbufptr))) {
  928.                             ch = toupper(*inbufptr++);
  929.                             curtokint *= i;
  930.                             if (ch <= '9')
  931.                                 curtokint += ch - '0';
  932.                             else
  933.                                 curtokint += ch - 'A' + 10;
  934.                         }
  935.                         sprintf(curtokbuf, "%ld", curtokint);
  936. if ((toupper(*inbufptr) == 'B' && i == 8) ||
  937.     (toupper(*inbufptr) == 'H' && i == 16))
  938.     inbufptr++;
  939. if (toupper(*inbufptr) == 'C' && i == 8) {
  940.     inbufptr++;
  941.     curtok = TOK_STRLIT;
  942.     curtokbuf[0] = curtokint;
  943.     curtokbuf[1] = 0;
  944.     curtokint = 1;
  945.     return;
  946. }
  947.                         if (toupper(*inbufptr) == 'L') {
  948.                             strcat(curtokbuf, "L");
  949.                             inbufptr++;
  950.                         }
  951.                         curtok = (i == 8) ? TOK_OCTLIT : TOK_HEXLIT;
  952.                         return;
  953.                     }
  954.                     cp = curtokbuf;
  955.                     i = 0;
  956.                     while (ch == '0')
  957.                         ch = *inbufptr++;
  958.                     if (isdigit(ch)) {
  959.                         while (isdigit(ch)) {
  960.                             *cp++ = ch;
  961.                             ch = *inbufptr++;
  962.                         }
  963.                     } else
  964.                         *cp++ = '0';
  965.                     if (ch == '.') {
  966.                         if (isdigit(*inbufptr)) {
  967.                             *cp++ = ch;
  968.                             ch = *inbufptr++;
  969.                             i = 1;
  970.                             while (isdigit(ch)) {
  971.                                 *cp++ = ch;
  972.                                 ch = *inbufptr++;
  973.                             }
  974.                         }
  975.                     }
  976.                     if (ch == 'e' || ch == 'E' ||
  977. ch == 'd' || ch == 'D' ||
  978. ch == 'q' || ch == 'Q') {
  979.                         ch = *inbufptr;
  980.                         if (isdigit(ch) || ch == '+' || ch == '-') {
  981.                             *cp++ = 'e';
  982.                             inbufptr++;
  983.                             i = 1;
  984.                             do {
  985.                                 *cp++ = ch;
  986.                                 ch = *inbufptr++;
  987.                             } while (isdigit(ch));
  988.                         }
  989.                     }
  990.                     inbufptr--;
  991.                     *cp = 0;
  992.                     if (i) {
  993.                         curtok = TOK_REALLIT;
  994.                         curtokint = cp - curtokbuf;
  995.                     } else {
  996.                         if (cp >= curtokbuf+10) {
  997.                             i = strcmp(curtokbuf, "2147483648");
  998.                             if (cp > curtokbuf+10 || i > 0) {
  999. curtok = TOK_REALLIT;
  1000. curtokint = cp - curtokbuf + 2;
  1001. strcat(curtokbuf, ".0");
  1002. return;
  1003.     }
  1004.                             if (i == 0) {
  1005.                                 curtok = TOK_MININT;
  1006.                                 curtokint = -2147483648;
  1007.                                 return;
  1008.                             }
  1009.                         }
  1010.                         curtok = TOK_INTLIT;
  1011.                         curtokint = atol(curtokbuf);
  1012.                         if (toupper(*inbufptr) == 'L') {
  1013.                             strcat(curtokbuf, "L");
  1014.                             inbufptr++;
  1015.                         }
  1016.                     }
  1017.                     return;
  1018.                 } else if (isalpha(ch) || ch == '_') {
  1019. ident:
  1020.                     {
  1021.                         register char *cp2;
  1022.                         curtoksym = NULL;
  1023.                         cp = curtokbuf;
  1024.                         cp2 = curtokcase;
  1025. *cp2++ = symcase ? ch : tolower(ch);
  1026. *cp++ = pascalcasesens ? ch : toupper(ch);
  1027. while (isalnum((ch = *inbufptr++)) ||
  1028.        ch == '_' ||
  1029.        (ch == '%' && !C_lex) ||
  1030.        (ch == '$' && dollar_idents)) {
  1031.     *cp2++ = symcase ? ch : tolower(ch);
  1032.     if (!ignorenonalpha || isalnum(ch))
  1033. *cp++ = pascalcasesens ? ch : toupper(ch);
  1034. }
  1035.                         inbufptr--;
  1036.                         *cp2 = 0;
  1037.                         *cp = 0;
  1038. if (pascalsignif > 0)
  1039.     curtokbuf[pascalsignif] = 0;
  1040.                     }
  1041.     if (*curtokbuf == '%') {
  1042. if (!strcicmp(curtokbuf, "%INCLUDE")) {
  1043.     char *cp2 = inbufptr;
  1044.     while (isspace(*cp2)) cp2++;
  1045.     if (*cp2 == ''')
  1046. cp2++;
  1047.     cp = curtokbuf;
  1048.     while (*cp2 && *cp2 != ''' &&
  1049.    *cp2 != ';' && !isspace(*cp2)) {
  1050. *cp++ = *cp2++;
  1051.     }
  1052.     *cp = 0;
  1053.     cp = my_strrchr(curtokbuf, '/');
  1054.     if (cp && (!strcicmp(cp, "/LIST") ||
  1055.        !strcicmp(cp, "/NOLIST")))
  1056. *cp = 0;
  1057.     if (*cp2 == ''')
  1058. cp2++;
  1059.     while (isspace(*cp2)) cp2++;
  1060.     if (*cp2 == ';')
  1061. cp2++;
  1062.     while (isspace(*cp2)) cp2++;
  1063.     if (!*cp2) {
  1064. inbufptr = cp2;
  1065. (void) handle_include(stralloc(curtokbuf));
  1066. return;
  1067.     }
  1068. } else if (!strcicmp(curtokbuf, "%TITLE") ||
  1069.    !strcicmp(curtokbuf, "%SUBTITLE")) {
  1070.     gettok();   /* string literal */
  1071.     break;
  1072. } else if (!strcicmp(curtokbuf, "%PAGE")) {
  1073.     /* should store a special page-break comment? */
  1074.     break;   /* ignore token */
  1075. } else if ((i = 2, !strcicmp(curtokbuf, "%B")) ||
  1076.    (i = 8, !strcicmp(curtokbuf, "%O")) ||
  1077.    (i = 16, !strcicmp(curtokbuf, "%X"))) {
  1078.     while (isspace(*inbufptr)) inbufptr++;
  1079.     if (*inbufptr == ''') {
  1080. inbufptr++;
  1081. curtokint = 0;
  1082. while (*inbufptr && *inbufptr != ''') {
  1083.     ch = toupper(*inbufptr++);
  1084.     if (isxdigit(ch)) {
  1085. curtokint *= i;
  1086. if (ch <= '9')
  1087.     curtokint += ch - '0';
  1088. else
  1089.     curtokint += ch - 'A' + 10;
  1090.     } else if (!isspace(ch))
  1091. warning("Bad digit in literal [246]");
  1092. }
  1093. if (*inbufptr)
  1094.     inbufptr++;
  1095. sprintf(curtokbuf, "%ld", curtokint);
  1096. curtok = (i == 8) ? TOK_OCTLIT : TOK_HEXLIT;
  1097. return;
  1098.     }
  1099.                         }
  1100.     }
  1101.                     {
  1102.                         register unsigned int hash;
  1103.                         register Symbol *sp;
  1104.                         hash = 0;
  1105.                         for (cp = curtokbuf; *cp; cp++)
  1106.                             hash = hash*3 + *cp;
  1107.                         sp = symtab[hash % SYMHASHSIZE];
  1108.                         while (sp && (i = strcmp(sp->name, curtokbuf)) != 0) {
  1109.                             if (i < 0)
  1110.                                 sp = sp->left;
  1111.                             else
  1112.                                 sp = sp->right;
  1113.                         }
  1114.                         if (!sp)
  1115.                             sp = findsymbol(curtokbuf);
  1116. if (sp->flags & SSYNONYM) {
  1117.     i = 100;
  1118.     while (--i > 0 && sp && (sp->flags & SSYNONYM)) {
  1119. Strlist *sl;
  1120. sl = strlist_find(sp->symbolnames, "===");
  1121. if (sl)
  1122.     sp = (Symbol *)sl->value;
  1123. else
  1124.     sp = NULL;
  1125.     }
  1126.     if (!sp)
  1127. break;    /* ignore token */
  1128. }
  1129. if (sp->kwtok && !(sp->flags & KWPOSS) &&
  1130.     (pascalcasesens != 2 || !islower(*curtokbuf)) &&
  1131.     (pascalcasesens != 3 || !isupper(*curtokbuf))) {
  1132.     curtok = sp->kwtok;
  1133.     return;
  1134. }
  1135. curtok = TOK_IDENT;
  1136.                         curtoksym = sp;
  1137.                         if ((i = withlevel) != 0 && sp->fbase) {
  1138.                             while (--i >= 0) {
  1139.                                 curtokmeaning = sp->fbase;
  1140.                                 while (curtokmeaning) {
  1141.                                     if (curtokmeaning->rectype == withlist[i]) {
  1142.                                         curtokint = i;
  1143.                                         return;
  1144.                                     }
  1145.                                     curtokmeaning = curtokmeaning->snext;
  1146.                                 }
  1147.                             }
  1148.                         }
  1149.                         curtokmeaning = sp->mbase;
  1150.                         while (curtokmeaning && !curtokmeaning->isactive)
  1151.                             curtokmeaning = curtokmeaning->snext;
  1152. if (!curtokmeaning)
  1153.     return;
  1154. while (curtokmeaning->kind == MK_SYNONYM)
  1155.     curtokmeaning = curtokmeaning->xnext;
  1156. /* look for unit.ident notation */
  1157.                         if (curtokmeaning->kind == MK_MODULE ||
  1158.     curtokmeaning->kind == MK_FUNCTION) {
  1159.                             for (cp = inbufptr; isspace(*cp); cp++) ;
  1160.                             if (*cp == '.') {
  1161.                                 for (cp++; isspace(*cp); cp++) ;
  1162.                                 if (isalpha(*cp)) {
  1163.                                     Meaning *mp = curtokmeaning;
  1164.                                     Symbol *sym = curtoksym;
  1165.                                     char *saveinbufptr = inbufptr;
  1166.                                     gettok();
  1167.                                     if (curtok == TOK_DOT)
  1168. gettok();
  1169.     else
  1170. curtok = TOK_END;
  1171.                                     if (curtok == TOK_IDENT) {
  1172. curtokmeaning = curtoksym->mbase;
  1173. while (curtokmeaning &&
  1174.        curtokmeaning->ctx != mp)
  1175.     curtokmeaning = curtokmeaning->snext;
  1176. if (!curtokmeaning &&
  1177.     !strcmp(sym->name, "SYSTEM")) {
  1178.     curtokmeaning = curtoksym->mbase;
  1179.     while (curtokmeaning &&
  1180.    curtokmeaning->ctx != nullctx)
  1181. curtokmeaning = curtokmeaning->snext;
  1182. }
  1183.     } else
  1184. curtokmeaning = NULL;
  1185.                                     if (!curtokmeaning) {
  1186.                                         /* oops, was probably funcname.field */
  1187.                                         inbufptr = saveinbufptr;
  1188.                                         curtokmeaning = mp;
  1189.                                         curtoksym = sym;
  1190.                                     }
  1191.                                 }
  1192.                             }
  1193.                         }
  1194.                         return;
  1195.                     }
  1196.                 } else {
  1197.                     warning("Unrecognized character in file [247]");
  1198.                 }
  1199.         }
  1200.     }
  1201. }
  1202. void checkkeyword(tok)
  1203. Token tok;
  1204. {
  1205.     if (curtok == TOK_IDENT &&
  1206. curtoksym->kwtok == tok) {
  1207. curtoksym->flags &= ~KWPOSS;
  1208. curtok = tok;
  1209.     }
  1210. }
  1211. void checkmodulewords()
  1212. {
  1213.     if (modula2) {
  1214. checkkeyword(TOK_FROM);
  1215. checkkeyword(TOK_DEFINITION);
  1216. checkkeyword(TOK_IMPLEMENT);
  1217. checkkeyword(TOK_MODULE);
  1218. checkkeyword(TOK_IMPORT);
  1219. checkkeyword(TOK_EXPORT);
  1220.     } else if (curtok == TOK_IDENT &&
  1221.        (curtoksym->kwtok == TOK_MODULE ||
  1222. curtoksym->kwtok == TOK_IMPORT ||
  1223. curtoksym->kwtok == TOK_EXPORT ||
  1224. curtoksym->kwtok == TOK_IMPLEMENT)) {
  1225. if (!strcmp(curtokbuf, "UNIT") ||
  1226.     !strcmp(curtokbuf, "USES") ||
  1227.     !strcmp(curtokbuf, "INTERFACE") ||
  1228.     !strcmp(curtokbuf, "IMPLEMENTATION")) {
  1229.     modulenotation = 0;
  1230.     findsymbol("UNIT")->flags &= ~KWPOSS;
  1231.     findsymbol("USES")->flags &= ~KWPOSS;
  1232.     findsymbol("INTERFACE")->flags &= ~KWPOSS;
  1233.     findsymbol("IMPLEMENTATION")->flags &= ~KWPOSS;
  1234. } else {
  1235.     modulenotation = 1;
  1236.     findsymbol("MODULE")->flags &= ~KWPOSS;
  1237.     findsymbol("EXPORT")->flags &= ~KWPOSS;
  1238.     findsymbol("IMPORT")->flags &= ~KWPOSS;
  1239.     findsymbol("IMPLEMENT")->flags &= ~KWPOSS;
  1240. }
  1241. curtok = curtoksym->kwtok;
  1242.     }
  1243. }
  1244. /* End. */