📄 token.c
字号:
} } setprompt(conf->prompt1);}/* * Continue to eat up a the current line * Typically a #! will require the rest of the line to be eaten as if * it were a comment. */static voideatline(void){ int ch; /* chars being eaten */ do { ch = nextchar(); } while (ch != '\n' && ch != EOF && ch != '\0'); reread();}/* * Read in a string and add it to the literal string pool. * The leading single or double quote has been read in at this point. */static voideatstring(int quotechar){ register char *cp; /* current character address */ int ch, cch; /* current character */ int i; /* index */ char buf[STRBUFSIZE]; /* buffer for string */ long len; /* length in buffer */ long totlen; /* total length, including '\0' */ char *str; BOOL done; str = buf; totlen = 0; done = FALSE; while (!done) { cp = buf; len = 0; while (!done && len < STRBUFSIZE) { ch = nextchar(); switch (ch) { case '\n': if (!newlines) break; case EOF: reread(); scanerror(T_NULL, "Unterminated string constant"); done = TRUE; ch = '\0'; break; case '\\': ch = nextchar(); if (isoctal(ch)) { ch = ch - '0'; for (i = 2; i > 0; i--) { cch = nextchar(); if (!isoctal(cch)) break; ch = 8 * ch + cch - '0'; } ch &= 0xff; if (i > 0) reread(); break; } switch (ch) { case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; case 'b': ch = '\b'; break; case 'f': ch = '\f'; break; case 'v': ch = '\v'; break; case 'a': ch = '\007'; break; case 'e': ch = '\033'; break; case '\n': setprompt(conf->prompt2); continue; case EOF: reread(); continue; case 'x': ch = 0; for (i = 2; i > 0; i--) { cch = nextchar(); if (isdigit(cch)) ch = 16 * ch + cch - '0'; else if (cch >= 'a' && cch <= 'f') ch = 16 * ch + 10 + cch - 'a'; else if (cch >= 'A' && cch <= 'F') ch = 16 * ch + 10 + cch - 'A'; else break; } if (i > 0) reread(); } break; case '"': case '\'': if (ch == quotechar) { for (;;) { ch = nextchar(); if (ch != ' ' && ch != '\t' && (ch != '\n' || newlines)) break; } if (ch == '"' || ch == '\'') { quotechar = ch; continue; } reread(); done = TRUE; ch = '\0'; } break; } *cp++ = (char) ch; len++; } if (!done || totlen) { if (totlen) str = (char *) realloc(str, totlen + len); else str = (char *) malloc(len); if (str == NULL) { math_error("Out of memory for reading tokens"); /*NOTREACHED*/ } memcpy(str + totlen, buf, len); totlen += len; len = 0; } } curtoken.t_strindex = addstring(str, totlen + len); if (str != buf) free(str);}/* * Read in a symbol name which may or may not be a keyword. * If allsyms is set, keywords are not looked up and almost all chars * will be accepted for the symbol. Returns the type of symbol found. */static inteatsymbol(void){ register struct keyword *kp; /* pointer to current keyword */ register char *cp; /* current character pointer */ int ch; /* current character */ int cc; /* character count */ static char buf[SYMBOLSIZE+1]; /* temporary buffer */ cp = buf; cc = SYMBOLSIZE; if (allsyms) { for (;;) { ch = nextchar(); if (ch == ' ' || ch == ';' || ch == '\n' || ch == EOF) break; if (cc-- > 0) *cp++ = (char) ch; } reread(); *cp = '\0'; if (cc < 0) scanerror(T_NULL, "Symbol too long"); curtoken.t_sym = buf; return T_SYMBOL; } for (;;) { ch = nextchar(); if (!issymbol(ch)) break; if (cc-- > 0) *cp++ = (char)ch; } reread(); *cp = '\0'; if (cc < 0) scanerror(T_NULL, "Symbol too long"); for (kp = keywords; kp->k_name; kp++) if (strcmp(kp->k_name, buf) == 0) return kp->k_token; curtoken.t_sym = buf; return T_SYMBOL;}/* * Read in and remember a possibly numeric constant value. * The constant is inserted into a constant table so further uses * of the same constant will not take more memory. This can also * return just a period, which is used for element accesses and for * the old numeric value. */static inteatnumber(void){ register char *cp; /* current character pointer */ long len; /* parsed size of number */ long res; /* result of parsing number */ if (numbufsize == 0) { numbuf = (char *)malloc(128+1); if (numbuf == NULL) math_error("Cannot allocate number buffer"); numbufsize = 128; } cp = numbuf; len = 0; for (;;) { if (len >= numbufsize) { cp = (char *)realloc(numbuf, numbufsize + 1001); if (cp == NULL) { math_error("Cannot reallocate number buffer"); /*NOTREACHED*/ } numbuf = cp; numbufsize += 1000; cp = &numbuf[len]; } *cp = nextchar(); *(++cp) = '\0'; if ((numbuf[0] == '.') && isletter(numbuf[1])) { reread(); return T_PERIOD; } res = qparse(numbuf, QPF_IMAG); if (res < 0) { reread(); scanerror(T_NULL, "Badly formatted number"); curtoken.t_numindex = addnumber("0"); return T_NUMBER; } if (res != ++len) break; } cp[-1] = '\0'; reread(); if ((numbuf[0] == '.') && (numbuf[1] == '\0')) { curtoken.t_numindex = 0; return T_OLDVALUE; } cp -= 2; res = T_NUMBER; if ((*cp == 'i') || (*cp == 'I')) { *cp = '\0'; res = T_IMAGINARY; } curtoken.t_numindex = addnumber(numbuf); return (int)res;}/* * Return the index for string value of the current token. */longtokenstring(void){ return curtoken.t_strindex;}/* * Return the constant index of a numeric token. */longtokennumber(void){ return curtoken.t_numindex;}/* * Return the address of a symbol */char *tokensymbol(void){ return curtoken.t_sym;}/* * Push back the token just read so that it will be seen again. */voidrescantoken(void){ rescan = TRUE;}/* * Describe an error message. * Then skip to the next specified token (or one more powerful). */voidscanerror(int skip, char *fmt, ...){ va_list ap; char *name; /* name of file with error */ char buf[MAXERROR+1]; /* count the error */ errorcount++; /* print the error message */ name = inputname(); if (name) fprintf(stderr, "\"%s\", line %ld: ", name, linenumber()); va_start(ap, fmt); vsnprintf(buf, MAXERROR, fmt, ap); va_end(ap); buf[MAXERROR] = '\0'; fprintf(stderr, "%s\n", buf); /* bail out if continuation not permitted */ if ((!c_flag && !stoponerror) || stoponerror > 0) longjmp(jmpbuf, 1); /* bail out if too many errors */ if (conf->maxscancount > 0 && errorcount > conf->maxscancount) { fputs("Too many scan errors, compilation aborted.\n", stderr); longjmp(jmpbuf, 1); /*NOTREACHED*/ } /* post-error report processing */ switch (skip) { case T_NULL: return; case T_COMMA: rescan = TRUE; for (;;) { switch (gettoken()) { case T_NEWLINE: case T_SEMICOLON: case T_LEFTBRACE: case T_RIGHTBRACE: case T_EOF: case T_COMMA: rescan = TRUE; return; } } default: fprintf(stderr, "Unknown skip token for scanerror\n"); /* fall into semicolon case */ /*FALLTHRU*/ case T_SEMICOLON: rescan = TRUE; for (;;) { switch (gettoken()) { case T_NEWLINE: case T_SEMICOLON: case T_LEFTBRACE: case T_RIGHTBRACE: case T_EOF: rescan = TRUE; return; } } }}/* * Display a warning and return to compiling */voidwarning(char *fmt, ...){ va_list ap; char *name; /* name of file with error */ char buf[MAXERROR+1]; name = inputname(); if (name) fprintf(stderr, "\"%s\", line %ld: ", name, linenumber()); va_start(ap, fmt); vsnprintf(buf, MAXERROR, fmt, ap); va_end(ap); buf[MAXERROR] = '\0'; fprintf(stderr, "Warning: %s\n", buf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -