[comp.compilers] Collecting look ahead set

craig@comp.lancs.ac.uk (Craig) (02/22/89)

The following two programs are usefull in the production of yacc based
grammars.  The first will collect a follow set of acceptable tokens into
an array (yylkahead) which should be declared extern where ever you intend
to use it.  At the moment the set is only collected when ever the grammar
reduces the 'error' token.  This can then be used for debugging the grammar,
use in error messages etc.  There is no manual page, it is however well
commented.
 
The second program will take the contents of the y.tab.h file produced by yacc
and produce a C function that will print the token name, given the number.
This is useful when used in conjunction with the first program as you can print
the names of the tokens found in the follow set.
 
Craig.
 
----------------- cut here ----------------- cut here -----------------------
#!/bin/sh
#
#    A program to add code to y.tab.c that will collect an array
#    of tokens that the compiler would have accepted, it is only
#    compiled on an error token being read
#
#    It is accesible to yacc programmers via the extern int variables
#
#    extern int yylkahead[YYLOOKAHEAD],
#           yylkind;
#
#    yylkahead contains the look ahead symbols, yylkind is the number
#    of entries in yylkahead
#
#    If you find that yylkahead is not large enough then by setting
#    YYLOOKAHEAD to a suitable value the size of the array can be
#    altered, by default it is set to 50.
#
#    Craig W. Wylie        June 12th 1987
#    University of Lancaster
#    Lancaster
#    U.K.
#    craig@uk.ac.lancs.comp
#
#    All rights reserved, this software can be reproduced freely so long
#    as the authors name and this text is included in the distribution
#
ex $1 << \YED_EOF 2> /dev/null 1>/dev/null
/^YYSTYPE/
a
# ifndef YYLOOKAHEAD
# define YYLOOKAHEAD    50
# endif
int    yylkahead[YYLOOKAHEAD],        /* Used to collect the look ahead set */
    yylkind;            /* Number of tokens in look ahead set */
..
/        switch( /
+2
a
            /*
                the following code which collects the
                look ahead set is largely derived from
                " Introduction to Compiler Construction
                  with Unix" Prentice Hall
                by Axel T. Schreiner and
                H. George Friedman, Jr.
            */
            if ((yyn = yypact[yystate]) > YYFLAG && yyn < YYLAST)
            {    register int x;
 
                yylkind = 0;
                for (x = yyn>0? yyn : 0; x < YYLAST; ++x)
                    if (yychk[yyact[x]] == x - yyn
                       && x - yyn != YYERRCODE)
                        yylkahead[yylkind++] = x - yyn;
            }
..
wq
YED_EOF
 
------------------------------------------
#!/bin/sh
#
#    dtok
#
#    dtok creates a c function  --  by default called disp_token
#    that when called returns a string representation of the token
#    number passed to it. ie if INT is defined as 300 then
#    disp_token (INT)
#    will return the string (" INT ")
#
#    The representations are retrieved from a file in y.tab.h format,
#    the name of this file is the first argument to dtok.
#
#    Arguments
#    ---------
#        -f source file
#        -c name for display function
#
#    the only necessary argument is the -f argument
#    and if this is not present then default input is
#    from y.tab.h
#
#    Zero arguments selects the defaults of y.tab.h for input and
#    disp_token for output.
#
#    Craig W. Wylie        June 12th 1987
#
usage=`basename $0`": [-f input file name] [-c function name] "
prog=`basename $0`
inpf="y.tab.h"
cfunc="disp_token"
version=2
release=1
if test $USER
then
    me=$USER
else
    me="Don't know"
fi
 
while test $# -ne 0
do
    case $1 in
        "-f")    inpf=$2
            shift;;
        "-c")    cfunc=$2
            shift;;
        *   )    echo $1 "Bad argument"
            echo $usage
            exit;;
    esac
    shift
done
 
if test -r $inpf
then
    ok=1
else
    echo $prog" : Input file "$inpf" not found"
    exit
fi
echo "/*"
echo
echo "    Built by :    "$me
echo "    On     :    "`date`
echo
echo "  Yacc tool kit  -- "`basename $0` $version"."$release
echo "*/"
echo
echo
echo "char    *"$cfunc"(token)"
echo "int    token;"
echo "{"
echo
echo "    switch (token){"
awk '
    /^# define/    {
            print "        case",$4,":"
            print "            return (\""$3"\");"
            print "            break;"
        }
 
    END    {
            print "        default :"
            print "            return (\"Unknown token\");"
            print "    }"
            print "}"
        }' $inpf
[From Craig <craig@comp.lancs.ac.uk>]
--
Send compilers articles to ima!compilers or, in a pinch, to Levine@YALE.EDU
Plausible paths are { decvax | harvard | yale | bbn}!ima
Please send responses to the originator of the message -- I cannot forward
mail accidentally sent back to compilers.  Meta-mail to ima!compilers-request

djones@decwrl.dec.com (Dave Jones) (03/11/89)

> In article <3436@ima.ima.isc.com>, eachus@mbunix (Eachus) writes:
>>     Of course, going to all this effort for yacc is probably not
>>worth it unless a lot of other bugs are fixed.

The only bad bug I know of is the default-reduction-on-error-bug,
which we fixed here in comp.compilers a few months ago.

Since fixing that, I have had no problems with yacc.

Do you know something I don't know?
[From megatest!djones@decwrl.dec.com (Dave Jones)]
--
Send compilers articles to ima!compilers or, in a pinch, to Levine@YALE.EDU
Plausible paths are { decvax | harvard | yale | bbn}!ima
Please send responses to the originator of the message -- I cannot forward
mail accidentally sent back to compilers.  Meta-mail to ima!compilers-request