1: # 2: # include <stdio.h> 3: 4: # include "constants.h" 5: # include "globals.h" 6: 7: /* 8: ** OPERATOR -- process a token starting with an operator 9: ** 10: ** Processes operators, strings, comments, and 11: ** floating constants without a leading 0. 12: ** 13: ** Parameters: 14: ** chr - first character of token {Cmap [chr] == OPATR} 15: ** 16: ** Returns: 17: ** NUMBER or STRING token, or operator token. 18: ** CONTINUE on error. 19: ** 20: ** Side Effects: 21: ** Adds a node to the Symbol space, and returns adress 22: ** in "yylval". 23: ** Opcode is set to the opcode of the operator. 24: ** May backup a character. 25: ** 26: ** Defines: 27: ** operator() 28: ** 29: ** Requires: 30: ** yylval - to return a value for the token 31: ** Cmap - to get character classes 32: ** Opcode - to return opcodes for operators 33: ** Token - for the lex codes of begin comments, and string 34: ** quotes. 35: ** Optab - to search through for operators. 36: ** backup() - to push a char back on the input stream 37: ** getch() - to get a char from the input stream 38: ** number() - to process mantissas 39: ** sequal() - for string equality tests 40: ** string() - for processing strings 41: ** comment() - " " comments 42: ** addsym() - to add a node to symbol space 43: ** yysemerr() - to report illegal operators 44: ** CONTINUE - to have yylex() get next token on error 45: ** 46: ** Called By: 47: ** yylex() 48: ** 49: ** Files: 50: ** globals.h 51: ** 52: ** Diagnostics: 53: ** "bad operator" - an operator was read and not found 54: ** The operator is per force one character, 55: ** and is skipped. 56: ** 57: ** History: 58: ** written - 4/19/78 (marc) 59: ** 60: */ 61: 62: operator(chr) 63: char chr; 64: { 65: register struct optab *op; 66: char opbuf [3]; 67: 68: opbuf [0] = chr; 69: opbuf [1] = getch(); 70: opbuf [2] = '\0'; 71: 72: if (opbuf [0] == '.' && Cmap [opbuf [1]] == NUMBR) 73: { 74: /* floating mantissa w/o leading 0 */ 75: backup(opbuf [1]); 76: return (number(opbuf [0])); 77: } 78: if (Cmap [opbuf [1]] != OPATR) 79: { 80: backup(opbuf [1]); 81: opbuf [1] = '\0'; 82: } 83: /* operator has been reduced to its smallest 84: * possible length, now try to find it in the 85: * operator table [tokens.y] 86: */ 87: for ( ; ; ) 88: { 89: for (op = Optab; op->op_term; op++) 90: if (sequal(op->op_term, opbuf)) 91: break; 92: if (!op->op_term && opbuf [1]) 93: { 94: /* reduce a 2 char operator to 1 char, 95: * and re-search 96: */ 97: backup(opbuf[1]); 98: opbuf [1] = '\0'; 99: continue; 100: } 101: break; 102: } 103: if (op->op_term) 104: { 105: /* string quotes ? */ 106: if (op->op_token == Tokens.sp_quote) 107: return (string(op)); 108: 109: /* comment indicator ? */ 110: if (op->op_token == Tokens.sp_bgncmnt) 111: return (comment()); 112: 113: /* {sequal(opbuf, op->op_term)} */ 114: Opcode = op->op_code; 115: yylval = addsym(op->op_term); 116: return (op->op_token); 117: } 118: yysemerr("bad operator", opbuf); 119: 120: /* operator not found, skip token and try again */ 121: return (CONTINUE); 122: }