#ifndef lint
static char const 
yyrcsid[] = "$FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28 2000/01/17 02:04:06 bde Exp $";
#endif
#include <stdlib.h>
#define YYBYACC 1
#define YYMAJOR 1
#define YYMINOR 9
#define YYLEX yylex()
#define YYEMPTY -1
#define yyclearin (yychar=(YYEMPTY))
#define yyerrok (yyerrflag=0)
#define YYRECOVERING() (yyerrflag!=0)
static int yygrowstack();
#define YYPREFIX "yy"
#line 2 "dm.y"
/*  Copyright 1980 Gary Perlman */

#include "stat.h"
PGM(dm,Data Manipulation,5.9,10/1/88)
#define	DM_VERSION      "5.9 10/1/88"

#ifndef sun /* no need for corrective version of atof */
#define	myatof(s)   atof(s)
#else
double	myatof ();
#endif

/*
dm is a data manipulator designed to manipulate files of columns of number and
strings.  The major components of this program are:
	(1) a parser, built by yacc, called yyparse.
	(2) a scanner, yylex, called by yyparse.
	(3) a parse tree node function, called by yyparse.
	(4) a function, eval, that evaluates the parse trees.
	(5) a main that calls I/O routines and the control loop.
The following section is a bunch of global declarations that will be put
literally into the program, y.tab.c by yacc.
*/

#define MAXEXPR      100             /* maximum number of expressions */
#define MAXSTRING    32              /* maximum length of input string */
#define MAXCOL       100             /* maximum number of input columns */
#define MAXCONST     100             /* maximum number of constants */
#define FLOATPTR     0               /* codes for parse tree node types */
#define OPERATOR     1
#define STRINGOP     2
#define STRINGPTR    3
#define PARSERROR    1               /* returned by yyparse on error */
/*
The following few numbers are reserved by dm to signal special conditions by
being returned by various routines.  They are hopefully numbers that no
expressions would ever evaluate to.
*/
#define	LARGE         9999999999999.0      /* a large number */
#define	SUPPRESS     -1125899906842624.    /* suppress output */
#define	STRINGFLAG   -8888888888888777.0   /* returned by eval */
#define	NIL          -998888677484837274.  /* cause nil output */
#define	EXITFLAG     -99999999999999.9     /* cause exit */

#define	S_NUMBER      "number"
#define	S_LEN         "len"
#define	S_LOG         "log"
#define	S_LOG10       "Log"
#define	S_EXP         "exp"
#define	S_SQRT        "sqrt"
#define	S_SIN         "sin"
#define	S_COS         "cos"
#define	S_TAN         "tan"
#define	S_ASIN        "asin"
#define	S_ACOS        "acos"
#define	S_ATAN        "atan"
#define	S_CEIL        "ceil"
#define	S_FLOOR       "floor"
#define	S_ROUND       "round"
#define	S_ABS         "abs"

char	Outpipe = 0;                       /* true if output is piped */
FILE	*Infile;                           /* data read from here */
char	Inputline[4096];                   /* INPUT read into here */
FILE	*Outfile;                          /* output from dm */
char	*Evalstr[MAXCOL+1];                /* ptrs to strings from eval */
char	Str[MAXCOL+1][MAXSTRING];          /* columns from each dataline */
char	*Expra;                            /* ptr to each expression */
typedef	union
	{
	int 	opr;        /* if operator or stringop */
	double	*num;       /* if FLOATPTR */
	char	*str;       /* if STRINGOP */
	} STUFF;
STUFF	Tmp1, Tmp2;  /* used in the parser to cast operators */
typedef struct enode        /* expression node in tree */
	{
	int 	etype;          /* type of node */
	STUFF	contents;
	struct	enode *lchild;
	struct	enode *rchild;
	} ENODE;
#define	ENULL ((ENODE *) NULL)
ENODE	*Expr[MAXEXPR+1];           /* ptr to each parse tree */
double	Input[MAXCOL+1];            /* input numbers */
#define	INLINE (Input[0])           /* input line number stored here */
double	Output[MAXEXPR+1];          /* output numbers */
#define	OUTLINE (Output[0])         /* output line number stored here */
double	Const[MAXCONST];            /* constants stored here */
int 	Nconst;                     /* number of constants */
double	Nil = NIL;                  /* flagged by NIL */
double	Suppress  = SUPPRESS;       /* flagged by KILL */
double	Stringflag = STRINGFLAG;    /* eval returns string */
double	Exitflag = EXITFLAG;        /* flagged by EXIT */
double	Randu;                      /* uniform rand num */
extern	double	Maxrand;            /* set by initrand */
int 	Seed;                       /* random seed sent to initrand */
Boole	Userand;                    /* true if Randu is used */
double	N;                          /* number of input cols */
double	Sum;                        /* sum of input cols */
int 	Should_output[MAXEXPR+1];   /* used with X */
int 	Exprno;                     /* expression number */
int 	Nexpr;                      /* number of expressions */
#line 116 "dm.y"
typedef union { /* union of the data types the parser will deal with */
	int 	opr;
	char	*str;
	double	*num;
	ENODE	*ex;
	} YYSTYPE;
