📄 lex.c
字号:
continue; if(cp == symb+2) yyerror("malformed hex constant"); goto ncu; } if(c < '0' || c > '7') goto dc; for(;;) { if(c >= '0' && c <= '7') { *cp++ = c; c = GETC(); continue; } goto ncu; }dc: if(c == '.') goto casedot; if(c == 'e' || c == 'E') goto casee;ncu: if((c == 'U' || c == 'u') && !(c1 & Numuns)) { c = GETC(); c1 |= Numuns; goto ncu; } if((c == 'L' || c == 'l') && !(c1 & Numvlong)) { c = GETC(); if(c1 & Numlong) c1 |= Numvlong; c1 |= Numlong; goto ncu; } *cp = 0; peekc = c; if(mpatov(symb, &yylval.vval)) yyerror("overflow in constant"); vv = yylval.vval; if(c1 & Numvlong) { if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) { c = LUVLCONST; t = TUVLONG; goto nret; } c = LVLCONST; t = TVLONG; goto nret; } if(c1 & Numlong) { if((c1 & Numuns) || convvtox(vv, TLONG) < 0) { c = LULCONST; t = TULONG; goto nret; } c = LLCONST; t = TLONG; goto nret; } if((c1 & Numuns) || convvtox(vv, TINT) < 0) { c = LUCONST; t = TUINT; goto nret; } c = LCONST; t = TINT; goto nret;nret: yylval.vval = convvtox(vv, t); if(yylval.vval != vv){ nearln = lineno; warn(Z, "truncated constant: %T %s", types[t], symb); } return c;casedot: for(;;) { *cp++ = c; c = GETC(); if(!isdigit(c)) break; } if(c != 'e' && c != 'E') goto caseout;casee: *cp++ = 'e'; c = GETC(); if(c == '+' || c == '-') { *cp++ = c; c = GETC(); } if(!isdigit(c)) yyerror("malformed fp constant exponent"); while(isdigit(c)) { *cp++ = c; c = GETC(); }caseout: if(c == 'L' || c == 'l') { c = GETC(); c1 |= Numlong; } else if(c == 'F' || c == 'f') { c = GETC(); c1 |= Numflt; } *cp = 0; peekc = c; yylval.dval = strtod(symb, nil); if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) { yyerror("overflow in float constant"); yylval.dval = 0; } if(c1 & Numflt) return LFCONST; return LDCONST;}/* * convert a string, s, to vlong in *v * return conversion overflow. * required syntax is [0[x]]d* */intmpatov(char *s, vlong *v){ vlong n, nn; int c; n = 0; c = *s; if(c == '0') goto oct; while(c = *s++) { if(c >= '0' && c <= '9') nn = n*10 + c-'0'; else goto bad; if(n < 0 && nn >= 0) goto bad; n = nn; } goto out;oct: s++; c = *s; if(c == 'x' || c == 'X') goto hex; while(c = *s++) { if(c >= '0' || c <= '7') nn = n*8 + c-'0'; else goto bad; if(n < 0 && nn >= 0) goto bad; n = nn; } goto out;hex: s++; while(c = *s++) { if(c >= '0' && c <= '9') c += 0-'0'; else if(c >= 'a' && c <= 'f') c += 10-'a'; else if(c >= 'A' && c <= 'F') c += 10-'A'; else goto bad; nn = n*16 + c; if(n < 0 && nn >= 0) goto bad; n = nn; }out: *v = n; return 0;bad: *v = ~0; return 1;}intgetc(void){ int c; if(peekc != IGN) { c = peekc; peekc = IGN; } else c = GETC(); if(c == '\n') lineno++; if(c == EOF) { yyerror("End of file"); errorexit(); } return c;}longgetr(void){ int c, i; char str[UTFmax+1]; Rune rune; c = getc(); if(c < Runeself) return c; i = 0; str[i++] = c;loop: c = getc(); str[i++] = c; if(!fullrune(str, i)) goto loop; c = chartorune(&rune, str); if(rune == Runeerror && c == 1) { nearln = lineno; diag(Z, "illegal rune in string"); for(c=0; c<i; c++) print(" %.2x", *(uchar*)(str+c)); print("\n"); } return rune;}intgetnsc(void){ int c; if(peekc != IGN) { c = peekc; peekc = IGN; } else c = GETC(); for(;;) { if(!isspace(c)) return c; if(c == '\n') { lineno++; return c; } c = GETC(); }}voidunget(int c){ peekc = c; if(c == '\n') lineno--;}longescchar(long e, int longflg, int escflg){ long c, l; int i;loop: c = getr(); if(c == '\n') { yyerror("newline in string"); return EOF; } if(c != '\\') { if(c == e) c = EOF; return c; } c = getr(); if(c == 'x') { /* * note this is not ansi, * supposed to only accept 2 hex */ i = 2; if(longflg) i = 4; l = 0; for(; i>0; i--) { c = getc(); if(c >= '0' && c <= '9') { l = l*16 + c-'0'; continue; } if(c >= 'a' && c <= 'f') { l = l*16 + c-'a' + 10; continue; } if(c >= 'A' && c <= 'F') { l = l*16 + c-'A' + 10; continue; } unget(c); break; } if(escflg) l |= ESC; return l; } if(c >= '0' && c <= '7') { /* * note this is not ansi, * supposed to only accept 3 oct */ i = 2; if(longflg) i = 5; l = c - '0'; for(; i>0; i--) { c = getc(); if(c >= '0' && c <= '7') { l = l*8 + c-'0'; continue; } unget(c); } if(escflg) l |= ESC; return l; } switch(c) { case '\n': goto loop; case 'n': return '\n'; case 't': return '\t'; case 'b': return '\b'; case 'r': return '\r'; case 'f': return '\f'; case 'a': return '\a'; case 'v': return '\v'; } return c;}struct{ char *name; ushort lexical; ushort type;} itab[] ={ "auto", LAUTO, 0, "break", LBREAK, 0, "case", LCASE, 0, "char", LCHAR, TCHAR, "const", LCONSTNT, 0, "continue", LCONTINUE, 0, "default", LDEFAULT, 0, "do", LDO, 0, "double", LDOUBLE, TDOUBLE, "else", LELSE, 0, "enum", LENUM, 0, "extern", LEXTERN, 0, "float", LFLOAT, TFLOAT, "for", LFOR, 0, "goto", LGOTO, 0, "if", LIF, 0, "inline", LINLINE, 0, "int", LINT, TINT, "long", LLONG, TLONG, "register", LREGISTER, 0, "restrict", LRESTRICT, 0, "return", LRETURN, 0, "SET", LSET, 0, "short", LSHORT, TSHORT, "signed", LSIGNED, 0, "signof", LSIGNOF, 0, "sizeof", LSIZEOF, 0, "static", LSTATIC, 0, "struct", LSTRUCT, 0, "switch", LSWITCH, 0, "typedef", LTYPEDEF, 0, "typestr", LTYPESTR, 0, "union", LUNION, 0, "unsigned", LUNSIGNED, 0, "USED", LUSED, 0, "void", LVOID, TVOID, "volatile", LVOLATILE, 0, "while", LWHILE, 0, 0};voidcinit(void){ Sym *s; int i; Type *t; nerrors = 0; lineno = 1; iostack = I; iofree = I; peekc = IGN; nhunk = 0; types[TXXX] = T; types[TCHAR] = typ(TCHAR, T); types[TUCHAR] = typ(TUCHAR, T); types[TSHORT] = typ(TSHORT, T); types[TUSHORT] = typ(TUSHORT, T); types[TINT] = typ(TINT, T); types[TUINT] = typ(TUINT, T); types[TLONG] = typ(TLONG, T); types[TULONG] = typ(TULONG, T); types[TVLONG] = typ(TVLONG, T); types[TUVLONG] = typ(TUVLONG, T); types[TFLOAT] = typ(TFLOAT, T); types[TDOUBLE] = typ(TDOUBLE, T); types[TVOID] = typ(TVOID, T); types[TENUM] = typ(TENUM, T); types[TFUNC] = typ(TFUNC, types[TINT]); types[TIND] = typ(TIND, types[TVOID]); for(i=0; i<NHASH; i++) hash[i] = S; for(i=0; itab[i].name; i++) { s = slookup(itab[i].name); s->lexical = itab[i].lexical; if(itab[i].type != 0) s->type = types[itab[i].type]; } blockno = 0; autobn = 0; autoffset = 0; t = typ(TARRAY, types[TCHAR]); t->width = 0; symstring = slookup(".string"); symstring->class = CSTATIC; symstring->type = t; t = typ(TARRAY, types[TCHAR]); t->width = 0; nodproto = new(OPROTO, Z, Z); dclstack = D; pathname = allocn(pathname, 0, 100); if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) strcpy(pathname, "/???"); } fmtinstall('O', Oconv); fmtinstall('T', Tconv); fmtinstall('F', FNconv); fmtinstall('L', Lconv); fmtinstall('Q', Qconv); fmtinstall('|', VBconv);}intfilbuf(void){ Io *i;loop: i = iostack; if(i == I) return EOF; if(i->f < 0) goto pop; fi.c = read(i->f, i->b, BUFSIZ) - 1; if(fi.c < 0) { close(i->f); linehist(0, 0); goto pop; } fi.p = i->b + 1; return i->b[0] & 0xff;pop: iostack = i->link; i->link = iofree; iofree = i; i = iostack; if(i == I) return EOF; fi.p = i->p; fi.c = i->c; if(--fi.c < 0) goto loop; return *fi.p++ & 0xff;}intOconv(Fmt *fp){ int a; a = va_arg(fp->args, int); if(a < OXXX || a > OEND) return fmtprint(fp, "***badO %d***", a); return fmtstrcpy(fp, onames[a]);}intLconv(Fmt *fp){ char str[STRINGSZ], s[STRINGSZ]; Hist *h; struct { Hist* incl; /* start of this include file */ long idel; /* delta line number to apply to include */ Hist* line; /* start of this #line directive */ long ldel; /* delta line number to apply to #line */ } a[HISTSZ]; long l, d; int i, n; l = va_arg(fp->args, long); n = 0; for(h = hist; h != H; h = h->link) { if(l < h->line) break; if(h->name) { if(h->offset != 0) { /* #line directive, not #pragma */ if(n > 0 && n < HISTSZ && h->offset >= 0) { a[n-1].line = h; a[n-1].ldel = h->line - h->offset + 1; } } else { if(n < HISTSZ) { /* beginning of file */ a[n].incl = h; a[n].idel = h->line; a[n].line = 0; } n++; } continue; } n--; if(n > 0 && n < HISTSZ) { d = h->line - a[n].incl->line; a[n-1].ldel += d; a[n-1].idel += d; } } if(n > HISTSZ) n = HISTSZ; str[0] = 0; for(i=n-1; i>=0; i--) { if(i != n-1) { if(fp->flags & ~(FmtWidth|FmtPrec)) /* BUG ROB - was f3 */ break; strcat(str, " "); } if(a[i].line) snprint(s, STRINGSZ, "%s:%ld[%s:%ld]", a[i].line->name, l-a[i].ldel+1, a[i].incl->name, l-a[i].idel+1); else snprint(s, STRINGSZ, "%s:%ld", a[i].incl->name, l-a[i].idel+1); if(strlen(s)+strlen(str) >= STRINGSZ-10) break; strcat(str, s); l = a[i].incl->line - 1; /* now print out start of this file */ } if(n == 0) strcat(str, "<eof>"); return fmtstrcpy(fp, str);}intTconv(Fmt *fp){ char str[STRINGSZ+20], s[STRINGSZ+20]; Type *t, *t1; int et; long n; str[0] = 0; for(t = va_arg(fp->args, Type*); t != T; t = t->link) { et = t->etype; if(str[0]) strcat(str, " "); if(t->garb&~GINCOMPLETE) { sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]); if(strlen(str) + strlen(s) < STRINGSZ) strcat(str, s); } sprint(s, "%s", tnames[et]); if(strlen(str) + strlen(s) < STRINGSZ) strcat(str, s); if(et == TFUNC && (t1 = t->down)) { sprint(s, "(%T", t1); if(strlen(str) + strlen(s) < STRINGSZ) strcat(str, s); while(t1 = t1->down) { sprint(s, ", %T", t1); if(strlen(str) + strlen(s) < STRINGSZ) strcat(str, s); } if(strlen(str) + strlen(s) < STRINGSZ) strcat(str, ")"); } if(et == TARRAY) { n = t->width; if(t->link && t->link->width) n /= t->link->width; sprint(s, "[%ld]", n); if(strlen(str) + strlen(s) < STRINGSZ) strcat(str, s); } if(t->nbits) { sprint(s, " %d:%d", t->shift, t->nbits); if(strlen(str) + strlen(s) < STRINGSZ) strcat(str, s); } if(typesu[et]) { if(t->tag) { strcat(str, " "); if(strlen(str) + strlen(t->tag->name) < STRINGSZ) strcat(str, t->tag->name); } else strcat(str, " {}"); break; } } return fmtstrcpy(fp, str);}intFNconv(Fmt *fp){ char *str; Node *n; n = va_arg(fp->args, Node*); str = "<indirect>"; if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM)) str = n->sym->name; return fmtstrcpy(fp, str);}intQconv(Fmt *fp){ char str[STRINGSZ+20], *s; long b; int i; str[0] = 0; for(b = va_arg(fp->args, long); b;) { i = bitno(b); if(str[0]) strcat(str, " "); s = qnames[i]; if(strlen(str) + strlen(s) >= STRINGSZ) break; strcat(str, s); b &= ~(1L << i); } return fmtstrcpy(fp, str);}intVBconv(Fmt *fp){ char str[STRINGSZ]; int i, n, t, pc; n = va_arg(fp->args, int); pc = 0; /* BUG: was printcol */ i = 0; while(pc < n) { t = (pc+4) & ~3; if(t <= n) { str[i++] = '\t'; pc = t; continue; } str[i++] = ' '; pc++; } str[i] = 0; return fmtstrcpy(fp, str);}/* * real allocs */void*alloc(long n){ void *p; while((uintptr)hunk & MAXALIGN) { hunk++; nhunk--; } while(nhunk < n) gethunk(); p = hunk; nhunk -= n; hunk += n; return p;}void*allocn(void *p, long on, long n){ void *q; q = (uchar*)p + on; if(q != hunk || nhunk < n) { while(nhunk < on+n) gethunk(); memmove(hunk, p, on); p = hunk; hunk += on; nhunk -= on; } hunk += n; nhunk -= n; return p;}voidsetinclude(char *p){ int i; char *e; while(*p != 0) { e = strchr(p, ' '); if(e != 0) *e = '\0'; for(i=1; i < ninclude; i++) if(strcmp(p, include[i]) == 0) break; if(i >= ninclude) include[ninclude++] = p; if(ninclude > nelem(include)) { diag(Z, "ninclude too small %d", nelem(include)); exits("ninclude"); } if(e == 0) break; p = e+1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -