Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Yacc productions for "expr" command: */
2
 
3
%token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ
4
%token A_STRING SUBSTR LENGTH INDEX NOARG MATCH
5
 
6
/* operators listed below in increasing precedence: */
7
%left OR
8
%left AND
9
%left EQ LT GT GEQ LEQ NEQ
10
%left ADD SUBT
11
%left MULT DIV REM
12
%left MCH
13
%left MATCH
14
%left SUBSTR
15
%left LENGTH INDEX
16
 
17
%{
18
#define YYSTYPE charp
19
 
20
typedef char *charp;
21
%}
22
 
23
%%
24
 
25
/* a single `expression' is evaluated and printed: */
26
 
27
expression:	expr NOARG = {
28
			prt(1, $1);
29
			exit((!strcmp($1,"0")||!strcmp($1,"\0"))? 1: 0);
30
			}
31
	;
32
 
33
 
34
expr:	'(' expr ')' = { $$ = $2; }
35
	| expr OR expr   = { $$ = conj(OR, $1, $3); }
36
	| expr AND expr   = { $$ = conj(AND, $1, $3); }
37
	| expr EQ expr   = { $$ = rel(EQ, $1, $3); }
38
	| expr GT expr   = { $$ = rel(GT, $1, $3); }
39
	| expr GEQ expr   = { $$ = rel(GEQ, $1, $3); }
40
	| expr LT expr   = { $$ = rel(LT, $1, $3); }
41
	| expr LEQ expr   = { $$ = rel(LEQ, $1, $3); }
42
	| expr NEQ expr   = { $$ = rel(NEQ, $1, $3); }
43
	| expr ADD expr   = { $$ = arith(ADD, $1, $3); }
44
	| expr SUBT expr   = { $$ = arith(SUBT, $1, $3); }
45
	| expr MULT expr   = { $$ = arith(MULT, $1, $3); }
46
	| expr DIV expr   = { $$ = arith(DIV, $1, $3); }
47
	| expr REM expr   = { $$ = arith(REM, $1, $3); }
48
	| expr MCH expr	 = { $$ = match($1, $3); }
49
	| MATCH expr expr = { $$ = match($2, $3); }
50
	| SUBSTR expr expr expr = { $$ = substr($2, $3, $4); }
51
	| LENGTH expr       = { $$ = length($2); }
52
	| INDEX expr expr = { $$ = index($2, $3); }
53
	| A_STRING
54
	;
55
%%
56
/*	expression command */
57
#include <stdio.h>
58
/* get rid of yacc debug printf's */
59
#define printf
60
#define ESIZE	512
61
#define error(c)	errxx(c)
62
#define EQL(x,y) !strcmp(x,y)
63
long atol();
64
char *ltoa();
65
char	**Av;
66
int	Ac;
67
int	Argi;
68
 
69
char Mstring[1][128];
70
char *malloc();
71
extern int nbra;
72
int yyparse(void);
73
 
74
main(argc, argv) char **argv; {
75
	Ac = argc;
76
	Argi = 1;
77
	Av = argv;
78
	yyparse();
79
}
80
 
81
char *operator[] = { "|", "&", "+", "-", "*", "/", "%", ":",
82
	"=", "==", "<", "<=", ">", ">=", "!=",
83
	"match", "substr", "length", "index", "\0" };
84
int op[] = { OR, AND, ADD,  SUBT, MULT, DIV, REM, MCH,
85
	EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
86
	MATCH, SUBSTR, LENGTH, INDEX };
87
yylex() {
88
	register char *p;
89
	register i;
90
 
91
	if(Argi >= Ac) return NOARG;
92
 
93
	p = Av[Argi++];
94
 
95
	if(*p == '(' || *p == ')')
96
		return (int)*p;
97
	for(i = 0; *operator[i]; ++i)
98
		if(EQL(operator[i], p))
99
			return op[i];
100
 
101
	yylval = p;
102
	return A_STRING;
103
}
104
 
