#include <sys/cdefs.h>
#ifndef lint
#if 0
static char yysccsid[] = "@(#)yaccpar	1.9 (Berkeley) 02/21/93";
#else
__IDSTRING(yyrcsid, "$NetBSD: skeleton.c,v 1.14 1997/10/20 03:41:16 lukem Exp $");
#endif
#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)
#define YYPREFIX "yy"
#line 40 "expr.y"
#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
#define	USED	__attribute__ ((used))
#elif defined __GNUC__
#define	USED	__attribute__ ((unused))
#else
#define	USED
#endif
#if defined (S42)
static const char sccsid[] USED = "@(#)expr_s42.sl	1.28 (gritter) 5/29/05";
static int	sus = 0;
#elif defined (SU3)
static const char sccsid[] USED = "@(#)expr_su3.sl	1.28 (gritter) 5/29/05";
static int	sus = 3;
#elif defined (SUS)
static const char sccsid[] USED = "@(#)expr_sus.sl	1.28 (gritter) 5/29/05";
static int	sus = 1;
#else
static const char sccsid[] USED = "@(#)expr.sl	1.28 (gritter) 5/29/05";
static int	sus = 0;
#endif

/*	expression command */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libgen.h>
#include <locale.h>
#include <wchar.h>
#include <unistd.h>
#include <limits.h>
#include <ctype.h>
#include <inttypes.h>

#include	"atoll.h"

#define EQL(x,y) !strcmp(x,y)

#define	NUMSZ	25

static char	**Av;
static int	Ac;
static int	Argi;
static int	mb_cur_max;
static char	*progname;
extern int	sysv3;

static char	*Mstring[1];

int		yylex(void);
static char	*_rel(int op, register char *r1, register char *r2);
static char	*_arith(int op, char *r1, char *r2);
static char	*_conj(int op, char *r1, char *r2);
static char	*match(char *s, char *p);
static int	ematch(char *s, register char *p);
static void	errxx(int c);
static int	yyerror(const char *s);
static int	numeric(const char *s);
static int	chars(const char *s, const char *end);
static void	*srealloc(void *, size_t);
static void	*smalloc(size_t);
static char	*numpr(int64_t val);

static char	*substr(char *, const char *, const char *);
static char	*length(const char *);
static char	*eindex(const char *, const char *);

