Initial revision
authorJan Brittenson <bson@gnu.org>
Sat, 25 Sep 1993 10:17:32 +0000 (03:17 -0700)
committerJan Brittenson <bson@gnu.org>
Sat, 25 Sep 1993 10:17:32 +0000 (03:17 -0700)
From-SVN: r5470

gcc/bi-lexer.c [new file with mode: 0644]

diff --git a/gcc/bi-lexer.c b/gcc/bi-lexer.c
new file mode 100644 (file)
index 0000000..954638a
--- /dev/null
@@ -0,0 +1,171 @@
+/* Lexer for scanner of bytecode definition file.
+   Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "bi-parser.h"
+
+extern char *malloc ();
+extern char *realloc ();
+
+
+/* Current read buffer and point */
+static char *buffer = NULL;
+static char *inpoint = NULL;
+
+
+/* Safely allocate NBYTES bytes of memory. Reuturns pointer to block of
+   memory. */
+
+static char *
+xmalloc (nbytes)
+     int nbytes;
+{
+  char *tmp = malloc (nbytes);
+
+  if (!tmp)
+    {
+      fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
+      exit (1);
+    }
+
+  return tmp;
+}
+
+
+/* Safely reallocate BLOCK so its size becomes NBYTES.
+   The block returned may be different from the one supplied. */
+
+static char *
+xrealloc (block, nbytes)
+     char *block;
+     int nbytes;
+{
+  char *tmp = realloc (block, nbytes);
+
+  if (!tmp)
+    {
+      fprintf (stderr, "can't reallocate %d bytes (out of virtual memory)\n", nbytes);
+      exit (1);
+    }
+
+  return tmp;
+}
+
+
+/* Scan for string token on standard input.  A string is, for our
+   purposes here, a sequence of characters that starts with the regexp
+   ``[^ #\t\n(),]'' and is then followed by the regexp ``[^#(),]*''. Any
+   character is accepted if preceded by a backslash, "\\".  It is assumed
+   that the first character has already been checked by the main loop. */
+
+static char *
+scan_string ()
+{
+  char *buffer = NULL;
+  char *point = NULL;
+  int buffer_size = 0;
+  int c;
+
+  while ((c = getc (stdin)) != EOF
+        && c != '#' && c != '(' && c != ')' && c != ',')
+    {
+      /* Extend buffer, if necessary (minus two so there's room for the NUL
+        trailer as well as another character if this one is a backslash).  */
+      if (!buffer_size || (point - buffer >= buffer_size-2))
+       {
+         int previous_point_index = point - buffer;
+
+         buffer_size = (!buffer_size ? 32 : buffer_size * 2);
+         if (buffer)
+           buffer = xmalloc (buffer_size);
+         else
+           buffer = xrealloc (buffer, buffer_size);
+         
+         point = buffer + previous_point_index;
+       }
+      *point++ = c & 0xff;
+
+      if (c == '\\')
+       {
+         c = getc (stdin);
+
+         /* Catch special case: backslash at end of file */
+         if (c == EOF)
+           break;
+
+         *point++ = c;
+       }
+    }
+  *point = 0;
+
+  if (c != EOF)
+    ungetc (c, stdin);
+
+  return buffer;
+}
+
+
+int
+yylex ()
+{
+  int c;
+  char *token;
+
+
+  /* First char determines what token we're looking at */
+  for (;;)
+    {
+      c = getc (stdin);
+
+      switch (c)
+       {
+       case EOF:
+         return 0;
+         
+       case ' ':
+       case '\t':
+       case '\n':
+         /* Ignore whitespace */
+         continue;
+         
+       case '#':
+         /* Comments advance to next line */
+         while ((c = getc (stdin)) != '\n' && c != EOF);
+         continue;
+         
+       default:
+         if (c != '(' && c != ')' && c != '\\' && c != ',')
+           {
+             ungetc (c, stdin);
+             yylval.string = scan_string ();
+
+             /* Check if string is "define_operator"; if so, return
+                a DEFOP token instead.  */
+             if (!strcmp (yylval.string, "define_operator"))
+               {
+                 free (yylval.string);
+                 yylval.string = 0;
+                 return DEFOP;
+               }
+             return STRING;
+           }
+         return c & 0xff;
+       }
+    }
+}