summaryrefslogtreecommitdiff
path: root/usr/src/cmd/sgs/yacc/common/y2.c
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/sgs/yacc/common/y2.c
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/sgs/yacc/common/y2.c')
-rw-r--r--usr/src/cmd/sgs/yacc/common/y2.c2101
1 files changed, 2101 insertions, 0 deletions
diff --git a/usr/src/cmd/sgs/yacc/common/y2.c b/usr/src/cmd/sgs/yacc/common/y2.c
new file mode 100644
index 0000000000..a0f450f4ce
--- /dev/null
+++ b/usr/src/cmd/sgs/yacc/common/y2.c
@@ -0,0 +1,2101 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 2002 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 "dextern"
+#include "sgs.h"
+#define IDENTIFIER 257
+
+#define MARK 258
+#define TERM 259
+#define LEFT 260
+#define RIGHT 261
+#define BINARY 262
+#define PREC 263
+#define LCURLY 264
+#define C_IDENTIFIER 265 /* name followed by colon */
+#define NUMBER 266
+#define START 267
+#define TYPEDEF 268
+#define TYPENAME 269
+#define UNION 270
+#define ENDFILE 0
+#define LHS_TEXT_LEN 80 /* length of lhstext */
+#define RHS_TEXT_LEN 640 /* length of rhstext */
+ /* communication variables between various I/O routines */
+
+#define v_FLAG 0x01
+#define d_FLAG 0x02
+#define DEFAULT_PREFIX "y"
+
+char *infile; /* input file name */
+static int numbval; /* value of an input number */
+static int toksize = NAMESIZE;
+static wchar_t *tokname; /* input token name */
+char *parser = NULL; /* location of common parser */
+
+static void finact(void);
+static wchar_t *cstash(wchar_t *);
+static void defout(void);
+static void cpyunion(void);
+static void cpycode(void);
+static void cpyact(int);
+static void lhsfill(wchar_t *);
+static void rhsfill(wchar_t *);
+static void lrprnt(void);
+static void beg_debug(void);
+static void end_toks(void);
+static void end_debug(void);
+static void exp_tokname(void);
+static void exp_prod(void);
+static void exp_ntok(void);
+static void exp_nonterm(void);
+static int defin(int, wchar_t *);
+static int gettok(void);
+static int chfind(int, wchar_t *);
+static int skipcom(void);
+static int findchtok(int);
+static void put_prefix_define(char *);
+
+
+/* storage of names */
+
+/*
+ * initial block to place token and
+ * nonterminal names are stored
+ * points to initial block - more space
+ * is allocated as needed.
+ */
+static wchar_t cnamesblk0[CNAMSZ];
+static wchar_t *cnames = cnamesblk0;
+
+/* place where next name is to be put in */
+static wchar_t *cnamp = cnamesblk0;
+
+/* number of defined symbols output */
+static int ndefout = 3;
+
+ /* storage of types */
+static int defunion = 0; /* union of types defined? */
+static int ntypes = 0; /* number of types defined */
+static wchar_t *typeset[NTYPES]; /* pointers to type tags */
+
+ /* symbol tables for tokens and nonterminals */
+
+int ntokens = 0;
+int ntoksz = NTERMS;
+TOKSYMB *tokset;
+int *toklev;
+
+int nnonter = -1;
+NTSYMB *nontrst;
+int nnontersz = NNONTERM;
+
+static int start; /* start symbol */
+
+ /* assigned token type values */
+static int extval = 0;
+
+ /* input and output file descriptors */
+
+FILE *finput; /* yacc input file */
+FILE *faction; /* file for saving actions */
+FILE *fdefine; /* file for # defines */
+FILE *ftable; /* y.tab.c file */
+FILE *ftemp; /* tempfile to pass 2 */
+FILE *fdebug; /* where the strings for debugging are stored */
+FILE *foutput; /* y.output file */
+
+ /* output string */
+
+static wchar_t *lhstext;
+static wchar_t *rhstext;
+
+ /* storage for grammar rules */
+
+int *mem0; /* production storage */
+int *mem;
+int *tracemem;
+extern int *optimmem;
+int new_memsize = MEMSIZE;
+int nprod = 1; /* number of productions */
+int nprodsz = NPROD;
+
+int **prdptr;
+int *levprd;
+wchar_t *had_act;
+
+/* flag for generating the # line's default is yes */
+int gen_lines = 1;
+int act_lines = 0;
+
+/* flag for whether to include runtime debugging */
+static int gen_testing = 0;
+
+/* flag for version stamping--default turned off */
+static char *v_stmp = "n";
+
+#ifndef NOLIBW /* No wchar_t, no multibyte char handling! */
+int nmbchars = 0; /* number of mb literals in mbchars */
+MBCLIT *mbchars = (MBCLIT *) 0; /* array of mb literals */
+int nmbcharsz = 0; /* allocated space for mbchars */
+#endif /* !NOLIBW */
+
+void
+setup(argc, argv)
+int argc;
+char *argv[];
+{ int ii, i, j, lev, t, ty;
+ /* ty is the sequencial number of token name in tokset */
+ int c;
+ int *p;
+ char *cp;
+ wchar_t actname[8];
+ unsigned int options = 0;
+ char *file_prefix = DEFAULT_PREFIX;
+ char *sym_prefix = "";
+#define F_NAME_LENGTH 128
+ char fname[F_NAME_LENGTH+1];
+
+ extern char *optarg;
+ extern int optind;
+ extern getopt();
+
+ foutput = NULL;
+ fdefine = NULL;
+ i = 1;
+
+ tokname = (wchar_t *)malloc(sizeof (wchar_t) * toksize);
+ tokset = (TOKSYMB *)malloc(sizeof (TOKSYMB) * ntoksz);
+ toklev = (int *)malloc(sizeof (int) * ntoksz);
+ nontrst = (NTSYMB *)malloc(sizeof (NTSYMB) * nnontersz);
+ mem0 = (int *)malloc(sizeof (int) * new_memsize);
+ prdptr = (int **)malloc(sizeof (int *) * (nprodsz+2));
+ levprd = (int *)malloc(sizeof (int) * (nprodsz+2));
+ had_act = (wchar_t *)calloc((nprodsz + 2), sizeof (wchar_t));
+ lhstext = (wchar_t *)malloc(sizeof (wchar_t) * LHS_TEXT_LEN);
+ rhstext = (wchar_t *)malloc(sizeof (wchar_t) * RHS_TEXT_LEN);
+ aryfil(toklev, ntoksz, 0);
+ aryfil(levprd, nprodsz, 0);
+ for (ii = 0; ii < ntoksz; ++ii)
+ tokset[ii].value = 0;
+ for (ii = 0; ii < nnontersz; ++ii)
+ nontrst[ii].tvalue = 0;
+ aryfil(mem0, new_memsize, 0);
+ mem = mem0;
+ tracemem = mem0;
+
+ while ((c = getopt(argc, argv, "vVdltp:Q:Y:P:b:")) != EOF)
+ switch (c) {
+ case 'v':
+ options |= v_FLAG;
+ break;
+ case 'V':
+ (void) fprintf(stderr, "yacc: %s %s\n",
+ (const char *)SGU_PKG,
+ (const char *)SGU_REL);
+ break;
+ case 'Q':
+ v_stmp = optarg;
+ if (*v_stmp != 'y' && *v_stmp != 'n')
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate -Q and [y/n].
+ */
+ error(gettext(
+ "yacc: -Q should be followed by [y/n]"));
+ break;
+ case 'd':
+ options |= d_FLAG;
+ break;
+ case 'l':
+ gen_lines = 0; /* don't gen #lines */
+ break;
+ case 't':
+ gen_testing = 1; /* set YYDEBUG on */
+ break;
+ case 'Y':
+ cp = (char *)malloc(strlen(optarg)+
+ sizeof ("/yaccpar") + 1);
+ cp = strcpy(cp, optarg);
+ parser = strcat(cp, "/yaccpar");
+ break;
+ case 'P':
+ parser = optarg;
+ break;
+ case 'p':
+ if (strcmp(optarg, "yy") != 0)
+ sym_prefix = optarg;
+ else
+ sym_prefix = "";
+ break;
+ case 'b':
+ file_prefix = optarg;
+ break;
+ case '?':
+ default:
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This is a usage message. The translate should be
+ * consistent with man page translation.
+ */
+ (void) fprintf(stderr, gettext(
+"Usage: yacc [-vVdltY] [-Q(y/n)] [-b file_prefix] [-p sym_prefix]"
+" [-P parser] file\n"));
+ exit(1);
+ }
+ /*
+ * Open y.output if -v is specified
+ */
+ if (options & v_FLAG) {
+ strncpy(fname,
+ file_prefix,
+ F_NAME_LENGTH-strlen(".output"));
+ strcat(fname, ".output");
+ foutput = fopen(fname, "w");
+ if (foutput == NULL)
+ error(gettext(
+ "cannot open y.output"));
+ }
+
+ /*
+ * Open y.tab.h if -d is specified
+ */
+ if (options & d_FLAG) {
+ strncpy(fname,
+ file_prefix,
+ F_NAME_LENGTH-strlen(".tab.h"));
+ strcat(fname, ".tab.h");
+ fdefine = fopen(fname, "w");
+ if (fdefine == NULL)
+ error(gettext(
+ "cannot open y.tab.h"));
+ }
+
+ fdebug = fopen(DEBUGNAME, "w");
+ if (fdebug == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate yacc.debug.
+ */
+ error(gettext(
+ "cannot open yacc.debug"));
+ /*
+ * Open y.tab.c
+ */
+ strncpy(fname,
+ file_prefix,
+ F_NAME_LENGTH-strlen(".tab.c"));
+ strcat(fname, ".tab.c");
+ ftable = fopen(fname, "w");
+ if (ftable == NULL)
+ error(gettext(
+ "cannot open %s"), fname);
+
+ ftemp = fopen(TEMPNAME, "w");
+ faction = fopen(ACTNAME, "w");
+ if (ftemp == NULL || faction == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * The message means: "Could not open a temporary file."
+ */
+ error(gettext(
+ "cannot open temp file"));
+
+ if ((finput = fopen(infile = argv[optind], "r")) == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "cannot open input file"));
+
+ lineno = 1;
+ cnamp = cnames;
+ (void) defin(0, L"$end");
+ extval = 0400;
+ (void) defin(0, L"error");
+ (void) defin(1, L"$accept");
+ mem = mem0;
+ lev = 0;
+ ty = 0;
+ i = 0;
+ beg_debug(); /* initialize fdebug file */
+
+ /*
+ * sorry -- no yacc parser here.....
+ * we must bootstrap somehow...
+ */
+
+ t = gettok();
+ if (*v_stmp == 'y')
+ (void) fprintf(ftable, "#ident\t\"yacc: %s %s\"\n",
+ (const char *)SGU_PKG, (const char *)SGU_REL);
+ for (; t != MARK && t != ENDFILE; ) {
+ int tok_in_line;
+ switch (t) {
+
+ case L';':
+ t = gettok();
+ break;
+
+ case START:
+ if ((t = gettok()) != IDENTIFIER) {
+ error("bad %%start construction");
+ }
+ start = chfind(1, tokname);
+ t = gettok();
+ continue;
+
+ case TYPEDEF:
+ tok_in_line = 0;
+ if ((t = gettok()) != TYPENAME)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%type.
+ */
+ error(gettext(
+ "bad syntax in %%type"));
+ ty = numbval;
+ for (;;) {
+ t = gettok();
+ switch (t) {
+
+ case IDENTIFIER:
+ /*
+ * The following lines are idented to left.
+ */
+ tok_in_line = 1;
+ if ((t = chfind(1, tokname)) < NTBASE) {
+ j = TYPE(toklev[t]);
+ if (j != 0 && j != ty) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "type redeclaration of token %ws"),
+ tokset[t].name);
+ }
+ else
+ SETTYPE(toklev[t], ty);
+ } else {
+ j = nontrst[t-NTBASE].tvalue;
+ if (j != 0 && j != ty) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how nonterminal is translated in translated
+ * yacc man page or yacc user's document.
+ */
+ error(gettext(
+ "type redeclaration of nonterminal %ws"),
+ nontrst[t-NTBASE].name);
+ }
+ else
+ nontrst[t-NTBASE].tvalue = ty;
+ }
+ /* FALLTHRU */
+ /*
+ * End Indentation
+ */
+ case L',':
+ continue;
+
+ case L';':
+ t = gettok();
+ break;
+ default:
+ break;
+ }
+ if (!tok_in_line)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "missing tokens or illegal tokens"));
+ break;
+ }
+ continue;
+
+ case UNION:
+ /* copy the union declaration to the output */
+ cpyunion();
+ defunion = 1;
+ t = gettok();
+ continue;
+
+ case LEFT:
+ case BINARY:
+ case RIGHT:
+ i++;
+ /* FALLTHRU */
+ case TERM:
+ tok_in_line = 0;
+
+ /* nonzero means new prec. and assoc. */
+ lev = (t-TERM) | 04;
+ ty = 0;
+
+ /* get identifiers so defined */
+
+ t = gettok();
+ if (t == TYPENAME) { /* there is a type defined */
+ ty = numbval;
+ t = gettok();
+ }
+
+ for (;;) {
+ switch (t) {
+
+ case L',':
+ t = gettok();
+ continue;
+
+ case L';':
+ break;
+
+ case IDENTIFIER:
+ tok_in_line = 1;
+ j = chfind(0, tokname);
+ if (j > NTBASE) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "%ws is not a token."),
+ tokname);
+ }
+ if (lev & ~04) {
+ if (ASSOC(toklev[j]) & ~04)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "redeclaration of precedence of %ws"),
+ tokname);
+ SETASC(toklev[j], lev);
+ SETPLEV(toklev[j], i);
+ } else {
+ if (ASSOC(toklev[j]))
+ (void) warning(1, gettext(
+ "redeclaration of precedence of %ws."),
+ tokname);
+ SETASC(toklev[j], lev);
+ }
+ if (ty) {
+ if (TYPE(toklev[j]))
+ error(gettext(
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ "redeclaration of type of %ws"),
+ tokname);
+ SETTYPE(toklev[j], ty);
+ }
+ if ((t = gettok()) == NUMBER) {
+ tokset[j].value = numbval;
+ if (j < ndefout && j > 2) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "type number of %ws should be defined earlier"),
+ tokset[j].name);
+ }
+ if (numbval >= -YYFLAG1) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "token numbers must be less than %d"),
+ -YYFLAG1);
+ }
+ t = gettok();
+ }
+ continue;
+
+ }
+ if (!tok_in_line)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "missing tokens or illegal tokens"));
+ break;
+ }
+ continue;
+
+ case LCURLY:
+ defout();
+ cpycode();
+ t = gettok();
+ continue;
+
+ default:
+ error("syntax error");
+
+ }
+
+ }
+
+ if (t == ENDFILE) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%%%.
+ */
+ error("unexpected EOF before %%%%");
+ }
+
+ /* t is MARK */
+
+ defout();
+ end_toks(); /* all tokens dumped - get ready for reductions */
+
+ (void) fprintf(ftable, "\n#include <inttypes.h>\n");
+ (void) fprintf(ftable, "\n#ifdef __STDC__\n");
+ (void) fprintf(ftable, "#include <stdlib.h>\n");
+ (void) fprintf(ftable, "#include <string.h>\n");
+ (void) fprintf(ftable, "#define YYCONST const\n");
+ (void) fprintf(ftable, "#else\n");
+ (void) fprintf(ftable, "#include <malloc.h>\n");
+ (void) fprintf(ftable, "#include <memory.h>\n");
+ (void) fprintf(ftable, "#define YYCONST\n");
+ (void) fprintf(ftable, "#endif\n");
+ (void) fprintf(ftable, "\n#include <values.h>\n");
+
+ if (sym_prefix[0] != '\0')
+ put_prefix_define(sym_prefix);
+
+ (void) fprintf(ftable,
+ "\n#if defined(__cplusplus) || defined(__STDC__)\n");
+ (void) fprintf(ftable,
+ "\n#if defined(__cplusplus) && defined(__EXTERN_C__)\n");
+ (void) fprintf(ftable, "extern \"C\" {\n");
+ (void) fprintf(ftable, "#endif\n");
+ (void) fprintf(ftable, "#ifndef yyerror\n");
+ (void) fprintf(ftable, "#if defined(__cplusplus)\n");
+ (void) fprintf(ftable, " void yyerror(YYCONST char *);\n");
+ (void) fprintf(ftable, "#endif\n");
+ (void) fprintf(ftable, "#endif\n");
+ (void) fprintf(ftable, "#ifndef yylex\n");
+ (void) fprintf(ftable, " int yylex(void);\n");
+ (void) fprintf(ftable, "#endif\n");
+ (void) fprintf(ftable, " int yyparse(void);\n");
+ (void) fprintf(ftable,
+ "#if defined(__cplusplus) && defined(__EXTERN_C__)\n");
+ (void) fprintf(ftable, "}\n");
+ (void) fprintf(ftable, "#endif\n");
+ (void) fprintf(ftable, "\n#endif\n\n");
+
+ (void) fprintf(ftable, "#define yyclearin yychar = -1\n");
+ (void) fprintf(ftable, "#define yyerrok yyerrflag = 0\n");
+ (void) fprintf(ftable, "extern int yychar;\nextern int yyerrflag;\n");
+ if (!(defunion || ntypes))
+ (void) fprintf(ftable,
+ "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
+ (void) fprintf(ftable, "YYSTYPE yylval;\n");
+ (void) fprintf(ftable, "YYSTYPE yyval;\n");
+ (void) fprintf(ftable, "typedef int yytabelem;\n");
+ (void) fprintf(ftable,
+ "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n");
+ (void) fprintf(ftable, "#if YYMAXDEPTH > 0\n");
+ (void) fprintf(ftable, "int yy_yys[YYMAXDEPTH], *yys = yy_yys;\n");
+ (void) fprintf(ftable, "YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv;\n");
+ (void) fprintf(ftable, "#else /* user does initial allocation */\n");
+ (void) fprintf(ftable, "int *yys;\nYYSTYPE *yyv;\n#endif\n");
+ (void) fprintf(ftable, "static int yymaxdepth = YYMAXDEPTH;\n");
+
+ prdptr[0] = mem;
+ /* added production */
+ *mem++ = NTBASE;
+
+ /* if start is 0, we will overwrite with the lhs of the first rule */
+ *mem++ = start;
+ *mem++ = 1;
+ *mem++ = 0;
+ prdptr[1] = mem;
+
+ while ((t = gettok()) == LCURLY)
+ cpycode();
+
+ if (t != C_IDENTIFIER)
+ error("bad syntax on first rule");
+
+ if (!start)
+ prdptr[0][1] = chfind(1, tokname);
+
+ /* read rules */
+
+ while (t != MARK && t != ENDFILE) {
+
+ /* process a rule */
+
+ if (t == L'|') {
+ rhsfill((wchar_t *)0); /* restart fill of rhs */
+ *mem = *prdptr[nprod-1];
+ if (++mem >= &tracemem[new_memsize])
+ exp_mem(1);
+ } else if (t == C_IDENTIFIER) {
+ *mem = chfind(1, tokname);
+ if (*mem < NTBASE)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how nonterminal is translated.
+ */
+ error(gettext(
+ "illegal nonterminal in grammar rule"));
+ if (++mem >= &tracemem[new_memsize])
+ exp_mem(1);
+ lhsfill(tokname); /* new rule: restart strings */
+ } else
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "illegal rule: missing semicolon or | ?"));
+
+ /* read rule body */
+
+
+ t = gettok();
+ more_rule:
+ while (t == IDENTIFIER) {
+ *mem = chfind(1, tokname);
+ if (*mem < NTBASE)
+ levprd[nprod] = toklev[*mem]& ~04;
+ if (++mem >= &tracemem[new_memsize])
+ exp_mem(1);
+ rhsfill(tokname); /* add to rhs string */
+ t = gettok();
+ }
+
+ if (t == PREC) {
+ if (gettok() != IDENTIFIER)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%prec.
+ */
+ error(gettext(
+ "illegal %%prec syntax"));
+ j = chfind(2, tokname);
+ if (j >= NTBASE)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%prec.
+ */
+ error(gettext(
+ "nonterminal %ws illegal after %%prec"),
+ nontrst[j-NTBASE].name);
+ levprd[nprod] = toklev[j] & ~04;
+ t = gettok();
+ }
+
+ if (t == L'=') {
+ had_act[nprod] = 1;
+ levprd[nprod] |= ACTFLAG;
+ (void) fprintf(faction, "\ncase %d:", nprod);
+ cpyact(mem-prdptr[nprod] - 1);
+ (void) fprintf(faction, " break;");
+ if ((t = gettok()) == IDENTIFIER) {
+ /* action within rule... */
+
+ lrprnt(); /* dump lhs, rhs */
+ (void) wsprintf(actname, "$$%d", nprod);
+ /*
+ * make it nonterminal
+ */
+ j = chfind(1, actname);
+
+ /*
+ * the current rule will become rule
+ * number nprod+1 move the contents down,
+ * and make room for the null
+ */
+
+ if (mem + 2 >= &tracemem[new_memsize])
+ exp_mem(1);
+ for (p = mem; p >= prdptr[nprod]; --p)
+ p[2] = *p;
+ mem += 2;
+
+ /* enter null production for action */
+
+ p = prdptr[nprod];
+
+ *p++ = j;
+ *p++ = -nprod;
+
+ /* update the production information */
+
+ levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
+ levprd[nprod] = ACTFLAG;
+
+ if (++nprod >= nprodsz)
+ exp_prod();
+ prdptr[nprod] = p;
+
+ /*
+ * make the action appear in
+ * the original rule
+ */
+ *mem++ = j;
+ if (mem >= &tracemem[new_memsize])
+ exp_mem(1);
+ /* get some more of the rule */
+ goto more_rule;
+ }
+ }
+ while (t == L';')
+ t = gettok();
+ *mem++ = -nprod;
+ if (mem >= &tracemem[new_memsize])
+ exp_mem(1);
+
+ /* check that default action is reasonable */
+
+ if (ntypes && !(levprd[nprod] & ACTFLAG) &&
+ nontrst[*prdptr[nprod]-NTBASE].tvalue) {
+ /* no explicit action, LHS has value */
+ register tempty;
+ tempty = prdptr[nprod][1];
+ if (tempty < 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * LHS means Left Hand Side. It does not need to be translated.
+ */
+ error(gettext(
+ "must return a value, since LHS has a type"));
+ else if (tempty >= NTBASE)
+ tempty = nontrst[tempty-NTBASE].tvalue;
+ else
+ tempty = TYPE(toklev[tempty]);
+ if (tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how action is transltated in yacc man page or documents.
+ */
+ error(gettext(
+ "default action causes potential type clash"));
+ }
+ }
+
+ if (++nprod >= nprodsz)
+ exp_prod();
+ prdptr[nprod] = mem;
+ levprd[nprod] = 0;
+ }
+ /* end of all rules */
+
+ end_debug(); /* finish fdebug file's input */
+ finact();
+ if (t == MARK) {
+ if (gen_lines)
+ (void) fprintf(ftable, "\n# line %d \"%s\"\n",
+ lineno, infile);
+ while ((c = getwc(finput)) != EOF)
+ (void) putwc(c, ftable);
+ }
+ (void) fclose(finput);
+}
+
+static void
+finact()
+{
+ /* finish action routine */
+ (void) fclose(faction);
+ (void) fprintf(ftable, "# define YYERRCODE %d\n", tokset[2].value);
+}
+
+static wchar_t *
+cstash(s)
+register wchar_t *s;
+{
+ wchar_t *temp;
+ static int used = 0;
+ static int used_save = 0;
+ static int exp_cname = CNAMSZ;
+ int len = wslen(s);
+
+ /*
+ * 2/29/88 -
+ * Don't need to expand the table, just allocate new space.
+ */
+ used_save = used;
+ while (len >= (exp_cname - used_save)) {
+ exp_cname += CNAMSZ;
+ if (!used)
+ free((char *)cnames);
+ if ((cnames = (wchar_t *)
+ malloc(sizeof (wchar_t)*exp_cname)) == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error(gettext(
+ "cannot expand string dump"));
+ cnamp = cnames;
+ used = 0;
+ }
+
+ temp = cnamp;
+ do {
+ *cnamp++ = *s;
+ } while (*s++);
+ used += cnamp - temp;
+ return (temp);
+}
+
+static int
+defin(t, s)
+register wchar_t *s;
+{
+ /* define s to be a terminal if t=0 or a nonterminal if t=1 */
+
+ register val;
+
+ if (t) {
+ if (++nnonter >= nnontersz)
+ exp_nonterm();
+ nontrst[nnonter].name = cstash(s);
+ return (NTBASE + nnonter);
+ }
+ /* must be a token */
+ if (++ntokens >= ntoksz)
+ exp_ntok();
+ tokset[ntokens].name = cstash(s);
+
+ /* establish value for token */
+
+ if (s[0] == L' ' && s[2] == 0) { /* single character literal */
+ val = findchtok(s[1]);
+ } else if (s[0] == L' ' && s[1] == L'\\') { /* escape sequence */
+ if (s[3] == 0) { /* single character escape sequence */
+ switch (s[2]) {
+ /* character which is escaped */
+ case L'a':
+ (void) warning(1, gettext(
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to warning() function.
+ * Do not trasnlate ANSI C, \\a.
+ */
+ "\\a is ANSI C \"alert\" character"));
+#if __STDC__ - 1 == 0
+ val = L'\a';
+ break;
+#else
+ val = L'\007';
+ break;
+#endif
+ case L'v': val = L'\v'; break;
+ case L'n': val = L'\n'; break;
+ case L'r': val = L'\r'; break;
+ case L'b': val = L'\b'; break;
+ case L't': val = L'\t'; break;
+ case L'f': val = L'\f'; break;
+ case L'\'': val = L'\''; break;
+ case L'"': val = L'"'; break;
+ case L'?': val = L'?'; break;
+ case L'\\': val = L'\\'; break;
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ default: error(gettext(
+ "invalid escape"));
+ }
+ } else if (s[2] <= L'7' && s[2] >= L'0') { /* \nnn sequence */
+ int i = 3;
+ val = s[2] - L'0';
+ while (iswdigit(s[i]) && i <= 4) {
+ if (s[i] >= L'0' && s[i] <= L'7')
+ val = val * 8 + s[i] - L'0';
+ else
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error(gettext(
+ "illegal octal number"));
+ i++;
+ }
+ if (s[i] != 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\nnn.
+ */
+ error(gettext(
+ "illegal \\nnn construction"));
+ if (val > 255)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate
+ * \\nnn, \\xnnnnnnnn.
+ */
+ error(
+"\\nnn exceed \\377; use \\xnnnnnnnn for wchar_t value of multibyte char");
+ if (val == 0 && i >= 4)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\000.
+ */
+ error(gettext(
+ "'\\000' is illegal"));
+ } else if (s[2] == L'x') { /* hexadecimal \xnnn sequence */
+ int i = 3;
+ val = 0;
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to warning() function.
+ * Do not translate \\x, ANSI C.
+ */
+ (void) warning(1, gettext(
+ "\\x is ANSI C hex escape"));
+ if (iswxdigit(s[i]))
+ while (iswxdigit(s[i])) {
+ int tmpval;
+ if (iswdigit(s[i]))
+ tmpval = s[i] - L'0';
+ else if (s[i] >= L'a')
+ tmpval = s[i] - L'a' + 10;
+ else
+ tmpval = s[i] - L'A' + 10;
+ val = 16 * val + tmpval;
+ i++;
+ }
+ else
+ error(gettext(
+ "illegal hexadecimal number"));
+ if (s[i] != 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\xnn.
+ */
+ error(gettext(
+ "illegal \\xnn construction"));
+#define LWCHAR_MAX 0x7fffffff
+ if ((unsigned)val > LWCHAR_MAX)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\xnnnnnnnn and %#x.
+ */
+ error(gettext(
+ " \\xnnnnnnnn exceed %#x"),
+ LWCHAR_MAX);
+ if (val == 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\x00.
+ */
+ error(gettext(
+ "'\\x00' is illegal"));
+ val = findchtok(val);
+ } else
+ error(gettext(
+ "invalid escape"));
+ } else {
+ val = extval++;
+ }
+ tokset[ntokens].value = val;
+ toklev[ntokens] = 0;
+ return (ntokens);
+}
+
+static void
+defout()
+{
+ /* write out the defines (at the end of the declaration section) */
+
+ register int i, c;
+ register wchar_t *cp;
+
+ for (i = ndefout; i <= ntokens; ++i) {
+
+ cp = tokset[i].name;
+ if (*cp == L' ') /* literals */
+ {
+ (void) fprintf(fdebug, "\t\"%ws\",\t%d,\n",
+ tokset[i].name + 1, tokset[i].value);
+ continue; /* was cp++ */
+ }
+
+ for (; (c = *cp) != 0; ++cp) {
+ if (iswlower(c) || iswupper(c) ||
+ iswdigit(c) || c == L'_') /* EMPTY */;
+ else
+ goto nodef;
+ }
+
+ (void) fprintf(fdebug,
+ "\t\"%ws\",\t%d,\n", tokset[i].name,
+ tokset[i].value);
+ (void) fprintf(ftable,
+ "# define %ws %d\n", tokset[i].name,
+ tokset[i].value);
+ if (fdefine != NULL)
+ (void) fprintf(fdefine,
+ "# define %ws %d\n",
+ tokset[i].name,
+ tokset[i].value);
+
+ nodef:;
+ }
+ ndefout = ntokens+1;
+}
+
+static
+gettok()
+{
+ register i, base;
+ static int peekline; /* number of '\n' seen in lookahead */
+ register c, match, reserve;
+begin:
+ reserve = 0;
+ lineno += peekline;
+ peekline = 0;
+ c = getwc(finput);
+ /*
+ * while (c == ' ' || c == '\n' || c == '\t' || c == '\f') {
+ */
+ while (iswspace(c)) {
+ if (c == L'\n')
+ ++lineno;
+ c = getwc(finput);
+ }
+ if (c == L'/') { /* skip comment */
+ lineno += skipcom();
+ goto begin;
+ }
+
+ switch (c) {
+
+ case EOF:
+ return (ENDFILE);
+ case L'{':
+ (void) ungetwc(c, finput);
+ return (L'='); /* action ... */
+ case L'<': /* get, and look up, a type name (union member name) */
+ i = 0;
+ while ((c = getwc(finput)) != L'>' &&
+ c != EOF && c != L'\n') {
+ tokname[i] = c;
+ if (++i >= toksize)
+ exp_tokname();
+ }
+ if (c != L'>')
+ error(gettext(
+ "unterminated < ... > clause"));
+ tokname[i] = 0;
+ if (i == 0)
+ error("missing type name in < ... > clause");
+ for (i = 1; i <= ntypes; ++i) {
+ if (!wscmp(typeset[i], tokname)) {
+ numbval = i;
+ return (TYPENAME);
+ }
+ }
+ typeset[numbval = ++ntypes] = cstash(tokname);
+ return (TYPENAME);
+
+ case L'"':
+ case L'\'':
+ match = c;
+ tokname[0] = L' ';
+ i = 1;
+ for (;;) {
+ c = getwc(finput);
+ if (c == L'\n' || c == EOF)
+ error(gettext(
+ "illegal or missing ' or \""));
+ if (c == L'\\') {
+ c = getwc(finput);
+ tokname[i] = L'\\';
+ if (++i >= toksize)
+ exp_tokname();
+ } else if (c == match) break;
+ tokname[i] = c;
+ if (++i >= toksize)
+ exp_tokname();
+ }
+ break;
+
+ case L'%':
+ case L'\\':
+
+ switch (c = getwc(finput)) {
+
+ case L'0': return (TERM);
+ case L'<': return (LEFT);
+ case L'2': return (BINARY);
+ case L'>': return (RIGHT);
+ case L'%':
+ case L'\\': return (MARK);
+ case L'=': return (PREC);
+ case L'{': return (LCURLY);
+ default: reserve = 1;
+ }
+
+ default:
+
+ if (iswdigit(c)) { /* number */
+ numbval = c - L'0';
+ base = (c == L'0') ? 8 : 10;
+ for (c = getwc(finput);
+ iswdigit(c);
+ c = getwc(finput)) {
+ numbval = numbval*base + c - L'0';
+ }
+ (void) ungetwc(c, finput);
+ return (NUMBER);
+ } else if (iswlower(c) || iswupper(c) ||
+ c == L'_' || c == L'.' ||
+ c == L'$') {
+ i = 0;
+ while (iswlower(c) || iswupper(c) ||
+ iswdigit(c) || c == L'_' ||
+ c == L'.' || c == L'$') {
+ tokname[i] = c;
+ if (reserve && iswupper(c))
+ tokname[i] = towlower(c);
+ if (++i >= toksize)
+ exp_tokname();
+ c = getwc(finput);
+ }
+ }
+ else
+ return (c);
+
+ (void) ungetwc(c, finput);
+ }
+
+ tokname[i] = 0;
+
+ if (reserve) { /* find a reserved word */
+ if (!wscmp(tokname, L"term"))
+ return (TERM);
+ if (!wscmp(tokname, L"token"))
+ return (TERM);
+ if (!wscmp(tokname, L"left"))
+ return (LEFT);
+ if (!wscmp(tokname, L"nonassoc"))
+ return (BINARY);
+ if (!wscmp(tokname, L"binary"))
+ return (BINARY);
+ if (!wscmp(tokname, L"right"))
+ return (RIGHT);
+ if (!wscmp(tokname, L"prec"))
+ return (PREC);
+ if (!wscmp(tokname, L"start"))
+ return (START);
+ if (!wscmp(tokname, L"type"))
+ return (TYPEDEF);
+ if (!wscmp(tokname, L"union"))
+ return (UNION);
+ error(gettext(
+ "invalid escape, or illegal reserved word: %ws"),
+ tokname);
+ }
+
+ /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
+
+ c = getwc(finput);
+ /*
+ * while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/')
+ * {
+ */
+ while (iswspace(c) || c == L'/') {
+ if (c == L'\n') {
+ ++peekline;
+ } else if (c == L'/') { /* look for comments */
+ peekline += skipcom();
+ }
+ c = getwc(finput);
+ }
+ if (c == L':')
+ return (C_IDENTIFIER);
+ (void) ungetwc(c, finput);
+ return (IDENTIFIER);
+}
+
+static
+fdtype(t)
+{
+ /* determine the type of a symbol */
+ register v;
+ if (t >= NTBASE)
+ v = nontrst[t-NTBASE].tvalue;
+ else
+ v = TYPE(toklev[t]);
+ if (v <= 0)
+ error(gettext(
+ "must specify type for %ws"),
+ (t >= NTBASE) ? nontrst[t-NTBASE].name:
+ tokset[t].name);
+ return (v);
+}
+
+static
+chfind(t, s)
+register wchar_t *s;
+{
+ int i;
+
+ if (s[0] == ' ')
+ t = 0;
+ TLOOP(i) {
+ if (!wscmp(s, tokset[i].name)) {
+ return (i);
+ }
+ }
+ NTLOOP(i) {
+ if (!wscmp(s, nontrst[i].name)) {
+ return (i + NTBASE);
+ }
+ }
+ /* cannot find name */
+ if (t > 1)
+ error(gettext(
+ "%ws should have been defined earlier"), s);
+ return (defin(t, s));
+}
+
+static void
+cpyunion()
+{
+ /*
+ * copy the union declaration to the output,
+ * and the define file if present
+ */
+ int level, c;
+ if (gen_lines)
+ (void) fprintf(ftable, "\n# line %d \"%s\"\n", lineno, infile);
+ (void) fprintf(ftable, "typedef union\n");
+ if (fdefine)
+ (void) fprintf(fdefine, "\ntypedef union\n");
+ (void) fprintf(ftable, "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
+ if (fdefine)
+ (void) fprintf(fdefine,
+ "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
+
+ level = 0;
+ for (;;) {
+ if ((c = getwc(finput)) == EOF)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * EOF - End Of File.
+ * Do not translate %%union.
+ */
+ error(gettext(
+ "EOF encountered while processing %%union"));
+ (void) putwc(c, ftable);
+ if (fdefine)
+ (void) putwc(c, fdefine);
+
+ switch (c) {
+
+ case L'\n':
+ ++lineno;
+ break;
+
+ case L'{':
+ ++level;
+ break;
+
+ case L'}':
+ --level;
+ if (level == 0) { /* we are finished copying */
+ (void) fprintf(ftable, " YYSTYPE;\n");
+ if (fdefine)
+ (void) fprintf(fdefine,
+ " YYSTYPE;\nextern YYSTYPE yylval;\n");
+ return;
+ }
+ }
+ }
+}
+
+static void
+cpycode()
+{
+ /* copies code between \{ and \} */
+
+ int c;
+ c = getwc(finput);
+ if (c == L'\n') {
+ c = getwc(finput);
+ lineno++;
+ }
+ if (gen_lines)
+ (void) fprintf(ftable, "\n# line %d \"%s\"\n", lineno, infile);
+ while (c != EOF) {
+ if (c == L'\\') {
+ if ((c = getwc(finput)) == L'}')
+ return;
+ else
+ (void) putwc(L'\\', ftable);
+ } else if (c == L'%') {
+ if ((c = getwc(finput)) == L'}')
+ return;
+ else
+ (void) putwc(L'%', ftable);
+ }
+ (void) putwc(c, ftable);
+ if (c == L'\n')
+ ++lineno;
+ c = getwc(finput);
+ }
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%}.
+ */
+ error(gettext(
+ "eof before %%}"));
+}
+
+static
+skipcom()
+{
+ /* skip over comments */
+ register c, i = 0; /* i is the number of lines skipped */
+
+ /* skipcom is called after reading a / */
+
+ if (getwc(finput) != L'*')
+ error(gettext(
+ "illegal comment"));
+ c = getwc(finput);
+ while (c != EOF) {
+ while (c == L'*') {
+ if ((c = getwc(finput)) == L'/')
+ return (i);
+ }
+ if (c == L'\n')
+ ++i;
+ c = getwc(finput);
+ }
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * EOF -- End Of File.
+ */
+ error(gettext(
+ "EOF inside comment"));
+ /* NOTREACHED */
+}
+
+static void
+cpyact(offset)
+{
+ /* copy C action to the next ; or closing } */
+ int brac, c, match, i, t, j, s, tok, argument, m;
+ wchar_t id_name[NAMESIZE+1];
+ int id_idx = 0;
+
+ if (gen_lines) {
+ (void) fprintf(faction, "\n# line %d \"%s\"\n", lineno, infile);
+ act_lines++;
+ }
+ brac = 0;
+ id_name[0] = 0;
+loop:
+ c = getwc(finput);
+swt:
+ switch (c) {
+ case L';':
+ if (brac == 0) {
+ (void) putwc(c, faction);
+ return;
+ }
+ goto lcopy;
+ case L'{':
+ brac++;
+ goto lcopy;
+ case L'$':
+ s = 1;
+ tok = -1;
+ argument = 1;
+ while ((c = getwc(finput)) == L' ' || c == L'\t') /* EMPTY */;
+ if (c == L'<') { /* type description */
+ (void) ungetwc(c, finput);
+ if (gettok() != TYPENAME)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate $<ident>
+ */
+ error(gettext(
+ "bad syntax on $<ident> clause"));
+ tok = numbval;
+ c = getwc(finput);
+ }
+ if (c == L'$') {
+ (void) fprintf(faction, "yyval");
+ if (ntypes) { /* put out the proper tag... */
+ if (tok < 0)
+ tok = fdtype(*prdptr[nprod]);
+ (void) fprintf(faction,
+ ".%ws", typeset[tok]);
+ }
+ goto loop;
+ }
+ if (iswalpha(c)) {
+ int same = 0;
+ int id_sw = 0;
+ (void) ungetwc(c, finput);
+ if (gettok() != IDENTIFIER)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how action is translated in yacc man page/document.
+ */
+ error(gettext(
+ "bad action format"));
+ /*
+ * Save the number of non-terminal
+ */
+ id_sw = nnonter;
+ t = chfind(1, tokname);
+ /*
+ * Check if the identifier is added as a non-terminal
+ */
+ if (id_sw != nnonter)
+ id_sw = 1;
+ else
+ id_sw = 0;
+ while ((c = getwc(finput)) == L' ' ||
+ c == L'\t') /* EMPTY */;
+ if (c == L'#') {
+ while ((c = getwc(finput)) == L' ' ||
+ c == L'\t') /* EMPTY */;
+ if (iswdigit(c)) {
+ m = 0;
+ while (iswdigit(c)) {
+ m = m*10+c-L'0';
+ c = getwc(finput);
+ }
+ argument = m;
+ } else
+ error(gettext(
+ "illegal character \"#\""));
+ }
+ if (argument < 1)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how action is translated in yacc man page/document.
+ */
+ error(gettext(
+ "illegal action argument no."));
+ for (i = 1; i <= offset; ++i)
+ if (prdptr[nprod][i] == t)
+ if (++same == argument) {
+ (void) fprintf(faction,
+ "yypvt[-%d]", offset-i);
+ if (ntypes) {
+ if (tok < 0)
+ tok =
+ /* CSTYLED */
+ fdtype(prdptr[nprod][i]);
+ (void) fprintf(faction,
+ ".%ws", typeset[tok]);
+ }
+ goto swt;
+ }
+ /*
+ * This used to be handled as error.
+ * Treat this as a valid C statement.
+ * (Likely id with $ in.)
+ * If non-terminal is added, remove it from the list.
+ */
+ fprintf(faction, "$%ws", tokname);
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to warning() function.
+ * Do not translate Ansi C.
+ */
+ warning(1, gettext(
+ "Illegal character '$' in Ansi C symbol: %ws$%ws."),
+ id_name, tokname);
+
+ if (id_sw == 1)
+ --nnonter;
+ goto swt;
+ }
+ if (c == '-') {
+ s = -s;
+ c = getwc(finput);
+ }
+ if (iswdigit(c)) {
+ j = 0;
+ while (iswdigit(c)) {
+ j = j*10 + c - L'0';
+ c = getwc(finput);
+ }
+ j = j*s - offset;
+ if (j > 0) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate $%d.
+ */
+ error(gettext(
+ "Illegal use of $%d"),
+ j + offset);
+ }
+ (void) fprintf(faction, "yypvt[-%d]", -j);
+ if (ntypes) { /* put out the proper tag */
+ if (j + offset <= 0 && tok < 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate $%d.
+ */
+ error(gettext(
+ "must specify type of $%d"),
+ j + offset);
+ if (tok < 0)
+ tok = fdtype(prdptr[nprod][j+offset]);
+ (void) fprintf(faction,
+ ".%ws", typeset[tok]);
+ }
+ goto swt;
+ }
+ (void) putwc(L'$', faction);
+ if (s < 0)
+ (void) putwc(L'-', faction);
+ goto swt;
+ case L'}':
+ if (--brac)
+ goto lcopy;
+ (void) putwc(c, faction);
+ return;
+ case L'/': /* look for comments */
+ (void) putwc(c, faction);
+ c = getwc(finput);
+ if (c != L'*')
+ goto swt;
+ /* it really is a comment */
+ (void) putwc(c, faction);
+ c = getwc(finput);
+ while (c != EOF) {
+ while (c == L'*') {
+ (void) putwc(c, faction);
+ if ((c = getwc(finput)) == L'/')
+ goto lcopy;
+ }
+ (void) putwc(c, faction);
+ if (c == L'\n')
+ ++lineno;
+ c = getwc(finput);
+ }
+ error("EOF inside comment");
+ /* FALLTHRU */
+ case L'\'': /* character constant */
+ case L'"': /* character string */
+ match = c;
+ (void) putwc(c, faction);
+ while ((c = getwc(finput)) != EOF) {
+ if (c == L'\\') {
+ (void) putwc(c, faction);
+ c = getwc(finput);
+ if (c == L'\n')
+ ++lineno;
+ } else if (c == match)
+ goto lcopy;
+ else if (c == L'\n')
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This error message is issued when
+ * quoted string has multiple lines.
+ */
+ error(gettext(
+ "newline in string or char. const."));
+ (void) putwc(c, faction);
+ }
+ error(gettext(
+ "EOF in string or character constant"));
+ /* FALLTHRU */
+ case EOF:
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how 'action' is translated in yacc mapage/document.
+ */
+ error(gettext(
+ "action does not terminate"));
+ /* FALLTHRU */
+ case L'\n':
+ ++lineno;
+ goto lcopy;
+ }
+lcopy:
+ (void) putwc(c, faction);
+ /*
+ * Save the possible identifier name.
+ * Used to print out a warning message.
+ */
+ if (id_idx >= NAMESIZE) {
+ /*
+ * Error. Silently ignore.
+ */
+ ;
+ }
+ /*
+ * If c has a possibility to be a
+ * part of identifier, save it.
+ */
+ else if (iswalnum(c) || c == L'_') {
+ id_name[id_idx++] = c;
+ id_name[id_idx] = 0;
+ } else {
+ id_idx = 0;
+ id_name[id_idx] = 0;
+ }
+ goto loop;
+}
+
+static void
+lhsfill(s) /* new rule, dump old (if exists), restart strings */
+wchar_t *s;
+{
+ static int lhs_len = LHS_TEXT_LEN;
+ int s_lhs = wslen(s);
+ if (s_lhs >= lhs_len) {
+ lhs_len = s_lhs + 2;
+ lhstext = (wchar_t *)
+ realloc((char *)lhstext, sizeof (wchar_t)*lhs_len);
+ if (lhstext == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * LHS -- Left Hand Side.
+ */
+ error(gettext(
+ "couldn't expanded LHS length"));
+ }
+ rhsfill((wchar_t *)0);
+ (void) wscpy(lhstext, s); /* don't worry about too long of a name */
+}
+
+static void
+rhsfill(s)
+wchar_t *s; /* either name or 0 */
+{
+ static wchar_t *loc; /* next free location in rhstext */
+ static int rhs_len = RHS_TEXT_LEN;
+ static int used = 0;
+ int s_rhs = (s == NULL ? 0 : wslen(s));
+ register wchar_t *p;
+
+ if (!s) /* print out and erase old text */
+ {
+ if (*lhstext) /* there was an old rule - dump it */
+ lrprnt();
+ (loc = rhstext)[0] = 0;
+ return;
+ }
+ /* add to stuff in rhstext */
+ p = s;
+
+ used = loc - rhstext;
+ if ((s_rhs + 3) >= (rhs_len - used)) {
+ static wchar_t *textbase;
+ textbase = rhstext;
+ rhs_len += s_rhs + RHS_TEXT_LEN;
+ rhstext = (wchar_t *)
+ realloc((char *)rhstext, sizeof (wchar_t)*rhs_len);
+ if (rhstext == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * RHS -- Right Hand Side.
+ */
+ error(gettext(
+ "couldn't expanded RHS length"));
+ loc = loc - textbase + rhstext;
+ }
+
+ *loc++ = L' ';
+ if (*s == L' ') /* special quoted symbol */
+ {
+ *loc++ = L'\''; /* add first quote */
+ p++;
+ }
+ while (*loc = *p++)
+ if (loc++ > &rhstext[ RHS_TEXT_LEN ] - 3)
+ break;
+
+ if (*s == L' ')
+ *loc++ = L'\'';
+ *loc = 0; /* terminate the string */
+}
+
+static void
+lrprnt() /* print out the left and right hand sides */
+{
+ wchar_t *rhs;
+ wchar_t *m_rhs = NULL;
+
+ if (!*rhstext) /* empty rhs - print usual comment */
+ rhs = L" /* empty */";
+ else {
+ int idx1; /* tmp idx used to find if there are d_quotes */
+ int idx2; /* tmp idx used to generate escaped string */
+ wchar_t *p;
+ /*
+ * Check if there are any double quote in RHS.
+ */
+ for (idx1 = 0; rhstext[idx1] != 0; idx1++) {
+ if (rhstext[idx1] == L'"') {
+ /*
+ * A double quote is found.
+ */
+ idx2 = wslen(rhstext)*2;
+ p = m_rhs = (wchar_t *)
+ malloc((idx2 + 1)*sizeof (wchar_t));
+ if (m_rhs == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * RHS - Right Hand Side.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error(gettext(
+ "Couldn't allocate memory for RHS."));
+ /*
+ * Copy string
+ */
+ for (idx2 = 0; rhstext[idx2] != 0; idx2++) {
+ /*
+ * Check if this quote is escaped or not
+ */
+ if (rhstext[idx2] == L'"') {
+ int tmp_l = idx2-1;
+ int cnt = 0;
+ while (tmp_l >= 0 &&
+ rhstext[tmp_l] == '\\') {
+ cnt++;
+ tmp_l--;
+ }
+ /*
+ * If quote is not escaped,
+ * then escape it.
+ */
+ if (cnt%2 == 0)
+ *p++ = L'\\';
+ }
+ *p++ = rhstext[idx2];
+ }
+ *p = 0;
+ /*
+ * Break from the loop
+ */
+ break;
+ }
+ }
+ if (m_rhs == NULL)
+ rhs = rhstext;
+ else
+ rhs = m_rhs;
+ }
+ (void) fprintf(fdebug, "\t\"%ws :%ws\",\n", lhstext, rhs);
+ if (m_rhs)
+ free(m_rhs);
+}
+
+
+static void
+beg_debug() /* dump initial sequence for fdebug file */
+{
+ (void) fprintf(fdebug,
+ "typedef struct\n");
+ (void) fprintf(fdebug,
+ "#ifdef __cplusplus\n\tyytoktype\n");
+ (void) fprintf(fdebug, "#endif\n{\n");
+ (void) fprintf(fdebug,
+ "#ifdef __cplusplus\nconst\n#endif\n");
+ (void) fprintf(fdebug, "char *t_name; int t_val; } yytoktype;\n");
+ (void) fprintf(fdebug,
+ "#ifndef YYDEBUG\n#\tdefine YYDEBUG\t%d", gen_testing);
+ (void) fprintf(fdebug, "\t/*%sallow debugging */\n#endif\n\n",
+ gen_testing ? " " : " don't ");
+ (void) fprintf(fdebug, "#if YYDEBUG\n\nyytoktype yytoks[] =\n{\n");
+}
+
+
+static void
+end_toks() /* finish yytoks array, get ready for yyred's strings */
+{
+ (void) fprintf(fdebug, "\t\"-unknown-\",\t-1\t/* ends search */\n");
+ (void) fprintf(fdebug, "};\n\n");
+ (void) fprintf(fdebug,
+ "#ifdef __cplusplus\nconst\n#endif\n");
+ (void) fprintf(fdebug, "char * yyreds[] =\n{\n");
+ (void) fprintf(fdebug, "\t\"-no such reduction-\",\n");
+}
+
+
+static void
+end_debug() /* finish yyred array, close file */
+{
+ lrprnt(); /* dump last lhs, rhs */
+ (void) fprintf(fdebug, "};\n#endif /* YYDEBUG */\n");
+ (void) fclose(fdebug);
+}
+
+
+/*
+ * 2/29/88 -
+ * The normal length for token sizes is NAMESIZE - If a token is
+ * seen that has a longer length, expand "tokname" by NAMESIZE.
+ */
+static void
+exp_tokname()
+{
+ toksize += NAMESIZE;
+ tokname = (wchar_t *)
+ realloc((char *)tokname, sizeof (wchar_t) * toksize);
+}
+
+
+/*
+ * 2/29/88 -
+ *
+ */
+static void
+exp_prod()
+{
+ int i;
+ nprodsz += NPROD;
+
+ prdptr = (int **) realloc((char *)prdptr, sizeof (int *) * (nprodsz+2));
+ levprd = (int *) realloc((char *)levprd, sizeof (int) * (nprodsz+2));
+ had_act = (wchar_t *)
+ realloc((char *)had_act, sizeof (wchar_t) * (nprodsz+2));
+ for (i = nprodsz-NPROD; i < nprodsz+2; ++i)
+ had_act[i] = 0;
+
+ if ((*prdptr == NULL) || (levprd == NULL) || (had_act == NULL))
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error(gettext(
+ "couldn't expand productions"));
+}
+
+/*
+ * 2/29/88 -
+ * Expand the number of terminals. Initially there are NTERMS;
+ * each time space runs out, the size is increased by NTERMS.
+ * The total size, however, cannot exceed MAXTERMS because of
+ * the way LOOKSETS(struct looksets) is set up.
+ * Tables affected:
+ * tokset, toklev : increased to ntoksz
+ *
+ * tables with initial dimensions of TEMPSIZE must be changed if
+ * (ntoksz + NNONTERM) >= TEMPSIZE : temp1[]
+ */
+static void
+exp_ntok()
+{
+ ntoksz += NTERMS;
+
+ tokset = (TOKSYMB *) realloc((char *)tokset, sizeof (TOKSYMB) * ntoksz);
+ toklev = (int *) realloc((char *)toklev, sizeof (int) * ntoksz);
+
+ if ((tokset == NULL) || (toklev == NULL))
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate NTERMS.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error(gettext(
+ "couldn't expand NTERMS"));
+}
+
+
+static void
+exp_nonterm()
+{
+ nnontersz += NNONTERM;
+
+ nontrst = (NTSYMB *)
+ realloc((char *)nontrst, sizeof (TOKSYMB) * nnontersz);
+ if (nontrst == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate NTERMS.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error(gettext(
+ "couldn't expand NNONTERM"));
+}
+
+void
+exp_mem(flag)
+int flag;
+{
+ int i;
+ static int *membase;
+ new_memsize += MEMSIZE;
+
+ membase = tracemem;
+ tracemem = (int *)
+ realloc((char *)tracemem, sizeof (int) * new_memsize);
+ if (tracemem == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error(gettext(
+ "couldn't expand mem table"));
+ if (flag) {
+ for (i = 0; i <= nprod; ++i)
+ prdptr[i] = prdptr[i] - membase + tracemem;
+ mem = mem - membase + tracemem;
+ } else {
+ size += MEMSIZE;
+ temp1 = (int *)realloc((char *)temp1, sizeof (int)*size);
+ optimmem = optimmem - membase + tracemem;
+ }
+}
+
+static int
+findchtok(chlit)
+int chlit;
+/*
+ * findchtok(chlit) returns the token number for a character literal
+ * chlit that is "bigger" than 255 -- the max char value that the
+ * original yacc was build for. This yacc treate them as though
+ * an ordinary token.
+ */
+{
+ int i;
+#ifdef NOLIBW
+ return (chlit); /* assume always singlebyte char */
+#else /* !NOLIBW */
+
+ if (chlit < 0xff)
+ return (chlit); /* single-byte char */
+ for (i = 0; i < nmbchars; ++i) {
+ if (mbchars->character == chlit)
+ return (mbchars->tvalue);
+ }
+
+ /* Not found. Register it! */
+ if (++nmbchars > nmbcharsz) { /* Make sure there's enough space */
+ nmbcharsz += NMBCHARSZ;
+ mbchars = (MBCLIT *)
+ realloc((char *)mbchars, sizeof (MBCLIT)*nmbcharsz);
+ if (mbchars == NULL)
+ error(gettext(
+ "too many character literals"));
+ }
+ mbchars[nmbchars-1].character = chlit;
+ return (mbchars[nmbchars-1].tvalue = extval++);
+ /* Return the newly assigned token. */
+#endif /* !NOLIBW */
+}
+
+/*
+ * When -p is specified, symbol prefix for
+ * yy{parse, lex, error}(),
+ * yy{lval, val, char, debug, errflag, nerrs}
+ * are defined to the specified name.
+ */
+static void
+put_prefix_define(char *pre)
+{
+ char *syms[] = {
+ /* Functions */
+ "parse",
+ "lex",
+ "error",
+ /* Variables */
+ "lval",
+ "val",
+ "char",
+ "debug",
+ "errflag",
+ "nerrs",
+ NULL};
+ int i;
+
+ for (i = 0; syms[i]; i++)
+ fprintf(ftable, "#define\tyy%s\t%s%s\n",
+ syms[i], pre, syms[i]);
+}