105
char *rel(op, r1, r2) register char *r1, *r2; {
106
	register i;
107
 
108
	if(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$"))
109
		i = atol(r1) - atol(r2);
110
	else
111
		i = strcmp(r1, r2);
112
	switch(op) {
113
	case EQ: i = i==0; break;
114
	case GT: i = i>0; break;
115
	case GEQ: i = i>=0; break;
116
	case LT: i = i<0; break;
117
	case LEQ: i = i<=0; break;
118
	case NEQ: i = i!=0; break;
119
	}
120
	return i? "1": "0";
121
}
122
 
123
char *arith(op, r1, r2) char *r1, *r2; {
124
	long i1, i2;
125
	register char *rv;
126
 
127
	if(!(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$")))
128
		yyerror("non-numeric argument");
129
	i1 = atol(r1);
130
	i2 = atol(r2);
131
 
132
	switch(op) {
133
	case ADD: i1 = i1 + i2; break;
134
	case SUBT: i1 = i1 - i2; break;
135
	case MULT: i1 = i1 * i2; break;
136
	case DIV: i1 = i1 / i2; break;
137
	case REM: i1 = i1 % i2; break;
138
	}
139
	rv = malloc(16);
140
	strcpy(rv, ltoa(i1));
141
	return rv;
142
}
143
char *conj(op, r1, r2) char *r1, *r2; {
144
	register char *rv;
145
 
146
	switch(op) {
147
 
148
	case OR:
149
		if(EQL(r1, "0")
150
		|| EQL(r1, ""))
151
			if(EQL(r2, "0")
152
			|| EQL(r2, ""))
153
				rv = "0";
154
			else
155
				rv = r2;
156
		else
157
			rv = r1;
158
		break;
159
	case AND:
160
		if(EQL(r1, "0")
161
		|| EQL(r1, ""))
162
			rv = "0";
163
		else if(EQL(r2, "0")
164
		|| EQL(r2, ""))
165
			rv = "0";
166
		else
167
			rv = r1;
168
		break;
169
	}
170
	return rv;
171
}
172
 
173
char *substr(v, s, w) char *v, *s, *w; {
174
register si, wi;
175
register char *res;
176
 
177
	si = atol(s);
178
	wi = atol(w);
179
	while(--si) if(*v) ++v;
180
 
181
	res = v;
182
 
183
	while(wi--) if(*v) ++v;
184
 
185
	*v = '\0';
186
	return res;
187
}
188
 
189
char *length(s) register char *s; {
190
	register i = 0;
191
	register char *rv;
192
 
193
	while(*s++) ++i;
194
 
195
	rv = malloc(8);
196
	strcpy(rv, ltoa((long)i));
197
	return rv;
198
}
199
 
200
char *index(s, t) char *s, *t; {
201
	register i, j;
202
	register char *rv;
203
 
204
	for(i = 0; s[i] ; ++i)
205
		for(j = 0; t[j] ; ++j)
206
			if(s[i]==t[j]) {
207
				strcpy(rv=malloc(8), ltoa((long)++i));
208
				return rv;
209
			}
210
	return "0";
211
}
212
 
213
char *match(s, p)
214
{
215
	register char *rv;
216
 
217
	strcpy(rv=malloc(8), ltoa((long)ematch(s, p)));
218
	if(nbra) {
219
		rv = malloc(strlen(Mstring[0])+1);
220
		strcpy(rv, Mstring[0]);
221
	}
222
	return rv;
223
}
224
 
225
#define INIT	register char *sp = instring;
226
#define GETC()		(*sp++)
227
#define PEEKC()		(*sp)
228
#define UNGETC(c)	(--sp)
229
#define RETURN(c)	return
230
#define ERROR(c)	errxx(c)
231
 
232
 
233
ematch(s, p)
234
char *s;
235
register char *p;
236
{
237
	static char expbuf[ESIZE];
238
	char *compile();
239
	register num;
240
	extern char *braslist[], *braelist[], *loc2;
241
 
242
	compile(p, expbuf, &expbuf[ESIZE], 0);
243
	if(nbra > 1)
244
		yyerror("Too many '\\('s");
245
	if(advance(s, expbuf)) {
246
		if(nbra == 1) {
247
			p = braslist[0];
248
			num = braelist[0] - p;
249
			strncpy(Mstring[0], p, num);
250
			Mstring[0][num] = '\0';
251
		}
252
		return(loc2-s);
253
	}
254
	return(0);
255
}
256
 
257
errxx(c)
258
{
259
	yyerror("RE error");
260
}
261
 
262
#include  "regexp.h"
263
yyerror(s)
264
 
265
{
266
	write(2, "expr: ", 6);
267
	prt(2, s);
268
	exit(2);
269
}
270
prt(fd, s)
271
char *s;
272
{
273
	write(fd, s, strlen(s));
274
	write(fd, "\n", 1);
275
}
276
char *ltoa(l)
277
long l;
278
{
279
	static char str[20];
280
	register char *sp = &str[18];
281
	register i;
282
	register neg = 0;
283
 
284
	if(l < 0)
285
		++neg, l *= -1;
286
	str[19] = '\0';
287
	do {
288
		i = l % 10;
289
		*sp-- = '0' + i;
290
		l /= 10;
291
	} while(l);
292
	if(neg)
293
		*sp-- = '-';
294
	return ++sp;
295
}