#if defined (SUS) || defined (SU3) || defined (S42)
#include	<regex.h>
static int	nbra;
#else	/* !SUS, !SU3, !S42 */
#include	<regexpr.h>
#endif	/* !SUS, !SU3, !S42 */
#line 116 "expr.y"
typedef union {
	char	*val;
} YYSTYPE;
#line 97 "y.tab.c"
#define OR 257
#define AND 258
#define ADD 259
#define SUBT 260
#define MULT 261
#define DIV 262
#define REM 263
#define EQ 264
#define GT 265
#define GEQ 266
#define LT 267
#define LEQ 268
#define NEQ 269
#define A_STRING 270
#define SUBSTR 271
#define LENGTH 272
#define INDEX 273
#define NOARG 274
#define MATCH 275
#define MCH 276
#define YYERRCODE 256
short yylhs[] = {                                        -1,
    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,
    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
    1,
};
short yylen[] = {                                         2,
    2,    3,    3,    3,    3,    3,    3,    3,    3,    3,
    3,    3,    3,    3,    3,    3,    3,    4,    2,    3,
    1,
};
short yydefred[] = {                                      0,
   21,    0,    0,    0,    0,    0,    0,    0,    0,   19,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    1,    0,    0,   20,
   17,    2,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,   16,   18,
};
short yydgoto[] = {                                       7,
    8,
};
short yysindex[] = {                                    294,
    0,  294,  294,  294,  294,  294,    0, -252,  -40,    0,
  -40,  -40,  193,  294,  294,  294,  294,  294,  294,  294,
  294,  294,  294,  294,  294,  294,    0,  294,  -40,    0,
    0,    0, -233, -215, -206, -206, -275, -275, -275, -197,
 -197, -197, -197, -197, -197,    0,    0,
};
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,    0,    0,    0,    0,    0,
    0,    0,  277,  258,   37,   56,  -20,   -1,   18,   75,
   94,  113,  132,  151,  170,    0,    0,
};
short yygindex[] = {                                      0,
  461,
};
#define YYTABLESIZE 569
short yytable[] = {                                       6,
   28,    0,    0,    0,   14,   15,   16,   17,   18,   19,
   20,   21,   22,   23,   24,   25,   26,    0,    0,   13,
   13,   27,    0,   28,   15,   16,   17,   18,   19,   20,
   21,   22,   23,   24,   25,   26,    0,    0,   14,   14,
    0,    0,   28,   16,   17,   18,   19,   20,   21,   22,
   23,   24,   25,   26,   18,   19,   20,   15,   15,    0,
   28,   16,   17,   18,   19,   20,    0,    0,    0,   28,
    0,    0,    0,    0,    0,    0,   11,   11,   28,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,   12,   12,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    5,    5,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    6,    6,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    7,    7,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    8,    8,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    9,    9,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,   10,
   10,    0,    0,    0,    0,    0,   14,   15,   16,   17,
   18,   19,   20,   21,   22,   23,   24,   25,   26,    1,
    2,    3,    4,   32,    5,   28,   13,   13,   13,   13,
   13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
   13,   13,   13,   13,   13,   14,   14,   14,   14,   14,
   14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
   14,   14,   14,   14,   15,   15,   15,   15,   15,   15,
   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
   15,   15,   15,   11,   11,   11,   11,    4,    4,    0,
   11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
   11,   11,   12,   12,   12,   12,    3,    3,    0,   12,
   12,   12,   12,   12,   12,   12,   12,   12,   12,   12,
   12,    5,    5,    6,    0,    0,    0,    0,    5,    5,
    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
    6,    6,    0,    0,    0,    0,    0,    6,    6,    6,
    6,    6,    6,    6,    6,    6,    6,    6,    6,    7,
    7,    0,    0,    0,    0,    0,    7,    7,    7,    7,
    7,    7,    7,    7,    7,    7,    7,    7,    8,    8,
    0,    0,    0,    0,    0,    8,    8,    8,    8,    8,
    8,    8,    8,    8,    8,    8,    8,    9,    9,    0,
    0,    0,    0,    0,    9,    9,    9,    9,    9,    9,
    9,    9,    9,    9,    9,    9,   10,   10,    0,    0,
    0,    0,    0,   10,   10,   10,   10,   10,   10,   10,
   10,   10,   10,   10,   10,    0,    0,    0,    0,   14,
   15,   16,   17,   18,   19,   20,   21,   22,   23,   24,
   25,   26,    9,   10,   11,   12,   13,    0,   28,   29,
    0,   30,   31,    0,   33,   34,   35,   36,   37,   38,
   39,   40,   41,   42,   43,   44,   45,    0,   46,   47,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    4,    4,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    4,    4,    4,
    4,    4,    4,    3,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    3,    3,    3,    3,
    3,    3,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    1,    2,    3,    4,    0,    5,
};
short yycheck[] = {                                      40,
  276,   -1,   -1,   -1,  257,  258,  259,  260,  261,  262,
  263,  264,  265,  266,  267,  268,  269,   -1,   -1,   40,
   41,  274,   -1,  276,  258,  259,  260,  261,  262,  263,
  264,  265,  266,  267,  268,  269,   -1,   -1,   40,   41,
   -1,   -1,  276,  259,  260,  261,  262,  263,  264,  265,
  266,  267,  268,  269,  261,  262,  263,   40,   41,   -1,
  276,  259,  260,  261,  262,  263,   -1,   -1,   -1,  276,
   -1,   -1,   -1,   -1,   -1,   -1,   40,   41,  276,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   40,   41,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   40,   41,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   40,   41,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   40,   41,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   40,   41,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   40,   41,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   40,
   41,   -1,   -1,   -1,   -1,   -1,  257,  258,  259,  260,
  261,  262,  263,  264,  265,  266,  267,  268,  269,  270,
  271,  272,  273,   41,  275,  276,  257,  258,  259,  260,
  261,  262,  263,  264,  265,  266,  267,  268,  269,  270,
  271,  272,  273,  274,  275,  257,  258,  259,  260,  261,
  262,  263,  264,  265,  266,  267,  268,  269,  270,  271,
  272,  273,  274,  275,  257,  258,  259,  260,  261,  262,
  263,  264,  265,  266,  267,  268,  269,  270,  271,  272,
  273,  274,  275,  257,  258,  259,  260,   40,   41,   -1,
  264,  265,  266,  267,  268,  269,  270,  271,  272,  273,
  274,  275,  257,  258,  259,  260,   40,   41,   -1,  264,
  265,  266,  267,  268,  269,  270,  271,  272,  273,  274,
  275,  257,  258,   40,   -1,   -1,   -1,   -1,  264,  265,
  266,  267,  268,  269,  270,  271,  272,  273,  274,  275,
  257,  258,   -1,   -1,   -1,   -1,   -1,  264,  265,  266,
  267,  268,  269,  270,  271,  272,  273,  274,  275,  257,
  258,   -1,   -1,   -1,   -1,   -1,  264,  265,  266,  267,
  268,  269,  270,  271,  272,  273,  274,  275,  257,  258,
   -1,   -1,   -1,   -1,   -1,  264,  265,  266,  267,  268,
  269,  270,  271,  272,  273,  274,  275,  257,  258,   -1,
   -1,   -1,   -1,   -1,  264,  265,  266,  267,  268,  269,
  270,  271,  272,  273,  274,  275,  257,  258,   -1,   -1,
   -1,   -1,   -1,  264,  265,  266,  267,  268,  269,  270,
  271,  272,  273,  274,  275,   -1,   -1,   -1,   -1,  257,
  258,  259,  260,  261,  262,  263,  264,  265,  266,  267,
  268,  269,    2,    3,    4,    5,    6,   -1,  276,    9,
   -1,   11,   12,   -1,   14,   15,   16,   17,   18,   19,
   20,   21,   22,   23,   24,   25,   26,   -1,   28,   29,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,  257,  258,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,  270,  271,  272,
  273,  274,  275,  257,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  270,  271,  272,  273,
  274,  275,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,  270,  271,  272,  273,   -1,  275,
};
#define YYFINAL 7
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 276
#if YYDEBUG
char *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,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"OR","AND","ADD","SUBT",
"MULT","DIV","REM","EQ","GT","GEQ","LT","LEQ","NEQ","A_STRING","SUBSTR",
"LENGTH","INDEX","NOARG","MATCH","MCH",
};
char *yyrule[] = {
"$accept : expression",
"expression : expr NOARG",
"expr : '(' expr ')'",
"expr : expr OR expr",
"expr : expr AND expr",
"expr : expr EQ expr",
"expr : expr GT expr",
"expr : expr GEQ expr",
"expr : expr LT expr",
"expr : expr LEQ expr",
"expr : expr NEQ expr",
"expr : expr ADD expr",
"expr : expr SUBT expr",
"expr : expr MULT expr",
"expr : expr DIV expr",
"expr : expr REM expr",
"expr : expr MCH expr",
"expr : MATCH expr expr",
"expr : SUBSTR expr expr expr",
"expr : LENGTH expr",
"expr : INDEX expr expr",
"expr : A_STRING",
};
#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 174 "expr.y"

