/* ** OPERATOR -- process a token starting with an operator ** ** Processes operators, strings, comments, and ** floating constants without a leading 0. ** ** Parameters: ** chr - first character of token {equel_cmap (chr) == OPATR} ** ** Returns: ** NUMBER or STRING token, or operator token. ** CONTINUE on error. ** ** Side Effects: ** Adds a node to the Symbol space, and returns adress ** in "yylval". ** Opcode is set to the opcode of the operator. ** May backup a character. */ int operator(char chr) { register struct optab *op; char opbuf [3]; opbuf [0] = chr; opbuf [1] = getch(); opbuf [2] = '\0'; if (opbuf [0] == '.' && equel_cmap(opbuf[1]) == NUMBR) { /* floating mantissa w/o leading 0 */ backup(opbuf [1]); return (number(opbuf [0])); } if (equel_cmap(opbuf[1]) != OPATR) { backup(opbuf [1]); opbuf [1] = '\0'; } /* operator has been reduced to its smallest * possible length, now try to find it in the * operator table [tokens.y] */ for ( ; ; ) { for (op = Optab; op->op_term; op++) if (strcmp(op->op_term, opbuf) == 0) break; if (!op->op_term && opbuf [1]) { /* reduce a 2 char operator to 1 char, * and re-search */ backup(opbuf[1]); opbuf [1] = '\0'; continue; } break; } if (op->op_term) { /* string quotes ? */ if (op->op_token == Tokens.sp_quote) return (string(op)); /* comment indicator ? */ if (op->op_token == Tokens.sp_bgncmnt) return (comment()); /* {strcmp(opbuf, op->op_term) == 0} */ Opcode = op->op_code; yylval.u_dn = addsym(op->op_term); return (op->op_token); } yysemerr("bad operator", opbuf); /* operator not found, skip token and try again */ return (CONTINUE); }
/* ** COMMENT.C -- routine to scan comments inside an EQL statement ** ** Uses the endcmnt token code to find the endcmnt ** terminal string, then reads the input until it sees this ** terminal (must be <= 2 characters), returning EOF_TOK and ** giving an error diagnostic if end-of-file is encountered. ** ** Returns: ** CONTINUE -- valid comment ** EOF_TOK -- EOF in comment ** ** Side Effects: ** deletes comments from within an EQL statement ** */ comment() { register int i; register int l; register struct optab *op; char buf[3]; /* find end of comment operator */ for (op = Optab; op->op_term; op++) if (op->op_token == Tokens.sp_endcmnt) break; if (!op->op_term) AAsyserr(13000); /* scan for the end of comment */ l = AAlength(op->op_term); if (l > sizeof buf - 1) AAsyserr(13001, l, op->op_term, sizeof buf -1); /* fill buffer to length of endmnt terminal */ for (i = 0; i < l; i++) { if ((buf[i] = getch()) == EOF_TOK) { nontermcom : /* non-terminated comment */ yysemerr("premature EOF encountered in comment", (char *) 0); return (EOF_TOK); } } /* shift on input until endcmnt */ while (!AAbequal(buf, op->op_term, l)) { for (i = 0; i < l - 1; i++) buf[i] = buf[i + 1]; if ((buf[l - 1] = getch()) == EOF_TOK) goto nontermcom; } return (CONTINUE); }