#line 128 "y.tab.c"
#define YYERRCODE 256
#define NUMBER 257
#define STRING 258
#define STRINDEX 259
#define IF 260
#define THEN 261
#define ELSE 262
#define NOR 263
#define NAND 264
#define EQ 265
#define NE 266
#define GE 267
#define GT 268
#define LE 269
#define LT 270
#define NOTIN 271
#define UMINUS 272
#define SQRT 273
#define SIN 274
#define COS 275
#define TAN 276
#define ATAN 277
#define ACOS 278
#define ASIN 279
#define NTYPE 280
const short yylhs[] = {                                        -1,
    0,    3,    3,    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,    2,    2,
};
const short yylen[] = {                                         2,
    1,    1,    1,    4,    4,    3,    3,    3,    3,    3,
    3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
    3,    3,    3,    3,    3,    3,    3,    3,    2,    2,
    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
    2,    2,    2,    2,    2,    2,    4,    3,    3,    5,
    6,    1,    3,    1,
};
const short yydefred[] = {                                      0,
   52,   54,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,
    0,   29,    0,   46,   31,   32,   40,   41,   42,   43,
   44,   33,   34,   35,   36,   37,   38,   39,   45,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    6,   53,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,   13,   14,   18,   17,   22,   21,   49,   48,
    0,    0,    4,    5,    0,   47,    0,   50,   51,
};
const short yydgoto[] = {                                      25,
   26,   30,   28,
};
const short yysindex[] = {                                    417,
    0,    0,  417,  417,  417,  -40,  417,  417,  417,  417,
  417,  417,  417,  417,  417,  417,  417,  417,  417,  417,
  -40,  -89,  -88,  417,    0,  694,  303,    0,  441,  303,
  485,    0,  -40,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,  417,
  417,  460,   49,  417,  417,  417,  417,  417,  417,  417,
  417,  417,  417,  417,  417,  417,  417,  417,  417,  417,
  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  417,  417,
  -36,  504,  515,    0,    0,  -52,  202,  202,  485,  485,
  -33,  -33,  -33,  -33,  -33,  -33,   -2,   -2,  -87,  -87,
  -87,  -87,    0,    0,    0,    0,    0,    0,    0,    0,
  574, -254,    0,    0,  417,    0,  417,    0,    0,
};
const short yyrindex[] = {                                      0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,  153,  105,    0,    0,    0,
   93,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,  113,  388,   97,  129,
  324,  340,  363,  372,  384,  396,   69,   81,    1,   13,
   25,   37,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,
};
const short yygindex[] = {                                      0,
  869,  791,  -28,
};
#define YYTABLESIZE 964
const short yytable[] = {                                      33,
    9,   50,   51,   69,   85,  115,   70,  117,   67,   65,
    0,   66,   11,   68,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,   10,   86,    0,    0,    0,    0,
    0,    0,    0,    0,   69,    0,   12,    9,    9,   67,
    0,    9,    9,    9,   68,    9,    0,    9,    0,   11,
   11,  112,    0,   11,   11,   11,    0,   11,    9,   11,
   70,   10,   10,    9,    0,   10,   10,   10,    7,   10,
   11,   10,    0,   12,   12,   11,    0,   12,   12,   12,
    8,   12,   10,   12,    0,    0,  118,   10,  119,   85,
    0,   70,   30,    9,   12,    0,   25,    0,    0,   12,
    0,    0,    0,    0,    3,   11,    7,    0,    0,    7,
    0,    7,   27,    7,    0,   78,    0,   10,    8,    0,
    0,    8,    0,    8,    9,    8,    7,    0,   26,   12,
   30,    7,    0,   30,   25,    0,   11,   25,    8,   79,
    0,    3,    3,    8,    0,    3,    3,    3,   10,    3,
   30,    3,    2,   27,   25,   30,    0,    0,    0,   25,
   12,    7,    3,    0,    0,    0,   26,    3,    0,   26,
   27,    0,    0,    8,    0,   27,    0,    0,    0,    0,
    0,    0,    0,    0,    0,   30,   26,    0,    0,   25,
    0,   26,    7,    2,    0,    0,    0,    3,    3,    0,
    0,    0,    0,    0,    8,   27,    0,    0,    0,    0,
    2,    0,    0,    0,    0,    0,   30,    2,    0,    0,
   25,   26,    0,    0,    0,    0,    0,    0,    3,    0,
    0,    0,    0,    0,    0,    0,   27,    0,   69,   57,
    0,    0,    0,   67,   65,    2,   66,    0,   68,    0,
    0,    0,   26,    0,    0,    0,    0,    0,    0,    0,
    0,    9,    9,    9,    9,    9,    9,    9,    9,    9,
    9,    0,    0,   11,   11,   11,   11,   11,   11,   11,
   11,   11,   11,    0,    0,   10,   10,   10,   10,   10,
   10,   10,   10,   10,   10,   70,    0,   12,   12,   12,
   12,   12,   12,   12,   12,   12,   12,    0,    0,    0,
    0,    0,    0,   71,   72,   73,   74,   75,   76,   77,
    0,    0,    0,   15,    0,    0,    0,    0,    0,    7,
    7,    7,    7,    7,    7,    7,    7,    7,    7,   16,
    0,    8,    8,    8,    8,    8,    8,    8,    8,    8,
    8,    0,    0,   30,   30,   30,   30,   25,   25,   25,
   25,   15,   20,    0,   15,    3,    3,    3,    3,   78,
    0,   19,    0,   27,   27,   27,    0,   16,    0,    0,
   16,   15,    0,   24,    0,    0,   15,   28,    0,   26,
   26,   26,   26,   79,    0,   23,    0,   16,    0,    0,
   20,    0,   16,   20,    0,    0,    0,    0,    0,   19,
    0,    0,   19,    2,    2,    0,   15,    0,    0,    0,
   20,   24,    0,    0,   24,   20,    0,    0,   28,   19,
    0,    0,   16,   23,   19,    0,   23,    0,    0,    0,
    0,   24,    0,    0,    0,   28,   24,   15,    0,    4,
   28,    6,    0,   23,    0,   20,   24,    0,   23,    0,
    0,    5,    0,   16,   19,   58,   59,   60,   61,   62,
   63,   64,    0,    0,    0,    0,   24,   69,   57,    0,
   28,    0,   67,   65,    0,   66,   20,   68,   23,    0,
    0,    0,    8,    0,    0,   19,   69,   57,    0,    0,
   84,   67,   65,   54,   66,    0,   68,   24,    0,    0,
    0,   28,    0,   10,    0,   13,    0,    9,   11,   23,
    0,   69,   54,    0,    7,    0,   67,   65,    0,   66,
   12,   68,    0,    0,   70,    0,   22,   23,    0,    0,
   69,   57,    0,    0,    0,   67,   65,    0,   66,    0,
   68,   69,   57,   70,    0,    0,   67,   65,    0,   66,
    0,   68,    0,    0,   55,    0,   54,   71,   72,   73,
   74,   75,   76,   77,    0,    0,    0,   54,   70,    0,
    0,    0,    0,   55,   15,   15,   15,   15,    0,    0,
    0,    0,    0,    0,    0,    0,  113,   70,    0,    0,
   16,   16,   16,   16,    0,    0,    0,  114,   70,    0,
   69,   57,    0,    0,    0,   67,   65,    0,   66,    0,
   68,    0,    0,   20,   20,   20,   20,   55,    0,    0,
    0,    0,   19,   19,   19,   19,   54,    0,   55,    0,
    0,    0,    0,    0,   24,   24,   24,   24,   28,   28,
   28,    0,    0,    0,    0,    0,   23,   23,   23,   23,
    0,    0,    0,    0,    0,    0,  116,   70,    0,    0,
    0,    0,    0,    1,    2,    0,    3,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,   14,
   15,   16,   17,   18,   19,   20,   21,   55,    0,    0,
    0,   80,    0,   56,   58,   59,   60,   61,   62,   63,
   64,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,   56,   58,   59,   60,   61,   62,   63,   64,
   69,   57,    0,    0,    0,   67,   65,    0,   66,    0,
   68,    0,    0,    0,    0,    0,    0,    0,    0,   59,
   60,   61,   62,   63,   64,    0,   54,    0,    0,    0,
    0,    0,    0,    0,    0,    0,   56,   58,   59,   60,
   61,   62,   63,   64,    0,    0,    0,   56,   58,   59,
   60,   61,   62,   63,   64,    0,    0,   70,    0,    0,
   27,    0,    0,    0,    0,    0,   34,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,   49,    0,    0,   53,    0,    0,   55,    0,    0,
    0,    0,    0,   81,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,   56,   58,   59,   60,
   61,   62,   63,   64,   27,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,  103,  104,  105,  106,  107,  108,  109,  110,    0,
   27,   29,   31,   32,    0,   35,   36,   37,   38,   39,
   40,   41,   42,   43,   44,   45,   46,   47,   48,    0,
    0,    0,   52,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,   27,    0,   27,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,   82,   83,
    0,    0,    0,   87,   88,   89,   90,   91,   92,   93,
   94,   95,   96,   97,   98,   99,  100,  101,  102,    0,
    0,    0,    0,    0,    0,    0,    0,  111,    0,    0,
    0,    0,    0,    0,    0,    0,   56,   58,   59,   60,
   61,   62,   63,   64,
};
const short yycheck[] = {                                      40,
    0,   91,   91,   37,   41,   58,   94,  262,   42,   43,
   -1,   45,    0,   47,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,    0,   54,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   37,   -1,    0,   37,   38,   42,
   -1,   41,   42,   43,   47,   45,   -1,   47,   -1,   37,
   38,   80,   -1,   41,   42,   43,   -1,   45,   58,   47,
   94,   37,   38,   63,   -1,   41,   42,   43,    0,   45,
   58,   47,   -1,   37,   38,   63,   -1,   41,   42,   43,
    0,   45,   58,   47,   -1,   -1,  115,   63,  117,   41,
   -1,   94,    0,   93,   58,   -1,    0,   -1,   -1,   63,
   -1,   -1,   -1,   -1,    0,   93,   38,   -1,   -1,   41,
   -1,   43,    0,   45,   -1,   67,   -1,   93,   38,   -1,
   -1,   41,   -1,   43,  124,   45,   58,   -1,    0,   93,
   38,   63,   -1,   41,   38,   -1,  124,   41,   58,   91,
   -1,   37,   38,   63,   -1,   41,   42,   43,  124,   45,
   58,   47,    0,   41,   58,   63,   -1,   -1,   -1,   63,
  124,   93,   58,   -1,   -1,   -1,   38,   63,   -1,   41,
   58,   -1,   -1,   93,   -1,   63,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   93,   58,   -1,   -1,   93,
   -1,   63,  124,   41,   -1,   -1,   -1,   93,   94,   -1,
   -1,   -1,   -1,   -1,  124,   93,   -1,   -1,   -1,   -1,
   58,   -1,   -1,   -1,   -1,   -1,  124,  258,   -1,   -1,
  124,   93,   -1,   -1,   -1,   -1,   -1,   -1,  124,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  124,   -1,   37,   38,
   -1,   -1,   -1,   42,   43,   93,   45,   -1,   47,   -1,
   -1,   -1,  124,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,  261,  262,  263,  264,  265,  266,  267,  268,  269,
  270,   -1,   -1,  261,  262,  263,  264,  265,  266,  267,
  268,  269,  270,   -1,   -1,  261,  262,  263,  264,  265,
  266,  267,  268,  269,  270,   94,   -1,  261,  262,  263,
  264,  265,  266,  267,  268,  269,  270,   -1,   -1,   -1,
   -1,   -1,   -1,  265,  266,  267,  268,  269,  270,  271,
   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,   -1,  261,
  262,  263,  264,  265,  266,  267,  268,  269,  270,    0,
   -1,  261,  262,  263,  264,  265,  266,  267,  268,  269,
  270,   -1,   -1,  261,  262,  263,  264,  261,  262,  263,
  264,   38,    0,   -1,   41,  261,  262,  263,  264,   67,
   -1,    0,   -1,  261,  262,  263,   -1,   38,   -1,   -1,
   41,   58,   -1,    0,   -1,   -1,   63,    0,   -1,  261,
  262,  263,  264,   91,   -1,    0,   -1,   58,   -1,   -1,
   38,   -1,   63,   41,   -1,   -1,   -1,   -1,   -1,   38,
   -1,   -1,   41,  261,  262,   -1,   93,   -1,   -1,   -1,
   58,   38,   -1,   -1,   41,   63,   -1,   -1,   41,   58,
   -1,   -1,   93,   38,   63,   -1,   41,   -1,   -1,   -1,
   -1,   58,   -1,   -1,   -1,   58,   63,  124,   -1,   33,
   63,   35,   -1,   58,   -1,   93,   40,   -1,   63,   -1,
   -1,   45,   -1,  124,   93,  264,  265,  266,  267,  268,
  269,  270,   -1,   -1,   -1,   -1,   93,   37,   38,   -1,
   93,   -1,   42,   43,   -1,   45,  124,   47,   93,   -1,
   -1,   -1,   76,   -1,   -1,  124,   37,   38,   -1,   -1,
   41,   42,   43,   63,   45,   -1,   47,  124,   -1,   -1,
   -1,  124,   -1,   97,   -1,   99,   -1,  101,  102,  124,
   -1,   37,   63,   -1,  108,   -1,   42,   43,   -1,   45,
  114,   47,   -1,   -1,   94,   -1,  120,  121,   -1,   -1,
   37,   38,   -1,   -1,   -1,   42,   43,   -1,   45,   -1,
   47,   37,   38,   94,   -1,   -1,   42,   43,   -1,   45,
   -1,   47,   -1,   -1,  124,   -1,   63,  265,  266,  267,
  268,  269,  270,  271,   -1,   -1,   -1,   63,   94,   -1,
   -1,   -1,   -1,  124,  261,  262,  263,  264,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   93,   94,   -1,   -1,
  261,  262,  263,  264,   -1,   -1,   -1,   93,   94,   -1,
   37,   38,   -1,   -1,   -1,   42,   43,   -1,   45,   -1,
   47,   -1,   -1,  261,  262,  263,  264,  124,   -1,   -1,
   -1,   -1,  261,  262,  263,  264,   63,   -1,  124,   -1,
   -1,   -1,   -1,   -1,  261,  262,  263,  264,  261,  262,
  263,   -1,   -1,   -1,   -1,   -1,  261,  262,  263,  264,
   -1,   -1,   -1,   -1,   -1,   -1,   93,   94,   -1,   -1,
   -1,   -1,   -1,  257,  258,   -1,  260,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  273,
  274,  275,  276,  277,  278,  279,  280,  124,   -1,   -1,
   -1,  261,   -1,  263,  264,  265,  266,  267,  268,  269,
  270,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,  263,  264,  265,  266,  267,  268,  269,  270,
   37,   38,   -1,   -1,   -1,   42,   43,   -1,   45,   -1,
   47,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  265,
  266,  267,  268,  269,  270,   -1,   63,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  263,  264,  265,  266,
  267,  268,  269,  270,   -1,   -1,   -1,  263,  264,  265,
  266,  267,  268,  269,  270,   -1,   -1,   94,   -1,   -1,
    0,   -1,   -1,   -1,   -1,   -1,    6,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   21,   -1,   -1,   24,   -1,   -1,  124,   -1,   -1,
   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  263,  264,  265,  266,
  267,  268,  269,  270,   54,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   71,   72,   73,   74,   75,   76,   77,   78,   -1,
   80,    3,    4,    5,   -1,    7,    8,    9,   10,   11,
   12,   13,   14,   15,   16,   17,   18,   19,   20,   -1,
   -1,   -1,   24,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,  115,   -1,  117,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   50,   51,
   -1,   -1,   -1,   55,   56,   57,   58,   59,   60,   61,
   62,   63,   64,   65,   66,   67,   68,   69,   70,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   79,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  263,  264,  265,  266,
  267,  268,  269,  270,
};
#define YYFINAL 25
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 280
#if YYDEBUG
const char * const yyname[] = {
"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"'!'",0,"'#'",0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,
0,0,0,0,0,"':'",0,0,0,0,"'?'",0,0,0,"'C'",0,0,0,0,0,0,0,0,"'L'",0,0,0,0,0,0,0,0,
0,0,0,0,0,0,"'['",0,"']'","'^'",0,0,"'a'",0,"'c'",0,"'e'","'f'",0,0,0,0,0,"'l'",
0,0,0,0,0,"'r'",0,0,0,0,0,"'x'","'y'",0,0,"'|'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"NUMBER","STRING","STRINDEX","IF","THEN","ELSE","NOR","NAND","EQ","NE","GE",
"GT","LE","LT","NOTIN","UMINUS","SQRT","SIN","COS","TAN","ATAN","ACOS","ASIN",
"NTYPE",
};
const char * const yyrule[] = {
"$accept : start",
"start : stringexpr",
"stringexpr : expr",
"stringexpr : string",
"expr : 'x' '[' expr ']'",
"expr : 'y' '[' expr ']'",
"expr : '(' expr ')'",
"expr : expr '+' expr",
"expr : expr '-' expr",
"expr : expr '*' expr",
"expr : expr '%' expr",
"expr : expr '/' expr",
"expr : expr '^' expr",
"expr : string EQ string",
"expr : string NE string",
"expr : expr EQ expr",
"expr : expr NE expr",
"expr : string GT string",
"expr : string GE string",
"expr : expr GT expr",
"expr : expr GE expr",
"expr : string LT string",
"expr : string LE string",
"expr : expr LT expr",
"expr : expr LE expr",
"expr : expr '&' expr",
"expr : expr NAND expr",
"expr : expr '|' expr",
"expr : expr NOR expr",
"expr : '-' expr",
"expr : '!' expr",
"expr : 'l' expr",
"expr : 'L' expr",
"expr : SQRT expr",
"expr : SIN expr",
"expr : COS expr",
"expr : TAN expr",
"expr : ATAN expr",
"expr : ACOS expr",
"expr : ASIN expr",
"expr : 'e' expr",
"expr : 'a' expr",
"expr : 'f' expr",
"expr : 'r' expr",
"expr : 'c' expr",
"expr : NTYPE string",
"expr : '#' string",
"expr : string '[' expr ']'",
"expr : string 'C' string",
"expr : string NOTIN string",
"expr : expr '?' stringexpr ':' stringexpr",
"expr : IF expr THEN stringexpr ELSE stringexpr",
"expr : NUMBER",
"string : '(' string ')'",
"string : STRING",
};
#endif
#if YYDEBUG
#include <stdio.h>
#endif
#ifdef YYSTACKSIZE
#undef YYMAXDEPTH
#define YYMAXDEPTH YYSTACKSIZE
#else
#ifdef YYMAXDEPTH
#define YYSTACKSIZE YYMAXDEPTH
#else
#define YYSTACKSIZE 10000
#define YYMAXDEPTH 10000
#endif
#endif
#define YYINITSTACKSIZE 200
int yydebug;
int yynerrs;
int yyerrflag;
int yychar;
short *yyssp;
YYSTYPE *yyvsp;
YYSTYPE yyval;
YYSTYPE yylval;
short *yyss;
short *yysslim;
YYSTYPE *yyvs;
int yystacksize;
#line 432 "dm.y"

