Annotation of GNUtools/bison/lex.c, revision 1.1

1.1     ! root        1: /* Token-reader for Bison's input parser,
        !             2:    Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of Bison, the GNU Compiler Compiler.
        !             5: 
        !             6: Bison is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 2, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: Bison is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with Bison; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: 
        !            21: /* 
        !            22:    lex() is the entry point.  It is called from reader.c.
        !            23:    It returns one of the token-type codes defined in lex.h.
        !            24:    When an identifier is seen, the code IDENTIFIER is returned
        !            25:    and the name is looked up in the symbol table using symtab.c;
        !            26:    symval is set to a pointer to the entry found.  */
        !            27: 
        !            28: #include <stdio.h>
        !            29: #include <ctype.h>
        !            30: #include "system.h"
        !            31: #include "files.h"
        !            32: #include "symtab.h"
        !            33: #include "lex.h"
        !            34: #include "new.h"
        !            35: 
        !            36: 
        !            37: extern int lineno;
        !            38: extern int translations;
        !            39: 
        !            40: int parse_percent_token();
        !            41: 
        !            42: extern void fatals();
        !            43: extern void fatal();
        !            44: 
        !            45: /* Buffer for storing the current token.  */
        !            46: char *token_buffer;
        !            47: 
        !            48: /* Allocated size of token_buffer, not including space for terminator.  */
        !            49: static int maxtoken;
        !            50: 
        !            51: bucket *symval;
        !            52: int numval;
        !            53: 
        !            54: static int unlexed;            /* these two describe a token to be reread */
        !            55: static bucket *unlexed_symval; /* by the next call to lex */
        !            56: 
        !            57: 
        !            58: void
        !            59: init_lex()
        !            60: {
        !            61:   maxtoken = 100;
        !            62:   token_buffer = NEW2 (maxtoken + 1, char);
        !            63:   unlexed = -1;
        !            64: }
        !            65: 
        !            66: 
        !            67: static char *
        !            68: grow_token_buffer (p)
        !            69:      char *p;
        !            70: {
        !            71:   int offset = p - token_buffer;
        !            72:   maxtoken *= 2;
        !            73:   token_buffer = (char *) xrealloc(token_buffer, maxtoken + 1);
        !            74:   return token_buffer + offset;
        !            75: }
        !            76: 
        !            77: 
        !            78: int
        !            79: skip_white_space()
        !            80: {
        !            81:   register int c;
        !            82:   register int inside;
        !            83: 
        !            84:   c = getc(finput);
        !            85: 
        !            86:   for (;;)
        !            87:     {
        !            88:       int cplus_comment;
        !            89: 
        !            90:       switch (c)
        !            91:        {
        !            92:        case '/':
        !            93:          c = getc(finput);
        !            94:          if (c != '*' && c != '/')
        !            95:            fatals("unexpected `/%c' found",c);
        !            96:          cplus_comment = (c == '/');
        !            97: 
        !            98:          c = getc(finput);
        !            99: 
        !           100:          inside = 1;
        !           101:          while (inside)
        !           102:            {
        !           103:              if (!cplus_comment && c == '*')
        !           104:                {
        !           105:                  while (c == '*')
        !           106:                    c = getc(finput);
        !           107: 
        !           108:                  if (c == '/')
        !           109:                    {
        !           110:                      inside = 0;
        !           111:                      c = getc(finput);
        !           112:                    }
        !           113:                }
        !           114:              else if (c == '\n')
        !           115:                {
        !           116:                  lineno++;
        !           117:                  if (cplus_comment)
        !           118:                    inside = 0;
        !           119:                  c = getc(finput);
        !           120:                }
        !           121:              else if (c == EOF)
        !           122:                fatal("unterminated comment");
        !           123:              else
        !           124:                c = getc(finput);
        !           125:            }
        !           126: 
        !           127:          break;
        !           128: 
        !           129:        case '\n':
        !           130:          lineno++;
        !           131: 
        !           132:        case ' ':
        !           133:        case '\t':
        !           134:        case '\f':
        !           135:          c = getc(finput);
        !           136:          break;
        !           137: 
        !           138:        default:
        !           139:          return (c);
        !           140:        }
        !           141:     }
        !           142: }
        !           143: 
        !           144: 
        !           145: void
        !           146: unlex(token)
        !           147: int token;
        !           148: {
        !           149:   unlexed = token;
        !           150:   unlexed_symval = symval;
        !           151: }
        !           152: 
        !           153: 
        !           154: 
        !           155: int
        !           156: lex()
        !           157: {
        !           158:   register int c;
        !           159:   register char *p;
        !           160: 
        !           161:   if (unlexed >= 0)
        !           162:     {
        !           163:       symval = unlexed_symval;
        !           164:       c = unlexed;
        !           165:       unlexed = -1;
        !           166:       return (c);
        !           167:     }
        !           168: 
        !           169:   c = skip_white_space();
        !           170: 
        !           171:   switch (c)
        !           172:     {
        !           173:     case EOF:
        !           174:       return (ENDFILE);
        !           175: 
        !           176:     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
        !           177:     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
        !           178:     case 'K':  case 'L':  case 'M':  case 'N':  case 'O':
        !           179:     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
        !           180:     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
        !           181:     case 'Z':
        !           182:     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
        !           183:     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
        !           184:     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
        !           185:     case 'p':  case 'q':  case 'r':  case 's':  case 't':
        !           186:     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
        !           187:     case 'z':
        !           188:     case '.':  case '_':
        !           189:       p = token_buffer;
        !           190:       while (isalnum(c) || c == '_' || c == '.')
        !           191:        {
        !           192:          if (p == token_buffer + maxtoken)
        !           193:            p = grow_token_buffer(p);
        !           194: 
        !           195:          *p++ = c;
        !           196:          c = getc(finput);
        !           197:        }
        !           198: 
        !           199:       *p = 0;
        !           200:       ungetc(c, finput);
        !           201:       symval = getsym(token_buffer);
        !           202:       return (IDENTIFIER);
        !           203: 
        !           204:     case '0':  case '1':  case '2':  case '3':  case '4':
        !           205:     case '5':  case '6':  case '7':  case '8':  case '9':
        !           206:       {
        !           207:        numval = 0;
        !           208: 
        !           209:        while (isdigit(c))
        !           210:          {
        !           211:            numval = numval*10 + c - '0';
        !           212:            c = getc(finput);
        !           213:          }
        !           214:        ungetc(c, finput);
        !           215:        return (NUMBER);
        !           216:       }
        !           217: 
        !           218:     case '\'':
        !           219:       translations = -1;
        !           220: 
        !           221:       /* parse the literal token and compute character code in  code  */
        !           222: 
        !           223:       c = getc(finput);
        !           224:       {
        !           225:        register int code = 0;
        !           226: 
        !           227:        if (c == '\\')
        !           228:          {
        !           229:            c = getc(finput);
        !           230: 
        !           231:            if (c <= '7' && c >= '0')
        !           232:              {
        !           233:                while (c <= '7' && c >= '0')
        !           234:                  {
        !           235:                    code = (code * 8) + (c - '0');
        !           236:                    c = getc(finput);
        !           237:                    if (code >= 256 || code < 0)
        !           238:                      fatals("malformatted literal token `\\%03o'", code);
        !           239:                  }
        !           240:              }
        !           241:            else
        !           242:              {
        !           243:                if (c == 't')
        !           244:                  code = '\t';
        !           245:                else if (c == 'n')
        !           246:                  code = '\n';
        !           247:                else if (c == 'a')
        !           248:                  code = '\007';
        !           249:                else if (c == 'r')
        !           250:                  code = '\r';
        !           251:                else if (c == 'f')
        !           252:                  code = '\f';
        !           253:                else if (c == 'b')
        !           254:                  code = '\b';
        !           255:                else if (c == 'v')
        !           256:                  code = 013;
        !           257:                else if (c == 'x')
        !           258:                  {
        !           259:                    c = getc(finput);
        !           260:                    while ((c <= '9' && c >= '0')
        !           261:                           || (c >= 'a' && c <= 'z')
        !           262:                           || (c >= 'A' && c <= 'Z'))
        !           263:                      {
        !           264:                        code *= 16;
        !           265:                        if (c <= '9' && c >= '0')
        !           266:                          code += c - '0';
        !           267:                        else if (c >= 'a' && c <= 'z')
        !           268:                          code += c - 'a' + 10;
        !           269:                        else if (c >= 'A' && c <= 'Z')
        !           270:                          code += c - 'A' + 10;
        !           271:                        if (code >= 256 || code<0)/* JF this said if(c>=128) */
        !           272:                          fatals("malformatted literal token `\\x%x'",code);
        !           273:                        c = getc(finput);
        !           274:                      }
        !           275:                    ungetc(c, finput);
        !           276:                  }
        !           277:                else if (c == '\\')
        !           278:                  code = '\\';
        !           279:                else if (c == '\'')
        !           280:                  code = '\'';
        !           281:                else if (c == '\"')     /* JF this is a good idea */
        !           282:                  code = '\"';
        !           283:                else
        !           284:                  {
        !           285:                    if (c >= 040 && c <= 0177)
        !           286:                      fatals ("unknown escape sequence `\\%c'", c);
        !           287:                    else
        !           288:                      fatals ("unknown escape sequence: `\\' followed by char code 0x%x", c);
        !           289:                  }
        !           290: 
        !           291:                c = getc(finput);
        !           292:              }
        !           293:          }
        !           294:        else
        !           295:          {
        !           296:            code = c;
        !           297:            c = getc(finput);
        !           298:          }
        !           299:        if (c != '\'')
        !           300:          fatal("multicharacter literal tokens not supported");
        !           301: 
        !           302:        /* now fill token_buffer with the canonical name for this character
        !           303:           as a literal token.  Do not use what the user typed,
        !           304:           so that '\012' and '\n' can be interchangeable.  */
        !           305: 
        !           306:        p = token_buffer;
        !           307:        *p++ = '\'';
        !           308:        if (code == '\\')
        !           309:          {
        !           310:            *p++ = '\\';
        !           311:            *p++ = '\\';
        !           312:          }
        !           313:        else if (code == '\'')
        !           314:          {
        !           315:            *p++ = '\\';
        !           316:            *p++ = '\'';
        !           317:          }
        !           318:        else if (code >= 040 && code != 0177)
        !           319:          *p++ = code;
        !           320:        else if (code == '\t')
        !           321:          {
        !           322:            *p++ = '\\';
        !           323:            *p++ = 't';
        !           324:          }
        !           325:        else if (code == '\n')
        !           326:          {
        !           327:            *p++ = '\\';
        !           328:            *p++ = 'n';
        !           329:          }
        !           330:        else if (code == '\r')
        !           331:          {
        !           332:            *p++ = '\\';
        !           333:            *p++ = 'r';
        !           334:          }
        !           335:        else if (code == '\v')
        !           336:          {
        !           337:            *p++ = '\\';
        !           338:            *p++ = 'v';
        !           339:          }
        !           340:        else if (code == '\b')
        !           341:          {
        !           342:            *p++ = '\\';
        !           343:            *p++ = 'b';
        !           344:          }
        !           345:        else if (code == '\f')
        !           346:          {
        !           347:            *p++ = '\\';
        !           348:            *p++ = 'f';
        !           349:          }
        !           350:         else
        !           351:          {
        !           352:            *p++ = code / 0100 + '0';
        !           353:            *p++ = ((code / 010) & 07) + '0';
        !           354:            *p++ = (code & 07) + '0';
        !           355:          }
        !           356:        *p++ = '\'';
        !           357:        *p = 0;
        !           358:        symval = getsym(token_buffer);
        !           359:        symval->class = STOKEN;
        !           360:        if (! symval->user_token_number)
        !           361:          symval->user_token_number = code;
        !           362:        return (IDENTIFIER);
        !           363:       }
        !           364: 
        !           365:     case ',':
        !           366:       return (COMMA);
        !           367: 
        !           368:     case ':':
        !           369:       return (COLON);
        !           370: 
        !           371:     case ';':
        !           372:       return (SEMICOLON);
        !           373: 
        !           374:     case '|':
        !           375:       return (BAR);
        !           376: 
        !           377:     case '{':
        !           378:       return (LEFT_CURLY);
        !           379: 
        !           380:     case '=':
        !           381:       do
        !           382:        {
        !           383:          c = getc(finput);
        !           384:          if (c == '\n') lineno++;
        !           385:        }
        !           386:       while(c==' ' || c=='\n' || c=='\t');
        !           387: 
        !           388:       if (c == '{')
        !           389:        return(LEFT_CURLY);
        !           390:       else
        !           391:        {
        !           392:          ungetc(c, finput);
        !           393:          return(ILLEGAL);
        !           394:        }
        !           395: 
        !           396:     case '<':
        !           397:       p = token_buffer;
        !           398:       c = getc(finput);
        !           399:       while (c != '>')
        !           400:        {
        !           401:          if (c == '\n' || c == EOF)
        !           402:            fatal("unterminated type name");
        !           403: 
        !           404:          if (p == token_buffer + maxtoken)
        !           405:            p = grow_token_buffer(p);
        !           406: 
        !           407:          *p++ = c;
        !           408:          c = getc(finput);
        !           409:        }
        !           410:       *p = 0;
        !           411:       return (TYPENAME);
        !           412:            
        !           413: 
        !           414:     case '%':
        !           415:       return (parse_percent_token());
        !           416: 
        !           417:     default:
        !           418:       return (ILLEGAL);
        !           419:     }
        !           420: }
        !           421: 
        !           422: 
        !           423: /* parse a token which starts with %.  Assumes the % has already been read and discarded.  */
        !           424: 
        !           425: int
        !           426: parse_percent_token ()
        !           427: {
        !           428:   register int c;
        !           429:   register char *p;
        !           430: 
        !           431:   p = token_buffer;
        !           432:   c = getc(finput);
        !           433: 
        !           434:   switch (c)
        !           435:     {
        !           436:     case '%':
        !           437:       return (TWO_PERCENTS);
        !           438: 
        !           439:     case '{':
        !           440:       return (PERCENT_LEFT_CURLY);
        !           441: 
        !           442:     case '<':
        !           443:       return (LEFT);
        !           444: 
        !           445:     case '>':
        !           446:       return (RIGHT);
        !           447: 
        !           448:     case '2':
        !           449:       return (NONASSOC);
        !           450: 
        !           451:     case '0':
        !           452:       return (TOKEN);
        !           453: 
        !           454:     case '=':
        !           455:       return (PREC);
        !           456:     }
        !           457:   if (!isalpha(c))
        !           458:     return (ILLEGAL);
        !           459: 
        !           460:   while (isalpha(c) || c == '_')
        !           461:     {
        !           462:       if (p == token_buffer + maxtoken)
        !           463:        p = grow_token_buffer(p);
        !           464: 
        !           465:       *p++ = c;
        !           466:       c = getc(finput);
        !           467:     }
        !           468: 
        !           469:   ungetc(c, finput);
        !           470: 
        !           471:   *p = 0;
        !           472: 
        !           473:   if (strcmp(token_buffer, "token") == 0
        !           474:       ||
        !           475:       strcmp(token_buffer, "term") == 0)
        !           476:     return (TOKEN);
        !           477:   else if (strcmp(token_buffer, "nterm") == 0)
        !           478:     return (NTERM);
        !           479:   else if (strcmp(token_buffer, "type") == 0)
        !           480:     return (TYPE);
        !           481:   else if (strcmp(token_buffer, "guard") == 0)
        !           482:     return (GUARD);
        !           483:   else if (strcmp(token_buffer, "union") == 0)
        !           484:     return (UNION);
        !           485:   else if (strcmp(token_buffer, "expect") == 0)
        !           486:     return (EXPECT);
        !           487:   else if (strcmp(token_buffer, "start") == 0)
        !           488:     return (START);
        !           489:   else if (strcmp(token_buffer, "left") == 0)
        !           490:     return (LEFT);
        !           491:   else if (strcmp(token_buffer, "right") == 0)
        !           492:     return (RIGHT);
        !           493:   else if (strcmp(token_buffer, "nonassoc") == 0
        !           494:           ||
        !           495:           strcmp(token_buffer, "binary") == 0)
        !           496:     return (NONASSOC);
        !           497:   else if (strcmp(token_buffer, "semantic_parser") == 0)
        !           498:     return (SEMANTIC_PARSER);
        !           499:   else if (strcmp(token_buffer, "pure_parser") == 0)
        !           500:     return (PURE_PARSER);
        !           501:   else if (strcmp(token_buffer, "prec") == 0)
        !           502:     return (PREC);
        !           503:   else return (ILLEGAL);
        !           504: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.