int
main(int argc, char **argv)
{
	extern int	 yyparse(void);

	Ac = argc;
	Argi = 1;
	Av = argv;
	progname = basename(argv[0]);
	if (getenv("SYSV3") != NULL)
		sysv3 = 1;
	setlocale(LC_COLLATE, "");
	setlocale(LC_CTYPE, "");
	mb_cur_max = MB_CUR_MAX;
	if (Av[1] && Av[1][0] == '-' && Av[1][1] == '-' && Av[1][2] == '\0')
		Argi++;
	yyparse();
	/*NOTREACHED*/
	return 0;
}

static const char *operators[] = {
	"|", "&", "+", "-", "*", "/", "%", ":",
	"=", "==", "<", "<=", ">", ">=", "!=",
	"match", "substr", "length", "index",
	"\0"
};

static int op[] = {
	OR, AND, ADD,  SUBT, MULT, DIV, REM, MCH,
	EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
	MATCH, SUBSTR, LENGTH, INDEX
};

int
yylex(void)
{
	register char *p;
	register int i;

	if(Argi >= Ac) return NOARG;

	p = Av[Argi++];

	if((*p == '(' || *p == ')') && p[1] == '\0')
		return (int)*p;
	for(i = 0; *operators[i]; ++i)
		if(EQL(operators[i], p))
			return op[i];

	yylval.val = p;
	return A_STRING;
}

