snapshot of project "byacc", label t20040328

This commit is contained in:
Thomas E. Dickey 2004-03-28 23:39:05 -05:00
parent 072c233ba2
commit 8efbbd9c39
30 changed files with 12123 additions and 139 deletions

21
CHANGES
View File

@ -1,3 +1,24 @@
2004-02-23 Thomas E. Dickey <dickey@invisible-island.net>
* config.sub: RCS_BASE
2004-02-17 Thomas E. Dickey <dickey@invisible-island.net>
* config.guess: RCS_BASE
2003-11-29 Thomas E. Dickey <dickey@invisible-island.net>
* install-sh: improved quoting
2002-06-29 Thomas E. Dickey <dickey@invisible-island.net>
* mkdirs.sh:
don't use character range, since some locales don't work as expected
2001-06-22 Thomas E. Dickey <dickey@clark.net>
* install-sh: RCS_BASE
2000-11-20 Thomas E. Dickey <dickey@clark.net>
* vmsbuild.com: original version

View File

@ -1,19 +1,28 @@
MANIFEST for byacc, version VMS-port
MANIFEST for byacc, version t20040328
--------------------------------------------------------------------------------
MANIFEST this file
ACKNOWLEDGEMENTS original version of byacc - 1993
Makefile original version of byacc - 1993
Makefile.old renamed from Makefile
NEW_FEATURES original version of byacc - 1993
NOTES original version of byacc - 1993
NO_WARRANTY original version of byacc - 1993
README original version of byacc - 1993
aclocal.m4 macros for configure-script
closure.c original version of byacc - 1993
config.guess configure-script utility
config.sub configure-script utility
config_h.in template for config.h
configure snapshot 2004/3/28
configure.in template for configure-script
defs.h original version of byacc - 1993
descrip.mms build-script for VMS
error.c original version of byacc - 1993
install-sh install-script
lalr.c original version of byacc - 1993
lr0.c original version of byacc - 1993
main.c original version of byacc - 1993
makefile.in template for makefile
mkdirs.sh script to make directories
mkpar.c original version of byacc - 1993
output.c original version of byacc - 1993
reader.c original version of byacc - 1993
@ -24,6 +33,11 @@ vmsbuild.com build-script for VMS
warshall.c original version of byacc - 1993
yacc.1 original version of byacc - 1993
test subdirectory
test/README describe contents of "test" subdirectory
test/calc.output "-v" output from byacc
test/calc.tab.c c-file for calc.y
test/calc.tab.h header-file for calc.y
test/calc.y example from VMS freeware version of byacc
test/error.output original version of byacc - 1993
test/error.tab.c original version of byacc - 1993
test/error.tab.h original version of byacc - 1993
@ -32,3 +46,8 @@ test/ftp.output original version of byacc - 1993
test/ftp.tab.c original version of byacc - 1993
test/ftp.tab.h original version of byacc - 1993
test/ftp.y original version of byacc - 1993
test/grammar.output "-v" output from grammar.y
test/grammar.tab.c c-file for grammar.y
test/grammar.tab.h h-file for grammar.y
test/grammar.y grammar from cproto
test/run_test.sh test-script for byacc

6
README
View File

@ -1,3 +1,9 @@
-- $Id: README,v 1.2 2004/03/28 17:24:53 tom Exp $
The original README is below. I've updated this version of Berkeley Yacc
to make it ANSI C compliant - Thomas Dickey
-------------------------------------------------------------------------------
Berkeley Yacc is an LALR(1) parser generator. Berkeley Yacc has been made
as compatible as possible with AT&T Yacc. Berkeley Yacc can accept any input
specification that conforms to the AT&T Yacc documentation. Specifications

460
aclocal.m4 vendored Normal file
View File

