aboutsummaryrefslogtreecommitdiff
path: root/unix/boot/xyacc/y2.c
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /unix/boot/xyacc/y2.c
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'unix/boot/xyacc/y2.c')
-rw-r--r--unix/boot/xyacc/y2.c1952
1 files changed, 1952 insertions, 0 deletions
diff --git a/unix/boot/xyacc/y2.c b/unix/boot/xyacc/y2.c
new file mode 100644
index 00000000..072b6c8c
--- /dev/null
+++ b/unix/boot/xyacc/y2.c
@@ -0,0 +1,1952 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+//#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "dextern.h"
+#include <stdio.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 char *tokname; /* input token name */
+char *parser = PARSER; /* location of common parser */
+
+static void finact (void);
+static char *cstash (char *);
+static void defout (void);
+static void cpyunion (void);
+static void cpycode (void);
+static void cpyact (int);
+static void lhsfill (char *);
+static void rhsfill (char *);
+static void lrprnt (void);
+#ifdef XYACC_DEBUG
+static void beg_debug (void);
+static void end_toks (void);
+static void end_debug (void);
+#endif
+static void exp_tokname (void);
+static void exp_prod (void);
+static void exp_ntok (void);
+static void exp_nonterm (void);
+static int defin (int, char *);
+static int gettok (void);
+static int chfind (int, char *);
+static int skipcom (void);
+static int findchtok (int);
+#ifdef PREFIX_DEFINE
+static void put_prefix_define (char *);
+#endif
+
+
+/* storage of names */
+
+/*
+ * initial block to place token and
+ * nonterminal names are stored
+ * points to initial block - more space
+ * is allocated as needed.
+ */
+static char cnamesblk0[CNAMSZ];
+static char *cnames = cnamesblk0;
+
+/* place where next name is to be put in */
+static char *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 char *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.x file */
+FILE *ftemp; /* tempfile to pass 2 */
+FILE *fudecl; /* file for user declarations */
+FILE *fsppout; /* SPP y.tab.x output file */
+FILE *fdebug; /* where the strings for debugging are stored */
+FILE *foutput; /* y.output file */
+
+ /* output string */
+
+static char *lhstext;
+static char *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;
+char *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";
+
+int nmbchars = 0; /* number of mb literals in mbchars */
+MBCLIT *mbchars = (MBCLIT *) 0; /* array of mb literals */
+int nmbcharsz = 0; /* allocated space for mbchars */
+
+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;
+ char 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];
+
+ foutput = NULL;
+ fdefine = NULL;
+ i = 1;
+
+ tokname = (char *) malloc (sizeof (char) * 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 = (char *) calloc ((nprodsz + 2), sizeof (char));
+ lhstext = (char *) calloc (1, sizeof (char) * LHS_TEXT_LEN);
+ rhstext = (char *) calloc (1, sizeof (char) * 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: NOAO/IRAF v1.0\n");
+ 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 ("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,
+ "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) {
+ (void) strncpy (fname,
+ file_prefix, F_NAME_LENGTH - strlen (".output"));
+ (void) strcat (fname, ".output");
+ foutput = fopen (fname, "w");
+ if (foutput == NULL)
+ error ("cannot open y.output");
+ }
+
+ /*
+ * Open y.tab.h if -d is specified
+ */
+ if (options & d_FLAG) {
+ (void) strncpy (fname,
+ file_prefix, F_NAME_LENGTH - strlen (".tab.h"));
+ (void) strcat (fname, ".tab.h");
+ fdefine = fopen (fname, "w");
+ if (fdefine == NULL)
+ error ("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 ("cannot open yacc.debug");
+ /*
+ * Open ytab.x
+ (void) strncpy(fname, file_prefix, F_NAME_LENGTH-strlen(".tab.x"));
+ (void) strcat(fname, ".tab.x");
+ ftable = fopen(fname, "w");
+ if (ftable == NULL)
+ error("cannot open %s", fname);
+ */
+
+
+ fsppout = fopen (OFILE, "w");
+ if (fsppout == NULL)
+ error ("cannot create output file");
+ ftable = fopen (TABFILE, "w");
+ if (ftable == NULL)
+ error ("cannot create table file");
+ fudecl = fopen (UDFILE, "w");
+ if (fudecl == NULL)
+ error ("cannot create user declarations file");
+
+
+ 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 ("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 ("cannot open input file");
+
+ lineno = 1;
+ cnamp = cnames;
+ (void) defin (0, "$end");
+ extval = 0400;
+ (void) defin (0, "error");
+ (void) defin (1, "$accept");
+ mem = mem0;
+ lev = 0;
+ ty = 0;
+ i = 0;
+#ifdef XYACC_DEBUG
+ beg_debug(); /* initialize fdebug file */
+#endif
+
+ /*
+ * sorry -- no yacc parser here.....
+ * we must bootstrap somehow...
+ */
+
+ t = gettok ();
+ if (*v_stmp == 'y')
+ (void) fprintf (ftable, "#ident\t\"yacc: NOAO/IRAF v1.0\"\n");
+ for (; t != MARK && t != ENDFILE;) {
+ int tok_in_line;
+ switch (t) {
+
+ case ';':
+ 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 ("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
+ ("type redeclaration of token %s",
+ 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
+ ("type redeclaration of nonterminal %s",
+ nontrst[t - NTBASE].name);
+ } else
+ nontrst[t - NTBASE].tvalue = ty;
+ }
+ /* FALLTHRU */
+ /*
+ * End Indentation
+ */
+ case ',':
+ continue;
+
+ case ';':
+ 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 ("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 ',':
+ t = gettok ();
+ continue;
+
+ case ';':
+ 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 ("%s 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
+ ("redeclaration of precedence of %s",
+ tokname);
+ SETASC (toklev[j], lev);
+ SETPLEV (toklev[j], i);
+ } else {
+ if (ASSOC (toklev[j]))
+ (void) warning (1,
+ "redeclaration of precedence of %s.",
+ tokname);
+ SETASC (toklev[j], lev);
+ }
+ if (ty) {
+ if (TYPE (toklev[j]))
+ error (
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ "redeclaration of type of %s", 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
+ ("type number of %s 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
+ ("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 ("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 ();
+#ifdef XYACC_DEBUG
+ end_toks(); /* all tokens dumped - get ready for reductions */
+#endif
+
+ fprintf (fsppout, "define\tyyclearin\tyychar = -1\n");
+ fprintf (fsppout, "define\tyyerrok\t\tyyerrflag = 0\n");
+ fprintf (fsppout,
+ "define\tYYMOVE\t\tcall amovi (Memi[$1], Memi[$2], YYOPLEN)\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 == '|') {
+ rhsfill ((char *) 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 ("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 ("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 ("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 ("nonterminal %s illegal after %%prec",
+ nontrst[j - NTBASE].name);
+ levprd[nprod] = toklev[j] & ~04;
+ t = gettok ();
+ }
+
+ if (t == '=') {
+ had_act[nprod] = 1;
+ levprd[nprod] |= ACTFLAG;
+ (void) fprintf (faction, "\ncase %d:", nprod);
+ cpyact (mem - prdptr[nprod] - 1);
+ /* !SPP (void) fprintf(faction, " break;"); */
+
+ if ((t = gettok ()) == IDENTIFIER) {
+ /* action within rule... */
+
+#ifdef XYACC_DEBUG
+ lrprnt(); /* dump lhs, rhs */
+#endif
+ (void) sprintf (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 == ';')
+ 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 */
+ int 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 ("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 ("default action causes potential type clash");
+ }
+ }
+
+ if (++nprod >= nprodsz)
+ exp_prod ();
+ prdptr[nprod] = mem;
+ levprd[nprod] = 0;
+ }
+ /* end of all rules */
+
+#ifdef XYACC_DEBUG
+ end_debug(); /* finish fdebug file's input */
+#endif
+ finact ();
+ if (t == MARK) {
+ /*
+ if (gen_lines)
+ (void) fprintf(fsppout, "\n# a line %d \"%s\"\n",
+ lineno, infile);
+ */
+ while ((c = getc (finput)) != EOF)
+ (void) putc (c, fsppout);
+ }
+ (void) fclose (finput);
+}
+
+static void
+finact ()
+{
+ /* finish action routine */
+ (void) fclose (faction);
+ (void) fprintf (fsppout, "define\tYYERRCODE\t%d\n", tokset[2].value);
+}
+
+static char *
+cstash (s)
+ register char *s;
+{
+ char *temp;
+ static int used = 0;
+ static int used_save = 0;
+ static int exp_cname = CNAMSZ;
+ int len = strlen (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 = (char *) malloc (sizeof (char) * 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 ("cannot expand string dump");
+ cnamp = cnames;
+ used = 0;
+ }
+
+ temp = cnamp;
+ do {
+ *cnamp++ = *s;
+ }
+ while (*s++);
+ used += cnamp - temp;
+ return (temp);
+}
+
+static int
+defin (int t, char *s)
+{
+ /* define s to be a terminal if t=0 or a nonterminal if t=1 */
+
+ int val;
+
+ val = 0;
+ 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] == ' ' && s[2] == 0) { /* single character literal */
+ val = findchtok (s[1]);
+ } else if (s[0] == ' ' && s[1] == '\\') { /* escape sequence */
+ if (s[3] == 0) { /* single character escape sequence */
+ switch (s[2]) {
+ /* character which is escaped */
+ case 'a':
+ (void) warning (1,
+/*
+ * 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 = '\a';
+ break;
+#else
+ val = '\007';
+ break;
+#endif
+ case 'v':
+ val = '\v';
+ break;
+ case 'n':
+ val = '\n';
+ break;
+ case 'r':
+ val = '\r';
+ break;
+ case 'b':
+ val = '\b';
+ break;
+ case 't':
+ val = '\t';
+ break;
+ case 'f':
+ val = '\f';
+ break;
+ case '\'':
+ val = '\'';
+ break;
+ case '"':
+ val = '"';
+ break;
+ case '?':
+ val = '?';
+ break;
+ case '\\':
+ val = '\\';
+ break;
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ default:
+ error ("invalid escape");
+ }
+ } else if (s[2] <= '7' && s[2] >= '0') { /* \nnn sequence */
+ int i = 3;
+ val = s[2] - '0';
+ while (isdigit (s[i]) && i <= 4) {
+ if (s[i] >= '0' && s[i] <= '7')
+ val = val * 8 + s[i] - '0';
+ else
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error ("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 ("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 char 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 ("'\\000' is illegal");
+ } else if (s[2] == '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, "\\x is ANSI C hex escape");
+ if (isxdigit (s[i]))
+ while (isxdigit (s[i])) {
+ int tmpval;
+ if (isdigit (s[i]))
+ tmpval = s[i] - '0';
+ else if (s[i] >= 'a')
+ tmpval = s[i] - 'a' + 10;
+ else
+ tmpval = s[i] - 'A' + 10;
+ val = 16 * val + tmpval;
+ i++;
+ } else
+ error ("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 ("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 (" \\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 ("'\\x00' is illegal");
+ val = findchtok (val);
+ } else
+ error ("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 char *cp;
+
+ for (i = ndefout; i <= ntokens; ++i) {
+
+ cp = tokset[i].name;
+ if (*cp == ' ') { /* literals */
+ (void) fprintf (fdebug, WSFMT ("\t\"%s\",\t%d,\n"),
+ tokset[i].name + 1, tokset[i].value);
+ continue; /* was cp++ */
+ }
+
+ for (; (c = *cp) != 0; ++cp) {
+ if (islower (c) || isupper (c) || isdigit (c) || c == '_')
+ /* EMPTY */ ;
+ else
+ goto nodef;
+ }
+
+ (void) fprintf (fdebug,
+ WSFMT ("\t\"%s\",\t%d,\n"), tokset[i].name,
+ tokset[i].value);
+ (void) fprintf (fsppout, WSFMT ("define\t%s\t\t%d\n"),
+ tokset[i].name, tokset[i].value);
+ if (fdefine != NULL)
+ (void) fprintf (fdefine,
+ WSFMT ("define\t%s\t\t%d\n"), tokset[i].name,
+ tokset[i].value);
+
+ nodef:;
+ }
+ ndefout = ntokens + 1;
+}
+
+static int
+gettok ()
+{
+ int i, base;
+ static int peekline; /* number of '\n' seen in lookahead */
+ int c, match, reserve;
+ begin:
+ reserve = 0;
+ lineno += peekline;
+ peekline = 0;
+ c = getc (finput);
+ /*
+ * while (c == ' ' || c == '\n' || c == '\t' || c == '\f') {
+ */
+ while (isspace (c)) {
+ if (c == '\n')
+ ++lineno;
+ c = getc (finput);
+ }
+ if (c == '#') { /* skip comment */
+ lineno += skipcom ();
+ goto begin;
+ }
+
+ switch (c) {
+
+ case EOF:
+ return (ENDFILE);
+ case '{':
+ (void) ungetc (c, finput);
+ return ('='); /* action ... */
+ case '<': /* get, and look up, a type name (union member name) */
+ i = 0;
+ while ((c = getc (finput)) != '>' && c != EOF && c != '\n') {
+ tokname[i] = c;
+ if (++i >= toksize)
+ exp_tokname ();
+ }
+ if (c != '>')
+ error ("unterminated < ... > clause");
+ tokname[i] = 0;
+ if (i == 0)
+ error ("missing type name in < ... > clause");
+ for (i = 1; i <= ntypes; ++i) {
+ if (!strcmp (typeset[i], tokname)) {
+ numbval = i;
+ return (TYPENAME);
+ }
+ }
+ typeset[numbval = ++ntypes] = cstash (tokname);
+ return (TYPENAME);
+
+ case '"':
+ case '\'':
+ match = c;
+ tokname[0] = ' ';
+ i = 1;
+ for (;;) {
+ c = getc (finput);
+ if (c == '\n' || c == EOF)
+ error ("illegal or missing ' or \"");
+ if (c == '\\') {
+ c = getc (finput);
+ tokname[i] = '\\';
+ if (++i >= toksize)
+ exp_tokname ();
+ } else if (c == match)
+ break;
+ tokname[i] = c;
+ if (++i >= toksize)
+ exp_tokname ();
+ }
+ break;
+
+ case '%':
+ case '\\':
+
+ switch (c = getc (finput)) {
+
+ case '0':
+ return (TERM);
+ case '<':
+ return (LEFT);
+ case '2':
+ return (BINARY);
+ case '>':
+ return (RIGHT);
+ case '%':
+ case '\\':
+ return (MARK);
+ case '=':
+ return (PREC);
+ case '{':
+ return (LCURLY);
+ default:
+ reserve = 1;
+ }
+
+ default:
+
+ if (isdigit (c)) { /* number */
+ numbval = c - '0';
+ base = (c == '0') ? 8 : 10;
+ for (c = getc (finput); isdigit (c); c = getc (finput)) {
+ numbval = numbval * base + c - '0';
+ }
+ (void) ungetc (c, finput);
+ return (NUMBER);
+ } else if (islower (c) || isupper (c) ||
+ c == '_' || c == '.' || c == '$') {
+ i = 0;
+ while (islower (c) || isupper (c) ||
+ isdigit (c) || c == '_' || c == '.' || c == '$') {
+ tokname[i] = c;
+ if (reserve && isupper (c))
+ tokname[i] = tolower (c);
+ if (++i >= toksize)
+ exp_tokname ();
+ c = getc (finput);
+ }
+ } else
+ return (c);
+
+ (void) ungetc (c, finput);
+ }
+
+ tokname[i] = 0;
+
+ if (reserve) { /* find a reserved word */
+ if (!strcmp (tokname, "term"))
+ return (TERM);
+ if (!strcmp (tokname, "token"))
+ return (TERM);
+ if (!strcmp (tokname, "left"))
+ return (LEFT);
+ if (!strcmp (tokname, "nonassoc"))
+ return (BINARY);
+ if (!strcmp (tokname, "binary"))
+ return (BINARY);
+ if (!strcmp (tokname, "right"))
+ return (RIGHT);
+ if (!strcmp (tokname, "prec"))
+ return (PREC);
+ if (!strcmp (tokname, "start"))
+ return (START);
+ if (!strcmp (tokname, "type"))
+ return (TYPEDEF);
+ if (!strcmp (tokname, "union"))
+ return (UNION);
+ error ("invalid escape, or illegal reserved word: %s", tokname);
+ }
+
+ /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
+
+ c = getc (finput);
+ /*
+ * while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/')
+ * {
+ */
+ while (isspace (c) || c == '/') {
+ if (c == '\n') {
+ ++peekline;
+ } else if (c == '#') { /* look for comments */
+ peekline += skipcom ();
+ }
+ c = getc (finput);
+ }
+ if (c == ':')
+ return (C_IDENTIFIER);
+ (void) ungetc (c, finput);
+ return (IDENTIFIER);
+}
+
+static int
+fdtype (int t)
+{
+ /* determine the type of a symbol */
+ int v;
+ if (t >= NTBASE)
+ v = nontrst[t - NTBASE].tvalue;
+ else
+ v = TYPE (toklev[t]);
+ if (v <= 0)
+ error ("must specify type for %s",
+ (t >= NTBASE) ? nontrst[t - NTBASE].name : tokset[t].name);
+ return (v);
+}
+
+static int
+chfind (int t, char *s)
+{
+ int i;
+
+ if (s[0] == ' ')
+ t = 0;
+ TLOOP (i) {
+ if (!strcmp (s, tokset[i].name)) {
+ return (i);
+ }
+ }
+ NTLOOP (i) {
+ if (!strcmp (s, nontrst[i].name)) {
+ return (i + NTBASE);
+ }
+ }
+ /* cannot find name */
+ if (t > 1)
+ error ("%s 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 (fsppout, "\n# line %d \"%s\"\n", lineno, infile);
+ (void) fprintf (fsppout, "typedef union\n");
+ if (fdefine)
+ (void) fprintf (fdefine, "\ntypedef union\n");
+ (void) fprintf (fsppout, "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
+ if (fdefine)
+ (void) fprintf (fdefine, "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
+
+ level = 0;
+ for (;;) {
+ if ((c = getc (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 ("EOF encountered while processing %%union");
+ (void) putc (c, fsppout);
+ if (fdefine)
+ (void) putc (c, fdefine);
+
+ switch (c) {
+
+ case '\n':
+ ++lineno;
+ break;
+
+ case '{':
+ ++level;
+ break;
+
+ case '}':
+ --level;
+ if (level == 0) { /* we are finished copying */
+ (void) fprintf (fsppout, " YYSTYPE;\n");
+ if (fdefine)
+ (void) fprintf (fdefine,
+ " YYSTYPE;\nextern YYSTYPE yylval;\n");
+ return;
+ }
+ }
+ }
+}
+
+static void
+cpycode ()
+{
+ /* copies code between \{ and \} */
+ int c;
+ FILE *out;
+
+
+ c = getc (finput);
+ if (c == '\n') {
+ c = getc (finput);
+ lineno++;
+ }
+
+ /* The %{ .. %} section is divided up into a global and a local region.
+ * The global region is first, so set the out file to fsppout (write
+ * directly into SPP output file). The start of the local declarations
+ * for the parser is marked by %L. When this is seen, direct output
+ * into the temp file fudecl, which is later inserted into the
+ * declarations section of yyparse.
+ */
+ out = fsppout;
+
+ if (gen_lines)
+ (void) fprintf (out, "\n# line %d \"%s\"\n", lineno, infile);
+ for (; c >= 0; c = getc (finput)) {
+ if (c == '\\') {
+ if ((c = getc (finput)) == '}')
+ return;
+ else
+ putc ('\\', out);
+ }
+ if (c == '%') {
+ if ((c = getc (finput)) == '}') {
+ return;
+ } else if (c == 'L') {
+ out = fudecl;
+ continue;
+ } else
+ putc ('%', out);
+ }
+ putc (c, out);
+ if (c == '\n')
+ ++lineno;
+ }
+
+ error ("eof before %%}");
+}
+
+static int
+skipcom ()
+{
+ register int ch;
+
+ /* skip over SPP comments */
+ while ((ch = getc (finput)) != '\n')
+ if (ch == EOF)
+ error ("EOF inside comment");
+
+ return (1);
+}
+
+
+static void
+cpyact (int offset)
+{
+ /* copy C action to the next ; or closing } */
+ int brac, c, match, j, s, tok, argument;
+ char 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 = getc (finput);
+ swt:
+ switch (c) {
+ case ';':
+ if (brac == 0) {
+ (void) putc (c, faction);
+ return;
+ }
+ goto lcopy;
+ case '{':
+ brac++;
+ goto lcopy;
+ case '$':
+ s = 1;
+ tok = -1;
+ argument = 1;
+ while ((c = getc (finput)) == ' ' || c == '\t')
+ /* NULL */ ;
+ if (c == '<') { /* type description */
+ (void) ungetc (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 ("bad syntax on $<ident> clause");
+ tok = numbval;
+ c = getc (finput);
+ }
+ if (c == '$') {
+ (void) fprintf (faction, "yyval");
+ if (ntypes) { /* put out the proper tag... */
+ if (tok < 0)
+ tok = fdtype (*prdptr[nprod]);
+ (void) fprintf (faction, WSFMT (".%s"), typeset[tok]);
+ }
+ goto loop;
+ }
+ if (c == '-') {
+ s = -s;
+ c = getc (finput);
+ }
+ if (isdigit (c)) {
+ j = 0;
+ while (isdigit (c)) {
+ j = j * 10 + c - '0';
+ c = getc (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 ("Illegal use of $%d", j + offset);
+ }
+
+ switch (-j) {
+ case 0:
+ fprintf (faction, "yypvt");
+ break;
+ case 1:
+ fprintf (faction, "yypvt-YYOPLEN");
+ break;
+ default:
+ fprintf (faction, "yypvt-%d*YYOPLEN", -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 ("must specify type of $%d", j + offset);
+ if (tok < 0)
+ tok = fdtype (prdptr[nprod][j + offset]);
+ (void) fprintf (faction, WSFMT (".%s"), typeset[tok]);
+ }
+ goto swt;
+ }
+ (void) putc ('$', faction);
+ if (s < 0)
+ (void) putc ('-', faction);
+ goto swt;
+ case '}':
+ if (--brac)
+ goto lcopy;
+ (void) putc (c, faction);
+ return;
+ case '/': /* look for comments */
+ (void) putc (c, faction);
+ c = getc (finput);
+ if (c != '*')
+ goto swt;
+ /* it really is a comment */
+ (void) putc (c, faction);
+ c = getc (finput);
+ while (c != EOF) {
+ while (c == '*') {
+ (void) putc (c, faction);
+ if ((c = getc (finput)) == '/')
+ goto lcopy;
+ }
+ (void) putc (c, faction);
+ if (c == '\n')
+ ++lineno;
+ c = getc (finput);
+ }
+ error ("EOF inside comment");
+ /* FALLTHRU */
+ case '\'': /* character constant */
+ case '"': /* character string */
+ match = c;
+ (void) putc (c, faction);
+ while ((c = getc (finput)) != EOF) {
+ if (c == '\\') {
+ (void) putc (c, faction);
+ c = getc (finput);
+ if (c == '\n')
+ ++lineno;
+ } else if (c == match)
+ goto lcopy;
+ else if (c == '\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 ("newline in string or char. const.");
+ (void) putc (c, faction);
+ }
+ error ("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 ("action does not terminate");
+ /* FALLTHRU */
+ case '\n':
+ ++lineno;
+ goto lcopy;
+ }
+ lcopy:
+ (void) putc (c, faction);
+ /*
+ * Save the possible identifier name.
+ * Used to print out a warning message.
+ */
+ if (id_idx >= NAMESIZE) {
+ /*
+ * Error. Silently ignore.
+ */
+ /* EMPTY */ ;
+ }
+ /*
+ * If c has a possibility to be a
+ * part of identifier, save it.
+ */
+ else if (isalnum (c) || c == '_') {
+ 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 */
+ char *s;
+{
+ static int lhs_len = LHS_TEXT_LEN;
+ int s_lhs = strlen (s);
+ if (s_lhs >= lhs_len) {
+ lhs_len = s_lhs + 2;
+ lhstext = (char *)
+ realloc ((char *) lhstext, sizeof (char) * 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 ("couldn't expanded LHS length");
+ }
+ rhsfill ((char *) 0);
+ (void) strcpy (lhstext, s); /* don't worry about too long of a name */
+}
+
+static void
+rhsfill (s)
+ char *s; /* either name or 0 */
+{
+ static char *loc; /* next free location in rhstext */
+ static int rhs_len = RHS_TEXT_LEN;
+ static int used = 0;
+ int s_rhs = (s == NULL ? 0 : strlen (s));
+ register char *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 char *textbase;
+ textbase = rhstext;
+ rhs_len += s_rhs + RHS_TEXT_LEN;
+ rhstext = (char *)
+ realloc ((char *) rhstext, sizeof (char) * 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 ("couldn't expanded RHS length");
+ loc = loc - textbase + rhstext;
+ }
+
+ *loc++ = ' ';
+ if (*s == ' ') { /* special quoted symbol */
+ *loc++ = '\''; /* add first quote */
+ p++;
+ }
+ while ((*loc = *p++)) {
+ if (loc++ > &rhstext[RHS_TEXT_LEN] - 3)
+ break;
+ }
+
+ if (*s == ' ')
+ *loc++ = '\'';
+ *loc = 0; /* terminate the string */
+}
+
+static void
+lrprnt ()
+{ /* print out the left and right hand sides */
+ char *rhs;
+ char *m_rhs = NULL;
+
+ if (!*rhstext) /* empty rhs - print usual comment */
+ rhs = " /* empty */";
+ else {
+ int idx1; /* tmp idx used to find if there are d_quotes */
+ int idx2; /* tmp idx used to generate escaped string */
+ char *p;
+ /*
+ * Check if there are any double quote in RHS.
+ */
+ for (idx1 = 0; rhstext[idx1] != 0; idx1++) {
+ if (rhstext[idx1] == '"') {
+ /*
+ * A double quote is found.
+ */
+ idx2 = strlen (rhstext) * 2;
+ p = m_rhs = (char *)
+ malloc ((idx2 + 1) * sizeof (char));
+ 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 ("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] == '"') {
+ 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++ = '\\';
+ }
+ *p++ = rhstext[idx2];
+ }
+ *p = 0;
+ /*
+ * Break from the loop
+ */
+ break;
+ }
+ }
+ if (m_rhs == NULL)
+ rhs = rhstext;
+ else
+ rhs = m_rhs;
+ }
+ (void) fprintf (fdebug, WSFMT ("\t\"%s :%s\",\n"), lhstext, rhs);
+ if (m_rhs)
+ free (m_rhs);
+}
+
+
+#ifdef XYACC_DEBUG
+
+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);
+}
+
+#endif
+
+
+/*
+ * 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 = (char *) realloc ((char *) tokname, sizeof (char) * 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 = (char *)
+ realloc ((char *) had_act, sizeof (char) * (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 ("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 ("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 ("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 ("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;
+
+ 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 ("too many character literals");
+ }
+ mbchars[nmbchars - 1].character = chlit;
+ return (mbchars[nmbchars - 1].tvalue = extval++);
+ /* Return the newly assigned token. */
+}
+
+/*
+ * When -p is specified, symbol prefix for
+ * yy{parse, lex, error}(),
+ * yy{lval, val, char, debug, errflag, nerrs}
+ * are defined to the specified name.
+ */
+#ifdef PREFIX_DEFINE
+
+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++)
+ (void) fprintf (fsppout, "define\tyy%s\t%s%s\n",
+ syms[i], pre, syms[i]);
+}
+
+#endif
+
+