9032 sgs: this statement may fall through
[unleashed.git] / usr / src / cmd / sgs / yacc / common / y2.c
blobfbdaf194451ef2ab2c61388ee7626b4ab3260699
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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 #include "dextern.h"
30 #include "sgs.h"
31 #include <stdio.h>
33 #define IDENTIFIER 257
35 #define MARK 258
36 #define TERM 259
37 #define LEFT 260
38 #define RIGHT 261
39 #define BINARY 262
40 #define PREC 263
41 #define LCURLY 264
42 #define C_IDENTIFIER 265 /* name followed by colon */
43 #define NUMBER 266
44 #define START 267
45 #define TYPEDEF 268
46 #define TYPENAME 269
47 #define UNION 270
48 #define ENDFILE 0
49 #define LHS_TEXT_LEN 80 /* length of lhstext */
50 #define RHS_TEXT_LEN 640 /* length of rhstext */
51 /* communication variables between various I/O routines */
53 #define v_FLAG 0x01
54 #define d_FLAG 0x02
55 #define DEFAULT_PREFIX "y"
57 char *infile; /* input file name */
58 static int numbval; /* value of an input number */
59 static int toksize = NAMESIZE;
60 static wchar_t *tokname; /* input token name */
61 char *parser = PARSER; /* location of common parser */
63 static void finact(void);
64 static wchar_t *cstash(wchar_t *);
65 static void defout(void);
66 static void cpyunion(void);
67 static void cpycode(void);
68 static void cpyact(int);
69 static void lhsfill(wchar_t *);
70 static void rhsfill(wchar_t *);
71 static void lrprnt(void);
72 static void beg_debug(void);
73 static void end_toks(void);
74 static void end_debug(void);
75 static void exp_tokname(void);
76 static void exp_prod(void);
77 static void exp_ntok(void);
78 static void exp_nonterm(void);
79 static int defin(int, wchar_t *);
80 static int gettok(void);
81 static int chfind(int, wchar_t *);
82 static int skipcom(void);
83 static int findchtok(int);
84 static void put_prefix_define(char *);
87 /* storage of names */
90 * initial block to place token and
91 * nonterminal names are stored
92 * points to initial block - more space
93 * is allocated as needed.
95 static wchar_t cnamesblk0[CNAMSZ];
96 static wchar_t *cnames = cnamesblk0;
98 /* place where next name is to be put in */
99 static wchar_t *cnamp = cnamesblk0;
101 /* number of defined symbols output */
102 static int ndefout = 3;
104 /* storage of types */
105 static int defunion = 0; /* union of types defined? */
106 static int ntypes = 0; /* number of types defined */
107 static wchar_t *typeset[NTYPES]; /* pointers to type tags */
109 /* symbol tables for tokens and nonterminals */
111 int ntokens = 0;
112 int ntoksz = NTERMS;
113 TOKSYMB *tokset;
114 int *toklev;
116 int nnonter = -1;
117 NTSYMB *nontrst;
118 int nnontersz = NNONTERM;
120 static int start; /* start symbol */
122 /* assigned token type values */
123 static int extval = 0;
125 /* input and output file descriptors */
127 FILE *finput; /* yacc input file */
128 FILE *faction; /* file for saving actions */
129 FILE *fdefine; /* file for # defines */
130 FILE *ftable; /* y.tab.c file */
131 FILE *ftemp; /* tempfile to pass 2 */
132 FILE *fdebug; /* where the strings for debugging are stored */
133 FILE *foutput; /* y.output file */
135 /* output string */
137 static wchar_t *lhstext;
138 static wchar_t *rhstext;
140 /* storage for grammar rules */
142 int *mem0; /* production storage */
143 int *mem;
144 int *tracemem;
145 extern int *optimmem;
146 int new_memsize = MEMSIZE;
147 int nprod = 1; /* number of productions */
148 int nprodsz = NPROD;
150 int **prdptr;
151 int *levprd;
152 wchar_t *had_act;
154 /* flag for generating the # line's default is yes */
155 int gen_lines = 1;
156 int act_lines = 0;
158 /* flag for whether to include runtime debugging */
159 static int gen_testing = 0;
161 /* flag for version stamping--default turned off */
162 static char *v_stmp = "n";
164 int nmbchars = 0; /* number of mb literals in mbchars */
165 MBCLIT *mbchars = (MBCLIT *) 0; /* array of mb literals */
166 int nmbcharsz = 0; /* allocated space for mbchars */
168 void
169 setup(argc, argv)
170 int argc;
171 char *argv[];
172 { int ii, i, j, lev, t, ty;
173 /* ty is the sequencial number of token name in tokset */
174 int c;
175 int *p;
176 char *cp;
177 wchar_t actname[8];
178 unsigned int options = 0;
179 char *file_prefix = DEFAULT_PREFIX;
180 char *sym_prefix = "";
181 #define F_NAME_LENGTH 128
182 char fname[F_NAME_LENGTH+1];
184 foutput = NULL;
185 fdefine = NULL;
186 i = 1;
188 tokname = (wchar_t *)malloc(sizeof (wchar_t) * toksize);
189 tokset = (TOKSYMB *)malloc(sizeof (TOKSYMB) * ntoksz);
190 toklev = (int *)malloc(sizeof (int) * ntoksz);
191 nontrst = (NTSYMB *)malloc(sizeof (NTSYMB) * nnontersz);
192 mem0 = (int *)malloc(sizeof (int) * new_memsize);
193 prdptr = (int **)malloc(sizeof (int *) * (nprodsz+2));
194 levprd = (int *)malloc(sizeof (int) * (nprodsz+2));
195 had_act = (wchar_t *)calloc((nprodsz + 2), sizeof (wchar_t));
196 lhstext = (wchar_t *)calloc(1, sizeof (wchar_t) * LHS_TEXT_LEN);
197 rhstext = (wchar_t *)calloc(1, sizeof (wchar_t) * RHS_TEXT_LEN);
198 aryfil(toklev, ntoksz, 0);
199 aryfil(levprd, nprodsz, 0);
200 for (ii = 0; ii < ntoksz; ++ii)
201 tokset[ii].value = 0;
202 for (ii = 0; ii < nnontersz; ++ii)
203 nontrst[ii].tvalue = 0;
204 aryfil(mem0, new_memsize, 0);
205 mem = mem0;
206 tracemem = mem0;
208 while ((c = getopt(argc, argv, "vVdltp:Q:Y:P:b:")) != EOF)
209 switch (c) {
210 case 'v':
211 options |= v_FLAG;
212 break;
213 case 'V':
214 (void) fprintf(stderr, "yacc: %s %s\n",
215 (const char *)SGU_PKG,
216 (const char *)SGU_REL);
217 break;
218 case 'Q':
219 v_stmp = optarg;
220 if (*v_stmp != 'y' && *v_stmp != 'n')
222 * TRANSLATION_NOTE -- This is a message from yacc.
223 * This message is passed to error() function.
224 * Do not translate -Q and [y/n].
226 error(gettext(
227 "yacc: -Q should be followed by [y/n]"));
228 break;
229 case 'd':
230 options |= d_FLAG;
231 break;
232 case 'l':
233 gen_lines = 0; /* don't gen #lines */
234 break;
235 case 't':
236 gen_testing = 1; /* set YYDEBUG on */
237 break;
238 case 'Y':
239 cp = (char *)malloc(strlen(optarg)+
240 sizeof ("/yaccpar") + 1);
241 cp = strcpy(cp, optarg);
242 parser = strcat(cp, "/yaccpar");
243 break;
244 case 'P':
245 parser = optarg;
246 break;
247 case 'p':
248 if (strcmp(optarg, "yy") != 0)
249 sym_prefix = optarg;
250 else
251 sym_prefix = "";
252 break;
253 case 'b':
254 file_prefix = optarg;
255 break;
256 case '?':
257 default:
259 * TRANSLATION_NOTE -- This is a message from yacc.
260 * This message is passed to error() function.
261 * This is a usage message. The translate should be
262 * consistent with man page translation.
264 (void) fprintf(stderr, gettext(
265 "Usage: yacc [-vVdltY] [-Q(y/n)] [-b file_prefix] [-p sym_prefix]"
266 " [-P parser] file\n"));
267 exit(1);
270 * Open y.output if -v is specified
272 if (options & v_FLAG) {
273 (void) strncpy(fname,
274 file_prefix,
275 F_NAME_LENGTH-strlen(".output"));
276 (void) strcat(fname, ".output");
277 foutput = fopen(fname, "w");
278 if (foutput == NULL)
279 error(gettext(
280 "cannot open y.output"));
284 * Open y.tab.h if -d is specified
286 if (options & d_FLAG) {
287 (void) strncpy(fname,
288 file_prefix,
289 F_NAME_LENGTH-strlen(".tab.h"));
290 (void) strcat(fname, ".tab.h");
291 fdefine = fopen(fname, "w");
292 if (fdefine == NULL)
293 error(gettext(
294 "cannot open y.tab.h"));
297 fdebug = fopen(DEBUGNAME, "w");
298 if (fdebug == NULL)
300 * TRANSLATION_NOTE -- This is a message from yacc.
301 * This message is passed to error() function.
302 * Do not translate yacc.debug.
304 error(gettext(
305 "cannot open yacc.debug"));
307 * Open y.tab.c
309 (void) strncpy(fname,
310 file_prefix,
311 F_NAME_LENGTH-strlen(".tab.c"));
312 (void) strcat(fname, ".tab.c");
313 ftable = fopen(fname, "w");
314 if (ftable == NULL)
315 error(gettext(
316 "cannot open %s"), fname);
318 ftemp = fopen(TEMPNAME, "w");
319 faction = fopen(ACTNAME, "w");
320 if (ftemp == NULL || faction == NULL)
322 * TRANSLATION_NOTE -- This is a message from yacc.
323 * This message is passed to error() function.
324 * The message means: "Could not open a temporary file."
326 error(gettext(
327 "cannot open temp file"));
329 if ((finput = fopen(infile = argv[optind], "r")) == NULL)
331 * TRANSLATION_NOTE -- This is a message from yacc.
332 * This message is passed to error() function.
334 error(gettext(
335 "cannot open input file"));
337 lineno = 1;
338 cnamp = cnames;
339 (void) defin(0, L"$end");
340 extval = 0400;
341 (void) defin(0, L"error");
342 (void) defin(1, L"$accept");
343 mem = mem0;
344 lev = 0;
345 ty = 0;
346 i = 0;
347 beg_debug(); /* initialize fdebug file */
350 * sorry -- no yacc parser here.....
351 * we must bootstrap somehow...
354 t = gettok();
355 if (*v_stmp == 'y')
356 (void) fprintf(ftable, "#ident\t\"yacc: %s %s\"\n",
357 (const char *)SGU_PKG, (const char *)SGU_REL);
358 for (; t != MARK && t != ENDFILE; ) {
359 int tok_in_line;
360 switch (t) {
362 case L';':
363 t = gettok();
364 break;
366 case START:
367 if ((t = gettok()) != IDENTIFIER) {
368 error("bad %%start construction");
370 start = chfind(1, tokname);
371 t = gettok();
372 continue;
374 case TYPEDEF:
375 tok_in_line = 0;
376 if ((t = gettok()) != TYPENAME)
378 * TRANSLATION_NOTE -- This is a message from yacc.
379 * This message is passed to error() function.
380 * Do not translate %%type.
382 error(gettext(
383 "bad syntax in %%type"));
384 ty = numbval;
385 for (;;) {
386 t = gettok();
387 switch (t) {
389 case IDENTIFIER:
391 * The following lines are idented to left.
393 tok_in_line = 1;
394 if ((t = chfind(1, tokname)) < NTBASE) {
395 j = TYPE(toklev[t]);
396 if (j != 0 && j != ty) {
398 * TRANSLATION_NOTE -- This is a message from yacc.
399 * This message is passed to error() function.
401 error(gettext(
402 "type redeclaration of token %ws"),
403 tokset[t].name);
405 else
406 SETTYPE(toklev[t], ty);
407 } else {
408 j = nontrst[t-NTBASE].tvalue;
409 if (j != 0 && j != ty) {
411 * TRANSLATION_NOTE -- This is a message from yacc.
412 * This message is passed to error() function.
413 * Check how nonterminal is translated in translated
414 * yacc man page or yacc user's document.
416 error(gettext(
417 "type redeclaration of nonterminal %ws"),
418 nontrst[t-NTBASE].name);
420 else
421 nontrst[t-NTBASE].tvalue = ty;
423 /* FALLTHRU */
425 * End Indentation
427 case L',':
428 continue;
430 case L';':
431 t = gettok();
432 break;
433 default:
434 break;
436 if (!tok_in_line)
438 * TRANSLATION_NOTE -- This is a message from yacc.
439 * This message is passed to error() function.
441 error(gettext(
442 "missing tokens or illegal tokens"));
443 break;
445 continue;
447 case UNION:
448 /* copy the union declaration to the output */
449 cpyunion();
450 defunion = 1;
451 t = gettok();
452 continue;
454 case LEFT:
455 case BINARY:
456 case RIGHT:
457 i++;
458 /* FALLTHRU */
459 case TERM:
460 tok_in_line = 0;
462 /* nonzero means new prec. and assoc. */
463 lev = (t-TERM) | 04;
464 ty = 0;
466 /* get identifiers so defined */
468 t = gettok();
469 if (t == TYPENAME) { /* there is a type defined */
470 ty = numbval;
471 t = gettok();
474 for (;;) {
475 switch (t) {
477 case L',':
478 t = gettok();
479 continue;
481 case L';':
482 break;
484 case IDENTIFIER:
485 tok_in_line = 1;
486 j = chfind(0, tokname);
487 if (j > NTBASE) {
489 * TRANSLATION_NOTE -- This is a message from yacc.
490 * This message is passed to error() function.
492 error(gettext(
493 "%ws is not a token."),
494 tokname);
496 if (lev & ~04) {
497 if (ASSOC(toklev[j]) & ~04)
499 * TRANSLATION_NOTE -- This is a message from yacc.
500 * This message is passed to error() function.
502 error(gettext(
503 "redeclaration of precedence of %ws"),
504 tokname);
505 SETASC(toklev[j], lev);
506 SETPLEV(toklev[j], i);
507 } else {
508 if (ASSOC(toklev[j]))
509 (void) warning(1, gettext(
510 "redeclaration of precedence of %ws."),
511 tokname);
512 SETASC(toklev[j], lev);
514 if (ty) {
515 if (TYPE(toklev[j]))
516 error(gettext(
518 * TRANSLATION_NOTE -- This is a message from yacc.
519 * This message is passed to error() function.
521 "redeclaration of type of %ws"),
522 tokname);
523 SETTYPE(toklev[j], ty);
525 if ((t = gettok()) == NUMBER) {
526 tokset[j].value = numbval;
527 if (j < ndefout && j > 2) {
529 * TRANSLATION_NOTE -- This is a message from yacc.
530 * This message is passed to error() function.
532 error(gettext(
533 "type number of %ws should be defined earlier"),
534 tokset[j].name);
536 if (numbval >= -YYFLAG1) {
538 * TRANSLATION_NOTE -- This is a message from yacc.
539 * This message is passed to error() function.
541 error(gettext(
542 "token numbers must be less than %d"),
543 -YYFLAG1);
545 t = gettok();
547 continue;
550 if (!tok_in_line)
552 * TRANSLATION_NOTE -- This is a message from yacc.
553 * This message is passed to error() function.
555 error(gettext(
556 "missing tokens or illegal tokens"));
557 break;
559 continue;
561 case LCURLY:
562 defout();
563 cpycode();
564 t = gettok();
565 continue;
567 default:
568 error("syntax error");
574 if (t == ENDFILE) {
576 * TRANSLATION_NOTE -- This is a message from yacc.
577 * This message is passed to error() function.
578 * Do not translate %%%%.
580 error("unexpected EOF before %%%%");
583 /* t is MARK */
585 defout();
586 end_toks(); /* all tokens dumped - get ready for reductions */
588 (void) fprintf(ftable, "\n#include <inttypes.h>\n");
589 (void) fprintf(ftable, "\n#ifdef __STDC__\n");
590 (void) fprintf(ftable, "#include <stdlib.h>\n");
591 (void) fprintf(ftable, "#include <string.h>\n");
592 (void) fprintf(ftable, "#define YYCONST const\n");
593 (void) fprintf(ftable, "#else\n");
594 (void) fprintf(ftable, "#include <malloc.h>\n");
595 (void) fprintf(ftable, "#include <memory.h>\n");
596 (void) fprintf(ftable, "#define YYCONST\n");
597 (void) fprintf(ftable, "#endif\n");
598 (void) fprintf(ftable, "\n#include <values.h>\n");
600 if (sym_prefix[0] != '\0')
601 put_prefix_define(sym_prefix);
603 (void) fprintf(ftable,
604 "\n#if defined(__cplusplus) || defined(__STDC__)\n");
605 (void) fprintf(ftable,
606 "\n#if defined(__cplusplus) && defined(__EXTERN_C__)\n");
607 (void) fprintf(ftable, "extern \"C\" {\n");
608 (void) fprintf(ftable, "#endif\n");
609 (void) fprintf(ftable, "#ifndef yyerror\n");
610 (void) fprintf(ftable, "#if defined(__cplusplus)\n");
611 (void) fprintf(ftable, " void yyerror(YYCONST char *);\n");
612 (void) fprintf(ftable, "#endif\n");
613 (void) fprintf(ftable, "#endif\n");
614 (void) fprintf(ftable, "#ifndef yylex\n");
615 (void) fprintf(ftable, " int yylex(void);\n");
616 (void) fprintf(ftable, "#endif\n");
617 (void) fprintf(ftable, " int yyparse(void);\n");
618 (void) fprintf(ftable,
619 "#if defined(__cplusplus) && defined(__EXTERN_C__)\n");
620 (void) fprintf(ftable, "}\n");
621 (void) fprintf(ftable, "#endif\n");
622 (void) fprintf(ftable, "\n#endif\n\n");
624 (void) fprintf(ftable, "#define yyclearin yychar = -1\n");
625 (void) fprintf(ftable, "#define yyerrok yyerrflag = 0\n");
626 (void) fprintf(ftable, "extern int yychar;\nextern int yyerrflag;\n");
627 if (!(defunion || ntypes))
628 (void) fprintf(ftable,
629 "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
630 (void) fprintf(ftable, "YYSTYPE yylval;\n");
631 (void) fprintf(ftable, "YYSTYPE yyval;\n");
632 (void) fprintf(ftable, "typedef int yytabelem;\n");
633 (void) fprintf(ftable,
634 "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n");
635 (void) fprintf(ftable, "#if YYMAXDEPTH > 0\n");
636 (void) fprintf(ftable, "int yy_yys[YYMAXDEPTH], *yys = yy_yys;\n");
637 (void) fprintf(ftable, "YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv;\n");
638 (void) fprintf(ftable, "#else /* user does initial allocation */\n");
639 (void) fprintf(ftable, "int *yys;\nYYSTYPE *yyv;\n#endif\n");
640 (void) fprintf(ftable, "static int yymaxdepth = YYMAXDEPTH;\n");
642 prdptr[0] = mem;
643 /* added production */
644 *mem++ = NTBASE;
646 /* if start is 0, we will overwrite with the lhs of the first rule */
647 *mem++ = start;
648 *mem++ = 1;
649 *mem++ = 0;
650 prdptr[1] = mem;
652 while ((t = gettok()) == LCURLY)
653 cpycode();
655 if (t != C_IDENTIFIER)
656 error("bad syntax on first rule");
658 if (!start)
659 prdptr[0][1] = chfind(1, tokname);
661 /* read rules */
663 while (t != MARK && t != ENDFILE) {
665 /* process a rule */
667 if (t == L'|') {
668 rhsfill((wchar_t *)0); /* restart fill of rhs */
669 *mem = *prdptr[nprod-1];
670 if (++mem >= &tracemem[new_memsize])
671 exp_mem(1);
672 } else if (t == C_IDENTIFIER) {
673 *mem = chfind(1, tokname);
674 if (*mem < NTBASE)
676 * TRANSLATION_NOTE -- This is a message from yacc.
677 * This message is passed to error() function.
678 * Check how nonterminal is translated.
680 error(gettext(
681 "illegal nonterminal in grammar rule"));
682 if (++mem >= &tracemem[new_memsize])
683 exp_mem(1);
684 lhsfill(tokname); /* new rule: restart strings */
685 } else
687 * TRANSLATION_NOTE -- This is a message from yacc.
688 * This message is passed to error() function.
690 error(gettext(
691 "illegal rule: missing semicolon or | ?"));
693 /* read rule body */
696 t = gettok();
697 more_rule:
698 while (t == IDENTIFIER) {
699 *mem = chfind(1, tokname);
700 if (*mem < NTBASE)
701 levprd[nprod] = toklev[*mem]& ~04;
702 if (++mem >= &tracemem[new_memsize])
703 exp_mem(1);
704 rhsfill(tokname); /* add to rhs string */
705 t = gettok();
708 if (t == PREC) {
709 if (gettok() != IDENTIFIER)
711 * TRANSLATION_NOTE -- This is a message from yacc.
712 * This message is passed to error() function.
713 * Do not translate %%prec.
715 error(gettext(
716 "illegal %%prec syntax"));
717 j = chfind(2, tokname);
718 if (j >= NTBASE)
720 * TRANSLATION_NOTE -- This is a message from yacc.
721 * This message is passed to error() function.
722 * Do not translate %%prec.
724 error(gettext(
725 "nonterminal %ws illegal after %%prec"),
726 nontrst[j-NTBASE].name);
727 levprd[nprod] = toklev[j] & ~04;
728 t = gettok();
731 if (t == L'=') {
732 had_act[nprod] = 1;
733 levprd[nprod] |= ACTFLAG;
734 (void) fprintf(faction, "\ncase %d:", nprod);
735 cpyact(mem-prdptr[nprod] - 1);
736 (void) fprintf(faction, " break;");
737 if ((t = gettok()) == IDENTIFIER) {
738 /* action within rule... */
740 lrprnt(); /* dump lhs, rhs */
741 (void) wsprintf(actname, "$$%d", nprod);
743 * make it nonterminal
745 j = chfind(1, actname);
748 * the current rule will become rule
749 * number nprod+1 move the contents down,
750 * and make room for the null
753 if (mem + 2 >= &tracemem[new_memsize])
754 exp_mem(1);
755 for (p = mem; p >= prdptr[nprod]; --p)
756 p[2] = *p;
757 mem += 2;
759 /* enter null production for action */
761 p = prdptr[nprod];
763 *p++ = j;
764 *p++ = -nprod;
766 /* update the production information */
768 levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
769 levprd[nprod] = ACTFLAG;
771 if (++nprod >= nprodsz)
772 exp_prod();
773 prdptr[nprod] = p;
776 * make the action appear in
777 * the original rule
779 *mem++ = j;
780 if (mem >= &tracemem[new_memsize])
781 exp_mem(1);
782 /* get some more of the rule */
783 goto more_rule;
786 while (t == L';')
787 t = gettok();
788 *mem++ = -nprod;
789 if (mem >= &tracemem[new_memsize])
790 exp_mem(1);
792 /* check that default action is reasonable */
794 if (ntypes && !(levprd[nprod] & ACTFLAG) &&
795 nontrst[*prdptr[nprod]-NTBASE].tvalue) {
796 /* no explicit action, LHS has value */
797 int tempty;
798 tempty = prdptr[nprod][1];
799 if (tempty < 0)
801 * TRANSLATION_NOTE -- This is a message from yacc.
802 * This message is passed to error() function.
803 * LHS means Left Hand Side. It does not need to be translated.
805 error(gettext(
806 "must return a value, since LHS has a type"));
807 else if (tempty >= NTBASE)
808 tempty = nontrst[tempty-NTBASE].tvalue;
809 else
810 tempty = TYPE(toklev[tempty]);
811 if (tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue) {
813 * TRANSLATION_NOTE -- This is a message from yacc.
814 * This message is passed to error() function.
815 * Check how action is transltated in yacc man page or documents.
817 error(gettext(
818 "default action causes potential type clash"));
822 if (++nprod >= nprodsz)
823 exp_prod();
824 prdptr[nprod] = mem;
825 levprd[nprod] = 0;
827 /* end of all rules */
829 end_debug(); /* finish fdebug file's input */
830 finact();
831 if (t == MARK) {
832 if (gen_lines)
833 (void) fprintf(ftable, "\n# line %d \"%s\"\n",
834 lineno, infile);
835 while ((c = getwc(finput)) != EOF)
836 (void) putwc(c, ftable);
838 (void) fclose(finput);
841 static void
842 finact()
844 /* finish action routine */
845 (void) fclose(faction);
846 (void) fprintf(ftable, "# define YYERRCODE %d\n", tokset[2].value);
849 static wchar_t *
850 cstash(s)
851 register wchar_t *s;
853 wchar_t *temp;
854 static int used = 0;
855 static int used_save = 0;
856 static int exp_cname = CNAMSZ;
857 int len = wslen(s);
860 * 2/29/88 -
861 * Don't need to expand the table, just allocate new space.
863 used_save = used;
864 while (len >= (exp_cname - used_save)) {
865 exp_cname += CNAMSZ;
866 if (!used)
867 free((char *)cnames);
868 if ((cnames = (wchar_t *)
869 malloc(sizeof (wchar_t)*exp_cname)) == NULL)
871 * TRANSLATION_NOTE -- This is a message from yacc.
872 * This message is passed to error() function.
874 * You may just translate this as:
875 * 'Could not allocate internally used memory.'
877 error(gettext(
878 "cannot expand string dump"));
879 cnamp = cnames;
880 used = 0;
883 temp = cnamp;
884 do {
885 *cnamp++ = *s;
886 } while (*s++);
887 used += cnamp - temp;
888 return (temp);
891 static int
892 defin(int t, wchar_t *s)
894 /* define s to be a terminal if t=0 or a nonterminal if t=1 */
896 int val;
898 if (t) {
899 if (++nnonter >= nnontersz)
900 exp_nonterm();
901 nontrst[nnonter].name = cstash(s);
902 return (NTBASE + nnonter);
904 /* must be a token */
905 if (++ntokens >= ntoksz)
906 exp_ntok();
907 tokset[ntokens].name = cstash(s);
909 /* establish value for token */
911 if (s[0] == L' ' && s[2] == 0) { /* single character literal */
912 val = findchtok(s[1]);
913 } else if (s[0] == L' ' && s[1] == L'\\') { /* escape sequence */
914 if (s[3] == 0) { /* single character escape sequence */
915 switch (s[2]) {
916 /* character which is escaped */
917 case L'a':
918 (void) warning(1, gettext(
920 * TRANSLATION_NOTE -- This is a message from yacc.
921 * This message is passed to warning() function.
922 * Do not trasnlate ANSI C, \\a.
924 "\\a is ANSI C \"alert\" character"));
925 #if __STDC__ - 1 == 0
926 val = L'\a';
927 break;
928 #else
929 val = L'\007';
930 break;
931 #endif
932 case L'v': val = L'\v'; break;
933 case L'n': val = L'\n'; break;
934 case L'r': val = L'\r'; break;
935 case L'b': val = L'\b'; break;
936 case L't': val = L'\t'; break;
937 case L'f': val = L'\f'; break;
938 case L'\'': val = L'\''; break;
939 case L'"': val = L'"'; break;
940 case L'?': val = L'?'; break;
941 case L'\\': val = L'\\'; break;
943 * TRANSLATION_NOTE -- This is a message from yacc.
944 * This message is passed to error() function.
946 default: error(gettext(
947 "invalid escape"));
949 } else if (s[2] <= L'7' && s[2] >= L'0') { /* \nnn sequence */
950 int i = 3;
951 val = s[2] - L'0';
952 while (iswdigit(s[i]) && i <= 4) {
953 if (s[i] >= L'0' && s[i] <= L'7')
954 val = val * 8 + s[i] - L'0';
955 else
957 * TRANSLATION_NOTE -- This is a message from yacc.
958 * This message is passed to error() function.
960 error(gettext(
961 "illegal octal number"));
962 i++;
964 if (s[i] != 0)
966 * TRANSLATION_NOTE -- This is a message from yacc.
967 * This message is passed to error() function.
968 * Do not translate \\nnn.
970 error(gettext(
971 "illegal \\nnn construction"));
972 if (val > 255)
974 * TRANSLATION_NOTE -- This is a message from yacc.
975 * This message is passed to error() function.
976 * Do not translate
977 * \\nnn, \\xnnnnnnnn.
979 error(
980 "\\nnn exceed \\377; use \\xnnnnnnnn for wchar_t value of multibyte char");
981 if (val == 0 && i >= 4)
983 * TRANSLATION_NOTE -- This is a message from yacc.
984 * This message is passed to error() function.
985 * Do not translate \\000.
987 error(gettext(
988 "'\\000' is illegal"));
989 } else if (s[2] == L'x') { /* hexadecimal \xnnn sequence */
990 int i = 3;
991 val = 0;
993 * TRANSLATION_NOTE -- This is a message from yacc.
994 * This message is passed to warning() function.
995 * Do not translate \\x, ANSI C.
997 (void) warning(1, gettext(
998 "\\x is ANSI C hex escape"));
999 if (iswxdigit(s[i]))
1000 while (iswxdigit(s[i])) {
1001 int tmpval;
1002 if (iswdigit(s[i]))
1003 tmpval = s[i] - L'0';
1004 else if (s[i] >= L'a')
1005 tmpval = s[i] - L'a' + 10;
1006 else
1007 tmpval = s[i] - L'A' + 10;
1008 val = 16 * val + tmpval;
1009 i++;
1011 else
1012 error(gettext(
1013 "illegal hexadecimal number"));
1014 if (s[i] != 0)
1016 * TRANSLATION_NOTE -- This is a message from yacc.
1017 * This message is passed to error() function.
1018 * Do not translate \\xnn.
1020 error(gettext(
1021 "illegal \\xnn construction"));
1022 #define LWCHAR_MAX 0x7fffffff
1023 if ((unsigned)val > LWCHAR_MAX)
1025 * TRANSLATION_NOTE -- This is a message from yacc.
1026 * This message is passed to error() function.
1027 * Do not translate \\xnnnnnnnn and %#x.
1029 error(gettext(
1030 " \\xnnnnnnnn exceed %#x"),
1031 LWCHAR_MAX);
1032 if (val == 0)
1034 * TRANSLATION_NOTE -- This is a message from yacc.
1035 * This message is passed to error() function.
1036 * Do not translate \\x00.
1038 error(gettext(
1039 "'\\x00' is illegal"));
1040 val = findchtok(val);
1041 } else
1042 error(gettext(
1043 "invalid escape"));
1044 } else {
1045 val = extval++;
1047 tokset[ntokens].value = val;
1048 toklev[ntokens] = 0;
1049 return (ntokens);
1052 static void
1053 defout()
1055 /* write out the defines (at the end of the declaration section) */
1057 register int i, c;
1058 register wchar_t *cp;
1060 for (i = ndefout; i <= ntokens; ++i) {
1062 cp = tokset[i].name;
1063 if (*cp == L' ') /* literals */
1065 (void) fprintf(fdebug, WSFMT("\t\"%ws\",\t%d,\n"),
1066 tokset[i].name + 1, tokset[i].value);
1067 continue; /* was cp++ */
1070 for (; (c = *cp) != 0; ++cp) {
1071 if (iswlower(c) || iswupper(c) ||
1072 iswdigit(c) || c == L'_')
1073 /* EMPTY */;
1074 else
1075 goto nodef;
1078 (void) fprintf(fdebug,
1079 WSFMT("\t\"%ws\",\t%d,\n"), tokset[i].name,
1080 tokset[i].value);
1081 (void) fprintf(ftable,
1082 WSFMT("# define %ws %d\n"), tokset[i].name,
1083 tokset[i].value);
1084 if (fdefine != NULL)
1085 (void) fprintf(fdefine,
1086 WSFMT("# define %ws %d\n"),
1087 tokset[i].name,
1088 tokset[i].value);
1090 nodef:;
1092 ndefout = ntokens+1;
1095 static int
1096 gettok()
1098 int i, base;
1099 static int peekline; /* number of '\n' seen in lookahead */
1100 int c, match, reserve;
1101 begin:
1102 reserve = 0;
1103 lineno += peekline;
1104 peekline = 0;
1105 c = getwc(finput);
1107 * while (c == ' ' || c == '\n' || c == '\t' || c == '\f') {
1109 while (iswspace(c)) {
1110 if (c == L'\n')
1111 ++lineno;
1112 c = getwc(finput);
1114 if (c == L'/') { /* skip comment */
1115 lineno += skipcom();
1116 goto begin;
1119 switch (c) {
1121 case EOF:
1122 return (ENDFILE);
1123 case L'{':
1124 (void) ungetwc(c, finput);
1125 return (L'='); /* action ... */
1126 case L'<': /* get, and look up, a type name (union member name) */
1127 i = 0;
1128 while ((c = getwc(finput)) != L'>' &&
1129 c != EOF && c != L'\n') {
1130 tokname[i] = c;
1131 if (++i >= toksize)
1132 exp_tokname();
1134 if (c != L'>')
1135 error(gettext(
1136 "unterminated < ... > clause"));
1137 tokname[i] = 0;
1138 if (i == 0)
1139 error("missing type name in < ... > clause");
1140 for (i = 1; i <= ntypes; ++i) {
1141 if (!wscmp(typeset[i], tokname)) {
1142 numbval = i;
1143 return (TYPENAME);
1146 typeset[numbval = ++ntypes] = cstash(tokname);
1147 return (TYPENAME);
1149 case L'"':
1150 case L'\'':
1151 match = c;
1152 tokname[0] = L' ';
1153 i = 1;
1154 for (;;) {
1155 c = getwc(finput);
1156 if (c == L'\n' || c == EOF)
1157 error(gettext(
1158 "illegal or missing ' or \""));
1159 if (c == L'\\') {
1160 c = getwc(finput);
1161 tokname[i] = L'\\';
1162 if (++i >= toksize)
1163 exp_tokname();
1164 } else if (c == match) break;
1165 tokname[i] = c;
1166 if (++i >= toksize)
1167 exp_tokname();
1169 break;
1171 case L'%':
1172 case L'\\':
1174 switch (c = getwc(finput)) {
1176 case L'0': return (TERM);
1177 case L'<': return (LEFT);
1178 case L'2': return (BINARY);
1179 case L'>': return (RIGHT);
1180 case L'%':
1181 case L'\\': return (MARK);
1182 case L'=': return (PREC);
1183 case L'{': return (LCURLY);
1184 default: reserve = 1;
1186 /* FALLTHROUGH */
1187 default:
1189 if (iswdigit(c)) { /* number */
1190 numbval = c - L'0';
1191 base = (c == L'0') ? 8 : 10;
1192 for (c = getwc(finput);
1193 iswdigit(c);
1194 c = getwc(finput)) {
1195 numbval = numbval*base + c - L'0';
1197 (void) ungetwc(c, finput);
1198 return (NUMBER);
1199 } else if (iswlower(c) || iswupper(c) ||
1200 c == L'_' || c == L'.' ||
1201 c == L'$') {
1202 i = 0;
1203 while (iswlower(c) || iswupper(c) ||
1204 iswdigit(c) || c == L'_' ||
1205 c == L'.' || c == L'$') {
1206 tokname[i] = c;
1207 if (reserve && iswupper(c))
1208 tokname[i] = towlower(c);
1209 if (++i >= toksize)
1210 exp_tokname();
1211 c = getwc(finput);
1214 else
1215 return (c);
1217 (void) ungetwc(c, finput);
1220 tokname[i] = 0;
1222 if (reserve) { /* find a reserved word */
1223 if (!wscmp(tokname, L"term"))
1224 return (TERM);
1225 if (!wscmp(tokname, L"token"))
1226 return (TERM);
1227 if (!wscmp(tokname, L"left"))
1228 return (LEFT);
1229 if (!wscmp(tokname, L"nonassoc"))
1230 return (BINARY);
1231 if (!wscmp(tokname, L"binary"))
1232 return (BINARY);
1233 if (!wscmp(tokname, L"right"))
1234 return (RIGHT);
1235 if (!wscmp(tokname, L"prec"))
1236 return (PREC);
1237 if (!wscmp(tokname, L"start"))
1238 return (START);
1239 if (!wscmp(tokname, L"type"))
1240 return (TYPEDEF);
1241 if (!wscmp(tokname, L"union"))
1242 return (UNION);
1243 error(gettext(
1244 "invalid escape, or illegal reserved word: %ws"),
1245 tokname);
1248 /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
1250 c = getwc(finput);
1252 * while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/')
1255 while (iswspace(c) || c == L'/') {
1256 if (c == L'\n') {
1257 ++peekline;
1258 } else if (c == L'/') { /* look for comments */
1259 peekline += skipcom();
1261 c = getwc(finput);
1263 if (c == L':')
1264 return (C_IDENTIFIER);
1265 (void) ungetwc(c, finput);
1266 return (IDENTIFIER);
1269 static int
1270 fdtype(int t)
1272 /* determine the type of a symbol */
1273 int v;
1274 if (t >= NTBASE)
1275 v = nontrst[t-NTBASE].tvalue;
1276 else
1277 v = TYPE(toklev[t]);
1278 if (v <= 0)
1279 error(gettext(
1280 "must specify type for %ws"),
1281 (t >= NTBASE) ? nontrst[t-NTBASE].name:
1282 tokset[t].name);
1283 return (v);
1286 static int
1287 chfind(int t, wchar_t *s)
1289 int i;
1291 if (s[0] == ' ')
1292 t = 0;
1293 TLOOP(i) {
1294 if (!wscmp(s, tokset[i].name)) {
1295 return (i);
1298 NTLOOP(i) {
1299 if (!wscmp(s, nontrst[i].name)) {
1300 return (i + NTBASE);
1303 /* cannot find name */
1304 if (t > 1)
1305 error(gettext(
1306 "%ws should have been defined earlier"), s);
1307 return (defin(t, s));
1310 static void
1311 cpyunion()
1314 * copy the union declaration to the output,
1315 * and the define file if present
1317 int level, c;
1318 if (gen_lines)
1319 (void) fprintf(ftable, "\n# line %d \"%s\"\n", lineno, infile);
1320 (void) fprintf(ftable, "typedef union\n");
1321 if (fdefine)
1322 (void) fprintf(fdefine, "\ntypedef union\n");
1323 (void) fprintf(ftable, "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
1324 if (fdefine)
1325 (void) fprintf(fdefine,
1326 "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
1328 level = 0;
1329 for (;;) {
1330 if ((c = getwc(finput)) == EOF)
1332 * TRANSLATION_NOTE -- This is a message from yacc.
1333 * This message is passed to error() function.
1334 * EOF - End Of File.
1335 * Do not translate %%union.
1337 error(gettext(
1338 "EOF encountered while processing %%union"));
1339 (void) putwc(c, ftable);
1340 if (fdefine)
1341 (void) putwc(c, fdefine);
1343 switch (c) {
1345 case L'\n':
1346 ++lineno;
1347 break;
1349 case L'{':
1350 ++level;
1351 break;
1353 case L'}':
1354 --level;
1355 if (level == 0) { /* we are finished copying */
1356 (void) fprintf(ftable, " YYSTYPE;\n");
1357 if (fdefine)
1358 (void) fprintf(fdefine,
1359 " YYSTYPE;\nextern YYSTYPE yylval;\n");
1360 return;
1366 static void
1367 cpycode()
1369 /* copies code between \{ and \} */
1371 int c;
1372 c = getwc(finput);
1373 if (c == L'\n') {
1374 c = getwc(finput);
1375 lineno++;
1377 if (gen_lines)
1378 (void) fprintf(ftable, "\n# line %d \"%s\"\n", lineno, infile);
1379 while (c != EOF) {
1380 if (c == L'\\') {
1381 if ((c = getwc(finput)) == L'}')
1382 return;
1383 else
1384 (void) putwc(L'\\', ftable);
1385 } else if (c == L'%') {
1386 if ((c = getwc(finput)) == L'}')
1387 return;
1388 else
1389 (void) putwc(L'%', ftable);
1391 (void) putwc(c, ftable);
1392 if (c == L'\n')
1393 ++lineno;
1394 c = getwc(finput);
1397 * TRANSLATION_NOTE -- This is a message from yacc.
1398 * This message is passed to error() function.
1399 * Do not translate %%}.
1401 error(gettext(
1402 "eof before %%}"));
1405 static int
1406 skipcom()
1408 /* skip over comments */
1409 int c, i = 0; /* i is the number of lines skipped */
1411 /* skipcom is called after reading a / */
1413 if (getwc(finput) != L'*')
1414 error(gettext(
1415 "illegal comment"));
1416 c = getwc(finput);
1417 while (c != EOF) {
1418 while (c == L'*') {
1419 if ((c = getwc(finput)) == L'/')
1420 return (i);
1422 if (c == L'\n')
1423 ++i;
1424 c = getwc(finput);
1427 * TRANSLATION_NOTE -- This is a message from yacc.
1428 * This message is passed to error() function.
1429 * EOF -- End Of File.
1431 error(gettext(
1432 "EOF inside comment"));
1433 /* NOTREACHED */
1434 return (0);
1437 static void
1438 cpyact(int offset)
1440 /* copy C action to the next ; or closing } */
1441 int brac, c, match, i, t, j, s, tok, argument, m;
1442 wchar_t id_name[NAMESIZE+1];
1443 int id_idx = 0;
1445 if (gen_lines) {
1446 (void) fprintf(faction, "\n# line %d \"%s\"\n", lineno, infile);
1447 act_lines++;
1449 brac = 0;
1450 id_name[0] = 0;
1451 loop:
1452 c = getwc(finput);
1453 swt:
1454 switch (c) {
1455 case L';':
1456 if (brac == 0) {
1457 (void) putwc(c, faction);
1458 return;
1460 goto lcopy;
1461 case L'{':
1462 brac++;
1463 goto lcopy;
1464 case L'$':
1465 s = 1;
1466 tok = -1;
1467 argument = 1;
1468 while ((c = getwc(finput)) == L' ' || c == L'\t')
1469 /* NULL */;
1470 if (c == L'<') { /* type description */
1471 (void) ungetwc(c, finput);
1472 if (gettok() != TYPENAME)
1474 * TRANSLATION_NOTE -- This is a message from yacc.
1475 * This message is passed to error() function.
1476 * Do not translate $<ident>
1478 error(gettext(
1479 "bad syntax on $<ident> clause"));
1480 tok = numbval;
1481 c = getwc(finput);
1483 if (c == L'$') {
1484 (void) fprintf(faction, "yyval");
1485 if (ntypes) { /* put out the proper tag... */
1486 if (tok < 0)
1487 tok = fdtype(*prdptr[nprod]);
1488 (void) fprintf(faction,
1489 WSFMT(".%ws"), typeset[tok]);
1491 goto loop;
1493 if (iswalpha(c)) {
1494 int same = 0;
1495 int id_sw = 0;
1496 (void) ungetwc(c, finput);
1497 if (gettok() != IDENTIFIER)
1499 * TRANSLATION_NOTE -- This is a message from yacc.
1500 * This message is passed to error() function.
1501 * Check how action is translated in yacc man page/document.
1503 error(gettext(
1504 "bad action format"));
1506 * Save the number of non-terminal
1508 id_sw = nnonter;
1509 t = chfind(1, tokname);
1511 * Check if the identifier is added as a non-terminal
1513 if (id_sw != nnonter)
1514 id_sw = 1;
1515 else
1516 id_sw = 0;
1517 while ((c = getwc(finput)) == L' ' ||
1518 c == L'\t')
1519 /* NULL */;
1520 if (c == L'#') {
1521 while ((c = getwc(finput)) == L' ' ||
1522 c == L'\t')
1523 /* NULL */;
1524 if (iswdigit(c)) {
1525 m = 0;
1526 while (iswdigit(c)) {
1527 m = m*10+c-L'0';
1528 c = getwc(finput);
1530 argument = m;
1531 } else
1532 error(gettext(
1533 "illegal character \"#\""));
1535 if (argument < 1)
1537 * TRANSLATION_NOTE -- This is a message from yacc.
1538 * This message is passed to error() function.
1539 * Check how action is translated in yacc man page/document.
1541 error(gettext(
1542 "illegal action argument no."));
1543 for (i = 1; i <= offset; ++i)
1544 if (prdptr[nprod][i] == t)
1545 if (++same == argument) {
1546 (void) fprintf(faction,
1547 "yypvt[-%d]", offset-i);
1548 if (ntypes) {
1549 if (tok < 0)
1550 tok =
1551 /* CSTYLED */
1552 fdtype(prdptr[nprod][i]);
1553 (void) fprintf(faction,
1554 WSFMT(".%ws"),
1555 typeset[tok]);
1557 goto swt;
1560 * This used to be handled as error.
1561 * Treat this as a valid C statement.
1562 * (Likely id with $ in.)
1563 * If non-terminal is added, remove it from the list.
1565 (void) fprintf(faction, WSFMT("$%ws"), tokname);
1567 * TRANSLATION_NOTE -- This is a message from yacc.
1568 * This message is passed to warning() function.
1569 * Do not translate Ansi C.
1571 warning(1, gettext(
1572 "Illegal character '$' in Ansi C symbol: %ws$%ws."),
1573 id_name, tokname);
1575 if (id_sw == 1)
1576 --nnonter;
1577 goto swt;
1579 if (c == '-') {
1580 s = -s;
1581 c = getwc(finput);
1583 if (iswdigit(c)) {
1584 j = 0;
1585 while (iswdigit(c)) {
1586 j = j*10 + c - L'0';
1587 c = getwc(finput);
1589 j = j*s - offset;
1590 if (j > 0) {
1592 * TRANSLATION_NOTE -- This is a message from yacc.
1593 * This message is passed to error() function.
1594 * Do not translate $%d.
1596 error(gettext(
1597 "Illegal use of $%d"),
1598 j + offset);
1600 (void) fprintf(faction, "yypvt[-%d]", -j);
1601 if (ntypes) { /* put out the proper tag */
1602 if (j + offset <= 0 && tok < 0)
1604 * TRANSLATION_NOTE -- This is a message from yacc.
1605 * This message is passed to error() function.
1606 * Do not translate $%d.
1608 error(gettext(
1609 "must specify type of $%d"),
1610 j + offset);
1611 if (tok < 0)
1612 tok = fdtype(prdptr[nprod][j+offset]);
1613 (void) fprintf(faction,
1614 WSFMT(".%ws"), typeset[tok]);
1616 goto swt;
1618 (void) putwc(L'$', faction);
1619 if (s < 0)
1620 (void) putwc(L'-', faction);
1621 goto swt;
1622 case L'}':
1623 if (--brac)
1624 goto lcopy;
1625 (void) putwc(c, faction);
1626 return;
1627 case L'/': /* look for comments */
1628 (void) putwc(c, faction);
1629 c = getwc(finput);
1630 if (c != L'*')
1631 goto swt;
1632 /* it really is a comment */
1633 (void) putwc(c, faction);
1634 c = getwc(finput);
1635 while (c != EOF) {
1636 while (c == L'*') {
1637 (void) putwc(c, faction);
1638 if ((c = getwc(finput)) == L'/')
1639 goto lcopy;
1641 (void) putwc(c, faction);
1642 if (c == L'\n')
1643 ++lineno;
1644 c = getwc(finput);
1646 error("EOF inside comment");
1647 /* FALLTHRU */
1648 case L'\'': /* character constant */
1649 case L'"': /* character string */
1650 match = c;
1651 (void) putwc(c, faction);
1652 while ((c = getwc(finput)) != EOF) {
1653 if (c == L'\\') {
1654 (void) putwc(c, faction);
1655 c = getwc(finput);
1656 if (c == L'\n')
1657 ++lineno;
1658 } else if (c == match)
1659 goto lcopy;
1660 else if (c == L'\n')
1662 * TRANSLATION_NOTE -- This is a message from yacc.
1663 * This message is passed to error() function.
1664 * This error message is issued when
1665 * quoted string has multiple lines.
1667 error(gettext(
1668 "newline in string or char. const."));
1669 (void) putwc(c, faction);
1671 error(gettext(
1672 "EOF in string or character constant"));
1673 /* FALLTHRU */
1674 case EOF:
1676 * TRANSLATION_NOTE -- This is a message from yacc.
1677 * This message is passed to error() function.
1678 * Check how 'action' is translated in yacc mapage/document.
1680 error(gettext(
1681 "action does not terminate"));
1682 /* FALLTHRU */
1683 case L'\n':
1684 ++lineno;
1685 goto lcopy;
1687 lcopy:
1688 (void) putwc(c, faction);
1690 * Save the possible identifier name.
1691 * Used to print out a warning message.
1693 if (id_idx >= NAMESIZE) {
1695 * Error. Silently ignore.
1697 /* EMPTY */;
1700 * If c has a possibility to be a
1701 * part of identifier, save it.
1703 else if (iswalnum(c) || c == L'_') {
1704 id_name[id_idx++] = c;
1705 id_name[id_idx] = 0;
1706 } else {
1707 id_idx = 0;
1708 id_name[id_idx] = 0;
1710 goto loop;
1713 static void
1714 lhsfill(s) /* new rule, dump old (if exists), restart strings */
1715 wchar_t *s;
1717 static int lhs_len = LHS_TEXT_LEN;
1718 int s_lhs = wslen(s);
1719 if (s_lhs >= lhs_len) {
1720 lhs_len = s_lhs + 2;
1721 lhstext = (wchar_t *)
1722 realloc((char *)lhstext, sizeof (wchar_t)*lhs_len);
1723 if (lhstext == NULL)
1725 * TRANSLATION_NOTE -- This is a message from yacc.
1726 * This message is passed to error() function.
1727 * LHS -- Left Hand Side.
1729 error(gettext(
1730 "couldn't expanded LHS length"));
1732 rhsfill((wchar_t *)0);
1733 (void) wscpy(lhstext, s); /* don't worry about too long of a name */
1736 static void
1737 rhsfill(s)
1738 wchar_t *s; /* either name or 0 */
1740 static wchar_t *loc; /* next free location in rhstext */
1741 static int rhs_len = RHS_TEXT_LEN;
1742 static int used = 0;
1743 int s_rhs = (s == NULL ? 0 : wslen(s));
1744 register wchar_t *p;
1746 if (!s) /* print out and erase old text */
1748 if (*lhstext) /* there was an old rule - dump it */
1749 lrprnt();
1750 (loc = rhstext)[0] = 0;
1751 return;
1753 /* add to stuff in rhstext */
1754 p = s;
1756 used = loc - rhstext;
1757 if ((s_rhs + 3) >= (rhs_len - used)) {
1758 static wchar_t *textbase;
1759 textbase = rhstext;
1760 rhs_len += s_rhs + RHS_TEXT_LEN;
1761 rhstext = (wchar_t *)
1762 realloc((char *)rhstext, sizeof (wchar_t)*rhs_len);
1763 if (rhstext == NULL)
1765 * TRANSLATION_NOTE -- This is a message from yacc.
1766 * This message is passed to error() function.
1767 * RHS -- Right Hand Side.
1769 error(gettext(
1770 "couldn't expanded RHS length"));
1771 loc = loc - textbase + rhstext;
1774 *loc++ = L' ';
1775 if (*s == L' ') /* special quoted symbol */
1777 *loc++ = L'\''; /* add first quote */
1778 p++;
1780 while (*loc = *p++)
1781 if (loc++ > &rhstext[ RHS_TEXT_LEN ] - 3)
1782 break;
1784 if (*s == L' ')
1785 *loc++ = L'\'';
1786 *loc = 0; /* terminate the string */
1789 static void
1790 lrprnt() /* print out the left and right hand sides */
1792 wchar_t *rhs;
1793 wchar_t *m_rhs = NULL;
1795 if (!*rhstext) /* empty rhs - print usual comment */
1796 rhs = L" /* empty */";
1797 else {
1798 int idx1; /* tmp idx used to find if there are d_quotes */
1799 int idx2; /* tmp idx used to generate escaped string */
1800 wchar_t *p;
1802 * Check if there are any double quote in RHS.
1804 for (idx1 = 0; rhstext[idx1] != 0; idx1++) {
1805 if (rhstext[idx1] == L'"') {
1807 * A double quote is found.
1809 idx2 = wslen(rhstext)*2;
1810 p = m_rhs = (wchar_t *)
1811 malloc((idx2 + 1)*sizeof (wchar_t));
1812 if (m_rhs == NULL)
1814 * TRANSLATION_NOTE -- This is a message from yacc.
1815 * This message is passed to error() function.
1816 * RHS - Right Hand Side.
1818 * You may just translate this as:
1819 * 'Could not allocate internally used memory.'
1821 error(gettext(
1822 "Couldn't allocate memory for RHS."));
1824 * Copy string
1826 for (idx2 = 0; rhstext[idx2] != 0; idx2++) {
1828 * Check if this quote is escaped or not
1830 if (rhstext[idx2] == L'"') {
1831 int tmp_l = idx2-1;
1832 int cnt = 0;
1833 while (tmp_l >= 0 &&
1834 rhstext[tmp_l] == '\\') {
1835 cnt++;
1836 tmp_l--;
1839 * If quote is not escaped,
1840 * then escape it.
1842 if (cnt%2 == 0)
1843 *p++ = L'\\';
1845 *p++ = rhstext[idx2];
1847 *p = 0;
1849 * Break from the loop
1851 break;
1854 if (m_rhs == NULL)
1855 rhs = rhstext;
1856 else
1857 rhs = m_rhs;
1859 (void) fprintf(fdebug, WSFMT("\t\"%ws :%ws\",\n"), lhstext, rhs);
1860 if (m_rhs)
1861 free(m_rhs);
1865 static void
1866 beg_debug() /* dump initial sequence for fdebug file */
1868 (void) fprintf(fdebug,
1869 "typedef struct\n");
1870 (void) fprintf(fdebug,
1871 "#ifdef __cplusplus\n\tyytoktype\n");
1872 (void) fprintf(fdebug, "#endif\n{\n");
1873 (void) fprintf(fdebug,
1874 "#ifdef __cplusplus\nconst\n#endif\n");
1875 (void) fprintf(fdebug, "char *t_name; int t_val; } yytoktype;\n");
1876 (void) fprintf(fdebug,
1877 "#ifndef YYDEBUG\n#\tdefine YYDEBUG\t%d", gen_testing);
1878 (void) fprintf(fdebug, "\t/*%sallow debugging */\n#endif\n\n",
1879 gen_testing ? " " : " don't ");
1880 (void) fprintf(fdebug, "#if YYDEBUG\n\nyytoktype yytoks[] =\n{\n");
1884 static void
1885 end_toks() /* finish yytoks array, get ready for yyred's strings */
1887 (void) fprintf(fdebug, "\t\"-unknown-\",\t-1\t/* ends search */\n");
1888 (void) fprintf(fdebug, "};\n\n");
1889 (void) fprintf(fdebug,
1890 "#ifdef __cplusplus\nconst\n#endif\n");
1891 (void) fprintf(fdebug, "char * yyreds[] =\n{\n");
1892 (void) fprintf(fdebug, "\t\"-no such reduction-\",\n");
1896 static void
1897 end_debug() /* finish yyred array, close file */
1899 lrprnt(); /* dump last lhs, rhs */
1900 (void) fprintf(fdebug, "};\n#endif /* YYDEBUG */\n");
1901 (void) fclose(fdebug);
1906 * 2/29/88 -
1907 * The normal length for token sizes is NAMESIZE - If a token is
1908 * seen that has a longer length, expand "tokname" by NAMESIZE.
1910 static void
1911 exp_tokname()
1913 toksize += NAMESIZE;
1914 tokname = (wchar_t *)
1915 realloc((char *)tokname, sizeof (wchar_t) * toksize);
1920 * 2/29/88 -
1923 static void
1924 exp_prod()
1926 int i;
1927 nprodsz += NPROD;
1929 prdptr = (int **) realloc((char *)prdptr, sizeof (int *) * (nprodsz+2));
1930 levprd = (int *) realloc((char *)levprd, sizeof (int) * (nprodsz+2));
1931 had_act = (wchar_t *)
1932 realloc((char *)had_act, sizeof (wchar_t) * (nprodsz+2));
1933 for (i = nprodsz-NPROD; i < nprodsz+2; ++i)
1934 had_act[i] = 0;
1936 if ((*prdptr == NULL) || (levprd == NULL) || (had_act == NULL))
1938 * TRANSLATION_NOTE -- This is a message from yacc.
1939 * This message is passed to error() function.
1941 * You may just translate this as:
1942 * 'Could not allocate internally used memory.'
1944 error(gettext(
1945 "couldn't expand productions"));
1949 * 2/29/88 -
1950 * Expand the number of terminals. Initially there are NTERMS;
1951 * each time space runs out, the size is increased by NTERMS.
1952 * The total size, however, cannot exceed MAXTERMS because of
1953 * the way LOOKSETS(struct looksets) is set up.
1954 * Tables affected:
1955 * tokset, toklev : increased to ntoksz
1957 * tables with initial dimensions of TEMPSIZE must be changed if
1958 * (ntoksz + NNONTERM) >= TEMPSIZE : temp1[]
1960 static void
1961 exp_ntok()
1963 ntoksz += NTERMS;
1965 tokset = (TOKSYMB *) realloc((char *)tokset, sizeof (TOKSYMB) * ntoksz);
1966 toklev = (int *) realloc((char *)toklev, sizeof (int) * ntoksz);
1968 if ((tokset == NULL) || (toklev == NULL))
1970 * TRANSLATION_NOTE -- This is a message from yacc.
1971 * This message is passed to error() function.
1972 * Do not translate NTERMS.
1974 * You may just translate this as:
1975 * 'Could not allocate internally used memory.'
1977 error(gettext(
1978 "couldn't expand NTERMS"));
1982 static void
1983 exp_nonterm()
1985 nnontersz += NNONTERM;
1987 nontrst = (NTSYMB *)
1988 realloc((char *)nontrst, sizeof (TOKSYMB) * nnontersz);
1989 if (nontrst == NULL)
1991 * TRANSLATION_NOTE -- This is a message from yacc.
1992 * This message is passed to error() function.
1993 * Do not translate NTERMS.
1995 * You may just translate this as:
1996 * 'Could not allocate internally used memory.'
1998 error(gettext(
1999 "couldn't expand NNONTERM"));
2002 void
2003 exp_mem(flag)
2004 int flag;
2006 int i;
2007 static int *membase;
2008 new_memsize += MEMSIZE;
2010 membase = tracemem;
2011 tracemem = (int *)
2012 realloc((char *)tracemem, sizeof (int) * new_memsize);
2013 if (tracemem == NULL)
2015 * TRANSLATION_NOTE -- This is a message from yacc.
2016 * This message is passed to error() function.
2018 * You may just translate this as:
2019 * 'Could not allocate internally used memory.'
2021 error(gettext(
2022 "couldn't expand mem table"));
2023 if (flag) {
2024 for (i = 0; i <= nprod; ++i)
2025 prdptr[i] = prdptr[i] - membase + tracemem;
2026 mem = mem - membase + tracemem;
2027 } else {
2028 size += MEMSIZE;
2029 temp1 = (int *)realloc((char *)temp1, sizeof (int)*size);
2030 optimmem = optimmem - membase + tracemem;
2034 static int
2035 findchtok(chlit)
2036 int chlit;
2038 * findchtok(chlit) returns the token number for a character literal
2039 * chlit that is "bigger" than 255 -- the max char value that the
2040 * original yacc was build for. This yacc treate them as though
2041 * an ordinary token.
2044 int i;
2046 if (chlit < 0xff)
2047 return (chlit); /* single-byte char */
2048 for (i = 0; i < nmbchars; ++i) {
2049 if (mbchars->character == chlit)
2050 return (mbchars->tvalue);
2053 /* Not found. Register it! */
2054 if (++nmbchars > nmbcharsz) { /* Make sure there's enough space */
2055 nmbcharsz += NMBCHARSZ;
2056 mbchars = (MBCLIT *)
2057 realloc((char *)mbchars, sizeof (MBCLIT)*nmbcharsz);
2058 if (mbchars == NULL)
2059 error(gettext(
2060 "too many character literals"));
2062 mbchars[nmbchars-1].character = chlit;
2063 return (mbchars[nmbchars-1].tvalue = extval++);
2064 /* Return the newly assigned token. */
2068 * When -p is specified, symbol prefix for
2069 * yy{parse, lex, error}(),
2070 * yy{lval, val, char, debug, errflag, nerrs}
2071 * are defined to the specified name.
2073 static void
2074 put_prefix_define(char *pre)
2076 char *syms[] = {
2077 /* Functions */
2078 "parse",
2079 "lex",
2080 "error",
2081 /* Variables */
2082 "lval",
2083 "val",
2084 "char",
2085 "debug",
2086 "errflag",
2087 "nerrs",
2088 NULL};
2089 int i;
2091 for (i = 0; syms[i]; i++)
2092 (void) fprintf(ftable, "#define\tyy%s\t%s%s\n",
2093 syms[i], pre, syms[i]);