/*
Next is the scanner that will be repeatedly called by yyparse, yylex.
This simple program reads from a global char *Expra, set by main.  Variables
are handled by returning NUMBER or STRING, tokens defined in above grammar.
*/
yylex ()
	{
	extern	YYSTYPE yylval;
	char	*strsave ();
	int 	column;

	while (isspace (*Expra) || *Expra == '_')
		Expra++;
	if (isdigit (*Expra) || *Expra == '.')
		{
		if (Nconst == MAXCONST)
			ERRMSG1 (Maximum number of constants is %d, MAXCONST)
		Const[Nconst] = myatof (Expra);
		yylval.num = &Const[Nconst++];
		Expra += skipnumber (Expra, 1);
		return (NUMBER);
		}
	switch (*Expra)
		{
		case '"':
		case '\'':
			yylval.str = strsave ();
			return (STRING);
		case 'a':
			if (begins (S_ATAN, Expra))
				{Expra += 4; return (ATAN);}
			if (begins (S_ASIN, Expra))
				{Expra += 4; return (ASIN);}
			if (begins (S_ACOS, Expra))
				{Expra += 4; return (ACOS);}
			if (begins (S_ABS, Expra))
				{Expra += 3; return ('a');}
			if (begins ("and", Expra))
				{Expra += 3; return ('&');}
			break;
		case 'A':
			if (begins ("AND", Expra))
				{ Expra += 3; return ('&'); }
			break;
		case 'c':
			if (begins (S_COS, Expra))
				{Expra += 3; return (COS);}
			if (begins (S_CEIL, Expra))
				{Expra += 4; return ('c');}
			break;
		case 'f': if (begins (S_FLOOR, Expra))
				{Expra += 5; return ('f');}
			break;
		case 'r': if (begins (S_ROUND, Expra))
				{Expra += 5; return ('r');}
			break;
		case 'G':
			if (begins ("GE", Expra))
				{
				Expra += 2;
				return (GE);
				}
			if (begins ("GT", Expra))
				{
				Expra += 2;
				return (GT);
				}
			break;
		case 'e': if (begins ("else", Expra))
				{Expra += 4; return (ELSE);}
			else if (begins (S_EXP, Expra))
				{Expra += 3; return ('e');}
			break;
		case 'E':
			if (begins ("EQ", Expra))
				{ Expra += 2; return (EQ); }
			if (begins ("ELSE", Expra))
				{ Expra += 4; return (ELSE); }
			if (begins ("EXIT", Expra))
				Expra += 4;
			else Expra++;
			yylval.num = &Exitflag;
			return (NUMBER);
		case 'i':
			if (begins ("if", Expra))
				{Expra += 2; return (IF);}
			break;
		case 'I':
			if (begins ("IF", Expra))
				{ Expra += 2; return (IF); }
			if (begins ("INLINE", Expra))
				{
				Expra += 6;
				yylval.num = &INLINE;
				return (NUMBER);
				}
			if (begins ("INPUT", Expra))
				Expra += 5;
			else Expra++;
			yylval.str = Inputline;
			return (STRING);
		case 'K':
			if (begins ("KILL", Expra))
				Expra += 4;
			else Expra++;
			yylval.num = &Suppress;
			return (NUMBER);
		case 'l':
			if (begins (S_LOG, Expra))
				{Expra += 3; return ('l');}
			if (begins (S_LEN, Expra))
				{Expra += 3; return ('#');}
			break;
		case 'L':
			if (begins ("LE", Expra))
				{ Expra += 2; return (LE); }
			if (begins ("LT", Expra))
				{ Expra += 2; return (LT); }
			if (begins (S_LOG10, Expra))
				{Expra += 3; return ('L');}
			break;
		case 'n':
			if (begins ("not", Expra))
				{ Expra += 3; return ('!'); }
			if (begins (S_NUMBER, Expra))
				{ Expra += 6; return (NTYPE); }
			break;
		case 'N':
			if (begins ("NOT", Expra))
				{ Expra += 3; return ('!'); }
			if (begins ("NE", Expra) && !begins ("NEXT", Expra))
				{ Expra += 2; return (NE); }
			if (begins ("NIL", Expra))
				{
				Expra += 3;
				yylval.num = &Nil;
				}
			else if (begins ("NEXT", Expra))
				{
				Expra += 4;
				yylval.num = &Suppress;
				}
			else
				{
				Expra++;
				yylval.num = &N;
				}
			return (NUMBER);
		case 'o':
			if (begins ("or", Expra))
				{ Expra += 2; return ('|'); }
			break;
		case 'O':
			if (begins ("OR", Expra))
				{ Expra += 2; return ('|'); }
			if (begins ("OUTLINE", Expra))
				{
				Expra += 7;
				yylval.num = &OUTLINE;
				return (NUMBER);
				}
			break;
		case 'R':
			if (begins ("RAND", Expra))
				Expra += 4;
			else
				Expra++;
			Userand = TRUE;
			if (isdigit (*Expra))
				{
				Seed = atoi (Expra);
				while (isdigit (*Expra))
					Expra++;
				}
			yylval.num = &Randu;
			return (NUMBER);
		case 's':
			if (begins (S_SQRT, Expra))
				{
				Expra += 4;
				return (SQRT);
				}
			if (begins (S_SIN, Expra))
				{
				Expra += 3;
				return (SIN);
				}
			column = atoi (++Expra);
			Expra += skipnumber (Expra, 0);
			yylval.str = Str[column];
			return (STRING);
		case 'S':
			if (begins ("SKIP", Expra))
				{
				Expra += 4;
				yylval.num = &Suppress;
				}
			else
				{
				if (begins ("SUM", Expra))
					Expra += 3;
				else Expra++;
				yylval.num = &Sum;
				}
			return (NUMBER);
		case 't':
			if (begins (S_TAN, Expra))
				{Expra += 3; return (TAN);}
			if (begins ("then", Expra))
				{Expra += 4; return (THEN);}
			break;
		case 'T':
			if (begins ("THEN", Expra))
				{Expra += 4; return (THEN);}
			break;
		case 'x':
			if (Expra[1] == '[')
				{
				Expra++;
				return ('x');
				}
			column = atoi (++Expra);
			Expra += skipnumber (Expra, 0);
			yylval.num = &Input[column];
			return (NUMBER);
		case 'y':
			if (Expra[1] == '[')
				{
				Expra++;
				return ('y');
				}
			column = atoi (++Expra);
			Expra += skipnumber (Expra, 0);
			yylval.num = &Output[column];
			return (NUMBER);
		case '=': if (Expra[1] == '=') Expra += 2;
			else Expra++;
			return (EQ);
		case '<': if (Expra[1] == '=')
			{
			Expra += 2;
			return (LE);
			}
			Expra++;
			return (LT);
		case '>': if (Expra[1] == '=')
			{
			Expra += 2;
			return (GE);
			}
			Expra++;
			return (GT);
		case '!': switch (Expra[1])
				{
				case '=': Expra += 2; return (NE);
				case 'C': Expra += 2; return (NOTIN);
				case '&': Expra += 2; return (NAND);
				case '|': Expra += 2; return (NOR);
				default: Expra++; return ('!');
				}
		case '&': if (Expra[1] == '&') Expra++; break;
		case '|': if (Expra[1] == '|') Expra++; break;

		}
	return ((int) *Expra++);
	}

