#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define nl '\n'
// TO DO!!! Option to generate tables.h (C include file) instead of the imp include file
// for bootstrapping - currently the imp file is converted to C using a nasty ecce macro.
// And by nasty, I mean it was just a script of an editor session that is replayed. It
// could be made much tidier...)
// All arrays get bounds checking just like in Imp.
// Disable the checks if you really must, by adding -DNO_RANGE_CHECK on the command line
#ifdef NO_RANGE_CHECK
//Important that n is only ever evaluated once, as side-effects such as ++ would break it
#define RANGECHECK(n) (n)
#else
int RANGECHECK(int n, int low,int high, char *name, int line) {
if ((n < low) || (n > high)) {
fprintf(stderr, "* Array bounds exceeded at line %d: %s(%d)\n", line, name, n);
exit(0);
}
return n;
}
#endif
static FILE **instream = NULL, **outstream = NULL;
static FILE *grammarstream = NULL, *glist = NULL, *errorstream = NULL, *dlist = NULL, *tablestream = NULL;
static inline void Exit(int i, int L) {
if (i == 0) exit(0);
fprintf(stderr, "Error exit %d at line %d\n", i, L);
exit(i);
}
#define exit(n) Exit(n,__LINE__)
// Imp library!
static inline void readsymbol(int *ch) {
*ch = fgetc(*instream);
if (feof(*instream)) {
fprintf(stderr, "* Unexpected End of file\n");
exit(1);
}
}
static inline int nextsymbol(void) {
int ch = fgetc(*instream);
if (feof(*instream)) {
fprintf(stderr, "* Unexpected End of file\n");
exit(1);
}
ungetc(ch, *instream);
return ch;
}
static inline void skipsymbol(void) {
(void)fgetc(*instream);
if (feof(*instream)) {
fprintf(stderr, "* Unexpected End of file\n");
exit(1);
}
}
static inline void space(void) {
fprintf(*outstream, " ");
}
static inline void spaces(int n) {
while (--n >= 0) space();
}
static inline void newline(void) {
fprintf(*outstream, "\n");
}
static inline void newlines(int n) {
while (--n >= 0) newline();
}
static inline void printsymbol(int ch) {
fputc(ch, *outstream);
}
static inline void printstring(char *s) {
fprintf(*outstream, "%s", s);
}
//============================================================================
int main (int argc, char **argv) {
// takeon: convert imp grammar 31/1/77
//const int grammarstream = 1; // in streams
//const int errorstream = 0, tablestream = 1, glist = 2, dlist = 3; // out streams
const int firstphrase = 200;
const int ident = 90;
static int charmax = 0, nmax = -1, inits = 0;
static int newname = 0, outstring = -1;
int sym;
//int count;
int gmin;
int gmax;
int kmax;
// Although it is not needed by the Imp2C translation,
// I've moved all the array declarations to here and
// made them all standard auto variables off the stack.
// I've added a procedure to explicitly initialise
// them all to 0's which makes them compatible with
// externals and statics.
unsigned char Char_[1400];
#define Char(x) Char_[RANGECHECK(x,1,1400,"main:Char",__LINE__)-1]
unsigned char tran_[256];
#define tran(x) tran_[RANGECHECK(x,0,255,"tran",__LINE__)]
int index_[256];
#define index(x) index_[RANGECHECK(x,0,255,"index",__LINE__)]
int item_[802];
#define item(x) item_[RANGECHECK(x,-1,800,"item",__LINE__)+1]
int next_[802];
#define next(x) next_[RANGECHECK(x,-1,800,"next",__LINE__)+1]
int atomic_[179 - 130 + 1];
#define atomic(x) atomic_[RANGECHECK(x,130,179,"atomic",__LINE__)-130]
int phrase_[255 - 200 + 1];
#define phrase(x) phrase_[RANGECHECK(x,200,255,"phrase",__LINE__)-200]
int initial_[256];
#define initial(x) initial_[RANGECHECK(x,0,255,"initial",__LINE__)]
int initnext_[256];
#define initnext(x) initnext_[RANGECHECK(x,0,255,"initnext",__LINE__)]
int keydict_[1023 - 32 + 1];
#define keydict(x) keydict_[RANGECHECK(x,32,1023,"keydict",__LINE__)-32]
int Char_inner[1001], cont[1001], alt[1001]; // I renamed the nested "char" array to Char_inner
#define Char_inner(x) Char_inner[RANGECHECK(x,0,1000,"readatoms:Char",__LINE__)]
#define cont(x) cont[RANGECHECK(x,0,1000,"cont",__LINE__)]
#define alt(x) alt[RANGECHECK(x,0,1000,"alt",__LINE__)]
int converted[350 + 200 + 1];
#define converted(x) converted[RANGECHECK(x,-200,350,"converted",__LINE__)+200]
int head[200];
#define head(x) head[RANGECHECK(x,-200,-1,"head",__LINE__)+200]
int tail[200];
#define tail(x) tail[RANGECHECK(x,-200,-1,"tail",__LINE__)+200]
int token[350];
#define token(x) token[RANGECHECK(x,1,350,"token",__LINE__)-1]
int link[350];
#define link(x) link[RANGECHECK(x,1,350,"link",__LINE__)-1]
int map[801];
#define map(x) map[RANGECHECK(x,0,800,"map",__LINE__)]
int stack[150];
#define stack(x) stack[RANGECHECK(x,1,150,"stack",__LINE__)-1]
auto void hwrite (int n, int m) {
if (n & 0x8000) n |= 0xFFFF0000;
fprintf(*outstream, "%*d", m, n); // not quite the same spacing as the imp version
}
auto void readsym (void) {
for (;;) {
do { readsymbol (&sym); } while (sym == ' ');
if ((sym != '&') || (nextsymbol() != nl)) return;
skipsymbol ();
}
}
void read(int *n_) {
#define n *n_
n = 0;
readsym();
if (!isdigit(sym)) {
printstring("Not a number: "); printsymbol(sym); newline ();
exit(1);
}
for (;;) {
n = n*10 + (sym-'0');
if (!isdigit(nextsymbol())) break;
readsymbol(&sym);
}
#undef n
}
auto void printchars (int p) {
int flag;
flag = outstring;
if (p) {
while ((Char (p) && flag)) {
flag -= 1;
printsymbol (Char (p++) & 127);
}
}
}
auto void printname (int n) {
printchars (index(n & 255));
while (n & 0x300) {
printsymbol ('<');
n -= 256;
}
if (outstring < 0) {
if ((n & 0x800) || tran (n & 255)) printsymbol ('"');
n >>= 16;
if (n) { printsymbol ('['); hwrite (n, 0); printsymbol (']'); }
}
}
auto void readname (int *n_) {
#define n *n_
int i, j, k, m;
i = charmax;
do {
Char (++i) = sym;
readsymbol (&sym);
} while ((('A' <= sym) && (sym <= 'Z')) || (('0' <= sym) && (sym <= '9')));
Char (++i) = 0;
if (sym == ' ') readsym ();
m = nmax;
while (m >= 0) {
j = index(m);
k = charmax + 1;
while (j && ((Char (j) & 127) == Char (k))) {
if (!Char (k)) goto ok;
j += 1; k += 1;
}
m -= 1;
}
ok:
if (newname) {
if (m >= 0) {
printstring ("DUPLICATE: "); printchars (charmax + 1); newline ();
}
index(n) = charmax + 1;
charmax = i;
if (sym == '"') {
tran (n) = 1;
readsym ();
}
if (nmax < n) nmax = n;
} else {
if (m < 0) {
printstring ("UNKNOWN: "); printchars (charmax + 1); newline ();
m = 0;
}
n = m;
}
#undef n
}
auto void readgrammar (void) {
int i, j, k, l, p, min, max, exp, end;
auto int cell (int h, int t) {
// creates a list cell, if necessary, with head h and tail t
int i;
i = t;
if (i > 0) i = 0;
while (i-- != min) {
if (((head (i) == h) && (tail (i) == t))) return (i);
}
head (--min) = h; tail (min) = t;
converted (min) = 0;
return (min);
}
auto int union_ (int x, int y) {
int hx, hy;
if (x == y) return (x);
if (x < y) { hx = x; x = y; y = hx; }
if (x >= 0) {
if (y >= 0) return (cell (x, y));
hy = head (y);
if (x > hy) return (cell (x, y));
if (x != hy) return (cell (hy, union_ (x, tail (y))));
return (y);
}
hx = head (x);
hy = head (y);
if (hx > hy) return (cell (hx, union_ (tail (x), y)));
if (hx != hy) return (cell (hy, union_ (x, tail (y))));
return (cell (hx, union_ (tail (x), tail (y))));
}
auto void concatenate (int x, int y) {
int i = x, j;
do { j = link (i); link (i) = y; i = j; } while (i != x);
}
auto void acceptexp (int *exp_, int *expend_) {
#define exp *exp_
#define expend *expend_
// inputs a regular expression
// and creates intermediate graph representation
int i, string, stringend, unit, unitend, n;
exp = 0;
s:
string = 0;
u:
if (sym == '(') {
readsym ();
acceptexp (&unit, &unitend);
if ((!unit) || (sym != ')')) goto err;
readsym ();
} else {
if ((('A' <= sym) && (sym <= 'Z')) || (sym == '%')) {
readname (&i);
if (i) Char (index(i)) |= 128;
i |= (tran (i) << 11);
while (sym == '<') {
i += 256;
readsym ();
}
if (sym == '"') { // force transparent
readsym ();
i |= 1 << 11;
}
if (sym == '[') {
read (&n);
if (n >> 4) goto err;
i += (n << 16);
readsym ();
if (sym != ']') goto err;
readsym ();
}
} else {
if (sym != '+') goto err;
i = 0;
while (sym == '+') {
i += 256;
readsym ();
}
}
token (++max) = i;
link (max) = max;
unit = max;
unitend = max;
}
if ((sym == '*') || (sym == '!')) {
token (++max) = -1;
link (max) = max;
head (--min) = max;
tail (min) = unit;
concatenate (unitend, min);
unitend = max;
if (sym == '*') unit = min;
readsym ();
}
if (sym == '?') {
token (++max) = -1;
link (max) = link (unitend);
link (unitend) = max;
head (--min) = max;
tail (min) = unit;
unit = min;
readsym ();
}
if (!string) string = unit; else concatenate (stringend, unit);
stringend = unitend;
if ((sym != ',') && (sym != ')') && (sym != nl)) goto u;
if (!exp) {
exp = string;
expend = stringend;
} else {
exp = union_ (string, exp);
i = link (expend);
link (expend) = link (stringend);
link (stringend) = i;
}
if (sym != ',') return;
do readsym (); while (sym == nl);
goto s;
err:
exp = 0;
#undef exp
#undef expend
}
auto void convert (void) {
int i, j, k, m, n, gmax1, loopstop;
auto void tcount (int x) {
int t;
for (;;) {
if (!x) return;
if (x < 0) { tcount (tail (x)); x = head (x); }
t = token (x);
if (t >= 0) break;
if (t == loopstop) return;
token (x) = loopstop;
x = link (x);
}
k -= 1;
}
auto void addcomponents (int x) {
static int i, k, t, u;
while (x) {
if (x < 0) { addcomponents (tail (x)); x = head (x); }
if ((t = token (x)) >= 0) break;
if (t == loopstop) return;
token (x) = loopstop; x = link (x);
}
if (x) x = link (x); else t = 0;
u = t & (0xF0000 + (15 << 11) + 255);
i = gmax1;
while (++i <= gmax) {
k = item (i);
if (k == t) {
next (i) = union_ (next (i), x);
return;
}
if ((k & (0xF0000 + (15 << 11) + 255)) == u) {
if (p) printname (p);
printstring ("-CLASH: ");
printname (k); space (); printname (t);
newline ();
}
k = k & 255;
if ((u == ident) || (((u & 255) < k) && (k >= 180)) || !k) {
int initial_i = i;
for (i = gmax; i >= initial_i; i -= 1) { // %cycle i = gmax,-1,i
item (i + 1) = item (i);
next (i + 1) = next (i);
}
i = initial_i; // BUG FIX! I guess regular for loops leave i greater than the loop ending test and need something similar
break;
}
}
gmax += 1;
item (i) = t;
next (i) = x;
} // addcomponents
loopstop = -1; gmin = gmax + 1;
for (i = min; i <= max; i += 1) {
converted (i) = 0;
}
n = next (0);
l1:
gmax1 = gmax;
loopstop -= 1;
addcomponents (n);
item (gmax) += 1024;
if (!gmax1) {
inits = gmax;
while (inits && (item ((inits) & 255) >= firstphrase)) inits -= 1;
}
converted (n) = gmax1 + 1;
m = 0;
for (i = gmin; i <= gmax; i += 1) {
j = next (i);
if (j) {
k = converted (j);
if (!k) {
loopstop -= 1;
tcount (j);
converted (j) = k;
}
if (k < m) {
m = k; n = j;
}
}
}
if (m) goto l1;
for (i = gmin; i <= gmax; i += 1) {
k = next (i);
if (k) k = converted (k);
next (i) = k;
}
} // convert
auto void minimize (void) {
int i, j, k, m, n;
// declaration of stack belongs here
auto int ultmap (int i) {
int j;
do { j = i; i = map (i); } while ((i != j) && i);
return (j);
}
auto int equivalent (int nn, int mm) {
int i, j, k, pos1, pos2;
pos1 = pos2 = 0;
l1:
do {
k = item (mm);
if (item (nn) != k) goto l9;
i = next (nn);
j = next (mm);
if ((!i && j) || (i && !j)) goto l9;
stack (++pos1) = nn;
map (nn++) = mm++;
} while (!(k & 1024)); // last alternative
l2:
if (pos2++ == pos1) return (1);
i = stack (pos2);
nn = ultmap (next (i));
mm = ultmap (next (map (i)));
if (nn == mm) goto l2;
if (nn < mm) { i = nn; nn = mm; mm = i; } // swap
if (nn > n) goto l1;
l9:
while (pos1) {
i = stack (pos1--);
map (i) = i;;
}
return (0);
}
for (i = 0; i <= gmax; i += 1) { map (i) = i; }
if (gmin > gmax) return;
for (n = gmin; n <= gmax; n += 1) {
if (map (n) == n) {
if ((n == gmin) || (item (n - 1) & 1024)) {
m = 1;
while (m != n) {
if ((map (m) == m) && equivalent (n, m)) break;
m += 1;
}
}
} else {
map (n) = ultmap (n);
}
}
j = gmin - 1;
for (i = gmin; i <= gmax; i += 1) {
k = map (i);
if (k == i) {
map (i) = ++j;
item (j) = item (i); next (j) = next (i);
} else {
map (i) = map (k);
}
}
gmax = j;
for (i = gmin; i <= gmax; i += 1) {
k = next (i);
if (k) next (i) = map (k);
}
} // minimize
gmax = 0;
l1:
do { readsym (); } while (sym == nl);
if (sym == '/') goto l10;
if ((sym == 'S') && (nextsymbol() == 'S')) {
skipsymbol (); p = 0;
} else {
readname (&p); if (!p) exit (0);
}
min = 0; max = 0;
do { readsym (); } while (!(((sym != nl) && ((sym != '-') && (sym != '>')))));
acceptexp (&exp, &end);
if ((!exp) || (sym != nl)) goto l9;
concatenate (end, 0);
item (0) = 2047; next (0) = exp;
convert ();
i = gmin;
minimize ();
i = map (gmin);
if (!p) { // ss
// !! j = item(i);! k = next(i)
// !! k = k-inits;! %stop %if k <= 0
// !! %if i <= inits %start
// !! ->l99 %if l >= first phrase
// !! %signal 0,25 %if initial(l) # 0
// !! %else
// !! %finish
// !! gmax = gmax-inits
for (i = 1; i <= inits; i += 1) {
l = item (i) & 255;
if (l >= 200) continue;
if ((130 <= l) && (l < 180)) l = atomic (l);
if (initial (l)) exit(1);
initial (l) = i; initnext (l) = item (i);
}
outstream = &glist;
newline ();
} else {
phrase (p) = i;
outstream = &glist;
newline ();
printname (p); printstring (" =>"); hwrite (i, 1);
}
k = 1024;
for (i = gmin; i <= gmax; i += 1) {
if (k & 1024) {
newline ();
hwrite (i, 3);
j = 0;
}
if (++j > 5) { newline (); spaces (4); j = 1; }
spaces (3);
k = item (i);
if (k & 255) {
printname (k);
} else {
printstring ("*E");
while (k & 0x300) { printsymbol ('+'); k -= 256; }
}
hwrite (next (i), 1);
}
outstream = &errorstream;
goto l1;
l9:
printstring ("WRONG FORMAT AT: ");
while (sym != nl) { printsymbol (sym); readsym (); }
newline ();
goto l1;
// deal with initial phrase
// assumes exactly one (imp)
l10:
if (inits == 1) { // not imp!!!
outstream = &errorstream;
printstring ("NOT AN IMP GRAMMAR");
newline ();
return;
}
if (!(p = phrase (item (inits + 1) & 255))) exit(1);
for (;;) {
j = item (p); k = j & 255;
if (k >= 160) exit(1);
if (k >= 120) k = atomic (k);
if (initial (k)) exit(1);
initial (k) = p | 0x8000; initnext (k) = j;
if (j & 1024) break;
p += 1;
}
initial (0) = initial (182); // %decl
outstream = &glist;
newlines (2);
for (i = 0; i <= 119; i += 1) {
k = initial (i);
if (k) {
hwrite (i, 2); printstring (": "); printname (initnext (i)); hwrite (k & 255, 3);
if (k < 0) printsymbol ('`');
newline ();
}
}
outstream = &errorstream;
} // read grammar
auto void readatoms (void) {
int i, j;
//int k;
int dict, dmax, code, class, sub;
auto void readcode (void) {
int n;
code = nextsymbol(); sub = 0;
if ((code != ',') && (code != nl)) {
skipsymbol ();
if (code == '$') {
read (&code); return;
}
if (code != '(') return;
read (&sub);
while (nextsymbol() == '+') {
skipsymbol (); read (&n); sub += n;
}
skipsymbol ();
}
code = class + 128;
}
auto void insertin (int *x_) {
#define x *x_
for (;;) {
while (Char_inner (x) < code) {
if (!cont (x)) cont (x) = sub;
x_ = &alt (x) /* Pointer assignment */ ;
}
if (Char_inner (x) != code) {
dmax += 1; Char_inner (dmax) = code;
cont (dmax) = 0; alt (dmax) = x; x = dmax;
}
if (code & 128) break;
readcode ();
x_ = &cont (x) /* Pointer assignment */ ;
}
if (!sub && alt (x)) sub = cont (alt (x));
cont (x) = sub;
#undef x
}
auto void store (int x) {
int m,n,v, mm, q;
for (;;) {
n = ++kmax;
m = alt (x); mm = m;
if (m) { store (m); m = 0x8000; }
v = Char_inner (x); x = cont (x);
if (v & 128) break;
if (!m) { // no alternatives
if (!alt (x) && !(Char_inner (x) & 128)) {
v += Char_inner (x) << 7; x = cont (x);
}
} else {
q = kmax - n + 1;
if (q >> 7) {
outstream = &errorstream;
printstring ("Keydict overflow!"); newline ();
exit (0);
}
v = (q << 7) + (v | 0x8000);
}
keydict (n) = v;
}
if (!mm) {
keydict (++kmax) = 0;
} else {
kmax -= 1;
}
keydict (n) = m + 0x4000 + ((keydict (n + 1) & 127) << 7) + (v & 127);
keydict (n + 1) = x;
}
auto void display (int i, int s) {
int j;
auto void show (int sym) {
if (sym == nl) sym = '$';
printsymbol (sym);
}
for (;;) {
j = keydict (i);
if (!(j & 0x4000)) {
show (j & 127);
if (!(j & 0x8000)) {
j >>= 7;
if (j) { show (j); s += 1; }
space ();
i += 1; s += 2;
} else {
space ();
display (((j >> 7) & 127) + i, s + 2);
if (!(j >> 15)) break;
spaces (s);
i += 1;
}
} else {
printsymbol (':'); printname (j & 127);
if ((j >> 7) & 127) {
space (); printname ((j >> 7) & 127);
}
j = keydict (i + 1) & 0x3FFF;
if (j) hwrite (j, 4);
newline ();
break;
}
}
}
dict = 0; dmax = 0; Char_inner (0) = 999;
l1:
for (;;) {
sym = nextsymbol();
if ((sym != '[') && (sym != nl)) break;
do { readsymbol (&sym); } while (sym != nl);
}
if (sym == '/') goto l10;
read (&class);
newname = 1;
readsym (); readname (&class);
newname = 0;
if (class < 130) {
if (sym != '[') {
if (sym == '$') read (&sym);
for (;;) {
code = sym; insertin (&dict);
readsymbol (&sym);
if (sym != ',') break;
do { readsymbol (&sym); } while ((sym == ' ') || (sym == nl));
}
}
} else {
if ((class <= firstphrase) && (sym == '=')) {
readsym ();
readname (&atomic (class));
}
}
while (sym != nl) readsymbol (&sym);
goto l1;
l10:
outstream = &dlist; newlines (2);
kmax = 126; keydict (32) = 0;
for (i = 33; i <= 126; i += 1) {
printsymbol (i); space ();
if (Char_inner (dict) == i) {
j = (kmax + 1) << 2;
store (cont (dict));
dict = alt (dict);
display (j >> 2, 2);
} else {
printsymbol ('?'); newline ();
j = 32 << 2;
}
// let:0 dig:1 term:2 other:3
if (!(('A' <= i) && (i <= 'Z'))) j += 3;
if (('0' <= i) && (i <= '9')) j -= 2;
if (i == ';') j -= 1;
keydict (i) = j;
}
// WTF! Following assignment blocks the use of ~ eg ~=
// So, assignment commented out.
// keydict('~') = keydict('^')
newlines (2);
outstream = &errorstream;
}
auto int packed (int j, int k) {
j = ((j & 1024) << 5) + ((j & 0x0300) << 4) + (((j >> 3) & 0x0100) << 6) + ((j >> 8) & 0xF00);
return j + (k & 255);
}
int i, j, k;
auto void FULLY_INITIALIZE(void) {
int i;
// This was a little bit of paranoia during one debugging session.
// I thiink I'll leave it in.
for (i = 1; i <= 1400; i++) Char(i) = 0;
for (i = 0; i <= 255; i++) tran(i) = 0;
for (i = 0; i <= 255; i++) index(i) = 0;
for (i = -1; i <= 800; i++) item(i) = 0;
for (i = -1; i <= 800; i++) next(i) = 0;
for (i = 130; i <= 179; i++) atomic(i) = 0;
for (i = 200; i <= 255; i++) phrase(i) = 0;
for (i = 0; i <= 255; i++) initial(i) = 0;
for (i = 0; i <= 255; i++) initnext(i) = 0;
for (i = 32; i <= 1023; i++) keydict(i) = 0;
for (i = -200; i <= 350; i++) converted(i) = 0;
for (i = -200; i <= -1; i++) head(i) = 0;
for (i = -200; i <= -1; i++) tail(i) = 0;
for (i = 1; i <= 350; i++) token(i) = 0;
for (i = 1; i <= 350; i++) link(i) = 0;
for (i = 0; i <= 800; i++) map(i) = 0;
for (i = 1; i <= 150; i++) stack(i) = 0;
for (i = 0; i <= 1000; i++) Char_inner(i) = 0;
for (i = 0; i <= 1000; i++) cont(i) = 0;
for (i = 0; i <= 1000; i++) alt(i) = 0;
}
FULLY_INITIALIZE();
charmax = 0;
// Using JDM's names for files ...
glist = fopen("i77.par.debug", "w"); // grammar list
errorstream = stderr;
dlist = fopen("i77.lex.debug", "w"); // grammar dict
tablestream = fopen("i77.tables-new.imp", "w");
grammarstream = fopen("i77.grammar", "r");
#ifdef NEVER // no longer needed
for (i = -1; i <= 800; i += 1) { item (i) = 0; next (i) = 0; }
for (i = 0; i <= 255; i += 1) { index (i) = 0; initnext (i) = 0; initial (i) = 0; }
for (i = 130; i <= 179; i += 1) { atomic (i) = i; }
for (i = firstphrase; i <= 255; i += 1) { phrase (i) = 0; }
#endif
instream = &grammarstream;
outstream = &errorstream;
do { readsymbol (&i); } while (i != '/');
do { readsymbol (&i); } while (i != nl);
readatoms ();
do { readsymbol (&i); } while (i != nl);
readgrammar ();
// write required values
outstream = &tablestream;
printstring (" %endoflist"); newline ();
const int namesperline = 8;
printstring ("%conststring(8)%array text(0:255) = %c"); newline ();
printstring ("\"Z\",");
// we have just output the first name already
// so initialise k with good value
k = namesperline - 1; outstring = 8;
for (j = 1; j <= 255; j += 1) {
printsymbol ('"'); printname (j); printsymbol ('"');
if (j != 255) printsymbol (',');
if (--k <= 0) { k = namesperline; newline (); }
}
newline ();
outstring = -1;
printstring ("%constinteger gmax1="); hwrite (gmax, 0); newline ();
printstring ("%owninteger gmax="); hwrite (gmax, 0); newline ();
printstring ("%constinteger imp phrase ="); hwrite (inits + 1, 0); newlines (2);
printstring ("! FLAG<1> 0<1> SS<2> 0<3> T<1> LINK<8>"); newline ();
printstring ("%constshortintegerarray initial(0:119) = %c");
for (i = 0; i <= 119; i += 1) {
if (!(i & 7)) newline ();
hwrite (initial (i), 7);
if (i != 119) printsymbol (',');
}
newlines (2);
printstring ("%constbyteintegerarray atomic(130:179) = %c");
k = 0;
for (i = 130; i <= 179; i += 1) {
if (!(k++ & 7)) newline ();
hwrite (atomic (i), 3);
if (i != 179) printsymbol (',');
}
newlines (2);
printstring ("%ownshortintegerarray phrase(200:255) = %C");
for (i = 200; i <= 255; i += 1) {
if (!(i & 7)) newline ();
hwrite (phrase (i), 3);
if (i != 255) printsymbol (',');
}
newlines (2);
printstring ("! MORE<1> 0<1> ORDER<2> TYPE<4> CLASS<8>"); newline ();
printstring ("%ownshortintegerarray gram(0:max grammar) = %c");
for (i = 0; i <= gmax; i += 1) {
if (!(i & 7)) newline ();
k = 0;
if (i) k = packed (item (i) ^ 1024, item (i));
hwrite (k, 7); printsymbol (',');
}
newline ();
printstring ("0(max grammar-gmax1)"); newlines (2);
printstring ("%ownshortintegerarray glink(0:max grammar) = %c");
for (i = 0; i <= gmax; i += 1) {
if (!(i & 7)) newline ();
hwrite (next (i), 7); printsymbol (',');
}
newline ();
printstring ("0(max grammar-gmax1)"); newlines (2);
printstring ("%constshortinteger max kdict = "); hwrite (kmax, 0); newline ();
printstring ("%constshortintegerarray kdict(32:max kdict) = %c");
for (i = 32; i <= kmax; i += 1) {
if (!(i & 7)) newline ();
hwrite (keydict (i), 7);
if (i != kmax) printsymbol (',');
}
newline ();
printstring (" %list"); newline ();
printstring ("%endoffile"); newline ();
outstream = &errorstream;
printstring ("Grammar complete"); newline ();
exit(0);
return 1;
}