home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / bi-lexer.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  171 lines

  1. /* Lexer for scanner of bytecode definition file.
  2.    Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC 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. GNU CC 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 GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include "hconfig.h"
  22. #include "bi-parser.h"
  23.  
  24. /* Current read buffer and point */
  25. static char *buffer = NULL;
  26. static char *inpoint = NULL;
  27.  
  28.  
  29. /* Safely allocate NBYTES bytes of memory. Reuturns pointer to block of
  30.    memory. */
  31.  
  32. static char *
  33. xmalloc (nbytes)
  34.      int nbytes;
  35. {
  36.   char *tmp = (char *) malloc (nbytes);
  37.  
  38.   if (!tmp)
  39.     {
  40.       fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
  41.       exit (FATAL_EXIT_CODE);
  42.     }
  43.  
  44.   return tmp;
  45. }
  46.  
  47.  
  48. /* Safely reallocate BLOCK so its size becomes NBYTES.
  49.    The block returned may be different from the one supplied. */
  50.  
  51. static char *
  52. xrealloc (block, nbytes)
  53.      char *block;
  54.      int nbytes;
  55. {
  56.   char *tmp = (block
  57.            ? (char *) realloc (block, nbytes)
  58.            : (char *) malloc (nbytes));
  59.  
  60.   if (!tmp)
  61.     {
  62.       fprintf (stderr, "can't reallocate %d bytes (out of virtual memory)\n", nbytes);
  63.       exit (FATAL_EXIT_CODE);
  64.     }
  65.  
  66.   return tmp;
  67. }
  68.  
  69.  
  70. /* Scan for string token on standard input.  A string is, for our
  71.    purposes here, a sequence of characters that starts with the regexp
  72.    ``[^ #\t\n(),]'' and is then followed by the regexp ``[^#(),]*''. Any
  73.    character is accepted if preceded by a backslash, "\\".  It is assumed
  74.    that the first character has already been checked by the main loop. */
  75.  
  76. static char *
  77. scan_string ()
  78. {
  79.   char *buffer = NULL;
  80.   char *point = NULL;
  81.   int buffer_size = 0;
  82.   int c;
  83.  
  84.   while ((c = getc (stdin)) != EOF
  85.      && c != '#' && c != '(' && c != ')' && c != ',')
  86.     {
  87.       /* Extend buffer, if necessary (minus two so there's room for the NUL
  88.      trailer as well as another character if this one is a backslash).  */
  89.       if (!buffer_size || (point - buffer >= buffer_size-2))
  90.     {
  91.       int previous_point_index = point - buffer;
  92.  
  93.       buffer_size = (!buffer_size ? 32 : buffer_size * 2);
  94.       if (!buffer)
  95.         buffer = xmalloc (buffer_size);
  96.       else
  97.         buffer = xrealloc (buffer, buffer_size);
  98.       
  99.       point = buffer + previous_point_index;
  100.     }
  101.       *point++ = c & 0xff;
  102.  
  103.       if (c == '\\')
  104.     {
  105.       c = getc (stdin);
  106.  
  107.       /* Catch special case: backslash at end of file */
  108.       if (c == EOF)
  109.         break;
  110.  
  111.       *point++ = c;
  112.     }
  113.     }
  114.   *point = 0;
  115.  
  116.   if (c != EOF)
  117.     ungetc (c, stdin);
  118.  
  119.   return buffer;
  120. }
  121.  
  122.  
  123. int
  124. yylex ()
  125. {
  126.   int c;
  127.   char *token;
  128.  
  129.  
  130.   /* First char determines what token we're looking at */
  131.   for (;;)
  132.     {
  133.       c = getc (stdin);
  134.  
  135.       switch (c)
  136.     {
  137.     case EOF:
  138.       return 0;
  139.       
  140.     case ' ':
  141.     case '\t':
  142.     case '\n':
  143.       /* Ignore whitespace */
  144.       continue;
  145.       
  146.     case '#':
  147.       /* Comments advance to next line */
  148.       while ((c = getc (stdin)) != '\n' && c != EOF);
  149.       continue;
  150.       
  151.     default:
  152.       if (c != '(' && c != ')' && c != '\\' && c != ',')
  153.         {
  154.           ungetc (c, stdin);
  155.           yylval.string = scan_string ();
  156.  
  157.           /* Check if string is "define_operator"; if so, return
  158.          a DEFOP token instead.  */
  159.           if (!strcmp (yylval.string, "define_operator"))
  160.         {
  161.           free (yylval.string);
  162.           yylval.string = 0;
  163.           return DEFOP;
  164.         }
  165.           return STRING;
  166.         }
  167.       return c & 0xff;
  168.     }
  169.     }
  170. }
  171.