yyerror (msg)
char	*msg;
	{
	if (msg && *msg)
		fprintf (stderr, "\007dm: %s\n", msg);
	fprintf (stderr,
		"\007dm: Failure occurred with this left in input: (%s)\n", Expra-1);
#ifdef PTREE
	ptree (Expr[Exprno]);
	putchar ('\n');
#endif
	}

char *
strsave ()
	{
	char	buf[BUFSIZ], *bptr = buf;
	char	quotechar = *Expra++;
	while (*Expra && *Expra != quotechar)
		*bptr++ = *Expra++;
	if (*Expra == quotechar)
		Expra++;
	*bptr = '\0';
	return (strdup (buf));
	}

ENODE *
node (datum, dtype, lson, rson)
STUFF	*datum;                /* string, number, or operator */
int 	dtype;                 /* STRINGPTR, FLOATPTR, OPERATOR, STRINGOP */
ENODE	*lson;
ENODE	*rson;
	{
	ENODE	*newnode;
	newnode = myalloc (ENODE, 1);
	if (newnode == NULL)
		ERRSPACE(expressions)
	newnode->etype = dtype;
	switch (dtype)
		{
		case FLOATPTR: newnode->contents.num = datum->num; break;
		case STRINGPTR: newnode->contents.str = datum->str; break;
		case STRINGOP:
		case OPERATOR: newnode->contents.opr = datum->opr; break;
		default: fprintf (stderr, "\007dm/enode: unknown data type.\n");
		}
	newnode->lchild = lson;
	newnode->rchild = rson;
	return (newnode);
	}

