Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

lex.c

Go to the documentation of this file.
00001 #include "c.h"
00002 #include <float.h>
00003 #include <errno.h>
00004 
00005 
00006 #define MAXTOKEN 32
00007 
00008 enum { BLANK=01,  NEWLINE=02, LETTER=04,
00009        DIGIT=010, HEX=020,    OTHER=040 };
00010 
00011 static unsigned char map[256] = { /* 000 nul */ 0,
00012                    /* 001 soh */    0,
00013                    /* 002 stx */    0,
00014                    /* 003 etx */    0,
00015                    /* 004 eot */    0,
00016                    /* 005 enq */    0,
00017                    /* 006 ack */    0,
00018                    /* 007 bel */    0,
00019                    /* 010 bs  */    0,
00020                    /* 011 ht  */    BLANK,
00021                    /* 012 nl  */    NEWLINE,
00022                    /* 013 vt  */    BLANK,
00023                    /* 014 ff  */    BLANK,
00024                    /* 015 cr  */    0,
00025                    /* 016 so  */    0,
00026                    /* 017 si  */    0,
00027                    /* 020 dle */    0,
00028                    /* 021 dc1 */    0,
00029                    /* 022 dc2 */    0,
00030                    /* 023 dc3 */    0,
00031                    /* 024 dc4 */    0,
00032                    /* 025 nak */    0,
00033                    /* 026 syn */    0,
00034                    /* 027 etb */    0,
00035                    /* 030 can */    0,
00036                    /* 031 em  */    0,
00037                    /* 032 sub */    0,
00038                    /* 033 esc */    0,
00039                    /* 034 fs  */    0,
00040                    /* 035 gs  */    0,
00041                    /* 036 rs  */    0,
00042                    /* 037 us  */    0,
00043                    /* 040 sp  */    BLANK,
00044                    /* 041 !   */    OTHER,
00045                    /* 042 "   */    OTHER,
00046                    /* 043 #   */    OTHER,
00047                    /* 044 $   */    0,
00048                    /* 045 %   */    OTHER,
00049                    /* 046 &   */    OTHER,
00050                    /* 047 '   */    OTHER,
00051                    /* 050 (   */    OTHER,
00052                    /* 051 )   */    OTHER,
00053                    /* 052 *   */    OTHER,
00054                    /* 053 +   */    OTHER,
00055                    /* 054 ,   */    OTHER,
00056                    /* 055 -   */    OTHER,
00057                    /* 056 .   */    OTHER,
00058                    /* 057 /   */    OTHER,
00059                    /* 060 0   */    DIGIT,
00060                    /* 061 1   */    DIGIT,
00061                    /* 062 2   */    DIGIT,
00062                    /* 063 3   */    DIGIT,
00063                    /* 064 4   */    DIGIT,
00064                    /* 065 5   */    DIGIT,
00065                    /* 066 6   */    DIGIT,
00066                    /* 067 7   */    DIGIT,
00067                    /* 070 8   */    DIGIT,
00068                    /* 071 9   */    DIGIT,
00069                    /* 072 :   */    OTHER,
00070                    /* 073 ;   */    OTHER,
00071                    /* 074 <   */    OTHER,
00072                    /* 075 =   */    OTHER,
00073                    /* 076 >   */    OTHER,
00074                    /* 077 ?   */    OTHER,
00075                    /* 100 @   */    0,
00076                    /* 101 A   */    LETTER|HEX,
00077                    /* 102 B   */    LETTER|HEX,
00078                    /* 103 C   */    LETTER|HEX,
00079                    /* 104 D   */    LETTER|HEX,
00080                    /* 105 E   */    LETTER|HEX,
00081                    /* 106 F   */    LETTER|HEX,
00082                    /* 107 G   */    LETTER,
00083                    /* 110 H   */    LETTER,
00084                    /* 111 I   */    LETTER,
00085                    /* 112 J   */    LETTER,
00086                    /* 113 K   */    LETTER,
00087                    /* 114 L   */    LETTER,
00088                    /* 115 M   */    LETTER,
00089                    /* 116 N   */    LETTER,
00090                    /* 117 O   */    LETTER,
00091                    /* 120 P   */    LETTER,
00092                    /* 121 Q   */    LETTER,
00093                    /* 122 R   */    LETTER,
00094                    /* 123 S   */    LETTER,
00095                    /* 124 T   */    LETTER,
00096                    /* 125 U   */    LETTER,
00097                    /* 126 V   */    LETTER,
00098                    /* 127 W   */    LETTER,
00099                    /* 130 X   */    LETTER,
00100                    /* 131 Y   */    LETTER,
00101                    /* 132 Z   */    LETTER,
00102                    /* 133 [   */    OTHER,
00103                    /* 134 \   */    OTHER,
00104                    /* 135 ]   */    OTHER,
00105                    /* 136 ^   */    OTHER,
00106                    /* 137 _   */    LETTER,
00107                    /* 140 `   */    0,
00108                    /* 141 a   */    LETTER|HEX,
00109                    /* 142 b   */    LETTER|HEX,
00110                    /* 143 c   */    LETTER|HEX,
00111                    /* 144 d   */    LETTER|HEX,
00112                    /* 145 e   */    LETTER|HEX,
00113                    /* 146 f   */    LETTER|HEX,
00114                    /* 147 g   */    LETTER,
00115                    /* 150 h   */    LETTER,
00116                    /* 151 i   */    LETTER,
00117                    /* 152 j   */    LETTER,
00118                    /* 153 k   */    LETTER,
00119                    /* 154 l   */    LETTER,
00120                    /* 155 m   */    LETTER,
00121                    /* 156 n   */    LETTER,
00122                    /* 157 o   */    LETTER,
00123                    /* 160 p   */    LETTER,
00124                    /* 161 q   */    LETTER,
00125                    /* 162 r   */    LETTER,
00126                    /* 163 s   */    LETTER,
00127                    /* 164 t   */    LETTER,
00128                    /* 165 u   */    LETTER,
00129                    /* 166 v   */    LETTER,
00130                    /* 167 w   */    LETTER,
00131                    /* 170 x   */    LETTER,
00132                    /* 171 y   */    LETTER,
00133                    /* 172 z   */    LETTER,
00134                    /* 173 {   */    OTHER,
00135                    /* 174 |   */    OTHER,
00136                    /* 175 }   */    OTHER,
00137                    /* 176 ~   */    OTHER, };
00138 static struct symbol tval;
00139 static char cbuf[BUFSIZE+1];
00140 static unsigned int wcbuf[BUFSIZE+1];
00141 
00142 Coordinate src;     /* current source coordinate */
00143 int t;
00144 char *token;        /* current token */
00145 Symbol tsym;        /* symbol table entry for current token */
00146 
00147 static void *cput(int c, void *cl);
00148 static void *wcput(int c, void *cl);
00149 static void *scon(int q, void *put(int c, void *cl), void *cl);
00150 static int backslash(int q);
00151 static Symbol fcon(void);
00152 static Symbol icon(unsigned long, int, int);
00153 static void ppnumber(char *);
00154 
00155 int gettok(void) {
00156     for (;;) {
00157         register unsigned char *rcp = cp;
00158         while (map[*rcp]&BLANK)
00159             rcp++;
00160         if (limit - rcp < MAXTOKEN) {
00161             cp = rcp;
00162             fillbuf();
00163             rcp = cp;
00164         }
00165         src.file = file;
00166         src.x = (char *)rcp - line;
00167         src.y = lineno;
00168         cp = rcp + 1;
00169         switch (*rcp++) {
00170         case '/': if (*rcp == '*') {
00171                 int c = 0;
00172                 for (rcp++; *rcp != '/' || c != '*'; )
00173                     if (map[*rcp]&NEWLINE) {
00174                         if (rcp < limit)
00175                             c = *rcp;
00176                         cp = rcp + 1;
00177                         nextline();
00178                         rcp = cp;
00179                         if (rcp == limit)
00180                             break;
00181                     } else
00182                         c = *rcp++;
00183                 if (rcp < limit)
00184                     rcp++;
00185                 else
00186                     error("unclosed comment\n");
00187                 cp = rcp;
00188                 continue;
00189               }
00190               return '/';
00191         case '<':
00192             if (*rcp == '=') return cp++, LEQ;
00193             if (*rcp == '<') return cp++, LSHIFT;
00194             return '<';
00195         case '>':
00196             if (*rcp == '=') return cp++, GEQ;
00197             if (*rcp == '>') return cp++, RSHIFT;
00198             return '>';
00199         case '-':
00200             if (*rcp == '>') return cp++, DEREF;
00201             if (*rcp == '-') return cp++, DECR;
00202             return '-';
00203         case '=': return *rcp == '=' ? cp++, EQL    : '=';
00204         case '!': return *rcp == '=' ? cp++, NEQ    : '!';
00205         case '|': return *rcp == '|' ? cp++, OROR   : '|';
00206         case '&': return *rcp == '&' ? cp++, ANDAND : '&';
00207         case '+': return *rcp == '+' ? cp++, INCR   : '+';
00208         case ';': case ',': case ':':
00209         case '*': case '~': case '%': case '^': case '?':
00210         case '[': case ']': case '{': case '}': case '(': case ')': 
00211             return rcp[-1];
00212         case '\n': case '\v': case '\r': case '\f':
00213             nextline();
00214             if (cp == limit) {
00215                 tsym = NULL;
00216                 return EOI;
00217             }
00218             continue;
00219 
00220         case 'i':
00221             if (rcp[0] == 'f'
00222             && !(map[rcp[1]]&(DIGIT|LETTER))) {
00223                 cp = rcp + 1;
00224                 return IF;
00225             }
00226             if (rcp[0] == 'n'
00227             &&  rcp[1] == 't'
00228             && !(map[rcp[2]]&(DIGIT|LETTER))) {
00229                 cp = rcp + 2;
00230                 tsym = inttype->u.sym;
00231                 return INT;
00232             }
00233             goto id;
00234         case 'h': case 'j': case 'k': case 'm': case 'n': case 'o':
00235         case 'p': case 'q': case 'x': case 'y': case 'z':
00236         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00237         case 'G': case 'H': case 'I': case 'J': case 'K':
00238         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
00239         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
00240         case 'Y': case 'Z':
00241         id:
00242             if (limit - rcp < MAXLINE) {
00243                 cp = rcp - 1;
00244                 fillbuf();
00245                 rcp = ++cp;
00246             }
00247             assert(cp == rcp);
00248             token = (char *)rcp - 1;
00249             while (map[*rcp]&(DIGIT|LETTER))
00250                 rcp++;
00251             token = stringn(token, (char *)rcp - token);
00252             tsym = lookup(token, identifiers);
00253             cp = rcp;
00254             return ID;
00255         case '0': case '1': case '2': case '3': case '4':
00256         case '5': case '6': case '7': case '8': case '9': {
00257             unsigned long n = 0;
00258             if (limit - rcp < MAXLINE) {
00259                 cp = rcp - 1;
00260                 fillbuf();
00261                 rcp = ++cp;
00262             }
00263             assert(cp == rcp);
00264             token = (char *)rcp - 1;
00265             if (*token == '0' && (*rcp == 'x' || *rcp == 'X')) {
00266                 int d, overflow = 0;
00267                 while (*++rcp) {
00268                     if (map[*rcp]&DIGIT)
00269                         d = *rcp - '0';
00270                     else if (*rcp >= 'a' && *rcp <= 'f')
00271                         d = *rcp - 'a' + 10;
00272                     else if (*rcp >= 'A' && *rcp <= 'F')
00273                         d = *rcp - 'A' + 10;
00274                     else
00275                         break;
00276                     if (n&~(~0UL >> 4))
00277                         overflow = 1;
00278                     else
00279                         n = (n<<4) + d;
00280                 }
00281                 if ((char *)rcp - token <= 2)
00282                     error("invalid hexadecimal constant `%S'\n", token, (char *)rcp-token);
00283                 cp = rcp;
00284                 tsym = icon(n, overflow, 16);
00285             } else if (*token == '0') {
00286                 int err = 0, overflow = 0;
00287                 for ( ; map[*rcp]&DIGIT; rcp++) {
00288                     if (*rcp == '8' || *rcp == '9')
00289                         err = 1;
00290                     if (n&~(~0UL >> 3))
00291                         overflow = 1;
00292                     else
00293                         n = (n<<3) + (*rcp - '0');
00294                 }
00295                 if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
00296                     cp = rcp;
00297                     tsym = fcon();
00298                     return FCON;
00299                 }
00300                 cp = rcp;
00301                 tsym = icon(n, overflow, 8);
00302                 if (err)
00303                     error("invalid octal constant `%S'\n", token, (char*)cp-token);
00304             } else {
00305                 int overflow = 0;
00306                 for (n = *token - '0'; map[*rcp]&DIGIT; ) {
00307                     int d = *rcp++ - '0';
00308                     if (n > (ULONG_MAX - d)/10)
00309                         overflow = 1;
00310                     else
00311                         n = 10*n + d;
00312                 }
00313                 if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
00314                     cp = rcp;
00315                     tsym = fcon();
00316                     return FCON;
00317                 }
00318                 cp = rcp;
00319                 tsym = icon(n, overflow, 10);
00320             }
00321             return ICON;
00322         }
00323         case '.':
00324             if (rcp[0] == '.' && rcp[1] == '.') {
00325                 cp += 2;
00326                 return ELLIPSIS;
00327             }
00328             if ((map[*rcp]&DIGIT) == 0)
00329                 return '.';
00330             if (limit - rcp < MAXLINE) {
00331                 cp = rcp - 1;
00332                 fillbuf();
00333                 rcp = ++cp;
00334             }
00335             assert(cp == rcp);
00336             cp = rcp - 1;
00337             token = (char *)cp;
00338             tsym = fcon();
00339             return FCON;
00340         case 'L':
00341             if (*rcp == '\'') {
00342                 unsigned int *s = scon(*cp, wcput, wcbuf);
00343                 if (s - wcbuf > 2)
00344                     warning("excess characters in wide-character literal ignored\n");
00345                 tval.type = widechar;
00346                 tval.u.c.v.u = wcbuf[0];
00347                 tsym = &tval;
00348                 return ICON;
00349             } else if (*rcp == '"') {
00350                 unsigned int *s = scon(*cp, wcput, wcbuf);
00351                 tval.type = array(widechar, s - wcbuf, 0);
00352                 tval.u.c.v.p = wcbuf;
00353                 tsym = &tval;
00354                 return SCON;
00355             } else
00356                 goto id;
00357         case '\'': {
00358             char *s = scon(*--cp, cput, cbuf);
00359             if (s - cbuf > 2)
00360                 warning("excess characters in multibyte character literal ignored\n");
00361             tval.type = inttype;
00362             if (chartype->op == INT)
00363                 tval.u.c.v.i = extend(cbuf[0], chartype);
00364             else
00365                 tval.u.c.v.i = cbuf[0]&0xFF;
00366             tsym = &tval;
00367             return ICON;
00368             }
00369         case '"': {
00370             char *s = scon(*--cp, cput, cbuf);
00371             tval.type = array(chartype, s - cbuf, 0);
00372             tval.u.c.v.p = cbuf;
00373             tsym = &tval;
00374             return SCON;
00375             }
00376         case 'a':
00377             if (rcp[0] == 'u'
00378             &&  rcp[1] == 't'
00379             &&  rcp[2] == 'o'
00380             && !(map[rcp[3]]&(DIGIT|LETTER))) {
00381                 cp = rcp + 3;
00382                 return AUTO;
00383             }
00384             goto id;
00385         case 'b':
00386             if (rcp[0] == 'r'
00387             &&  rcp[1] == 'e'
00388             &&  rcp[2] == 'a'
00389             &&  rcp[3] == 'k'
00390             && !(map[rcp[4]]&(DIGIT|LETTER))) {
00391                 cp = rcp + 4;
00392                 return BREAK;
00393             }
00394             goto id;
00395         case 'c':
00396             if (rcp[0] == 'a'
00397             &&  rcp[1] == 's'
00398             &&  rcp[2] == 'e'
00399             && !(map[rcp[3]]&(DIGIT|LETTER))) {
00400                 cp = rcp + 3;
00401                 return CASE;
00402             }
00403             if (rcp[0] == 'h'
00404             &&  rcp[1] == 'a'
00405             &&  rcp[2] == 'r'
00406             && !(map[rcp[3]]&(DIGIT|LETTER))) {
00407                 cp = rcp + 3;
00408                 tsym = chartype->u.sym;
00409                 return CHAR;
00410             }
00411             if (rcp[0] == 'o'
00412             &&  rcp[1] == 'n'
00413             &&  rcp[2] == 's'
00414             &&  rcp[3] == 't'
00415             && !(map[rcp[4]]&(DIGIT|LETTER))) {
00416                 cp = rcp + 4;
00417                 return CONST;
00418             }
00419             if (rcp[0] == 'o'
00420             &&  rcp[1] == 'n'
00421             &&  rcp[2] == 't'
00422             &&  rcp[3] == 'i'
00423             &&  rcp[4] == 'n'
00424             &&  rcp[5] == 'u'
00425             &&  rcp[6] == 'e'
00426             && !(map[rcp[7]]&(DIGIT|LETTER))) {
00427                 cp = rcp + 7;
00428                 return CONTINUE;
00429             }
00430             goto id;
00431         case 'd':
00432             if (rcp[0] == 'e'
00433             &&  rcp[1] == 'f'
00434             &&  rcp[2] == 'a'
00435             &&  rcp[3] == 'u'
00436             &&  rcp[4] == 'l'
00437             &&  rcp[5] == 't'
00438             && !(map[rcp[6]]&(DIGIT|LETTER))) {
00439                 cp = rcp + 6;
00440                 return DEFAULT;
00441             }
00442             if (rcp[0] == 'o'
00443             &&  rcp[1] == 'u'
00444             &&  rcp[2] == 'b'
00445             &&  rcp[3] == 'l'
00446             &&  rcp[4] == 'e'
00447             && !(map[rcp[5]]&(DIGIT|LETTER))) {
00448                 cp = rcp + 5;
00449                 tsym = doubletype->u.sym;
00450                 return DOUBLE;
00451             }
00452             if (rcp[0] == 'o'
00453             && !(map[rcp[1]]&(DIGIT|LETTER))) {
00454                 cp = rcp + 1;
00455                 return DO;
00456             }
00457             goto id;
00458         case 'e':
00459             if (rcp[0] == 'l'
00460             &&  rcp[1] == 's'
00461             &&  rcp[2] == 'e'
00462             && !(map[rcp[3]]&(DIGIT|LETTER))) {
00463                 cp = rcp + 3;
00464                 return ELSE;
00465             }
00466             if (rcp[0] == 'n'
00467             &&  rcp[1] == 'u'
00468             &&  rcp[2] == 'm'
00469             && !(map[rcp[3]]&(DIGIT|LETTER))) {
00470                 cp = rcp + 3;
00471                 return ENUM;
00472             }
00473             if (rcp[0] == 'x'
00474             &&  rcp[1] == 't'
00475             &&  rcp[2] == 'e'
00476             &&  rcp[3] == 'r'
00477             &&  rcp[4] == 'n'
00478             && !(map[rcp[5]]&(DIGIT|LETTER))) {
00479                 cp = rcp + 5;
00480                 return EXTERN;
00481             }
00482             goto id;
00483         case 'f':
00484             if (rcp[0] == 'l'
00485             &&  rcp[1] == 'o'
00486             &&  rcp[2] == 'a'
00487             &&  rcp[3] == 't'
00488             && !(map[rcp[4]]&(DIGIT|LETTER))) {
00489                 cp = rcp + 4;
00490                 tsym = floattype->u.sym;
00491                 return FLOAT;
00492             }
00493             if (rcp[0] == 'o'
00494             &&  rcp[1] == 'r'
00495             && !(map[rcp[2]]&(DIGIT|LETTER))) {
00496                 cp = rcp + 2;
00497                 return FOR;
00498             }
00499             goto id;
00500         case 'g':
00501             if (rcp[0] == 'o'
00502             &&  rcp[1] == 't'
00503             &&  rcp[2] == 'o'
00504             && !(map[rcp[3]]&(DIGIT|LETTER))) {
00505                 cp = rcp + 3;
00506                 return GOTO;
00507             }
00508             goto id;
00509         case 'l':
00510             if (rcp[0] == 'o'
00511             &&  rcp[1] == 'n'
00512             &&  rcp[2] == 'g'
00513             && !(map[rcp[3]]&(DIGIT|LETTER))) {
00514                 cp = rcp + 3;
00515                 return LONG;
00516             }
00517             goto id;
00518         case 'r':
00519             if (rcp[0] == 'e'
00520             &&  rcp[1] == 'g'
00521             &&  rcp[2] == 'i'
00522             &&  rcp[3] == 's'
00523             &&  rcp[4] == 't'
00524             &&  rcp[5] == 'e'
00525             &&  rcp[6] == 'r'
00526             && !(map[rcp[7]]&(DIGIT|LETTER))) {
00527                 cp = rcp + 7;
00528                 return REGISTER;
00529             }
00530             if (rcp[0] == 'e'
00531             &&  rcp[1] == 't'
00532             &&  rcp[2] == 'u'
00533             &&  rcp[3] == 'r'
00534             &&  rcp[4] == 'n'
00535             && !(map[rcp[5]]&(DIGIT|LETTER))) {
00536                 cp = rcp + 5;
00537                 return RETURN;
00538             }
00539             goto id;
00540         case 's':
00541             if (rcp[0] == 'h'
00542             &&  rcp[1] == 'o'
00543             &&  rcp[2] == 'r'
00544             &&  rcp[3] == 't'
00545             && !(map[rcp[4]]&(DIGIT|LETTER))) {
00546                 cp = rcp + 4;
00547                 return SHORT;
00548             }
00549             if (rcp[0] == 'i'
00550             &&  rcp[1] == 'g'
00551             &&  rcp[2] == 'n'
00552             &&  rcp[3] == 'e'
00553             &&  rcp[4] == 'd'
00554             && !(map[rcp[5]]&(DIGIT|LETTER))) {
00555                 cp = rcp + 5;
00556                 return SIGNED;
00557             }
00558             if (rcp[0] == 'i'
00559             &&  rcp[1] == 'z'
00560             &&  rcp[2] == 'e'
00561             &&  rcp[3] == 'o'
00562             &&  rcp[4] == 'f'
00563             && !(map[rcp[5]]&(DIGIT|LETTER))) {
00564                 cp = rcp + 5;
00565                 return SIZEOF;
00566             }
00567             if (rcp[0] == 't'
00568             &&  rcp[1] == 'a'
00569             &&  rcp[2] == 't'
00570             &&  rcp[3] == 'i'
00571             &&  rcp[4] == 'c'
00572             && !(map[rcp[5]]&(DIGIT|LETTER))) {
00573                 cp = rcp + 5;
00574                 return STATIC;
00575             }
00576             if (rcp[0] == 't'
00577             &&  rcp[1] == 'r'
00578             &&  rcp[2] == 'u'
00579             &&  rcp[3] == 'c'
00580             &&  rcp[4] == 't'
00581             && !(map[rcp[5]]&(DIGIT|LETTER))) {
00582                 cp = rcp + 5;
00583                 return STRUCT;
00584             }
00585             if (rcp[0] == 'w'
00586             &&  rcp[1] == 'i'
00587             &&  rcp[2] == 't'
00588             &&  rcp[3] == 'c'
00589             &&  rcp[4] == 'h'
00590             && !(map[rcp[5]]&(DIGIT|LETTER))) {
00591                 cp = rcp + 5;
00592                 return SWITCH;
00593             }
00594             goto id;
00595         case 't':
00596             if (rcp[0] == 'y'
00597             &&  rcp[1] == 'p'
00598             &&  rcp[2] == 'e'
00599             &&  rcp[3] == 'd'
00600             &&  rcp[4] == 'e'
00601             &&  rcp[5] == 'f'
00602             && !(map[rcp[6]]&(DIGIT|LETTER))) {
00603                 cp = rcp + 6;
00604                 return TYPEDEF;
00605             }
00606             goto id;
00607         case 'u':
00608             if (rcp[0] == 'n'
00609             &&  rcp[1] == 'i'
00610             &&  rcp[2] == 'o'
00611             &&  rcp[3] == 'n'
00612             && !(map[rcp[4]]&(DIGIT|LETTER))) {
00613                 cp = rcp + 4;
00614                 return UNION;
00615             }
00616             if (rcp[0] == 'n'
00617             &&  rcp[1] == 's'
00618             &&  rcp[2] == 'i'
00619             &&  rcp[3] == 'g'
00620             &&  rcp[4] == 'n'
00621             &&  rcp[5] == 'e'
00622             &&  rcp[6] == 'd'
00623             && !(map[rcp[7]]&(DIGIT|LETTER))) {
00624                 cp = rcp + 7;
00625                 return UNSIGNED;
00626             }
00627             goto id;
00628         case 'v':
00629             if (rcp[0] == 'o'
00630             &&  rcp[1] == 'i'
00631             &&  rcp[2] == 'd'
00632             && !(map[rcp[3]]&(DIGIT|LETTER))) {
00633                 cp = rcp + 3;
00634                 tsym = voidtype->u.sym;
00635                 return VOID;
00636             }
00637             if (rcp[0] == 'o'
00638             &&  rcp[1] == 'l'
00639             &&  rcp[2] == 'a'
00640             &&  rcp[3] == 't'
00641             &&  rcp[4] == 'i'
00642             &&  rcp[5] == 'l'
00643             &&  rcp[6] == 'e'
00644             && !(map[rcp[7]]&(DIGIT|LETTER))) {
00645                 cp = rcp + 7;
00646                 return VOLATILE;
00647             }
00648             goto id;
00649         case 'w':
00650             if (rcp[0] == 'h'
00651             &&  rcp[1] == 'i'
00652             &&  rcp[2] == 'l'
00653             &&  rcp[3] == 'e'
00654             && !(map[rcp[4]]&(DIGIT|LETTER))) {
00655                 cp = rcp + 4;
00656                 return WHILE;
00657             }
00658             goto id;
00659         case '_':
00660             if (rcp[0] == '_'
00661             &&  rcp[1] == 't'
00662             &&  rcp[2] == 'y'
00663             &&  rcp[3] == 'p'
00664             &&  rcp[4] == 'e'
00665             &&  rcp[5] == 'c'
00666             &&  rcp[6] == 'o'
00667             &&  rcp[7] == 'd'
00668             &&  rcp[8] == 'e'
00669             && !(map[rcp[9]]&(DIGIT|LETTER))) {
00670                 cp = rcp + 9;
00671                 return TYPECODE;
00672             }
00673             if (rcp[0] == '_'
00674             &&  rcp[1] == 'f'
00675             &&  rcp[2] == 'i'
00676             &&  rcp[3] == 'r'
00677             &&  rcp[4] == 's'
00678             &&  rcp[5] == 't'
00679             &&  rcp[6] == 'a'
00680             &&  rcp[7] == 'r'
00681             &&  rcp[8] == 'g'
00682             && !(map[rcp[9]]&(DIGIT|LETTER))) {
00683                 cp = rcp + 9;
00684                 return FIRSTARG;
00685             }
00686             goto id;
00687         default:
00688             if ((map[cp[-1]]&BLANK) == 0)
00689                 if (cp[-1] < ' ' || cp[-1] >= 0177)
00690                     error("illegal character `\\0%o'\n", cp[-1]);
00691                 else
00692                     error("illegal character `%c'\n", cp[-1]);
00693         }
00694     }
00695 }
00696 static Symbol icon(unsigned long n, int overflow, int base) {
00697     if ((*cp=='u'||*cp=='U') && (cp[1]=='l'||cp[1]=='L')
00698     ||  (*cp=='l'||*cp=='L') && (cp[1]=='u'||cp[1]=='U')) {
00699         tval.type = unsignedlong;
00700         cp += 2;
00701     } else if (*cp == 'u' || *cp == 'U') {
00702         if (overflow || n > unsignedtype->u.sym->u.limits.max.i)
00703             tval.type = unsignedlong;
00704         else
00705             tval.type = unsignedtype;
00706         cp += 1;
00707     } else if (*cp == 'l' || *cp == 'L') {
00708         if (overflow || n > longtype->u.sym->u.limits.max.i)
00709             tval.type = unsignedlong;
00710         else
00711             tval.type = longtype;
00712         cp += 1;
00713     } else if (overflow || n > longtype->u.sym->u.limits.max.i)
00714         tval.type = unsignedlong;
00715     else if (n > inttype->u.sym->u.limits.max.i)
00716         tval.type = longtype;
00717     else if (base != 10 && n > inttype->u.sym->u.limits.max.i)
00718         tval.type = unsignedtype;
00719     else
00720         tval.type = inttype;
00721     switch (tval.type->op) {
00722     case INT:
00723         if (overflow || n > tval.type->u.sym->u.limits.max.i) {
00724             warning("overflow in constant `%S'\n", token,
00725                 (char*)cp - token);
00726             tval.u.c.v.i = tval.type->u.sym->u.limits.max.i;
00727         } else
00728             tval.u.c.v.i = n;
00729         break;
00730     case UNSIGNED:
00731         if (overflow || n > tval.type->u.sym->u.limits.max.u) {
00732             warning("overflow in constant `%S'\n", token,
00733                 (char*)cp - token);
00734             tval.u.c.v.u = tval.type->u.sym->u.limits.max.u;
00735         } else
00736             tval.u.c.v.u = n;
00737         break;
00738     default: assert(0);
00739     }
00740     ppnumber("integer");
00741     return &tval;
00742 }
00743 static void ppnumber(char *which) {
00744     unsigned char *rcp = cp--;
00745 
00746     for ( ; (map[*cp]&(DIGIT|LETTER)) || *cp == '.'; cp++)
00747         if ((cp[0] == 'E' || cp[0] == 'e')
00748         &&  (cp[1] == '-' || cp[1] == '+'))
00749             cp++;
00750     if (cp > rcp)
00751         error("`%S' is a preprocessing number but an invalid %s constant\n", token,
00752 
00753             (char*)cp-token, which);
00754 }
00755 static Symbol fcon(void) {
00756     if (*cp == '.')
00757         do
00758             cp++;
00759         while (map[*cp]&DIGIT);
00760     if (*cp == 'e' || *cp == 'E') {
00761         if (*++cp == '-' || *cp == '+')
00762             cp++;
00763         if (map[*cp]&DIGIT)
00764             do
00765                 cp++;
00766             while (map[*cp]&DIGIT);
00767         else
00768             error("invalid floating constant `%S'\n", token,
00769                 (char*)cp - token);
00770     }
00771 
00772     errno = 0;
00773     tval.u.c.v.d = strtod(token, NULL);
00774     if (errno == ERANGE)
00775         warning("overflow in floating constant `%S'\n", token,
00776             (char*)cp - token);
00777     if (*cp == 'f' || *cp == 'F') {
00778         ++cp;
00779         if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d)
00780             warning("overflow in floating constant `%S'\n", token,
00781                 (char*)cp - token);
00782         tval.type = floattype;
00783     } else if (*cp == 'l' || *cp == 'L') {
00784         cp++;
00785         tval.type = longdouble;
00786     } else {
00787         if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d)
00788             warning("overflow in floating constant `%S'\n", token,
00789                 (char*)cp - token);
00790         tval.type = doubletype;
00791     }
00792     ppnumber("floating");
00793     return &tval;
00794 }
00795 
00796 static void *cput(int c, void *cl) {
00797     char *s = cl;
00798 
00799     if (c < 0 || c > 255)
00800         warning("overflow in escape sequence with resulting value `%d'\n", c);
00801     *s++ = c;
00802     return s;
00803 }
00804 
00805 static void *wcput(int c, void *cl) {
00806     unsigned int *s = cl;
00807 
00808     *s++ = c;
00809     return s;
00810 }
00811 
00812 static void *scon(int q, void *put(int c, void *cl), void *cl) {
00813     int n = 0, nbad = 0;
00814 
00815     do {
00816         cp++;
00817         while (*cp != q) {
00818             int c;
00819             if (map[*cp]&NEWLINE) {
00820                 if (cp < limit)
00821                     break;
00822                 cp++;
00823                 nextline();
00824                 if (cp == limit)
00825                     break;
00826                 continue;
00827             }
00828             c = *cp++;
00829             if (c == '\\') {
00830                 if (map[*cp]&NEWLINE) {
00831                     if (cp < limit)
00832                         break;
00833                     cp++;
00834                     nextline();
00835                 }
00836                 if (limit - cp < MAXTOKEN)
00837                     fillbuf();
00838                 c = backslash(q);
00839             } else if (c < 0 || c > 255 || map[c] == 0)
00840                 nbad++;
00841             if (n++ < BUFSIZE)
00842                 cl = put(c, cl);
00843         }
00844         if (*cp == q)
00845             cp++;
00846         else
00847             error("missing %c\n", q);
00848     } while (q == '"' && getchr() == '"');
00849     cl = put(0, cl);
00850     if (n >= BUFSIZE)
00851         error("%s literal too long\n", q == '"' ? "string" : "character");
00852     if (Aflag >= 2 && q == '"' && n > 509)
00853         warning("more than 509 characters in a string literal\n");
00854     if (Aflag >= 2 && nbad > 0)
00855         warning("%s literal contains non-portable characters\n",
00856             q == '"' ? "string" : "character");
00857     return cl;
00858 }
00859 int getchr(void) {
00860     for (;;) {
00861         while (map[*cp]&BLANK)
00862             cp++;
00863         if (!(map[*cp]&NEWLINE))
00864             return *cp;
00865         cp++;
00866         nextline();
00867         if (cp == limit)
00868             return EOI;
00869     }
00870 }
00871 static int backslash(int q) {
00872     unsigned int c;
00873 
00874     switch (*cp++) {
00875     case 'a': return 7;
00876     case 'b': return '\b';
00877     case 'f': return '\f';
00878     case 'n': return '\n';
00879     case 'r': return '\r';
00880     case 't': return '\t';
00881     case 'v': return '\v';
00882     case '\'': case '"': case '\\': case '\?': break;
00883     case 'x': {
00884         int overflow = 0;
00885         if ((map[*cp]&(DIGIT|HEX)) == 0) {
00886             if (*cp < ' ' || *cp == 0177)
00887                 error("ill-formed hexadecimal escape sequence\n");
00888             else
00889                 error("ill-formed hexadecimal escape sequence `\\x%c'\n", *cp);
00890             if (*cp != q)
00891                 cp++;
00892             return 0;
00893         }
00894         for (c = 0; map[*cp]&(DIGIT|HEX); cp++) {
00895             if (c >> (8*widechar->size - 4))
00896                 overflow = 1;
00897             if (map[*cp]&DIGIT)
00898                 c = (c<<4) + *cp - '0';
00899             else
00900                 c = (c<<4) + (*cp&~040) - 'A' + 10;
00901         }
00902         if (overflow)
00903             warning("overflow in hexadecimal escape sequence\n");
00904         return c&ones(8*widechar->size);
00905         }
00906     case '0': case '1': case '2': case '3':
00907     case '4': case '5': case '6': case '7':
00908         c = *(cp-1) - '0';
00909         if (*cp >= '0' && *cp <= '7') {
00910             c = (c<<3) + *cp++ - '0';
00911             if (*cp >= '0' && *cp <= '7')
00912                 c = (c<<3) + *cp++ - '0';
00913         }
00914         return c;
00915     default:
00916         if (cp[-1] < ' ' || cp[-1] >= 0177)
00917             warning("unrecognized character escape sequence\n");
00918         else
00919             warning("unrecognized character escape sequence `\\%c'\n", cp[-1]);
00920     }
00921     return cp[-1];
00922 }

Generated on Thu Aug 25 12:38:09 2005 for Quake III Arena by  doxygen 1.3.9.1