static char *
_rel(int op, register char *r1, register char *r2)
{
	register int64_t i;

	if (numeric(r1) && numeric(r2))
		i = atoll(r1) - atoll(r2);
	else
		i = strcoll(r1, r2);
	switch(op) {
	case EQ: i = i==0; break;
	case GT: i = i>0; break;
	case GEQ: i = i>=0; break;
	case LT: i = i<0; break;
	case LEQ: i = i<=0; break;
	case NEQ: i = i!=0; break;
	}
	return i? "1": "0";
}

static char *
_arith(int op, char *r1, char *r2)
{
	int64_t i1, i2;
	register char *rv;

	if (!numeric(r1) || !numeric(r2))
		yyerror("non-numeric argument");
	i1 = atoll(r1);
	i2 = atoll(r2);

	switch(op) {
	case ADD: i1 = i1 + i2; break;
	case SUBT: i1 = i1 - i2; break;
	case MULT: i1 = i1 * i2; break;
	case DIV:
		if (i2 == 0) yyerror("division by zero");
		i1 = i1 / i2; break;
	case REM: i1 = i1 % i2; break;
	}
	rv = numpr(i1);
	return rv;
}

static char *
_conj(int op, char *r1, char *r2)
{
	register char *rv = NULL;

	switch(op) {

	case OR:
		if(EQL(r1, "0")
		|| EQL(r1, ""))
			if(EQL(r2, "0")
			|| EQL(r2, ""))
				rv = "0";
			else
				rv = r2;
		else
			rv = r1;
		break;
	case AND:
		if(EQL(r1, "0")
		|| EQL(r1, ""))
			rv = "0";
		else if(EQL(r2, "0")
		|| EQL(r2, ""))
			rv = "0";
		else
			rv = r1;
		break;
	}
	return rv;
}

static char *
match(char *s, char *p)
{
	register char *rv;
	int	gotcha;

	gotcha = ematch(s, p);
	if(nbra) {
		if (gotcha) {
			rv = smalloc(strlen(Mstring[0])+1);
			strcpy(rv, Mstring[0]);
		} else
			rv = "";
	} else
		rv = numpr(gotcha);
	return rv;
}

#if defined (SUS) || defined (SU3) || defined (S42)
static int
ematch(char *s, register char *p)
{
	regex_t	re;
	register int	num;
	regmatch_t	bralist[2];
	int	reflags = 0, val;

#ifdef	REG_ANGLES
	reflags |= REG_ANGLES;
#endif
#if defined (SU3) && defined (REG_AVOIDNULL)
	reflags |= REG_AVOIDNULL;
#endif
	if ((num = regcomp(&re, p, reflags)) != 0)
		errxx(0);
	nbra = re.re_nsub;
	if (regexec(&re, s, 2, bralist, 0) == 0 && bralist[0].rm_so == 0) {
		if (re.re_nsub >= 1) {
			num = bralist[1].rm_eo - bralist[1].rm_so;
			Mstring[0] = srealloc(Mstring[0], num + 1);
			strncpy(Mstring[0], s + bralist[1].rm_so, num);
			Mstring[0][num] = '\0';
		}
		val = chars(s, &s[bralist[0].rm_eo]);
	} else
		val = 0;
	regfree(&re);
	return val;
}
#else	/* !SUS, !SU3, !S42 */
static int
ematch(char *s, register char *p)
{
	char *expbuf;
	register int num, val;

	if ((expbuf = compile(p, NULL, NULL)) == NULL)
		errxx(regerrno);
	if(nbra > 1)
		yyerror("Too many '\\('s");
	if(advance(s, expbuf)) {
		if(nbra == 1) {
			p = braslist[0];
			num = braelist[0] ? braelist[0] - p : 0;
			Mstring[0] = srealloc(Mstring[0], num + 1);
			strncpy(Mstring[0], p, num);
			Mstring[0][num] = '\0';
		}
		val = chars(s, loc2);
	} else
		val = 0;
	free(expbuf);
	return(val);
}
#endif	/* !SUS, !SU3, !S42 */

