10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*4538Sdamico * Common Development and Distribution License (the "License"). 6*4538Sdamico * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*4538Sdamico * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 270Sstevel@tonic-gate /* All Rights Reserved */ 280Sstevel@tonic-gate 290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 31*4538Sdamico #include "ldefs.h" 320Sstevel@tonic-gate 330Sstevel@tonic-gate static void add(int **array, int n); 340Sstevel@tonic-gate static void follow(int v); 350Sstevel@tonic-gate static void first(int v); 360Sstevel@tonic-gate static void nextstate(int s, int c); 370Sstevel@tonic-gate static void packtrans(int st, CHR *tch, int *tst, int cnt, int tryit); 380Sstevel@tonic-gate static void acompute(int s); 390Sstevel@tonic-gate static void rprint(int *a, char *s, int n); 400Sstevel@tonic-gate static void shiftr(int *a, int n); 410Sstevel@tonic-gate static void upone(int *a, int n); 420Sstevel@tonic-gate static void bprint(char *a, char *s, int n); 430Sstevel@tonic-gate static int notin(int n); 440Sstevel@tonic-gate static int member(int d, CHR *t); 450Sstevel@tonic-gate 460Sstevel@tonic-gate #ifdef PP 470Sstevel@tonic-gate static void padd(int **array, int n); 480Sstevel@tonic-gate #endif 490Sstevel@tonic-gate 500Sstevel@tonic-gate void 510Sstevel@tonic-gate cfoll(int v) 520Sstevel@tonic-gate { 530Sstevel@tonic-gate int i, j, k; 540Sstevel@tonic-gate CHR *p; 550Sstevel@tonic-gate i = name[v]; 560Sstevel@tonic-gate if (!ISOPERATOR(i)) 570Sstevel@tonic-gate i = 1; 580Sstevel@tonic-gate switch (i) { 590Sstevel@tonic-gate case 1: case RSTR: case RCCL: case RNCCL: case RNULLS: 600Sstevel@tonic-gate for (j = 0; j < tptr; j++) 610Sstevel@tonic-gate tmpstat[j] = FALSE; 620Sstevel@tonic-gate count = 0; 630Sstevel@tonic-gate follow(v); 640Sstevel@tonic-gate #ifdef PP 650Sstevel@tonic-gate padd(foll, v); /* packing version */ 660Sstevel@tonic-gate #else 670Sstevel@tonic-gate add(foll, v); /* no packing version */ 680Sstevel@tonic-gate #endif 690Sstevel@tonic-gate if (i == RSTR) 700Sstevel@tonic-gate cfoll(left[v]); 710Sstevel@tonic-gate else if (i == RCCL || i == RNCCL) { 720Sstevel@tonic-gate for (j = 1; j < ncg; j++) 730Sstevel@tonic-gate symbol[j] = (i == RNCCL); 740Sstevel@tonic-gate p = (CHR *) left[v]; 750Sstevel@tonic-gate while (*p) 760Sstevel@tonic-gate symbol[*p++] = (i == RCCL); 770Sstevel@tonic-gate p = pcptr; 780Sstevel@tonic-gate for (j = 1; j < ncg; j++) 790Sstevel@tonic-gate if (symbol[j]) { 800Sstevel@tonic-gate for (k = 0; p + k < pcptr; k++) 81*4538Sdamico if (cindex[j] == 82*4538Sdamico *(p + k)) 83*4538Sdamico break; 840Sstevel@tonic-gate if (p + k >= pcptr) 850Sstevel@tonic-gate *pcptr++ = cindex[j]; 860Sstevel@tonic-gate } 870Sstevel@tonic-gate *pcptr++ = 0; 880Sstevel@tonic-gate if (pcptr > pchar + pchlen) 890Sstevel@tonic-gate error( 900Sstevel@tonic-gate "Too many packed character classes"); 910Sstevel@tonic-gate left[v] = (int)p; 920Sstevel@tonic-gate name[v] = RCCL; /* RNCCL eliminated */ 930Sstevel@tonic-gate #ifdef DEBUG 940Sstevel@tonic-gate if (debug && *p) { 950Sstevel@tonic-gate (void) printf("ccl %d: %d", v, *p++); 960Sstevel@tonic-gate while (*p) 970Sstevel@tonic-gate (void) printf(", %d", *p++); 980Sstevel@tonic-gate (void) putchar('\n'); 990Sstevel@tonic-gate } 1000Sstevel@tonic-gate #endif 1010Sstevel@tonic-gate } 1020Sstevel@tonic-gate break; 1030Sstevel@tonic-gate case CARAT: 1040Sstevel@tonic-gate cfoll(left[v]); 1050Sstevel@tonic-gate break; 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate /* XCU4: add RXSCON */ 1080Sstevel@tonic-gate case RXSCON: 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate case STAR: case PLUS: case QUEST: case RSCON: 1110Sstevel@tonic-gate cfoll(left[v]); 1120Sstevel@tonic-gate break; 1130Sstevel@tonic-gate case BAR: case RCAT: case DIV: case RNEWE: 1140Sstevel@tonic-gate cfoll(left[v]); 1150Sstevel@tonic-gate cfoll(right[v]); 1160Sstevel@tonic-gate break; 1170Sstevel@tonic-gate #ifdef DEBUG 1180Sstevel@tonic-gate case FINAL: 1190Sstevel@tonic-gate case S1FINAL: 1200Sstevel@tonic-gate case S2FINAL: 1210Sstevel@tonic-gate break; 1220Sstevel@tonic-gate default: 1230Sstevel@tonic-gate warning("bad switch cfoll %d", v); 1240Sstevel@tonic-gate #endif 1250Sstevel@tonic-gate } 1260Sstevel@tonic-gate } 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate #ifdef DEBUG 1290Sstevel@tonic-gate void 1300Sstevel@tonic-gate pfoll(void) 1310Sstevel@tonic-gate { 1320Sstevel@tonic-gate int i, k, *p; 1330Sstevel@tonic-gate int j; 1340Sstevel@tonic-gate /* print sets of chars which may follow positions */ 1350Sstevel@tonic-gate (void) printf("pos\tchars\n"); 1360Sstevel@tonic-gate for (i = 0; i < tptr; i++) 1370Sstevel@tonic-gate if (p = foll[i]) { 1380Sstevel@tonic-gate j = *p++; 1390Sstevel@tonic-gate if (j >= 1) { 1400Sstevel@tonic-gate (void) printf("%d:\t%d", i, *p++); 1410Sstevel@tonic-gate for (k = 2; k <= j; k++) 1420Sstevel@tonic-gate (void) printf(", %d", *p++); 1430Sstevel@tonic-gate (void) putchar('\n'); 1440Sstevel@tonic-gate } 1450Sstevel@tonic-gate } 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate #endif 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate static void 1500Sstevel@tonic-gate add(int **array, int n) 1510Sstevel@tonic-gate { 1520Sstevel@tonic-gate int i, *temp; 1530Sstevel@tonic-gate CHR *ctemp; 1540Sstevel@tonic-gate temp = nxtpos; 1550Sstevel@tonic-gate ctemp = tmpstat; 1560Sstevel@tonic-gate array[n] = nxtpos; /* note no packing is done in positions */ 1570Sstevel@tonic-gate *temp++ = count; 1580Sstevel@tonic-gate for (i = 0; i < tptr; i++) 1590Sstevel@tonic-gate if (ctemp[i] == TRUE) 1600Sstevel@tonic-gate *temp++ = i; 1610Sstevel@tonic-gate nxtpos = temp; 1620Sstevel@tonic-gate if (nxtpos >= positions+maxpos) 1630Sstevel@tonic-gate error( 1640Sstevel@tonic-gate "Too many positions %s", 165*4538Sdamico (maxpos == MAXPOS ? "\nTry using %p num" : "")); 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate static void 1690Sstevel@tonic-gate follow(int v) 1700Sstevel@tonic-gate { 1710Sstevel@tonic-gate int p; 1720Sstevel@tonic-gate if (v >= tptr-1) 1730Sstevel@tonic-gate return; 1740Sstevel@tonic-gate p = parent[v]; 1750Sstevel@tonic-gate if (p == 0) 1760Sstevel@tonic-gate return; 1770Sstevel@tonic-gate switch (name[p]) { 1780Sstevel@tonic-gate /* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */ 1790Sstevel@tonic-gate case RSTR: 1800Sstevel@tonic-gate if (tmpstat[p] == FALSE) { 1810Sstevel@tonic-gate count++; 1820Sstevel@tonic-gate tmpstat[p] = TRUE; 1830Sstevel@tonic-gate } 1840Sstevel@tonic-gate break; 1850Sstevel@tonic-gate case STAR: case PLUS: 1860Sstevel@tonic-gate first(v); 1870Sstevel@tonic-gate follow(p); 1880Sstevel@tonic-gate break; 1890Sstevel@tonic-gate case BAR: case QUEST: case RNEWE: 1900Sstevel@tonic-gate follow(p); 1910Sstevel@tonic-gate break; 1920Sstevel@tonic-gate case RCAT: case DIV: 1930Sstevel@tonic-gate if (v == left[p]) { 1940Sstevel@tonic-gate if (nullstr[right[p]]) 1950Sstevel@tonic-gate follow(p); 1960Sstevel@tonic-gate first(right[p]); 1970Sstevel@tonic-gate } 1980Sstevel@tonic-gate else 1990Sstevel@tonic-gate follow(p); 2000Sstevel@tonic-gate break; 2010Sstevel@tonic-gate /* XCU4: add RXSCON */ 2020Sstevel@tonic-gate case RXSCON: 2030Sstevel@tonic-gate case RSCON: case CARAT: 2040Sstevel@tonic-gate follow(p); 2050Sstevel@tonic-gate break; 2060Sstevel@tonic-gate #ifdef DEBUG 2070Sstevel@tonic-gate default: 2080Sstevel@tonic-gate warning("bad switch follow %d", p); 2090Sstevel@tonic-gate #endif 2100Sstevel@tonic-gate } 2110Sstevel@tonic-gate } 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate /* 2140Sstevel@tonic-gate * Check if I have a RXSCON in my upper node 2150Sstevel@tonic-gate */ 2160Sstevel@tonic-gate static int 2170Sstevel@tonic-gate check_me(int v) 2180Sstevel@tonic-gate { 2190Sstevel@tonic-gate int tmp = parent[v]; 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate while (name[tmp] != RNEWE) { 2220Sstevel@tonic-gate if (name[tmp] == RXSCON) 2230Sstevel@tonic-gate return (1); 2240Sstevel@tonic-gate tmp = parent[tmp]; 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate return (0); 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate /* calculate set of positions with v as root which can be active initially */ 2300Sstevel@tonic-gate static void 2310Sstevel@tonic-gate first(int v) 2320Sstevel@tonic-gate { 2330Sstevel@tonic-gate int i; 2340Sstevel@tonic-gate CHR *p; 2350Sstevel@tonic-gate i = name[v]; 2360Sstevel@tonic-gate if (!ISOPERATOR(i)) 2370Sstevel@tonic-gate i = 1; 2380Sstevel@tonic-gate switch (i) { 2390Sstevel@tonic-gate case 1: case RCCL: case RNCCL: 2400Sstevel@tonic-gate case RNULLS: case FINAL: 2410Sstevel@tonic-gate case S1FINAL: case S2FINAL: 2420Sstevel@tonic-gate /* 2430Sstevel@tonic-gate * XCU4: if we are working on an exclusive start state and 2440Sstevel@tonic-gate * the parent of this position is not RXSCON or RSTR this 2450Sstevel@tonic-gate * is not an active position. 2460Sstevel@tonic-gate * 2470Sstevel@tonic-gate * (There is a possibility that RSXCON appreas as the 2480Sstevel@tonic-gate * (parent)* node. Check it by check_me().) 2490Sstevel@tonic-gate */ 2500Sstevel@tonic-gate if ((exclusive[stnum/2]) && 2510Sstevel@tonic-gate ISOPERATOR(name[parent[v]]) && 2520Sstevel@tonic-gate (name[parent[v]] != RXSCON) && 2530Sstevel@tonic-gate (name[parent[v]] != RSTR) && 2540Sstevel@tonic-gate (check_me(v) == 0)) { 2550Sstevel@tonic-gate break; 2560Sstevel@tonic-gate } 2570Sstevel@tonic-gate if (tmpstat[v] == FALSE) { 2580Sstevel@tonic-gate count++; 2590Sstevel@tonic-gate tmpstat[v] = TRUE; 2600Sstevel@tonic-gate } 2610Sstevel@tonic-gate break; 2620Sstevel@tonic-gate case BAR: case RNEWE: 2630Sstevel@tonic-gate first(left[v]); 2640Sstevel@tonic-gate first(right[v]); 2650Sstevel@tonic-gate break; 2660Sstevel@tonic-gate case CARAT: 2670Sstevel@tonic-gate if (stnum % 2 == 1) 2680Sstevel@tonic-gate first(left[v]); 2690Sstevel@tonic-gate break; 2700Sstevel@tonic-gate /* XCU4: add RXSCON */ 2710Sstevel@tonic-gate case RXSCON: 2720Sstevel@tonic-gate case RSCON: 2730Sstevel@tonic-gate i = stnum/2 +1; 2740Sstevel@tonic-gate p = (CHR *) right[v]; 2750Sstevel@tonic-gate while (*p) 2760Sstevel@tonic-gate if (*p++ == i) { 2770Sstevel@tonic-gate first(left[v]); 2780Sstevel@tonic-gate break; 2790Sstevel@tonic-gate } 2800Sstevel@tonic-gate break; 2810Sstevel@tonic-gate case STAR: case QUEST: 2820Sstevel@tonic-gate case PLUS: case RSTR: 2830Sstevel@tonic-gate /* 2840Sstevel@tonic-gate * XCU4: if we are working on an exclusive start state and 2850Sstevel@tonic-gate * the parent of this position is not RXSCON or RSTR this 2860Sstevel@tonic-gate * is not an active position. 2870Sstevel@tonic-gate * 2880Sstevel@tonic-gate * (There is a possibility that RSXCON appreas as the 2890Sstevel@tonic-gate * (parent)* node. Check it by check_me().) 2900Sstevel@tonic-gate */ 2910Sstevel@tonic-gate if ((exclusive[stnum/2]) && 2920Sstevel@tonic-gate ISOPERATOR(name[parent[v]]) && 2930Sstevel@tonic-gate (name[parent[v]] != RXSCON) && 2940Sstevel@tonic-gate (name[parent[v]] != RSTR) && 2950Sstevel@tonic-gate (check_me(v) == 0)) { 2960Sstevel@tonic-gate break; 2970Sstevel@tonic-gate } 2980Sstevel@tonic-gate first(left[v]); 2990Sstevel@tonic-gate break; 3000Sstevel@tonic-gate case RCAT: case DIV: 3010Sstevel@tonic-gate first(left[v]); 3020Sstevel@tonic-gate if (nullstr[left[v]]) 3030Sstevel@tonic-gate first(right[v]); 3040Sstevel@tonic-gate break; 3050Sstevel@tonic-gate #ifdef DEBUG 3060Sstevel@tonic-gate default: 3070Sstevel@tonic-gate warning("bad switch first %d", v); 3080Sstevel@tonic-gate #endif 3090Sstevel@tonic-gate } 3100Sstevel@tonic-gate } 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate void 3130Sstevel@tonic-gate cgoto(void) 3140Sstevel@tonic-gate { 3150Sstevel@tonic-gate int i, j; 3160Sstevel@tonic-gate static int s; 3170Sstevel@tonic-gate int npos, curpos, n; 3180Sstevel@tonic-gate int tryit; 3190Sstevel@tonic-gate CHR tch[MAXNCG]; 3200Sstevel@tonic-gate int tst[MAXNCG]; 3210Sstevel@tonic-gate CHR *q; 3220Sstevel@tonic-gate /* generate initial state, for each start condition */ 3230Sstevel@tonic-gate if (ratfor) { 3240Sstevel@tonic-gate (void) fprintf(fout, "blockdata\n"); 3250Sstevel@tonic-gate (void) fprintf(fout, "common /Lvstop/ vstop\n"); 3260Sstevel@tonic-gate (void) fprintf(fout, "define Svstop %d\n", nstates+1); 3270Sstevel@tonic-gate (void) fprintf(fout, "integer vstop(Svstop)\n"); 3280Sstevel@tonic-gate } else 3290Sstevel@tonic-gate (void) fprintf(fout, "int yyvstop[] = {\n0,\n"); 3300Sstevel@tonic-gate while (stnum < 2 || stnum/2 < sptr) { 3310Sstevel@tonic-gate for (i = 0; i < tptr; i++) 3320Sstevel@tonic-gate tmpstat[i] = 0; 3330Sstevel@tonic-gate count = 0; 3340Sstevel@tonic-gate if (tptr > 0) 3350Sstevel@tonic-gate first(tptr-1); 3360Sstevel@tonic-gate add(state, stnum); 3370Sstevel@tonic-gate #ifdef DEBUG 3380Sstevel@tonic-gate if (debug) { 3390Sstevel@tonic-gate if (stnum > 1) 3400Sstevel@tonic-gate (void) printf("%ws:\n", sname[stnum/2]); 3410Sstevel@tonic-gate pstate(stnum); 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate #endif 3440Sstevel@tonic-gate stnum++; 3450Sstevel@tonic-gate } 3460Sstevel@tonic-gate stnum--; 3470Sstevel@tonic-gate /* even stnum = might not be at line begin */ 3480Sstevel@tonic-gate /* odd stnum = must be at line begin */ 3490Sstevel@tonic-gate /* even states can occur anywhere, odd states only at line begin */ 3500Sstevel@tonic-gate for (s = 0; s <= stnum; s++) { 3510Sstevel@tonic-gate tryit = FALSE; 3520Sstevel@tonic-gate cpackflg[s] = FALSE; 3530Sstevel@tonic-gate sfall[s] = -1; 3540Sstevel@tonic-gate acompute(s); 3550Sstevel@tonic-gate for (i = 0; i < ncg; i++) 3560Sstevel@tonic-gate symbol[i] = 0; 3570Sstevel@tonic-gate npos = *state[s]; 3580Sstevel@tonic-gate for (i = 1; i <= npos; i++) { 3590Sstevel@tonic-gate curpos = *(state[s]+i); 3600Sstevel@tonic-gate if (!ISOPERATOR(name[curpos])) 3610Sstevel@tonic-gate symbol[name[curpos]] = TRUE; 3620Sstevel@tonic-gate else { 3630Sstevel@tonic-gate switch (name[curpos]) { 3640Sstevel@tonic-gate case RCCL: 3650Sstevel@tonic-gate tryit = TRUE; 3660Sstevel@tonic-gate q = (CHR *)left[curpos]; 3670Sstevel@tonic-gate while (*q) { 3680Sstevel@tonic-gate for (j = 1; j < ncg; j++) 369*4538Sdamico if (cindex[j] == *q) 370*4538Sdamico symbol[j] = 371*4538Sdamico TRUE; 3720Sstevel@tonic-gate q++; 3730Sstevel@tonic-gate } 3740Sstevel@tonic-gate break; 3750Sstevel@tonic-gate case RSTR: 3760Sstevel@tonic-gate symbol[right[curpos]] = TRUE; 3770Sstevel@tonic-gate break; 3780Sstevel@tonic-gate #ifdef DEBUG 3790Sstevel@tonic-gate case RNULLS: 3800Sstevel@tonic-gate case FINAL: 3810Sstevel@tonic-gate case S1FINAL: 3820Sstevel@tonic-gate case S2FINAL: 3830Sstevel@tonic-gate break; 3840Sstevel@tonic-gate default: 3850Sstevel@tonic-gate warning( 3860Sstevel@tonic-gate "bad switch cgoto %d state %d", 387*4538Sdamico curpos, s); 3880Sstevel@tonic-gate break; 3890Sstevel@tonic-gate #endif 3900Sstevel@tonic-gate } 3910Sstevel@tonic-gate } 3920Sstevel@tonic-gate } 3930Sstevel@tonic-gate #ifdef DEBUG 3940Sstevel@tonic-gate if (debug) { 3950Sstevel@tonic-gate printf("State %d transitions on char-group {", s); 3960Sstevel@tonic-gate charc = 0; 3970Sstevel@tonic-gate for (i = 1; i < ncg; i++) { 3980Sstevel@tonic-gate if (symbol[i]) { 3990Sstevel@tonic-gate printf("%d,", i); 4000Sstevel@tonic-gate } 4010Sstevel@tonic-gate if (i == ncg-1) 4020Sstevel@tonic-gate printf("}\n"); 4030Sstevel@tonic-gate if (charc > LINESIZE/4) { 4040Sstevel@tonic-gate charc = 0; 4050Sstevel@tonic-gate printf("\n\t"); 4060Sstevel@tonic-gate } 4070Sstevel@tonic-gate } 4080Sstevel@tonic-gate } 4090Sstevel@tonic-gate #endif 4100Sstevel@tonic-gate /* for each char, calculate next state */ 4110Sstevel@tonic-gate n = 0; 4120Sstevel@tonic-gate for (i = 1; i < ncg; i++) { 4130Sstevel@tonic-gate if (symbol[i]) { 4140Sstevel@tonic-gate /* executed for each state, transition pair */ 4150Sstevel@tonic-gate nextstate(s, i); 4160Sstevel@tonic-gate xstate = notin(stnum); 4170Sstevel@tonic-gate if (xstate == -2) 4180Sstevel@tonic-gate warning("bad state %d %o", s, i); 4190Sstevel@tonic-gate else if (xstate == -1) { 4200Sstevel@tonic-gate if (stnum+1 >= nstates) { 4210Sstevel@tonic-gate stnum++; 4220Sstevel@tonic-gate error("Too many states %s", 423*4538Sdamico (nstates == NSTATES ? 424*4538Sdamico "\nTry using %n num":"")); 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate add(state, ++stnum); 4270Sstevel@tonic-gate #ifdef DEBUG 4280Sstevel@tonic-gate if (debug) 4290Sstevel@tonic-gate pstate(stnum); 4300Sstevel@tonic-gate #endif 4310Sstevel@tonic-gate tch[n] = i; 4320Sstevel@tonic-gate tst[n++] = stnum; 4330Sstevel@tonic-gate } else { /* xstate >= 0 ==> state exists */ 4340Sstevel@tonic-gate tch[n] = i; 4350Sstevel@tonic-gate tst[n++] = xstate; 4360Sstevel@tonic-gate } 4370Sstevel@tonic-gate } 4380Sstevel@tonic-gate } 4390Sstevel@tonic-gate tch[n] = 0; 4400Sstevel@tonic-gate tst[n] = -1; 4410Sstevel@tonic-gate /* pack transitions into permanent array */ 4420Sstevel@tonic-gate if (n > 0) 4430Sstevel@tonic-gate packtrans(s, tch, tst, n, tryit); 4440Sstevel@tonic-gate else 4450Sstevel@tonic-gate gotof[s] = -1; 4460Sstevel@tonic-gate } 4470Sstevel@tonic-gate ratfor ? fprintf(fout, "end\n") : fprintf(fout, "0};\n"); 4480Sstevel@tonic-gate } 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate /* 4510Sstevel@tonic-gate * Beware -- 70% of total CPU time is spent in this subroutine - 4520Sstevel@tonic-gate * if you don't believe me - try it yourself ! 4530Sstevel@tonic-gate */ 4540Sstevel@tonic-gate static void 4550Sstevel@tonic-gate nextstate(int s, int c) 4560Sstevel@tonic-gate { 4570Sstevel@tonic-gate int j, *newpos; 4580Sstevel@tonic-gate CHR *temp, *tz; 4590Sstevel@tonic-gate int *pos, i, *f, num, curpos, number; 4600Sstevel@tonic-gate /* state to goto from state s on char c */ 4610Sstevel@tonic-gate num = *state[s]; 4620Sstevel@tonic-gate temp = tmpstat; 4630Sstevel@tonic-gate pos = state[s] + 1; 4640Sstevel@tonic-gate for (i = 0; i < num; i++) { 4650Sstevel@tonic-gate curpos = *pos++; 4660Sstevel@tonic-gate j = name[curpos]; 4670Sstevel@tonic-gate if ((!ISOPERATOR(j)) && j == c || 468*4538Sdamico j == RSTR && c == right[curpos] || 469*4538Sdamico j == RCCL && member(c, (CHR *) left[curpos])) { 4700Sstevel@tonic-gate f = foll[curpos]; 4710Sstevel@tonic-gate number = *f; 4720Sstevel@tonic-gate newpos = f+1; 4730Sstevel@tonic-gate for (j = 0; j < number; j++) 4740Sstevel@tonic-gate temp[*newpos++] = 2; 4750Sstevel@tonic-gate } 4760Sstevel@tonic-gate } 4770Sstevel@tonic-gate j = 0; 4780Sstevel@tonic-gate tz = temp + tptr; 4790Sstevel@tonic-gate while (temp < tz) { 4800Sstevel@tonic-gate if (*temp == 2) { 4810Sstevel@tonic-gate j++; 4820Sstevel@tonic-gate *temp++ = 1; 4830Sstevel@tonic-gate } 4840Sstevel@tonic-gate else 4850Sstevel@tonic-gate *temp++ = 0; 4860Sstevel@tonic-gate } 4870Sstevel@tonic-gate count = j; 4880Sstevel@tonic-gate } 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate static int 4910Sstevel@tonic-gate notin(int n) 4920Sstevel@tonic-gate { /* see if tmpstat occurs previously */ 4930Sstevel@tonic-gate int *j, k; 4940Sstevel@tonic-gate CHR *temp; 4950Sstevel@tonic-gate int i; 4960Sstevel@tonic-gate if (count == 0) 4970Sstevel@tonic-gate return (-2); 4980Sstevel@tonic-gate temp = tmpstat; 4990Sstevel@tonic-gate for (i = n; i >= 0; i--) { /* for each state */ 5000Sstevel@tonic-gate j = state[i]; 5010Sstevel@tonic-gate if (count == *j++) { 5020Sstevel@tonic-gate for (k = 0; k < count; k++) 5030Sstevel@tonic-gate if (!temp[*j++]) 5040Sstevel@tonic-gate break; 5050Sstevel@tonic-gate if (k >= count) 5060Sstevel@tonic-gate return (i); 5070Sstevel@tonic-gate } 5080Sstevel@tonic-gate } 5090Sstevel@tonic-gate return (-1); 5100Sstevel@tonic-gate } 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate static void 5130Sstevel@tonic-gate packtrans(int st, CHR *tch, int *tst, int cnt, int tryit) 5140Sstevel@tonic-gate { 5150Sstevel@tonic-gate /* 5160Sstevel@tonic-gate * pack transitions into nchar, nexts 5170Sstevel@tonic-gate * nchar is terminated by '\0', nexts uses cnt, followed by elements 5180Sstevel@tonic-gate * gotof[st] = index into nchr, nexts for state st 5190Sstevel@tonic-gate * sfall[st] = t implies t is fall back state for st 5200Sstevel@tonic-gate * == -1 implies no fall back 5210Sstevel@tonic-gate */ 5220Sstevel@tonic-gate 5230Sstevel@tonic-gate int cmin, cval, tcnt, diff, p, *ast; 5240Sstevel@tonic-gate int i, j, k; 5250Sstevel@tonic-gate CHR *ach; 5260Sstevel@tonic-gate int go[MAXNCG], temp[MAXNCG], index, c; 5270Sstevel@tonic-gate int swork[MAXNCG]; 5280Sstevel@tonic-gate CHR cwork[MAXNCG]; 5290Sstevel@tonic-gate int upper; 5300Sstevel@tonic-gate 5310Sstevel@tonic-gate rcount += (long)cnt; 5320Sstevel@tonic-gate cmin = -1; 5330Sstevel@tonic-gate cval = ncg; 5340Sstevel@tonic-gate ast = tst; 5350Sstevel@tonic-gate ach = tch; 5360Sstevel@tonic-gate /* try to pack transitions using ccl's */ 5370Sstevel@tonic-gate if (!optim) 5380Sstevel@tonic-gate goto nopack; /* skip all compaction */ 5390Sstevel@tonic-gate if (tryit) { /* ccl's used */ 5400Sstevel@tonic-gate for (i = 1; i < ncg; i++) { 5410Sstevel@tonic-gate go[i] = temp[i] = -1; 5420Sstevel@tonic-gate symbol[i] = 1; 5430Sstevel@tonic-gate } 5440Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 5450Sstevel@tonic-gate index = (unsigned char) tch[i]; 5460Sstevel@tonic-gate if ((index >= 0) && (index < NCH)) { 5470Sstevel@tonic-gate go[index] = tst[i]; 5480Sstevel@tonic-gate symbol[index] = 0; 5490Sstevel@tonic-gate } else { 5500Sstevel@tonic-gate fprintf(stderr, 5510Sstevel@tonic-gate "lex`sub2`packtran: tch[%d] out of bounds (%d)\n", 552*4538Sdamico i, tch[i]); 5530Sstevel@tonic-gate } 5540Sstevel@tonic-gate } 5550Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 5560Sstevel@tonic-gate c = match[tch[i]]; 5570Sstevel@tonic-gate if (go[c] != tst[i] || c == tch[i]) 5580Sstevel@tonic-gate temp[tch[i]] = tst[i]; 5590Sstevel@tonic-gate } 5600Sstevel@tonic-gate /* fill in error entries */ 5610Sstevel@tonic-gate for (i = 1; i < ncg; i++) 5620Sstevel@tonic-gate if (symbol[i]) 5630Sstevel@tonic-gate temp[i] = -2; /* error trans */ 5640Sstevel@tonic-gate /* count them */ 5650Sstevel@tonic-gate k = 0; 5660Sstevel@tonic-gate for (i = 1; i < ncg; i++) 5670Sstevel@tonic-gate if (temp[i] != -1) 5680Sstevel@tonic-gate k++; 5690Sstevel@tonic-gate if (k < cnt) { /* compress by char */ 5700Sstevel@tonic-gate #ifdef DEBUG 5710Sstevel@tonic-gate if (debug) 5720Sstevel@tonic-gate (void) printf( 5730Sstevel@tonic-gate "use compression %d, %d vs %d\n", st, k, cnt); 5740Sstevel@tonic-gate #endif 5750Sstevel@tonic-gate k = 0; 5760Sstevel@tonic-gate for (i = 1; i < ncg; i++) 5770Sstevel@tonic-gate if (temp[i] != -1) { 5780Sstevel@tonic-gate cwork[k] = i; 5790Sstevel@tonic-gate swork[k++] = 580*4538Sdamico (temp[i] == -2 ? -1 : temp[i]); 5810Sstevel@tonic-gate } 5820Sstevel@tonic-gate cwork[k] = 0; 5830Sstevel@tonic-gate #ifdef PC 5840Sstevel@tonic-gate ach = cwork; 5850Sstevel@tonic-gate ast = swork; 5860Sstevel@tonic-gate cnt = k; 5870Sstevel@tonic-gate cpackflg[st] = TRUE; 5880Sstevel@tonic-gate #endif 5890Sstevel@tonic-gate } 5900Sstevel@tonic-gate } 5910Sstevel@tonic-gate /* 5920Sstevel@tonic-gate * get most similar state 5930Sstevel@tonic-gate * reject state with more transitions, 5940Sstevel@tonic-gate * state already represented by a third state, 5950Sstevel@tonic-gate * and state which is compressed by char if ours is not to be 5960Sstevel@tonic-gate */ 5970Sstevel@tonic-gate for (i = 0; i < st; i++) { 5980Sstevel@tonic-gate if (sfall[i] != -1) 5990Sstevel@tonic-gate continue; 6000Sstevel@tonic-gate if (cpackflg[st] == 1) 6010Sstevel@tonic-gate if (!(cpackflg[i] == 1)) 6020Sstevel@tonic-gate continue; 6030Sstevel@tonic-gate p = gotof[i]; 6040Sstevel@tonic-gate if (p == -1) /* no transitions */ 6050Sstevel@tonic-gate continue; 6060Sstevel@tonic-gate tcnt = nexts[p]; 6070Sstevel@tonic-gate if (tcnt > cnt) 6080Sstevel@tonic-gate continue; 6090Sstevel@tonic-gate diff = 0; 6100Sstevel@tonic-gate k = 0; 6110Sstevel@tonic-gate j = 0; 6120Sstevel@tonic-gate upper = p + tcnt; 6130Sstevel@tonic-gate while (ach[j] && p < upper) { 6140Sstevel@tonic-gate while (ach[j] < nchar[p] && ach[j]) { 6150Sstevel@tonic-gate diff++; 6160Sstevel@tonic-gate j++; 6170Sstevel@tonic-gate } 6180Sstevel@tonic-gate if (ach[j] == 0) 6190Sstevel@tonic-gate break; 6200Sstevel@tonic-gate if (ach[j] > nchar[p]) { 6210Sstevel@tonic-gate diff = ncg; 6220Sstevel@tonic-gate break; 6230Sstevel@tonic-gate } 6240Sstevel@tonic-gate /* ach[j] == nchar[p] */ 6250Sstevel@tonic-gate if (ast[j] != nexts[++p] || 626*4538Sdamico ast[j] == -1 || 627*4538Sdamico (cpackflg[st] && ach[j] != match[ach[j]])) 6280Sstevel@tonic-gate diff++; 6290Sstevel@tonic-gate j++; 6300Sstevel@tonic-gate } 6310Sstevel@tonic-gate while (ach[j]) { 6320Sstevel@tonic-gate diff++; 6330Sstevel@tonic-gate j++; 6340Sstevel@tonic-gate } 6350Sstevel@tonic-gate if (p < upper) 6360Sstevel@tonic-gate diff = ncg; 6370Sstevel@tonic-gate if (diff < cval && diff < tcnt) { 6380Sstevel@tonic-gate cval = diff; 6390Sstevel@tonic-gate cmin = i; 6400Sstevel@tonic-gate if (cval == 0) 6410Sstevel@tonic-gate break; 6420Sstevel@tonic-gate } 6430Sstevel@tonic-gate } 6440Sstevel@tonic-gate /* cmin = state "most like" state st */ 6450Sstevel@tonic-gate #ifdef DEBUG 6460Sstevel@tonic-gate if (debug) 6470Sstevel@tonic-gate (void) printf("select st %d for st %d diff %d\n", 648*4538Sdamico cmin, st, cval); 6490Sstevel@tonic-gate #endif 6500Sstevel@tonic-gate #ifdef PS 6510Sstevel@tonic-gate if (cmin != -1) { /* if we can use st cmin */ 6520Sstevel@tonic-gate gotof[st] = nptr; 6530Sstevel@tonic-gate k = 0; 6540Sstevel@tonic-gate sfall[st] = cmin; 6550Sstevel@tonic-gate p = gotof[cmin] + 1; 6560Sstevel@tonic-gate j = 0; 6570Sstevel@tonic-gate while (ach[j]) { 6580Sstevel@tonic-gate /* if cmin has a transition on c, then so will st */ 6590Sstevel@tonic-gate /* st may be "larger" than cmin, however */ 6600Sstevel@tonic-gate while (ach[j] < nchar[p-1] && ach[j]) { 6610Sstevel@tonic-gate k++; 6620Sstevel@tonic-gate nchar[nptr] = ach[j]; 6630Sstevel@tonic-gate nexts[++nptr] = ast[j]; 6640Sstevel@tonic-gate j++; 6650Sstevel@tonic-gate } 6660Sstevel@tonic-gate if (nchar[p-1] == 0) 6670Sstevel@tonic-gate break; 6680Sstevel@tonic-gate if (ach[j] > nchar[p-1]) { 6690Sstevel@tonic-gate warning("bad transition %d %d", st, cmin); 6700Sstevel@tonic-gate goto nopack; 6710Sstevel@tonic-gate } 6720Sstevel@tonic-gate /* ach[j] == nchar[p-1] */ 6730Sstevel@tonic-gate if (ast[j] != nexts[p] || 674*4538Sdamico ast[j] == -1 || 675*4538Sdamico (cpackflg[st] && ach[j] != match[ach[j]])) { 6760Sstevel@tonic-gate k++; 6770Sstevel@tonic-gate nchar[nptr] = ach[j]; 6780Sstevel@tonic-gate nexts[++nptr] = ast[j]; 6790Sstevel@tonic-gate } 6800Sstevel@tonic-gate p++; 6810Sstevel@tonic-gate j++; 6820Sstevel@tonic-gate } 6830Sstevel@tonic-gate while (ach[j]) { 6840Sstevel@tonic-gate nchar[nptr] = ach[j]; 6850Sstevel@tonic-gate nexts[++nptr] = ast[j++]; 6860Sstevel@tonic-gate k++; 6870Sstevel@tonic-gate } 6880Sstevel@tonic-gate nexts[gotof[st]] = cnt = k; 6890Sstevel@tonic-gate nchar[nptr++] = 0; 6900Sstevel@tonic-gate } else { 6910Sstevel@tonic-gate #endif 6920Sstevel@tonic-gate nopack: 6930Sstevel@tonic-gate /* stick it in */ 6940Sstevel@tonic-gate gotof[st] = nptr; 6950Sstevel@tonic-gate nexts[nptr] = cnt; 6960Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 6970Sstevel@tonic-gate nchar[nptr] = ach[i]; 6980Sstevel@tonic-gate nexts[++nptr] = ast[i]; 6990Sstevel@tonic-gate } 7000Sstevel@tonic-gate nchar[nptr++] = 0; 7010Sstevel@tonic-gate #ifdef PS 7020Sstevel@tonic-gate } 7030Sstevel@tonic-gate #endif 7040Sstevel@tonic-gate if (cnt < 1) { 7050Sstevel@tonic-gate gotof[st] = -1; 7060Sstevel@tonic-gate nptr--; 7070Sstevel@tonic-gate } else 7080Sstevel@tonic-gate if (nptr > ntrans) 7090Sstevel@tonic-gate error( 7100Sstevel@tonic-gate "Too many transitions %s", 711*4538Sdamico (ntrans == NTRANS ? "\nTry using %a num" : "")); 7120Sstevel@tonic-gate } 7130Sstevel@tonic-gate 7140Sstevel@tonic-gate #ifdef DEBUG 7150Sstevel@tonic-gate void 7160Sstevel@tonic-gate pstate(int s) 7170Sstevel@tonic-gate { 7180Sstevel@tonic-gate int *p, i, j; 7190Sstevel@tonic-gate (void) printf("State %d:\n", s); 7200Sstevel@tonic-gate p = state[s]; 7210Sstevel@tonic-gate i = *p++; 7220Sstevel@tonic-gate if (i == 0) 7230Sstevel@tonic-gate return; 7240Sstevel@tonic-gate (void) printf("%4d", *p++); 7250Sstevel@tonic-gate for (j = 1; j < i; j++) { 7260Sstevel@tonic-gate (void) printf(", %4d", *p++); 7270Sstevel@tonic-gate if (j%30 == 0) 7280Sstevel@tonic-gate (void) putchar('\n'); 7290Sstevel@tonic-gate } 7300Sstevel@tonic-gate (void) putchar('\n'); 7310Sstevel@tonic-gate } 7320Sstevel@tonic-gate #endif 7330Sstevel@tonic-gate 7340Sstevel@tonic-gate static int 7350Sstevel@tonic-gate member(int d, CHR *t) 7360Sstevel@tonic-gate { 7370Sstevel@tonic-gate int c; 7380Sstevel@tonic-gate CHR *s; 7390Sstevel@tonic-gate c = d; 7400Sstevel@tonic-gate s = t; 7410Sstevel@tonic-gate c = cindex[c]; 7420Sstevel@tonic-gate while (*s) 7430Sstevel@tonic-gate if (*s++ == c) 7440Sstevel@tonic-gate return (1); 7450Sstevel@tonic-gate return (0); 7460Sstevel@tonic-gate } 7470Sstevel@tonic-gate 7480Sstevel@tonic-gate #ifdef DEBUG 7490Sstevel@tonic-gate void 7500Sstevel@tonic-gate stprt(int i) 7510Sstevel@tonic-gate { 7520Sstevel@tonic-gate int p, t; 7530Sstevel@tonic-gate (void) printf("State %d:", i); 7540Sstevel@tonic-gate /* print actions, if any */ 7550Sstevel@tonic-gate t = atable[i]; 7560Sstevel@tonic-gate if (t != -1) 7570Sstevel@tonic-gate (void) printf(" final"); 7580Sstevel@tonic-gate (void) putchar('\n'); 7590Sstevel@tonic-gate if (cpackflg[i] == TRUE) 7600Sstevel@tonic-gate (void) printf("backup char in use\n"); 7610Sstevel@tonic-gate if (sfall[i] != -1) 7620Sstevel@tonic-gate (void) printf("fall back state %d\n", sfall[i]); 7630Sstevel@tonic-gate p = gotof[i]; 7640Sstevel@tonic-gate if (p == -1) 7650Sstevel@tonic-gate return; 7660Sstevel@tonic-gate (void) printf("(%d transitions)\n", nexts[p]); 7670Sstevel@tonic-gate while (nchar[p]) { 7680Sstevel@tonic-gate charc = 0; 7690Sstevel@tonic-gate if (nexts[p+1] >= 0) 7700Sstevel@tonic-gate (void) printf("%d\t", nexts[p+1]); 7710Sstevel@tonic-gate else 7720Sstevel@tonic-gate (void) printf("err\t"); 7730Sstevel@tonic-gate allprint(nchar[p++]); 7740Sstevel@tonic-gate while (nexts[p] == nexts[p+1] && nchar[p]) { 7750Sstevel@tonic-gate if (charc > LINESIZE) { 7760Sstevel@tonic-gate charc = 0; 7770Sstevel@tonic-gate (void) printf("\n\t"); 7780Sstevel@tonic-gate } 7790Sstevel@tonic-gate allprint(nchar[p++]); 7800Sstevel@tonic-gate } 7810Sstevel@tonic-gate (void) putchar('\n'); 7820Sstevel@tonic-gate } 7830Sstevel@tonic-gate (void) putchar('\n'); 7840Sstevel@tonic-gate } 7850Sstevel@tonic-gate #endif 7860Sstevel@tonic-gate 7870Sstevel@tonic-gate /* compute action list = set of poss. actions */ 7880Sstevel@tonic-gate static void 7890Sstevel@tonic-gate acompute(int s) 7900Sstevel@tonic-gate { 7910Sstevel@tonic-gate int *p, i, j; 7920Sstevel@tonic-gate int q, r; 7930Sstevel@tonic-gate int cnt, m; 7940Sstevel@tonic-gate int temp[MAXPOSSTATE], k, neg[MAXPOSSTATE], n; 7950Sstevel@tonic-gate k = 0; 7960Sstevel@tonic-gate n = 0; 7970Sstevel@tonic-gate p = state[s]; 7980Sstevel@tonic-gate cnt = *p++; 7990Sstevel@tonic-gate if (cnt > MAXPOSSTATE) 8000Sstevel@tonic-gate error("Too many positions for one state - acompute"); 8010Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 8020Sstevel@tonic-gate q = *p; 8030Sstevel@tonic-gate if (name[q] == FINAL) 8040Sstevel@tonic-gate temp[k++] = left[q]; 8050Sstevel@tonic-gate else if (name[q] == S1FINAL) { 8060Sstevel@tonic-gate temp[k++] = left[q]; 8070Sstevel@tonic-gate if ((r = left[q]) >= NACTIONS) 8080Sstevel@tonic-gate error( 8090Sstevel@tonic-gate "INTERNAL ERROR:left[%d]==%d>=NACTIONS", q, r); 8100Sstevel@tonic-gate extra[r] = 1; 8110Sstevel@tonic-gate } else if (name[q] == S2FINAL) 8120Sstevel@tonic-gate neg[n++] = left[q]; 8130Sstevel@tonic-gate p++; 8140Sstevel@tonic-gate } 8150Sstevel@tonic-gate atable[s] = -1; 8160Sstevel@tonic-gate if (k < 1 && n < 1) 8170Sstevel@tonic-gate return; 8180Sstevel@tonic-gate #ifdef DEBUG 8190Sstevel@tonic-gate if (debug) 8200Sstevel@tonic-gate (void) printf("final %d actions:", s); 8210Sstevel@tonic-gate #endif 8220Sstevel@tonic-gate /* sort action list */ 8230Sstevel@tonic-gate for (i = 0; i < k; i++) 8240Sstevel@tonic-gate for (j = i+1; j < k; j++) 8250Sstevel@tonic-gate if (temp[j] < temp[i]) { 8260Sstevel@tonic-gate m = temp[j]; 8270Sstevel@tonic-gate temp[j] = temp[i]; 8280Sstevel@tonic-gate temp[i] = m; 8290Sstevel@tonic-gate } 8300Sstevel@tonic-gate /* remove dups */ 8310Sstevel@tonic-gate for (i = 0; i < k-1; i++) 8320Sstevel@tonic-gate if (temp[i] == temp[i+1]) 8330Sstevel@tonic-gate temp[i] = 0; 8340Sstevel@tonic-gate /* copy to permanent quarters */ 8350Sstevel@tonic-gate atable[s] = aptr; 8360Sstevel@tonic-gate #ifdef DEBUG 8370Sstevel@tonic-gate if (!ratfor) 8380Sstevel@tonic-gate (void) fprintf(fout, "/* actions for state %d */", s); 8390Sstevel@tonic-gate #endif 8400Sstevel@tonic-gate (void) putc('\n', fout); 8410Sstevel@tonic-gate for (i = 0; i < k; i++) 8420Sstevel@tonic-gate if (temp[i] != 0) { 8430Sstevel@tonic-gate ratfor ? 844*4538Sdamico fprintf(fout, "data vstop(%d)/%d/\n", 845*4538Sdamico aptr, temp[i]) : 846*4538Sdamico fprintf(fout, "%d,\n", temp[i]); 8470Sstevel@tonic-gate #ifdef DEBUG 8480Sstevel@tonic-gate if (debug) 8490Sstevel@tonic-gate (void) printf("%d ", temp[i]); 8500Sstevel@tonic-gate #endif 8510Sstevel@tonic-gate aptr++; 8520Sstevel@tonic-gate } 8530Sstevel@tonic-gate for (i = 0; i < n; i++) { /* copy fall back actions - all neg */ 8540Sstevel@tonic-gate ratfor ? 855*4538Sdamico fprintf(fout, "data vstop(%d)/%d/\n", aptr, neg[i]) : 856*4538Sdamico fprintf(fout, "%d,\n", neg[i]); 8570Sstevel@tonic-gate aptr++; 8580Sstevel@tonic-gate #ifdef DEBUG 8590Sstevel@tonic-gate if (debug) 8600Sstevel@tonic-gate (void) printf("%d ", neg[i]); 8610Sstevel@tonic-gate #endif 8620Sstevel@tonic-gate } 8630Sstevel@tonic-gate #ifdef DEBUG 8640Sstevel@tonic-gate if (debug) 8650Sstevel@tonic-gate (void) putchar('\n'); 8660Sstevel@tonic-gate #endif 8670Sstevel@tonic-gate ratfor ? fprintf(fout, "data vstop (%d)/0/\n", aptr) : 868*4538Sdamico fprintf(fout, "0, \n"); 8690Sstevel@tonic-gate aptr++; 8700Sstevel@tonic-gate } 8710Sstevel@tonic-gate 8720Sstevel@tonic-gate #ifdef DEBUG 8730Sstevel@tonic-gate void 8740Sstevel@tonic-gate pccl(void) 8750Sstevel@tonic-gate { 8760Sstevel@tonic-gate /* print character class sets */ 8770Sstevel@tonic-gate int i, j; 8780Sstevel@tonic-gate (void) printf("char class intersection\n"); 8790Sstevel@tonic-gate for (i = 0; i < ccount; i++) { 8800Sstevel@tonic-gate charc = 0; 8810Sstevel@tonic-gate (void) printf("class %d:\n\t", i); 8820Sstevel@tonic-gate for (j = 1; j < ncg; j++) 8830Sstevel@tonic-gate if (cindex[j] == i) { 8840Sstevel@tonic-gate allprint(j); 8850Sstevel@tonic-gate if (charc > LINESIZE) { 8860Sstevel@tonic-gate (void) printf("\n\t"); 8870Sstevel@tonic-gate charc = 0; 8880Sstevel@tonic-gate } 8890Sstevel@tonic-gate } 8900Sstevel@tonic-gate (void) putchar('\n'); 8910Sstevel@tonic-gate } 8920Sstevel@tonic-gate charc = 0; 8930Sstevel@tonic-gate (void) printf("match:\n"); 8940Sstevel@tonic-gate for (i = 0; i < ncg; i++) { 8950Sstevel@tonic-gate allprint(match[i]); 8960Sstevel@tonic-gate if (charc > LINESIZE) { 8970Sstevel@tonic-gate (void) putchar('\n'); 8980Sstevel@tonic-gate charc = 0; 8990Sstevel@tonic-gate } 9000Sstevel@tonic-gate } 9010Sstevel@tonic-gate (void) putchar('\n'); 9020Sstevel@tonic-gate } 9030Sstevel@tonic-gate #endif 9040Sstevel@tonic-gate 9050Sstevel@tonic-gate void 9060Sstevel@tonic-gate mkmatch(void) 9070Sstevel@tonic-gate { 9080Sstevel@tonic-gate int i; 9090Sstevel@tonic-gate CHR tab[MAXNCG]; 9100Sstevel@tonic-gate for (i = 0; i < ccount; i++) 9110Sstevel@tonic-gate tab[i] = 0; 9120Sstevel@tonic-gate for (i = 1; i < ncg; i++) 9130Sstevel@tonic-gate if (tab[cindex[i]] == 0) 9140Sstevel@tonic-gate tab[cindex[i]] = i; 9150Sstevel@tonic-gate /* tab[i] = principal char for new ccl i */ 9160Sstevel@tonic-gate for (i = 1; i < ncg; i++) 9170Sstevel@tonic-gate match[i] = tab[cindex[i]]; 9180Sstevel@tonic-gate } 9190Sstevel@tonic-gate 9200Sstevel@tonic-gate void 9210Sstevel@tonic-gate layout(void) 9220Sstevel@tonic-gate { 9230Sstevel@tonic-gate /* format and output final program's tables */ 9240Sstevel@tonic-gate int i, j, k; 9250Sstevel@tonic-gate int top, bot, startup, omin; 9260Sstevel@tonic-gate startup = 0; 9270Sstevel@tonic-gate for (i = 0; i < outsize; i++) 9280Sstevel@tonic-gate verify[i] = advance[i] = 0; 9290Sstevel@tonic-gate omin = 0; 9300Sstevel@tonic-gate yytop = 0; 9310Sstevel@tonic-gate for (i = 0; i <= stnum; i++) { /* for each state */ 9320Sstevel@tonic-gate j = gotof[i]; 9330Sstevel@tonic-gate if (j == -1) { 9340Sstevel@tonic-gate stoff[i] = 0; 9350Sstevel@tonic-gate continue; 9360Sstevel@tonic-gate } 9370Sstevel@tonic-gate bot = j; 9380Sstevel@tonic-gate while (nchar[j]) 9390Sstevel@tonic-gate j++; 9400Sstevel@tonic-gate top = j - 1; 9410Sstevel@tonic-gate #if DEBUG 9420Sstevel@tonic-gate if (debug) { 9430Sstevel@tonic-gate (void) printf("State %d: (layout)\n", i); 9440Sstevel@tonic-gate for (j = bot; j <= top; j++) { 9450Sstevel@tonic-gate (void) printf(" %o", nchar[j]); 9460Sstevel@tonic-gate if (j % 10 == 0) 9470Sstevel@tonic-gate (void) putchar('\n'); 9480Sstevel@tonic-gate } 9490Sstevel@tonic-gate (void) putchar('\n'); 9500Sstevel@tonic-gate } 9510Sstevel@tonic-gate #endif 9520Sstevel@tonic-gate while (verify[omin+ZCH]) 9530Sstevel@tonic-gate omin++; 9540Sstevel@tonic-gate startup = omin; 9550Sstevel@tonic-gate #if DEBUG 9560Sstevel@tonic-gate if (debug) 9570Sstevel@tonic-gate (void) printf( 9580Sstevel@tonic-gate "bot,top %d, %d startup begins %d\n", 959*4538Sdamico bot, top, startup); 9600Sstevel@tonic-gate #endif 9610Sstevel@tonic-gate if (chset) { 9620Sstevel@tonic-gate do { 9630Sstevel@tonic-gate startup += 1; 9640Sstevel@tonic-gate if (startup > outsize - ZCH) 9650Sstevel@tonic-gate error("output table overflow"); 9660Sstevel@tonic-gate for (j = bot; j <= top; j++) { 9670Sstevel@tonic-gate k = startup+ctable[nchar[j]]; 9680Sstevel@tonic-gate if (verify[k]) 9690Sstevel@tonic-gate break; 9700Sstevel@tonic-gate } 9710Sstevel@tonic-gate } while (j <= top); 9720Sstevel@tonic-gate #if DEBUG 9730Sstevel@tonic-gate if (debug) 9740Sstevel@tonic-gate (void) printf(" startup will be %d\n", 975*4538Sdamico startup); 9760Sstevel@tonic-gate #endif 9770Sstevel@tonic-gate /* have found place */ 9780Sstevel@tonic-gate for (j = bot; j <= top; j++) { 9790Sstevel@tonic-gate k = startup + ctable[nchar[j]]; 9800Sstevel@tonic-gate if (ctable[nchar[j]] <= 0) 9810Sstevel@tonic-gate (void) printf( 9820Sstevel@tonic-gate "j %d nchar %d ctable.nch %d\n", 983*4538Sdamico j, nchar[j], ctable[nchar[k]]); 9840Sstevel@tonic-gate verify[k] = i + 1; /* state number + 1 */ 9850Sstevel@tonic-gate advance[k] = nexts[j+1]+1; 9860Sstevel@tonic-gate if (yytop < k) 9870Sstevel@tonic-gate yytop = k; 9880Sstevel@tonic-gate } 9890Sstevel@tonic-gate } else { 9900Sstevel@tonic-gate do { 9910Sstevel@tonic-gate startup += 1; 9920Sstevel@tonic-gate if (startup > outsize - ZCH) 9930Sstevel@tonic-gate error("output table overflow"); 9940Sstevel@tonic-gate for (j = bot; j <= top; j++) { 9950Sstevel@tonic-gate k = startup + nchar[j]; 9960Sstevel@tonic-gate if (verify[k]) 9970Sstevel@tonic-gate break; 9980Sstevel@tonic-gate } 9990Sstevel@tonic-gate } while (j <= top); 10000Sstevel@tonic-gate /* have found place */ 10010Sstevel@tonic-gate #if DEBUG 10020Sstevel@tonic-gate if (debug) 10030Sstevel@tonic-gate (void) printf(" startup going to be %d\n", startup); 10040Sstevel@tonic-gate #endif 10050Sstevel@tonic-gate for (j = bot; j <= top; j++) { 10060Sstevel@tonic-gate k = startup + nchar[j]; 10070Sstevel@tonic-gate verify[k] = i+1; /* state number + 1 */ 10080Sstevel@tonic-gate advance[k] = nexts[j+1] + 1; 10090Sstevel@tonic-gate if (yytop < k) 10100Sstevel@tonic-gate yytop = k; 10110Sstevel@tonic-gate } 10120Sstevel@tonic-gate } 10130Sstevel@tonic-gate stoff[i] = startup; 10140Sstevel@tonic-gate } 10150Sstevel@tonic-gate 10160Sstevel@tonic-gate /* stoff[i] = offset into verify, advance for trans for state i */ 10170Sstevel@tonic-gate /* put out yywork */ 10180Sstevel@tonic-gate if (ratfor) { 10190Sstevel@tonic-gate (void) fprintf(fout, "define YYTOPVAL %d\n", yytop); 10200Sstevel@tonic-gate rprint(verify, "verif", yytop+1); 10210Sstevel@tonic-gate rprint(advance, "advan", yytop+1); 10220Sstevel@tonic-gate shiftr(stoff, stnum); 10230Sstevel@tonic-gate rprint(stoff, "stoff", stnum+1); 10240Sstevel@tonic-gate shiftr(sfall, stnum); 10250Sstevel@tonic-gate upone(sfall, stnum+1); 10260Sstevel@tonic-gate rprint(sfall, "fall", stnum+1); 10270Sstevel@tonic-gate bprint(extra, "extra", casecount+1); 10280Sstevel@tonic-gate bprint((char *)match, "match", ncg); 10290Sstevel@tonic-gate shiftr(atable, stnum); 10300Sstevel@tonic-gate rprint(atable, "atable", stnum+1); 10310Sstevel@tonic-gate } 10320Sstevel@tonic-gate (void) fprintf(fout, 10330Sstevel@tonic-gate "# define YYTYPE %s\n", stnum+1 >= NCH ? "int" : "unsigned char"); 10340Sstevel@tonic-gate (void) fprintf(fout, 10350Sstevel@tonic-gate "struct yywork { YYTYPE verify, advance; } yycrank[] = {\n"); 10360Sstevel@tonic-gate for (i = 0; i <= yytop; i += 4) { 10370Sstevel@tonic-gate for (j = 0; j < 4; j++) { 10380Sstevel@tonic-gate k = i+j; 10390Sstevel@tonic-gate if (verify[k]) 10400Sstevel@tonic-gate (void) fprintf(fout, 10410Sstevel@tonic-gate "%d,%d,\t", verify[k], advance[k]); 10420Sstevel@tonic-gate else 10430Sstevel@tonic-gate (void) fprintf(fout, "0,0,\t"); 10440Sstevel@tonic-gate } 10450Sstevel@tonic-gate (void) putc('\n', fout); 10460Sstevel@tonic-gate } 10470Sstevel@tonic-gate (void) fprintf(fout, "0,0};\n"); 10480Sstevel@tonic-gate 10490Sstevel@tonic-gate /* put out yysvec */ 10500Sstevel@tonic-gate 10510Sstevel@tonic-gate (void) fprintf(fout, "struct yysvf yysvec[] = {\n"); 10520Sstevel@tonic-gate (void) fprintf(fout, "0,\t0,\t0,\n"); 10530Sstevel@tonic-gate for (i = 0; i <= stnum; i++) { /* for each state */ 10540Sstevel@tonic-gate if (cpackflg[i]) 10550Sstevel@tonic-gate stoff[i] = -stoff[i]; 10560Sstevel@tonic-gate (void) fprintf(fout, "yycrank+%d,\t", stoff[i]); 10570Sstevel@tonic-gate if (sfall[i] != -1) 10580Sstevel@tonic-gate (void) fprintf(fout, 10590Sstevel@tonic-gate "yysvec+%d,\t", sfall[i]+1); /* state + 1 */ 10600Sstevel@tonic-gate else 10610Sstevel@tonic-gate (void) fprintf(fout, "0,\t\t"); 10620Sstevel@tonic-gate if (atable[i] != -1) 10630Sstevel@tonic-gate (void) fprintf(fout, "yyvstop+%d,", atable[i]); 10640Sstevel@tonic-gate else 10650Sstevel@tonic-gate (void) fprintf(fout, "0,\t"); 10660Sstevel@tonic-gate #ifdef DEBUG 10670Sstevel@tonic-gate (void) fprintf(fout, "\t\t/* state %d */", i); 10680Sstevel@tonic-gate #endif 10690Sstevel@tonic-gate (void) putc('\n', fout); 10700Sstevel@tonic-gate } 10710Sstevel@tonic-gate (void) fprintf(fout, "0,\t0,\t0};\n"); 10720Sstevel@tonic-gate 10730Sstevel@tonic-gate /* put out yymatch */ 10740Sstevel@tonic-gate 10750Sstevel@tonic-gate (void) fprintf(fout, "struct yywork *yytop = yycrank+%d;\n", yytop); 10760Sstevel@tonic-gate (void) fprintf(fout, "struct yysvf *yybgin = yysvec+1;\n"); 10770Sstevel@tonic-gate if (optim) { 10780Sstevel@tonic-gate if (handleeuc) { 10790Sstevel@tonic-gate (void) fprintf(fout, "int yymatch[] = {\n"); 10800Sstevel@tonic-gate } else { 10810Sstevel@tonic-gate (void) fprintf(fout, "char yymatch[] = {\n"); 10820Sstevel@tonic-gate } 10830Sstevel@tonic-gate if (chset == 0) { /* no chset, put out in normal order */ 10840Sstevel@tonic-gate for (i = 0; i < ncg; i += 8) { 10850Sstevel@tonic-gate for (j = 0; j < 8; j++) { 10860Sstevel@tonic-gate int fbch; 10870Sstevel@tonic-gate fbch = match[i+j]; 10880Sstevel@tonic-gate fprintf(fout, "%3d, ", fbch); 10890Sstevel@tonic-gate } 10900Sstevel@tonic-gate (void) putc('\n', fout); 10910Sstevel@tonic-gate } 10920Sstevel@tonic-gate } else { 10930Sstevel@tonic-gate int *fbarr; 10940Sstevel@tonic-gate fbarr = (int *)myalloc(2*MAXNCG, sizeof (*fbarr)); 10950Sstevel@tonic-gate if (fbarr == 0) 10960Sstevel@tonic-gate error("No space for char table reverse", 0); 10970Sstevel@tonic-gate for (i = 0; i < MAXNCG; i++) 10980Sstevel@tonic-gate fbarr[i] = 0; 10990Sstevel@tonic-gate for (i = 0; i < ncg; i++) 11000Sstevel@tonic-gate fbarr[ctable[i]] = ctable[match[i]]; 11010Sstevel@tonic-gate for (i = 0; i < ncg; i += 8) { 11020Sstevel@tonic-gate for (j = 0; j < 8; j++) 11030Sstevel@tonic-gate fprintf(fout, "0%-3o,", fbarr[i+j]); 11040Sstevel@tonic-gate putc('\n', fout); 11050Sstevel@tonic-gate } 11060Sstevel@tonic-gate free(fbarr); 11070Sstevel@tonic-gate } 11080Sstevel@tonic-gate (void) fprintf(fout, "0};\n"); 11090Sstevel@tonic-gate } 11100Sstevel@tonic-gate /* put out yyextra */ 11110Sstevel@tonic-gate (void) fprintf(fout, "char yyextra[] = {\n"); 11120Sstevel@tonic-gate for (i = 0; i < casecount; i += 8) { 11130Sstevel@tonic-gate for (j = 0; j < 8; j++) 11140Sstevel@tonic-gate (void) fprintf(fout, "%d,", i+j < NACTIONS ? 1115*4538Sdamico extra[i+j] : 0); 11160Sstevel@tonic-gate (void) putc('\n', fout); 11170Sstevel@tonic-gate } 11180Sstevel@tonic-gate (void) fprintf(fout, "0};\n"); 11190Sstevel@tonic-gate if (handleeuc) { 11200Sstevel@tonic-gate /* Put out yycgidtbl */ 11210Sstevel@tonic-gate fprintf(fout, "#define YYNCGIDTBL %d\n", ncgidtbl); 11220Sstevel@tonic-gate fprintf(fout, "\tunsigned long yycgidtbl[]={"); 11230Sstevel@tonic-gate /* 11240Sstevel@tonic-gate * Use "unsigned long" instead of "lchar" to minimize 11250Sstevel@tonic-gate * the name-space polution for the application program. 11260Sstevel@tonic-gate */ 11270Sstevel@tonic-gate for (i = 0; i < ncgidtbl; ++i) { 11280Sstevel@tonic-gate if (i%8 == 0) 11290Sstevel@tonic-gate fprintf(fout, "\n\t\t"); 11300Sstevel@tonic-gate fprintf(fout, "0x%08x, ", yycgidtbl[i]); 11310Sstevel@tonic-gate } 11320Sstevel@tonic-gate fprintf(fout, "\n\t0};\n"); 11330Sstevel@tonic-gate } 11340Sstevel@tonic-gate } 11350Sstevel@tonic-gate 11360Sstevel@tonic-gate static void 11370Sstevel@tonic-gate rprint(int *a, char *s, int n) 11380Sstevel@tonic-gate { 11390Sstevel@tonic-gate int i; 11400Sstevel@tonic-gate (void) fprintf(fout, "block data\n"); 11410Sstevel@tonic-gate (void) fprintf(fout, "common /L%s/ %s\n", s, s); 11420Sstevel@tonic-gate (void) fprintf(fout, "define S%s %d\n", s, n); 11430Sstevel@tonic-gate (void) fprintf(fout, "integer %s (S%s)\n", s, s); 11440Sstevel@tonic-gate for (i = 1; i <= n; i++) { 11450Sstevel@tonic-gate if (i%8 == 1) 11460Sstevel@tonic-gate (void) fprintf(fout, "data "); 11470Sstevel@tonic-gate (void) fprintf(fout, "%s (%d)/%d/", s, i, a[i]); 11480Sstevel@tonic-gate (void) fprintf(fout, (i%8 && i < n) ? ", " : "\n"); 11490Sstevel@tonic-gate } 11500Sstevel@tonic-gate (void) fprintf(fout, "end\n"); 11510Sstevel@tonic-gate } 11520Sstevel@tonic-gate 11530Sstevel@tonic-gate static void 11540Sstevel@tonic-gate shiftr(int *a, int n) 11550Sstevel@tonic-gate { 11560Sstevel@tonic-gate int i; 11570Sstevel@tonic-gate for (i = n; i >= 0; i--) 11580Sstevel@tonic-gate a[i+1] = a[i]; 11590Sstevel@tonic-gate } 11600Sstevel@tonic-gate 11610Sstevel@tonic-gate static void 11620Sstevel@tonic-gate upone(int *a, int n) 11630Sstevel@tonic-gate { 11640Sstevel@tonic-gate int i; 11650Sstevel@tonic-gate for (i = 0; i <= n; i++) 11660Sstevel@tonic-gate a[i]++; 11670Sstevel@tonic-gate } 11680Sstevel@tonic-gate 11690Sstevel@tonic-gate static void 11700Sstevel@tonic-gate bprint(char *a, char *s, int n) 11710Sstevel@tonic-gate { 11720Sstevel@tonic-gate int i, j, k; 11730Sstevel@tonic-gate (void) fprintf(fout, "block data\n"); 11740Sstevel@tonic-gate (void) fprintf(fout, "common /L%s/ %s\n", s, s); 11750Sstevel@tonic-gate (void) fprintf(fout, "define S%s %d\n", s, n); 11760Sstevel@tonic-gate (void) fprintf(fout, "integer %s (S%s)\n", s, s); 11770Sstevel@tonic-gate for (i = 1; i < n; i += 8) { 11780Sstevel@tonic-gate (void) fprintf(fout, "data %s (%d)/%d/", s, i, a[i]); 11790Sstevel@tonic-gate for (j = 1; j < 8; j++) { 11800Sstevel@tonic-gate k = i+j; 11810Sstevel@tonic-gate if (k < n) 11820Sstevel@tonic-gate (void) fprintf(fout, 1183*4538Sdamico ", %s (%d)/%d/", s, k, a[k]); 11840Sstevel@tonic-gate } 11850Sstevel@tonic-gate (void) putc('\n', fout); 11860Sstevel@tonic-gate } 11870Sstevel@tonic-gate (void) fprintf(fout, "end\n"); 11880Sstevel@tonic-gate } 11890Sstevel@tonic-gate 11900Sstevel@tonic-gate #ifdef PP 11910Sstevel@tonic-gate static void 11920Sstevel@tonic-gate padd(int **array, int n) 11930Sstevel@tonic-gate { 11940Sstevel@tonic-gate int i, *j, k; 11950Sstevel@tonic-gate array[n] = nxtpos; 11960Sstevel@tonic-gate if (count == 0) { 11970Sstevel@tonic-gate *nxtpos++ = 0; 11980Sstevel@tonic-gate return; 11990Sstevel@tonic-gate } 12000Sstevel@tonic-gate for (i = tptr-1; i >= 0; i--) { 12010Sstevel@tonic-gate j = array[i]; 12020Sstevel@tonic-gate if (j && *j++ == count) { 12030Sstevel@tonic-gate for (k = 0; k < count; k++) 12040Sstevel@tonic-gate if (!tmpstat[*j++]) 12050Sstevel@tonic-gate break; 12060Sstevel@tonic-gate if (k >= count) { 12070Sstevel@tonic-gate array[n] = array[i]; 12080Sstevel@tonic-gate return; 12090Sstevel@tonic-gate } 12100Sstevel@tonic-gate } 12110Sstevel@tonic-gate } 12120Sstevel@tonic-gate add(array, n); 12130Sstevel@tonic-gate } 12140Sstevel@tonic-gate #endif 1215