00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "mdef.h"
00054
00055 #define TRUE 1
00056 #define FALSE 0
00057 #define EOS (char) 0
00058 #define EQL 0
00059 #define NEQ 1
00060 #define LSS 2
00061 #define LEQ 3
00062 #define GTR 4
00063 #define GEQ 5
00064
00065 static char *nxtch;
00066
00067
00068
00069
00070 #include <setjmp.h>
00071 static jmp_buf expjump;
00072
00073
00074
00075
00076
00077
00078
00079 #define ungetch() nxtch--
00080 #define getch() *nxtch++
00081
00082 int expr(expbuf)
00083 char *expbuf;
00084 {
00085 register int rval;
00086
00087 nxtch = expbuf;
00088 if (setjmp(expjump) != 0)
00089 return (FALSE);
00090 rval = query();
00091 if (skipws() == EOS)
00092 return(rval);
00093 experr("Ill-formed expression");
00094
00095 return(0);
00096 }
00097
00098
00099
00100
00101
00102 int query()
00103 {
00104 register int bool, true_val, false_val;
00105
00106 bool = lor();
00107 if (skipws() != '?') {
00108 ungetch();
00109 return(bool);
00110 }
00111
00112 true_val = query();
00113 if (skipws() != ':')
00114 experr("Bad query");
00115
00116 false_val = query();
00117 return(bool ? true_val : false_val);
00118 }
00119
00120
00121
00122
00123
00124 int lor()
00125 {
00126 register int c, vl, vr;
00127
00128 vl = land();
00129 while ((c = skipws()) == '|' && getch() == '|') {
00130 vr = land();
00131 vl = vl || vr;
00132 }
00133
00134 if (c == '|')
00135 ungetch();
00136 ungetch();
00137 return(vl);
00138 }
00139
00140
00141
00142
00143
00144 int land()
00145 {
00146 register int c, vl, vr;
00147
00148 vl = bor();
00149 while ((c = skipws()) == '&' && getch() == '&') {
00150 vr = bor();
00151 vl = vl && vr;
00152 }
00153
00154 if (c == '&')
00155 ungetch();
00156 ungetch();
00157 return(vl);
00158 }
00159
00160
00161
00162
00163
00164 int bor()
00165 {
00166 register int vl, vr, c;
00167
00168 vl = bxor();
00169 while ((c = skipws()) == '|' && getch() != '|') {
00170 ungetch();
00171 vr = bxor();
00172 vl |= vr;
00173 }
00174
00175 if (c == '|')
00176 ungetch();
00177 ungetch();
00178 return(vl);
00179 }
00180
00181
00182
00183
00184
00185 int bxor()
00186 {
00187 register int vl, vr;
00188
00189 vl = band();
00190 while (skipws() == '^') {
00191 vr = band();
00192 vl ^= vr;
00193 }
00194
00195 ungetch();
00196 return(vl);
00197 }
00198
00199
00200
00201
00202
00203 int band()
00204 {
00205 register int vl, vr, c;
00206
00207 vl = eql();
00208 while ((c = skipws()) == '&' && getch() != '&') {
00209 ungetch();
00210 vr = eql();
00211 vl &= vr;
00212 }
00213
00214 if (c == '&')
00215 ungetch();
00216 ungetch();
00217 return(vl);
00218 }
00219
00220
00221
00222
00223
00224 int eql()
00225 {
00226 register int vl, vr, rel;
00227
00228 vl = relat();
00229 while ((rel = geteql()) != -1) {
00230 vr = relat();
00231
00232 switch (rel) {
00233
00234 case EQL:
00235 vl = (vl == vr);
00236 break;
00237 case NEQ:
00238 vl = (vl != vr);
00239 break;
00240 }
00241 }
00242 return(vl);
00243 }
00244
00245
00246
00247
00248
00249 int relat()
00250 {
00251 register int vl, vr, rel;
00252
00253 vl = shift();
00254 while ((rel = getrel()) != -1) {
00255
00256 vr = shift();
00257 switch (rel) {
00258
00259 case LEQ:
00260 vl = (vl <= vr);
00261 break;
00262 case LSS:
00263 vl = (vl < vr);
00264 break;
00265 case GTR:
00266 vl = (vl > vr);
00267 break;
00268 case GEQ:
00269 vl = (vl >= vr);
00270 break;
00271 }
00272 }
00273 return(vl);
00274 }
00275
00276
00277
00278
00279
00280 int shift()
00281 {
00282 register int vl, vr, c;
00283
00284 vl = primary();
00285 while (((c = skipws()) == '<' || c == '>') && c == getch()) {
00286 vr = primary();
00287
00288 if (c == '<')
00289 vl <<= vr;
00290 else
00291 vl >>= vr;
00292 }
00293
00294 if (c == '<' || c == '>')
00295 ungetch();
00296 ungetch();
00297 return(vl);
00298 }
00299
00300
00301
00302
00303
00304 int primary()
00305 {
00306 register int c, vl, vr;
00307
00308 vl = term();
00309 while ((c = skipws()) == '+' || c == '-') {
00310 vr = term();
00311 if (c == '+')
00312 vl += vr;
00313 else
00314 vl -= vr;
00315 }
00316
00317 ungetch();
00318 return(vl);
00319 }
00320
00321
00322
00323
00324
00325 int term()
00326 {
00327 register int c, vl, vr;
00328
00329 vl = unary();
00330 while ((c = skipws()) == '*' || c == '/' || c == '%') {
00331 vr = unary();
00332
00333 switch (c) {
00334 case '*':
00335 vl *= vr;
00336 break;
00337 case '/':
00338 vl /= vr;
00339 break;
00340 case '%':
00341 vl %= vr;
00342 break;
00343 }
00344 }
00345 ungetch();
00346 return(vl);
00347 }
00348
00349
00350
00351
00352
00353 int unary()
00354 {
00355 register int val, c;
00356
00357 if ((c = skipws()) == '!' || c == '~' || c == '-') {
00358 val = unary();
00359
00360 switch (c) {
00361 case '!':
00362 return(! val);
00363 case '~':
00364 return(~ val);
00365 case '-':
00366 return(- val);
00367 }
00368 }
00369
00370 ungetch();
00371 return(factor());
00372 }
00373
00374
00375
00376
00377
00378 int factor()
00379 {
00380 register int val;
00381
00382 if (skipws() == '(') {
00383 val = query();
00384 if (skipws() != ')')
00385 experr("Bad factor");
00386 return(val);
00387 }
00388
00389 ungetch();
00390 return(constant());
00391 }
00392
00393
00394
00395
00396
00397 int constant()
00398 {
00399
00400
00401
00402
00403 register int i;
00404 register int value;
00405 register char c;
00406 int v[sizeof (int)];
00407
00408 if (skipws() != '\'') {
00409 ungetch();
00410 return(num());
00411 }
00412 for (i = 0; i < sizeof(int); i++) {
00413 if ((c = getch()) == '\'') {
00414 ungetch();
00415 break;
00416 }
00417 if (c == '\\') {
00418 switch (c = getch()) {
00419 case '0':
00420 case '1':
00421 case '2':
00422 case '3':
00423 case '4':
00424 case '5':
00425 case '6':
00426 case '7':
00427 ungetch();
00428 c = num();
00429 break;
00430 case 'n':
00431 c = 012;
00432 break;
00433 case 'r':
00434 c = 015;
00435 break;
00436 case 't':
00437 c = 011;
00438 break;
00439 case 'b':
00440 c = 010;
00441 break;
00442 case 'f':
00443 c = 014;
00444 break;
00445 }
00446 }
00447 v[i] = c;
00448 }
00449 if (i == 0 || getch() != '\'')
00450 experr("Illegal character constant");
00451 for (value = 0; --i >= 0;) {
00452 value <<= 8;
00453 value += v[i];
00454 }
00455 return(value);
00456 }
00457
00458
00459
00460
00461
00462 int num()
00463 {
00464 register int rval, c, base;
00465 int ndig;
00466
00467 ndig = 0;
00468 if ((c = skipws()) == '0') {
00469 c = getch ();
00470 if (c == 'x' || c == 'X') {
00471 base = 16;
00472 c = getch ();
00473 } else {
00474 base = 8;
00475 ndig = 1;
00476 }
00477 } else {
00478 base = 10;
00479 }
00480 rval = 0;
00481 for (;;) {
00482 if (isdigit(c)) c -= '0';
00483 else if (isupper (c)) c -= ('A' - 10);
00484 else if (islower (c)) c -= ('a' - 10);
00485 else break;
00486 if (c < 0 || c >= base)
00487 break;
00488
00489 rval *= base;
00490 rval += c;
00491 c = getch();
00492 ndig++;
00493 }
00494 ungetch();
00495 if (ndig)
00496 return(rval);
00497 experr("Bad constant");
00498
00499 return(0);
00500 }
00501
00502
00503
00504
00505
00506 int geteql()
00507 {
00508 register int c1, c2;
00509
00510 c1 = skipws();
00511 c2 = getch();
00512
00513 switch (c1) {
00514
00515 case '=':
00516 if (c2 != '=')
00517 ungetch();
00518 return(EQL);
00519
00520 case '!':
00521 if (c2 == '=')
00522 return(NEQ);
00523 ungetch();
00524 ungetch();
00525 return(-1);
00526
00527 default:
00528 ungetch();
00529 ungetch();
00530 return(-1);
00531 }
00532 }
00533
00534
00535
00536
00537
00538 int getrel()
00539 {
00540 register int c1, c2;
00541
00542 c1 = skipws();
00543 c2 = getch();
00544
00545 switch (c1) {
00546
00547 case '<':
00548 if (c2 == '=')
00549 return(LEQ);
00550 ungetch();
00551 return(LSS);
00552
00553 case '>':
00554 if (c2 == '=')
00555 return(GEQ);
00556 ungetch();
00557 return(GTR);
00558
00559 default:
00560 ungetch();
00561 ungetch();
00562 return(-1);
00563 }
00564 }
00565
00566
00567
00568
00569 int skipws()
00570 {
00571 register char c;
00572
00573 while ((c = getch()) <= ' ' && c > EOS)
00574 ;
00575 return(c);
00576 }
00577
00578
00579
00580
00581
00582 int experr(msg)
00583 char *msg;
00584 {
00585 printf("mp: %s\n",msg);
00586 longjmp(expjump, -1);
00587 }