* Copyright (c) 1991 The Regents of the University of California.
* %sccs.include.proprietary.c%
/* Yacc productions for "expr" command: */
%token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ
%token A_STRING SUBSTR LENGTH INDEX NOARG MATCH
/* operators listed below in increasing precedence: */
%left EQ LT GT GEQ LEQ NEQ
/* a single `expression' is evaluated and printed: */
expression: expr NOARG = {
exit((!strcmp($1,"0")||!strcmp($1,"\0"))? 1: 0);
expr: '(' expr ')' = { $$ = $2; }
| expr OR expr = { $$ = conj(OR, $1, $3); }
| expr AND expr = { $$ = conj(AND, $1, $3); }
| expr EQ expr = { $$ = rel(EQ, $1, $3); }
| expr GT expr = { $$ = rel(GT, $1, $3); }
| expr GEQ expr = { $$ = rel(GEQ, $1, $3); }
| expr LT expr = { $$ = rel(LT, $1, $3); }
| expr LEQ expr = { $$ = rel(LEQ, $1, $3); }
| expr NEQ expr = { $$ = rel(NEQ, $1, $3); }
| expr ADD expr = { $$ = arith(ADD, $1, $3); }
| expr SUBT expr = { $$ = arith(SUBT, $1, $3); }
| expr MULT expr = { $$ = arith(MULT, $1, $3); }
| expr DIV expr = { $$ = arith(DIV, $1, $3); }
| expr REM expr = { $$ = arith(REM, $1, $3); }
| expr MCH expr = { $$ = match($1, $3); }
| MATCH expr expr = { $$ = match($2, $3); }
| SUBSTR expr expr expr = { $$ = substr($2, $3, $4); }
| LENGTH expr = { $$ = length($2); }
| INDEX expr expr = { $$ = index($2, $3); }
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
static char sccsid[] = "@(#)expr.y 5.3 (Berkeley) %G%";
#define error(c) errxx(c)
#define EQL(x,y) !strcmp(x,y)
main(argc, argv) char **argv; {
char *operators[] = { "|", "&", "+", "-", "*", "/", "%", ":",
"=", "==", "<", "<=", ">", ">=", "!=",
"match", "substr", "length", "index", "\0" };
int op[] = { OR, AND, ADD, SUBT, MULT, DIV, REM, MCH,
EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
MATCH, SUBSTR, LENGTH, INDEX };
if(Argi >= Ac) return NOARG;
if(*p == '(' || *p == ')')
for(i = 0; *operators[i]; ++i)
char *rel(op, r1, r2) register char *r1, *r2; {
if(ematch(r1, "-*[0-9]*$") && ematch(r2, "[0-9]*$"))
case EQ: i = i==0; break;
case GEQ: i = i>=0; break;
case LEQ: i = i<=0; break;
case NEQ: i = i!=0; break;
char *arith(op, r1, r2) char *r1, *r2; {
if(!((ematch(r1, "[0-9]*$") || ematch(r1, "-[0-9]*$")) &&
(ematch(r2, "[0-9]*$") || ematch(r2, "-[0-9]*$"))))
yyerror("non-numeric argument");
case ADD: i1 = i1 + i2; break;
case SUBT: i1 = i1 - i2; break;
case MULT: i1 = i1 * i2; break;
yyerror("Divide by zero");
yyerror("Remainder by zero");
(void)sprintf(rv, "%ld", i1);
char *conj(op, r1, r2) char *r1, *r2; {
char *substr(v, s, w) char *v, *s, *w; {
char *length(s) register char *s; {
(void)sprintf(rv, "%d", i);
char *index(s, t) char *s, *t; {
(void)sprintf(rv = malloc(8), "%d", ++i);
(void)sprintf(rv = malloc(8), "%d", ematch(s, p));
rv = malloc(strlen(Mstring[0])+1);
#define INIT register char *sp = instring;
#define ERROR(c) errxx(c)
static char expbuf[ESIZE];
extern char *braslist[], *braelist[], *loc2;
compile(p, expbuf, &expbuf[ESIZE], 0);
yyerror("Too many '\\('s");
strncpy(Mstring[0], p, num);
#define PLACE(c) ep[c >> 3] |= bittab[c & 07]
#define ISTHERE(c) (ep[c >> 3] & bittab[c & 07])
char *loc1, *loc2, *locs;
compile(instring, ep, endbuf, seof)
INIT /* Dependent declarations and initializations */
char bracket[NBRA], *bracketp;
if((c = GETC()) == eof) {
circf = closed = nbra = 0;
if((c = GETC()) != '*' && ((c != '\\') || (PEEKC() != '{')))
if (lastep==0 || *lastep==CBRA || *lastep==CKET)
if((c = GETC()) == '^') {
if(c == '\0' || c == '\n')
if(c == '-' && lc != 0) {
if ((c = GETC()) == ']') {
} while((c = GETC()) != ']');
for(cclcnt = 0; cclcnt < 16; cclcnt++)
if(lastep == (char *) (0))
if ('0' <= c && c <= '9')
} while(((c = GETC()) != '\\') && (c != ','));
goto nlim; /* get 2'nd number */
if(!cflg) /* one number */
else if((ep[-1] & 0377) < (ep[-2] & 0377))
if(c >= '1' && c <= '9') {
/* Drop through to default to use \ to turn off special chars */
/* fast check for first character */
for (;;) switch (*ep++) {
ct = braelist[*ep++] - bbeg;
ct = braelist[*ep++] - bbeg;
while(ecmp(bbeg, lp, ct))
if(advance(lp, ep)) return(1);
size = (*str & 0377) == 255 ? 20000 : (*str & 0377) - low;
if(a == b) /* should have been caught in compile() */
if(*a++ != *b++) return(0);
fprintf(stderr, "%s\n", s);