@ -0,0 +1,460 @@
dnl $Id: aclocal.m4,v 1.2 2004/03/28 20:14:05 tom Exp $
dnl
dnl Macros for cproto configure script (T.Dickey)
dnl ---------------------------------------------------------------------------
dnl ---------------------------------------------------------------------------
dnl CF_ADD_CFLAGS version: 5 updated: 2002/12/01 00:12:15
dnl -------------
dnl Copy non-preprocessor flags to $CFLAGS, preprocessor flags to $CPPFLAGS
dnl The second parameter if given makes this macro verbose.
AC_DEFUN([CF_ADD_CFLAGS],
[
cf_new_cflags=
cf_new_cppflags=
for cf_add_cflags in $1
do
case $cf_add_cflags in #(vi
-undef|-nostdinc*|-I*|-D*|-U*|-E|-P|-C) #(vi
case "$CPPFLAGS" in
*$cf_add_cflags) #(vi
;;
*) #(vi
cf_new_cppflags="$cf_new_cppflags $cf_add_cflags"
;;
esac
;;
*)
cf_new_cflags="$cf_new_cflags $cf_add_cflags"
;;
esac
done
if test -n "$cf_new_cflags" ; then
ifelse($2,,,[CF_VERBOSE(add to \$CFLAGS $cf_new_cflags)])
CFLAGS="$CFLAGS $cf_new_cflags"
fi
if test -n "$cf_new_cppflags" ; then
ifelse($2,,,[CF_VERBOSE(add to \$CPPFLAGS $cf_new_cppflags)])
CPPFLAGS="$cf_new_cppflags $CPPFLAGS"
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ANSI_CC_CHECK version: 9 updated: 2001/12/30 17:53:34
dnl ----------------
dnl This is adapted from the macros 'fp_PROG_CC_STDC' and 'fp_C_PROTOTYPES'
dnl in the sharutils 4.2 distribution.
AC_DEFUN([CF_ANSI_CC_CHECK],
[
AC_CACHE_CHECK(for ${CC-cc} option to accept ANSI C, cf_cv_ansi_cc,[
cf_cv_ansi_cc=no
cf_save_CFLAGS="$CFLAGS"
cf_save_CPPFLAGS="$CPPFLAGS"
# Don't try gcc -ansi; that turns off useful extensions and
# breaks some systems' header files.
# AIX -qlanglvl=ansi
# Ultrix and OSF/1 -std1
# HP-UX -Aa -D_HPUX_SOURCE
# SVR4 -Xc
# UnixWare 1.2 (cannot use -Xc, since ANSI/POSIX clashes)
for cf_arg in "-DCC_HAS_PROTOS" \
"" \
-qlanglvl=ansi \
-std1 \
-Ae \
"-Aa -D_HPUX_SOURCE" \
-Xc
do
CF_ADD_CFLAGS($cf_arg)
AC_TRY_COMPILE(
[
#ifndef CC_HAS_PROTOS
#if !defined(__STDC__) || (__STDC__ != 1)
choke me
#endif
#endif
],[
int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};],
[cf_cv_ansi_cc="$cf_arg"; break])
done
CFLAGS="$cf_save_CFLAGS"
CPPFLAGS="$cf_save_CPPFLAGS"
])
if test "$cf_cv_ansi_cc" != "no"; then
if test ".$cf_cv_ansi_cc" != ".-DCC_HAS_PROTOS"; then
CF_ADD_CFLAGS($cf_cv_ansi_cc)
else
AC_DEFINE(CC_HAS_PROTOS)
fi
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ANSI_CC_REQD version: 3 updated: 1997/09/06 13:40:44
dnl ---------------
dnl For programs that must use an ANSI compiler, obtain compiler options that
dnl will make it recognize prototypes. We'll do preprocessor checks in other
dnl macros, since tools such as unproto can fake prototypes, but only part of
dnl the preprocessor.
AC_DEFUN([CF_ANSI_CC_REQD],
[AC_REQUIRE([CF_ANSI_CC_CHECK])
if test "$cf_cv_ansi_cc" = "no"; then
AC_ERROR(
[Your compiler does not appear to recognize prototypes.
You have the following choices:
a. adjust your compiler options
b. get an up-to-date compiler
c. use a wrapper such as unproto])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ARG_DISABLE version: 3 updated: 1999/03/30 17:24:31
dnl --------------
dnl Allow user to disable a normally-on option.
AC_DEFUN([CF_ARG_DISABLE],
[CF_ARG_OPTION($1,[$2],[$3],[$4],yes)])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ARG_OPTION version: 3 updated: 1997/10/18 14:42:41
dnl -------------
dnl Restricted form of AC_ARG_ENABLE that ensures user doesn't give bogus
dnl values.
dnl
dnl Parameters:
dnl $1 = option name
dnl $2 = help-string
dnl $3 = action to perform if option is not default
dnl $4 = action if perform if option is default
dnl $5 = default option value (either 'yes' or 'no')
AC_DEFUN([CF_ARG_OPTION],
[AC_ARG_ENABLE($1,[$2],[test "$enableval" != ifelse($5,no,yes,no) && enableval=ifelse($5,no,no,yes)
if test "$enableval" != "$5" ; then
ifelse($3,,[ :]dnl
,[ $3]) ifelse($4,,,[
else
$4])
fi],[enableval=$5 ifelse($4,,,[
$4
])dnl
])])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_CACHE version: 9 updated: 2004/01/30 15:59:13
dnl --------------
dnl Check if we're accidentally using a cache from a different machine.
dnl Derive the system name, as a check for reusing the autoconf cache.
dnl
dnl If we've packaged config.guess and config.sub, run that (since it does a
dnl better job than uname). Normally we'll use AC_CANONICAL_HOST, but allow
dnl an extra parameter that we may override, e.g., for AC_CANONICAL_SYSTEM
dnl which is useful in cross-compiles.
dnl
dnl Note: we would use $ac_config_sub, but that is one of the places where
dnl autoconf 2.5x broke compatibility with autoconf 2.13
AC_DEFUN([CF_CHECK_CACHE],
[
if test -f $srcdir/config.guess ; then
ifelse([$1],,[AC_CANONICAL_HOST],[$1])
system_name="$host_os"
else
system_name="`(uname -s -r) 2>/dev/null`"
if test -z "$system_name" ; then
system_name="`(hostname) 2>/dev/null`"
fi
fi
test -n "$system_name" && AC_DEFINE_UNQUOTED(SYSTEM_NAME,"$system_name")
AC_CACHE_VAL(cf_cv_system_name,[cf_cv_system_name="$system_name"])
test -z "$system_name" && system_name="$cf_cv_system_name"
test -n "$cf_cv_system_name" && AC_MSG_RESULT(Configuring for $cf_cv_system_name)
if test ".$system_name" != ".$cf_cv_system_name" ; then
AC_MSG_RESULT(Cached system name ($system_name) does not agree with actual ($cf_cv_system_name))
AC_ERROR("Please remove config.cache and try again.")
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_DISABLE_ECHO version: 10 updated: 2003/04/17 22:27:11
dnl ---------------
dnl You can always use "make -n" to see the actual options, but it's hard to
dnl pick out/analyze warning messages when the compile-line is long.
dnl
dnl Sets:
dnl ECHO_LT - symbol to control if libtool is verbose
dnl ECHO_LD - symbol to prefix "cc -o" lines
dnl RULE_CC - symbol to put before implicit "cc -c" lines (e.g., .c.o)
dnl SHOW_CC - symbol to put before explicit "cc -c" lines
dnl ECHO_CC - symbol to put before any "cc" line
dnl
AC_DEFUN([CF_DISABLE_ECHO],[
AC_MSG_CHECKING(if you want to see long compiling messages)
CF_ARG_DISABLE(echo,
[ --disable-echo display "compiling" commands],
[
ECHO_LT='--silent'
ECHO_LD='@echo linking [$]@;'
RULE_CC=' @echo compiling [$]<'
SHOW_CC=' @echo compiling [$]@'
ECHO_CC='@'
],[
ECHO_LT=''
ECHO_LD=''
RULE_CC='# compiling'
SHOW_CC='# compiling'
ECHO_CC=''
])
AC_MSG_RESULT($enableval)
AC_SUBST(ECHO_LT)
AC_SUBST(ECHO_LD)
AC_SUBST(RULE_CC)
AC_SUBST(SHOW_CC)
AC_SUBST(ECHO_CC)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_GCC_ATTRIBUTES version: 9 updated: 2002/12/21 19:25:52
dnl -----------------
dnl Test for availability of useful gcc __attribute__ directives to quiet
dnl compiler warnings. Though useful, not all are supported -- and contrary
dnl to documentation, unrecognized directives cause older compilers to barf.
AC_DEFUN([CF_GCC_ATTRIBUTES],
[
if test "$GCC" = yes
then
cat > conftest.i <<EOF
#ifndef GCC_PRINTF
#define GCC_PRINTF 0
#endif
#ifndef GCC_SCANF
#define GCC_SCANF 0
#endif
#ifndef GCC_NORETURN
#define GCC_NORETURN /* nothing */
#endif
#ifndef GCC_UNUSED
#define GCC_UNUSED /* nothing */
#endif
EOF
if test "$GCC" = yes
then
AC_CHECKING([for $CC __attribute__ directives])
cat > conftest.$ac_ext <<EOF
#line __oline__ "configure"
#include "confdefs.h"
#include "conftest.h"
#include "conftest.i"
#if GCC_PRINTF
#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
#else
#define GCC_PRINTFLIKE(fmt,var) /*nothing*/
#endif
#if GCC_SCANF
#define GCC_SCANFLIKE(fmt,var) __attribute__((format(scanf,fmt,var)))
#else
#define GCC_SCANFLIKE(fmt,var) /*nothing*/
#endif
extern void wow(char *,...) GCC_SCANFLIKE(1,2);
extern void oops(char *,...) GCC_PRINTFLIKE(1,2) GCC_NORETURN;
extern void foo(void) GCC_NORETURN;
int main(int argc GCC_UNUSED, char *argv[[]] GCC_UNUSED) { return 0; }
EOF
for cf_attribute in scanf printf unused noreturn
do
CF_UPPER(CF_ATTRIBUTE,$cf_attribute)
cf_directive="__attribute__(($cf_attribute))"
echo "checking for $CC $cf_directive" 1>&AC_FD_CC
case $cf_attribute in
scanf|printf)
cat >conftest.h <<EOF
#define GCC_$CF_ATTRIBUTE 1
EOF
;;
*)
cat >conftest.h <<EOF
#define GCC_$CF_ATTRIBUTE $cf_directive
EOF
;;
esac
if AC_TRY_EVAL(ac_compile); then
test -n "$verbose" && AC_MSG_RESULT(... $cf_attribute)
cat conftest.h >>confdefs.h
fi
done
else
fgrep define conftest.i >>confdefs.h
fi
rm -rf conftest*
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_GCC_VERSION version: 3 updated: 2003/09/06 19:16:57
dnl --------------
dnl Find version of gcc
AC_DEFUN([CF_GCC_VERSION],[
AC_REQUIRE([AC_PROG_CC])
GCC_VERSION=none
if test "$GCC" = yes ; then
AC_MSG_CHECKING(version of $CC)
GCC_VERSION="`${CC} --version|sed -e '2,$d' -e 's/^[[^0-9.]]*//' -e 's/[[^0-9.]].*//'`"
test -z "$GCC_VERSION" && GCC_VERSION=unknown
AC_MSG_RESULT($GCC_VERSION)
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_GCC_WARNINGS version: 15 updated: 2003/07/05 18:42:30
dnl ---------------
dnl Check if the compiler supports useful warning options. There's a few that
dnl we don't use, simply because they're too noisy:
dnl
dnl -Wconversion (useful in older versions of gcc, but not in gcc 2.7.x)
dnl -Wredundant-decls (system headers make this too noisy)
dnl -Wtraditional (combines too many unrelated messages, only a few useful)
dnl -Wwrite-strings (too noisy, but should review occasionally). This
dnl is enabled for ncurses using "--enable-const".
dnl -pedantic
dnl
AC_DEFUN([CF_GCC_WARNINGS],
[
AC_REQUIRE([CF_GCC_VERSION])
if test "$GCC" = yes
then
cat > conftest.$ac_ext <<EOF
#line __oline__ "configure"
int main(int argc, char *argv[[]]) { return (argv[[argc-1]] == 0) ; }
EOF
AC_CHECKING([for $CC warning options])
cf_save_CFLAGS="$CFLAGS"
EXTRA_CFLAGS="-W -Wall"
cf_warn_CONST=""
test "$with_ext_const" = yes && cf_warn_CONST="Wwrite-strings"
for cf_opt in \
Wbad-function-cast \
Wcast-align \
Wcast-qual \
Winline \
Wmissing-declarations \
Wmissing-prototypes \
Wnested-externs \
Wpointer-arith \
Wshadow \
Wstrict-prototypes \
Wundef $cf_warn_CONST
do
CFLAGS="$cf_save_CFLAGS $EXTRA_CFLAGS -$cf_opt"
if AC_TRY_EVAL(ac_compile); then
test -n "$verbose" && AC_MSG_RESULT(... -$cf_opt)
case $cf_opt in #(vi
Wcast-qual) #(vi
CPPFLAGS="$CPPFLAGS -DXTSTRINGDEFINES"
;;
Winline) #(vi
case $GCC_VERSION in
3.3*)
CF_VERBOSE(feature is broken in gcc $GCC_VERSION)
continue;;
esac
;;
esac
EXTRA_CFLAGS="$EXTRA_CFLAGS -$cf_opt"
fi
done
rm -f conftest*
CFLAGS="$cf_save_CFLAGS"
fi
AC_SUBST(EXTRA_CFLAGS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PROG_EXT version: 10 updated: 2004/01/03 19:28:18
dnl -----------
dnl Compute $PROG_EXT, used for non-Unix ports, such as OS/2 EMX.
AC_DEFUN([CF_PROG_EXT],
[
AC_REQUIRE([CF_CHECK_CACHE])
case $cf_cv_system_name in
os2*)
CFLAGS="$CFLAGS -Zmt"
CPPFLAGS="$CPPFLAGS -D__ST_MT_ERRNO__"
CXXFLAGS="$CXXFLAGS -Zmt"
# autoconf's macro sets -Zexe and suffix both, which conflict:w
LDFLAGS="$LDFLAGS -Zmt -Zcrtdll"
ac_cv_exeext=.exe
;;
esac
AC_EXEEXT
AC_OBJEXT
PROG_EXT="$EXEEXT"
AC_SUBST(PROG_EXT)
test -n "$PROG_EXT" && AC_DEFINE_UNQUOTED(PROG_EXT,"$PROG_EXT")
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_UPPER version: 5 updated: 2001/01/29 23:40:59
dnl --------
dnl Make an uppercase version of a variable
dnl $1=uppercase($2)
AC_DEFUN([CF_UPPER],
[
$1=`echo "$2" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_VERBOSE version: 2 updated: 1997/09/05 10:45:14
dnl ----------
dnl Use AC_VERBOSE w/o the warnings
AC_DEFUN([CF_VERBOSE],
[test -n "$verbose" && echo " $1" 1>&AC_FD_MSG
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_DBMALLOC version: 4 updated: 2004/02/28 05:49:27
dnl ----------------
dnl Configure-option for dbmalloc. The optional parameter is used to override
dnl the updating of $LIBS, e.g., to avoid conflict with subsequent tests.
AC_DEFUN([CF_WITH_DBMALLOC],[
AC_MSG_CHECKING(if you want to link with dbmalloc for testing)
AC_ARG_WITH(dbmalloc,
[ --with-dbmalloc use Conor Cahill's dbmalloc library],
[with_dbmalloc=$withval],
[with_dbmalloc=no])
AC_MSG_RESULT($with_dbmalloc)
if test "$with_dbmalloc" = yes ; then
AC_CHECK_HEADER(dbmalloc.h,
[AC_CHECK_LIB(dbmalloc,[debug_malloc]ifelse($1,,[],[,$1]))])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_DMALLOC version: 4 updated: 2004/02/28 05:49:27
dnl ---------------
dnl Configure-option for dmalloc. The optional parameter is used to override
dnl the updating of $LIBS, e.g., to avoid conflict with subsequent tests.
AC_DEFUN([CF_WITH_DMALLOC],[
AC_MSG_CHECKING(if you want to link with dmalloc for testing)
AC_ARG_WITH(dmalloc,
[ --with-dmalloc use Gray Watson's dmalloc library],
[with_dmalloc=$withval],
[with_dmalloc=no])
AC_MSG_RESULT($with_dmalloc)
if test "$with_dmalloc" = yes ; then
AC_CHECK_HEADER(dmalloc.h,
[AC_CHECK_LIB(dmalloc,[dmalloc_debug]ifelse($1,,[],[,$1]))])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_WARNINGS version: 4 updated: 2003/05/24 15:01:41
dnl ----------------
dnl Combine the checks for gcc features into a configure-script option
AC_DEFUN([CF_WITH_WARNINGS],
[
if ( test "$GCC" = yes || test "$GXX" = yes )
then
AC_MSG_CHECKING(if you want to check for gcc warnings)
AC_ARG_WITH(warnings,
[ --with-warnings test: turn on gcc warnings],
[cf_opt_with_warnings=$withval],
[cf_opt_with_warnings=no])
AC_MSG_RESULT($cf_opt_with_warnings)
if test "$cf_opt_with_warnings" != no ; then
CF_GCC_ATTRIBUTES
CF_GCC_WARNINGS
fi
fi
])dnl

1450
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1549
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

3
config_h.in Normal file
View File

@ -0,0 +1,3 @@
/* @configure_input@ */
/* $Id: config_h.in,v 1.1 1995/01/01 19:34:59 tom Exp $ */
@DEFS@

2203
configure vendored Executable file

File diff suppressed because it is too large Load Diff

25
configure.in Normal file
View File

@ -0,0 +1,25 @@
dnl Process this file with 'autoconf' to produce a 'configure' script
dnl $Id: configure.in,v 1.4 2004/03/28 23:35:30 tom Exp $
AC_PREREQ(2.13.20020210)
AC_REVISION($Revision: 1.4 $)
AC_INIT(main.c)
AC_CONFIG_HEADER(config.h:config_h.in)
CF_CHECK_CACHE([AC_CANONICAL_SYSTEM])
AC_ARG_PROGRAM
AC_PROG_CC
AC_CONST
AC_PROG_MAKE_SET
AC_PROG_INSTALL
CF_ANSI_CC_REQD
CF_WITH_WARNINGS
CF_DISABLE_ECHO
CF_PROG_EXT
CF_WITH_DBMALLOC
CF_WITH_DMALLOC
### output makefile
AC_OUTPUT(makefile,,,cat)

13
defs.h
View File

@ -1,3 +1,9 @@
/* $Id: defs.h,v 1.5 2004/03/28 20:27:20 tom Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@ -207,13 +213,10 @@ extern char *header[];
extern char *body[];
extern char *trailer[];
extern char *action_file_name;
extern char *code_file_name;
extern char *defines_file_name;
extern char *input_file_name;
extern char *output_file_name;
extern char *text_file_name;
extern char *union_file_name;
extern char *verbose_file_name;
extern FILE *action_file;
@ -283,9 +286,7 @@ extern short final_state;
extern bucket *lookup(char *);
extern bucket *make_bucket(char *);
#ifdef __GNUC__
#define GCC_NORETURN __attribute__((noreturn))
#else
#ifndef GCC_NORETURN
#define GCC_NORETURN /* nothing */
#endif

251
install-sh Executable file
View File

@ -0,0 +1,251 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
:
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
:
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
:
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
:
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
:
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
:
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

76
main.c
View File

@ -1,3 +1,5 @@
/* $Id: main.c,v 1.5 2004/03/28 19:52:10 tom Exp $ */
#include <signal.h>
#include "defs.h"
@ -15,13 +17,10 @@ char *temp_form = "yacc.XXXXXXX";
int lineno;
int outline;
char *action_file_name;
char *code_file_name;
char *defines_file_name;
char *input_file_name = "";
char *output_file_name;
char *text_file_name;
char *union_file_name;
char *verbose_file_name;
FILE *action_file; /* a temp file, used to save actions associated */
@ -59,9 +58,9 @@ char *nullable;
void done(int k)
{
if (action_file) { fclose(action_file); remove(action_file_name); }
if (text_file) { fclose(text_file); remove(text_file_name); }
if (union_file) { fclose(union_file); remove(union_file_name); }
if (action_file) fclose(action_file);
if (text_file) fclose(text_file);
if (union_file) fclose(union_file);
exit(k);
}
@ -213,59 +212,9 @@ allocate(unsigned n)
return (p);
}
#ifdef VMS
#define DEFAULT_TMPDIR "sys$scratch"
#define PATHCHAR ':'
#else
#define DEFAULT_TMPDIR "/tmp"
#define PATHCHAR '/'
#endif
void create_file_names(void)
{
int i, len;
char *tmpdir;
tmpdir = getenv("TMPDIR");
if (tmpdir == 0) {
tmpdir = DEFAULT_TMPDIR;
}
len = strlen(tmpdir);
i = len + 13;
if (len && tmpdir[len-1] != PATHCHAR)
++i;
action_file_name = MALLOC(i);
if (action_file_name == 0) no_space();
text_file_name = MALLOC(i);
if (text_file_name == 0) no_space();
union_file_name = MALLOC(i);
if (union_file_name == 0) no_space();
strcpy(action_file_name, tmpdir);
strcpy(text_file_name, tmpdir);
strcpy(union_file_name, tmpdir);
if (len && tmpdir[len - 1] != PATHCHAR)
{
action_file_name[len] = PATHCHAR;
text_file_name[len] = PATHCHAR;
union_file_name[len] = PATHCHAR;
++len;
}
strcpy(action_file_name + len, temp_form);
strcpy(text_file_name + len, temp_form);
strcpy(union_file_name + len, temp_form);
action_file_name[len + 5] = 'a';
text_file_name[len + 5] = 't';
union_file_name[len + 5] = 'u';
mktemp(action_file_name);
mktemp(text_file_name);
mktemp(union_file_name);
int len;
len = strlen(file_prefix);
@ -317,13 +266,13 @@ void open_files(void)
open_error(input_file_name);
}
action_file = fopen(action_file_name, "w");
action_file = tmpfile();
if (action_file == 0)
open_error(action_file_name);
open_error("action_file");
text_file = fopen(text_file_name, "w");
text_file = tmpfile();
if (text_file == 0)
open_error(text_file_name);
open_error("text_file");
if (vflag)
{
@ -337,9 +286,9 @@ void open_files(void)
defines_file = fopen(defines_file_name, "w");
if (defines_file == 0)
open_error(defines_file_name);
union_file = fopen(union_file_name, "w");
union_file = tmpfile();
if (union_file == 0)
open_error(union_file_name);
open_error("union_file");
}
output_file = fopen(output_file_name, "w");
@ -360,7 +309,6 @@ void open_files(void)
int
main(int argc, char *argv[])
{
set_signals();
getargs(argc, argv);
open_files();
reader();

127
makefile.in Normal file
View File

@ -0,0 +1,127 @@
# $Id: makefile.in,v 1.5 2004/03/28 23:05:35 tom Exp $
#
# UNIX template-makefile for Berkeley Yacc
THIS = yacc
#### Start of system configuration section. ####
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
transform = @program_transform_name@
DEFINES =
EXTRA_CFLAGS = @EXTRA_CFLAGS@
CPPFLAGS = -I$(srcdir) $(DEFINES) -DHAVE_CONFIG_H @CPPFLAGS@
CFLAGS = @CFLAGS@ $(CPPFLAGS) $(EXTRA_CFLAGS)
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = $(DESTDIR)@bindir@
mandir = $(DESTDIR)@mandir@/man1
manext = 1
x = @EXEEXT@
o = .@OBJEXT@
#### End of system configuration section. ####
SHELL = /bin/sh
@SET_MAKE@
H_FILES = \
defs.h
C_FILES = \
closure.c \
error.c \
lalr.c \
lr0.c \
main.c \
mkpar.c \
output.c \
reader.c \
skeleton.c \
symtab.c \
verbose.c \
warshall.c
OBJS = \
closure$o \
error$o \
lalr$o \
lr0$o \
main$o \
mkpar$o \
output$o \
reader$o \
skeleton$o \
symtab$o \
verbose$o \
warshall$o
TRANSFORM_BIN = sed 's/$x$$//' |sed '$(transform)'|sed 's/$$/$x/'
TRANSFORM_MAN = sed 's/$(manext)$$//'|sed '$(transform)'|sed 's/$$/$(manext)/'
actual_bin = `echo $(THIS)$x | $(TRANSFORM_BIN)`
actual_man = `echo $(THIS).$(manext)| $(TRANSFORM_MAN)`
all : $(THIS)$x
install: all installdirs
$(INSTALL_PROGRAM) $(THIS)$x $(bindir)/$(actual_bin)
- $(INSTALL_DATA) $(srcdir)/$(THIS).1 $(mandir)/$(actual_man)
installdirs:
$(SHELL) ${srcdir}/mkdirs.sh $(bindir)
- $(SHELL) ${srcdir}/mkdirs.sh $(mandir)
uninstall:
- rm -f $(bindir)/$(actual_bin)
- rm -f $(mandir)/$(actual_man)
.c$o:
@RULE_CC@
@ECHO_CC@$(CC) -c $(CFLAGS) $<
$(THIS)$x : $(OBJS)
@ECHO_LD@$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
$(THIS).man : $(THIS).1
- nroff -man $(srcdir)/$(THIS).1 >$@
mostlyclean :
- rm -f core .nfs* *$o *.bak *.BAK *.log *.man *.out
clean : mostlyclean
- rm -f $(THIS)$x
distclean : clean
- rm -f config.log config.cache config.status config.h makefile
- cd test && rm -f test-*
realclean: distclean
- rm -f tags
check: $(THIS)$x
cd test && $(SHELL) ./run_test.sh
tags: $(H_FILES) $(C_FILES)
ctags -t $(C_FILES) $(H_FILES)
depend:
makedepend -- $(CPPFLAGS) -- $(C_FILES)
$(OBJS) : defs.h
# DO NOT DELETE THIS LINE -- make depend depends on it.

37
mkdirs.sh Executable file
View File

@ -0,0 +1,37 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Last modified: 1994-03-25
# Public domain
#
errstatus=0
umask 022
for file in ${1+"$@"} ; do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d in ${1+"$@"} ; do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
case "$pathcomp" in
[a-zA-Z]: ) ;; # DOSISH systems
* ) mkdir "$pathcomp" || errstatus=$? ;;
esac
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

View File

@ -1,3 +1,5 @@
/* $Id: output.c,v 1.3 2004/03/28 19:49:15 tom Exp $ */
#include "defs.h"
static int nvectors;
@ -808,9 +810,9 @@ void output_defines(void)
if (dflag && unionized)
{
fclose(union_file);
union_file = fopen(union_file_name, "r");
if (union_file == NULL) open_error(union_file_name);
rewind(union_file);
union_file = tmpfile();
if (union_file == NULL) open_error("union_file");
while ((c = getc(union_file)) != EOF)
putc(c, defines_file);
fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE %slval;\n",
@ -824,10 +826,9 @@ void output_stored_text(void)
register int c;
register FILE *in, *out;
fclose(text_file);
text_file = fopen(text_file_name, "r");
rewind(text_file);
if (text_file == NULL)
open_error(text_file_name);
open_error("text_file");
in = text_file;
if ((c = getc(in)) == EOF)
return;
@ -1132,11 +1133,7 @@ void output_semantic_actions(void)
register int c, last;
register FILE *out;
fclose(action_file);
action_file = fopen(action_file_name, "r");
if (action_file == NULL)
open_error(action_file_name);
rewind(action_file);
if ((c = getc(action_file)) == EOF)
return;

View File

@ -15,7 +15,7 @@
char *banner[] =
{
"#ifndef lint",
"static char yysccsid[] = \"@(#)yaccpar 1.9 (Berkeley) 02/21/93\";",
"static const char yysccsid[] = \"@(#)yaccpar 1.9 (Berkeley) 02/21/93\";",
"#endif",
"#define YYBYACC 1",
"#define YYMAJOR 1",
@ -23,6 +23,7 @@ char *banner[] =
"#define yyclearin (yychar=(-1))",
"#define yyerrok (yyerrflag=0)",
"#define YYRECOVERING (yyerrflag!=0)",
"extern int yyparse(void);",
0
};
@ -105,7 +106,7 @@ char *body[] =
" *yyssp = yystate = 0;",
"",
"yyloop:",
" if (yyn = yydefred[yystate]) goto yyreduce;",
" if ((yyn = yydefred[yystate]) != 0) goto yyreduce;",
" if (yychar < 0)",
" {",
" if ((yychar = yylex()) < 0) yychar = 0;",

4
test/README Normal file
View File

@ -0,0 +1,4 @@
-- $Id: README,v 1.1 2004/03/28 19:10:48 tom Exp $
The files in this directory are input (.y) and output (.output, .tab.c, .tab.h)
examples.

461
test/calc.output Normal file
View File

@ -0,0 +1,461 @@
0 $accept : list $end
1 list :
2 | list stat '\n'
3 | list error '\n'
4 stat : expr
5 | LETTER '=' expr
6 expr : '(' expr ')'
7 | expr '+' expr
8 | expr '-' expr
9 | expr '*' expr
10 | expr '/' expr
11 | expr '%' expr
12 | expr '&' expr
13 | expr '|' expr
14 | '-' expr
15 | LETTER
16 | number
17 number : DIGIT
18 | number DIGIT
state 0
$accept : . list $end (0)
list : . (1)
. reduce 1
list goto 1
state 1
$accept : list . $end (0)
list : list . stat '\n' (2)
list : list . error '\n' (3)
$end accept
error shift 2
DIGIT shift 3
LETTER shift 4
'-' shift 5
'(' shift 6
. error
stat goto 7
expr goto 8
number goto 9
state 2
list : list error . '\n' (3)
'\n' shift 10
. error
state 3
number : DIGIT . (17)
. reduce 17
state 4
stat : LETTER . '=' expr (5)
expr : LETTER . (15)
'=' shift 11
'|' reduce 15
'&' reduce 15
'+' reduce 15
'-' reduce 15
'*' reduce 15
'/' reduce 15
'%' reduce 15
'\n' reduce 15
state 5
expr : '-' . expr (14)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 13
number goto 9
state 6
expr : '(' . expr ')' (6)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 14
number goto 9
state 7
list : list stat . '\n' (2)
'\n' shift 15
. error
state 8
stat : expr . (4)
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
'|' shift 16
'&' shift 17
'+' shift 18
'-' shift 19
'*' shift 20
'/' shift 21
'%' shift 22
'\n' reduce 4
state 9
expr : number . (16)
number : number . DIGIT (18)
DIGIT shift 23
'|' reduce 16
'&' reduce 16
'+' reduce 16
'-' reduce 16
'*' reduce 16
'/' reduce 16
'%' reduce 16
'\n' reduce 16
')' reduce 16
state 10
list : list error '\n' . (3)
. reduce 3
state 11
stat : LETTER '=' . expr (5)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 24
number goto 9
state 12
expr : LETTER . (15)
. reduce 15
state 13
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
expr : '-' expr . (14)
. reduce 14
state 14
expr : '(' expr . ')' (6)
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
'|' shift 16
'&' shift 17
'+' shift 18
'-' shift 19
'*' shift 20
'/' shift 21
'%' shift 22
')' shift 25
. error
state 15
list : list stat '\n' . (2)
. reduce 2
state 16
expr : expr '|' . expr (13)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 26
number goto 9
state 17
expr : expr '&' . expr (12)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 27
number goto 9
state 18
expr : expr '+' . expr (7)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 28
number goto 9
state 19
expr : expr '-' . expr (8)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 29
number goto 9
state 20
expr : expr '*' . expr (9)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 30
number goto 9
state 21
expr : expr '/' . expr (10)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 31
number goto 9
state 22
expr : expr '%' . expr (11)
DIGIT shift 3
LETTER shift 12
'-' shift 5
'(' shift 6
. error
expr goto 32
number goto 9
state 23
number : number DIGIT . (18)
. reduce 18
state 24
stat : LETTER '=' expr . (5)
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
'|' shift 16
'&' shift 17
'+' shift 18
'-' shift 19
'*' shift 20
'/' shift 21
'%' shift 22
'\n' reduce 5
state 25
expr : '(' expr ')' . (6)
. reduce 6
state 26
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
expr : expr '|' expr . (13)
'&' shift 17
'+' shift 18
'-' shift 19
'*' shift 20
'/' shift 21
'%' shift 22
'|' reduce 13
'\n' reduce 13
')' reduce 13
state 27
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr '&' expr . (12)
expr : expr . '|' expr (13)
'+' shift 18
'-' shift 19
'*' shift 20
'/' shift 21
'%' shift 22
'|' reduce 12
'&' reduce 12
'\n' reduce 12
')' reduce 12
state 28
expr : expr . '+' expr (7)
expr : expr '+' expr . (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
'*' shift 20
'/' shift 21
'%' shift 22
'|' reduce 7
'&' reduce 7
'+' reduce 7
'-' reduce 7
'\n' reduce 7
')' reduce 7
state 29
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr '-' expr . (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
'*' shift 20
'/' shift 21
'%' shift 22
'|' reduce 8
'&' reduce 8
'+' reduce 8
'-' reduce 8
'\n' reduce 8
')' reduce 8
state 30
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr '*' expr . (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
. reduce 9
state 31
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr '/' expr . (10)
expr : expr . '%' expr (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
. reduce 10
state 32
expr : expr . '+' expr (7)
expr : expr . '-' expr (8)
expr : expr . '*' expr (9)
expr : expr . '/' expr (10)
expr : expr . '%' expr (11)
expr : expr '%' expr . (11)
expr : expr . '&' expr (12)
expr : expr . '|' expr (13)
. reduce 11
16 terminals, 5 nonterminals
19 grammar rules, 33 states

463
test/calc.tab.c Normal file
View File

@ -0,0 +1,463 @@
#ifndef lint
static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
#endif
#define YYBYACC 1
#define YYMAJOR 1
#define YYMINOR 9
#define yyclearin (yychar=(-1))
#define yyerrok (yyerrflag=0)
#define YYRECOVERING (yyerrflag!=0)
extern int yyparse(void);
#define YYPREFIX "yy"
#line 2 "calc.y"
# include <stdio.h>
# include <ctype.h>
int regs[26];
int base;
#line 20 "calc.tab.c"
#define DIGIT 257
#define LETTER 258
#define UMINUS 259
#define YYERRCODE 256
short yylhs[] = { -1,
0, 0, 0, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3,
};
short yylen[] = { 2,
0, 3, 3, 1, 3, 3, 3, 3, 3, 3,
3, 3, 3, 2, 1, 1, 1, 2,
};
short yydefred[] = { 1,
0, 0, 17, 0, 0, 0, 0, 0, 0, 3,
0, 15, 14, 0, 2, 0, 0, 0, 0, 0,
0, 0, 18, 0, 6, 0, 0, 0, 0, 9,
10, 11,
};
short yydgoto[] = { 1,
7, 8, 9,
};
short yysindex[] = { 0,
-40, -7, 0, -55, -38, -38, 1, -29, -247, 0,
-38, 0, 0, 22, 0, -38, -38, -38, -38, -38,
-38, -38, 0, -29, 0, 51, 60, -20, -20, 0,
0, 0,
};
short yyrindex[] = { 0,
0, 0, 0, 2, 0, 0, 0, 9, -9, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 10, 0, -6, 14, 5, 13, 0,
0, 0,
};
short yygindex[] = { 0,
0, 65, 0,
};
#define YYTABLESIZE 220
short yytable[] = { 6,
16, 6, 10, 13, 5, 11, 5, 22, 17, 23,
15, 15, 20, 18, 7, 19, 22, 21, 4, 5,
0, 20, 8, 12, 0, 0, 21, 16, 16, 0,
0, 16, 16, 16, 13, 16, 0, 16, 15, 15,
0, 0, 7, 15, 15, 7, 15, 7, 15, 7,
8, 12, 0, 8, 12, 8, 0, 8, 22, 17,
0, 0, 25, 20, 18, 0, 19, 0, 21, 13,
14, 0, 0, 0, 0, 24, 0, 0, 0, 0,
26, 27, 28, 29, 30, 31, 32, 22, 17, 0,
0, 0, 20, 18, 16, 19, 22, 21, 0, 0,
0, 20, 18, 0, 19, 0, 21, 0, 0, 0,
0, 0, 0, 0, 16, 0, 0, 13, 0, 0,
0, 0, 0, 0, 0, 15, 0, 0, 7, 0,
0, 0, 0, 0, 0, 0, 8, 12, 0, 0,
0, 0, 0, 0, 0, 16, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2, 3, 4, 3, 12,
};
short yycheck[] = { 40,
10, 40, 10, 10, 45, 61, 45, 37, 38, 257,
10, 10, 42, 43, 10, 45, 37, 47, 10, 10,
-1, 42, 10, 10, -1, -1, 47, 37, 38, -1,
-1, 41, 42, 43, 41, 45, -1, 47, 37, 38,
-1, -1, 38, 42, 43, 41, 45, 43, 47, 45,
38, 38, -1, 41, 41, 43, -1, 45, 37, 38,
-1, -1, 41, 42, 43, -1, 45, -1, 47, 5,
6, -1, -1, -1, -1, 11, -1, -1, -1, -1,
16, 17, 18, 19, 20, 21, 22, 37, 38, -1,
-1, -1, 42, 43, 124, 45, 37, 47, -1, -1,
-1, 42, 43, -1, 45, -1, 47, -1, -1, -1,
-1, -1, -1, -1, 124, -1, -1, 124, -1, -1,
-1, -1, -1, -1, -1, 124, -1, -1, 124, -1,
-1, -1, -1, -1, -1, -1, 124, 124, -1, -1,
-1, -1, -1, -1, -1, 124, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 256, 257, 258, 257, 258,
};
#define YYFINAL 1
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 259
#if YYDEBUG
char *yyname[] = {
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0,
0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,"DIGIT","LETTER","UMINUS",
};
char *yyrule[] = {
"$accept : list",
"list :",
"list : list stat '\\n'",
"list : list error '\\n'",
"stat : expr",
"stat : LETTER '=' expr",
"expr : '(' expr ')'",
"expr : expr '+' expr",
"expr : expr '-' expr",
"expr : expr '*' expr",
"expr : expr '/' expr",
"expr : expr '%' expr",
"expr : expr '&' expr",
"expr : expr '|' expr",
"expr : '-' expr",
"expr : LETTER",
"expr : number",
"number : DIGIT",
"number : number DIGIT",
};
#endif
#ifndef YYSTYPE
typedef int YYSTYPE;
#endif
#ifdef YYSTACKSIZE
#undef YYMAXDEPTH
#define YYMAXDEPTH YYSTACKSIZE
#else
#ifdef YYMAXDEPTH
#define YYSTACKSIZE YYMAXDEPTH
#else
#define YYSTACKSIZE 500
#define YYMAXDEPTH 500
#endif
#endif
int yydebug;
int yynerrs;
int yyerrflag;
int yychar;
short *yyssp;
YYSTYPE *yyvsp;
YYSTYPE yyval;
YYSTYPE yylval;
short yyss[YYSTACKSIZE];
YYSTYPE yyvs[YYSTACKSIZE];
#define yystacksize YYSTACKSIZE
#line 63 "calc.y"
/* start of programs */
main ()
{
while(!feof(stdin)) {
yyparse();
}
}
yyerror(char *s)
{
fprintf(stderr, "%s\n", s);
}
yylex() { /* lexical analysis routine */
/* returns LETTER for a lower case letter, yylval = 0 through 25 */
/* return DIGIT for a digit, yylval = 0 through 9 */
/* all other characters are returned immediately */
int c;
while( (c=getchar()) == ' ' ) { /* skip blanks */ }
/* c is now nonblank */
if( islower( c )) {
yylval = c - 'a';
return ( LETTER );
}
if( isdigit( c )) {
yylval = c - '0';
return ( DIGIT );
}
return( c );
}
#line 207 "calc.tab.c"
#define YYABORT goto yyabort
#define YYREJECT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab
int
yyparse(void)
{
register int yym, yyn, yystate;
#if YYDEBUG
register char *yys;
extern char *getenv();
if (yys = getenv("YYDEBUG"))
{
yyn = *yys;
if (yyn >= '0' && yyn <= '9')
yydebug = yyn - '0';
}
#endif
yynerrs = 0;
yyerrflag = 0;
yychar = (-1);
yyssp = yyss;
yyvsp = yyvs;
*yyssp = yystate = 0;
yyloop:
if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
if (yychar < 0)
{
if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
if (yydebug)
{
yys = 0;
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
if (!yys) yys = "illegal-symbol";
printf("%sdebug: state %d, reading %d (%s)\n",
YYPREFIX, yystate, yychar, yys);
}
#endif
}
if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
{
#if YYDEBUG
if (yydebug)
printf("%sdebug: state %d, shifting to state %d\n",
YYPREFIX, yystate, yytable[yyn]);
#endif
if (yyssp >= yyss + yystacksize - 1)
{
goto yyoverflow;
}
*++yyssp = yystate = yytable[yyn];
*++yyvsp = yylval;
yychar = (-1);
if (yyerrflag > 0) --yyerrflag;
goto yyloop;
}
if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
{
yyn = yytable[yyn];
goto yyreduce;
}
if (yyerrflag) goto yyinrecovery;
#ifdef lint
goto yynewerror;
#endif
yynewerror:
yyerror("syntax error");
#ifdef lint
goto yyerrlab;
#endif
yyerrlab:
++yynerrs;
yyinrecovery:
if (yyerrflag < 3)
{
yyerrflag = 3;
for (;;)
{
if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
{
#if YYDEBUG
if (yydebug)
printf("%sdebug: state %d, error recovery shifting\
to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
#endif
if (yyssp >= yyss + yystacksize - 1)
{
goto yyoverflow;
}
*++yyssp = yystate = yytable[yyn];
*++yyvsp = yylval;
goto yyloop;
}
else
{
#if YYDEBUG
if (yydebug)
printf("%sdebug: error recovery discarding state %d\n",
YYPREFIX, *yyssp);
#endif
if (yyssp <= yyss) goto yyabort;
--yyssp;
--yyvsp;
}
}
}
else
{
if (yychar == 0) goto yyabort;
#if YYDEBUG
if (yydebug)
{
yys = 0;
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
if (!yys) yys = "illegal-symbol";
printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
YYPREFIX, yystate, yychar, yys);
}
#endif
yychar = (-1);
goto yyloop;
}
yyreduce:
#if YYDEBUG
if (yydebug)
printf("%sdebug: state %d, reducing by rule %d (%s)\n",
YYPREFIX, yystate, yyn, yyrule[yyn]);
#endif
yym = yylen[yyn];
yyval = yyvsp[1-yym];
switch (yyn)
{
case 3:
#line 25 "calc.y"
{ yyerrok ; }
break;
case 4:
#line 29 "calc.y"
{ printf("%d\n",yyvsp[0]);}
break;
case 5:
#line 31 "calc.y"
{ regs[yyvsp[-2]] = yyvsp[0]; }
break;
case 6:
#line 35 "calc.y"
{ yyval = yyvsp[-1]; }
break;
case 7:
#line 37 "calc.y"
{ yyval = yyvsp[-2] + yyvsp[0]; }
break;
case 8:
#line 39 "calc.y"
{ yyval = yyvsp[-2] - yyvsp[0]; }
break;
case 9:
#line 41 "calc.y"
{ yyval = yyvsp[-2] * yyvsp[0]; }
break;
case 10:
#line 43 "calc.y"
{ yyval = yyvsp[-2] / yyvsp[0]; }
break;
case 11:
#line 45 "calc.y"
{ yyval = yyvsp[-2] % yyvsp[0]; }
break;
case 12:
#line 47 "calc.y"
{ yyval = yyvsp[-2] & yyvsp[0]; }
break;
case 13:
#line 49 "calc.y"
{ yyval = yyvsp[-2] | yyvsp[0]; }
break;
case 14:
#line 51 "calc.y"
{ yyval = - yyvsp[0]; }
break;
case 15:
#line 53 "calc.y"
{ yyval = regs[yyvsp[0]]; }
break;
case 17:
#line 58 "calc.y"
{ yyval = yyvsp[0]; base = (yyvsp[0]==0) ? 8 : 10; }
break;
case 18:
#line 60 "calc.y"
{ yyval = base * yyvsp[-1] + yyvsp[0]; }
break;
#line 408 "calc.tab.c"
}
yyssp -= yym;
yystate = *yyssp;
yyvsp -= yym;
yym = yylhs[yyn];
if (yystate == 0 && yym == 0)
{
#if YYDEBUG
if (yydebug)
printf("%sdebug: after reduction, shifting from state 0 to\
state %d\n", YYPREFIX, YYFINAL);
#endif
yystate = YYFINAL;
*++yyssp = YYFINAL;
*++yyvsp = yyval;
if (yychar < 0)
{
if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
if (yydebug)
{
yys = 0;
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
if (!yys) yys = "illegal-symbol";
printf("%sdebug: state %d, reading %d (%s)\n",
YYPREFIX, YYFINAL, yychar, yys);
}
#endif
}
if (yychar == 0) goto yyaccept;
goto yyloop;
}
if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
yystate = yytable[yyn];
else
yystate = yydgoto[yym];
#if YYDEBUG
if (yydebug)
printf("%sdebug: after reduction, shifting from state %d \
to state %d\n", YYPREFIX, *yyssp, yystate);
#endif
if (yyssp >= yyss + yystacksize - 1)
{
goto yyoverflow;
}
*++yyssp = yystate;
*++yyvsp = yyval;
goto yyloop;
yyoverflow:
yyerror("yacc stack overflow");
yyabort:
return (1);
yyaccept:
return (0);
}

3
test/calc.tab.h Normal file
View File

@ -0,0 +1,3 @@
#define DIGIT 257
#define LETTER 258
#define UMINUS 259

99
test/calc.y Normal file
View File

@ -0,0 +1,99 @@
%{
# include <stdio.h>
# include <ctype.h>
int regs[26];
int base;
%}
%start list
%token DIGIT LETTER
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS /* supplies precedence for unary minus */
%% /* beginning of rules section */
list : /* empty */
| list stat '\n'
| list error '\n'
{ yyerrok ; }
;
stat : expr
{ printf("%d\n",$1);}
| LETTER '=' expr
{ regs[$1] = $3; }
;
expr : '(' expr ')'
{ $$ = $2; }
| expr '+' expr
{ $$ = $1 + $3; }
| expr '-' expr
{ $$ = $1 - $3; }
| expr '*' expr
{ $$ = $1 * $3; }
| expr '/' expr
{ $$ = $1 / $3; }
| expr '%' expr
{ $$ = $1 % $3; }
| expr '&' expr
{ $$ = $1 & $3; }
| expr '|' expr
{ $$ = $1 | $3; }
| '-' expr %prec UMINUS
{ $$ = - $2; }
| LETTER
{ $$ = regs[$1]; }
| number
;
number: DIGIT
{ $$ = $1; base = ($1==0) ? 8 : 10; }
| number DIGIT
{ $$ = base * $1 + $2; }
;
%% /* start of programs */
main ()
{
while(!feof(stdin)) {
yyparse();
}
}
yyerror(char *s)
{
fprintf(stderr, "%s\n", s);
}
yylex() { /* lexical analysis routine */
/* returns LETTER for a lower case letter, yylval = 0 through 25 */
/* return DIGIT for a digit, yylval = 0 through 9 */
/* all other characters are returned immediately */
int c;
while( (c=getchar()) == ' ' ) { /* skip blanks */ }
/* c is now nonblank */
if( islower( c )) {
yylval = c - 'a';
return ( LETTER );
}
if( isdigit( c )) {
yylval = c - '0';
return ( DIGIT );
}
return( c );
}

View File

@ -1,5 +1,5 @@
#ifndef lint
static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
#endif
#define YYBYACC 1
#define YYMAJOR 1
@ -7,6 +7,7 @@ static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
#define yyclearin (yychar=(-1))
#define yyerrok (yyerrflag=0)
#define YYRECOVERING (yyerrflag!=0)
extern int yyparse(void);
#define YYPREFIX "yy"
#define YYERRCODE 256
short yylhs[] = { -1,
@ -76,13 +77,13 @@ YYSTYPE yyvs[YYSTACKSIZE];
main(){printf("yyparse() = %d\n",yyparse());}
yylex(){return-1;}
yyerror(s)char*s;{printf("%s\n",s);}
#line 80 "error.tab.c"
#line 81 "error.tab.c"
#define YYABORT goto yyabort
#define YYREJECT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab
int
yyparse()
yyparse(void)
{
register int yym, yyn, yystate;
#if YYDEBUG
@ -106,7 +107,7 @@ yyparse()
*yyssp = yystate = 0;
yyloop:
if (yyn = yydefred[yystate]) goto yyreduce;
if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
if (yychar < 0)
{
if ((yychar = yylex()) < 0) yychar = 0;

View File

@ -1,5 +1,5 @@
#ifndef lint
static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
#endif
#define YYBYACC 1
#define YYMAJOR 1
@ -7,6 +7,7 @@ static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
#define yyclearin (yychar=(-1))
#define yyerrok (yyerrflag=0)
#define YYRECOVERING (yyerrflag!=0)
extern int yyparse(void);
#define YYPREFIX "yy"
#line 26 "ftp.y"
@ -56,7 +57,7 @@ char cbuf[512];
char *fromname;
char *index();
#line 60 "ftp.tab.c"
#line 61 "ftp.tab.c"
#define A 257
#define B 258
#define C 259
@ -904,13 +905,13 @@ char *filename;
reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
}
}
#line 908 "ftp.tab.c"
#line 909 "ftp.tab.c"
#define YYABORT goto yyabort
#define YYREJECT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab
int
yyparse()
yyparse(void)
{
register int yym, yyn, yystate;
#if YYDEBUG
@ -934,7 +935,7 @@ yyparse()
*yyssp = yystate = 0;
yyloop:
if (yyn = yydefred[yystate]) goto yyreduce;
if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
if (yychar < 0)
{
if ((yychar = yylex()) < 0) yychar = 0;
@ -1684,7 +1685,7 @@ case 73:
}
}
break;
#line 1688 "ftp.tab.c"
#line 1689 "ftp.tab.c"
}
yyssp -= yym;
yystate = *yyssp;

2214
test/grammar.output Normal file

File diff suppressed because it is too large Load Diff

1615
test/grammar.tab.c Normal file

File diff suppressed because it is too large Load Diff

35
test/grammar.tab.h Normal file
View File

@ -0,0 +1,35 @@
#define T_IDENTIFIER 257
#define T_TYPEDEF_NAME 258
#define T_DEFINE_NAME 259
#define T_AUTO 260
#define T_EXTERN 261
#define T_REGISTER 262
#define T_STATIC 263
#define T_TYPEDEF 264
#define T_INLINE 265
#define T_EXTENSION 266
#define T_CHAR 267
#define T_DOUBLE 268
#define T_FLOAT 269
#define T_INT 270
#define T_VOID 271
#define T_LONG 272
#define T_SHORT 273
#define T_SIGNED 274
#define T_UNSIGNED 275
#define T_ENUM 276
#define T_STRUCT 277
#define T_UNION 278
#define T_Bool 279
#define T_Complex 280
#define T_Imaginary 281
#define T_TYPE_QUALIFIER 282
#define T_BRACKETS 283
#define T_LBRACE 284
#define T_MATCHRBRACE 285
#define T_ELLIPSIS 286
#define T_INITIALIZER 287
#define T_STRING_LITERAL 288
#define T_ASM 289
#define T_ASMARG 290
#define T_VA_DCL 291

973
test/grammar.y Normal file
View File

@ -0,0 +1,973 @@
/* $Id: grammar.y,v 1.1 2004/03/24 21:29:23 tom Exp $
*
* yacc grammar for C function prototype generator
* This was derived from the grammar in Appendix A of
* "The C Programming Language" by Kernighan and Ritchie.
*/
%token <text> '(' '*' '&'
/* identifiers that are not reserved words */
T_IDENTIFIER T_TYPEDEF_NAME T_DEFINE_NAME
/* storage class */
T_AUTO T_EXTERN T_REGISTER T_STATIC T_TYPEDEF
/* This keyword included for compatibility with C++. */
T_INLINE
/* This keyword included for compatibility with GCC */
T_EXTENSION
/* type specifiers */
T_CHAR T_DOUBLE T_FLOAT T_INT T_VOID
T_LONG T_SHORT T_SIGNED T_UNSIGNED
T_ENUM T_STRUCT T_UNION
/* C9X new types */
T_Bool T_Complex T_Imaginary
/* type qualifiers */
T_TYPE_QUALIFIER
/* paired square brackets and everything between them: [ ... ] */
T_BRACKETS
%token
/* left brace */
T_LBRACE
/* all input to the matching right brace */
T_MATCHRBRACE
/* three periods */
T_ELLIPSIS
/* constant expression or paired braces following an equal sign */
T_INITIALIZER
/* string literal */
T_STRING_LITERAL
/* asm */
T_ASM
/* ( "string literal" ) following asm keyword */
T_ASMARG
/* va_dcl from <varargs.h> */
T_VA_DCL
%type <decl_spec> decl_specifiers decl_specifier
%type <decl_spec> storage_class type_specifier type_qualifier
%type <decl_spec> struct_or_union_specifier enum_specifier
%type <decl_list> init_declarator_list
%type <declarator> init_declarator declarator direct_declarator
%type <declarator> abs_declarator direct_abs_declarator
%type <param_list> parameter_type_list parameter_list
%type <parameter> parameter_declaration
%type <param_list> opt_identifier_list identifier_list
%type <text> struct_or_union pointer opt_type_qualifiers type_qualifier_list
any_id identifier_or_ref
%type <text> enumeration
%{
#include <stdio.h>
#include <ctype.h>
#include "cproto.h"
#include "symbol.h"
#include "semantic.h"
#define YYMAXDEPTH 150
extern int yylex (void);
/* declaration specifier attributes for the typedef statement currently being
* scanned
*/
static int cur_decl_spec_flags;
/* pointer to parameter list for the current function definition */
static ParameterList *func_params;
/* A parser semantic action sets this pointer to the current declarator in
* a function parameter declaration in order to catch any comments following
* the parameter declaration on the same line. If the lexer scans a comment
* and <cur_declarator> is not NULL, then the comment is attached to the
* declarator. To ignore subsequent comments, the lexer sets this to NULL
* after scanning a comment or end of line.
*/
static Declarator *cur_declarator;
/* temporary string buffer */
static char buf[MAX_TEXT_SIZE];
/* table of typedef names */
static SymbolTable *typedef_names;
/* table of define names */
static SymbolTable *define_names;
/* table of type qualifiers */
static SymbolTable *type_qualifiers;
/* information about the current input file */
typedef struct {
char *base_name; /* base input file name */
char *file_name; /* current file name */
FILE *file; /* input file */
unsigned line_num; /* current line number in input file */
FILE *tmp_file; /* temporary file */
long begin_comment; /* tmp file offset after last written ) or ; */
long end_comment; /* tmp file offset after last comment */
boolean convert; /* if TRUE, convert function definitions */
boolean changed; /* TRUE if conversion done in this file */
} IncludeStack;
static IncludeStack *cur_file; /* current input file */
#include "yyerror.c"
static int haveAnsiParam (void);
/* Flags to enable us to find if a procedure returns a value.
*/
static int return_val, /* nonzero on BRACES iff return-expression found */
returned_at; /* marker for token-number to set 'return_val' */
#if OPT_LINTLIBRARY
static char *dft_decl_spec (void);
static char *
dft_decl_spec (void)
{
return (lintLibrary() && !return_val) ? "void" : "int";
}
#else
#define dft_decl_spec() "int"
#endif
static int
haveAnsiParam (void)
{
Parameter *p;
if (func_params != 0) {
for (p = func_params->first; p != 0; p = p->next) {
if (p->declarator->func_def == FUNC_ANSI) {
return TRUE;
}
}
}
return FALSE;
}
%}
%%
program
: /* empty */
| translation_unit
;
translation_unit
: external_declaration
| translation_unit external_declaration
;
external_declaration
: declaration
| function_definition
| ';'
| linkage_specification
| T_ASM T_ASMARG ';'
| error T_MATCHRBRACE
{
yyerrok;
}
| error ';'
{
yyerrok;
}
;
braces
: T_LBRACE T_MATCHRBRACE
;
linkage_specification
: T_EXTERN T_STRING_LITERAL braces
{
/* Provide an empty action here so bison will not complain about
* incompatible types in the default action it normally would
* have generated.
*/
}
| T_EXTERN T_STRING_LITERAL declaration
{
/* empty */
}
;
declaration
: decl_specifiers ';'
{
#if OPT_LINTLIBRARY
if (types_out && want_typedef()) {
gen_declarations(&$1, (DeclaratorList *)0);
flush_varargs();
}
#endif
free_decl_spec(&$1);
end_typedef();
}
| decl_specifiers init_declarator_list ';'
{
if (func_params != NULL) {
set_param_types(func_params, &$1, &$2);
} else {
gen_declarations(&$1, &$2);
#if OPT_LINTLIBRARY
flush_varargs();
#endif
free_decl_list(&$2);
}
free_decl_spec(&$1);
end_typedef();
}
| any_typedef decl_specifiers
{
cur_decl_spec_flags = $2.flags;
free_decl_spec(&$2);
}
opt_declarator_list ';'
{
end_typedef();
}
;
any_typedef
: T_EXTENSION T_TYPEDEF
{
begin_typedef();
}
| T_TYPEDEF
{
begin_typedef();
}
;
opt_declarator_list
: /* empty */
| declarator_list
;
declarator_list
: declarator
{
int flags = cur_decl_spec_flags;
/* If the typedef is a pointer type, then reset the short type
* flags so it does not get promoted.
*/
if (strcmp($1->text, $1->name) != 0)
flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
new_symbol(typedef_names, $1->name, NULL, flags);
free_declarator($1);
}
| declarator_list ',' declarator
{
int flags = cur_decl_spec_flags;
if (strcmp($3->text, $3->name) != 0)
flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
new_symbol(typedef_names, $3->name, NULL, flags);
free_declarator($3);
}
;
function_definition
: decl_specifiers declarator
{
check_untagged(&$1);
if ($2->func_def == FUNC_NONE) {
yyerror("syntax error");
YYERROR;
}
func_params = &($2->head->params);
func_params->begin_comment = cur_file->begin_comment;
func_params->end_comment = cur_file->end_comment;
}
opt_declaration_list T_LBRACE
{
/* If we're converting to K&R and we've got a nominally K&R
* function which has a parameter which is ANSI (i.e., a prototyped
* function pointer), then we must override the deciphered value of
* 'func_def' so that the parameter will be converted.
*/
if (func_style == FUNC_TRADITIONAL
&& haveAnsiParam()
&& $2->head->func_def == func_style) {
$2->head->func_def = FUNC_BOTH;
}
func_params = NULL;
if (cur_file->convert)
gen_func_definition(&$1, $2);
gen_prototype(&$1, $2);
#if OPT_LINTLIBRARY
flush_varargs();
#endif
free_decl_spec(&$1);
free_declarator($2);
}
T_MATCHRBRACE
| declarator
{
if ($1->func_def == FUNC_NONE) {
yyerror("syntax error");
YYERROR;
}
func_params = &($1->head->params);
func_params->begin_comment = cur_file->begin_comment;
func_params->end_comment = cur_file->end_comment;
}
opt_declaration_list T_LBRACE T_MATCHRBRACE
{
DeclSpec decl_spec;
func_params = NULL;
new_decl_spec(&decl_spec, dft_decl_spec(), $1->begin, DS_NONE);
if (cur_file->convert)
gen_func_definition(&decl_spec, $1);
gen_prototype(&decl_spec, $1);
#if OPT_LINTLIBRARY
flush_varargs();
#endif
free_decl_spec(&decl_spec);
free_declarator($1);
}
;
opt_declaration_list
: /* empty */
| T_VA_DCL
| declaration_list
;
declaration_list
: declaration
| declaration_list declaration
;
decl_specifiers
: decl_specifier
| decl_specifiers decl_specifier
{
join_decl_specs(&$$, &$1, &$2);
free($1.text);
free($2.text);
}
;
decl_specifier
: storage_class
| type_specifier
| type_qualifier
;
storage_class
: T_AUTO
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_EXTERN
{
new_decl_spec(&$$, $1.text, $1.begin, DS_EXTERN);
}
| T_REGISTER
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_STATIC
{
new_decl_spec(&$$, $1.text, $1.begin, DS_STATIC);
}
| T_INLINE
{
new_decl_spec(&$$, $1.text, $1.begin, DS_INLINE);
}
| T_EXTENSION
{
new_decl_spec(&$$, $1.text, $1.begin, DS_JUNK);
}
;
type_specifier
: T_CHAR
{
new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
}
| T_DOUBLE
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_FLOAT
{
new_decl_spec(&$$, $1.text, $1.begin, DS_FLOAT);
}
| T_INT
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_LONG
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_SHORT
{
new_decl_spec(&$$, $1.text, $1.begin, DS_SHORT);
}
| T_SIGNED
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_UNSIGNED
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_VOID
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_Bool
{
new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
}
| T_Complex
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_Imaginary
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_TYPEDEF_NAME
{
Symbol *s;
s = find_symbol(typedef_names, $1.text);
if (s != NULL)
new_decl_spec(&$$, $1.text, $1.begin, s->flags);
}
| struct_or_union_specifier
| enum_specifier
;
type_qualifier
: T_TYPE_QUALIFIER
{
new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
}
| T_DEFINE_NAME
{
/* This rule allows the <pointer> nonterminal to scan #define
* names as if they were type modifiers.
*/
Symbol *s;
s = find_symbol(define_names, $1.text);
if (s != NULL)
new_decl_spec(&$$, $1.text, $1.begin, s->flags);
}
;
struct_or_union_specifier
: struct_or_union any_id braces
{
char *s;
if ((s = implied_typedef()) == 0)
(void)sprintf(s = buf, "%s %s", $1.text, $2.text);
new_decl_spec(&$$, s, $1.begin, DS_NONE);
}
| struct_or_union braces
{
char *s;
if ((s = implied_typedef()) == 0)
(void)sprintf(s = buf, "%s {}", $1.text);
new_decl_spec(&$$, s, $1.begin, DS_NONE);
}
| struct_or_union any_id
{
(void)sprintf(buf, "%s %s", $1.text, $2.text);
new_decl_spec(&$$, buf, $1.begin, DS_NONE);
}
;
struct_or_union
: T_STRUCT
{
imply_typedef($$.text);
}
| T_UNION
{
imply_typedef($$.text);
}
;
init_declarator_list
: init_declarator
{
new_decl_list(&$$, $1);
}
| init_declarator_list ',' init_declarator
{
add_decl_list(&$$, &$1, $3);
}
;
init_declarator
: declarator
{
if ($1->func_def != FUNC_NONE && func_params == NULL &&
func_style == FUNC_TRADITIONAL && cur_file->convert) {
gen_func_declarator($1);
fputs(cur_text(), cur_file->tmp_file);
}
cur_declarator = $$;
}
| declarator '='
{
if ($1->func_def != FUNC_NONE && func_params == NULL &&
func_style == FUNC_TRADITIONAL && cur_file->convert) {
gen_func_declarator($1);
fputs(" =", cur_file->tmp_file);
}
}
T_INITIALIZER
;
enum_specifier
: enumeration any_id braces
{
char *s;
if ((s = implied_typedef()) == 0)
(void)sprintf(s = buf, "enum %s", $2.text);
new_decl_spec(&$$, s, $1.begin, DS_NONE);
}
| enumeration braces
{
char *s;
if ((s = implied_typedef()) == 0)
(void)sprintf(s = buf, "%s {}", $1.text);
new_decl_spec(&$$, s, $1.begin, DS_NONE);
}
| enumeration any_id
{
(void)sprintf(buf, "enum %s", $2.text);
new_decl_spec(&$$, buf, $1.begin, DS_NONE);
}
;
enumeration
: T_ENUM
{
imply_typedef("enum");
$$ = $1;
}
;
any_id
: T_IDENTIFIER
| T_TYPEDEF_NAME
;
declarator
: pointer direct_declarator
{
$$ = $2;
(void)sprintf(buf, "%s%s", $1.text, $$->text);
free($$->text);
$$->text = xstrdup(buf);
$$->begin = $1.begin;
$$->pointer = TRUE;
}
| direct_declarator
;
direct_declarator
: identifier_or_ref
{
$$ = new_declarator($1.text, $1.text, $1.begin);
}
| '(' declarator ')'
{
$$ = $2;
(void)sprintf(buf, "(%s)", $$->text);
free($$->text);
$$->text = xstrdup(buf);
$$->begin = $1.begin;
}
| direct_declarator T_BRACKETS
{
$$ = $1;
(void)sprintf(buf, "%s%s", $$->text, $2.text);
free($$->text);
$$->text = xstrdup(buf);
}
| direct_declarator '(' parameter_type_list ')'
{
$$ = new_declarator("%s()", $1->name, $1->begin);
$$->params = $3;
$$->func_stack = $1;
$$->head = ($1->func_stack == NULL) ? $$ : $1->head;
$$->func_def = FUNC_ANSI;
}
| direct_declarator '(' opt_identifier_list ')'
{
$$ = new_declarator("%s()", $1->name, $1->begin);
$$->params = $3;
$$->func_stack = $1;
$$->head = ($1->func_stack == NULL) ? $$ : $1->head;
$$->func_def = FUNC_TRADITIONAL;
}
;
pointer
: '*' opt_type_qualifiers
{
(void)sprintf($$.text, "*%s", $2.text);
$$.begin = $1.begin;
}
| '*' opt_type_qualifiers pointer
{
(void)sprintf($$.text, "*%s%s", $2.text, $3.text);
$$.begin = $1.begin;
}
;
opt_type_qualifiers
: /* empty */
{
strcpy($$.text, "");
$$.begin = 0L;
}
| type_qualifier_list
;
type_qualifier_list
: type_qualifier
{
(void)sprintf($$.text, "%s ", $1.text);
$$.begin = $1.begin;
free($1.text);
}
| type_qualifier_list type_qualifier
{
(void)sprintf($$.text, "%s%s ", $1.text, $2.text);
$$.begin = $1.begin;
free($2.text);
}
;
parameter_type_list
: parameter_list
| parameter_list ',' T_ELLIPSIS
{
add_ident_list(&$$, &$1, "...");
}
;
parameter_list
: parameter_declaration
{
new_param_list(&$$, $1);
}
| parameter_list ',' parameter_declaration
{
add_param_list(&$$, &$1, $3);
}
;
parameter_declaration
: decl_specifiers declarator
{
check_untagged(&$1);
$$ = new_parameter(&$1, $2);
}
| decl_specifiers abs_declarator
{
check_untagged(&$1);
$$ = new_parameter(&$1, $2);
}
| decl_specifiers
{
check_untagged(&$1);
$$ = new_parameter(&$1, (Declarator *)0);
}
;
opt_identifier_list
: /* empty */
{
new_ident_list(&$$);
}
| identifier_list
;
identifier_list
: any_id
{
new_ident_list(&$$);
add_ident_list(&$$, &$$, $1.text);
}
| identifier_list ',' any_id
{
add_ident_list(&$$, &$1, $3.text);
}
;
identifier_or_ref
: any_id
{
$$ = $1;
}
| '&' any_id
{
#if OPT_LINTLIBRARY
if (lintLibrary()) { /* Lint doesn't grok C++ ref variables */
$$ = $2;
} else
#endif
(void)sprintf($$.text, "&%s", $2.text);
$$.begin = $1.begin;
}
;
abs_declarator
: pointer
{
$$ = new_declarator($1.text, "", $1.begin);
}
| pointer direct_abs_declarator
{
$$ = $2;
(void)sprintf(buf, "%s%s", $1.text, $$->text);
free($$->text);
$$->text = xstrdup(buf);
$$->begin = $1.begin;
}
| direct_abs_declarator
;
direct_abs_declarator
: '(' abs_declarator ')'
{
$$ = $2;
(void)sprintf(buf, "(%s)", $$->text);
free($$->text);
$$->text = xstrdup(buf);
$$->begin = $1.begin;
}
| direct_abs_declarator T_BRACKETS
{
$$ = $1;
(void)sprintf(buf, "%s%s", $$->text, $2.text);
free($$->text);
$$->text = xstrdup(buf);
}
| T_BRACKETS
{
$$ = new_declarator($1.text, "", $1.begin);
}
| direct_abs_declarator '(' parameter_type_list ')'
{
$$ = new_declarator("%s()", "", $1->begin);
$$->params = $3;
$$->func_stack = $1;
$$->head = ($1->func_stack == NULL) ? $$ : $1->head;
$$->func_def = FUNC_ANSI;
}
| direct_abs_declarator '(' ')'
{
$$ = new_declarator("%s()", "", $1->begin);
$$->func_stack = $1;
$$->head = ($1->func_stack == NULL) ? $$ : $1->head;
$$->func_def = FUNC_ANSI;
}
| '(' parameter_type_list ')'
{
Declarator *d;
d = new_declarator("", "", $1.begin);
$$ = new_declarator("%s()", "", $1.begin);
$$->params = $2;
$$->func_stack = d;
$$->head = $$;
$$->func_def = FUNC_ANSI;
}
| '(' ')'
{
Declarator *d;
d = new_declarator("", "", $1.begin);
$$ = new_declarator("%s()", "", $1.begin);
$$->func_stack = d;
$$->head = $$;
$$->func_def = FUNC_ANSI;
}
;
%%
#if defined(__EMX__) || defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(vms)
# ifdef USE_flex
# include "lexyy.c"
# else
# include "lex_yy.c"
# endif
#else
# include "lex.yy.c"
#endif
static void
yaccError (char *msg)
{
func_params = NULL;
put_error(); /* tell what line we're on, and what file */
fprintf(stderr, "%s at token '%s'\n", msg, yytext);
}
/* Initialize the table of type qualifier keywords recognized by the lexical
* analyzer.
*/
void
init_parser (void)
{
static char *keywords[] = {
"const",
"restrict",
"volatile",
"interrupt",
#ifdef vms
"noshare",
"readonly",
#endif
#if defined(MSDOS) || defined(OS2)
"__cdecl",
"__export",
"__far",
"__fastcall",
"__fortran",
"__huge",
"__inline",
"__interrupt",
"__loadds",
"__near",
"__pascal",
"__saveregs",
"__segment",
"__stdcall",
"__syscall",
"_cdecl",
"_cs",
"_ds",
"_es",
"_export",
"_far",
"_fastcall",
"_fortran",
"_huge",
"_interrupt",
"_loadds",
"_near",
"_pascal",
"_saveregs",
"_seg",
"_segment",
"_ss",
"cdecl",
"far",
"huge",
"near",
"pascal",
#ifdef OS2
"__far16",
#endif
#endif
#ifdef __GNUC__
/* gcc aliases */
"__builtin_va_arg",
"__builtin_va_list",
"__const",
"__const__",
"__inline",
"__inline__",
"__restrict",
"__restrict__",
"__volatile",
"__volatile__",
#endif
};
unsigned i;
/* Initialize type qualifier table. */
type_qualifiers = new_symbol_table();
for (i = 0; i < sizeof(keywords)/sizeof(keywords[0]); ++i) {
new_symbol(type_qualifiers, keywords[i], NULL, DS_NONE);
}
}
/* Process the C source file. Write function prototypes to the standard
* output. Convert function definitions and write the converted source
* code to a temporary file.
*/
void
process_file (FILE *infile, char *name)
{
char *s;
if (strlen(name) > 2) {
s = name + strlen(name) - 2;
if (*s == '.') {
++s;
if (*s == 'l' || *s == 'y')
BEGIN LEXYACC;
#if defined(MSDOS) || defined(OS2)
if (*s == 'L' || *s == 'Y')
BEGIN LEXYACC;
#endif
}
}
included_files = new_symbol_table();
typedef_names = new_symbol_table();
define_names = new_symbol_table();
inc_depth = -1;
curly = 0;
ly_count = 0;
func_params = NULL;
yyin = infile;
include_file(strcpy(base_file, name), func_style != FUNC_NONE);
if (file_comments) {
#if OPT_LINTLIBRARY
if (lintLibrary()) {
put_blankline(stdout);
begin_tracking();
}
#endif
put_string(stdout, "/* ");
put_string(stdout, cur_file_name());
put_string(stdout, " */\n");
}
yyparse();
free_symbol_table(define_names);
free_symbol_table(typedef_names);
free_symbol_table(included_files);
}
#ifdef NO_LEAKS
void
free_parser(void)
{
free_symbol_table (type_qualifiers);
#ifdef FLEX_SCANNER
if (yy_current_buffer != 0)
yy_delete_buffer(yy_current_buffer);
#endif
}
#endif

35
test/run_test.sh Executable file
View File

@ -0,0 +1,35 @@
#!/bin/sh
# $Id: run_test.sh,v 1.1 2004/03/28 19:30:50 tom Exp $
#
echo '** '`date`
for i in *.y
do
case $i in
test*)
echo "?? ignored $i"
;;
*)
root=`basename $i .y`
ROOT="test-$root"
../yacc -v -d -b $ROOT $i
for type in .output .tab.c .tab.h
do
REF=${root}${type}
CMP=${ROOT}${type}
if test ! -f $CMP ; then
echo "...not found $CMP"
continue
fi
sed -s s/$CMP/$REF/ $CMP >temp$$ \
&& mv temp$$ $CMP
if ( cmp -s $REF $CMP )
then
echo "...ok $REF"
rm -f $CMP
else
echo "...diff $REF"
fi
done
;;
esac
done

70
yacc.1
View File

@ -1,109 +1,91 @@
.\" %W% %R% (Berkeley) %E%
.\" $Id: yacc.1,v 1.3 2004/03/28 20:02:43 tom Exp $
.\"
.TH YACC 1 "July\ 15,\ 1990"
.UC 6
.SH NAME
Yacc \- an LALR(1) parser generator
.SH SYNOPSIS
.B yacc [ -dlrtv ] [ -b
.B yacc [ -dlrtv ] [ \-b
.I file_prefix
.B ] [ -p
.B ] [ \-p
.I symbol_prefix
.B ]
.I filename
.SH DESCRIPTION
.I Yacc
.B Yacc
reads the grammar specification in the file
.I filename
and generates an LR(1) parser for it.
The parsers consist of a set of LALR(1) parsing tables and a driver routine
written in the C programming language.
.I Yacc
.B Yacc
normally writes the parse tables and the driver routine to the file
.IR y.tab.c.
.PP
The following options are available:
.RS
.TP
\fB-b \fIfile_prefix\fR
\fB\-b \fP\fIfile_prefix\fR
The
.B -b
.B \-b
option changes the prefix prepended to the output file names to
the string denoted by
.IR file_prefix.
The default prefix is the character
.IR y.
.TP
.B -d
.B \-d
The \fB-d\fR option causes the header file
.IR y.tab.h
to be written.
.TP
.B -l
.B \-l
If the
.B -l
.B \-l
option is not specified,
.I yacc
will insert \#line directives in the generated code.
The \#line directives let the C compiler relate errors in the
.B yacc
will insert \fI#line\fP directives in the generated code.
The \fI#line\fP directives let the C compiler relate errors in the
generated code to the user's original code.
If the \fB-l\fR option is specified,
.I yacc
will not insert the \#line directives.
\&\#line directives specified by the user will be retained.
.B yacc
will not insert the \fI#line\fP directives.
\&\fI#line\fP directives specified by the user will be retained.
.TP
\fB-p \fIsymbol_prefix\fR
\fB\-p \fP\fIsymbol_prefix\fR
The
.B -p
.B \-p
option changes the prefix prepended to yacc-generated symbols to
the string denoted by
.IR symbol_prefix.
The default prefix is the string
.IR yy.
.TP
.B -r
.B \-r
The
.B -r
.B \-r
option causes
.I yacc
.B yacc
to produce separate files for code and tables. The code file
is named
.IR y.code.c,
and the tables file is named
.IR y.tab.c.
.TP
.B -t
.B \-t
The
.B -t
.B \-t
option changes the preprocessor directives generated by
.I yacc
.B yacc
so that debugging statements will be incorporated in the compiled code.
.TP
.B -v
.B \-v
The
.B -v
.B \-v
option causes a human-readable description of the generated parser to
be written to the file
.IR y.output.
.RE
.PP
If the environment variable TMPDIR is set, the string denoted by
TMPDIR will be used as the name of the directory where the temporary
files are created.
.SH FILES
.IR y.code.c
.br
.IR y.tab.c
.br
.IR y.tab.h
.br
.IR y.output
.br
.IR /tmp/yacc.aXXXXXX
.br
.IR /tmp/yacc.tXXXXXX
.br
.IR /tmp/yacc.uXXXXXX
.SH DIAGNOSTICS
If there are rules that are never reduced, the number of such rules is
reported on standard error.