main (argc, argv) int argc; char *argv[];
	{
	ARGV0;
	initial (argc, argv);
	loop ();
	exit (0);
	}

/*
	initial does the following:
		1) inits the random number generator
		2) reads in expressions from file, user, or argv[i].
		3) parses expressions.
		4) opens input and output files.
*/
initial (argc, argv) int argc; char **argv;
	{
	Boole	interactive = FALSE;    /* if true, input in interactive mode */
	Boole	input_by_hand = FALSE;  /* true if expressions input by hand */
	char	exprline[BUFSIZ];       /* expressions read into here */
	FILE	*exprfile;              /* expressions read from here */
	FILE	*getfile ();            /* gets a file open */
	argc--;
	if (argc)
		checkstdin ();
	if (argc == 0)
		{
		interactive = TRUE;
		printf ("dm: version %s (Copyright 1980 Gary Perlman)\n", DM_VERSION);
		exprfile = getfile ("Expression file? ", "r");
		if (exprfile == NULL)
			{
			input_by_hand = TRUE;
			exprfile = stdin;
			printf ("Enter ONE expression per line.\n");
			printf ("End with an empty line.\n");
			}
		}
	else if (argv[1][0] == 'E') /*Expra file flag */
		{
		if ((exprfile = fopen (&argv[1][1], "r")) == NULL)
			ERROPEN (&argv[1][1])
		}
	else
		exprfile = NULL;

	for (;;) /* PARSE expressions until done */
		{
	readexpr:
		if (exprfile == NULL) /*read Expras from argv[i] */
			{
			if (++Exprno > argc)
				break;
			Expra = argv[Exprno];
			}
		else /*read Expras from exprfile */
			{
			++Exprno;
			if (input_by_hand)
				printf ("expression[%d]: ", Exprno);
			if (getline (exprline, BUFSIZ, exprfile) <= 0)
				break;
			Expra = exprline;
			}

		while (isspace (*Expra))
			Expra++;
		if (*Expra == 'X')
			{
			Should_output[Exprno] = FALSE;
			Expra++;
			}
		else
			Should_output[Exprno] = TRUE;
		if (yyparse() == PARSERROR) /* call parser */
			{
			fprintf (stderr, "\007dm: error in parsing expr[%d].\n", Exprno--);
			if (input_by_hand)
				goto readexpr;
			else
				exit (1);
			}
#ifdef PTREE
		if (interactive)
			{
			printf ("e%d: ", Exprno);
			ptree (Expr[Exprno]);
			putchar ('\n');
			}
#endif
		}
		Nexpr = Exprno - 1;
		if (Nexpr == 0)
			{
			Exprno = 0;
			fprintf (stderr, "dm: \007No expressions were read in\n");
			if (input_by_hand && !feof (stdin))
				goto readexpr;
			else
				exit (1);
			}
		/* OPEN I/O files */
		if (interactive)
			{
			if ((Infile = getfile ("Input file? ", "r")) == NULL)
				Infile = stdin;
			if ((Outfile = getfile ("Output file or pipe? ", "w")) == NULL)
				Outfile = stdout;
			}
		else
			{
			Infile = stdin;
			Outfile = stdout;
			}
	if (Userand)
		initrand (Seed);
	}

