|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)parser4.c 3.4 4/24/85"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1983 Regents of the University of California, ! 7: * All rights reserved. Redistribution permitted subject to ! 8: * the terms of the Berkeley Software License Agreement. ! 9: */ ! 10: ! 11: #include "parser.h" ! 12: ! 13: /* ! 14: * | 3 ! 15: * ^ 4 ! 16: * & 5 ! 17: * == != 6 ! 18: * < <= > >= 7 ! 19: * << >> 8 ! 20: * + - 9 ! 21: * * / % 10 ! 22: */ ! 23: p_expr3_10(level, v, flag) ! 24: register struct value *v; ! 25: char flag; ! 26: { ! 27: struct value l, r; ! 28: int op; ! 29: char *opname; ! 30: ! 31: if ((level == 10 ? p_expr11(v, flag) ! 32: : p_expr3_10(level + 1, v, flag)) < 0) ! 33: return -1; ! 34: for (;;) { ! 35: switch (level) { ! 36: case 3: ! 37: if (token != T_OR) ! 38: return 0; ! 39: opname = "|"; ! 40: break; ! 41: case 4: ! 42: if (token != T_XOR) ! 43: return 0; ! 44: opname = "^"; ! 45: break; ! 46: case 5: ! 47: if (token != T_AND) ! 48: return 0; ! 49: opname = "&"; ! 50: break; ! 51: case 6: ! 52: if (token == T_EQ) ! 53: opname = "=="; ! 54: else if (token == T_NE) ! 55: opname = "!="; ! 56: else ! 57: return 0; ! 58: break; ! 59: case 7: ! 60: switch (token) { ! 61: case T_LT: ! 62: opname = "<"; ! 63: break; ! 64: case T_LE: ! 65: opname = "<="; ! 66: break; ! 67: case T_GT: ! 68: opname = ">"; ! 69: break; ! 70: case T_GE: ! 71: opname = ">="; ! 72: break; ! 73: default: ! 74: return 0; ! 75: } ! 76: break; ! 77: case 8: ! 78: if (token == T_LS) ! 79: opname = "<<"; ! 80: else if (token == T_RS) ! 81: opname = ">>"; ! 82: else ! 83: return 0; ! 84: break; ! 85: case 9: ! 86: if (token == T_PLUS) ! 87: opname = "+"; ! 88: else if (token == T_MINUS) ! 89: opname = "-"; ! 90: else ! 91: return 0; ! 92: break; ! 93: case 10: ! 94: switch (token) { ! 95: case T_MUL: ! 96: opname = "*"; ! 97: break; ! 98: case T_DIV: ! 99: opname = "/"; ! 100: break; ! 101: case T_MOD: ! 102: opname = "%"; ! 103: break; ! 104: default: ! 105: return 0; ! 106: } ! 107: break; ! 108: } ! 109: l = *v; ! 110: if (l.v_type == V_ERR) ! 111: flag = 0; ! 112: ! 113: op = token; ! 114: (void) s_gettok(); ! 115: if ((level == 10 ? p_expr11(&r, flag) ! 116: : p_expr3_10(level + 1, &r, flag)) < 0) { ! 117: p_synerror(); ! 118: val_free(l); ! 119: return -1; ! 120: } ! 121: ! 122: if (r.v_type == V_ERR) ! 123: flag = 0; ! 124: else switch (op) { ! 125: case T_EQ: ! 126: case T_NE: ! 127: case T_LT: ! 128: case T_LE: ! 129: case T_GT: ! 130: case T_GE: ! 131: case T_PLUS: ! 132: if (l.v_type == V_STR) { ! 133: if (r.v_type == V_NUM) ! 134: if (p_convstr(&r) < 0) ! 135: flag = 0; ! 136: } else ! 137: if (r.v_type == V_STR) ! 138: if (p_convstr(&l) < 0) ! 139: flag = 0; ! 140: break; ! 141: case T_LS: ! 142: case T_RS: ! 143: if (r.v_type == V_STR) { ! 144: char *p = r.v_str; ! 145: r.v_type = V_NUM; ! 146: r.v_num = strlen(p); ! 147: str_free(p); ! 148: } ! 149: break; ! 150: case T_OR: ! 151: case T_XOR: ! 152: case T_AND: ! 153: case T_MINUS: ! 154: case T_MUL: ! 155: case T_DIV: ! 156: case T_MOD: ! 157: default: ! 158: if (l.v_type == V_STR || r.v_type == V_STR) { ! 159: p_error("%s: Numeric operands required.", ! 160: opname); ! 161: flag = 0; ! 162: } ! 163: } ! 164: if (!flag) { ! 165: val_free(l); ! 166: val_free(r); ! 167: v->v_type = V_ERR; ! 168: if (p_abort()) ! 169: return -1; ! 170: continue; ! 171: } ! 172: ! 173: v->v_type = V_NUM; ! 174: switch (op) { ! 175: case T_EQ: ! 176: case T_NE: ! 177: case T_LT: ! 178: case T_LE: ! 179: case T_GT: ! 180: case T_GE: ! 181: if (l.v_type == V_STR) { ! 182: int tmp = strcmp(l.v_str, r.v_str); ! 183: str_free(l.v_str); ! 184: str_free(r.v_str); ! 185: l.v_type = V_NUM; ! 186: l.v_num = tmp; ! 187: r.v_type = V_NUM; ! 188: r.v_num = 0; ! 189: } ! 190: break; ! 191: } ! 192: switch (op) { ! 193: case T_OR: ! 194: v->v_num = l.v_num | r.v_num; ! 195: break; ! 196: case T_XOR: ! 197: v->v_num = l.v_num ^ r.v_num; ! 198: break; ! 199: case T_AND: ! 200: v->v_num = l.v_num & r.v_num; ! 201: break; ! 202: case T_EQ: ! 203: v->v_num = l.v_num == r.v_num; ! 204: break; ! 205: case T_NE: ! 206: v->v_num = l.v_num != r.v_num; ! 207: break; ! 208: case T_LT: ! 209: v->v_num = l.v_num < r.v_num; ! 210: break; ! 211: case T_LE: ! 212: v->v_num = l.v_num <= r.v_num; ! 213: break; ! 214: case T_GT: ! 215: v->v_num = l.v_num > r.v_num; ! 216: break; ! 217: case T_GE: ! 218: v->v_num = l.v_num >= r.v_num; ! 219: break; ! 220: case T_LS: ! 221: if (l.v_type == V_STR) { ! 222: int i; ! 223: if ((i = strlen(l.v_str)) > r.v_num) ! 224: i = r.v_num; ! 225: v->v_str = str_ncpy(l.v_str, i); ! 226: v->v_type = V_STR; ! 227: } else ! 228: v->v_num = l.v_num << r.v_num; ! 229: break; ! 230: case T_RS: ! 231: if (l.v_type == V_STR) { ! 232: int i; ! 233: if ((i = strlen(l.v_str)) > r.v_num) ! 234: i -= r.v_num; ! 235: else ! 236: i = 0; ! 237: v->v_str = str_cpy(l.v_str + i); ! 238: v->v_type = V_STR; ! 239: } else ! 240: v->v_num = l.v_num >> r.v_num; ! 241: break; ! 242: case T_PLUS: ! 243: if (l.v_type == V_STR) { ! 244: v->v_str = str_cat(l.v_str, r.v_str); ! 245: v->v_type = V_STR; ! 246: } else ! 247: v->v_num = l.v_num + r.v_num; ! 248: break; ! 249: case T_MINUS: ! 250: v->v_num = l.v_num - r.v_num; ! 251: break; ! 252: case T_MUL: ! 253: v->v_num = l.v_num * r.v_num; ! 254: break; ! 255: case T_DIV: ! 256: v->v_num = l.v_num / r.v_num; ! 257: break; ! 258: case T_MOD: ! 259: v->v_num = l.v_num % r.v_num; ! 260: break; ! 261: } ! 262: val_free(l); ! 263: val_free(r); ! 264: } ! 265: /*NOTREACHED*/ ! 266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.