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

lex.c File Reference

#include "c.h"
#include <float.h>
#include <errno.h>

Include dependency graph for lex.c:

Include dependency graph

Go to the source code of this file.

Defines

#define MAXTOKEN   32

Enumerations

enum  {
  BLANK = 01, NEWLINE = 02, LETTER = 04, DIGIT = 010,
  HEX = 020, OTHER = 040
}

Functions

int backslash (int q)
void * cput (int c, void *cl)
Symbol fcon (void)
int getchr (void)
int gettok (void)
Symbol icon (unsigned long, int, int)
void ppnumber (char *)
void * scon (int q, void *put(int c, void *cl), void *cl)
void * wcput (int c, void *cl)

Variables

char cbuf [BUFSIZE+1]
unsigned char map [256]
Coordinate src
int t
char * token
Symbol tsym
symbol tval
unsigned int wcbuf [BUFSIZE+1]


Define Documentation

#define MAXTOKEN   32
 

Definition at line 6 of file lex.c.


Enumeration Type Documentation

anonymous enum
 

Enumeration values:
BLANK 
NEWLINE 
LETTER 
DIGIT 
HEX 
OTHER 

Definition at line 8 of file lex.c.

00008      { BLANK=01,  NEWLINE=02, LETTER=04,
00009        DIGIT=010, HEX=020,    OTHER=040 };


Function Documentation

int backslash int  q  )  [static]
 

Definition at line 871 of file lex.c.

References c, cp, DIGIT, error(), map, ones, type::size, warning(), and widechar.

00871                             {
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 }

Here is the call graph for this function:

void * cput int  c,
void *  cl
[static]
 

Definition at line 796 of file lex.c.

References c, s, and warning().

Referenced by gettok().

00796                                    {
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 }

Here is the call graph for this function:

Symbol fcon void   )  [static]
 

Definition at line 755 of file lex.c.

References symbol::c, cp, value::d, doubletype, errno, error(), floattype, symbol::limits, map, symbol::max, NULL, ppnumber(), strtod(), type::sym, Symbol, token, tval, symbol::type, type::u, symbol::u, symbol::v, and warning().

Referenced by gettok().

00755                          {
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 }

Here is the call graph for this function:

int getchr void   ) 
 

Definition at line 859 of file lex.c.

References cp, map, and nextline().

Referenced by compound(), scon(), and statement().

00859                  {
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 }

Here is the call graph for this function:

int gettok void   ) 
 

Definition at line 155 of file lex.c.

References ANDAND, array(), assert, symbol::c, c, cbuf, chartype, cp, cput(), d, DIGIT, doubletype, EQL, err(), error(), extend, fcon(), coord::file, fillbuf(), floattype, value::i, icon(), identifiers, INCR, inttype, limit, LONG, lookup(), map, n, NEQ, nextline(), type::op, OROR, value::p, s, scon(), src, stringn(), type::sym, token, tsym, tval, symbol::type, value::u, symbol::u, type::u, ULONG_MAX, symbol::v, voidtype, warning(), wcbuf, wcput(), widechar, coord::x, and coord::y.

Referenced by dclglobal(), dcllocal(), dclparam(), dclr1(), decl(), dostmt(), enumdcl(), expr1(), forstmt(), ifstmt(), initarray(), initchar(), initend(), initfields(), initglobal(), initializer(), initstruct(), main(), parameters(), pragma(), program(), specifier(), statement(), stmtlabel(), structdcl(), swstmt(), and whilestmt().

00155                  {
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 }

Here is the call graph for this function:

Symbol icon unsigned  long,
int  ,
int 
[static]
 

Definition at line 696 of file lex.c.

References assert, symbol::c, cp, value::i, INT, inttype, symbol::limits, longtype, symbol::max, n, type::op, ppnumber(), type::sym, Symbol, token, tval, symbol::type, value::u, symbol::u, type::u, UNSIGNED, unsignedtype, symbol::v, and warning().

Referenced by gettok().

00696                                                             {
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 }

Here is the call graph for this function:

void ppnumber char *   )  [static]
 

Definition at line 743 of file lex.c.

References cp, DIGIT, error(), map, and token.

Referenced by fcon(), and icon().

00743                                   {
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 }

Here is the call graph for this function:

void * scon int  q,
void *  put(int c, void *cl),
void *  cl
[static]
 

Definition at line 812 of file lex.c.

References Aflag, backslash(), c, cl, cp, error(), fillbuf(), getchr(), limit, map, n, nextline(), put(), q, and warning().

Referenced by gettok().

00812                                                                {
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 }

Here is the call graph for this function:

void * wcput int  c,
void *  cl
[static]
 

Definition at line 805 of file lex.c.

References s.

Referenced by gettok().

00805                                     {
00806     unsigned int *s = cl;
00807 
00808     *s++ = c;
00809     return s;
00810 }


Variable Documentation

char cbuf[BUFSIZE+1] [static]
 

Definition at line 139 of file lex.c.

Referenced by gettok().

unsigned char map[256] [static]
 

Definition at line 11 of file lex.c.

Referenced by backslash(), fcon(), getchr(), gettok(), ppnumber(), and scon().

Coordinate src
 

Definition at line 142 of file lex.c.

Referenced by __ConvertDOSToUnixName(), __ExtractFileBase(), __ExtractFileExtension(), __ExtractFileName(), __ExtractFilePath(), builtin(), CalcPHS(), COM_DefaultExtension(), Com_DefaultExtension(), Com_Memcpy(), compile(), ConcatRemaining(), Convert