#define printnum(ioptr, value)    fprintf (ioptr, "%g", value)

/*	loop runs the process on the input to produce the output */
loop ()
	{
	double	eval ();
	Boole	skip = FALSE;

	while (getinput () != EOF)
		{
		skip = FALSE;
		for (Exprno = 1; Exprno <= Nexpr; Exprno++)
			if ((Output[Exprno] = eval(Expr[Exprno])) == Suppress)
				{skip = TRUE; break;}
			else if (Output[Exprno] == Exitflag) exit (0);
		if (skip == TRUE) continue;
		OUTLINE += 1.0;
		for (Exprno = 1; Exprno <= Nexpr; Exprno++)
			if (Should_output[Exprno])
				{
				if (Output[Exprno] == Stringflag)
					fprintf (Outfile, "%s", Evalstr[Exprno]);
				else if (Output[Exprno] == Nil)
					continue;
				else
					printnum (Outfile, Output[Exprno]);
				if (Exprno < Nexpr)
					putc ('\t', Outfile);
				}
		putc ('\n', Outfile);
		/* fflush (Outfile);  why was this needed? */
		}
#ifndef __MSDOS__ /* no popen on MSDOS */
	if (Outpipe)
		(void) pclose (Outfile);
#endif
	}

int
getinput ()
	{
	int 	ncols;
	register int col;
	int 	randval;

	if (getline (Inputline, sizeof (Inputline), Infile) == EOF)
		return (EOF);
	if (Userand)
		{
		while ((randval = rand ()) < 0);
		Randu = randval/Maxrand;
		}
	Sum = 0.0;
	INLINE += 1.0;
	ncols = sstrings (Inputline, Str[1], MAXCOL, MAXSTRING);
	for (col = 1; col <= ncols; col++)
		if (number (Str[col]))
			Sum += (Input[col] = myatof(Str[col]));
		else
			Input[col] = 0.0;
	N = ncols;
	return (ncols);
	}


/*
eval is a recursive function that takes a parse tree of an expression,
and returns its value.  The major kludge in this program is how it handles
strings.  Since it wants to return a double, it cannot return a string, so
the use of strings is somewhat restricted.  When eval evals to a string, it
returns STRINGFLAG after setting a global char *Evalstr[Exprno] to the str
MAIN will look for this flag and switch its output to Evalstr[Exprno] rather
than Output[Exprno].
*/
double
eval (expression) ENODE *expression;
	{
	int 	comp;                 /*for string comparisons*/
	int 	sindex, character;    /*for STRINDEX function */
	char	*string_2b_indexed;   /*for STRINDEX function */
	double	tmp1, tmp2;
	int 	operator;
	if (expression == NULL) return (0.0);
	if (expression->etype == FLOATPTR)
		return (*expression->contents.num);
	if (expression->etype == STRINGPTR) 
		{
		Evalstr[Exprno] = expression->contents.str;
		return (Stringflag);
		}
	if (expression->etype == STRINGOP)
		{
		switch (expression->contents.opr)
			{
			case '=': /*string compare*/
				comp = strcmp (expression->lchild->contents.str,
					expression->rchild->contents.str);
				return (comp ? 0.0 : 1.0);
			case '>': /*string compare*/
				comp = strcmp (expression->lchild->contents.str,
					expression->rchild->contents.str);
				return (comp > 0 ? 1.0 : 0.0);
			case '<': /*string compare*/
				comp = strcmp (expression->lchild->contents.str,
					expression->rchild->contents.str);
				return (comp < 0 ? 1.0 : 0.0);
			case 'C': /*true is s1 is in s2 */
				comp = substr (expression->lchild->contents.str,
					expression->rchild->contents.str);
				return (comp ? 1.0 : 0.0);
			case '#':
				return ((double) strlen (expression->rchild->contents.str));
			case NTYPE:
				return ((double) number (expression->rchild->contents.str));
			case '[': /* string index */
				sindex = eval (expression->rchild);
				string_2b_indexed = expression->lchild->contents.str;
				character = string_2b_indexed[sindex-1];
				return (1.0 * character);
			}
		}
	operator = expression->contents.opr;
	if (operator == ':') return (0.0); /*dummy for conditional */
	tmp1 = eval (expression->lchild);
	tmp2 = eval (expression->rchild);
	switch (operator)
	{
	case 'x':
		sindex = (int) tmp2;
		if (sindex < 0 || sindex > N)
			ERRMSG1 (computed index for x (%d) is out of range, sindex)
		return (Input[sindex]);
	case 'y':
		sindex = (int) tmp2;
		if (sindex >= 0 && sindex <= Nexpr)
		return (Output[sindex]);
		ERRMSG1 (computed index for y (%d) is  out of range, sindex)
	case '_': return (-tmp2);
	case '!': return (fzero (tmp2) ? 1.0 : 0.0);
	case 'l': if (tmp2 <= 0.0)
		ERRMSG3 (log undefined for %g on line %.0f  expr[%d], tmp2, INLINE,Exprno)
		return (log (tmp2));
	case 'L': if (tmp2 <= 0.0)
		ERRMSG3(Log undefined for %g Input line %.0f  expr[%d], tmp2,INLINE,Exprno)
		return (log (tmp2) / LOGe10);
	case 'e': return (exp (tmp2));
	case SQRT:
		if (tmp2 < 0.0)
			ERRMSG3 (sqrt undefined for %g Input line %.0f  expr[%d],
				tmp2, INLINE, Exprno)
		return (sqrt (tmp2));
	case SIN: return (sin (tmp2));
	case COS: return (cos (tmp2));
	case TAN: return (tan (tmp2));
	case ATAN: return (atan (tmp2));
	case ACOS: return (acos (tmp2));
	case ASIN: return (asin (tmp2));
	case 'a': return (fabs (tmp2));
	case 'c': return (ceil (tmp2));
	case 'f': return (floor (tmp2));
	case 'r': return (floor (tmp2 + 0.5));
	case '+': return (tmp1 + tmp2);
	case '-': return (tmp1 - tmp2);
	case '*': return (tmp1 * tmp2);
	case '%': if (fzero (tmp2))
		ERRMSG2 (division by zero. input line %.0f  expr[%d], INLINE,Exprno)
		return ((double) (((int) tmp1) % ((int) tmp2)));
	case '/': if (fzero (tmp2))
		ERRMSG2 (division by zero. input line %.0f  expr[%d], INLINE,Exprno)
		return (tmp1/tmp2);
	case '^':
		if (tmp1 < 0.0 && (floor (tmp2) != tmp2))
			ERRMSG1 (power failure at line %.0f, INLINE)
		return (pow (tmp1, tmp2));
	case '>': return (tmp1 > tmp2 ? 1.0 : 0.0);
	case '<': return (tmp1 < tmp2 ? 1.0 : 0.0);
	case '=': return (fzero (tmp1 - tmp2) ? 1.0 : 0.0);
	case '&': return ((!fzero (tmp1) && !fzero (tmp2)) ? 1.0 : 0.0);
	case '|': return ((!fzero (tmp1) || !fzero (tmp2)) ? 1.0 : 0.0);
	case '?': if (!fzero (tmp1))
		return (eval (expression->rchild->lchild));
		return (eval (expression->rchild->rchild));
	default:
		ERRMSG3 (Unknown operator '%c' %d \\%3o, operator, operator, operator)
	}
	return (Exitflag);
	}