/*ARGSUSED*/
static void
errxx(int c)
{
	yyerror("RE error");
}

static int
yyerror(const char *s)
{
	fprintf(stderr, "%s: %s\n", progname, s);
	exit(2);
}

static int
numeric(const char *s)
{
	if (*s == '-')
		s++;
	if (!isdigit(*s & 0377))
		return 0;
	do
		s++;
	while (isdigit(*s & 0377));
	return (*s == '\0');
}

static int
chars(const char *s, const char *end)
{
	int	count = 0, n;
	wchar_t	wc;

	if (mb_cur_max > 1) {
		while (s < end) {
			if ((n = mbtowc(&wc, s, MB_LEN_MAX)) >= 0)
				count++;
			s += n > 0 ? n : 1;
		}
	} else
		count = end - s;
	return count;
}

static void *
srealloc(void *vp, size_t nbytes)
{
	void *p;

	if ((p = realloc(vp, nbytes)) == NULL) {
		write(2, "no memory\n", 10);
		exit(077);
	}
	return p;
}

static void *
smalloc(size_t nbytes)
{
	return srealloc(NULL, nbytes);
}

static char *
numpr(int64_t val)
{
	char	*rv;
	int	ret;

	rv = smalloc(NUMSZ);
	ret = snprintf(rv, NUMSZ, "%lld", (long long)val);
	if (ret < 0 || ret >= NUMSZ) {
		rv = srealloc(rv, ret + 1);
		ret = snprintf(rv, ret, "%lld", (long long)val);
		if (ret < 0)
			yyerror("illegal number");
	}
	return rv;
}

#define	next(wc, s, n) (mb_cur_max > 1 && *(s) & 0200 ? \
			((n) = mbtowc(&(wc), (s), mb_cur_max), \
			 (n) = ((n) > 0 ? (n) : (n) < 0 ? illseq() : 1)) :\
		((wc) = *(s) & 0377, (n) = 1))

static int
illseq(void)
{
	yyerror("illegal byte sequence");
	/*NOTREACHED*/
	return 0;
}

static char *
substr(char *v, const char *s, const char *w)
{
	long si, wi;
	char *res;
	wchar_t wc;
	int n;

#ifndef	S42
	if (sysv3 == 0)
		yyerror("syntax error");
#endif
	si = atoll(s);
	wi = atoll(w);
	while (--si)
		if (*v) {
			next(wc, v, n);
			v += n;
		}
	res = v;
	while (wi--)
		if (*v) {
			next(wc, v, n);
			v += n;
		}
	*v = '\0';
	return res;
}

static char *
length(const char *s)
{
	long i = 0;
	char *rv;
	wchar_t wc;
	int n;

#ifndef	S42
	if (sysv3 == 0)
		yyerror("syntax error");
#endif
	while (*s) {
		next(wc, s, n);
		s += n;
		++i;
	}
	rv = numpr(i);
	return rv;
}

