00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef lint
00038 char copyright[] =
00039 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\
00040 All rights reserved.\n";
00041 #endif
00042
00043 #ifndef lint
00044 static char sccsid[] = "@(#)mksyntax.c 5.2 (Berkeley) 3/8/91";
00045 #endif
00046
00047
00048
00049
00050
00051 #include <stdio.h>
00052 #include "parser.h"
00053
00054
00055 struct synclass {
00056 char *name;
00057 char *comment;
00058 };
00059
00060
00061 struct synclass synclass[] = {
00062 "CWORD", "character is nothing special",
00063 "CNL", "newline character",
00064 "CBACK", "a backslash character",
00065 "CSQUOTE", "single quote",
00066 "CDQUOTE", "double quote",
00067 "CENDQUOTE", "a terminating quote",
00068 "CBQUOTE", "backwards single quote",
00069 "CVAR", "a dollar sign",
00070 "CENDVAR", "a '}' character",
00071 "CEOF", "end of file",
00072 "CCTL", "like CWORD, except it must be escaped",
00073 "CSPCL", "these terminate a word",
00074 NULL, NULL
00075 };
00076
00077
00078
00079
00080
00081
00082 struct synclass is_entry[] = {
00083 "ISDIGIT", "a digit",
00084 "ISUPPER", "an upper case letter",
00085 "ISLOWER", "a lower case letter",
00086 "ISUNDER", "an underscore",
00087 "ISSPECL", "the name of a special parameter",
00088 NULL, NULL,
00089 };
00090
00091 char writer[] = "\
00092 /*\n\
00093 * This file was generated by the mksyntax program.\n\
00094 */\n\
00095 \n";
00096
00097
00098 FILE *cfile;
00099 FILE *hfile;
00100 char *syntax[513];
00101 int base;
00102 int size;
00103 int nbits;
00104 int digit_contig;
00105
00106
00107 main() {
00108 char c;
00109 char d;
00110 int sign;
00111 int i;
00112 char buf[80];
00113 int pos;
00114 static char digit[] = "0123456789";
00115
00116
00117 if ((cfile = fopen("syntax.c", "w")) == NULL) {
00118 perror("syntax.c");
00119 exit(2);
00120 }
00121 if ((hfile = fopen("syntax.h", "w")) == NULL) {
00122 perror("syntax.h");
00123 exit(2);
00124 }
00125 fputs(writer, hfile);
00126 fputs(writer, cfile);
00127
00128
00129 c = -1;
00130 if (c < 0)
00131 sign = 1;
00132 else
00133 sign = 0;
00134 for (nbits = 1 ; ; nbits++) {
00135 d = (1 << nbits) - 1;
00136 if (d == c)
00137 break;
00138 }
00139 printf("%s %d bit chars\n", sign? "signed" : "unsigned", nbits);
00140 if (nbits > 9) {
00141 fputs("Characters can't have more than 9 bits\n", stderr);
00142 exit(2);
00143 }
00144 size = (1 << nbits) + 1;
00145 base = 1;
00146 if (sign)
00147 base += 1 << (nbits - 1);
00148 digit_contig = 1;
00149 for (i = 0 ; i < 10 ; i++) {
00150 if (digit[i] != '0' + i)
00151 digit_contig = 0;
00152 }
00153
00154 fputs("#include <sys/cdefs.h>\n", hfile);
00155
00156
00157 fputs("/* Syntax classes */\n", hfile);
00158 for (i = 0 ; synclass[i].name ; i++) {
00159 sprintf(buf, "#define %s %d", synclass[i].name, i);
00160 fputs(buf, hfile);
00161 for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07)
00162 putc('\t', hfile);
00163 fprintf(hfile, "/* %s */\n", synclass[i].comment);
00164 }
00165 putc('\n', hfile);
00166 fputs("/* Syntax classes for is_ functions */\n", hfile);
00167 for (i = 0 ; is_entry[i].name ; i++) {
00168 sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i);
00169 fputs(buf, hfile);
00170 for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07)
00171 putc('\t', hfile);
00172 fprintf(hfile, "/* %s */\n", is_entry[i].comment);
00173 }
00174 putc('\n', hfile);
00175 fprintf(hfile, "#define SYNBASE %d\n", base);
00176 fprintf(hfile, "#define PEOF %d\n\n", -base);
00177 putc('\n', hfile);
00178 fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile);
00179 fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile);
00180 fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile);
00181 putc('\n', hfile);
00182 output_type_macros();
00183 putc('\n', hfile);
00184
00185
00186 fputs("#include \"shell.h\"\n", cfile);
00187 fputs("#include \"syntax.h\"\n\n", cfile);
00188 init();
00189 fputs("/* syntax table used when not in quotes */\n", cfile);
00190 add("\n", "CNL");
00191 add("\\", "CBACK");
00192 add("'", "CSQUOTE");
00193 add("\"", "CDQUOTE");
00194 add("`", "CBQUOTE");
00195 add("$", "CVAR");
00196 add("}", "CENDVAR");
00197 add("<>();&| \t", "CSPCL");
00198 print("basesyntax");
00199 init();
00200 fputs("\n/* syntax table used when in double quotes */\n", cfile);
00201 add("\n", "CNL");
00202 add("\\", "CBACK");
00203 add("\"", "CENDQUOTE");
00204 add("`", "CBQUOTE");
00205 add("$", "CVAR");
00206 add("}", "CENDVAR");
00207 add("!*?[=", "CCTL");
00208 print("dqsyntax");
00209 init();
00210 fputs("\n/* syntax table used when in single quotes */\n", cfile);
00211 add("\n", "CNL");
00212 add("'", "CENDQUOTE");
00213 add("!*?[=", "CCTL");
00214 print("sqsyntax");
00215 filltable("0");
00216 fputs("\n/* character classification table */\n", cfile);
00217 add("0123456789", "ISDIGIT");
00218 add("abcdefghijklmnopqrstucvwxyz", "ISLOWER");
00219 add("ABCDEFGHIJKLMNOPQRSTUCVWXYZ", "ISUPPER");
00220 add("_", "ISUNDER");
00221 add("#?$!-*@", "ISSPECL");
00222 print("is_type");
00223 if (! digit_contig)
00224 digit_convert();
00225 exit(0);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234 filltable(dftval)
00235 char *dftval;
00236 {
00237 int i;
00238
00239 for (i = 0 ; i < size ; i++)
00240 syntax[i] = dftval;
00241 }
00242
00243
00244
00245
00246
00247
00248 init() {
00249 filltable("CWORD");
00250 syntax[0] = "CEOF";
00251 syntax[base + CTLESC] = "CCTL";
00252 syntax[base + CTLVAR] = "CCTL";
00253 syntax[base + CTLENDVAR] = "CCTL";
00254 syntax[base + CTLBACKQ] = "CCTL";
00255 syntax[base + CTLBACKQ + CTLQUOTE] = "CCTL";
00256 }
00257
00258
00259
00260
00261
00262
00263 add(p, type)
00264 char *p, *type;
00265 {
00266 while (*p)
00267 syntax[*p++ + base] = type;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276 print(name)
00277 char *name;
00278 {
00279 int i;
00280 int col;
00281
00282 fprintf(hfile, "extern const char %s[];\n", name);
00283 fprintf(cfile, "const char %s[%d] = {\n", name, size);
00284 col = 0;
00285 for (i = 0 ; i < size ; i++) {
00286 if (i == 0) {
00287 fputs(" ", cfile);
00288 } else if ((i & 03) == 0) {
00289 fputs(",\n ", cfile);
00290 col = 0;
00291 } else {
00292 putc(',', cfile);
00293 while (++col < 9 * (i & 03))
00294 putc(' ', cfile);
00295 }
00296 fputs(syntax[i], cfile);
00297 col += strlen(syntax[i]);
00298 }
00299 fputs("\n};\n", cfile);
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309 char *macro[] = {
00310 "#define is_digit(c)\t((is_type+SYNBASE)[c] & ISDIGIT)",
00311 "#define is_alpha(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER))",
00312 "#define is_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER))",
00313 "#define is_in_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER|ISDIGIT))",
00314 "#define is_special(c)\t((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))",
00315 NULL
00316 };
00317
00318 output_type_macros() {
00319 char **pp;
00320
00321 if (digit_contig)
00322 macro[0] = "#define is_digit(c)\t((unsigned)((c) - '0') <= 9)";
00323 for (pp = macro ; *pp ; pp++)
00324 fprintf(hfile, "%s\n", *pp);
00325 if (digit_contig)
00326 fputs("#define digit_val(c)\t((c) - '0')\n", hfile);
00327 else
00328 fputs("#define digit_val(c)\t(digit_value[c])\n", hfile);
00329 }
00330
00331
00332
00333
00334
00335
00336
00337 digit_convert() {
00338 int maxdigit;
00339 static char digit[] = "0123456789";
00340 char *p;
00341 int i;
00342
00343 maxdigit = 0;
00344 for (p = digit ; *p ; p++)
00345 if (*p > maxdigit)
00346 maxdigit = *p;
00347 fputs("extern const char digit_value[];\n", hfile);
00348 fputs("\n\nconst char digit_value[] = {\n", cfile);
00349 for (i = 0 ; i <= maxdigit ; i++) {
00350 for (p = digit ; *p && *p != i ; p++);
00351 if (*p == '\0')
00352 p = digit;
00353 fprintf(cfile, " %d,\n", p - digit);
00354 }
00355 fputs("};\n", cfile);
00356 }