#ifdef PTREE
ptree (tree) ENODE *tree;
	{
	if (tree == NULL) return;
	if (tree->etype == FLOATPTR)
		if (*tree->contents.num < -LARGE)
			{
			double	*nptr = tree->contents.num;
			if (nptr == &Suppress)
				printf ("KILL");
			else if (nptr == &Exitflag)
				printf ("EXIT");
			else if (nptr == &Nil)
				printf ("NIL");
			else printf ("CONTROL");
			}
		else /* regular number */
			{
			double	*dptr = tree->contents.num;
			if (dptr > Input && dptr <= &Input[MAXCOL])
				printf ("x%d", dptr - Input);
			else if (dptr == &INLINE)
				printf ("INLINE");
			else if (dptr > Output && dptr <= &Output[MAXCOL])
				printf ("y%d", dptr - Output);
			else if (dptr == &OUTLINE)
				printf ("OUTLINE");
			else if (dptr == &N)
				printf ("N");
			else if (dptr == &Sum)
				printf ("SUM");
			else if (dptr == &Randu)
				printf ("RAND");
			else
				printnum (stdout, *dptr);
			}
	else if (tree->etype == STRINGPTR)
		{
		char	*sptr = tree->contents.str;
		if (sptr == Inputline)
			printf ("INPUT");
		else if (sptr >= Str[0] && sptr < Str[MAXCOL])
			printf ("s%d", (sptr - Str[0])/MAXSTRING);
		else printf ("'%s'", sptr);
		}
	else if (tree->etype == OPERATOR || tree->etype == STRINGOP)
		{
		int 	op = tree->contents.opr;
		printf ("(");
		ptree (tree->lchild);
		switch (op)
			{
			case NTYPE: printf ("%s ", S_NUMBER); break;
			case '#': printf ("%s ", S_LEN); break;
			case 'l': printf ("%s ", S_LOG); break;
			case 'L': printf ("%s ", S_LOG10); break;
			case 'e': printf ("%s ", S_EXP); break;
			case SQRT: printf ("%s ", S_SQRT); break;
			case SIN: printf ("%s ", S_SIN); break;
			case COS: printf ("%s ", S_COS); break;
			case TAN: printf ("%s ", S_TAN); break;
			case ATAN: printf ("%s ", S_ATAN); break;
			case ACOS: printf ("%s ", S_ACOS); break;
			case ASIN: printf ("%s ", S_ASIN); break;
			case 'c': printf ("%s ", S_CEIL); break;
			case 'f': printf ("%s ", S_FLOOR); break;
			case 'r': printf ("%s ", S_ROUND); break;
			case 'a': printf ("%s ", S_ABS); break;
			default:
				printf (" %c ", op);
			}
		ptree (tree->rchild);
		printf (")");
		}
	else printf ("(bad node type %d)", tree->etype);
	}
#endif

FILE *
getfile (prompt, mode) char *prompt, *mode;
	{
#ifndef __MSDOS__ /* no popen on MSDOS */
	FILE	*popen ();
#endif
	FILE	*fopen (), *ioptr;
	char	filename[BUFSIZ];
	char	*ptr = filename;
  newfile:
	printf ("%s", prompt);
	if (getline (filename, MAXSTRING, stdin) <= 0)
		return (NULL);
	while (isspace (*ptr))
		ptr++;
	if (*ptr == NULL)
		return (NULL);
	if (*mode == 'w')
		if (*ptr == '|')
			Outpipe = 1;
		else if (!canwrite (filename))
			goto newfile;
	if (Outpipe)
		{
#ifndef __MSDOS__ /* no popen on MSDOS */
		if ((ioptr = popen (ptr+1, "w")) == NULL)
#endif
			{
			fprintf (stderr, "Cannot create pipe.\n");
			Outpipe = 0;
			goto newfile;
			}
		}
	else if ((ioptr = fopen (filename, mode)) == NULL)
		{
		printf ("Cannot open '%s'.\n", filename);
		goto newfile;
		}
	return (ioptr);
	}

int
getline (string, maxlen, ioptr)
char	*string;
int 	maxlen;
FILE	*ioptr;
	{
	register	int 	inchar;
	register	int 	len = 0;
	while ((inchar = getc (ioptr)) != EOF)
		{
		if (inchar == '\n')
			break;
		else if (inchar == '\\')
			if ((inchar = getc (ioptr)) == EOF)
				inchar = '\\';
		string[len] = inchar;
		if (++len == maxlen)
			break;
		}
	string[len] = '\0';
	if (len == 0 && feof (ioptr))
		return (EOF);
	return (len);
	}

begins (s1, s2) char *s1, *s2;
	{
	while (*s1)
		if (*s1++ != *s2++)
			return (0);
	return (1);
	/* return (isalpha (*s2) ? 0 : 1);  can't be used because of s1 C s2 */
	}

substr (s1, s2) char *s1, *s2;
	{
	while (*s2)
		if (begins (s1, s2))
			return (1);
		else
			s2++;
	return (0);
	}
#line 1309 "y.tab.c"
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
static int yygrowstack()
{
    int newsize, i;
    short *newss;
    YYSTYPE *newvs;

    if ((newsize = yystacksize) == 0)
        newsize = YYINITSTACKSIZE;
    else if (newsize >= YYMAXDEPTH)
        return -1;
    else if ((newsize *= 2) > YYMAXDEPTH)
        newsize = YYMAXDEPTH;
    i = yyssp - yyss;
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
      (short *)malloc(newsize * sizeof *newss);
    if (newss == NULL)
        return -1;
    yyss = newss;
    yyssp = newss + i;
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
      (YYSTYPE *)malloc(newsize * sizeof *newvs);
    if (newvs == NULL)
        return -1;
    yyvs = newvs;
    yyvsp = newvs + i;
    yystacksize = newsize;
    yysslim = yyss + newsize - 1;
    return 0;
}

#define YYABORT goto yyabort
#define YYREJECT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab

#ifndef YYPARSE_PARAM
#if defined(__cplusplus) || __STDC__
#define YYPARSE_PARAM_ARG void
#define YYPARSE_PARAM_DECL
#else	/* ! ANSI-C/C++ */
#define YYPARSE_PARAM_ARG
#define YYPARSE_PARAM_DECL
#endif	/* ANSI-C/C++ */
#else	/* YYPARSE_PARAM */
#ifndef YYPARSE_PARAM_TYPE
#define YYPARSE_PARAM_TYPE void *
#endif
#if defined(__cplusplus) || __STDC__
#define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM
#define YYPARSE_PARAM_DECL
#else	/* ! ANSI-C/C++ */
#define YYPARSE_PARAM_ARG YYPARSE_PARAM
#define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM;
#endif	/* ANSI-C/C++ */
#endif	/* ! YYPARSE_PARAM */