static char *
eindex(const char *s, const char *t)
{
	long i, j, x;
	char *rv;
	wchar_t ws, wt;
	int ns, nt;

#ifndef	S42
	if (sysv3 == 0)
		yyerror("syntax error");
#endif
	for (i = 0, x = 0; s[i]; x++, i += ns) {
		next(ws, &s[i], ns);
		for (j = 0; t[j]; j += nt) {
			next(wt, &t[j], nt);
			if (ws == wt) {
				rv = numpr(++x);
				return rv;
			}
		}
	}
	return "0";
}
#line 715 "y.tab.c"
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
int yyparse __P((void));
static int yygrowstack __P((void));
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;
    if ((newss = (short *)realloc(yyss, newsize * sizeof *newss)) == NULL)
        return -1;
    yyss = newss;
    yyssp = newss + i;
    if ((newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *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
int
yyparse()
{
    int yym, yyn, yystate;
#if YYDEBUG
    char *yys;

    if ((yys = getenv("YYDEBUG")) != NULL)
    {
        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]) != 0) goto yyreduce;
    if (yychar < 0)
    {
        if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("%sdebug: state %d, reading %d (%s)\n",
                    YYPREFIX, yystate, yychar, yys);
        }
#endif
    }
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
#if YYDEBUG
        if (yydebug)
            printf("%sdebug: state %d, shifting to state %d\n",
                    YYPREFIX, yystate, yytable[yyn]);
#endif
        if (yyssp >= 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;
    goto yynewerror;
yynewerror:
    yyerror("syntax error");
    goto yyerrlab;
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 139 "expr.y"
{
			if (sus && numeric(yyvsp[-1].val)) {
				int64_t	n;
				n = atoll(yyvsp[-1].val);
				printf("%lld\n", n);
				exit(n == 0);
			} else
				puts(yyvsp[-1].val);
			exit((!strcmp(yyvsp[-1].val,"0")||!strcmp(yyvsp[-1].val,"\0"))? 1: 0);
			}
break;
case 2:
#line 152 "expr.y"
{ yyval.val = yyvsp[-1].val; }
break;
case 3:
#line 153 "expr.y"
{ yyval.val = _conj(OR, yyvsp[-2].val, yyvsp[0].val); }
break;
case 4:
#line 154 "expr.y"
{ yyval.val = _conj(AND, yyvsp[-2].val, yyvsp[0].val); }
break;
case 5:
#line 155 "expr.y"
{ yyval.val = _rel(EQ, yyvsp[-2].val, yyvsp[0].val); }
break;
case 6:
#line 156 "expr.y"
{ yyval.val = _rel(GT, yyvsp[-2].val, yyvsp[0].val); }
break;
case 7:
#line 157 "expr.y"
{ yyval.val = _rel(GEQ, yyvsp[-2].val, yyvsp[0].val); }
break;
case 8:
#line 158 "expr.y"
{ yyval.val = _rel(LT, yyvsp[-2].val, yyvsp[0].val); }
break;
case 9:
#line 159 "expr.y"
{ yyval.val = _rel(LEQ, yyvsp[-2].val, yyvsp[0].val); }
break;
case 10:
#line 160 "expr.y"
{ yyval.val = _rel(NEQ, yyvsp[-2].val, yyvsp[0].val); }
break;
case 11:
#line 161 "expr.y"
{ yyval.val = _arith(ADD, yyvsp[-2].val, yyvsp[0].val); }
break;
case 12:
#line 162 "expr.y"
{ yyval.val = _arith(SUBT, yyvsp[-2].val, yyvsp[0].val); }
break;
case 13:
#line 163 "expr.y"
{ yyval.val = _arith(MULT, yyvsp[-2].val, yyvsp[0].val); }
break;
case 14:
#line 164 "expr.y"
{ yyval.val = _arith(DIV, yyvsp[-2].val, yyvsp[0].val); }
break;
case 15:
#line 165 "expr.y"
{ yyval.val = _arith(REM, yyvsp[-2].val, yyvsp[0].val); }
break;
case 16:
#line 166 "expr.y"
{ yyval.val = match(yyvsp[-2].val, yyvsp[0].val); }
break;
case 17:
#line 167 "expr.y"
{ yyval.val = match(yyvsp[-1].val, yyvsp[0].val); }
break;
case 18:
#line 168 "expr.y"
{ yyval.val = substr(yyvsp[-2].val, yyvsp[-1].val, yyvsp[0].val); }
break;
case 19:
#line 169 "expr.y"
{ yyval.val = length(yyvsp[0].val); }
break;
case 20:
#line 170 "expr.y"
{ yyval.val = eindex(yyvsp[-1].val, yyvsp[0].val); }
break;
#line 970 "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);
}


syntax highlighted by Code2HTML, v. 0.9.1