Annotation of src/usr.bin/compile_et/error_table.y, Revision 1.1
1.1 ! downsj 1: %{
! 2: /* $OpenBSD$ */
! 3:
! 4: /*-
! 5: * Copyright 1987, 1988 by the Student Information Processing Board
! 6: * of the Massachusetts Institute of Technology
! 7: *
! 8: * Permission to use, copy, modify, and distribute this software
! 9: * and its documentation for any purpose and without fee is
! 10: * hereby granted, provided that the above copyright notice
! 11: * appear in all copies and that both that copyright notice and
! 12: * this permission notice appear in supporting documentation,
! 13: * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
! 14: * used in advertising or publicity pertaining to distribution
! 15: * of the software without specific, written prior permission.
! 16: * M.I.T. and the M.I.T. S.I.P.B. make no representations about
! 17: * the suitability of this software for any purpose. It is
! 18: * provided "as is" without express or implied warranty.
! 19: */
! 20:
! 21: #include <stdio.h>
! 22: #include <stdlib.h>
! 23: char *str_concat(), *ds(), *quote();
! 24: char *current_token = (char *)NULL;
! 25: extern char *table_name;
! 26: %}
! 27: %union {
! 28: char *dynstr;
! 29: }
! 30:
! 31: %token ERROR_TABLE ERROR_CODE_ENTRY END
! 32: %token <dynstr> STRING QUOTED_STRING
! 33: %type <dynstr> ec_name description table_id
! 34: %{
! 35: %}
! 36: %start error_table
! 37: %%
! 38:
! 39: error_table : ERROR_TABLE table_id error_codes END
! 40: { table_name = ds($2);
! 41: current_token = table_name;
! 42: put_ecs(); }
! 43: ;
! 44:
! 45: table_id : STRING
! 46: { current_token = $1;
! 47: set_table_num($1);
! 48: $$ = $1; }
! 49: ;
! 50:
! 51: error_codes : error_codes ec_entry
! 52: | ec_entry
! 53: ;
! 54:
! 55: ec_entry : ERROR_CODE_ENTRY ec_name ',' description
! 56: { add_ec($2, $4);
! 57: free($2);
! 58: free($4); }
! 59: | ERROR_CODE_ENTRY ec_name '=' STRING ',' description
! 60: { add_ec_val($2, $4, $6);
! 61: free($2);
! 62: free($4);
! 63: free($6);
! 64: }
! 65: ;
! 66:
! 67: ec_name : STRING
! 68: { $$ = ds($1);
! 69: current_token = $$; }
! 70: ;
! 71:
! 72: description : QUOTED_STRING
! 73: { $$ = ds($1);
! 74: current_token = $$; }
! 75: ;
! 76:
! 77: %%
! 78: /*
! 79: * Copyright 1987, 1988 by the Student Information Processing Board
! 80: * of the Massachusetts Institute of Technology
! 81: *
! 82: * Permission to use, copy, modify, and distribute this software
! 83: * and its documentation for any purpose and without fee is
! 84: * hereby granted, provided that the above copyright notice
! 85: * appear in all copies and that both that copyright notice and
! 86: * this permission notice appear in supporting documentation,
! 87: * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
! 88: * used in advertising or publicity pertaining to distribution
! 89: * of the software without specific, written prior permission.
! 90: * M.I.T. and the M.I.T. S.I.P.B. make no representations about
! 91: * the suitability of this software for any purpose. It is
! 92: * provided "as is" without express or implied warranty.
! 93: */
! 94:
! 95: #include <string.h>
! 96: #include <assert.h>
! 97: #include <ctype.h>
! 98: #include <sys/types.h>
! 99: #include <sys/time.h>
! 100: #include "error_table.h"
! 101:
! 102: #ifndef lint
! 103: static char const rcsid_error_table_y[] =
! 104: "$Id: error_table.y,v 1.2 1996/09/15 23:27:09 millert Exp $";
! 105: #endif
! 106:
! 107: #include "et_lex.lex.c"
! 108:
! 109: extern FILE *hfile, *cfile;
! 110:
! 111: static long gensym_n = 0;
! 112: char *
! 113: gensym(x)
! 114: char const *x;
! 115: {
! 116: char *symbol;
! 117: if (!gensym_n) {
! 118: struct timeval tv;
! 119: struct timezone tzp;
! 120: gettimeofday(&tv, &tzp);
! 121: gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000;
! 122: }
! 123: symbol = (char *)malloc(32 * sizeof(char));
! 124: gensym_n++;
! 125: snprintf(symbol, 32 * sizeof(char), "et%ld", gensym_n);
! 126: return(symbol);
! 127: }
! 128:
! 129: char *
! 130: ds(string)
! 131: char const *string;
! 132: {
! 133: char *rv;
! 134: rv = (char *)malloc(strlen(string)+1);
! 135: strcpy(rv, string);
! 136: return(rv);
! 137: }
! 138:
! 139: char *
! 140: quote(string)
! 141: char const *string;
! 142: {
! 143: char *rv;
! 144: rv = (char *)malloc(strlen(string)+3);
! 145: strcpy(rv, "\"");
! 146: strcat(rv, string);
! 147: strcat(rv, "\"");
! 148: return(rv);
! 149: }
! 150:
! 151: long table_number;
! 152: int current = 0;
! 153: char **error_codes = (char **)NULL;
! 154:
! 155: add_ec(name, description)
! 156: char const *name, *description;
! 157: {
! 158: fprintf(cfile, "\t\"%s\",\n", description);
! 159: if (error_codes == (char **)NULL) {
! 160: error_codes = (char **)malloc(sizeof(char *));
! 161: *error_codes = (char *)NULL;
! 162: }
! 163: error_codes = (char **)realloc((char *)error_codes,
! 164: (current + 2)*sizeof(char *));
! 165: error_codes[current++] = ds(name);
! 166: error_codes[current] = (char *)NULL;
! 167: }
! 168:
! 169: add_ec_val(name, val, description)
! 170: char const *name, *val, *description;
! 171: {
! 172: const int ncurrent = atoi(val);
! 173: if (ncurrent < current) {
! 174: printf("Error code %s (%d) out of order", name,
! 175: current);
! 176: return;
! 177: }
! 178:
! 179: while (ncurrent > current)
! 180: fputs("\t(char *)NULL,\n", cfile), current++;
! 181:
! 182: fprintf(cfile, "\t\"%s\",\n", description);
! 183: if (error_codes == (char **)NULL) {
! 184: error_codes = (char **)malloc(sizeof(char *));
! 185: *error_codes = (char *)NULL;
! 186: }
! 187: error_codes = (char **)realloc((char *)error_codes,
! 188: (current + 2)*sizeof(char *));
! 189: error_codes[current++] = ds(name);
! 190: error_codes[current] = (char *)NULL;
! 191: }
! 192:
! 193: put_ecs()
! 194: {
! 195: int i;
! 196: for (i = 0; i < current; i++) {
! 197: if (error_codes[i] != (char *)NULL)
! 198: fprintf(hfile, "#define %-40s (%ldL)\n",
! 199: error_codes[i], table_number + i);
! 200: }
! 201: }
! 202:
! 203: /*
! 204: * char_to_num -- maps letters and numbers into a small numbering space
! 205: * uppercase -> 1-26
! 206: * lowercase -> 27-52
! 207: * digits -> 53-62
! 208: * underscore-> 63
! 209: */
! 210:
! 211: static const char char_set[] =
! 212: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
! 213:
! 214: int char_to_num(c)
! 215: char c;
! 216: {
! 217: const char *where;
! 218: int diff;
! 219:
! 220: where = strchr (char_set, c);
! 221: if (where) {
! 222: diff = where - char_set + 1;
! 223: assert (diff < (1 << ERRCODE_RANGE));
! 224: return diff;
! 225: }
! 226: else if (isprint (c))
! 227: fprintf (stderr,
! 228: "Illegal character `%c' in error table name\n",
! 229: c);
! 230: else
! 231: fprintf (stderr,
! 232: "Illegal character %03o in error table name\n",
! 233: c);
! 234: exit (1);
! 235: }
! 236:
! 237: set_table_num(string)
! 238: char *string;
! 239: {
! 240: if (char_to_num (string[0]) > char_to_num ('z')) {
! 241: fprintf (stderr, "%s%s%s%s",
! 242: "First character of error table name must be ",
! 243: "a letter; name ``",
! 244: string, "'' rejected\n");
! 245: exit (1);
! 246: }
! 247: if (strlen(string) > 4) {
! 248: fprintf(stderr, "Table name %s too long, truncated ",
! 249: string);
! 250: string[4] = '\0';
! 251: fprintf(stderr, "to %s\n", string);
! 252: }
! 253: while (*string != '\0') {
! 254: table_number = (table_number << BITS_PER_CHAR)
! 255: + char_to_num(*string);
! 256: string++;
! 257: }
! 258: table_number = table_number << ERRCODE_RANGE;
! 259: }
! 260: