2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // KWGEN.C - Keyword & Mnemonic Definition and State Machine Creation Tool
4 // Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source utilised with the kind permission of Landon Dyer
10 * keyword transition-table generation utility
15 * SYNOPSIS: kw basename <file1 >file2
17 * `-d' turns on debugging messages
19 * Accepts a list of keywords and corresponding values. Lines
20 * beginning with '#' are comments. Values may be empty (resulting
21 * in a default value of the previous item's value plus 1, or zero
22 * if there is no previous item), decimal numbers, or characters
23 * enclosed between single quotes.
30 * The `basename' is a string prepended to the beginning of each of
31 * the output array names, and should be one or two characters.
43 #define TABSIZE 1024 /* state table size */
44 #define NSTRINGS 500 /* maximum number of keywords */
45 #define STRPOOLSIZ (NSTRINGS * 10) /* size of string pool */
51 #define EOS '\0' /* null */
52 #define UNUSED -1 /* slot in ktab[] is unused */
53 #define MARKED -2 /* slot in ktab[] is used, not assigned yet */
57 * Table-building tables
59 int kmax = 0; /* largest index into ktab */
60 int ktab[TABSIZE]; /* next state number (or -1) */
61 int kcheck[TABSIZE]; /* check state number (or -1) */
62 int kaccept[TABSIZE]; /* accept (or -1) */
63 int kbase[TABSIZE]; /* ktab[] index for a state `i' */
64 int nstates; /* number of states in kbase[] */
69 int tab[128]; /* tmp table for building ktab[] */
70 int accept[128]; /* tmp table for building accept[] */
73 char *nstr; /* -> name string */
74 int nval; /* = name's value */
77 int nnames; /* number of keywords */
78 char strpool[STRPOOLSIZ]; /* pool for keyword text */
79 char *basename; /* -> string to prepend to array names */
80 char uppername[100]; /* all-uppercase version of basename */
81 int debug = 0; /* 1, enable debugging messages */
85 int nmatch(int, char *, char *);
87 void print_tables(void);
88 void dumptab(char *, char *, int *, int);
92 int main(int argc, char ** argv)
94 register int i, /*j,*/ k, w;
103 panic("bad commandline");
108 for(s=basename, s1=uppername; *s; ++s, ++s1)
109 *s1 = (char)toupper(*s);
116 for(i=0; i<TABSIZE; ++i)
131 // while (gets(s) != NULL)
132 while (fgets(s, STRPOOLSIZ, stdin) != NULL)
134 if (*s == '#' || !*s) /* ignore comment and empty lines */
137 namtab[nnames].nstr = s;
139 while (*s && !isspace(*s))
148 if (*s && isspace(*s))
153 while (*s1 && isspace(*s1))
158 empty: /* use previous entry + 1 */
159 if (!nnames) /* complain if no previous entry */
160 namtab[nnames].nval = 0;
162 namtab[nnames].nval = namtab[nnames-1].nval + 1;
164 else if (isdigit(*s1))
165 namtab[nnames].nval = atoi(s1);
166 else if (*s1 == '\'')
167 namtab[nnames].nval = *++s1;
169 { /* same as previous entry */
170 if (!nnames) /* zero for first entry */
171 namtab[nnames].nval = 0;
173 namtab[nnames].nval = namtab[nnames-1].nval;
177 fprintf(stderr, "bad expression at '%s'\n", namtab[nnames].nstr);
183 if (nnames >= NSTRINGS)
184 panic("name table overflow");
186 if (s >= &strpool[STRPOOLSIZ-100])
187 panic("string table overflow");
190 qsort(namtab, nnames, sizeof(struct name_entry), comp_entry);
193 * compute table start indices
197 for(k=1; found1; ++k)
201 for(w=0; w<=nnames; ++w)
203 if (w == 0 || w == nnames
204 || !nmatch(k-1, namtab[w].nstr, namtab[w-1].nstr))
206 if (w != 0 && valid != 0)
216 if (ktab[kbase[state] + *(namtab[w-1].nstr + i)] < 0)
217 panic("table build error");
219 state = ktab[kbase[state] + *(namtab[w-1].nstr + i)];
222 ktab[kbase[state] + *(namtab[w-1].nstr + k-2)] = nstates;
238 if (w >= nnames || (int)strlen(namtab[w].nstr) < k)
243 tab[*(namtab[w].nstr + k-1)] = MARKED;
245 if (*(namtab[w].nstr + k) == '\0')
247 accept[*(namtab[w].nstr + k-1)] = namtab[w].nval;
262 * find position for set of characters;
270 for(base=0; base<TABSIZE-128; ++base)
273 if (ktab[base+i] != UNUSED && tab[i] == MARKED)
280 if (base >= TABSIZE-128)
281 panic("Cannot build table (won't fit in tables)\n");
285 if (tab[i] == MARKED)
287 ktab[base + i] = MARKED;
288 kaccept[base + i] = accept[i];
289 kcheck[base + i] = nstates;
293 kbase[nstates] = base;
300 void print_tables(void)
304 printf("\n#ifdef DECL_%s\n", uppername);
305 printf("/*\n * keyword state-machine tables\n *\n */\n");
306 dumptab("base", basename, kbase, nstates);
307 dumptab("tab", basename, ktab, kmax + 128);
308 dumptab("check", basename, kcheck, kmax + 128);
309 dumptab("accept", basename, kaccept, kmax + 128);
314 void dumptab(char * tabname, char * tabprefix, int * table, int tabsize)
318 printf("\nint %s%s[%d] = {\n", tabprefix, tabname, tabsize);
320 for(i=j=0; i<tabsize; ++i)
322 printf(" %d", table[i]);
341 int comp_entry(struct name_entry * ent1, struct name_entry * ent2)
343 return strcmp(ent1->nstr, ent2->nstr);
347 int nmatch(int len, char * s1, char * s2)
362 void traverse(int state)
364 register int base, i;//, j;
369 printf("#ifdef DEF_%s\n", uppername);
370 printf("/*\n * Keyword definitions\n */\n");
379 if (kcheck[base + i] == state)
390 if (kaccept[base + i] >= 0 && !isupper(*s))
392 printf("#define\t%s_", uppername);
394 for(s=nam; (c=*s); ++s)
398 else if ((c >= 'a') && (c <= 'z'))
404 printf("\t%d\n", kaccept[base + i]);
407 if (ktab[base + i] >= 0)
408 traverse(ktab[base + i]);
421 fprintf(stderr, "Panic: %s\n", s);