/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#include "ldefs.h"
static void follow(int v);
static void first(int v);
static void nextstate(int s, int c);
static void acompute(int s);
static void rprint(int *a, char *s, int n);
static void shiftr(int *a, int n);
static void upone(int *a, int n);
static void bprint(char *a, char *s, int n);
static int notin(int n);
#ifdef PP
#endif
void
cfoll(int v)
{
int i, j, k;
CHR *p;
i = name[v];
if (!ISOPERATOR(i))
i = 1;
switch (i) {
for (j = 0; j < tptr; j++)
count = 0;
follow(v);
#ifdef PP
#else
#endif
if (i == RSTR)
for (j = 1; j < ncg; j++)
while (*p)
p = pcptr;
for (j = 1; j < ncg; j++)
if (symbol[j]) {
for (k = 0; p + k < pcptr; k++)
if (cindex[j] ==
*(p + k))
break;
if (p + k >= pcptr)
}
*pcptr++ = 0;
"Too many packed character classes");
left[v] = (int)p;
#ifdef DEBUG
if (debug && *p) {
(void) printf("ccl %d: %d", v, *p++);
while (*p)
(void) printf(", %d", *p++);
(void) putchar('\n');
}
#endif
}
break;
case CARAT:
break;
/* XCU4: add RXSCON */
case RXSCON:
break;
break;
#ifdef DEBUG
case FINAL:
case S1FINAL:
case S2FINAL:
break;
default:
warning("bad switch cfoll %d", v);
#endif
}
}
#ifdef DEBUG
void
pfoll(void)
{
int i, k, *p;
int j;
/* print sets of chars which may follow positions */
(void) printf("pos\tchars\n");
for (i = 0; i < tptr; i++)
if (p = foll[i]) {
j = *p++;
if (j >= 1) {
(void) printf("%d:\t%d", i, *p++);
for (k = 2; k <= j; k++)
(void) printf(", %d", *p++);
(void) putchar('\n');
}
}
}
#endif
static void
{
int i, *temp;
for (i = 0; i < tptr; i++)
*temp++ = i;
"Too many positions %s",
}
static void
follow(int v)
{
int p;
if (v >= tptr-1)
return;
p = parent[v];
if (p == 0)
return;
switch (name[p]) {
/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
case RSTR:
count++;
}
break;
first(v);
follow(p);
break;
follow(p);
break;
if (v == left[p]) {
follow(p);
}
else
follow(p);
break;
/* XCU4: add RXSCON */
case RXSCON:
follow(p);
break;
#ifdef DEBUG
default:
warning("bad switch follow %d", p);
#endif
}
}
/*
* Check if I have a RXSCON in my upper node
*/
static int
check_me(int v)
{
return (1);
}
return (0);
}
/* calculate set of positions with v as root which can be active initially */
static void
first(int v)
{
int i;
CHR *p;
i = name[v];
if (!ISOPERATOR(i))
i = 1;
switch (i) {
/*
* XCU4: if we are working on an exclusive start state and
* the parent of this position is not RXSCON or RSTR this
* is not an active position.
*
* (There is a possibility that RSXCON appreas as the
* (parent)* node. Check it by check_me().)
*/
(check_me(v) == 0)) {
break;
}
count++;
}
break;
break;
case CARAT:
break;
/* XCU4: add RXSCON */
case RXSCON:
case RSCON:
while (*p)
if (*p++ == i) {
break;
}
break;
/*
* XCU4: if we are working on an exclusive start state and
* the parent of this position is not RXSCON or RSTR this
* is not an active position.
*
* (There is a possibility that RSXCON appreas as the
* (parent)* node. Check it by check_me().)
*/
(check_me(v) == 0)) {
break;
}
break;
break;
#ifdef DEBUG
default:
warning("bad switch first %d", v);
#endif
}
}
void
cgoto(void)
{
int i, j;
static int s;
int tryit;
CHR *q;
/* generate initial state, for each start condition */
if (ratfor) {
} else
for (i = 0; i < tptr; i++)
tmpstat[i] = 0;
count = 0;
if (tptr > 0)
#ifdef DEBUG
if (debug) {
if (stnum > 1)
}
#endif
stnum++;
}
stnum--;
/* even stnum = might not be at line begin */
/* odd stnum = must be at line begin */
/* even states can occur anywhere, odd states only at line begin */
for (s = 0; s <= stnum; s++) {
sfall[s] = -1;
acompute(s);
for (i = 0; i < ncg; i++)
symbol[i] = 0;
for (i = 1; i <= npos; i++) {
else {
case RCCL:
while (*q) {
for (j = 1; j < ncg; j++)
if (cindex[j] == *q)
symbol[j] =
TRUE;
q++;
}
break;
case RSTR:
break;
#ifdef DEBUG
case RNULLS:
case FINAL:
case S1FINAL:
case S2FINAL:
break;
default:
"bad switch cgoto %d state %d",
curpos, s);
break;
#endif
}
}
}
#ifdef DEBUG
if (debug) {
printf("State %d transitions on char-group {", s);
charc = 0;
for (i = 1; i < ncg; i++) {
if (symbol[i]) {
printf("%d,", i);
}
if (i == ncg-1)
printf("}\n");
charc = 0;
printf("\n\t");
}
}
}
#endif
/* for each char, calculate next state */
n = 0;
for (i = 1; i < ncg; i++) {
if (symbol[i]) {
/* executed for each state, transition pair */
nextstate(s, i);
if (xstate == -2)
warning("bad state %d %o", s, i);
else if (xstate == -1) {
stnum++;
error("Too many states %s",
"\nTry using %n num":""));
}
#ifdef DEBUG
if (debug)
#endif
tch[n] = i;
} else { /* xstate >= 0 ==> state exists */
tch[n] = i;
}
}
}
tch[n] = 0;
tst[n] = -1;
/* pack transitions into permanent array */
if (n > 0)
else
gotof[s] = -1;
}
}
/*
* Beware -- 70% of total CPU time is spent in this subroutine -
* if you don't believe me - try it yourself !
*/
static void
nextstate(int s, int c)
{
int j, *newpos;
/* state to goto from state s on char c */
for (i = 0; i < num; i++) {
if ((!ISOPERATOR(j)) && j == c ||
number = *f;
newpos = f+1;
for (j = 0; j < number; j++)
}
}
j = 0;
if (*temp == 2) {
j++;
*temp++ = 1;
}
else
*temp++ = 0;
}
count = j;
}
static int
notin(int n)
{ /* see if tmpstat occurs previously */
int *j, k;
int i;
if (count == 0)
return (-2);
for (i = n; i >= 0; i--) { /* for each state */
j = state[i];
if (count == *j++) {
for (k = 0; k < count; k++)
if (!temp[*j++])
break;
if (k >= count)
return (i);
}
}
return (-1);
}
static void
{
/*
* pack transitions into nchar, nexts
* nchar is terminated by '\0', nexts uses cnt, followed by elements
* gotof[st] = index into nchr, nexts for state st
* sfall[st] = t implies t is fall back state for st
* == -1 implies no fall back
*/
int i, j, k;
int upper;
cmin = -1;
/* try to pack transitions using ccl's */
if (!optim)
goto nopack; /* skip all compaction */
if (tryit) { /* ccl's used */
for (i = 1; i < ncg; i++) {
symbol[i] = 1;
}
for (i = 0; i < cnt; i++) {
} else {
"lex`sub2`packtran: tch[%d] out of bounds (%d)\n",
i, (int)tch[i]);
}
}
for (i = 0; i < cnt; i++) {
}
/* fill in error entries */
for (i = 1; i < ncg; i++)
if (symbol[i])
/* count them */
k = 0;
for (i = 1; i < ncg; i++)
if (temp[i] != -1)
k++;
if (k < cnt) { /* compress by char */
#ifdef DEBUG
if (debug)
(void) printf(
#endif
k = 0;
for (i = 1; i < ncg; i++)
if (temp[i] != -1) {
cwork[k] = i;
swork[k++] =
}
cwork[k] = 0;
#ifdef PC
cnt = k;
#endif
}
}
/*
* get most similar state
* reject state with more transitions,
* state already represented by a third state,
* and state which is compressed by char if ours is not to be
*/
for (i = 0; i < st; i++) {
if (sfall[i] != -1)
continue;
if (!(cpackflg[i] == 1))
continue;
p = gotof[i];
if (p == -1) /* no transitions */
continue;
continue;
diff = 0;
k = 0;
j = 0;
diff++;
j++;
}
if (ach[j] == 0)
break;
break;
}
/* ach[j] == nchar[p] */
ast[j] == -1 ||
diff++;
j++;
}
while (ach[j]) {
diff++;
j++;
}
if (p < upper)
cmin = i;
if (cval == 0)
break;
}
}
/* cmin = state "most like" state st */
#ifdef DEBUG
if (debug)
(void) printf("select st %d for st %d diff %d\n",
#endif
#ifdef PS
k = 0;
j = 0;
while (ach[j]) {
/* if cmin has a transition on c, then so will st */
/* st may be "larger" than cmin, however */
k++;
j++;
}
if (nchar[p-1] == 0)
break;
goto nopack;
}
/* ach[j] == nchar[p-1] */
ast[j] == -1 ||
k++;
}
p++;
j++;
}
while (ach[j]) {
k++;
}
} else {
#endif
/* stick it in */
for (i = 0; i < cnt; i++) {
}
#ifdef PS
}
#endif
if (cnt < 1) {
nptr--;
} else
"Too many transitions %s",
}
#ifdef DEBUG
void
pstate(int s)
{
int *p, i, j;
(void) printf("State %d:\n", s);
p = state[s];
i = *p++;
if (i == 0)
return;
(void) printf("%4d", *p++);
for (j = 1; j < i; j++) {
(void) printf(", %4d", *p++);
if (j%30 == 0)
(void) putchar('\n');
}
(void) putchar('\n');
}
#endif
static int
{
int c;
CHR *s;
c = d;
s = t;
c = cindex[c];
while (*s)
if (*s++ == c)
return (1);
return (0);
}
#ifdef DEBUG
void
stprt(int i)
{
int p, t;
(void) printf("State %d:", i);
/* print actions, if any */
t = atable[i];
if (t != -1)
(void) printf(" final");
(void) putchar('\n');
(void) printf("backup char in use\n");
if (sfall[i] != -1)
p = gotof[i];
if (p == -1)
return;
while (nchar[p]) {
charc = 0;
if (nexts[p+1] >= 0)
else
(void) printf("err\t");
charc = 0;
(void) printf("\n\t");
}
}
(void) putchar('\n');
}
(void) putchar('\n');
}
#endif
/* compute action list = set of poss. actions */
static void
acompute(int s)
{
int *p, i, j;
int q, r;
int cnt, m;
k = 0;
n = 0;
p = state[s];
cnt = *p++;
if (cnt > MAXPOSSTATE)
error("Too many positions for one state - acompute");
for (i = 0; i < cnt; i++) {
q = *p;
"INTERNAL ERROR:left[%d]==%d>=NACTIONS", q, r);
extra[r] = 1;
p++;
}
atable[s] = -1;
if (k < 1 && n < 1)
return;
#ifdef DEBUG
if (debug)
(void) printf("final %d actions:", s);
#endif
/* sort action list */
for (i = 0; i < k; i++)
for (j = i+1; j < k; j++)
m = temp[j];
temp[i] = m;
}
/* remove dups */
for (i = 0; i < k-1; i++)
temp[i] = 0;
/* copy to permanent quarters */
#ifdef DEBUG
if (!ratfor)
#endif
for (i = 0; i < k; i++)
if (temp[i] != 0) {
(void) (ratfor ?
#ifdef DEBUG
if (debug)
#endif
aptr++;
}
for (i = 0; i < n; i++) { /* copy fall back actions - all neg */
ratfor ?
aptr++;
#ifdef DEBUG
if (debug)
#endif
}
#ifdef DEBUG
if (debug)
(void) putchar('\n');
#endif
aptr++;
}
#ifdef DEBUG
void
pccl(void)
{
/* print character class sets */
int i, j;
(void) printf("char class intersection\n");
for (i = 0; i < ccount; i++) {
charc = 0;
(void) printf("class %d:\n\t", i);
for (j = 1; j < ncg; j++)
if (cindex[j] == i) {
allprint(j);
(void) printf("\n\t");
charc = 0;
}
}
(void) putchar('\n');
}
charc = 0;
(void) printf("match:\n");
for (i = 0; i < ncg; i++) {
(void) putchar('\n');
charc = 0;
}
}
(void) putchar('\n');
}
#endif
void
mkmatch(void)
{
int i;
for (i = 0; i < ccount; i++)
tab[i] = 0;
for (i = 1; i < ncg; i++)
/* tab[i] = principal char for new ccl i */
for (i = 1; i < ncg; i++)
}
void
layout(void)
{
/* format and output final program's tables */
int i, j, k;
startup = 0;
for (i = 0; i < outsize; i++)
omin = 0;
yytop = 0;
for (i = 0; i <= stnum; i++) { /* for each state */
j = gotof[i];
if (j == -1) {
stoff[i] = 0;
continue;
}
bot = j;
while (nchar[j])
j++;
top = j - 1;
#if DEBUG
if (debug) {
(void) printf("State %d: (layout)\n", i);
if (j % 10 == 0)
(void) putchar('\n');
}
(void) putchar('\n');
}
#endif
omin++;
#if DEBUG
if (debug)
(void) printf(
"bot,top %d, %d startup begins %d\n",
#endif
if (chset) {
do {
startup += 1;
error("output table overflow");
if (verify[k])
break;
}
} while (j <= top);
#if DEBUG
if (debug)
(void) printf(" startup will be %d\n",
startup);
#endif
/* have found place */
(void) printf(
"j %d nchar %d ctable.nch %d\n",
if (yytop < k)
yytop = k;
}
} else {
do {
startup += 1;
error("output table overflow");
if (verify[k])
break;
}
} while (j <= top);
/* have found place */
#if DEBUG
if (debug)
#endif
if (yytop < k)
yytop = k;
}
}
}
/* stoff[i] = offset into verify, advance for trans for state i */
/* put out yywork */
if (ratfor) {
}
"struct yywork { YYTYPE verify, advance; } yycrank[] = {\n");
for (i = 0; i <= yytop; i += 4) {
for (j = 0; j < 4; j++) {
k = i+j;
if (verify[k])
else
}
}
/* put out yysvec */
for (i = 0; i <= stnum; i++) { /* for each state */
if (cpackflg[i])
if (sfall[i] != -1)
else
if (atable[i] != -1)
else
#ifdef DEBUG
#endif
}
/* put out yymatch */
if (optim) {
if (handleeuc) {
} else {
}
if (chset == 0) { /* no chset, put out in normal order */
for (i = 0; i < ncg; i += 8) {
for (j = 0; j < 8; j++) {
int fbch;
}
}
} else {
int *fbarr;
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
if (fbarr == 0)
error("No space for char table reverse", 0);
for (i = 0; i < MAXNCG; i++)
fbarr[i] = 0;
for (i = 0; i < ncg; i++)
for (i = 0; i < ncg; i += 8) {
for (j = 0; j < 8; j++)
fbarr[i+j]);
}
}
}
/* put out yyextra */
for (i = 0; i < casecount; i += 8) {
for (j = 0; j < 8; j++)
extra[i+j] : 0);
}
if (handleeuc) {
/* Put out yycgidtbl */
/*
* Use "unsigned long" instead of "lchar" to minimize
* the name-space polution for the application program.
*/
for (i = 0; i < ncgidtbl; ++i) {
if (i%8 == 0)
}
}
}
static void
rprint(int *a, char *s, int n)
{
int i;
for (i = 1; i <= n; i++) {
if (i%8 == 1)
}
}
static void
shiftr(int *a, int n)
{
int i;
for (i = n; i >= 0; i--)
a[i+1] = a[i];
}
static void
upone(int *a, int n)
{
int i;
for (i = 0; i <= n; i++)
a[i]++;
}
static void
bprint(char *a, char *s, int n)
{
int i, j, k;
for (i = 1; i < n; i += 8) {
for (j = 1; j < 8; j++) {
k = i+j;
if (k < n)
", %s (%d)/%d/", s, k, a[k]);
}
}
}
#ifdef PP
static void
{
int i, *j, k;
if (count == 0) {
*nxtpos++ = 0;
return;
}
for (i = tptr-1; i >= 0; i--) {
j = array[i];
if (j && *j++ == count) {
for (k = 0; k < count; k++)
if (!tmpstat[*j++])
break;
if (k >= count) {
return;
}
}
}
}
#endif