4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
29 #pragma ident "%Z%%M% %I% %E% SMI"
33 static void add(int **array
, int n
);
34 static void follow(int v
);
35 static void first(int v
);
36 static void nextstate(int s
, int c
);
37 static void packtrans(int st
, CHR
*tch
, int *tst
, int cnt
, int tryit
);
38 static void acompute(int s
);
39 static void rprint(int *a
, char *s
, int n
);
40 static void shiftr(int *a
, int n
);
41 static void upone(int *a
, int n
);
42 static void bprint(char *a
, char *s
, int n
);
43 static int notin(int n
);
44 static int member(int d
, CHR
*t
);
47 static void padd(int **array
, int n
);
59 case 1: case RSTR
: case RCCL
: case RNCCL
: case RNULLS
:
60 for (j
= 0; j
< tptr
; j
++)
65 padd(foll
, v
); /* packing version */
67 add(foll
, v
); /* no packing version */
71 else if (i
== RCCL
|| i
== RNCCL
) {
72 for (j
= 1; j
< ncg
; j
++)
73 symbol
[j
] = (i
== RNCCL
);
76 symbol
[*p
++] = (i
== RCCL
);
78 for (j
= 1; j
< ncg
; j
++)
80 for (k
= 0; p
+ k
< pcptr
; k
++)
88 if (pcptr
> pchar
+ pchlen
)
90 "Too many packed character classes");
92 name
[v
] = RCCL
; /* RNCCL eliminated */
95 (void) printf("ccl %d: %d", v
, *p
++);
97 (void) printf(", %d", *p
++);
107 /* XCU4: add RXSCON */
110 case STAR
: case PLUS
: case QUEST
: case RSCON
:
113 case BAR
: case RCAT
: case DIV
: case RNEWE
:
123 warning("bad switch cfoll %d", v
);
134 /* print sets of chars which may follow positions */
135 (void) printf("pos\tchars\n");
136 for (i
= 0; i
< tptr
; i
++)
140 (void) printf("%d:\t%d", i
, *p
++);
141 for (k
= 2; k
<= j
; k
++)
142 (void) printf(", %d", *p
++);
143 (void) putchar('\n');
150 add(int **array
, int n
)
156 array
[n
] = nxtpos
; /* note no packing is done in positions */
158 for (i
= 0; i
< tptr
; i
++)
159 if (ctemp
[i
] == TRUE
)
162 if (nxtpos
>= positions
+maxpos
)
164 "Too many positions %s",
165 (maxpos
== MAXPOS
? "\nTry using %p num" : ""));
178 /* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
180 if (tmpstat
[p
] == FALSE
) {
185 case STAR
: case PLUS
:
189 case BAR
: case QUEST
: case RNEWE
:
194 if (nullstr
[right
[p
]])
201 /* XCU4: add RXSCON */
203 case RSCON
: case CARAT
:
208 warning("bad switch follow %d", p
);
214 * Check if I have a RXSCON in my upper node
221 while (name
[tmp
] != RNEWE
) {
222 if (name
[tmp
] == RXSCON
)
229 /* calculate set of positions with v as root which can be active initially */
239 case 1: case RCCL
: case RNCCL
:
240 case RNULLS
: case FINAL
:
241 case S1FINAL
: case S2FINAL
:
243 * XCU4: if we are working on an exclusive start state and
244 * the parent of this position is not RXSCON or RSTR this
245 * is not an active position.
247 * (There is a possibility that RSXCON appreas as the
248 * (parent)* node. Check it by check_me().)
250 if ((exclusive
[stnum
/2]) &&
251 ISOPERATOR(name
[parent
[v
]]) &&
252 (name
[parent
[v
]] != RXSCON
) &&
253 (name
[parent
[v
]] != RSTR
) &&
254 (check_me(v
) == 0)) {
257 if (tmpstat
[v
] == FALSE
) {
262 case BAR
: case RNEWE
:
270 /* XCU4: add RXSCON */
274 p
= (CHR
*) right
[v
];
281 case STAR
: case QUEST
:
282 case PLUS
: case RSTR
:
284 * XCU4: if we are working on an exclusive start state and
285 * the parent of this position is not RXSCON or RSTR this
286 * is not an active position.
288 * (There is a possibility that RSXCON appreas as the
289 * (parent)* node. Check it by check_me().)
291 if ((exclusive
[stnum
/2]) &&
292 ISOPERATOR(name
[parent
[v
]]) &&
293 (name
[parent
[v
]] != RXSCON
) &&
294 (name
[parent
[v
]] != RSTR
) &&
295 (check_me(v
) == 0)) {
302 if (nullstr
[left
[v
]])
307 warning("bad switch first %d", v
);
322 /* generate initial state, for each start condition */
324 (void) fprintf(fout
, "blockdata\n");
325 (void) fprintf(fout
, "common /Lvstop/ vstop\n");
326 (void) fprintf(fout
, "define Svstop %d\n", nstates
+1);
327 (void) fprintf(fout
, "integer vstop(Svstop)\n");
329 (void) fprintf(fout
, "int yyvstop[] = {\n0,\n");
330 while (stnum
< 2 || stnum
/2 < sptr
) {
331 for (i
= 0; i
< tptr
; i
++)
340 (void) printf("%ws:\n", sname
[stnum
/2]);
347 /* even stnum = might not be at line begin */
348 /* odd stnum = must be at line begin */
349 /* even states can occur anywhere, odd states only at line begin */
350 for (s
= 0; s
<= stnum
; s
++) {
355 for (i
= 0; i
< ncg
; i
++)
358 for (i
= 1; i
<= npos
; i
++) {
359 curpos
= *(state
[s
]+i
);
360 if (!ISOPERATOR(name
[curpos
]))
361 symbol
[name
[curpos
]] = TRUE
;
363 switch (name
[curpos
]) {
366 q
= (CHR
*)left
[curpos
];
368 for (j
= 1; j
< ncg
; j
++)
376 symbol
[right
[curpos
]] = TRUE
;
386 "bad switch cgoto %d state %d",
395 printf("State %d transitions on char-group {", s
);
397 for (i
= 1; i
< ncg
; i
++) {
403 if (charc
> LINESIZE
/4) {
410 /* for each char, calculate next state */
412 for (i
= 1; i
< ncg
; i
++) {
414 /* executed for each state, transition pair */
416 xstate
= notin(stnum
);
418 warning("bad state %d %o", s
, i
);
419 else if (xstate
== -1) {
420 if (stnum
+1 >= nstates
) {
422 error("Too many states %s",
423 (nstates
== NSTATES
?
424 "\nTry using %n num":""));
433 } else { /* xstate >= 0 ==> state exists */
441 /* pack transitions into permanent array */
443 packtrans(s
, tch
, tst
, n
, tryit
);
447 (void) (ratfor
? fprintf(fout
, "end\n") : fprintf(fout
, "0};\n"));
451 * Beware -- 70% of total CPU time is spent in this subroutine -
452 * if you don't believe me - try it yourself !
455 nextstate(int s
, int c
)
459 int *pos
, i
, *f
, num
, curpos
, number
;
460 /* state to goto from state s on char c */
464 for (i
= 0; i
< num
; i
++) {
467 if ((!ISOPERATOR(j
)) && j
== c
||
468 j
== RSTR
&& c
== right
[curpos
] ||
469 j
== RCCL
&& member(c
, (CHR
*) left
[curpos
])) {
473 for (j
= 0; j
< number
; j
++)
492 { /* see if tmpstat occurs previously */
499 for (i
= n
; i
>= 0; i
--) { /* for each state */
502 for (k
= 0; k
< count
; k
++)
513 packtrans(int st
, CHR
*tch
, int *tst
, int cnt
, int tryit
)
516 * pack transitions into nchar, nexts
517 * nchar is terminated by '\0', nexts uses cnt, followed by elements
518 * gotof[st] = index into nchr, nexts for state st
519 * sfall[st] = t implies t is fall back state for st
520 * == -1 implies no fall back
523 int cmin
, cval
, tcnt
, diff
, p
, *ast
;
526 int go
[MAXNCG
], temp
[MAXNCG
], index
, c
;
536 /* try to pack transitions using ccl's */
538 goto nopack
; /* skip all compaction */
539 if (tryit
) { /* ccl's used */
540 for (i
= 1; i
< ncg
; i
++) {
541 go
[i
] = temp
[i
] = -1;
544 for (i
= 0; i
< cnt
; i
++) {
545 index
= (unsigned char) tch
[i
];
546 if ((index
>= 0) && (index
< NCH
)) {
550 (void) fprintf(stderr
,
551 "lex`sub2`packtran: tch[%d] out of bounds (%d)\n",
555 for (i
= 0; i
< cnt
; i
++) {
557 if (go
[c
] != tst
[i
] || c
== tch
[i
])
558 temp
[tch
[i
]] = tst
[i
];
560 /* fill in error entries */
561 for (i
= 1; i
< ncg
; i
++)
563 temp
[i
] = -2; /* error trans */
566 for (i
= 1; i
< ncg
; i
++)
569 if (k
< cnt
) { /* compress by char */
573 "use compression %d, %d vs %d\n", st
, k
, cnt
);
576 for (i
= 1; i
< ncg
; i
++)
580 (temp
[i
] == -2 ? -1 : temp
[i
]);
592 * get most similar state
593 * reject state with more transitions,
594 * state already represented by a third state,
595 * and state which is compressed by char if ours is not to be
597 for (i
= 0; i
< st
; i
++) {
600 if (cpackflg
[st
] == 1)
601 if (!(cpackflg
[i
] == 1))
604 if (p
== -1) /* no transitions */
613 while (ach
[j
] && p
< upper
) {
614 while (ach
[j
] < nchar
[p
] && ach
[j
]) {
620 if (ach
[j
] > nchar
[p
]) {
624 /* ach[j] == nchar[p] */
625 if (ast
[j
] != nexts
[++p
] ||
627 (cpackflg
[st
] && ach
[j
] != match
[ach
[j
]]))
637 if (diff
< cval
&& diff
< tcnt
) {
644 /* cmin = state "most like" state st */
647 (void) printf("select st %d for st %d diff %d\n",
651 if (cmin
!= -1) { /* if we can use st cmin */
658 /* if cmin has a transition on c, then so will st */
659 /* st may be "larger" than cmin, however */
660 while (ach
[j
] < nchar
[p
-1] && ach
[j
]) {
662 nchar
[nptr
] = ach
[j
];
663 nexts
[++nptr
] = ast
[j
];
668 if (ach
[j
] > nchar
[p
-1]) {
669 warning("bad transition %d %d", st
, cmin
);
672 /* ach[j] == nchar[p-1] */
673 if (ast
[j
] != nexts
[p
] ||
675 (cpackflg
[st
] && ach
[j
] != match
[ach
[j
]])) {
677 nchar
[nptr
] = ach
[j
];
678 nexts
[++nptr
] = ast
[j
];
684 nchar
[nptr
] = ach
[j
];
685 nexts
[++nptr
] = ast
[j
++];
688 nexts
[gotof
[st
]] = cnt
= k
;
696 for (i
= 0; i
< cnt
; i
++) {
697 nchar
[nptr
] = ach
[i
];
698 nexts
[++nptr
] = ast
[i
];
710 "Too many transitions %s",
711 (ntrans
== NTRANS
? "\nTry using %a num" : ""));
719 (void) printf("State %d:\n", s
);
724 (void) printf("%4d", *p
++);
725 for (j
= 1; j
< i
; j
++) {
726 (void) printf(", %4d", *p
++);
728 (void) putchar('\n');
730 (void) putchar('\n');
735 member(int d
, CHR
*t
)
753 (void) printf("State %d:", i
);
754 /* print actions, if any */
757 (void) printf(" final");
758 (void) putchar('\n');
759 if (cpackflg
[i
] == TRUE
)
760 (void) printf("backup char in use\n");
762 (void) printf("fall back state %d\n", sfall
[i
]);
766 (void) printf("(%d transitions)\n", nexts
[p
]);
770 (void) printf("%d\t", nexts
[p
+1]);
772 (void) printf("err\t");
773 allprint(nchar
[p
++]);
774 while (nexts
[p
] == nexts
[p
+1] && nchar
[p
]) {
775 if (charc
> LINESIZE
) {
777 (void) printf("\n\t");
779 allprint(nchar
[p
++]);
781 (void) putchar('\n');
783 (void) putchar('\n');
787 /* compute action list = set of poss. actions */
794 int temp
[MAXPOSSTATE
], k
, neg
[MAXPOSSTATE
], n
;
799 if (cnt
> MAXPOSSTATE
)
800 error("Too many positions for one state - acompute");
801 for (i
= 0; i
< cnt
; i
++) {
803 if (name
[q
] == FINAL
)
805 else if (name
[q
] == S1FINAL
) {
807 if ((r
= left
[q
]) >= NACTIONS
)
809 "INTERNAL ERROR:left[%d]==%d>=NACTIONS", q
, r
);
811 } else if (name
[q
] == S2FINAL
)
820 (void) printf("final %d actions:", s
);
822 /* sort action list */
823 for (i
= 0; i
< k
; i
++)
824 for (j
= i
+1; j
< k
; j
++)
825 if (temp
[j
] < temp
[i
]) {
831 for (i
= 0; i
< k
-1; i
++)
832 if (temp
[i
] == temp
[i
+1])
834 /* copy to permanent quarters */
838 (void) fprintf(fout
, "/* actions for state %d */", s
);
840 (void) putc('\n', fout
);
841 for (i
= 0; i
< k
; i
++)
844 fprintf(fout
, "data vstop(%d)/%d/\n",
846 fprintf(fout
, "%d,\n", temp
[i
]));
849 (void) printf("%d ", temp
[i
]);
853 for (i
= 0; i
< n
; i
++) { /* copy fall back actions - all neg */
855 (void) fprintf(fout
, "data vstop(%d)/%d/\n", aptr
, neg
[i
]) :
856 (void) fprintf(fout
, "%d,\n", neg
[i
]);
860 (void) printf("%d ", neg
[i
]);
865 (void) putchar('\n');
867 (void) (ratfor
? fprintf(fout
, "data vstop (%d)/0/\n", aptr
) :
868 fprintf(fout
, "0, \n"));
876 /* print character class sets */
878 (void) printf("char class intersection\n");
879 for (i
= 0; i
< ccount
; i
++) {
881 (void) printf("class %d:\n\t", i
);
882 for (j
= 1; j
< ncg
; j
++)
883 if (cindex
[j
] == i
) {
885 if (charc
> LINESIZE
) {
886 (void) printf("\n\t");
890 (void) putchar('\n');
893 (void) printf("match:\n");
894 for (i
= 0; i
< ncg
; i
++) {
896 if (charc
> LINESIZE
) {
897 (void) putchar('\n');
901 (void) putchar('\n');
910 for (i
= 0; i
< ccount
; i
++)
912 for (i
= 1; i
< ncg
; i
++)
913 if (tab
[cindex
[i
]] == 0)
915 /* tab[i] = principal char for new ccl i */
916 for (i
= 1; i
< ncg
; i
++)
917 match
[i
] = tab
[cindex
[i
]];
923 /* format and output final program's tables */
925 int top
, bot
, startup
, omin
;
927 for (i
= 0; i
< outsize
; i
++)
928 verify
[i
] = advance
[i
] = 0;
931 for (i
= 0; i
<= stnum
; i
++) { /* for each state */
943 (void) printf("State %d: (layout)\n", i
);
944 for (j
= bot
; j
<= top
; j
++) {
945 (void) printf(" %o", nchar
[j
]);
947 (void) putchar('\n');
949 (void) putchar('\n');
952 while (verify
[omin
+ZCH
])
958 "bot,top %d, %d startup begins %d\n",
964 if (startup
> outsize
- ZCH
)
965 error("output table overflow");
966 for (j
= bot
; j
<= top
; j
++) {
967 k
= startup
+ctable
[nchar
[j
]];
974 (void) printf(" startup will be %d\n",
977 /* have found place */
978 for (j
= bot
; j
<= top
; j
++) {
979 k
= startup
+ ctable
[nchar
[j
]];
980 if (ctable
[nchar
[j
]] <= 0)
982 "j %d nchar %d ctable.nch %d\n",
983 j
, (int)nchar
[j
], ctable
[nchar
[k
]]);
984 verify
[k
] = i
+ 1; /* state number + 1 */
985 advance
[k
] = nexts
[j
+1]+1;
992 if (startup
> outsize
- ZCH
)
993 error("output table overflow");
994 for (j
= bot
; j
<= top
; j
++) {
995 k
= startup
+ nchar
[j
];
1000 /* have found place */
1003 (void) printf(" startup going to be %d\n", startup
);
1005 for (j
= bot
; j
<= top
; j
++) {
1006 k
= startup
+ nchar
[j
];
1007 verify
[k
] = i
+1; /* state number + 1 */
1008 advance
[k
] = nexts
[j
+1] + 1;
1016 /* stoff[i] = offset into verify, advance for trans for state i */
1017 /* put out yywork */
1019 (void) fprintf(fout
, "define YYTOPVAL %d\n", yytop
);
1020 rprint(verify
, "verif", yytop
+1);
1021 rprint(advance
, "advan", yytop
+1);
1022 shiftr(stoff
, stnum
);
1023 rprint(stoff
, "stoff", stnum
+1);
1024 shiftr(sfall
, stnum
);
1025 upone(sfall
, stnum
+1);
1026 rprint(sfall
, "fall", stnum
+1);
1027 bprint(extra
, "extra", casecount
+1);
1028 bprint((char *)match
, "match", ncg
);
1029 shiftr(atable
, stnum
);
1030 rprint(atable
, "atable", stnum
+1);
1032 (void) fprintf(fout
,
1033 "# define YYTYPE %s\n", stnum
+1 >= NCH
? "int" : "unsigned char");
1034 (void) fprintf(fout
,
1035 "struct yywork { YYTYPE verify, advance; } yycrank[] = {\n");
1036 for (i
= 0; i
<= yytop
; i
+= 4) {
1037 for (j
= 0; j
< 4; j
++) {
1040 (void) fprintf(fout
,
1041 "%d,%d,\t", verify
[k
], advance
[k
]);
1043 (void) fprintf(fout
, "0,0,\t");
1045 (void) putc('\n', fout
);
1047 (void) fprintf(fout
, "0,0};\n");
1049 /* put out yysvec */
1051 (void) fprintf(fout
, "struct yysvf yysvec[] = {\n");
1052 (void) fprintf(fout
, "0,\t0,\t0,\n");
1053 for (i
= 0; i
<= stnum
; i
++) { /* for each state */
1055 stoff
[i
] = -stoff
[i
];
1056 (void) fprintf(fout
, "yycrank+%d,\t", stoff
[i
]);
1058 (void) fprintf(fout
,
1059 "yysvec+%d,\t", sfall
[i
]+1); /* state + 1 */
1061 (void) fprintf(fout
, "0,\t\t");
1062 if (atable
[i
] != -1)
1063 (void) fprintf(fout
, "yyvstop+%d,", atable
[i
]);
1065 (void) fprintf(fout
, "0,\t");
1067 (void) fprintf(fout
, "\t\t/* state %d */", i
);
1069 (void) putc('\n', fout
);
1071 (void) fprintf(fout
, "0,\t0,\t0};\n");
1073 /* put out yymatch */
1075 (void) fprintf(fout
, "struct yywork *yytop = yycrank+%d;\n", yytop
);
1076 (void) fprintf(fout
, "struct yysvf *yybgin = yysvec+1;\n");
1079 (void) fprintf(fout
, "int yymatch[] = {\n");
1081 (void) fprintf(fout
, "char yymatch[] = {\n");
1083 if (chset
== 0) { /* no chset, put out in normal order */
1084 for (i
= 0; i
< ncg
; i
+= 8) {
1085 for (j
= 0; j
< 8; j
++) {
1088 (void) fprintf(fout
, "%3d, ", fbch
);
1090 (void) putc('\n', fout
);
1094 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
1095 fbarr
= (int *)myalloc(2*MAXNCG
, sizeof (*fbarr
));
1097 error("No space for char table reverse", 0);
1098 for (i
= 0; i
< MAXNCG
; i
++)
1100 for (i
= 0; i
< ncg
; i
++)
1101 fbarr
[ctable
[i
]] = ctable
[match
[i
]];
1102 for (i
= 0; i
< ncg
; i
+= 8) {
1103 for (j
= 0; j
< 8; j
++)
1104 (void) fprintf(fout
, "0%-3o,",
1106 (void) putc('\n', fout
);
1110 (void) fprintf(fout
, "0};\n");
1112 /* put out yyextra */
1113 (void) fprintf(fout
, "char yyextra[] = {\n");
1114 for (i
= 0; i
< casecount
; i
+= 8) {
1115 for (j
= 0; j
< 8; j
++)
1116 (void) fprintf(fout
, "%d,", i
+j
< NACTIONS
?
1118 (void) putc('\n', fout
);
1120 (void) fprintf(fout
, "0};\n");
1122 /* Put out yycgidtbl */
1123 (void) fprintf(fout
, "#define YYNCGIDTBL %d\n", ncgidtbl
);
1124 (void) fprintf(fout
, "\tunsigned long yycgidtbl[]={");
1126 * Use "unsigned long" instead of "lchar" to minimize
1127 * the name-space polution for the application program.
1129 for (i
= 0; i
< ncgidtbl
; ++i
) {
1131 (void) fprintf(fout
, "\n\t\t");
1132 (void) fprintf(fout
, "0x%08x, ", (int)yycgidtbl
[i
]);
1134 (void) fprintf(fout
, "\n\t0};\n");
1139 rprint(int *a
, char *s
, int n
)
1142 (void) fprintf(fout
, "block data\n");
1143 (void) fprintf(fout
, "common /L%s/ %s\n", s
, s
);
1144 (void) fprintf(fout
, "define S%s %d\n", s
, n
);
1145 (void) fprintf(fout
, "integer %s (S%s)\n", s
, s
);
1146 for (i
= 1; i
<= n
; i
++) {
1148 (void) fprintf(fout
, "data ");
1149 (void) fprintf(fout
, "%s (%d)/%d/", s
, i
, a
[i
]);
1150 (void) fprintf(fout
, (i
%8 && i
< n
) ? ", " : "\n");
1152 (void) fprintf(fout
, "end\n");
1156 shiftr(int *a
, int n
)
1159 for (i
= n
; i
>= 0; i
--)
1164 upone(int *a
, int n
)
1167 for (i
= 0; i
<= n
; i
++)
1172 bprint(char *a
, char *s
, int n
)
1175 (void) fprintf(fout
, "block data\n");
1176 (void) fprintf(fout
, "common /L%s/ %s\n", s
, s
);
1177 (void) fprintf(fout
, "define S%s %d\n", s
, n
);
1178 (void) fprintf(fout
, "integer %s (S%s)\n", s
, s
);
1179 for (i
= 1; i
< n
; i
+= 8) {
1180 (void) fprintf(fout
, "data %s (%d)/%d/", s
, i
, a
[i
]);
1181 for (j
= 1; j
< 8; j
++) {
1184 (void) fprintf(fout
,
1185 ", %s (%d)/%d/", s
, k
, a
[k
]);
1187 (void) putc('\n', fout
);
1189 (void) fprintf(fout
, "end\n");
1194 padd(int **array
, int n
)
1202 for (i
= tptr
-1; i
>= 0; i
--) {
1204 if (j
&& *j
++ == count
) {
1205 for (k
= 0; k
< count
; k
++)
1209 array
[n
] = array
[i
];