|
|
1.1 ! root 1: /* Copyright Bell Telephone Laboratories Whippany, N.J. ! 2: ! 3: * ///////////////////////////////////// ! 4: * ///////////////////////////////////// ! 5: * ////////////// class.c ////////////// ! 6: * /// J. P. Hawkins WH X4610 8C-001 /// ! 7: * ///// Fri Aug 24 16:52:56 1979 ////// ! 8: * ///////////////////////////////////// ! 9: * ///////////////////////////////////// ! 10: * ! 11: * ALGEBRAIC EXPRESSION FIELD and OPERATOR CLASSIFIER ! 12: * and SYNTAX CHECKER ! 13: * (LEXICAL analyzer of sorts) ! 14: * ! 15: * MOD,J.P.Hawkins,31-JAN-81 to recognize string variables and strings ! 16: * MOD,J.P.Hawkins,17-FEB-81 to recognize string functions ! 17: * ! 18: * calling format: ! 19: * ! 20: * field class (or error) = class(&sptr, field); ! 21: * ! 22: * where the ADDRESS of the Pointer sptr MUST be passed ! 23: * the input string pointer will be MODIFIED and ! 24: * LEFT at a point after the field just parsed ! 25: * ! 26: * field = pointer to txtbuf where a null terminated copy ! 27: * of the field just parsed will be left ! 28: * ! 29: * error code = negative of class ! 30: * (i.e. a certain type field was attempted ! 31: * but something illegal happened ! 32: */ ! 33: /* "@(#) class.c: V 1.4 3/1/81" */ ! 34: #include "bas.h" ! 35: #define cpychr() {*fptr++ = **sptr ; *sptr += 1; } ! 36: /* ! 37: * the legdlm(X) test implies that those fields as checked by class ! 38: * may have the defined limited char values following the field ! 39: * the chars 1 through 37(8) are keywords (defined in bed.c) which ! 40: * replace "goto","go to","then","to","step","<=","=<","<",">=","=>",">" ! 41: * "=" or "<>" which is done at input time to compact the code and to ! 42: * simplify run time tests for these combinations ! 43: */ ! 44: #define legdlm(X) ((any(X," ^*+/-)") || (X>='\0' && X <= '\37'))) ! 45: /* ! 46: #define skip00() {while(**sptr == ' ' || **sptr == '\t') *sptr +=1;} ! 47: */ ! 48: #define skip00() {} /* skip00 does nothing */ ! 49: class(sptr, field) ! 50: char **sptr; /* input string pointer */ ! 51: char *field; /* pointer to output field */ ! 52: { ! 53: char *fptr; /* output field pointer */ ! 54: int pcnt; /* parenthesis best counter */ ! 55: #ifdef STRINGS ! 56: int strflg; /* string function flag */ ! 57: #endif ! 58: pcnt = 0; /* init paren nest counter */ ! 59: fptr = field; /* init output field pointer */ ! 60: skip00(); /* skip leading blanks and tabs */ ! 61: /* ! 62: * QUOTED LITERAL STRING? ! 63: */ ! 64: #ifdef STRINGS ! 65: if(**sptr == '"') /* if beginning of string */ ! 66: { ! 67: *sptr += 1; /* bump past 1st quote */ ! 68: while(!(**sptr == '"' || **sptr == '\0')) ! 69: cpychr(); ! 70: if(**sptr == '"') ! 71: { ! 72: *sptr += 1; /* bump past end delimiter */ ! 73: *fptr = '\0'; /* null terminate */ ! 74: return(STCLASS); /* LITERAL STRING CLASS */ ! 75: } ! 76: return(-STCLASS); /* unbalanced quotes */ ! 77: } ! 78: #endif ! 79: if(alpha(**sptr)) /* if 1st char is alpha */ ! 80: { ! 81: cpychr(); /* copy first alpha */ ! 82: if(alpha(**sptr)) /* if second alpha it must be func */ ! 83: { ! 84: /* ! 85: * copy until first non-alphanumeric ! 86: * this must be a FUNCTION FIELD. ! 87: * The first non-alpha numeric must be a '(' ! 88: */ ! 89: while(alpha(**sptr) || num(**sptr)) ! 90: cpychr(); ! 91: #ifdef STRINGS ! 92: strflg = 0; ! 93: if(**sptr == '$') /* string function? */ ! 94: { ! 95: strflg = 1; /* yes */ ! 96: cpychr(); ! 97: } ! 98: #endif ! 99: ! 100: if(**sptr == '(') /* func name followed by '(' */ ! 101: { ! 102: pcnt = 1; /* count first nest deep */ ! 103: cpychr(); /* copy initial '(' */ ! 104: /* ! 105: * scan stuff inside of parens. ! 106: * parens must be balanced to terminate ! 107: * function field. ! 108: */ ! 109: while(pcnt > 0 && **sptr != 0) ! 110: { ! 111: switch(**sptr){ ! 112: case '(': ! 113: pcnt += 1; ! 114: break; ! 115: case ')': ! 116: pcnt -= 1; ! 117: break; ! 118: default: ! 119: break; ! 120: } ! 121: cpychr(); ! 122: } ! 123: if(**sptr == 0 && pcnt != 0) ! 124: { ! 125: *fptr='\0'; ! 126: /* ! 127: * line terminates before ! 128: * function defined. ! 129: */ ! 130: #ifdef STRINGS ! 131: if(strflg) ! 132: return(-SFCLASS); ! 133: else ! 134: #endif ! 135: return(-FNCLASS); ! 136: } ! 137: if(legdlm(**sptr)) ! 138: { ! 139: *fptr = '\0'; /* null term */ ! 140: /* ! 141: * Return function class code ! 142: */ ! 143: #ifdef STRINGS ! 144: if(strflg) ! 145: return(SFCLASS); ! 146: else ! 147: #endif ! 148: return(FNCLASS); ! 149: } ! 150: else /* illegal delim */ ! 151: return(-FNCLASS); ! 152: } ! 153: else ! 154: { ! 155: return(-FNCLASS); /* function def without ! 156: '(' */ ! 157: } ! 158: } ! 159: else /* VARIABLE OR VARIABLE ARRAY FIELD */ ! 160: { ! 161: if(num(**sptr)) ! 162: cpychr(); /* cpy numeric part of var name */ ! 163: #ifdef STRINGS ! 164: strflg = 0; ! 165: if(**sptr == '$') /* string function? */ ! 166: { ! 167: strflg = 1; /* yes */ ! 168: cpychr(); ! 169: } ! 170: #endif ! 171: if(**sptr == '(') /* array paren? */ ! 172: { ! 173: pcnt = 1; /* init paren count */ ! 174: cpychr(); /* copy 1st paren */ ! 175: /* ! 176: * scan stuff inside of parens. ! 177: * parens must be balanced to terminate ! 178: * function field. ! 179: */ ! 180: while(pcnt > 0 && **sptr != 0) ! 181: { ! 182: switch(**sptr){ ! 183: case '(': ! 184: pcnt += 1; ! 185: break; ! 186: case ')': ! 187: pcnt -= 1; ! 188: break; ! 189: default: ! 190: break; ! 191: } ! 192: cpychr(); ! 193: } ! 194: if(**sptr == 0 && pcnt != 0) ! 195: { ! 196: *fptr='\0'; ! 197: /* ! 198: * line terminates before array ! 199: * defined ! 200: */ ! 201: #ifdef STRINGS ! 202: if(strflg) ! 203: return(-SACLASS); ! 204: else ! 205: #endif ! 206: return(-VACLASS); ! 207: } ! 208: if(legdlm(**sptr)) ! 209: { ! 210: *fptr = '\0'; /* null term */ ! 211: #ifdef STRINGS ! 212: if(strflg) ! 213: return(SACLASS); ! 214: else ! 215: #endif ! 216: return(VACLASS); ! 217: } ! 218: else ! 219: { ! 220: *fptr = '\0'; ! 221: /* ill delim */ ! 222: #ifdef STRINGS ! 223: if(strflg) ! 224: return(-SACLASS); ! 225: else ! 226: #endif ! 227: return(-VACLASS); ! 228: } ! 229: } ! 230: else /* VARIABLE NAME FIELD */ ! 231: { ! 232: if(legdlm(**sptr)) /* legal delimiter */ ! 233: { ! 234: *fptr = '\0'; /* null term */ ! 235: #ifdef STRINGS ! 236: if(strflg) ! 237: return(SVCLASS); ! 238: else ! 239: #endif ! 240: return(VRCLASS); ! 241: } ! 242: else ! 243: { ! 244: #ifdef STRINGS ! 245: if(strflg) ! 246: return(-SVCLASS); ! 247: else ! 248: #endif ! 249: return(-VRCLASS); /* ill delim */ ! 250: } ! 251: } ! 252: } ! 253: } ! 254: else /* EITHER NUMERIC OR OPERATOR FIELD */ ! 255: { ! 256: if(num(**sptr) || **sptr == '.') ! 257: { ! 258: cpychr(); /* copy 1st dig of num */ ! 259: while(num(**sptr)) /* copy all consec dig */ ! 260: cpychr(); ! 261: if(**sptr == '.') /* embedded '.' is allowed */ ! 262: { ! 263: cpychr(); /* copy '.' */ ! 264: while(num(**sptr)) /* get digits following ! 265: decimal point */ ! 266: cpychr(); ! 267: } ! 268: if(**sptr == 'e' || **sptr == 'E') ! 269: { ! 270: cpychr(); ! 271: /* ! 272: * HANDLE EXPONENTIAL NOTATION TYPE ! 273: */ ! 274: if(**sptr == '+' || **sptr == '-') ! 275: { ! 276: cpychr(); ! 277: if(num(**sptr)) ! 278: { ! 279: /* copy exponent */ ! 280: while(num(**sptr)) ! 281: cpychr(); ! 282: } ! 283: else ! 284: { ! 285: return(-NMCLASS); ! 286: } ! 287: } ! 288: else ! 289: { ! 290: return(-NMCLASS); ! 291: } ! 292: } ! 293: if(legdlm(**sptr)) /* check for legal delim */ ! 294: { ! 295: *fptr = '\0'; /* null term */ ! 296: return(NMCLASS); /* numeric */ ! 297: } ! 298: else ! 299: return(-NMCLASS); /* ill delim */ ! 300: } ! 301: else /* OPERATOR FIELD */ ! 302: { ! 303: if(any(**sptr, "^*/+-()")) ! 304: { ! 305: cpychr(); /* copy the operator */ ! 306: *fptr = '\0'; /* term with null */ ! 307: return(OPCLASS); /* operator */ ! 308: } ! 309: else ! 310: return(-OPCLASS); /* illegal delim */ ! 311: } ! 312: } ! 313: } ! 314: /* ! 315: * ! 316: * //////// TRUE IF ANY CHARS IN STRING as MATCH c //////// ! 317: */ ! 318: any(c, as) ! 319: int c; ! 320: char *as; ! 321: { ! 322: register char *s; ! 323: ! 324: s = as; ! 325: while(*s) ! 326: if(*s++ == c) ! 327: return(1); ! 328: return(0); ! 329: } ! 330: ! 331: /* ! 332: * //// TRUE IF ALPHA lower case //// ! 333: */ ! 334: alpha(c) ! 335: char c; ! 336: { ! 337: if(c >= 'a' && c <= 'z') ! 338: return(1); ! 339: else ! 340: return(0); ! 341: } ! 342: ! 343: /* ! 344: * //// TRUE IF NUMERIC //// ! 345: */ ! 346: num(c) ! 347: char c; ! 348: { ! 349: if(c >= '0' && c <= '9') ! 350: return(1); ! 351: else ! 352: return(0); ! 353: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.