int
yyparse (YYPARSE_PARAM_ARG)
    YYPARSE_PARAM_DECL
{
    register int yym, yyn, yystate;
#if YYDEBUG
    register const char *yys;

    if ((yys = getenv("YYDEBUG")))
    {
        yyn = *yys;
        if (yyn >= '0' && yyn <= '9')
            yydebug = yyn - '0';
    }
#endif

    yynerrs = 0;
    yyerrflag = 0;
    yychar = (-1);

    if (yyss == NULL && yygrowstack()) goto yyoverflow;
    yyssp = yyss;
    yyvsp = yyvs;
    *yyssp = yystate = 0;

yyloop:
    if ((yyn = yydefred[yystate])) 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 >= yysslim && yygrowstack())
        {
            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;
#if defined(lint) || defined(__GNUC__)
    goto yynewerror;
#endif
yynewerror:
    yyerror("syntax error");
#if defined(lint) || defined(__GNUC__)
    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 >= yysslim && yygrowstack())
                {
                    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 1:
#line 142 "dm.y"
{
		Expr[Exprno] = yyvsp[0].ex;
		}
break;
case 2:
#line 147 "dm.y"
{
		yyval.ex = yyvsp[0].ex;
		}
break;
case 3:
#line 151 "dm.y"
{
		yyval.ex = yyvsp[0].ex;
		}
break;
case 4:
#line 156 "dm.y"
{
		Tmp1.opr = 'x';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[-1].ex);
		}
break;
case 5:
#line 161 "dm.y"
{
		Tmp1.opr = 'y';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[-1].ex);
		}
break;
case 6:
#line 166 "dm.y"
{
		yyval.ex = yyvsp[-1].ex;
		}
break;
case 7:
#line 170 "dm.y"
{
		Tmp1.opr = '+';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 8:
#line 175 "dm.y"
{
		Tmp1.opr = '-';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 9:
#line 180 "dm.y"
{
		Tmp1.opr = '*';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 10:
#line 185 "dm.y"
{
		Tmp1.opr = '%';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 11:
#line 190 "dm.y"
{
		Tmp1.opr = '/';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 12:
#line 195 "dm.y"
{
		Tmp1.opr = '^';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 13:
#line 200 "dm.y"
{
		Tmp1.opr = '=';
		yyval.ex = node (&Tmp1, STRINGOP, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 14:
#line 205 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = '=';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, STRINGOP, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 15:
#line 212 "dm.y"
{
		Tmp1.opr = '=';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 16:
#line 217 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = '=';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 17:
#line 224 "dm.y"
{
		Tmp1.opr = '>';
		yyval.ex = node (&Tmp1, STRINGOP, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 18:
#line 229 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = '<';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, STRINGOP, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 19:
#line 236 "dm.y"
{
		Tmp1.opr = '>';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 20:
#line 241 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = '<';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 21:
#line 248 "dm.y"
{
		Tmp1.opr = '<';
		yyval.ex = node (&Tmp1, STRINGOP, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 22:
#line 253 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = '>';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, STRINGOP, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 23:
#line 260 "dm.y"
{
		Tmp1.opr = '<';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 24:
#line 265 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = '>';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 25:
#line 272 "dm.y"
{
		Tmp1.opr = '&';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 26:
#line 277 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = '&';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 27:
#line 284 "dm.y"
{
		Tmp1.opr = '|';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 28:
#line 289 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = '|';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 29:
#line 296 "dm.y"
{
		Tmp1.opr = '_';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 30:
#line 301 "dm.y"
{
		Tmp1.opr = '!';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 31:
#line 306 "dm.y"
{
		Tmp1.opr = 'l';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 32:
#line 311 "dm.y"
{
		Tmp1.opr = 'L';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 33:
#line 316 "dm.y"
{
		Tmp1.opr = SQRT;
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 34:
#line 321 "dm.y"
{
		Tmp1.opr = SIN;
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 35:
#line 326 "dm.y"
{
		Tmp1.opr = COS;
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 36:
#line 331 "dm.y"
{
		Tmp1.opr = TAN;
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 37:
#line 336 "dm.y"
{
		Tmp1.opr = ATAN;
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 38:
#line 341 "dm.y"
{
		Tmp1.opr = ACOS;
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 39:
#line 346 "dm.y"
{
		Tmp1.opr = ASIN;
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 40:
#line 351 "dm.y"
{
		Tmp1.opr = 'e';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 41:
#line 356 "dm.y"
{
		Tmp1.opr = 'a';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 42:
#line 361 "dm.y"
{
		Tmp1.opr = 'f';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 43:
#line 366 "dm.y"
{
		Tmp1.opr = 'r';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 44:
#line 371 "dm.y"
{
		Tmp1.opr = 'c';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL, yyvsp[0].ex);
		}
break;
case 45:
#line 376 "dm.y"
{
		Tmp1.opr = NTYPE;
		yyval.ex = node (&Tmp1, STRINGOP, ENULL, yyvsp[0].ex);
		}
break;
case 46:
#line 381 "dm.y"
{
		Tmp1.opr = '#';
		yyval.ex = node (&Tmp1, STRINGOP, ENULL, yyvsp[0].ex);
		}
break;
case 47:
#line 386 "dm.y"
{
		Tmp1.opr = '[';
		yyval.ex = node (&Tmp1, STRINGOP, yyvsp[-3].ex, yyvsp[-1].ex);
		}
break;
case 48:
#line 391 "dm.y"
{
		Tmp1.opr = 'C';
		yyval.ex = node (&Tmp1, STRINGOP, yyvsp[-2].ex, yyvsp[0].ex);
		}
break;
case 49:
#line 396 "dm.y"
{
		Tmp1.opr = '!';
		Tmp2.opr = 'C';
		yyval.ex = node (&Tmp1, OPERATOR, ENULL,
			node (&Tmp2, STRINGOP, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 50:
#line 403 "dm.y"
{
		Tmp1.opr = '?';
		Tmp2.opr = ':';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-4].ex,
			node (&Tmp2, OPERATOR,  yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 51:
#line 410 "dm.y"
{
		Tmp1.opr = '?';
		Tmp2.opr = ':';
		yyval.ex = node (&Tmp1, OPERATOR, yyvsp[-4].ex,
			node (&Tmp2, OPERATOR, yyvsp[-2].ex, yyvsp[0].ex));
		}
break;
case 52:
#line 417 "dm.y"
{
		Tmp1.num = yyvsp[0].num;
		yyval.ex = node (&Tmp1, FLOATPTR, ENULL, ENULL);
		}
break;
case 53:
#line 423 "dm.y"
{
		yyval.ex = yyvsp[-1].ex;
		}
break;
case 54:
#line 427 "dm.y"
{
		Tmp1.str = yyvsp[0].str;
		yyval.ex = node (&Tmp1, STRINGPTR, ENULL, ENULL);
		}
break;
#line 1899 "y.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 >= yysslim && yygrowstack())
    {
        goto yyoverflow;
    }
    *++yyssp = yystate;
    *++yyvsp = yyval;
    goto yyloop;
yyoverflow:
    yyerror("yacc stack overflow");
yyabort:
    return (1);
yyaccept:
    return (0);
}
