|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.