# # 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 (c) 1995,1997 by Sun Microsystems, Inc. # All Rights Reserved. # # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. include ../../../Makefile.master SUBDIRS = $(MACH64) CSRC= common/y1.c common/y2.c common/y3.c common/y4.c # conditional statements all : TARGET= all install : TARGET= install install_lib : TARGET= install_lib clean : TARGET= clean clobber : TARGET= clobber # for messaging catalog # POFILE= yacc.po .KEEP_STATE: all clean clobber install install_lib: $(SUBDIRS) catalog: $(POFILE) $(POFILE): $(RM) $@ $(XGETTEXT) $(XGETFLAGS) $(CSRC) sed "/^domain/d" < messages.po > $@ $(RM) messages.po $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # 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 2015 Gary Mills # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright (c) 2018, Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # PROG= yacc COMOBJS= y1.o y2.o y3.o y4.o POBJECTS= $(COMOBJS) POBJS= $(POBJECTS:%=objs/%) OBJECTS= libmai.o libzer.o LIBRARY= liby.a VERS= .1 YACCPAR= yaccpar include ../../../../lib/Makefile.lib COMPATLINKS= usr/ccs/lib/liby.so # Hammerhead: flattened layout — no amd64 subdir COMPATLINKS64= $(COMPATLINKS) $(ROOT)/usr/ccs/lib/liby.so : COMPATLINKTARGET=../../lib/liby.so.1 SRCDIR = ../common # Override default source file derivation rule (in Makefile.lib) # from objects # COMSRCS= $(COMOBJS:%.o=../common/%.c) LIBSRCS= $(OBJECTS:%.o=../common/%.c) SRCS= $(COMSRCS) $(LIBSRCS) LIBS = $(DYNLIB) # Tune ZDEFS to ignore undefined symbols for building the yacc shared library # since these symbols (mainly yyparse) are to be resolved elsewhere. # $(DYNLIB): ZDEFS = $(ZNODEFS) $(DYNLIBCCC): ZDEFS = $(ZNODEFS) INCLIST= -I../../include -I../../include/$(MACH) CPPFLAGS= $(INCLIST) $(DEFLIST) $(CPPFLAGS.master) $(PROG): LDLIBS = $(LDLIBS.cmd) CSTD= $(CSTD_GNU99) CFLAGS += $(CCVERBOSE) CFLAGS64 += $(CCVERBOSE) $(ROOTPROG): FILEMODE = 0555 ROOTYACCPAR= $(YACCPAR:%=$(ROOTSHLIBCCS)/%) DYNLINKLIBDIR= $(ROOTLIBDIR) DYNLINKLIB= $(LIBLINKS:%=$(DYNLINKLIBDIR)/%) LDLIBS += -lc CLOBBERFILES += $(LIBS) $(LIBRARY) # # 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 2015 Gary Mills # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # .SECONDEXPANSION: $(PROG): objs .WAIT $(POBJS) $(LINK.c) $(POBJS) -o $@ $(LDLIBS) $(POST_PROCESS) # conditional assignment of default permissions for the installed # DYNLIB/DYNLIBCCC. Set here and in Makefile.mach, instead of Makefile.lib, # because ROOTLIBDIR may be changed in the including makefile after it has # included Makefile.lib. # $(ROOTLIBDIR)/$(DYNLIB) : FILEMODE= 755 $(ROOTLIBDIR)/$(DYNLIBCCC) : FILEMODE= 755 $(ROOTLIBDIR64)/$(DYNLIB) : FILEMODE= 755 $(ROOTLIBDIR64)/$(DYNLIBCCC) : FILEMODE= 755 # library install rules $(ROOTLIBDIR)/%: % $(INS.file) $(ROOTLIBDIR64)/%: % $(INS.file) $(ROOTLIBDIR)/$(LIBLINKS): $(ROOTLIBDIR)/$(LIBLINKS)$(VERS) $(INS.liblink) $(ROOTLIBDIR64)/$(LIBLINKS): $(ROOTLIBDIR64)/$(LIBLINKS)$(VERS) $(INS.liblink64) $(ROOTLIBDIR)/$(LIBLINKSCCC): $(ROOTLIBDIR)/$(LIBLINKSCCC)$(VERS) $(INS.liblinkccc) $(ROOTLIBDIR64)/$(LIBLINKSCCC): $(ROOTLIBDIR64)/$(LIBLINKSCCC)$(VERS) $(INS.liblinkccc64) objs pics: -@mkdir -p $@ $(DYNLIB): pics .WAIT $$(PICS) $(BUILD.SO) $(POST_PROCESS_SO) $(DYNLIBCCC): pics .WAIT $$(PICS) $(BUILDCCC.SO) $(POST_PROCESS_SO) objs/%.o: ../common/%.c $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) pics/%.o: ../common/%.c $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) $(DYNLINKLIBDIR)/%: %$(VERS) $(INS.liblink) $(ROOTCOMPATLINKS) $(ROOTCOMPATLINKS64): $(RM) $@; $(SYMLINK) $(COMPATLINKTARGET) $@ clean: $(RM) $(POBJS) $(OBJS) $(PICS) $(CLEANFILES) # # 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 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Makefile is only to produce 64-bit yacc shared library liby.so.1 # and not for building 64-bit yacc itself. # include ../Makefile.com include ../../../../lib/Makefile.lib.64 # no messaging files here POFILE= .KEEP_STATE: all_lib: $(LIBS) install_lib: all_lib $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTCOMPATLINKS64) include ../Makefile.targ include ../../../Makefile.targ all: FRC install: FRC FRC: /* * 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 */ #ifndef _DEXTERN_H #define _DEXTERN_H #include #include #include #include #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* MANIFEST CONSTANT DEFINITIONS */ #if u3b || u3b15 || u3b2 || vax || uts || sparc #define WORD32 #endif #include /* base of nonterminal internal numbers */ #define NTBASE (10000000) /* internal codes for error and accept actions */ #define ERRCODE 8190 #define ACCEPTCODE 8191 /* sizes and limits */ #define ACTSIZE 4000 #define MEMSIZE 2000 #define PSTSIZE 1024 #define NSTATES 1000 #define NTERMS 127 #define NPROD 300 #define NNONTERM 600 #define TEMPSIZE 800 #define CNAMSZ 1000 #define LSETSIZE 950 #define WSETSIZE 850 #define NAMESIZE 50 #define NTYPES 1000 #define NMBCHARSZ 100 #define LKFACTOR 5 #ifdef WORD32 /* bit packing macros (may be machine dependent) */ #define BIT(a, i) ((a)[(i)>>5] & (1<<((i)&037))) #define SETBIT(a, i) ((a)[(i)>>5] |= (1<<((i)&037))) /* number of words needed to hold n+1 bits */ #define NWORDS(n) (((n)+32)/32) #else /* bit packing macros (may be machine dependent) */ #define BIT(a, i) ((a)[(i)>>4] & (1<<((i)&017))) #define SETBIT(a, i) ((a)[(i)>>4] |= (1<<((i)&017))) /* number of words needed to hold n+1 bits */ #define NWORDS(n) (((n)+16)/16) #endif /* * relationships which must hold: * TBITSET ints must hold NTERMS+1 bits... * WSETSIZE >= NNONTERM * LSETSIZE >= NNONTERM * TEMPSIZE >= NTERMS + NNONTERMs + 1 * TEMPSIZE >= NSTATES */ /* associativities */ #define NOASC 0 /* no assoc. */ #define LASC 1 /* left assoc. */ #define RASC 2 /* right assoc. */ #define BASC 3 /* binary assoc. */ /* flags for state generation */ #define DONE 0 #define MUSTDO 1 #define MUSTLOOKAHEAD 2 /* flags for a rule having an action, and being reduced */ #define ACTFLAG 04 #define REDFLAG 010 /* output parser flags */ #define YYFLAG1 (-10000000) /* macros for getting associativity and precedence levels */ #define ASSOC(i) ((i)&07) #define PLEVEL(i) (((i)>>4)&077) #define TYPE(i) ((i>>10)&077) /* macros for setting associativity and precedence levels */ #define SETASC(i, j) i |= j #define SETPLEV(i, j) i |= (j<<4) #define SETTYPE(i, j) i |= (j<<10) /* looping macros */ #define TLOOP(i) for (i = 1; i <= ntokens; ++i) #define NTLOOP(i) for (i = 0; i <= nnonter; ++i) #define PLOOP(s, i) for (i = s; i < nprod; ++i) #define SLOOP(i) for (i = 0; i < nstate; ++i) #define WSBUMP(x) ++x #define WSLOOP(s, j) for (j = s; j < &wsets[cwp]; ++j) #define ITMLOOP(i, p, q) q = pstate[i+1]; for (p = pstate[i]; p < q; ++p) #define SETLOOP(i) for (i = 0; i < tbitset; ++i) /* I/O descriptors */ extern FILE *finput; /* input file */ extern FILE *faction; /* file for saving actions */ extern FILE *fdefine; /* file for #defines */ extern FILE *ftable; /* y.tab.c file */ extern FILE *ftemp; /* tempfile to pass 2 */ extern FILE *fdebug; /* tempfile for two debugging info arrays */ extern FILE *foutput; /* y.output file */ /* structure declarations */ typedef struct looksets { int *lset; } LOOKSETS; typedef struct item { int *pitem; LOOKSETS *look; } ITEM; typedef struct toksymb { wchar_t *name; int value; } TOKSYMB; typedef struct mbclit { wchar_t character; int tvalue; /* token issued for the character */ } MBCLIT; typedef struct ntsymb { wchar_t *name; int tvalue; } NTSYMB; typedef struct wset { int *pitem; int flag; LOOKSETS ws; } WSET; /* token information */ extern int ntokens; /* number of tokens */ extern TOKSYMB *tokset; extern int ntoksz; /* * multibyte (c > 255) character literals are * handled as though they were tokens except * that it generates a separate mapping table. */ extern int nmbchars; /* number of mb literals */ extern MBCLIT *mbchars; extern int nmbcharsz; /* nonterminal information */ extern int nnonter; /* the number of nonterminals */ extern NTSYMB *nontrst; extern int nnontersz; /* grammar rule information */ extern int nprod; /* number of productions */ extern int **prdptr; /* pointers to descriptions of productions */ extern int *levprd; /* contains production levels to break conflicts */ extern wchar_t *had_act; /* set if reduction has associated action code */ /* state information */ extern int nstate; /* number of states */ extern ITEM **pstate; /* pointers to the descriptions of the states */ extern int *tystate; /* contains type information about the states */ extern int *defact; /* the default action of the state */ extern int size; /* lookahead set information */ extern int TBITSET; extern LOOKSETS *lkst; extern int nolook; /* flag to turn off lookahead computations */ /* working set information */ extern WSET *wsets; /* storage for productions */ extern int *mem0; extern int *mem; extern int *tracemem; extern int new_memsize; /* storage for action table */ extern int *amem; extern int *memp; /* next free action table position */ extern int *indgo; /* index to the stored goto table */ extern int new_actsize; /* temporary vector, indexable by states, terms, or ntokens */ extern int *temp1; extern int lineno; /* current line number */ /* statistics collection variables */ extern int zzgoent; extern int zzgobest; extern int zzacent; extern int zzexcp; extern int zzrrconf; extern int zzsrconf; /* define external functions */ extern void setup(int, char *[]); extern void closure(int); extern void output(void); extern void aryfil(int *, int, int); extern void error(char *, ...); extern void warning(int, char *, ...); extern void putitem(int *, LOOKSETS *); extern void go2out(void); extern void hideprod(void); extern void callopt(void); extern void warray(wchar_t *, int *, int); extern wchar_t *symnam(int); extern wchar_t *writem(int *); extern void exp_mem(int); extern void exp_act(int **); extern int apack(int *, int); extern int state(int); extern void fprintf3(FILE *, const char *, const wchar_t *, const char *, ...); extern void error3(const char *, const wchar_t *, const char *, ...); extern wchar_t *wscpy(wchar_t *, const wchar_t *); extern size_t wslen(const wchar_t *); extern int wscmp(const wchar_t *, const wchar_t *); /* yaccpar location */ extern char *parser; /* default settings for a number of macros */ /* name of yacc tempfiles */ #ifndef TEMPNAME #define TEMPNAME "yacc.tmp" #endif #ifndef ACTNAME #define ACTNAME "yacc.acts" #endif #ifndef DEBUGNAME #define DEBUGNAME "yacc.debug" #endif /* command to clobber tempfiles after use */ #ifndef ZAPFILE #define ZAPFILE(x) (void)unlink(x) #endif #ifndef PARSER #define PARSER "/usr/share/lib/ccs/yaccpar" #endif #ifdef __cplusplus } #endif #endif /* _DEXTERN_H */ /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1989 AT&T */ /* All Rights Reserved */ #include #pragma weak yyparse extern int yyparse(void); /* ARGSUSED */ int main(int argc, char **argv) { (void) setlocale(LC_ALL, ""); (void) yyparse(); return (0); } /* * 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 (c) 1989 AT&T */ /* All Rights Reserved */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include int yyerror(const char *s) { (void) fprintf(stderr, "%s\n", s); return (0); } # # Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. # # 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 # # interface definition for yacc library # # # MAPFILE HEADER START # # WARNING: STOP NOW. DO NOT MODIFY THIS FILE. # Object versioning must comply with the rules detailed in # # usr/src/lib/README.mapfiles # # You should not be making modifications here until you've read the most current # copy of that file. If you need help, contact a gatekeeper for guidance. # # MAPFILE HEADER END # $mapfile_version 2 SYMBOL_VERSION SUNW_1.1 { global: main; yyerror; local: *; }; /* * 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 */ #include "dextern.h" #include #include #include #include #include /* For error() */ static void mktbls(void); static void others(void); static void summary(void); static wchar_t *chcopy(wchar_t *, wchar_t *); static int setunion(int *, int *); static void prlook(LOOKSETS *); static void cpres(void); static void cpfir(void); static void cempty(void); static void stagen(void); static LOOKSETS *flset(LOOKSETS *); static void exp_lkst(void); static void exp_wsets(void); static void exp_states(void); static void exp_psmem(void); /* lookahead computations */ int TBITSET; static int tbitset; /* size of lookahead sets */ LOOKSETS *lkst; static int lsetsize; static int nlset = 0; /* next lookahead set index */ int nolook = 0; /* flag to suppress lookahead computations */ static LOOKSETS clset; /* temporary storage for lookahead computations */ static ITEM *psmem, *zzmemsz; static int new_pstsize = PSTSIZE; /* working set computations */ WSET *wsets; int cwp; static int wsetsz = 0; /* number of WSET items in wsets block */ /* state information */ int nstate = 0; /* number of states */ static int nstatesz = NSTATES; /* number of state space allocated */ ITEM **pstate; /* ptr to descriptions of the states */ int *tystate; /* contains type info about the states */ int *indgo; /* index to the stored goto table */ static int *tmp_lset; static int *tstates; /* states generated by terminal gotos */ static int *ntstates; /* states generated by non-term gotos */ static int *mstates; /* chain of overflows of term/nonterm */ /* generation lists */ /* storage for the actions in the parser */ int *amem, *memp; /* next free action table position */ int new_actsize = ACTSIZE; /* other storage areas */ int *temp1; /* temp storate, indexed by terms+ntokens or states */ int lineno = 0; /* current input line number */ int size; static int fatfl = 1; /* if on, error is fatal */ static int nerrors = 0; /* number of errors */ /* storage for information about the nonterminals */ static int ***pres; /* vector of pointers to productions */ /* yielding each nonterminal */ static LOOKSETS **pfirst; /* vector of pointers to first sets for */ /* each nonterminal */ static int *pempty; /* vector of nonterminals nontrivially */ /* deriving e */ extern int nprodsz; int main(int argc, char *argv[]) { (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); setup(argc, argv); /* initialize and read productions */ TBITSET = NWORDS(ntoksz*LKFACTOR); tbitset = NWORDS(ntokens*LKFACTOR); mktbls(); cpres(); /* make table of which productions yield a */ /* given nonterminal */ cempty(); /* make a table of which nonterminals can match */ /* the empty string */ cpfir(); /* make a table of firsts of nonterminals */ stagen(); /* generate the states */ output(); /* write the states and the tables */ go2out(); hideprod(); summary(); callopt(); others(); return (0); } static void mktbls(void) { int i; size = ntoksz + nnontersz +1; if (size < nstatesz) size = nstatesz; if (size < new_memsize) size = new_memsize; amem = (int *) malloc(sizeof (int) * new_actsize); psmem = (ITEM *) malloc(sizeof (ITEM) * new_pstsize); if ((psmem == NULL) || (amem == NULL)) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * This error happens when yacc could not allocate * initial memory to be used for internal tables. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "couldn't allocate initial table")); zzmemsz = psmem; memp = amem; /* * For lkst */ #define INIT_LSIZE nnontersz * LKFACTOR tmp_lset = (int *) calloc((size_t)(TBITSET * (INIT_LSIZE+1)), sizeof (int)); if (tmp_lset == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Yacc could not allocate memory for table named lookset. * Do not translate 'lookset'. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "could not allocate lookset array")); lkst = (LOOKSETS *) malloc(sizeof (LOOKSETS) * (INIT_LSIZE + 1)); for (i = 0; i <= INIT_LSIZE; ++i) lkst[i].lset = tmp_lset + TBITSET * i; tmp_lset = NULL; /* * For wsets */ tmp_lset = (int *) calloc((size_t)(TBITSET * (nnontersz+1)), sizeof (int)); if (tmp_lset == NULL) error(gettext( "could not allocate lookset array")); wsets = (WSET *) malloc(sizeof (WSET) * (nnontersz + 1)); for (i = 0; i <= nnontersz; ++i) wsets[i].ws.lset = tmp_lset + TBITSET * i; tmp_lset = NULL; clset.lset = (int *)malloc(sizeof (int)*TBITSET); tstates = (int *)malloc(sizeof (int)*(ntoksz + 1)); ntstates = (int *)malloc(sizeof (int)*(nnontersz + 1)); temp1 = (int *)malloc(sizeof (int)*size); pres = (int ***)malloc(sizeof (int **)*(nnontersz + 2)); pfirst = (LOOKSETS **)malloc(sizeof (LOOKSETS *)*(nnontersz + 2)); pempty = (int *)malloc(sizeof (int)*(nnontersz + 1)); pstate = (ITEM **)malloc(sizeof (ITEM *)*(nstatesz+2)); tystate = (int *)malloc(sizeof (int)*nstatesz); indgo = (int *)malloc(sizeof (int)*nstatesz); mstates = (int *)malloc(sizeof (int)*nstatesz); defact = (int *)malloc(sizeof (int)*nstatesz); if ((lkst == NULL) || (wsets == NULL) || (tstates == NULL) || (ntstates == NULL) || (temp1 == NULL) || (pres == NULL) || (pfirst == NULL) || (pempty == NULL) || (pstate == NULL) || (tystate == NULL) || (indgo == NULL) || (mstates == NULL) || (defact == NULL) || (clset.lset == NULL)) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Do not translate mktbls(). It is a function name. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "cannot allocate tables in mktbls()")); aryfil(ntstates, nnontersz+1, 0); aryfil(tstates, ntoksz+1, 0); wsetsz = nnontersz + 1; lsetsize = INIT_LSIZE + 1; } /* put out other arrays, copy the parsers */ static void others(void) { extern int gen_lines; int c, i, j; int tmpline; finput = fopen(parser, "r"); if (finput == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * This error message is issued when yacc can not find * the parser to be copied. */ error(gettext( "cannot find parser %s"), parser); warray(L"yyr1", levprd, nprod); aryfil(temp1, nprod, 0); /* had_act[i] is either 1 or 0 */ PLOOP(1, i) temp1[i] = ((prdptr[i+1] - prdptr[i]-2) << 1) | had_act[i]; warray(L"yyr2", temp1, nprod); aryfil(temp1, nstate, -10000000); TLOOP(i) for (j = tstates[i]; j != 0; j = mstates[j]) temp1[j] = tokset[i].value; NTLOOP(i) for (j = ntstates[i]; j != 0; j = mstates[j]) temp1[j] = -i; warray(L"yychk", temp1, nstate); warray(L"yydef", defact, nstate); if ((fdebug = fopen(DEBUGNAME, "r")) == NULL) error("cannot open yacc.debug"); while ((c = getwc(fdebug)) != EOF) (void) putwc(c, ftable); (void) fclose(fdebug); ZAPFILE(DEBUGNAME); if (gen_lines) (void) fprintf(ftable, "# line\t1 \"%s\"\n", parser); tmpline = 1; /* copy parser text */ while ((c = getwc(finput)) != EOF) { if (c == '\n') tmpline++; if (c == L'$') { if ((c = getwc(finput)) != L'A') (void) putwc(L'$', ftable); else { /* copy actions */ tmpline++; faction = fopen(ACTNAME, "r"); if (faction == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * This error is issued when yacc can not open a * temporary file to be used. You do not need to * use the word 'tempfile'. You can translate it to * mean 'temporary file'. */ error(gettext( "cannot open action tempfile")); while ((c = getwc(faction)) != EOF) (void) putwc(c, ftable); (void) fclose(faction); if (gen_lines) (void) fprintf(ftable, "\n# line\t%d \"%s\"", tmpline, parser); ZAPFILE(ACTNAME); c = getwc(finput); } } (void) putwc(c, ftable); } (void) fclose(ftable); } /* copies string q into p, returning next free char ptr */ static wchar_t * chcopy(wchar_t *p, wchar_t *q) { while ((*p = *q++) != L'\0') ++p; return (p); } #define ISIZE 400 /* creates output string for item pointed to by pp */ wchar_t * writem(int *pp) { int i, *p; static int isize = ISIZE; static wchar_t *sarr = NULL; wchar_t *q; if (sarr == NULL) { sarr = (wchar_t *)malloc(sizeof (wchar_t) * isize); if (sarr == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * This error is issued when yacc could not allocate * memory for internally used array. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "could not allocate output string array")); for (i = 0; i < isize; ++i) sarr[i] = L' '; } for (p = pp; *p > 0; ++p) /* NULL */ ; p = prdptr[-*p]; q = chcopy(sarr, nontrst[*p-NTBASE].name); q = chcopy(q, L" : "); for (;;) { *q++ = ++p == pp ? L'_' : L' '; *q = 0; if ((i = *p) <= 0) break; q = chcopy(q, symnam(i)); while (q > &sarr[isize-30]) { static wchar_t *sarrbase; sarrbase = sarr; isize += ISIZE; sarr = (wchar_t *) realloc((char *)sarr, sizeof (*sarr) * isize); if (sarr == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * This error is issued when yacc could not allocate * memory for internally used array. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "cannot expand sarr arrays")); q = q - sarrbase + sarr; } } /* an item calling for a reduction */ if ((i = *pp) < 0) { q = chcopy(q, L" ("); (void) wsprintf(q, "%d)", -i); } return (sarr); } /* return a pointer to the name of symbol i */ wchar_t * symnam(int i) { wchar_t *cp; cp = (i >= NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name; if (*cp == L' ') ++cp; return (cp); } static int zzcwp = 0; static int zzclose = 0; int zzgoent = 0; int zzgobest = 0; int zzacent = 0; int zzexcp = 0; int zzsrconf = 0; int zzrrconf = 0; /* output the summary on the tty */ static void summary(void) { if (foutput != NULL) { (void) fprintf(foutput, "\n%d/%d terminals, %d/%d nonterminals\n", ntokens, ntoksz, nnonter, nnontersz); (void) fprintf(foutput, "%d/%d grammar rules, %d/%d states\n", nprod, nprodsz, nstate, nstatesz); (void) fprintf(foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf); (void) fprintf(foutput, "%d/%d working sets used\n", zzcwp, wsetsz); (void) fprintf(foutput, "memory: states,etc. %" PRIdPTR "/%d, parser %" PRIdPTR "/%d\n", mem-tracemem, new_memsize, memp-amem, new_actsize); (void) fprintf(foutput, "%d/%d distinct lookahead sets\n", nlset, lsetsize); (void) fprintf(foutput, "%d extra closures\n", zzclose - 2*nstate); (void) fprintf(foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp); (void) fprintf(foutput, "%d goto entries\n", zzgoent); (void) fprintf(foutput, "%d entries saved by goto default\n", zzgobest); } if (zzsrconf != 0 || zzrrconf != 0) { /* * TRANSLATION_NOTE -- This is a message from yacc. * You may just leave this message un-translated. * This message only makes sense to those who knows * how yacc works, and the person should know what * this message means in English. */ (void) fprintf(stderr, gettext( "\nconflicts: ")); if (zzsrconf) (void) fprintf(stderr, "%d shift/reduce", zzsrconf); if (zzsrconf && zzrrconf) (void) fprintf(stderr, ", "); if (zzrrconf) (void) fprintf(stderr, "%d reduce/reduce", zzrrconf); (void) fprintf(stderr, "\n"); } if (ftemp != NULL) (void) fclose(ftemp); if (fdefine != NULL) (void) fclose(fdefine); } /* write out error comment */ /*PRINTFLIKE1*/ void error(char *s, ...) { extern char *infile; va_list ap; va_start(ap, s); ++nerrors; if (!lineno) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is a prefix to the error messages * passed to error() function. */ (void) fprintf(stderr, gettext( "command line: fatal: ")); else { (void) fprintf(stderr, "\"%s\", ", infile); /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is a prefix to the error messages * passed to error() function. */ (void) fprintf(stderr, gettext( "line %d: fatal: "), lineno); } (void) vfprintf(stderr, s, ap); (void) fprintf(stderr, "\n"); va_end(ap); if (!fatfl) return; summary(); exit(1); } /* * Print out a warning message. */ /*PRINTFLIKE2*/ void warning(int flag, char *s, ...) { extern char *infile; va_list ap; va_start(ap, s); (void) fprintf(stderr, "\"%s\", ", infile); /* * If flag, print lineno as well. */ if (flag == 0) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is a prefix to the warning messages * passed to warning() function. */ (void) fprintf(stderr, gettext( "warning: ")); else /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is a prefix to the warning messages * passed to warning() function. */ (void) fprintf(stderr, gettext( "line %d: warning: "), lineno); (void) vfprintf(stderr, s, ap); (void) fprintf(stderr, "\n"); va_end(ap); } /* set elements 0 through n-1 to c */ void aryfil(int *v, int n, int c) { int i; for (i = 0; i < n; ++i) v[i] = c; } /* set a to the union of a and b */ /* return 1 if b is not a subset of a, 0 otherwise */ static int setunion(int *a, int *b) { int i, x, sub; sub = 0; SETLOOP(i) { *a = (x = *a) | *b++; if (*a++ != x) sub = 1; } return (sub); } static void prlook(LOOKSETS *p) { int j, *pp; pp = p->lset; if (pp == 0) (void) fprintf(foutput, "\tNULL"); else { (void) fprintf(foutput, " { "); TLOOP(j) { if (BIT(pp, j)) (void) fprintf(foutput, "%ws ", symnam(j)); } (void) fprintf(foutput, "}"); } } /* * compute an array with the beginnings of productions yielding * given nonterminals * The array pres points to these lists * the array pyield has the lists: the total size is only NPROD+1 */ static void cpres(void) { int **ptrpy; int **pyield; int c, j, i; /* * 2/29/88 - * nprodsz is the size of the tables describing the productions. * Normally this will be NPROD unless the production tables have * been expanded, in which case the tables will be NPROD * N(where * N is the number of times the tables had to be expanded.) */ if ((pyield = (int **) malloc(sizeof (int *) * nprodsz)) == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * This error is issued when yacc could not allocate * memory for internally used array. * * pyield is name of an array. You should not try to translate * this word. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "cannot allocate space for pyield array")); ptrpy = pyield; NTLOOP(i) { c = i+NTBASE; pres[i] = ptrpy; fatfl = 0; /* make undefined symbols nonfatal */ PLOOP(0, j) { if (*prdptr[j] == c) /* linear search for all c's */ *ptrpy++ = prdptr[j] + 1; } if (pres[i] == ptrpy) { /* c not found */ /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Ask somebody who knows yacc how to translate nonterminal or * look at translated yacc document. */ error(gettext( "undefined nonterminal: %ws"), nontrst[i].name); } } pres[i] = ptrpy; fatfl = 1; if (nerrors) { summary(); exit(1); } if (ptrpy != &pyield[nprod]) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * This is an internal error message. * Very little use to user. You may leave it * un-translated. * * pyied is name of an array. Do not translate it. */ error(gettext( "internal Yacc error: pyield %d"), ptrpy-&pyield[nprod]); } static int indebug = 0; /* compute an array with the first of nonterminals */ static void cpfir(void) { int *p, **s, i, **t, ch, changes; zzcwp = nnonter; NTLOOP(i) { aryfil(wsets[i].ws.lset, tbitset, 0); t = pres[i+1]; /* initially fill the sets */ for (s = pres[i]; s < t; ++s) { /* check if ch is non-terminal */ for (p = *s; (ch = *p) > 0; ++p) { if (ch < NTBASE) { /* should be token */ SETBIT(wsets[i].ws.lset, ch); break; } else if (!pempty[ch-NTBASE]) break; } } } /* now, reflect transitivity */ changes = 1; while (changes) { changes = 0; NTLOOP(i) { t = pres[i+1]; for (s = pres[i]; s < t; ++s) { for (p = *s; (ch = (*p-NTBASE)) >= 0; ++p) { changes |= setunion(wsets[i].ws.lset, wsets[ch].ws.lset); if (!pempty[ch]) break; } } } } NTLOOP(i) pfirst[i] = flset(&wsets[i].ws); if (!indebug) return; if ((foutput != NULL)) { NTLOOP(i) { (void) fprintf(foutput, "\n%ws: ", nontrst[i].name); prlook(pfirst[i]); (void) fprintf(foutput, " %d\n", pempty[i]); } } } /* sorts last state,and sees if it equals earlier ones. returns state number */ int state(int c) { int size1, size2; int i; ITEM *p1, *p2, *k, *l, *q1, *q2; p1 = pstate[nstate]; p2 = pstate[nstate+1]; if (p1 == p2) return (0); /* null state */ /* sort the items */ for (k = p2 - 1; k > p1; k--) { /* make k the biggest */ for (l = k-1; l >= p1; --l) if (l->pitem > k->pitem) { int *s; LOOKSETS *ss; s = k->pitem; k->pitem = l->pitem; l->pitem = s; ss = k->look; k->look = l->look; l->look = ss; } } size1 = p2 - p1; /* size of state */ for (i = (c >= NTBASE) ? ntstates[c-NTBASE] : tstates[c]; i != 0; i = mstates[i]) { /* get ith state */ q1 = pstate[i]; q2 = pstate[i+1]; size2 = q2 - q1; if (size1 != size2) continue; k = p1; for (l = q1; l < q2; l++) { if (l->pitem != k->pitem) break; ++k; } if (l != q2) continue; /* found it */ pstate[nstate+1] = pstate[nstate]; /* delete last state */ /* fix up lookaheads */ if (nolook) return (i); for (l = q1, k = p1; l < q2; ++l, ++k) { int s; SETLOOP(s) clset.lset[s] = l->look->lset[s]; if (setunion(clset.lset, k->look->lset)) { tystate[i] = MUSTDO; /* register the new set */ l->look = flset(&clset); } } return (i); } /* state is new */ if (nolook) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * You may leave this untranslated. Leave * state/nolook un-translated. */ error(gettext( "yacc state/nolook error")); pstate[nstate+2] = p2; if (nstate+1 >= nstatesz) exp_states(); if (c >= NTBASE) { mstates[nstate] = ntstates[c - NTBASE]; ntstates[c - NTBASE] = nstate; } else { mstates[nstate] = tstates[c]; tstates[c] = nstate; } tystate[nstate] = MUSTDO; return (nstate++); } static int pidebug = 0; void putitem(int *ptr, LOOKSETS *lptr) { register ITEM *j; if (pidebug && (foutput != NULL)) (void) fprintf(foutput, "putitem(%ws), state %d\n", writem(ptr), nstate); j = pstate[nstate+1]; j->pitem = ptr; if (!nolook) j->look = flset(lptr); pstate[nstate+1] = ++j; if (j > zzmemsz) { zzmemsz = j; if (zzmemsz >= &psmem[new_pstsize]) exp_psmem(); /* error("out of state space"); */ } } /* * mark nonterminals which derive the empty string * also, look for nonterminals which don't derive any token strings */ static void cempty(void) { #define EMPTY 1 #define WHOKNOWS 0 #define OK 1 int i, *p; /* * first, use the array pempty to detect productions * that can never be reduced */ /* set pempty to WHONOWS */ aryfil(pempty, nnonter+1, WHOKNOWS); /* * now, look at productions, marking nonterminals which * derive something */ more: PLOOP(0, i) { if (pempty[*prdptr[i] - NTBASE]) continue; for (p = prdptr[i] + 1; *p >= 0; ++p) if (*p >= NTBASE && pempty[*p-NTBASE] == WHOKNOWS) break; if (*p < 0) { /* production can be derived */ pempty[*prdptr[i]-NTBASE] = OK; goto more; } } /* now, look at the nonterminals, to see if they are all OK */ NTLOOP(i) { /* * the added production rises or falls as the * start symbol ... */ if (i == 0) continue; if (pempty[i] != OK) { fatfl = 0; /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Ask somebody who knows yacc how to translate nonterminal or * look at translated yacc document. Check how 'derive' is * translated in these documents also. */ error(gettext( "nonterminal %ws never derives any token string"), nontrst[i].name); } } if (nerrors) { summary(); exit(1); } /* * now, compute the pempty array, to see which nonterminals * derive the empty string */ /* set pempty to WHOKNOWS */ aryfil(pempty, nnonter+1, WHOKNOWS); /* loop as long as we keep finding empty nonterminals */ again: PLOOP(1, i) { /* not known to be empty */ if (pempty[*prdptr[i]-NTBASE] == WHOKNOWS) { for (p = prdptr[i]+1; *p >= NTBASE && pempty[*p-NTBASE] == EMPTY; ++p) ; /* we have a nontrivially empty nonterminal */ if (*p < 0) { pempty[*prdptr[i]-NTBASE] = EMPTY; goto again; /* got one ... try for another */ } } } } /* generate the states */ static int gsdebug = 0; static void stagen(void) { int i, j; int c; register WSET *p, *q; /* initialize */ nstate = 0; pstate[0] = pstate[1] = psmem; aryfil(clset.lset, tbitset, 0); putitem(prdptr[0] + 1, &clset); tystate[0] = MUSTDO; nstate = 1; pstate[2] = pstate[1]; aryfil(amem, new_actsize, 0); /* now, the main state generation loop */ more: SLOOP(i) { if (tystate[i] != MUSTDO) continue; tystate[i] = DONE; aryfil(temp1, nnonter + 1, 0); /* take state i, close it, and do gotos */ closure(i); WSLOOP(wsets, p) { /* generate goto's */ if (p->flag) continue; p->flag = 1; c = *(p->pitem); if (c <= 1) { if (pstate[i+1]-pstate[i] <= p-wsets) tystate[i] = MUSTLOOKAHEAD; continue; } /* do a goto on c */ WSLOOP(p, q) { /* this item contributes to the goto */ if (c == *(q->pitem)) { putitem(q->pitem + 1, &q->ws); q->flag = 1; } } if (c < NTBASE) (void) state(c); /* register new state */ else temp1[c-NTBASE] = state(c); } if (gsdebug && (foutput != NULL)) { (void) fprintf(foutput, "%d: ", i); NTLOOP(j) { if (temp1[j]) (void) fprintf(foutput, "%ws %d, ", nontrst[j].name, temp1[j]); } (void) fprintf(foutput, "\n"); } indgo[i] = apack(&temp1[1], nnonter - 1) - 1; goto more; /* we have done one goto; do some more */ } /* no more to do... stop */ } /* generate the closure of state i */ static int cldebug = 0; /* debugging flag for closure */ void closure(int i) { int c, ch, work, k; register WSET *u, *v; int *pi; int **s, **t; ITEM *q; register ITEM *p; int idx1 = 0; ++zzclose; /* first, copy kernel of state i to wsets */ cwp = 0; ITMLOOP(i, p, q) { wsets[cwp].pitem = p->pitem; wsets[cwp].flag = 1; /* this item must get closed */ SETLOOP(k) wsets[cwp].ws.lset[k] = p->look->lset[k]; WSBUMP(cwp); } /* now, go through the loop, closing each item */ work = 1; while (work) { work = 0; /* * WSLOOP(wsets, u) { */ for (idx1 = 0; idx1 < cwp; idx1++) { u = &wsets[idx1]; if (u->flag == 0) continue; c = *(u->pitem); /* dot is before c */ if (c < NTBASE) { u->flag = 0; /* * only interesting case is where . is * before nonterminal */ continue; } /* compute the lookahead */ aryfil(clset.lset, tbitset, 0); /* find items involving c */ WSLOOP(u, v) { if (v->flag == 1 && *(pi = v->pitem) == c) { v->flag = 0; if (nolook) continue; while ((ch = *++pi) > 0) { /* terminal symbol */ if (ch < NTBASE) { SETBIT(clset.lset, ch); break; } /* nonterminal symbol */ (void) setunion(clset.lset, pfirst[ch-NTBASE]->lset); if (!pempty[ch-NTBASE]) break; } if (ch <= 0) (void) setunion(clset.lset, v->ws.lset); } } /* now loop over productions derived from c */ c -= NTBASE; /* c is now nonterminal number */ t = pres[c+1]; for (s = pres[c]; s < t; ++s) { /* put these items into the closure */ WSLOOP(wsets, v) { /* is the item there */ /* yes, it is there */ if (v->pitem == *s) { if (nolook) goto nexts; if (setunion(v->ws.lset, clset.lset)) v->flag = work = 1; goto nexts; } } /* not there; make a new entry */ if (cwp + 1 >= wsetsz) exp_wsets(); wsets[cwp].pitem = *s; wsets[cwp].flag = 1; if (!nolook) { work = 1; SETLOOP(k) wsets[cwp].ws.lset[k] = clset.lset[k]; } WSBUMP(cwp); nexts:; } } } /* have computed closure; flags are reset; return */ if (&wsets[cwp] > &wsets[zzcwp]) zzcwp = cwp; if (cldebug && (foutput != NULL)) { (void) fprintf(foutput, "\nState %d, nolook = %d\n", i, nolook); WSLOOP(wsets, u) { if (u->flag) (void) fprintf(foutput, "flag set!\n"); u->flag = 0; (void) fprintf(foutput, "\t%ws", writem(u->pitem)); prlook(&u->ws); (void) fprintf(foutput, "\n"); } } } static LOOKSETS * flset(LOOKSETS *p) { /* decide if the lookahead set pointed to by p is known */ /* return pointer to a perminent location for the set */ int j, *w; int *u, *v; register LOOKSETS *q; for (q = &lkst[nlset]; q-- > lkst; ) { u = p->lset; v = q->lset; w = & v[tbitset]; while (v < w) if (*u++ != *v++) goto more; /* we have matched */ return (q); more:; } /* add a new one */ q = &lkst[nlset++]; if (nlset >= lsetsize) { exp_lkst(); q = &lkst[nlset++]; } SETLOOP(j) q->lset[j] = p->lset[j]; return (q); } static void exp_lkst(void) { int i, j; static LOOKSETS *lookbase; lookbase = lkst; lsetsize += LSETSIZE; tmp_lset = (int *) calloc((size_t)(TBITSET * (lsetsize-LSETSIZE)), sizeof (int)); if (tmp_lset == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Memory allocation error. Do not translate lookset. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "could not expand lookset array")); lkst = (LOOKSETS *) realloc((char *)lkst, sizeof (LOOKSETS) * lsetsize); for (i = lsetsize-LSETSIZE, j = 0; i < lsetsize; ++i, ++j) lkst[i].lset = tmp_lset + TBITSET * j; tmp_lset = NULL; if (lkst == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Memory allocation error. Do not translate lookset. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "could not expand lookahead sets")); for (i = 0; i <= nnonter; ++i) pfirst[i] = pfirst[i] - lookbase + lkst; for (i = 0; i <= nstate+1; ++i) { if (psmem[i].look) psmem[i].look = psmem[i].look - lookbase + lkst; if (pstate[i]->look) pstate[i]->look = pstate[i]->look - lookbase + lkst; } } static void exp_wsets(void) { int i, j; wsetsz += WSETSIZE; tmp_lset = (int *) calloc((size_t)(TBITSET * (wsetsz-WSETSIZE)), sizeof (int)); if (tmp_lset == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Memory allocation error. Do not translate lookset. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "could not expand lookset array")); wsets = (WSET *) realloc((char *)wsets, sizeof (WSET) * wsetsz); for (i = wsetsz-WSETSIZE, j = 0; i < wsetsz; ++i, ++j) wsets[i].ws.lset = tmp_lset + TBITSET * j; tmp_lset = NULL; if (wsets == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Memory allocation error. You may just transltate * this as 'Could not allocate internally used memory.' * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "could not expand working sets")); } static void exp_states(void) { nstatesz += NSTATES; pstate = (ITEM **) realloc((char *)pstate, sizeof (ITEM *)*(nstatesz+2)); mstates = (int *)realloc((char *)mstates, sizeof (int)*nstatesz); defact = (int *)realloc((char *)defact, sizeof (int)*nstatesz); tystate = (int *)realloc((char *)tystate, sizeof (int)*nstatesz); indgo = (int *)realloc((char *)indgo, sizeof (int)*nstatesz); if ((*pstate == NULL) || (tystate == NULL) || (defact == NULL) || (indgo == NULL) || (mstates == NULL)) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Memory allocation error. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "cannot expand table of states")); } static void exp_psmem(void) { int i; new_pstsize += PSTSIZE; psmem = (ITEM *) realloc((char *)psmem, sizeof (ITEM) * new_pstsize); if (psmem == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Memory allocation error. * * You may just translate this as: * 'Could not allocate internally used memory.' */ error(gettext( "cannot expand pstate memory")); zzmemsz = zzmemsz - pstate[0] + psmem; for (i = 1; i <= nstate+1; ++i) pstate[i] = pstate[i] - pstate[0] + psmem; pstate[0] = psmem; } /* * 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 */ #include "dextern.h" #include "sgs.h" #include #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 = PARSER; /* 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"; int nmbchars = 0; /* number of mb literals in mbchars */ MBCLIT *mbchars = (MBCLIT *) 0; /* array of mb literals */ int nmbcharsz = 0; /* allocated space for mbchars */ #define F_NAME_LENGTH 128 void setup(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 = ""; char fname[F_NAME_LENGTH+1]; foutput = NULL; fdefine = NULL; i = 1; tokname = malloc(sizeof (wchar_t) * toksize); tokset = malloc(sizeof (TOKSYMB) * ntoksz); toklev = malloc(sizeof (int) * ntoksz); nontrst = malloc(sizeof (NTSYMB) * nnontersz); mem0 = malloc(sizeof (int) * new_memsize); prdptr = malloc(sizeof (int *) * (nprodsz + 2)); levprd = malloc(sizeof (int) * (nprodsz + 2)); had_act = calloc(nprodsz + 2, sizeof (wchar_t)); lhstext = calloc(LHS_TEXT_LEN, sizeof (wchar_t)); rhstext = calloc(RHS_TEXT_LEN, sizeof (wchar_t)); 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) { (void) strncpy(fname, file_prefix, F_NAME_LENGTH - strlen(".output")); (void) 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) { (void) strncpy(fname, file_prefix, F_NAME_LENGTH - strlen(".tab.h")); (void) 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 */ (void) strncpy(fname, file_prefix, F_NAME_LENGTH - strlen(".tab.c")); (void) 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 \n"); (void) fprintf(ftable, "#include \n"); (void) fprintf(ftable, "#include \n"); (void) fprintf(ftable, "\n#include \n"); if (sym_prefix[0] != '\0') put_prefix_define(sym_prefix); (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 */ 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(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(void) { /* finish action routine */ (void) fclose(faction); (void) fprintf(ftable, "# define YYERRCODE %d\n", tokset[2].value); } static wchar_t * cstash(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(int t, wchar_t *s) { /* define s to be a terminal if t=0 or a nonterminal if t=1 */ int 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] == 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(void) { /* 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 int gettok(void) { int i, base; static int peekline; /* number of '\n' seen in lookahead */ int 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; } /* FALLTHROUGH */ 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 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(gettext( "must specify type for %ws"), (t >= NTBASE) ? nontrst[t-NTBASE].name: tokset[t].name); return (v); } static int chfind(int t, 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(void) { /* * 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(void) { /* 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 int skipcom(void) { /* skip over comments */ int 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 */ return (0); } static void cpyact(int 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') /* NULL */; 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 $ */ error(gettext( "bad syntax on $ 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') /* NULL */; if (c == L'#') { while ((c = getwc(finput)) == L' ' || c == L'\t') /* NULL */; 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. */ (void) 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. */ /* EMPTY */; } /* * 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(wchar_t *s) /* new rule, dump old (if exists), restart strings */ { 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(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(void) /* 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(void) /* 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(void) /* 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, "const char * yyreds[] =\n{\n"); (void) fprintf(fdebug, "\t\"-no such reduction-\",\n"); } static void end_debug(void) /* 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(void) { toksize += NAMESIZE; tokname = (wchar_t *) realloc((char *)tokname, sizeof (wchar_t) * toksize); } /* * 2/29/88 - * */ static void exp_prod(void) { 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(void) { 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(void) { 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(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; } } /* * 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. */ static int findchtok(int chlit) { 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(gettext( "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. */ 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(ftable, "#define\tyy%s\t%s%s\n", syms[i], pre, syms[i]); } /* * 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 */ #include "dextern.h" static void go2gen(int); static void precftn(int, int, int); static void wract(int); static void wrstate(int); static void wdef(wchar_t *, int); static void wrmbchars(void); /* important local variables */ static int lastred; /* number of the last reduction of a state */ int *defact; extern int *toklev; extern int cwp; /* print the output for the states */ void output(void) { int i, k, c; WSET *u, *v; (void) fprintf(ftable, "static const yytabelem yyexca[] ={\n"); SLOOP(i) { /* output the stuff for state i */ nolook = !(tystate[i] == MUSTLOOKAHEAD); closure(i); /* output actions */ nolook = 1; aryfil(temp1, ntoksz+nnontersz+1, 0); WSLOOP(wsets, u) { c = *(u->pitem); if (c > 1 && c < NTBASE && temp1[c] == 0) { WSLOOP(u, v) { if (c == *(v->pitem)) putitem(v->pitem + 1, (LOOKSETS *)0); } temp1[c] = state(c); } else if (c > NTBASE && temp1[(c -= NTBASE) + ntokens] == 0) { temp1[c + ntokens] = amem[indgo[i] + c]; } } if (i == 1) temp1[1] = ACCEPTCODE; /* now, we have the shifts; look at the reductions */ lastred = 0; WSLOOP(wsets, u) { c = *(u->pitem); if (c <= 0) { /* reduction */ lastred = -c; TLOOP(k) { if (BIT(u->ws.lset, k)) { if (temp1[k] == 0) temp1[k] = c; else if (temp1[k] < 0) { /* * reduce/reduce * conflict */ /* BEGIN CSTYLED */ if (foutput != NULL) (void) fprintf(foutput, "\n%d: reduce/reduce conflict" " (red'ns %d and %d ) on %ws", i, -temp1[k], lastred, symnam(k)); if (-temp1[k] > lastred) temp1[k] = -lastred; ++zzrrconf; /* END CSTYLED */ } else /* * potentia * shift/reduce * conflict. */ precftn(lastred, k, i); } } } } wract(i); } (void) fprintf(ftable, "\t};\n"); wdef(L"YYNPROD", nprod); if (nmbchars > 0) { wrmbchars(); } } static int pkdebug = 0; int apack(int *p, int n) { /* pack state i from temp1 into amem */ int off; int *pp, *qq; int *q, *rr; int diff; /* * we don't need to worry about checking because we * we will only look up entries known to be there... */ /* eliminate leading and trailing 0's */ q = p + n; for (pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off) /* NULL */; if (pp > q) return (0); /* no actions */ p = pp; /* now, find a place for the elements from p to q, inclusive */ /* for( rr=amem; rr<=r; ++rr,++off ){ */ /* try rr */ rr = amem; for (; ; ++rr, ++off) { while (rr >= &amem[new_actsize-1]) exp_act(&rr); qq = rr; for (pp = p; pp <= q; ++pp, ++qq) { if (*pp) { diff = qq - rr; while (qq >= &amem[new_actsize-1]) { exp_act(&rr); qq = diff + rr; } if (*pp != *qq && *qq != 0) goto nextk; } } /* we have found an acceptable k */ if (pkdebug && foutput != NULL) (void) fprintf(foutput, "off = %d, k = %" PRIdPTR "\n", off, rr-amem); qq = rr; for (pp = p; pp <= q; ++pp, ++qq) { if (*pp) { diff = qq - rr; while (qq >= &amem[new_actsize-1]) { exp_act(&rr); qq = diff + rr; } if (qq > memp) memp = qq; *qq = *pp; } } if (pkdebug && foutput != NULL) { for (pp = amem; pp <= memp; pp += 10) { (void) fprintf(foutput, "\t"); for (qq = pp; qq <= pp + 9; ++qq) (void) fprintf(foutput, "%d ", *qq); (void) fprintf(foutput, "\n"); } } return (off); nextk:; } /* error("no space in action table" ); */ /* NOTREACHED */ } void go2out(void) { /* output the gotos for the nontermninals */ int i, j, k, best, count, cbest, times; (void) fprintf(ftemp, "$\n"); /* mark begining of gotos */ for (i = 1; i <= nnonter; ++i) { go2gen(i); /* find the best one to make default */ best = -1; times = 0; for (j = 0; j < nstate; ++j) { /* is j the most frequent */ if (tystate[j] == 0) continue; if (tystate[j] == best) continue; /* is tystate[j] the most frequent */ count = 0; cbest = tystate[j]; for (k = j; k < nstate; ++k) if (tystate[k] == cbest) ++count; if (count > times) { best = cbest; times = count; } } /* best is now the default entry */ zzgobest += (times-1); for (j = 0; j < nstate; ++j) { if (tystate[j] != 0 && tystate[j] != best) { (void) fprintf(ftemp, "%d,%d,", j, tystate[j]); zzgoent += 1; } } /* now, the default */ zzgoent += 1; (void) fprintf(ftemp, "%d\n", best); } } static int g2debug = 0; static void go2gen(int c) { /* output the gotos for nonterminal c */ int i, work, cc; ITEM *p, *q; /* first, find nonterminals with gotos on c */ aryfil(temp1, nnonter + 1, 0); temp1[c] = 1; work = 1; while (work) { work = 0; PLOOP(0, i) { if ((cc = prdptr[i][1] - NTBASE) >= 0) { /* cc is a nonterminal */ if (temp1[cc] != 0) { /* * cc has a goto on c * thus, the left side of * production i does too. */ cc = *prdptr[i] - NTBASE; if (temp1[cc] == 0) { work = 1; temp1[cc] = 1; } } } } } /* now, we have temp1[c] = 1 if a goto on c in closure of cc */ if (g2debug && foutput != NULL) { (void) fprintf(foutput, "%ws: gotos on ", nontrst[c].name); NTLOOP(i) if (temp1[i]) (void) fprintf(foutput, "%ws ", nontrst[i].name); (void) fprintf(foutput, "\n"); } /* now, go through and put gotos into tystate */ aryfil(tystate, nstate, 0); SLOOP(i) { ITMLOOP(i, p, q) { if ((cc = *p->pitem) >= NTBASE) { if (temp1[cc -= NTBASE]) { /* goto on c is possible */ tystate[i] = amem[indgo[i] + c]; break; } } } } } /* decide a shift/reduce conflict by precedence. */ static void precftn(int r, int t, int s) { /* * r is a rule number, t a token number * the conflict is in state s * temp1[t] is changed to reflect the action */ int lp, lt, action; lp = levprd[r]; lt = toklev[t]; if (PLEVEL(lt) == 0 || PLEVEL(lp) == 0) { /* conflict */ if (foutput != NULL) (void) fprintf(foutput, "\n%d: shift/reduce conflict" " (shift %d, red'n %d) on %ws", s, temp1[t], r, symnam(t)); ++zzsrconf; return; } if (PLEVEL(lt) == PLEVEL(lp)) action = ASSOC(lt) & ~04; else if (PLEVEL(lt) > PLEVEL(lp)) action = RASC; /* shift */ else action = LASC; /* reduce */ switch (action) { case BASC: /* error action */ temp1[t] = ERRCODE; return; case LASC: /* reduce */ temp1[t] = -r; return; } } static void wract(int i) { /* output state i */ /* temp1 has the actions, lastred the default */ int p, p0, p1; int ntimes, tred, count, j; int flag; /* find the best choice for lastred */ lastred = 0; ntimes = 0; TLOOP(j) { if (temp1[j] >= 0) continue; if (temp1[j] + lastred == 0) continue; /* count the number of appearances of temp1[j] */ count = 0; tred = -temp1[j]; levprd[tred] |= REDFLAG; TLOOP(p) { if (temp1[p] + tred == 0) ++count; } if (count > ntimes) { lastred = tred; ntimes = count; } } /* * for error recovery, arrange that, if there is a shift on the * error recovery token, `error', that the default be the error action */ if (temp1[2] > 0) lastred = 0; /* clear out entries in temp1 which equal lastred */ TLOOP(p) { if (temp1[p] + lastred == 0) temp1[p] = 0; } wrstate(i); defact[i] = lastred; flag = 0; TLOOP(p0) { if ((p1 = temp1[p0]) != 0) { if (p1 < 0) { p1 = -p1; goto exc; } else if (p1 == ACCEPTCODE) { p1 = -1; goto exc; } else if (p1 == ERRCODE) { p1 = 0; goto exc; exc: if (flag++ == 0) (void) fprintf(ftable, "-1, %d,\n", i); (void) fprintf(ftable, "\t%d, %d,\n", tokset[p0].value, p1); ++zzexcp; } else { (void) fprintf(ftemp, "%d,%d,", tokset[p0].value, p1); ++zzacent; } } } if (flag) { defact[i] = -2; (void) fprintf(ftable, "\t-2, %d,\n", lastred); } (void) fprintf(ftemp, "\n"); } static void wrstate(int i) { /* writes state i */ int j0, j1; register ITEM *pp, *qq; register WSET *u; if (foutput == NULL) return; (void) fprintf(foutput, "\nstate %d\n", i); ITMLOOP(i, pp, qq) { (void) fprintf(foutput, "\t%ws\n", writem(pp->pitem)); } if (tystate[i] == MUSTLOOKAHEAD) { /* print out empty productions in closure */ WSLOOP(wsets + (pstate[i + 1] - pstate[i]), u) { if (*(u->pitem) < 0) (void) fprintf(foutput, "\t%ws\n", writem(u->pitem)); } } /* check for state equal to another */ TLOOP(j0) if ((j1 = temp1[j0]) != 0) { (void) fprintf(foutput, "\n\t%ws ", symnam(j0)); if (j1 > 0) { /* shift, error, or accept */ if (j1 == ACCEPTCODE) (void) fprintf(foutput, "accept"); else if (j1 == ERRCODE) (void) fprintf(foutput, "error"); else (void) fprintf(foutput, "shift %d", j1); } else (void) fprintf(foutput, "reduce %d", -j1); } /* output the final production */ if (lastred) (void) fprintf(foutput, "\n\t. reduce %d\n\n", lastred); else (void) fprintf(foutput, "\n\t. error\n\n"); /* now, output nonterminal actions */ j1 = ntokens; for (j0 = 1; j0 <= nnonter; ++j0) { if (temp1[++j1]) (void) fprintf(foutput, "\t%ws goto %d\n", symnam(j0 + NTBASE), temp1[j1]); } } static void wdef(wchar_t *s, int n) { /* output a definition of s to the value n */ (void) fprintf(ftable, "# define %ws %d\n", s, n); } void warray(wchar_t *s, int *v, int n) { int i; (void) fprintf(ftable, "static const yytabelem %ws[]={\n", s); for (i = 0; i < n; ) { if (i % 10 == 0) (void) fprintf(ftable, "\n"); (void) fprintf(ftable, "%6d", v[i]); if (++i == n) (void) fprintf(ftable, " };\n"); else (void) fprintf(ftable, ","); } } void hideprod(void) { /* * in order to free up the mem and amem arrays for the optimizer, * and still be able to output yyr1, etc., after the sizes of * the action array is known, we hide the nonterminals * derived by productions in levprd. */ int i, j; j = 0; levprd[0] = 0; PLOOP(1, i) { if (!(levprd[i] & REDFLAG)) { ++j; if (foutput != NULL) { (void) fprintf(foutput, "Rule not reduced: %ws\n", writem(prdptr[i])); } } levprd[i] = *prdptr[i] - NTBASE; } if (j) /* * TRANSLATION_NOTE -- This is a message from yacc. * Check how 'reduced' is translated in yacc man page/document. */ (void) fprintf(stderr, gettext("%d rules never reduced\n"), j); } static int cmpmbchars(MBCLIT *p, MBCLIT *q) { /* Compare two MBLITs. */ return ((p->character) - (q->character)); } static void wrmbchars(void) { int i; wdef(L"YYNMBCHARS", nmbchars); qsort(mbchars, nmbchars, sizeof (*mbchars), (int (*)(const void *, const void *))cmpmbchars); (void) fprintf(ftable, "static struct{\n\twchar_t character;" "\n\tint tvalue;\n}yymbchars[YYNMBCHARS]={\n"); for (i = 0; i < nmbchars; ++i) { (void) fprintf(ftable, "\t{%#x,%d}", (int)mbchars[i].character, mbchars[i].tvalue); if (i < nmbchars - 1) { /* Not the last. */ (void) fprintf(ftable, ",\n"); } } (void) fprintf(ftable, "\n};\n"); } /* * 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 */ #include "dextern.h" #define NOMORE -1000 static void gin(int); static void stin(int); static void osummary(void); static void aoutput(void); static void arout(wchar_t *, int *, int); static int nxti(void); static int gtnm(void); static int *ggreed; static int *pgo; static int *yypgo; static int maxspr = 0; /* maximum spread of any entry */ static int maxoff = 0; /* maximum offset into an array */ int *optimmem; static int *maxa; static int nxdb = 0; static int adb = 0; void callopt(void) { int i, *p, j, k, *q; ggreed = (int *) malloc(sizeof (int) * size); pgo = (int *) malloc(sizeof (int) * size); yypgo = &nontrst[0].tvalue; /* read the arrays from tempfile and set parameters */ if ((finput = fopen(TEMPNAME, "r")) == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * tempfile can be translated as temporary file. */ error(gettext( "optimizer cannot open tempfile")); optimmem = tracemem; pgo[0] = 0; temp1[0] = 0; nstate = 0; nnonter = 0; for (;;) { switch (gtnm()) { case L'\n': temp1[++nstate] = (--optimmem) - tracemem; /* FALLTHRU */ case L',': continue; case L'$': break; default: error("bad tempfile"); } break; } temp1[nstate] = yypgo[0] = (--optimmem) - tracemem; for (;;) { switch (gtnm()) { case L'\n': yypgo[++nnonter] = optimmem-tracemem; /* FALLTHRU */ case L',': continue; case EOF: break; default: /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * tempfile can be translated as 'temporary file'. */ error(gettext( "bad tempfile")); } break; } yypgo[nnonter--] = (--optimmem) - tracemem; for (i = 0; i < nstate; ++i) { k = 32000000; j = 0; q = tracemem + temp1[i+1]; for (p = tracemem + temp1[i]; p < q; p += 2) { if (*p > j) j = *p; if (*p < k) k = *p; } if (k <= j) { /* * nontrivial situation * temporarily, kill this for compatibility */ /* j -= k; j is now the range */ if (k > maxoff) maxoff = k; } tystate[i] = (temp1[i+1] - temp1[i]) + 2*j; if (j > maxspr) maxspr = j; } /* initialize ggreed table */ for (i = 1; i <= nnonter; ++i) { ggreed[i] = 1; j = 0; /* minimum entry index is always 0 */ q = tracemem + yypgo[i+1] -1; for (p = tracemem + yypgo[i]; p < q; p += 2) { ggreed[i] += 2; if (*p > j) j = *p; } ggreed[i] = ggreed[i] + 2*j; if (j > maxoff) maxoff = j; } /* now, prepare to put the shift actions into the amem array */ for (i = 0; i < new_actsize; ++i) amem[i] = 0; maxa = amem; for (i = 0; i < nstate; ++i) { if (tystate[i] == 0 && adb > 1) (void) fprintf(ftable, "State %d: null\n", i); indgo[i] = YYFLAG1; } while ((i = nxti()) != NOMORE) { if (i >= 0) stin(i); else gin(-i); } if (adb > 2) { /* print a array */ for (p = amem; p <= maxa; p += 10) { (void) fprintf(ftable, "%4" PRIdPTR " ", p-amem); for (i = 0; i < 10; ++i) (void) fprintf(ftable, "%4d ", p[i]); (void) fprintf(ftable, "\n"); } } /* write out the output appropriate to the language */ aoutput(); osummary(); ZAPFILE(TEMPNAME); } static void gin(int i) { int *r, *s, *q1, *q2; int *p; /* enter gotos on nonterminal i into array amem */ ggreed[i] = 0; q2 = tracemem + yypgo[i+1] - 1; q1 = tracemem + yypgo[i]; /* now, find a place for it */ /* for( p=amem; p < &amem[new_actsize]; ++p ){ */ p = amem; for (;;) { while (p >= &amem[new_actsize]) exp_act(&p); if (*p) goto nextgp; for (r = q1; r < q2; r += 2) { s = p + *r + 1; /* * Check if action table needs to * be expanded or not. If so, * expand it. */ while (s >= &amem[new_actsize]) { exp_act(&p); s = p + *r + 1; } if (*s) goto nextgp; if (s > maxa) { while ((maxa = s) >= &amem[new_actsize]) /* error( "amem array overflow" ); */ exp_act(&p); } } /* we have found a spot */ *p = *q2; if (p > maxa) { while ((maxa = p) >= &amem[new_actsize]) /* error("amem array overflow"); */ exp_act(&p); } for (r = q1; r < q2; r += 2) { s = p + *r + 1; /* * Check if action table needs to * be expanded or not. If so, * expand it. */ while (s >= &amem[new_actsize]) { exp_act(&p); s = p + *r + 1; } *s = r[1]; } pgo[i] = p - amem; if (adb > 1) (void) fprintf(ftable, "Nonterminal %d, entry at %d\n", i, pgo[i]); goto nextgi; nextgp: ++p; } /* error( "cannot place goto %d\n", i ); */ nextgi:; } static void stin(int i) { int *r, n, nn, flag, j, *q1, *q2; int *s; tystate[i] = 0; /* Enter state i into the amem array */ q2 = tracemem + temp1[i + 1]; q1 = tracemem + temp1[i]; /* Find an acceptable place */ nn = -maxoff; more: for (n = nn; n < new_actsize; ++n) { flag = 0; for (r = q1; r < q2; r += 2) { s = *r + n + amem; if (s < amem) goto nextn; /* * Check if action table needs to * be expanded or not. If so, * expand it. */ while (s >= &amem[new_actsize]) { exp_act((int **)NULL); s = *r + n + amem; } if (*s == 0) ++flag; else if (*s != r[1]) goto nextn; } /* * check that the position equals another * only if the states are identical */ for (j = 0; j < nstate; ++j) { if (indgo[j] == n) { if (flag) /* * we have some disagreement. */ goto nextn; if (temp1[j+1] + temp1[i] == temp1[j] + temp1[i+1]) { /* states are equal */ indgo[i] = n; if (adb > 1) (void) fprintf(ftable, "State %d: entry at" " %d equals state %d\n", i, n, j); return; } goto nextn; /* we have some disagreement */ } } for (r = q1; r < q2; r += 2) { while ((s = *r + n + amem) >= &amem[new_actsize]) { /* * error( "out of space"); */ exp_act((int **)NULL); } if (s > maxa) maxa = s; if (*s != 0 && *s != r[1]) /* * TRANSLATION_NOTE -- This is a message from yacc. * This message is passed to error() function. * Leave this untrasnlated. Yacc internal error. */ error(gettext( "clobber of amem array, pos'n %d, by %d"), s-amem, r[1]); *s = r[1]; } indgo[i] = n; if (adb > 1) (void) fprintf(ftable, "State %d: entry at %d\n", i, indgo[i]); return; nextn:; } /* error( "Error; failure to place state %d\n", i ); */ exp_act((int **)NULL); nn = new_actsize - ACTSIZE; goto more; /* NOTREACHED */ } static int nxti(void) { /* finds the next i */ int i, max, maxi; max = 0; for (i = 1; i <= nnonter; ++i) if (ggreed[i] >= max) { max = ggreed[i]; maxi = -i; } for (i = 0; i < nstate; ++i) if (tystate[i] >= max) { max = tystate[i]; maxi = i; } if (nxdb) (void) fprintf(ftable, "nxti = %d, max = %d\n", maxi, max); if (max == 0) return (NOMORE); else return (maxi); } static void osummary(void) { /* write summary */ int i, *p; if (foutput == NULL) return; i = 0; for (p = maxa; p >= amem; --p) { if (*p == 0) ++i; } (void) fprintf(foutput, "Optimizer space used: input %" PRIdPTR "/%d, output %" PRIdPTR "/%d\n", optimmem-tracemem + 1, new_memsize, maxa-amem + 1, new_actsize); (void) fprintf(foutput, "%" PRIdPTR " table entries, %d zero\n", (maxa-amem) + 1, i); (void) fprintf(foutput, "maximum spread: %d, maximum offset: %d\n", maxspr, maxoff); } static void aoutput(void) { /* this version is for C */ /* write out the optimized parser */ (void) fprintf(ftable, "# define YYLAST %" PRIdPTR "\n", maxa-amem + 1); arout(L"yyact", amem, (maxa - amem) + 1); arout(L"yypact", indgo, nstate); arout(L"yypgo", pgo, nnonter + 1); } static void arout(wchar_t *s, int *v, int n) { int i; (void) fprintf(ftable, "static const yytabelem %ws[]={\n", s); for (i = 0; i < n; ) { if (i % 10 == 0) (void) fprintf(ftable, "\n"); (void) fprintf(ftable, "%6d", v[i]); if (++i == n) (void) fprintf(ftable, " };\n"); else (void) fprintf(ftable, ","); } } static int gtnm(void) { int s, val, c; /* read and convert an integer from the standard input */ /* return the terminating character */ /* blanks, tabs, and newlines are ignored */ s = 1; val = 0; while ((c = getwc(finput)) != EOF) { if (iswdigit(c)) val = val * 10 + c - L'0'; else if (c == L'-') s = -1; else break; } *optimmem++ = s*val; if (optimmem >= &tracemem[new_memsize]) exp_mem(0); return (c); } void exp_act(int **ptr) { static int *actbase; int i; new_actsize += ACTSIZE; actbase = amem; amem = (int *) realloc((char *)amem, sizeof (int) * new_actsize); if (amem == 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 action table")); for (i = new_actsize-ACTSIZE; i < new_actsize; ++i) amem[i] = 0; if (ptr != NULL) *ptr = *ptr - actbase + amem; if (memp >= amem) memp = memp - actbase + amem; if (maxa >= amem) maxa = maxa - actbase + amem; } /* * 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 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ /* ** Skeleton parser driver for yacc output */ /* ** yacc user known macros and defines */ #define YYERROR goto yyerrlab #define YYACCEPT return(0) #define YYABORT return(1) #define YYBACKUP( newtoken, newvalue )\ {\ if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ {\ (void) yyerror( "syntax error - cannot backup" );\ goto yyerrlab;\ }\ yychar = newtoken;\ yystate = *yyps;\ yylval = newvalue;\ goto yynewstate;\ } #define YYRECOVERING() (!!yyerrflag) #define YYNEW(type) malloc(sizeof(type) * yynewmax) #define YYCOPY(to, from, type) \ (type *) memcpy(to, (char *) from, yymaxdepth * sizeof (type)) #define YYENLARGE( from, type) \ (type *) realloc((char *) from, yynewmax * sizeof(type)) #ifndef YYDEBUG # define YYDEBUG 1 /* make debugging available */ #endif /* ** user known globals */ int yydebug; /* set to 1 to get debugging */ /* ** driver internal defines */ #define YYFLAG (-10000000) /* ** global variables used by the parser */ YYSTYPE *yypv; /* top of value stack */ int *yyps; /* top of state stack */ int yystate; /* current state */ int yytmp; /* extra var (lasts between blocks) */ int yynerrs; /* number of errors */ int yyerrflag; /* error recovery flag */ int yychar; /* current input token number */ #ifdef YYNMBCHARS #define YYLEX() yycvtok(yylex()) /* ** yycvtok - return a token if i is a wchar_t value that exceeds 255. ** If i<255, i itself is the token. If i>255 but the neither ** of the 30th or 31st bit is on, i is already a token. */ int yycvtok(int i) { int first = 0; int last = YYNMBCHARS - 1; int mid; wchar_t j; if(i&0x60000000){/*Must convert to a token. */ if( yymbchars[last].character < i ){ return i;/*Giving up*/ } while ((last>=first)&&(first>=0)) {/*Binary search loop*/ mid = (first+last)/2; j = yymbchars[mid].character; if( j==i ){/*Found*/ return yymbchars[mid].tvalue; }else if( j= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) break; } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ { /* ** reallocate and recover. Note that pointers ** have to be reset, or bad things will happen */ long yyps_index = (yy_ps - yys); long yypv_index = (yy_pv - yyv); long yypvt_index = (yypvt - yyv); int yynewmax; #ifdef YYEXPAND yynewmax = YYEXPAND(yymaxdepth); #else yynewmax = 2 * yymaxdepth; /* double table size */ if (yymaxdepth == YYMAXDEPTH) /* first time growth */ { char *newyys = (char *)YYNEW(int); char *newyyv = (char *)YYNEW(YYSTYPE); if (newyys != 0 && newyyv != 0) { yys = YYCOPY(newyys, yys, int); yyv = YYCOPY(newyyv, yyv, YYSTYPE); } else yynewmax = 0; /* failed */ } else /* not first time */ { yys = YYENLARGE(yys, int); yyv = YYENLARGE(yyv, YYSTYPE); if (yys == 0 || yyv == 0) yynewmax = 0; /* failed */ } #endif if (yynewmax <= yymaxdepth) /* tables not expanded */ { (void) yyerror( "yacc stack overflow" ); YYABORT; } yymaxdepth = yynewmax; yy_ps = yys + yyps_index; yy_pv = yyv + yypv_index; yypvt = yyv + yypvt_index; } *yy_ps = yy_state; *++yy_pv = yyval; /* ** we have a new state - find out what to do */ yy_newstate: if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) goto yydefault; /* simple state */ #if YYDEBUG /* ** if debugging, need to mark whether new token grabbed */ yytmp = yychar < 0; #endif if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) yychar = 0; /* reached EOF */ #if YYDEBUG if ( yydebug && yytmp ) { int yy_i; printf( "Received token " ); if ( yychar == 0 ) printf( "end-of-file\n" ); else if ( yychar < 0 ) printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) break; } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) goto yydefault; if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ { yychar = -1; yyval = yylval; yy_state = yy_n; if ( yyerrflag > 0 ) yyerrflag--; goto yy_stack; } yydefault: if ( ( yy_n = yydef[ yy_state ] ) == -2 ) { #if YYDEBUG yytmp = yychar < 0; #endif if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) yychar = 0; /* reached EOF */ #if YYDEBUG if ( yydebug && yytmp ) { int yy_i; printf( "Received token " ); if ( yychar == 0 ) printf( "end-of-file\n" ); else if ( yychar < 0 ) printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) { break; } } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ /* ** look through exception table */ { const int *yyxi = yyexca; while ( ( *yyxi != -1 ) || ( yyxi[1] != yy_state ) ) { yyxi += 2; } while ( ( *(yyxi += 2) >= 0 ) && ( *yyxi != yychar ) ) ; if ( ( yy_n = yyxi[1] ) < 0 ) YYACCEPT; } } /* ** check for syntax error */ if ( yy_n == 0 ) /* have an error */ { /* no worry about speed here! */ switch ( yyerrflag ) { case 0: /* new error */ (void) yyerror( "syntax error" ); goto skip_init; yyerrlab: /* ** get globals into registers. ** we have a user generated syntax type error */ yy_pv = yypv; yy_ps = yyps; yy_state = yystate; skip_init: yynerrs++; /* FALLTHRU */ case 1: case 2: /* incompletely recovered error */ /* try again... */ yyerrflag = 3; /* ** find state where "error" is a legal ** shift action */ while ( yy_ps >= yys ) { yy_n = yypact[ *yy_ps ] + YYERRCODE; if ( yy_n >= 0 && yy_n < YYLAST && yychk[yyact[yy_n]] == YYERRCODE) { /* ** simulate shift of "error" */ yy_state = yyact[ yy_n ]; goto yy_stack; } /* ** current state has no shift on ** "error", pop stack */ #if YYDEBUG # define _POP_ "Error recovery pops state %d, uncovers state %d\n" if ( yydebug ) printf( _POP_, *yy_ps, yy_ps[-1] ); # undef _POP_ #endif yy_ps--; yy_pv--; } /* ** there is no state on stack with "error" as ** a valid shift. give up. */ YYABORT; case 3: /* no shift yet; eat a token */ #if YYDEBUG /* ** if debugging, look up token in list of ** pairs. 0 and negative shouldn't occur, ** but since timing doesn't matter when ** debugging, it doesn't hurt to leave the ** tests here. */ if ( yydebug ) { int yy_i; printf( "Error recovery discards " ); if ( yychar == 0 ) printf( "token end-of-file\n" ); else if ( yychar < 0 ) printf( "token -none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) { break; } } printf( "token %s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( yychar == 0 ) /* reached EOF. quit */ YYABORT; yychar = -1; goto yy_newstate; } }/* end if ( yy_n == 0 ) */ /* ** reduction by production yy_n ** put stack tops, etc. so things right after switch */ #if YYDEBUG /* ** if debugging, print the string that is the user's ** specification of the reduction which is just about ** to be done. */ if ( yydebug ) printf( "Reduce by (%d) \"%s\"\n", yy_n, yyreds[ yy_n ] ); #endif yytmp = yy_n; /* value to switch over */ yypvt = yy_pv; /* $vars top of value stack */ /* ** Look in goto table for next state ** Sorry about using yy_state here as temporary ** register variable, but why not, if it works... ** If yyr2[ yy_n ] doesn't have the low order bit ** set, then there is no action to be done for ** this reduction. So, no saving & unsaving of ** registers done. The only difference between the ** code just after the if and the body of the if is ** the goto yy_stack in the body. This way the test ** can be made before the choice of what to do is needed. */ { /* length of production doubled with extra bit */ int yy_len = yyr2[ yy_n ]; if ( !( yy_len & 01 ) ) { yy_len >>= 1; yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + *( yy_ps -= yy_len ) + 1; if ( yy_state >= YYLAST || yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) { yy_state = yyact[ yypgo[ yy_n ] ]; } goto yy_stack; } yy_len >>= 1; yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + *( yy_ps -= yy_len ) + 1; if ( yy_state >= YYLAST || yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) { yy_state = yyact[ yypgo[ yy_n ] ]; } } /* save until reenter driver code */ yystate = yy_state; yyps = yy_ps; yypv = yy_pv; } /* ** code supplied by user is placed in this switch */ switch( yytmp ) { $A } goto yystack; /* reset registers in driver code */ }