GETSYM.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:27k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /* scanner
  23.  */
  24. /* Trigraphs implemented, won't work for token pasting though */
  25. #include        <stdio.h>
  26. #include <ctype.h>
  27. #include <limits.h>
  28. #include "list.h"
  29. #include        "expr.h"
  30. #include        "c.h"
  31. #include        "errors.h"
  32. #include "utype.h"
  33. #include "interp.h"
  34. extern int prm_errfile;
  35. extern int version;
  36. extern LIST *clist;
  37. extern FILE *cppFile, *listFile, *inputFile;
  38. extern int prm_cplusplus,prm_cmangle,prm_ansi;
  39. extern int ifskip,elsetaken;
  40. extern IFSTRUCT *ifs;
  41. extern char *errfile;
  42. extern int errlineno;
  43. extern int phiused;
  44. extern char *infile;
  45. extern short            *lptr;          /* shared with preproc */
  46. extern FILE            *inclfile[10];  /* shared with preproc */
  47. extern char            *inclfname[10];  /* shared with preproc */
  48. extern IFSTRUCT  *ifshold[10];
  49. extern int             inclline[10];   /* shared with preproc */
  50. extern int             incldepth;      /* shared with preproc */
  51. extern int prm_listfile;
  52. int lineno;
  53. short     inputline[4096];
  54. int             lastch;
  55. enum e_sym      lastst;
  56. char            lastid[100] = "";
  57. char            laststr[MAX_STRLEN + 1] = "";
  58. long            ival = 0;
  59. long double          rval = 0.0;
  60. char            *linstack[20];  /* stack for substitutions */
  61. char            chstack[20];    /* place to save lastch */
  62. int             lstackptr = 0;  /* substitution stack pointer */
  63. int cantnewline = FALSE;
  64. int incconst = FALSE;
  65. int backupchar = -1;
  66. static int phiputcpp,phiputlist,phiputerror;
  67. static int commentlevel;
  68. void initsym(void)
  69. {       lptr = inputline;
  70.         inputline[0] = 0;
  71.         lineno = 0; errlineno = 0;
  72. lastid[0] = 0;
  73. laststr[0] = 0;
  74. ival = 0;
  75. rval = 0.0;
  76. cantnewline=FALSE;
  77. incconst = FALSE;
  78. backupchar = -1;
  79. phiputcpp=phiputlist = phiputerror = FALSE;
  80. }
  81. void lineToCpp(void)
  82. /*
  83.  * line has been preprocessed, dump it to a file
  84.  */
  85. {
  86. if (cppFile) {
  87. char buf[100],*q=buf;
  88. short *p = inputline;
  89. *q = 0;
  90. if (!phiputcpp) {
  91. phiputcpp = TRUE;
  92. if (phiused)
  93. fputc('x1f',cppFile);
  94. fprintf(cppFile,"/* LADsoft C compiler Version %d.%02d */nn",version / 100, version %100);
  95. }
  96. while (*p) {
  97. int i;
  98. if (*q) {
  99. buf[0] = *q;
  100. i = 1;
  101. }
  102. else
  103. i = 0;
  104. i+=installphichar(*p++,buf,i);
  105. buf[i] = 0;
  106. q = buf;
  107. while (*q && (*(q+1) || ((*q &0xf0) != 0x90)))
  108. fputc(*q++,cppFile);
  109. }
  110. }
  111. }
  112. /* Strips comments and also the newline char at the end of the line */
  113. static void stripcomment (short *line)
  114. {
  115. short *s = line, *e = s;
  116. while (*e) {
  117. if (*e == '/' && (!commentlevel || !prm_ansi || prm_cplusplus)) {
  118. if (*(e+1) == '*') {
  119. e++;
  120. commentlevel++;
  121. }
  122. else if (*(e+1) == '/' && !commentlevel && (!prm_ansi || prm_cplusplus)) {
  123. *s = 0;
  124. return;
  125. }
  126. else if (!commentlevel)
  127. *s++ = *e;
  128. }
  129. else if (commentlevel && *e == '*' && *(e+1) == '/') {
  130. commentlevel--;
  131. e++;
  132. if (commentlevel == 0) {
  133. *s++ = ' '; /* Comments are whitespace */
  134. }
  135. }
  136. else if (!commentlevel)
  137. *s++ = *e;
  138.     e++;
  139. }
  140. *s = 0;
  141. }
  142. /* strip trigraphs */
  143. void striptrigraph(short *buf)
  144. {
  145. short *cp = buf;
  146. while (*cp) {
  147. if (*cp == '?' && *(cp+1) == '?') {
  148. cp +=2;
  149. switch (*cp++) {
  150. case '=':
  151. *buf++='#';
  152. break;
  153. case '(':
  154. *buf++='[';
  155. break;
  156. case '/':
  157. *buf++='\';
  158. break;
  159. case ')':
  160. *buf++=']';
  161. break;
  162. case ''':
  163. *buf++='^';
  164. break;
  165. case '<':
  166. *buf++='{';
  167. break;
  168. case '!':
  169. *buf++='|';
  170. break;
  171. case '>':
  172. *buf++='}';
  173. break;
  174. case '-':
  175. *buf++='~';
  176. break;
  177. default:
  178. cp-=2;
  179. break;
  180. }
  181. }
  182. else *buf++ = *cp++;
  183. }
  184. *buf = 0;
  185. }
  186. int     getline(int listflag)
  187. /*
  188.  * Read in a line, preprocess it, and dump it to the list and preproc files
  189.  * Also strip comments and alter trigraphs
  190.  */
  191. {       int     rv,rvc,i,prepping,temp;
  192. char ibuf[4096];
  193. int *ptr = ibuf;
  194. if (cantnewline) {
  195. return(0);
  196. }
  197. do {
  198. rv = FALSE;
  199. prepping = FALSE;
  200. rvc = 0;
  201.         if( lineno > 0 && listflag && prm_listfile) {
  202. if (!phiputlist) {
  203. if (phiused) {
  204. fputc('x1f',listFile);
  205. }
  206. phiputlist = TRUE;
  207. }
  208.         }
  209.         if( lineno > 0 && prm_errfile) {
  210. if (!phiputerror) {
  211. if (phiused) {
  212. fputc('x1f',listFile);
  213. }
  214. phiputerror = TRUE;
  215. }
  216.         }
  217. lferror();
  218. while(rvc +131 < 4096 && !rv) {
  219.         ++lineno; ++errlineno;
  220.          rv = (philine(ibuf+rvc,200,inputFile) == NULL);
  221. if (rv)
  222. break;
  223. rvc = strlen(ibuf);
  224. if (ibuf[rvc-1] != 'n') {
  225. ibuf[rvc++] = 'n';
  226. ibuf[rvc] = 0;
  227. }
  228. rvc-=2;
  229. while (ibuf[rvc]==' ')
  230. rvc--;
  231. if (ibuf[rvc] != '\')
  232. break;
  233. }
  234. if (rvc)
  235. rv = FALSE;
  236.         if(prm_listfile) {
  237. if (!phiputlist) {
  238. if (phiused) {
  239. fputc('x1f',listFile);
  240. }
  241. fprintf(listFile,"LADsoft C compiler Version %d.%02d - %snn",version / 100, version % 100,clist->data);
  242. phiputlist = TRUE;
  243. }
  244. fprintf(listFile,"%5d: %s",lineno, ibuf);
  245.         }
  246.         if( rv) {
  247. if (ifs)
  248. generror(ERR_PREPROCMATCH,0,0);
  249. if (commentlevel)
  250. generror(ERR_COMMENTMATCH,0,0);
  251. if (incldepth > 0) {
  252.                 fclose(inputFile);
  253.                  inputFile = inclfile[--incldepth];
  254.                  lineno = inclline[incldepth];
  255. infile = inclfname[incldepth];
  256. errlineno = lineno;
  257. errfile = infile;
  258. ifs = ifshold[incldepth];
  259. commentlevel = 0;
  260. popif();
  261.                  return getline(0);
  262. }
  263.         }
  264.         if( rv )
  265.                 return 1;
  266. lptr = inputline;
  267. ptr = ibuf;
  268. while((temp = parsechar(&ptr)) != 0)
  269. *lptr++ = temp;
  270. *lptr = 0;
  271. stripcomment(inputline);
  272. striptrigraph(inputline);
  273.         lptr = inputline;
  274. while (iswhitespacechar(*lptr))
  275. lptr++;
  276.         if(lptr[0] == '#') {
  277.           listflag = preprocess();
  278. prepping = TRUE;
  279. }
  280. } while (ifskip || prepping);
  281. defcheck(inputline);
  282. lineToCpp();
  283.     return 0;
  284. }
  285. /*
  286.  *      getch - basic get character routine.
  287.  */
  288. int     getch(void)
  289. {       while( (lastch = *lptr++) == '') {
  290.                 if( lstackptr > 0 ) {
  291.                         lptr = linstack[--lstackptr];
  292.                         lastch = chstack[lstackptr];
  293.                         return lastch;
  294.                         }
  295. if (cantnewline) {
  296. lptr--;
  297. return lastch = ' ';
  298. }
  299.                 if(getline(incldepth == 0))
  300.                         return lastch = -1;
  301.                 }
  302.         return lastch;
  303. }
  304.  
  305. /*
  306.  *      getid - get an identifier.
  307.  *
  308.  *      identifiers are any isidch conglomerate
  309.  *      that doesn't start with a numeric character.
  310.  *      this set INCLUDES keywords.
  311.  */
  312. void     getid()
  313. {       register int    i;
  314.         i = 0;
  315. if (prm_cmangle)
  316. lastid[i++] = '_'; /* Mangling */
  317. if (lastch == 'L') {
  318. lastid[i++] = 'L';
  319. getch();
  320. if (lastch == '"') {
  321. getch();
  322. i=0;
  323. while (lastch != '"' && lastch) {
  324. *(((short*)(laststr))+i++) = lastch;
  325. getch();
  326. }
  327. if ((lastch & 0x7f) != '"')
  328.                                  generror(ERR_NEEDCHAR,'"',0);
  329.                          else
  330.                                  getch();
  331. *(((short*)(laststr))+i) = 0;
  332. lastst = lsconst;
  333. return;
  334. }
  335. }
  336. while(issymchar(lastch)) {
  337. if (i < 100)
  338. i+=installphichar(lastch,lastid,i);
  339. getch();
  340.         }
  341. if ((lastid[i-1] & 0xf0) == 0x90)
  342. lastid[i-1] = 0x90;
  343.         lastid[i] = '';
  344.         lastst = id;
  345. }
  346.  
  347. /*
  348.  *      getsch - get a character in a quoted string.
  349.  *
  350.  *      this routine handles all of the escape mechanisms
  351.  *      for characters in strings and character constants.
  352.  */
  353. int     getsch(void)        /* return an in-quote character */
  354. {       register int    i, j;
  355.         if(lastch == 'n')
  356.                 return -1;
  357.         if(lastch != '\') {
  358.                 i = lastch;
  359.                 getch();
  360.                 return i;
  361.                 }
  362.         getch();        /* get an escaped character */
  363.         if(isdigit(lastch)) {
  364.                 for(i = 0,j=0;j < 3;++j) {
  365.                         if(lastch <= '7' && lastch >= '0')
  366.                                 i = (i << 3) + lastch - '0';
  367.                         else
  368.                                 break;
  369.                         getch();
  370.                         }
  371.                 return i;
  372.                 }
  373.         i = lastch;
  374.         getch();
  375.         switch(i) {
  376.                 case 'n':
  377.                         getch();
  378.                         return getsch();
  379. case 'a':
  380. return 'a';
  381.                 case 'b':
  382.                         return 'b';
  383.                 case 'f':
  384.                         return 'f';
  385.                 case 'n':
  386.                         return 'n';
  387.                 case 'r':
  388.                         return 'r';
  389. case 't':
  390. return 't';
  391. case ''':
  392. return ''';
  393. case '"':
  394. return '"';
  395. case '\':
  396. return '\';
  397. case 'x':
  398. {
  399. int n=0,count=0;
  400.   while (isxdigit(lastch)) {
  401. count++;
  402.   lastch-=0x30;
  403. if (lastch > 10) lastch -=7;
  404. if (lastch > 10) lastch -=32;
  405. n*=16;
  406. n+=lastch;
  407. getch();
  408. }
  409. if (count > 2)
  410. generror(ERR_CONSTTOOLARGE,0,0);
  411. return n;
  412. }
  413.                 default:
  414. if (isdigit(i) && i < '9') {
  415. int n = 0;
  416. while (isdigit(i) && i < '9') {
  417. n = n * 8 + (lastch - '0');
  418. getch();
  419. }
  420. return n;
  421. }
  422.                         return i;
  423.                 }
  424. }
  425. int     radix36(char c)
  426. {       if(isdigit(c))
  427.                 return c - '0';
  428.         if(c >= 'a' && c <= 'z')
  429.                 return c - 'a' + 10;
  430.         if(c >= 'A' && c <= 'Z')
  431.                 return c - 'A' + 10;
  432.         return -1;
  433. }
  434.  
  435. /*
  436.  *      getbase - get an integer in any base.
  437.  */
  438. void getbase(int b,char **ptr)
  439. {       register long    i, j;
  440. int errd = 0;
  441.         i = 0;
  442.         while(isalnum(**ptr)) {
  443.                 if((j = radix36(*(*ptr)++)) < b) {
  444. if (i > (ULONG_MAX-j)/b)
  445. if (!errd) {
  446. generror(ERR_CONSTTOOLARGE,0,0);
  447. errd++;
  448. }
  449.                         i = i * b + j;
  450.                         }
  451.                 else break;
  452.                 }
  453.         ival = i;
  454.         lastst = iconst;
  455. }
  456.  
  457. /*
  458.  *      getfrac - get fraction part of a floating number.
  459.  */
  460. void getfrac(char **ptr)
  461. {       double  frmul;
  462.         frmul = 0.1;
  463.         while(isdigit(**ptr)) {
  464.                 rval += frmul * (*(*ptr)++ - '0');
  465.                 frmul *= 0.1;
  466.                 }
  467. }
  468.  
  469. /*
  470.  *      getexp - get exponent part of floating number.
  471.  *
  472.  *      this algorithm is primative but usefull.  Floating
  473.  *      exponents are limited to +/-255 but most hardware
  474.  *      won't support more anyway.
  475.  */
  476. void getexp(char **ptr)
  477. {       double  expo, exmul;
  478.         expo = 1.0;
  479.         if(lastst != rconst)
  480.                 rval = ival;
  481.         if(**ptr == '-') {
  482.                 exmul = 0.1;
  483.                 (*ptr)++;
  484.                 }
  485.         else {
  486.                 exmul = 10.0;
  487. if (**ptr == '+')
  488. (*ptr)++;
  489. }
  490.         getbase(10,ptr);
  491.         if(ival > 255)
  492.                 generror(ERR_FPCON,0,0);
  493.         else
  494.                 while(ival--)
  495.                         expo *= exmul;
  496.         rval *= expo;
  497. lastst = rconst;
  498. }
  499.  
  500. /*
  501.  *      getnum - get a number from input.
  502.  *
  503.  *      getnum handles all of the numeric input. it accepts
  504.  *      decimal, octal, hexidecimal, and floating point numbers.
  505.  */
  506. void getnum(void)
  507. {
  508. int isfloat=FALSE;
  509. char buf[50],*ptr = buf;
  510. while (isxdigit(lastch) || lastch == 'x' || lastch == 'X') {
  511. *ptr++ = lastch;
  512. getch();
  513. }
  514. if (lastch == '.') {
  515. isfloat = TRUE;
  516. *ptr++=lastch;
  517. getch();
  518. while (isdigit(lastch)) {
  519. *ptr++ = lastch;
  520. getch();
  521. }
  522. }
  523. if (lastch == 'e' || lastch == 'E') {
  524. isfloat = TRUE;
  525. *ptr++ = lastch;
  526. getch();
  527. if (lastch == '+' || lastch == '-') {
  528. *ptr++=lastch;
  529. getch();
  530. }
  531. while (isdigit(lastch)) {
  532. *ptr++ = lastch;
  533. getch();
  534. }
  535. }
  536. if (lastch == 'F') {
  537. isfloat = TRUE;
  538. }
  539. *ptr = 0;
  540. ptr = buf;
  541. if (!isfloat) {
  542. if (*ptr == '0') {
  543. ptr++;
  544.       if(*ptr == 'x' || *ptr == 'X') {
  545.        ptr++;
  546.        getbase(16,&ptr);
  547.      }
  548.      else getbase(8,&ptr);
  549.     }
  550. else
  551. getbase(10,&ptr);
  552. if (lastch == 'U') {
  553. lastst = iuconst;
  554. getch();
  555. if (lastch == 'L') {
  556. lastst = luconst;
  557. getch();
  558. }
  559. }
  560. else if (lastch == 'L') {
  561. lastst = iconst;
  562. getch();
  563. if (lastch == 'U') {
  564. lastst = luconst;
  565. getch();
  566. }
  567. }
  568. }
  569.   else    {
  570.                 getbase(10,&ptr);
  571.                 if(*ptr == '.') {
  572. ptr++;
  573.                         rval = ival;    /* float the integer part */
  574.                         getfrac(&ptr);      /* add the fractional part */
  575.                         lastst = rconst;
  576.                      }
  577.                  if(*ptr == 'e' || *ptr == 'E') {
  578.                         ptr++;
  579.                         getexp(&ptr);       /* get the exponent */
  580.                         }
  581. if (lastch == 'F') {
  582. if (lastst != rconst) {
  583. rval = ival;
  584. }
  585. lastst = fconst;
  586. getch();
  587. }
  588. else if (lastch == 'L') {
  589. if (lastst != rconst) {
  590. rval = ival;
  591. }
  592. lastst = lrconst;
  593. getch();
  594. }
  595. }
  596. }
  597.  
  598. int getsym2(void) 
  599. /*
  600.  * translate character sequences to appropriate token names
  601.  */
  602. {       register int    i, j;
  603. int size;
  604. swlp:
  605.  switch(lastch) {
  606.                 case '+':
  607.                         getch();
  608.                         if(lastch == '+') {
  609.                                 getch();
  610.                                 lastst = autoinc;
  611.                                 }
  612.                         else if(lastch == '=') {
  613.                                 getch();
  614.                                 lastst = asplus;
  615.                                 }
  616.                         else lastst = plus;
  617.                         break;
  618.                 case '-':
  619.                         getch();
  620.                         if(lastch == '-') {
  621.                                 getch();
  622.                                 lastst = autodec;
  623.                                 }
  624.                         else if(lastch == '=') {
  625.                                 getch();
  626.                                 lastst = asminus;
  627.                                 }
  628.                         else if(lastch == '>') {
  629.                                 getch();
  630. #ifdef CPLUSPLUS
  631. if (prm_cplusplus && lastch == '*') {
  632. getch();
  633. lastst = pointstar;
  634. }
  635. else
  636. #endif
  637.                                  lastst = pointsto;
  638.                                 }
  639.                         else lastst = minus;
  640.                         break;
  641.                 case '*':
  642.                         getch();
  643.                         if(lastch == '=') {
  644.                                 getch();
  645.                                 lastst = astimes;
  646.                                 }
  647.                         else lastst = star;
  648.                         break;
  649.                 case '/':
  650.                         getch();
  651.                         if(lastch == '=') {
  652.                                 getch();
  653.                                 lastst = asdivide;
  654.                                 }
  655.                         else lastst = divide;
  656.                         break;
  657.                 case '^':
  658.                         getch();
  659.                         if(lastch == '=') {
  660.                                 getch();
  661.                                 lastst = asxor;
  662.                                 }
  663.                         else lastst = uparrow;
  664.                         break;
  665.                 case ';':
  666.                         getch();
  667.                         lastst = semicolon;
  668.                         break;
  669.                 case ':':
  670.                         getch();
  671. #ifdef CPLUSPLUS
  672. if (prm_cplusplus && lastch == ':') {
  673. lastst = classsel;
  674. getch();
  675. }
  676. else
  677. #endif
  678.                          lastst = colon;
  679.                         break;
  680.                 case '=':
  681.                         getch();
  682.                         if(lastch == '=') {
  683.                                 getch();
  684.                                 lastst = eq;
  685.                                 }
  686.                         else lastst = assign;
  687.                         break;
  688.                 case '>':
  689.                         getch();
  690.                         if(lastch == '=') {
  691.                                 getch();
  692.                                 lastst = geq;
  693.                                 }
  694.                         else if(lastch == '>') {
  695.                                 getch();
  696.                                 if(lastch == '=') {
  697.                                         getch();
  698.                                         lastst = asrshift;
  699.                                         }
  700.                                 else lastst = rshift;
  701.                                 }
  702.                         else lastst = gt;
  703.                         break;
  704.                 case '<':
  705.                         getch();
  706. if (incconst) {
  707.                          for(i = 0;i < MAX_STRLEN;++i) {
  708.                                 if(lastch == '>')
  709.                                         break;
  710.                                 if((j = getsch()) == -1)
  711.                                         break;
  712.                                 else
  713.                                         laststr[i] = j;
  714.                               }
  715.                          laststr[i] = 0;
  716.                          lastst = sconst;
  717.                          if(lastch != '>')
  718.                                  generror(ERR_NEEDCHAR,'>',0);
  719.                          else
  720.                                  getch();
  721. } else
  722.                          if(lastch == '=') {
  723.                                 getch();
  724.                                 lastst = leq;
  725.                                 }
  726.                          else if(lastch == '<') {
  727.                                 getch();
  728.                                 if(lastch == '=') {
  729.                                         getch();
  730.                                         lastst = aslshift;
  731.                                         }
  732.                                 else lastst = lshift;
  733.                                 }
  734.                          else lastst = lt;
  735.                         break;
  736.                 case ''':
  737.                         getch();
  738.                         ival = getsch();        /* get a string char */
  739.                         if(lastch != ''')
  740.                                 generror(ERR_NEEDCHAR,''',0);
  741.                         else
  742.                                 getch();
  743.                         lastst = cconst;
  744.                         break;
  745. case 0x2d4:
  746. getch();
  747. i=0;
  748. while (lastch != '"' && lastch)
  749. i=installphichar(lastch,laststr,i);
  750. if ((lastch & 0x7f) != '"')
  751.                                  generror(ERR_NEEDCHAR,'"',0);
  752.                          else
  753.                                  getch();
  754. size = strlen(laststr);
  755. lastst = sconst;
  756. break;
  757.                 case '"':
  758.   size = 0;
  759. while (lastch == '"') {
  760.                          getch();
  761.                          for(i = size;i < MAX_STRLEN;++i) {
  762.                                 if(lastch == '"')
  763.                                         break;
  764.                                 if((j = getsch()) == -1)
  765.                                         break;
  766.                                 else
  767.                                         laststr[i] = j;
  768.                                 }
  769.                         laststr[i] = 0;
  770. size = i;
  771.                          lastst = sconst;
  772.                          if(lastch != '"')
  773.                                  generror(ERR_NEEDCHAR,'"',0);
  774.                          else
  775.                                  getch();
  776. }
  777.                         break;
  778.                 case '!':
  779.                         getch();
  780.                         if(lastch == '=') {
  781.                                 getch();
  782.                                 lastst = neq;
  783.                                 }
  784.                         else lastst = not;
  785.                         break;
  786.                 case '%':
  787.                         getch();
  788.                         if(lastch == '=') {
  789.                                 getch();
  790.                                 lastst = asmodop;
  791.                                 }
  792.                         else lastst = modop;
  793.                         break;
  794.                 case '~':
  795.                         getch();
  796.                         lastst = compl;
  797.                         break;
  798.                 case '.':
  799. if (isdigit(*lptr))
  800. getnum();
  801. else {
  802.                         getch();
  803. #ifdef CPLUSPLUS
  804. if (prm_cplusplus && lastch == '*') {
  805. getch();
  806. lastst = dotstar;
  807. }
  808. else 
  809. #endif
  810.   if (lastch == '.') {
  811.    getch();
  812. if (lastch == '.') {
  813. getch();
  814. lastst = ellipse;
  815. break;
  816. }
  817. else {
  818.                              generror(ERR_ILLCHAR,lastch,0);
  819. }
  820. }
  821.                          lastst = dot;
  822. }
  823.                         break;
  824.                 case ',':
  825.                         getch();
  826.                         lastst = comma;
  827.                         break;
  828.                 case '&':
  829.                         getch();
  830.                         if( lastch == '&') {
  831.                                 lastst = land;
  832.                                 getch();
  833.                                 }
  834.                         else if( lastch == '=') {
  835.                                 lastst = asand;
  836.                                 getch();
  837.                                 }
  838.                         else
  839.                                 lastst = and;
  840.                         break;
  841.                 case '|':
  842.                         getch();
  843.                         if(lastch == '|') {
  844.                                 lastst = lor;
  845.                                 getch();
  846.                                 }
  847.                         else if( lastch == '=') {
  848.                                 lastst = asor;
  849.                                 getch();
  850.                                 }
  851.                         else
  852.                                 lastst = or;
  853.                         break;
  854.                 case '(':
  855.                         getch();
  856.                         lastst = openpa;
  857.                         break;
  858.                 case ')':
  859.                         getch();
  860.                         lastst = closepa;
  861.                         break;
  862.                 case '[':
  863.                         getch();
  864.                         lastst = openbr;
  865.                         break;
  866.                 case ']':
  867.                         getch();
  868.                         lastst = closebr;
  869.                         break;
  870.                 case '{':
  871.                         getch();
  872.                         lastst = begin;
  873.                         break;
  874.                 case '}':
  875.                         getch();
  876.                         lastst = end;
  877.                         break;
  878.                 case '?':
  879.                         getch();
  880.                         lastst = hook;
  881.                         break;
  882.                 default:
  883. if (iscommentchar(lastch)) {
  884. do {
  885. getch();
  886. } while (!iscommentchar(lastch) && lastch != 'n');
  887. }
  888. else
  889.                          generror(ERR_ILLCHAR,lastch,0);
  890.                         getch();
  891. return 1;
  892.                 }
  893. return 0;
  894. }
  895. /*
  896.  *      getsym - get next symbol from input stream.
  897.  *
  898.  *      getsym is the basic lexical analyzer.  It builds
  899.  *      basic tokens out of the characters on the input
  900.  *      stream and sets the following global variables:
  901.  *
  902.  *      lastch:         A look behind buffer.
  903.  *      lastst:         type of last symbol read.
  904.  *      laststr:        last string constant read.
  905.  *      lastid:         last identifier read.
  906.  *      ival:           last integer constant read.
  907.  *      rval:           last real constant read.
  908.  *
  909.  *      getsym should be called for all your input needs...
  910.  */
  911. void     getsym(void)
  912. {
  913. if (backupchar != -1) {
  914. lastst = backupchar;
  915. backupchar = -1;
  916. return;
  917. }
  918. if (cantnewline && !*lptr) {
  919. lastst = eol;
  920. return;
  921. }
  922.         while(iswhitespacechar(lastch)) {
  923.           getch();
  924. if (cantnewline && !*lptr) {
  925. lastst = eol;
  926. return;
  927. }
  928. }
  929.         if( lastch == -1)
  930.                 lastst = eof;
  931.         else if(isdigit(lastch))
  932.                 getnum();
  933.         else if(isstartchar(lastch)) {
  934.                 getid();
  935.                 searchkw();
  936. }
  937.         else getsym2();
  938. }
  939. /*
  940.  * when we need specific punctuation, call one of these routines
  941.  */
  942. int needpunc(enum e_sym p, int *skimlist)
  943. {       if( lastst == p) {
  944.                 getsym();
  945. return(TRUE);
  946. }
  947.         else
  948.                 expecttoken(p,skimlist);
  949. return(FALSE);
  950. }
  951. int needpuncexp(enum e_sym p, int *skimlist)
  952. {       if( lastst == p) {
  953.                 getsym();
  954. return(TRUE);
  955. }
  956.         else
  957.                 expecttokenexp(p,skimlist);
  958. return(FALSE);
  959. }
  960. /*
  961.  * having to back up a character is rare, but sometimes...
  962.  */
  963. void backup(int st)
  964. {
  965.   backupchar = lastst;
  966.   lastst = st;
  967. }