home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!mcnc!uvaarpa!umd5!ames!necntc!ncoast!allbery
- From: richardh@killer.UUCP (Richard Hargrove)
- Newsgroups: comp.sources.misc
- Subject: v03i063: hexcalc 1.1
- Keywords: hex calculator utility
- Message-ID: <4622@killer.UUCP>
- Date: 28 Jun 88 01:35:22 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: richardh@killer.UUCP (Richard Hargrove)
- Organization: The Unix(R) Connection, Dallas, Texas
- Lines: 1875
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 3, Issue 63
- Submitted-By: "Richard Hargrove" <richardh@killer.UUCP>
- Archive-Name: hexcalc1.1
-
- Brandon,
-
- Just what the net needs. Another calculator program! This one is modeled
- the TI Programmer II (decimal radix is still integer, though). I won't
- repeat the readme file here. I've tested the makefiles under MS-DOS,
- Microport Unix SYS V/AT, ATT SYS V, R3 (on a 3b2), SCO Xenix SYS V, and
- Intel Xenix 3.5 (SYS III based). All make without a hitch.
-
- If you think it is a reasonable contribution, post away.
-
- thanks,
- richard hargrove
-
- -------- cut here -------- cut here -------- cut here -------- cut here --------
- #!/bin/sh
- # shar: Shell Archiver (v1.22)
- #
- # Run the following text with /bin/sh to create:
- # 1st_read.me
- # bltins.c
- # hctest01.txt
- # hctest02.txt
- # hexcalc.h
- # hexcalc.man
- # hexcalc.y
- # init.c
- # makefile.dos
- # makefile.unx
- # symbol.c
- # ulpow.c
- # ytab.c
- # ytab.h
- # yylex.c
- #
- sed 's/^X//' << 'SHAR_EOF' > 1st_read.me &&
- X ----------------
- X Here is a yacc toy, a hexadecimal calculator program. It's based on
- X hoc3 for those familiar with chapter 8 in _The Unix Programming
- X Environment_ by Kernighan and Pike. To use it, run it and type help.
- X Or better yet, read the included man pages.
- X
- X This package is being distributed in both .ARC archive and shell
- X archive (shar) form and is made up of the following files:
- X
- X 1st_read.me this file
- X
- X hexcalc.exe executable (.ARC only)
- X
- X hexcalc.h c source code
- X ytab.h
- X bltins.c
- X symbol.c
- X ulpow.c
- X yylex.c
- X init.c
- X ytab.c
- X
- X hexcalc.y yacc source code
- X
- X makefile.dos miscellaneous files
- X makefile.unx
- X hexcalc.man
- X hctest01.txt
- X hctest02.txt
- X
- X Included are two simple test "programs" that when fed to hexcalc via
- X stdin exercise expression evaluation and commands. See the test
- X dependency in the Unix makefile.
- X
- X I have included the yacc generated source and header files for those
- X who are developing in a non-Unix environment and don't have
- X immediate access to yacc(1). For the MS-DOS environment, I use the
- X version of yacc distributed with the MKS Toolkit. That was the
- X version used to generate the yacc output files.
- X
- X The MS-DOS makefile requires the presence of the MKS Toolkit and
- X Turbo C to be useable. The mv, rm, and tcc command invocations can
- X be modified as appropriate, but it still requires yacc to generate
- X new ytab.h and ytab.c files. However, the use of make is not required
- X to generate the executable. The tcc invocation line
- X
- X tcc -ehexcalc.exe ytab.c init.c symbol.c bltins.c yylex.c ulpow.c
- X
- X should do it.
- X
- X Needless to say, Unix is a trademark of AT&T, MKS Toolkit is a
- X trademark of Mortice Kern Systems, Turbo C is a trademark of
- X Borland International, and MS-DOS is a trademark of Microsoft.
- X
- X Richard Hargrove, 25 June 1988
- X ...!{ihnp4 | codas | cbosgd}!killer!richardh
- X --------------------------------------------
- SHAR_EOF
- chmod 0666 1st_read.me || echo "restore of 1st_read.me fails"
- sed 's/^X//' << 'SHAR_EOF' > bltins.c &&
- X
- X/* bltins.c hexcalc built-in functions
- X */
- X
- X#include "hexcalc.h"
- X
- X/******************************************************************************/
- XBASE_TYPE dec(val)
- XBASE_TYPE val;
- X{
- X printf("\t%lu\n", val);
- X return val;
- X}
- X
- X/******************************************************************************/
- X
- XBASE_TYPE oct(val)
- XBASE_TYPE val;
- X{
- X printf("\t%lo\n", val);
- X return val;
- X}
- X
- X/******************************************************************************/
- X
- XBASE_TYPE hex(val)
- XBASE_TYPE val;
- X{
- X printf("\t%lx\n", val);
- X return val;
- X}
- SHAR_EOF
- chmod 0666 bltins.c || echo "restore of bltins.c fails"
- sed 's/^X//' << 'SHAR_EOF' > hctest01.txt &&
- X# simple expression evaluation test
- X
- X## numeric literals (12345678 fedcba98)
- X12345678
- X0fedcba98
- X
- X## assignment: assigning values to a and b (no output)
- Xa=0deaddead
- Xb=2bad2bad
- X
- X## a (deaddead)
- Xa
- X## b (2bad2bad)
- Xb
- X
- X## a << 3 (f56ef568)
- Xa << 3
- X## a >> 4 (deaddea); note unsigned shift
- Xa >> 4
- X
- X## a | b (ffadffad)
- Xa | b
- X
- X## a ^ b (f500f500)
- Xa ^ b
- X
- X## a & b (aad0aad)
- Xa & b
- X
- X## reassigning values to a and b
- Xa = 0dead
- Xb = 2bad
- X## a + b (10a5a)
- Xa + b
- X
- X## a - b (b300)
- Xa - b
- X
- X## b - a (ffff4d00)
- Xb - a
- X
- X## a * b (25fd89e9)
- Xa * b
- X
- X## a / b (5)
- Xa / b
- X
- X## a % b (44c)
- Xa % b
- X
- X## b ** 2 (77392e9)
- Xb ** 2
- X
- X## a + b * 345 (8fab4e)
- Xa + b * 345
- X
- X## (a + b) * 345 (366d842)
- X(a + b) * 345
- X
- X## quitting
- Xexit
- SHAR_EOF
- chmod 0666 hctest01.txt || echo "restore of hctest01.txt fails"
- sed 's/^X//' << 'SHAR_EOF' > hctest02.txt &&
- X# hexcalc test script - test the commands, built-in functions, and both
- X# silent and echoing comments
- X
- Xhelp ## help
- XHELP ## HELP
- Xa=1000 # init a
- Xb=8888 # init b
- Xa+b ## hex default: a + b (9888)
- XOCT(DEC(a+b)) ## 39048 114210 9888
- Xdec
- Xa+b ## dec default: a + b (39048)
- XOCT(HEX(a+b)) ## 9888 114210 39048
- Xoct
- Xa+b ## oct default: a + b (114210)
- XDEC(HEX(a+b)) ## 9888 39048 114210
- Xquit ## quitting
- SHAR_EOF
- chmod 0666 hctest02.txt || echo "restore of hctest02.txt fails"
- sed 's/^X//' << 'SHAR_EOF' > hexcalc.h &&
- X
- X/* hexcalc.h include file supporting the calculator utility hexcalc
- X */
- X
- X#ifdef DEBUG
- X#define STATIC
- X#else
- X#define STATIC static
- X#endif
- X
- Xtypedef unsigned long BASE_TYPE;
- X
- XBASE_TYPE dec(), oct(), hex();
- XBASE_TYPE ulpow();
- X
- Xtypedef struct Symbol /* symbol table entry */
- X{
- X char *name;
- X short type; /* VAR, BLTIN, UNDEF */
- X union
- X {
- X BASE_TYPE val; /* if VAR */
- X BASE_TYPE (*ptr)(); /* if BLTIN */
- X } u;
- X struct Symbol *next; /* to link to another */
- X} Symbol;
- X
- XSymbol *install(), *lookup();
- SHAR_EOF
- chmod 0666 hexcalc.h || echo "restore of hexcalc.h fails"
- sed 's/^X//' << 'SHAR_EOF' > hexcalc.man &&
- X
- X
- X
- X HEXCALC(1) HEXCALC(1)
- X
- X
- X
- X NAME
- X hexcalc - interactive hexadecimal calculator
- X
- X SYNOPSIS
- X hexcalc
- X
- X DESCRIPTION
- X Hexcalc reads standard input for a sequence of expressions and
- X commands. Expressions are evaluated and the result is output in
- X the default radix on standard output. Commands are executed,
- X producing their defined action.
- X
- X Expressions are made up of the following operands and operators:
- X
- X Operands: Numeric literals; in the default radix, must begin
- X with a digit (for example, 0cc01e).
- X
- X Variables; initialized with an assignment operation,
- X 31 significant chars max.
- X
- X Built-in functions:
- X name description
- X --------- -----------
- X DEC(expr) output decimal value of expr
- X OCT(expr) output octal value of expr
- X HEX(expr) output hex value of expr
- X
- X Operators (highest to lowest precedence):
- X operator description
- X -------- -----------
- X ( ) grouping
- X ** exponentiation
- X - ~ unary minus, bitwise not
- X * / % multiplication, division, modulus
- X + - addition, subtraction
- X << >> left-shift, right-shift
- X & bitwise and
- X ^ bitwise exclusive-or
- X | bitwise or
- X = assignment
- X
- X The following commands are supported:
- X name description
- X ---------- -----------
- X help HELP print a help message
- X quit exit terminate execution
- X hex dec oct set the default radix
- X
- X If assignment is the last operation performed when evaluating an
- X expression, nothing is output.
- X
- X
- X
- X
- X
- X [ 1 ]
- X
- X
- X HEXCALC(1) HEXCALC(1)
- X
- X
- X
- X Hexcalc also recognizes and ignores comments. Comments begin with
- X either a '#' character or a '##' character pair and are terminated
- X by a newline. Comments beginning with a single '#' are called non-
- X echoing and are completely ignored. Comments beginning with a '##'
- X pair are called echoing comments and are output to stdout, beginning
- X with the second '#', without modification. While comments make
- X little sense when using hexcalc interactively, they can be used in
- X files that are fed to stdin to good effect.
- X
- X The _rationale_ behind the current built-in functions is to allow
- X the capture of intermediate results in the output stream as well as
- X modifying the default radix for the results of expression
- X evaluation. Note that they are functions which return the input
- X value as a result so they can be used as operands in more complex
- X expressions.
- X
- X The initial default radix is hexadecimal.
- X
- X NOTES
- X Hexcalc is based on hoc3, a calculator program that can be found in
- X _The Unix Programming Environment_ by Brian W. Kernighan and Rob
- X Pike, chapter 8. The entire chapter is an exposition of a method of
- X organizing a software development project which develops six
- X different, and successively more complex, versions of hoc, a
- X calculator program. It also serves as an excellent introduction to
- X and tutorial for yacc(1).
- X
- X AUTHOR
- X Richard Hargrove
- X 25 June 1988
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X [ 2 ]
- SHAR_EOF
- chmod 0666 hexcalc.man || echo "restore of hexcalc.man fails"
- sed 's/^X//' << 'SHAR_EOF' > hexcalc.y &&
- X%{
- X#include "hexcalc.h"
- X%}
- X
- X%union /* stack type */
- X{
- X BASE_TYPE val; /* actual value */
- X Symbol *sym; /* symbol table pointer */
- X}
- X
- X%token <val> NUMBER
- X%token <sym> CONST VAR BLTIN UNDEF QUIT HELP CHRADIX
- X%type <val> expr asgn
- X%right '='
- X%left '|'
- X%left '^'
- X%left '&'
- X%left LSH RSH
- X%left '+' '-'
- X%left '*' '/' '%'
- X%left UNARYMINUS '~'
- X%right POW /* exponentiation */
- X
- X%%
- Xlist: /* nothing */
- X | list '\n'
- X | list asgn '\n'
- X | list expr '\n' {
- X if (radix == 16)
- X printf ("\t%lx\n", $2);
- X else if (radix == 10)
- X printf ("\t%lu\n", $2);
- X else
- X printf ("\t%lo\n", $2);
- X }
- X | list HELP '\n' { puthelp(); }
- X | list QUIT '\n' { longjmp (prog_end, 1); }
- X | list CHRADIX '\n' {
- X if (*($2->name) == 'h')
- X radix = 16;
- X else if (*($2->name) == 'd')
- X radix = 10;
- X else
- X radix = 8;
- X }
- X | list error '\n' { yyerrok; }
- X ;
- Xasgn: VAR '=' expr { $$ = $1->u.val = $3; $1->type = VAR; }
- X ;
- Xexpr: NUMBER { $$ = $1; }
- X | CONST { $$ = $1->u.val; }
- X | VAR {
- X if ($1->type == UNDEF)
- X execerror ("undefined variable", $1->name);
- X $$ = $1->u.val; }
- X | asgn
- X | BLTIN '(' expr ')' { $$ = (*($1->u.ptr))($3); }
- X | expr LSH expr { $$ = $1 << $3; }
- X | expr RSH expr { $$ = $1 >> $3; }
- X | expr '|' expr { $$ = $1 | $3; }
- X | expr '^' expr { $$ = $1 ^ $3; }
- X | expr '&' expr { $$ = $1 & $3; }
- X | expr '+' expr { $$ = $1 + $3; }
- X | expr '-' expr { $$ = $1 - $3; }
- X | expr '*' expr { $$ = $1 * $3; }
- X | expr '/' expr {
- X if ($3 == 0)
- X execerror ("division by zero", (char *)0);
- X $$ = $1 / $3; }
- X | expr '%' expr {
- X if ($3 == 0)
- X execerror ("modulo zero", (char *)0);
- X $$ = $1 % $3; }
- X | expr POW expr { $$ = ulpow ($1, $3); }
- X | '(' expr ')' { $$ = $2; }
- X | '-' expr %prec UNARYMINUS { $$ = -$2; }
- X | '~' expr { $$ = ~ $2; }
- X ;
- X%%
- X
- X#include <stdio.h>
- X#include <setjmp.h>
- X
- Xchar *progname; /* for error messages */
- Xint lineno = 1;
- Xint radix = 16;
- X
- XSTATIC char *credit =
- X"hexcalc 1.1 by Richard Hargrove, 25 June 1988; based on hoc3 from Kernighan and Pike";
- X
- Xjmp_buf prog_begin, prog_end;
- X
- X/******************************************************************************/
- X
- Xvoid puthelp()
- X{
- X static char *help_text[] = {
- X "Type in an expression or command. Expressions other than assignment",
- X "cause the evaluated result to be output. All values are 32-bit integers.",
- X "Expressions are made up of the following operands and operators:",
- X "",
- X "Operands: numeric literals (must begin with a digit), variables",
- X "(31 chars max, initialized with assignment), and built-in functions.",
- X "Built-ins: DEC(expr) output decimal value of expr",
- X " OCT(expr) output octal value of expr",
- X " HEX(expr) output hex value of expr",
- X "Operators: ( ) grouping",
- X " ** exponentiation",
- X " - ~ unary minus, bitwise not",
- X " * / % multiplication, division, modulus",
- X " + - addition, subtraction",
- X " << >> left-shift, right-shift",
- X " & bitwise and",
- X " ^ bitwise exclusive-or",
- X " | bitwise or",
- X " = assignment",
- X "",
- X "Commands: help HELP print this message",
- X " quit exit terminate execution",
- X " hex dec oct set the default radix",
- X (char *)0
- X };
- X int i = 0;
- X
- X while (help_text[i] != (char *)0)
- X {
- X puts(help_text[i++]);
- X }
- X}
- X
- X/******************************************************************************/
- X
- Xvoid warning (s, t) /* print warning message */
- Xchar *s, *t;
- X{
- X fprintf (stderr, "%s : %s", progname, s);
- X if (t != (char *)0)
- X {
- X fprintf (stderr, " %s", t);
- X }
- X fprintf (stderr, " near line %d\n", lineno);
- X}
- X
- X
- X/******************************************************************************/
- X
- Xvoid yyerror (s) /* called for yacc syntax error */
- Xchar *s;
- X{
- X warning (s, (char *)0);
- X}
- X
- X/******************************************************************************/
- X
- Xvoid execerror (s, t)
- Xchar *s, *t;
- X{
- X warning (s, t);
- X longjmp (prog_begin, 1);
- X}
- X
- X/******************************************************************************/
- X
- Xmain (argc, argv)
- Xint argc;
- Xchar *argv [];
- X{
- X progname = argv [0];
- X init ();
- X if (setjmp (prog_end) == 0)
- X {
- X (void)setjmp (prog_begin);
- X yyparse ();
- X }
- X return 0;
- X}
- SHAR_EOF
- chmod 0666 hexcalc.y || echo "restore of hexcalc.y fails"
- sed 's/^X//' << 'SHAR_EOF' > init.c &&
- X
- X/* init.c hexcalc initilization code
- X */
- X
- X#include "hexcalc.h"
- X#ifdef __TURBOC__
- X#include "ytab.h"
- X#else
- X#include "y.tab.h"
- X#endif
- X
- XSTATIC struct /* constants */
- X{
- X char *name;
- X BASE_TYPE cval;
- X} consts[] =
- X {
- X (char *)0, (BASE_TYPE)0
- X };
- X
- XSTATIC struct /* built-ins */
- X{
- X char *name;
- X BASE_TYPE (*func)();
- X} builtins[] =
- X {
- X "DEC", dec,
- X "OCT", oct,
- X "HEX", hex,
- X (char *)0, (BASE_TYPE(*)())0
- X };
- X
- XSTATIC struct /* keywords */
- X{
- X char *name;
- X short token;
- X} keywords[] =
- X {
- X "oct", CHRADIX,
- X "HELP", HELP,
- X "exit", QUIT,
- X "help", HELP,
- X "quit", QUIT,
- X "dec", CHRADIX,
- X "hex", CHRADIX,
- X (char *)0, 0
- X };
- X
- X/******************************************************************************/
- X
- Xinit() /* install keywords, constants, and built-ins in table */
- X{
- X int i;
- X Symbol *s;
- X
- X for (i=0; keywords [i].name != (char *)0; ++i)
- X {
- X install (keywords [i].name, keywords [i].token, (BASE_TYPE)0);
- X }
- X for (i=0; consts [i].name != (char *)0; ++i)
- X {
- X install (consts [i].name, CONST, consts [i].cval);
- X }
- X for (i=0; builtins [i].name != (char *)0; ++i)
- X {
- X s = install (builtins [i].name, BLTIN, (BASE_TYPE)0);
- X s->u.ptr = builtins [i].func;
- X }
- X}
- SHAR_EOF
- chmod 0666 init.c || echo "restore of init.c fails"
- sed 's/^X//' << 'SHAR_EOF' > makefile.dos &&
- X
- X# makefile for hexcalc - works with MKS Toolkit yacc, Turbo C, and Turbo Make.
- X# Will work with other Unix make-like MAKEs (such as NDMAKE).
- X
- X# macros
- X
- XOBJS=hexcalc.obj init.obj bltins.obj ulpow.obj symbol.obj yylex.obj
- XYACC=yacc
- XYFLAGS=-d
- XCC=tcc
- XCFLAGS=
- X
- X# implicit rules (Turbo Make doesn't have ANY predefined implicit rules)
- X
- X.c.obj :
- X $(CC) -c $<
- X
- X# MKS yacc generates inline assembler for small model Turbo C !
- X
- X.y.obj :
- X $(YACC) $(YFLAGS) $<
- X $(CC) $(CFLAGS) -B -c ytab.c
- X mv ytab.obj $&.obj
- X
- X# dependencies
- X
- Xhexcalc.exe : $(OBJS)
- X $(CC) $(CFLAGS) -ehexcalc.exe $(OBJS)
- X
- Xinit.obj : hexcalc.h ytab.h
- X
- Xyylex.obj : hexcalc.h ytab.h
- X
- Xytab.h : hexcalc.y
- X
- Xsymbol.obj : hexcalc.h
- X
- Xbltins.obj : hexcalc.h
- X
- Xulpow.obj : hexcalc.h
- X
- Xhexcalc.obj : hexcalc.h
- X
- Xclean :
- X rm -f $(OBJS) *.map ytab.[ch]
- SHAR_EOF
- chmod 0666 makefile.dos || echo "restore of makefile.dos fails"
- sed 's/^X//' << 'SHAR_EOF' > makefile.unx &&
- X
- X# Unix makefile for hexcalc
- X
- X# macros
- X
- XOBJS=hexcalc.o init.o bltins.o ulpow.o symbol.o yylex.o
- XCFLAGS=-O
- XYFLAGS=-d
- X
- X# browser utility used to verify test results
- X# more(1) or pg(1) are alternatives
- XBROWSER=less
- X
- X# implicit rules
- X
- X.y.o: # modify default to keep y.tab.c lying around
- X $(YACC) $(YFLAGS) $<
- X $(CC) $(CFLAGS) -c y.tab.c
- X mv y.tab.o $@
- X
- X# dependencies
- X
- Xhexcalc : $(OBJS)
- X $(CC) $(CFLAGS) -o hexcalc $(OBJS)
- X
- Xinit.o : hexcalc.h y.tab.h
- X
- Xyylex.o : hexcalc.h y.tab.h
- X
- Xy.tab.h : hexcalc.y
- X
- Xsymbol.o : hexcalc.h
- X
- Xbltins.o : hexcalc.h
- X
- Xulpow.o : hexcalc.h
- X
- Xhexcalc.o : hexcalc.h
- X
- Xtest :
- X hexcalc <hctest01.txt | $(BROWSER)
- X hexcalc <hctest02.txt | $(BROWSER)
- X
- Xlint :
- X lint y.tab.c init.c bltins.c ulpow.c symbol.c yylex.c
- X
- Xclean :
- X rm -f $(OBJS) y.tab.[ch]
- SHAR_EOF
- chmod 0666 makefile.unx || echo "restore of makefile.unx fails"
- sed 's/^X//' << 'SHAR_EOF' > symbol.c &&
- X
- X/* symbol.c hexcalc symbol table management routines
- X */
- X
- X#include <string.h>
- X#include "hexcalc.h"
- X
- X/* head ptr for the symbol table linked list */
- XSTATIC Symbol *symlist = (Symbol *)0;
- X
- X/******************************************************************************/
- X
- XSymbol *lookup (s)
- Xchar *s;
- X{
- X Symbol *sp;
- X
- X for (sp = symlist; sp != (Symbol *)0; sp = sp->next)
- X {
- X if (strcmp (sp->name, s) == 0) return sp;
- X }
- X return (Symbol *)0;
- X}
- X
- X/******************************************************************************/
- X
- Xchar *emalloc (n)
- Xunsigned n;
- X{
- X void *p, *malloc();
- X
- X if ((p = malloc (n)) == (void *)0)
- X {
- X execerror ("out of memory", (char *)0);
- X }
- X return (char *)p;
- X}
- X
- X/******************************************************************************/
- X
- XSymbol *install (s, t, l) /* install s in symbol table */
- Xchar *s;
- Xint t;
- XBASE_TYPE l;
- X{
- X Symbol *sp = (Symbol *)emalloc (sizeof(Symbol));
- X
- X sp->name = (char *)emalloc (strlen (s) + 1); /* + 1 for '\0' */
- X strcpy (sp->name, s);
- X sp->type = t;
- X sp->u.val = l;
- X sp->next = symlist;
- X symlist = sp;
- X return sp;
- X}
- SHAR_EOF
- chmod 0666 symbol.c || echo "restore of symbol.c fails"
- sed 's/^X//' << 'SHAR_EOF' > ulpow.c &&
- X
- X/* ulpow -- BASE_TYPE exponentiation (no overflow detection)
- X *
- X * Based on lpow() code distributed by Doug Gwyn
- X */
- X
- X#include "hexcalc.h" /* contains BASE_TYPE typedef */
- X
- XBASE_TYPE ulpow(base, exponent) /* returns base^exponent */
- XBASE_TYPE base;
- XBASE_TYPE exponent;
- X{
- X BASE_TYPE result; /* result accumulator */
- X
- X /* handle simple special cases separately: */
- X if (exponent == 0)
- X {
- X return 1; /* includes 0^0 */
- X }
- X else if (base == 0)
- X {
- X return 0; /* exp. < 0 should be EDOM */
- X }
- X else if (base == 1)
- X {
- X return 1;
- X }
- X else if (base == -1)
- X {
- X#if 0 /* intended code: */
- X return exponent % 2 == 0 ? 1 : -1;
- X#else /* faster equivalent (suggested by Dan Levy of Teletype): */
- X return (exponent & 1) == 0 ? 1 : -1;
- X#endif
- X }
- X else if (exponent < 0)
- X {
- X return 0;
- X }
- X
- X /* general case with exponent > 0: */
- X result = 1;
- X for ( ; ; ) /* LOOP INVARIANT: result*base^exponent */
- X {
- X#if 0 /* intended code: */
- X if (exponent % 2 != 0)
- X#else /* faster equivalent (suggested by Dan Levy of Teletype): */
- X if ((exponent & 1) != 0)
- X#endif
- X {
- X result *= base;
- X }
- X#if 0 /* intended code: */
- X if ((exponent /= 2) == 0)
- X#else /* faster equivalent (suggested by Dan Levy of Teletype): */
- X if ((exponent >>= 1) == 0)
- X#endif
- X {
- X break; /* result now stable */
- X }
- X base *= base;
- X }
- X
- X return result;
- X}
- SHAR_EOF
- chmod 0666 ulpow.c || echo "restore of ulpow.c fails"
- sed 's/^X//' << 'SHAR_EOF' > ytab.c &&
- X/* C:/BIN\YACC.EXE -d hexcalc.y */
- X#line 1 "hexcalc.y"
- X
- X#include "hexcalc.h"
- Xtypedef union {
- X BASE_TYPE val; /* actual value */
- X Symbol *sym; /* symbol table pointer */
- X} YYSTYPE;
- X#define NUMBER 257
- X#define CONST 258
- X#define VAR 259
- X#define BLTIN 260
- X#define UNDEF 261
- X#define QUIT 262
- X#define HELP 263
- X#define CHRADIX 264
- X#define LSH 265
- X#define RSH 266
- X#define UNARYMINUS 267
- X#define POW 268
- Xextern int yychar, yyerrflag;
- Xextern YYSTYPE yyval, yylval;
- X#line 81
- X#include <stdio.h>
- X#include <setjmp.h>
- X
- Xchar *progname; /* for error messages */
- Xint lineno = 1;
- Xint radix = 16;
- X
- XSTATIC char *credit =
- X"hexcalc 1.1 by Richard Hargrove, 25 June 1988; based on hoc3 from Kernighan and Pike";
- X
- Xjmp_buf prog_begin, prog_end;
- X
- X/******************************************************************************/
- X
- Xvoid puthelp()
- X{
- X static char *help_text[] = {
- X "Type in an expression or command. Expressions other than assignment",
- X "cause the evaluated result to be output. All values are 32-bit integers.",
- X "Expressions are made up of the following operands and operators:",
- X "",
- X "Operands: numeric literals (must begin with a digit), variables",
- X "(31 chars max, initialized with assignment), and built-in functions.",
- X "Built-ins: DEC(expr) output decimal value of expr",
- X " OCT(expr) output octal value of expr",
- X " HEX(expr) output hex value of expr",
- X "Operators: ( ) grouping",
- X " ** exponentiation",
- X " - ~ unary minus, bitwise not",
- X " * / % multiplication, division, modulus",
- X " + - addition, subtraction",
- X " << >> left-shift, right-shift",
- X " & bitwise and",
- X " ^ bitwise exclusive-or",
- X " | bitwise or",
- X " = assignment",
- X "",
- X "Commands: help HELP print this message",
- X " quit exit terminate execution",
- X " hex dec oct set the default radix",
- X (char *)0
- X };
- X int i = 0;
- X
- X while (help_text[i] != (char *)0)
- X {
- X puts(help_text[i++]);
- X }
- X}
- X
- X/******************************************************************************/
- X
- Xvoid warning (s, t) /* print warning message */
- Xchar *s, *t;
- X{
- X fprintf (stderr, "%s : %s", progname, s);
- X if (t != (char *)0)
- X {
- X fprintf (stderr, " %s", t);
- X }
- X fprintf (stderr, " near line %d\n", lineno);
- X}
- X
- X
- X/******************************************************************************/
- X
- Xvoid yyerror (s) /* called for yacc syntax error */
- Xchar *s;
- X{
- X warning (s, (char *)0);
- X}
- X
- X/******************************************************************************/
- X
- Xvoid execerror (s, t)
- Xchar *s, *t;
- X{
- X warning (s, t);
- X longjmp (prog_begin, 1);
- X}
- X
- X/******************************************************************************/
- X
- Xmain (argc, argv)
- Xint argc;
- Xchar *argv [];
- X{
- X progname = argv [0];
- X init ();
- X if (setjmp (prog_end) == 0)
- X {
- X (void)setjmp (prog_begin);
- X yyparse ();
- X }
- X return 0;
- X}
- Xstatic short yydef[] = {
- X -1, 4, 30, 17, 16, 3, 15, 14, 13, 12,
- X 11, 10, 9, 8, 7, 6, 5
- X};
- Xstatic short yyex[] = {
- X 0, 0, -1, 1
- X};
- Xstatic short yyact[] = {
- X -52, -39, -40, -41, -37, -45, -44, -2, -38, -35,
- X -34, -36, 264, 263, 262, 260, 259, 258, 257, 256,
- X 126, 45, 40, 10, -39, -40, -41, -45, -44, -2,
- X -38, 260, 259, 258, 257, 126, 45, 40, -31, 40,
- X -30, 61, -46, 10, -47, 10, -48, 10, -49, 10,
- X -50, -28, -23, -26, -24, -25, -27, -22, -21, -19,
- X -20, -29, 268, 266, 265, 124, 94, 47, 45, 43,
- X 42, 38, 37, 10, -53, 10, -29, 268, -28, -23,
- X -42, -26, -24, -25, -27, -22, -21, -19, -20, -29,
- X 268, 266, 265, 124, 94, 47, 45, 43, 42, 41,
- X 38, 37, -28, -23, -43, -26, -24, -25, -27, -22,
- X -21, -19, -20, -29, 268, 266, 265, 124, 94, 47,
- X 45, 43, 42, 41, 38, 37, -28, -23, -26, -24,
- X -25, -27, -22, -21, -19, -20, -29, 268, 266, 265,
- X 124, 94, 47, 45, 43, 42, 38, 37, -28, -26,
- X -27, -29, 268, 47, 42, 37, -28, -26, -24, -25,
- X -27, -19, -20, -29, 268, 266, 265, 47, 45, 43,
- X 42, 37, -28, -23, -26, -24, -25, -27, -19, -20,
- X -29, 268, 266, 265, 47, 45, 43, 42, 38, 37,
- X -28, -23, -26, -24, -25, -27, -22, -19, -20, -29,
- X 268, 266, 265, 94, 47, 45, 43, 42, 38, 37,
- X -28, -26, -24, -25, -27, -29, 268, 47, 45, 43,
- X 42, 37, -1
- X};
- Xstatic short yypact[] = {
- X 12, 41, 75, 77, 77, 137, 77, 77, 77, 77,
- X 152, 152, 164, 181, 200, 216, 216, 114, 31, 31,
- X 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- X 31, 90, 62, 49, 47, 45, 43, 39, 31, 31, 31
- X};
- Xstatic short yygo[] = {
- X -17, -16, -15, -14, -13, -12, -11, -10, -9, -8,
- X -7, -6, -18, -32, -5, -4, -33, 40, 39, 38,
- X 30, 29, 28, 27, 26, 25, 24, 23, 22, 21,
- X 20, 19, 18, -3, -54, 0, -1, -1
- X};
- Xstatic short yypgo[] = {
- X 0, 0, 0, 34, 16, 16, 16, 16, 16, 16,
- X 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- X 16, 16, 36, 36, 36, 36, 36, 36, 36, 36,
- X 16, 0
- X};
- Xstatic short yyrlen[] = {
- X 0, 0, 0, 3, 1, 3, 3, 3, 3, 3,
- X 3, 3, 3, 3, 3, 3, 2, 2, 3, 4,
- X 1, 1, 3, 3, 3, 3, 3, 0, 2, 3,
- X 1, 2
- X};
- X#define YYS0 50
- X#define YYDELTA 23
- X#define YYNPACT 41
- X#define YYNDEF 17
- X
- X#define YYr29 0
- X#define YYr30 1
- X#define YYr31 2
- X#define YYr9 3
- X#define YYr12 4
- X#define YYr15 5
- X#define YYr16 6
- X#define YYr17 7
- X#define YYr18 8
- X#define YYr19 9
- X#define YYr20 10
- X#define YYr21 11
- X#define YYr22 12
- X#define YYr23 13
- X#define YYr24 14
- X#define YYr25 15
- X#define YYr27 16
- X#define YYr28 17
- X#define YYr26 18
- X#define YYr14 19
- X#define YYr11 20
- X#define YYr10 21
- X#define YYr8 22
- X#define YYr7 23
- X#define YYr6 24
- X#define YYr5 25
- X#define YYr4 26
- X#define YYrACCEPT YYr29
- X#define YYrERROR YYr30
- X#define YYrLR2 YYr31
- X#line 2 "yacc parser: c:/etc/yyparse.c"
- X
- X/*
- X * Automaton to interpret LALR(1) tables.
- X *
- X * Macros:
- X * yyclearin - clear the lookahead token.
- X * yyerrok - forgive a pending error
- X * YYERROR - simulate an error
- X * YYACCEPT - halt and return 0
- X * YYABORT - halt and return 1
- X * YYRETURN(value) - halt and return value. You should use this
- X * instead of return(value).
- X * YYREAD - ensure yychar contains a lookahead token by reading
- X * one if it does not. See also YYSYNC.
- X *
- X * Preprocessor flags:
- X * YYDEBUG - includes debug code. The parser will print
- X * a travelogue of the parse if this is defined
- X * and yydebug is non-zero.
- X * YYSSIZE - size of state and value stacks (default 150).
- X * YYSTATIC - By default, the state stack is an automatic array.
- X * If this is defined, the stack will be static.
- X * In either case, the value stack is static.
- X * YYALLOC - Dynamically allocate both the state and value stacks
- X * by calling malloc() and free().
- X * YYLR2 - defined if lookahead is needed to resolve R/R or S/R conflicts
- X * YYSYNC - if defined, yacc guarantees to fetch a lookahead token
- X * before any action, even if it doesnt need it for a decision.
- X * If YYSYNC is defined, YYREAD will never be necessary unless
- X * the user explicitly sets yychar = -1
- X *
- X * Copyright (c) 1983, by the University of Waterloo
- X */
- X
- X#ifndef YYSSIZE
- X# define YYSSIZE 150
- X#endif
- X#ifndef YYDEBUG
- X#define YYDEBUG 0
- X#endif
- X#define YYERROR goto yyerrlabel
- X#define yyerrok yyerrflag = 0
- X#define yyclearin yychar = -1
- X#define YYACCEPT YYRETURN(0)
- X#define YYABORT YYRETURN(1)
- X#ifdef YYALLOC
- X# define YYRETURN(val) { retval = (val); goto yyReturn; }
- X#else
- X# define YYRETURN(val) return(val)
- X#endif
- X#if YYDEBUG
- X/* The if..else makes this macro behave exactly like a statement */
- X# define YYREAD if (yychar < 0) { \
- X if ((yychar = yylex()) < 0) \
- X yychar = 0; \
- X if (yydebug) \
- X printf("read %s (%d)\n", yyptok(yychar),\
- X yychar); \
- X } else
- X#else
- X# define YYREAD if (yychar < 0) { \
- X if ((yychar = yylex()) < 0) \
- X yychar = 0; \
- X } else
- X#endif
- X#define YYERRCODE 256 /* value of `error' */
- X#if __TURBOC__&&__SMALL__
- X#define YYQYYP *(int *)((int)yyq + ((int)yyq-(int)yyp))
- X#else
- X#define YYQYYP yyq[yyq-yyp]
- X#endif
- X
- XYYSTYPE yyval, /* $$ */
- X *yypvt, /* $n */
- X yylval; /* yylex() sets this */
- X
- Xint yychar, /* current token */
- X yyerrflag, /* error flag */
- X yynerrs; /* error count */
- X
- X#if YYDEBUG
- Xint yydebug = YYDEBUG-0; /* debug flag & tables */
- Xextern char *yysvar[], *yystoken[], *yyptok();
- Xextern short yyrmap[], yysmap[];
- Xextern int yynstate, yynvar, yyntoken, yynrule;
- X# define yyassert(condition, msg, arg) \
- X if (!(condition)) { printf("\nyacc bug: "); printf(msg, arg); YYABORT; }
- X#else /* !YYDEBUG */
- X# define yyassert(condition, msg, arg)
- X#endif
- X
- Xyyparse()
- X{
- X
- X register short yyi, *yyp; /* for table lookup */
- X register short *yyps; /* top of state stack */
- X register short yystate; /* current state */
- X register YYSTYPE *yypv; /* top of value stack */
- X register short *yyq;
- X register int yyj;
- X
- X#ifdef YYSTATIC
- X static short yys[YYSSIZE + 1];
- X static YYSTYPE yyv[YYSSIZE + 1];
- X#else
- X#ifdef YYALLOC
- X YYSTYPE *yyv;
- X short *yys;
- X YYSTYPE save_yylval, save_yyval, *save_yypvt;
- X int save_yychar, save_yyerrflag, save_yynerrs;
- X int retval;
- X#if 0 /* defined in <stdlib.h>*/
- X extern char *malloc();
- X#endif 0
- X#else
- X short yys[YYSSIZE + 1];
- X static YYSTYPE yyv[YYSSIZE + 1]; /* historically static */
- X#endif
- X#endif
- X
- X#ifdef YYALLOC
- X yys = (short *) malloc((YYSSIZE + 1) * sizeof(short));
- X yyv = (YYSTYPE *) malloc((YYSSIZE + 1) * sizeof(YYSTYPE));
- X if (yys == (short *)0 || yyv == (YYSTYPE *)0) {
- X yyerror("Not enough space for parser stacks");
- X return 1;
- X }
- X save_yylval = yylval;
- X save_yyval = yyval;
- X save_yypvt = yypvt;
- X save_yychar = yychar;
- X save_yyerrflag = yyerrflag;
- X save_yynerrs = yynerrs;
- X#endif
- X
- X yynerrs = 0;
- X yyerrflag = 0;
- X yychar = -1;
- X yyps = yys;
- X yypv = yyv;
- X yystate = YYS0; /* start state */
- X
- XyyStack:
- X yyassert((unsigned)yystate < yynstate, "state %d\n", yystate);
- X if (++yyps > &yys[YYSSIZE]) {
- X yyerror("Parser stack overflow");
- X YYABORT;
- X }
- X *yyps = yystate; /* stack current state */
- X *++yypv = yyval; /* ... and value */
- X
- X#if YYDEBUG
- X if (yydebug)
- X printf("state %d (%d), char %s (%d)\n", yysmap[yystate],
- X yystate, yyptok(yychar), yychar);
- X#endif
- X
- X /*
- X * Look up next action in action table.
- X */
- XyyEncore:
- X#ifdef YYSYNC
- X YYREAD;
- X#endif
- X if (yystate >= sizeof yypact/sizeof yypact[0]) /* simple state */
- X yyi = yystate - YYDELTA; /* reduce in any case */
- X else {
- X if(*(yyp = &yyact[yypact[yystate]]) >= 0) {
- X /* Look for a shift on yychar */
- X#ifndef YYSYNC
- X YYREAD;
- X#endif
- X yyq = yyp;
- X yyi = yychar;
- X#if __TURBOC__&&__SMALL__
- X /* yyi is in di, yyp is in si */
- X L01:
- X asm lodsw /* ax = *yyp++; */
- X asm cmp yyi, ax
- X asm jl L01
- X#else
- X while (yyi < *yyp++)
- X ;
- X#endif
- X if (yyi == yyp[-1]) {
- X yystate = ~YYQYYP;
- X#if YYDEBUG
- X if (yydebug)
- X printf("shift %d (%d)\n", yysmap[yystate], yystate);
- X#endif
- X yyval = yylval; /* stack what yylex() set */
- X yychar = -1; /* clear token */
- X if (yyerrflag)
- X yyerrflag--; /* successful shift */
- X goto yyStack;
- X }
- X }
- X
- X /*
- X * Fell through - take default action
- X */
- X
- X if (yystate >= sizeof yydef /sizeof yydef[0])
- X goto yyError;
- X if ((yyi = yydef[yystate]) < 0) { /* default == reduce? */
- X /* Search exception table */
- X yyassert((unsigned)~yyi < sizeof yyex/sizeof yyex[0],
- X "exception %d\n", yystate);
- X yyp = &yyex[~yyi];
- X#ifndef YYSYNC
- X YYREAD;
- X#endif
- X while((yyi = *yyp) >= 0 && yyi != yychar)
- X yyp += 2;
- X yyi = yyp[1];
- X yyassert(yyi >= 0,"Ex table not reduce %d\n", yyi);
- X }
- X }
- X
- X#ifdef YYLR2
- XyyReduce: /* reduce yyi */
- X#endif
- X yyassert((unsigned)yyi < yynrule, "reduce %d\n", yyi);
- X yyj = yyrlen[yyi];
- X#if YYDEBUG
- X if (yydebug) printf("reduce %d (%d), pops %d (%d)\n", yyrmap[yyi],
- X yyi, yysmap[yyps[-yyj]], yyps[-yyj]);
- X#endif
- X yyps -= yyj; /* pop stacks */
- X yypvt = yypv; /* save top */
- X yypv -= yyj;
- X yyval = yypv[1]; /* default action $$ = $1 */
- X switch (yyi) { /* perform semantic action */
- X
- Xcase YYr4: { /* list : list expr '\n' */
- X#line 28
- X
- X if (radix == 16)
- X printf ("\t%lx\n", yypvt[-1].val);
- X else if (radix == 10)
- X printf ("\t%lu\n", yypvt[-1].val);
- X else
- X printf ("\t%lo\n", yypvt[-1].val);
- X
- X} break;
- X
- Xcase YYr5: { /* list : list HELP '\n' */
- X#line 36
- X puthelp();
- X} break;
- X
- Xcase YYr6: { /* list : list QUIT '\n' */
- X#line 37
- X longjmp (prog_end, 1);
- X} break;
- X
- Xcase YYr7: { /* list : list CHRADIX '\n' */
- X#line 38
- X
- X if (*(yypvt[-1].sym->name) == 'h')
- X radix = 16;
- X else if (*(yypvt[-1].sym->name) == 'd')
- X radix = 10;
- X else
- X radix = 8;
- X
- X} break;
- X
- Xcase YYr8: { /* list : list error '\n' */
- X#line 46
- X yyerrok;
- X} break;
- X
- Xcase YYr9: { /* asgn : VAR '=' expr */
- X#line 48
- X yyval.val = yypvt[-2].sym->u.val = yypvt[0].val; yypvt[-2].sym->type = VAR;
- X} break;
- X
- Xcase YYr10: { /* expr : NUMBER */
- X#line 50
- X yyval.val = yypvt[0].val;
- X} break;
- X
- Xcase YYr11: { /* expr : CONST */
- X#line 51
- X yyval.val = yypvt[0].sym->u.val;
- X} break;
- X
- Xcase YYr12: { /* expr : VAR */
- X#line 52
- X
- X if (yypvt[0].sym->type == UNDEF)
- X execerror ("undefined variable", yypvt[0].sym->name);
- X yyval.val = yypvt[0].sym->u.val;
- X} break;
- X
- Xcase YYr14: { /* expr : BLTIN '(' expr ')' */
- X#line 57
- X yyval.val = (*(yypvt[-3].sym->u.ptr))(yypvt[-1].val);
- X} break;
- X
- Xcase YYr15: { /* expr : expr LSH expr */
- X#line 58
- X yyval.val = yypvt[-2].val << yypvt[0].val;
- X} break;
- X
- Xcase YYr16: { /* expr : expr RSH expr */
- X#line 59
- X yyval.val = yypvt[-2].val >> yypvt[0].val;
- X} break;
- X
- Xcase YYr17: { /* expr : expr '|' expr */
- X#line 60
- X yyval.val = yypvt[-2].val | yypvt[0].val;
- X} break;
- X
- Xcase YYr18: { /* expr : expr '^' expr */
- X#line 61
- X yyval.val = yypvt[-2].val ^ yypvt[0].val;
- X} break;
- X
- Xcase YYr19: { /* expr : expr '&' expr */
- X#line 62
- X yyval.val = yypvt[-2].val & yypvt[0].val;
- X} break;
- X
- Xcase YYr20: { /* expr : expr '+' expr */
- X#line 63
- X yyval.val = yypvt[-2].val + yypvt[0].val;
- X} break;
- X
- Xcase YYr21: { /* expr : expr '-' expr */
- X#line 64
- X yyval.val = yypvt[-2].val - yypvt[0].val;
- X} break;
- X
- Xcase YYr22: { /* expr : expr '*' expr */
- X#line 65
- X yyval.val = yypvt[-2].val * yypvt[0].val;
- X} break;
- X
- Xcase YYr23: { /* expr : expr '/' expr */
- X#line 66
- X
- X if (yypvt[0].val == 0)
- X execerror ("division by zero", (char *)0);
- X yyval.val = yypvt[-2].val / yypvt[0].val;
- X} break;
- X
- Xcase YYr24: { /* expr : expr '%' expr */
- X#line 70
- X
- X if (yypvt[0].val == 0)
- X execerror ("modulo zero", (char *)0);
- X yyval.val = yypvt[-2].val % yypvt[0].val;
- X} break;
- X
- Xcase YYr25: { /* expr : expr POW expr */
- X#line 74
- X yyval.val = ulpow (yypvt[-2].val, yypvt[0].val);
- X} break;
- X
- Xcase YYr26: { /* expr : '(' expr ')' */
- X#line 75
- X yyval.val = yypvt[-1].val;
- X} break;
- X
- Xcase YYr27: { /* expr : '-' expr */
- X#line 76
- X yyval.val = -yypvt[0].val;
- X} break;
- X
- Xcase YYr28: { /* expr : '~' expr */
- X#line 77
- X yyval.val = ~ yypvt[0].val;
- X} break;
- X#line 237 "yacc parser: c:/etc/yyparse.c"
- X case YYrACCEPT:
- X YYACCEPT;
- X case YYrERROR:
- X goto yyError;
- X#ifdef YYLR2
- X case YYrLR2:
- X#ifndef YYSYNC
- X YYREAD;
- X#endif
- X yyj = 0;
- X while(yylr2[yyj] >= 0) {
- X if(yylr2[yyj] == yystate && yylr2[yyj+1] == yychar
- X && yylook(yys+1,yyps,yystate,yychar,yy2lex(),yylr2[yyj+2]))
- X break;
- X yyj += 3;
- X }
- X if(yylr2[yyj] < 0)
- X goto yyError;
- X if(yylr2[yyj+2] < 0) {
- X yystate = ~ yylr2[yyj+2];
- X goto yyStack;
- X }
- X yyi = yylr2[yyj+2];
- X goto yyReduce;
- X#endif
- X }
- X
- X /*
- X * Look up next state in goto table.
- X */
- X
- X yyp = &yygo[yypgo[yyi]];
- X yyq = yyp++;
- X yyi = *yyps;
- X#if __TURBOC__ && __SMALL__
- X /* yyi is in di, yyp is in si */
- XL02:
- X asm lodsw /* ax = *yyp++; */
- X asm cmp yyi, ax
- X asm jl L02
- X#else
- X while (yyi < *yyp++)
- X ;
- X#endif
- X yystate = ~(yyi == *--yyp? YYQYYP: *yyq);
- X goto yyStack;
- X
- Xyyerrlabel: ; /* come here from YYERROR */
- X/*
- X#pragma used yyerrlabel
- X */
- X yyerrflag = 1;
- X yyps--, yypv--;
- X
- XyyError:
- X switch (yyerrflag) {
- X
- X case 0: /* new error */
- X yynerrs++;
- X yyi = yychar;
- X yyerror("Syntax error");
- X if (yyi != yychar) {
- X /* user has changed the current token */
- X /* try again */
- X yyerrflag++; /* avoid loops */
- X goto yyEncore;
- X }
- X
- X case 1: /* partially recovered */
- X case 2:
- X yyerrflag = 3; /* need 3 valid shifts to recover */
- X
- X /*
- X * Pop states, looking for a
- X * shift on `error'.
- X */
- X
- X for ( ; yyps > yys; yyps--, yypv--) {
- X if (*yyps >= sizeof yypact/sizeof yypact[0])
- X continue;
- X yyp = &yyact[yypact[*yyps]];
- X yyq = yyp;
- X do
- X ;
- X while (YYERRCODE < *yyp++);
- X if (YYERRCODE == yyp[-1]) {
- X yystate = ~YYQYYP;
- X goto yyStack;
- X }
- X
- X /* no shift in this state */
- X#if YYDEBUG
- X if (yydebug && yyps > yys+1)
- X printf("Error recovery pops state %d (%d), uncovers %d (%d)\n",
- X yysmap[yyps[0]], yyps[0],
- X yysmap[yyps[-1]], yyps[-1]);
- X#endif
- X /* pop stacks; try again */
- X }
- X /* no shift on error - abort */
- X break;
- X
- X case 3:
- X /*
- X * Erroneous token after
- X * an error - discard it.
- X */
- X
- X if (yychar == 0) /* but not EOF */
- X break;
- X#if YYDEBUG
- X if (yydebug)
- X printf("Error recovery discards %s (%d), ",
- X yyptok(yychar), yychar);
- X#endif
- X yyclearin;
- X goto yyEncore; /* try again in same state */
- X }
- X YYABORT;
- X
- X#ifdef YYALLOC
- XyyReturn:
- X yylval = save_yylval;
- X yyval = save_yyval;
- X yypvt = save_yypvt;
- X yychar = save_yychar;
- X yyerrflag = save_yyerrflag;
- X yynerrs = save_yynerrs;
- X free((char *)yys);
- X free((char *)yyv);
- X return(retval);
- X#endif
- X}
- X
- X#ifdef YYLR2
- Xyylook(s,rsp,state,c1,c2,i)
- Xshort *s; /* stack */
- Xshort *rsp; /* real top of stack */
- Xint state; /* current state */
- Xint c1; /* current char */
- Xint c2; /* next char */
- Xint i; /* action S < 0, R >= 0 */
- X{
- X int j;
- X short *p,*q;
- X short *sb,*st;
- X#if YYDEBUG
- X if(yydebug) {
- X printf("LR2 state %d (%d) char %s (%d) lookahead %s (%d)",
- X yysmap[state],state,yyptok(c1),c1,yyptok(c2),c2);
- X if(i > 0)
- X printf("reduce %d (%d)\n", yyrmap[i], i);
- X else
- X printf("shift %d (%d)\n", yysmap[i], i);
- X }
- X#endif
- X st = sb = rsp+1;
- X if(i >= 0)
- X goto reduce;
- X shift:
- X state = ~i;
- X c1 = c2;
- X if(c1 < 0)
- X return 1;
- X c2 = -1;
- X
- X stack:
- X if(++st >= &s[YYSSIZE]) {
- X yyerror("Parser Stack Overflow");
- X return 0;
- X }
- X *st = state;
- X if(state >= sizeof yypact/sizeof yypact[0])
- X i = state- YYDELTA;
- X else {
- X p = &yyact[yypact[state]];
- X q = p;
- X i = c1;
- X while(i < *p++)
- X ;
- X if(i == p[-1]) {
- X state = ~q[q-p];
- X c1 = c2;
- X if(c1 < 0)
- X return 1;
- X c2 = -1;
- X goto stack;
- X }
- X if(state >= sizeof yydef/sizeof yydef[0])
- X return 0
- X if((i = yydef[state]) < 0) {
- X p = &yyex[~i];
- X while((i = *p) >= 0 && i != c1)
- X p += 2;
- X i = p[1];
- X }
- X }
- X reduce:
- X j = yyrlen[i];
- X if(st-sb >= j)
- X st -= j;
- X else {
- X rsp -= j+st-sb;
- X st = sb;
- X }
- X switch(i) {
- X case YYrERROR:
- X return 0;
- X case YYrACCEPT:
- X return 1;
- X case YYrLR2:
- X j = 0;
- X while(yylr2[j] >= 0) {
- X if(yylr2[j] == state && yylr2[j+1] == c1)
- X if((i = yylr2[j+2]) < 0)
- X goto shift;
- X else
- X goto reduce;
- X }
- X return 0;
- X }
- X p = &yygo[yypgo[i]];
- X q = p++;
- X i = st==sb ? *rsp : *st;
- X while(i < *p++);
- X state = ~(i == *--p? q[q-p]: *q);
- X goto stack;
- X}
- X#endif
- X
- X#if YYDEBUG
- X
- X/*
- X * Print a token legibly.
- X * This won't work if you roll your own token numbers,
- X * but I've found it useful.
- X */
- Xchar *
- Xyyptok(i)
- X{
- X static char buf[10];
- X
- X if (i >= YYERRCODE)
- X return yystoken[i-YYERRCODE];
- X if (i < 0)
- X return "";
- X if (i == 0)
- X return "$end";
- X if (i < ' ')
- X sprintf(buf, "'^%c'", i+'@');
- X else
- X sprintf(buf, "'%c'", i);
- X return buf;
- X}
- X#endif
- X#ifdef YYDEBUG
- Xchar * yystoken[] = {
- X "error",
- X "NUMBER",
- X "CONST",
- X "VAR",
- X "BLTIN",
- X "UNDEF",
- X "QUIT",
- X "HELP",
- X "CHRADIX",
- X "LSH",
- X "RSH",
- X "UNARYMINUS",
- X "POW",
- X 0
- X};
- Xchar * yysvar[] = {
- X "$accept",
- X "expr",
- X "asgn",
- X "list",
- X 0
- X};
- Xshort yyrmap[] = {
- X 29, 30, 31, 9, 12, 15, 16, 17, 18, 19,
- X 20, 21, 22, 23, 24, 25, 27, 28, 26, 14,
- X 11, 10, 8, 7, 6, 5, 4, 1, 2, 3,
- X 13, 0
- X};
- Xshort yysmap[] = {
- X 1, 8, 14, 16, 18, 41, 42, 43, 44, 45,
- X 46, 47, 48, 49, 50, 51, 52, 40, 36, 35,
- X 34, 33, 32, 31, 30, 29, 28, 27, 26, 21,
- X 20, 19, 13, 12, 11, 10, 9, 5, 4, 3,
- X 2, 39, 53, 6, 7, 22, 23, 24, 25, 37,
- X 0, 15, 38, 17
- X};
- Xint yyntoken = 27, yynvar = 4, yynstate = 54, yynrule = 32;
- X#endif
- SHAR_EOF
- chmod 0666 ytab.c || echo "restore of ytab.c fails"
- sed 's/^X//' << 'SHAR_EOF' > ytab.h &&
- Xtypedef union {
- X BASE_TYPE val; /* actual value */
- X Symbol *sym; /* symbol table pointer */
- X} YYSTYPE;
- X#define NUMBER 257
- X#define CONST 258
- X#define VAR 259
- X#define BLTIN 260
- X#define UNDEF 261
- X#define QUIT 262
- X#define HELP 263
- X#define CHRADIX 264
- X#define LSH 265
- X#define RSH 266
- X#define UNARYMINUS 267
- X#define POW 268
- Xextern YYSTYPE yyval, yylval;
- SHAR_EOF
- chmod 0666 ytab.h || echo "restore of ytab.h fails"
- sed 's/^X//' << 'SHAR_EOF' > yylex.c &&
- X
- X/* yylex.c lexical scanner for the hexcalc utility
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#include "hexcalc.h"
- X#ifdef __TURBOC__
- X#include "ytab.h"
- X#else
- X#include "y.tab.h"
- X#endif
- X
- Xextern int lineno;
- Xextern int radix;
- X
- X#define MAXCHARS 31 /* number of significant chars in an identifier */
- X
- X/******************************************************************************/
- X
- Xint yylex ()
- X{
- X int c;
- X
- X while ((c = getchar()) == ' ' || c == '\t') /* skip whitespace */;
- X if (c == EOF) return 0;
- X
- X if (radix == 8)
- X {
- X if (c >= '0' && c <= '7')
- X {
- X ungetc (c, stdin);
- X scanf ("%lo", &yylval.val);
- X return NUMBER;
- X }
- X }
- X else if (isdigit(c))
- X {
- X ungetc (c, stdin);
- X scanf (radix == 16 ? "%lx" : "%lu", &yylval.val);
- X return NUMBER;
- X }
- X if (isalpha(c))
- X {
- X Symbol *s;
- X char sbuf [MAXCHARS+1], *p = sbuf;
- X
- X do
- X {
- X if (p < sbuf+MAXCHARS) *p++ = c;
- X }
- X while ((c = getchar()) != EOF && isalnum(c));
- X ungetc (c, stdin);
- X *p = '\0';
- X if ((s = lookup (sbuf)) == (Symbol *)0)
- X {
- X s = install (sbuf, UNDEF, (BASE_TYPE)0);
- X }
- X yylval.sym = s;
- X return s->type == UNDEF ? VAR : s->type;
- X }
- X /* handle multi-char operator tokens */
- X if ((c == '<') || (c == '>'))
- X {
- X int c2 = getchar();
- X
- X if ((c == '<') && (c2 == '<'))
- X {
- X return LSH;
- X }
- X else if ((c == '>') && (c2 == '>'))
- X {
- X return RSH;
- X }
- X else
- X {
- X ungetc(c2, stdin);
- X }
- X }
- X if (c == '*')
- X {
- X int c2 = getchar();
- X
- X if (c2 == '*')
- X {
- X return POW;
- X }
- X else
- X {
- X ungetc(c2, stdin);
- X }
- X }
- X if (c == '#') /* handle comments */
- X {
- X int echo = (c = getchar()) == '#';
- X
- X if (echo != 0) putchar('\t');
- X while (c != '\n')
- X {
- X if (echo != 0) putchar(c);
- X c = getchar();
- X }
- X if (echo != 0) putchar(c);
- X }
- X if (c == '\n') ++lineno;
- X
- X return c;
- X}
- SHAR_EOF
- chmod 0666 yylex.c || echo "restore of yylex.c fails"
- exit 0
- -------- cut here -------- cut here -------- cut here -------- cut here --------
-
- richard hargrove
- ...!{ihnp4 | codas | cbosgd}!killer!richardh
- --------------------------------------------
-