📄 vtc.y
字号:
} Token;Token *tokbuf;int tokpos = 0, toksize;#define INIT_TOKENS 128#define Textend Checkinc(tokbuf, Token, toksize, tokpos)#define Add_vtoken(t, elem, v) if (1) { Textend; tokbuf[tokpos].type = (t); \ tokbuf[tokpos++].val.elem = (v); } else#define Add_ntoken(t) if (1) { Textend; tokbuf[tokpos++].type = (t); } else#define INIT_SCONST 32#define INIT_IDENTS 64static Cstr *sconsts; /* Allocated string constants */static char **idents; /* Allocated identifiers */static int sconstpos = 0, identpos = 0, sconstsize, identsize;static int braces = 0, incomment = 0, instring = 0, infunc = 0, tokindex;static String sbuf;static char *ecodes = "ntvbrf\\'\"";static char *results = "\n\t\v\b\r\f\\'\"";static int begin[128], end[128]; /* Lookup table for words */static char transtab[128]; /* Table for escape codes *//* Table of reserved words and compound operators *//* These do not need to be in alphabetical order, but words with the** same first character must be adjacent. Among compound operators** with the same first character, longer operators should come first. */static struct word { char *s; int val;} words[] = { { "" , 0 }, { "do" , DO }, { "while" , WHILE }, { "if" , IF }, { "else" , ELSE }, { "for" , FOR }, { "func" , FUNC }, { "goto" , GOTO }, { "break" , BREAK }, { "continue" , CONTINUE }, { "return" , RETURN }, { "^=" , BXA }, { "*=" , TA }, { "/=" , DA }, { "%=" , MA }, { "+=" , AA }, { "++" , INC }, { "-=" , SA }, { "-->" , FASSIGN }, { "--" , DEC }, { "->" , DEREF }, { "<<=" , SLA }, { "<<" , SL }, { "<=" , LE }, { ">>=" , SRA }, { ">>" , SR }, { ">=" , GE }, { "&=" , BAA }, { "&&" , AND }, { "|=" , BOA }, { "||" , OR }, { "==" , EQ }, { "!=" , NE }, { "?:=" , CONDA }, { "" , 0 }};#define NWORDS (sizeof(words) / sizeof(struct word) - 1)/* Set up data */void init_compile(){ int i; bzero(begin, sizeof(begin)); bzero(end, sizeof(end)); for (i = 0; i < NWORDS; i++) { begin[*words[i].s] = i; while (*words[i + 1].s == *words[i].s) i++; end[*words[i].s] = i; } bzero(transtab, sizeof(transtab)); for (i = 0; ecodes[i]; i++) transtab[ecodes[i]] = results[i]; tokbuf = Newarray(Token, toksize = INIT_TOKENS); icode = Newarray(Instr, codesize = INIT_CODE); sconsts = Newarray(Cstr, sconstsize = INIT_SCONST); idents = Newarray(char *, identsize = INIT_IDENTS); jmptab = Newarray(int, jmpsize = INIT_JMP); condstack = Newarray(int, condsize = INIT_COND); loopstack = Newarray(int, loopsize = INIT_COND); sbuf = empty_string;}/* Analyze text and place tokens in buffer */void parse(text) char *text;{ while (*text) { text = parse_token(text); if (!text) return; } if (!infunc && !braces && !incomment && !instring && tokpos) compile();}static char *parse_token(s) char *s;{ char *ptr, buf[MAXILEN + 1]; int i; void (*bobj)(); Const *cp; if (incomment) return read_comment(s); if (instring) return read_string(s); for (; isspace(*s); s++); if (!*s || *s == '/' && s[1] == '/') return ""; if (*s == '/' && s[1] == '*') return read_comment(s + 2); if (*s == '"') { s_term(&sbuf, 0); return read_string(s + 1); } if (*s == '\'') { s++; Add_vtoken(ICONST, num, read_char(&s)); if (*s++ != '\'') lexerror(ERR_UNTERMCHAR); return s; } if (isdigit(*s)) { i = 0; if (*s == '0' && lcase(s[1]) == 'x' && isxdigit(s[2])) { s++; while (isxdigit(*++s)) i = i * 0x10 + Hexdigitvalue(*s); Add_vtoken(ICONST, num, i); return s; } if (*s == '0' && s[1] >= '0' && s[1] <= '8') { while (*++s >= '0' && *s <= '8') i = i * 010 + *s - '0'; Add_vtoken(ICONST, num, i); return s; } Add_vtoken(ICONST, num, atoi(s)); while (isdigit(*++s)); return s; } if (*s == '\\' && !s[1]) return NULL; if (isalpha(*s) || *s == '_') { for (ptr = s; isalnum(*ptr) || *ptr == '_'; ptr++); strncpy(buf, s, min(ptr - s, MAXILEN)); buf[min(ptr - s, MAXILEN)] = '\0'; if (!(*buf & ~0x7f) && begin[*buf]) { for (i = begin[*buf]; i <= end[*buf]; i++) { if (streq(buf + 1, words[i].s + 1)) break; } if (i <= end[*buf]) { if (words[i].val == FUNC) { if (tokpos) { lexerror(ERR_ILLFUNC); braces = 0; } infunc = 1; } Add_ntoken(words[i].val); return ptr; } } bobj = find_bobj(buf); if (bobj) { Add_vtoken(BOBJ, bobj, bobj); return ptr; } cp = find_const(buf); if (cp) { Add_vtoken(ICONST, num, cp->val); return ptr; } Push(idents, char *, identsize, identpos, vtstrdup(buf)); Add_vtoken(IDENT, s, idents[identpos - 1]); return ptr; } if (!(*s & ~0x7f) && begin[*s]) { for (i = begin[*s]; i <= end[*s]; i++) { if (!strncmp(s + 1, words[i].s + 1, strlen(words[i].s) - 1)) break; } if (i <= end[*s]) { Add_ntoken(words[i].val); if (words[i].val == FASSIGN) infunc = 0; return s + strlen(words[i].s); } } Add_ntoken(*s); if (*s == '{') braces++; else if (*s == '}') { if (!braces) lexerror(ERR_BADBRACE); else if (!--braces) infunc = 0; } return s + 1;}static int read_char(s) char **s;{ char c; int val = 0, count; if (**s != '\\') return *(*s)++; c = transtab[*++(*s) & 0x7f]; if (c) { (*s)++; return c; } if (**s < '0' || **s > '8') return '\\'; for (count = 0; count < 3 && **s >= '0' && **s <= '8'; (*s)++) val = val * 8 + **s - '0'; return val;}static int enter_sconst(c) Cstr c;{ Push(sconsts, Cstr, sconstsize, sconstpos, cstr_c(c)); return sconstpos - 1;}static char *read_string(s) char *s;{ while (*s && *s != '"') { if (*s == '\\' && !s[1]) { instring = 1; return ""; } s_fadd(&sbuf, read_char(&s)); } if (!*s) { lexerror(ERR_UNTERMSTR); return ""; } instring = 0; Add_vtoken(SCONST, str, enter_sconst(sbuf.c)); return s + 1;}static char *read_comment(s) char *s;{ s = strchr(s, '*'); while (s) { if (s[1] == '/') { incomment = 0; return s + 2; } s = strchr(s + 1, '*'); } incomment = 1; return "";}static void compile(){ tokindex = 0; yyparse(); if (!errflag) { scan(); return; } while (yylex()); condpos = looppos = 0; cleanup_parse();}static void scan(){ Prog *newprog; Instr *in, *end; char *s; Func *func; String dtext; dtext = empty_string; jmptab[0] = loc; Code(I_STOP); newprog = New(Prog); newprog->refs = 0; newprog->avarc = avarc; newprog->reqargs = reqargs; newprog->lvarc = lvarc; newprog->code = Newarray(Instr, loc); Copy(icode, newprog->code, loc, Instr); end = newprog->code + loc; for (in = newprog->code; in < end; in += iwidth[in->type]) { switch(in->type) { case I_SCONST: in[1].sconst = add_sconst(&sconsts[in[1].sindex]); Case I_FCALL: s = in[2].ident; func = find_func(s); if (debug && (!func || !func->cmd) && !strstr(dtext.c.s, s)) { s_acat(&dtext, " "); s_acat(&dtext, s); s_acat(&dtext, "()"); } in[2].func = func ? func : add_func(s, NULL); Case I_FPTR: s = in[1].ident; func = find_func(s); if (debug && (!func || !func->cmd) && !strstr(dtext.c.s, s)) { s_acat(&dtext, " ."); s_acat(&dtext, s); } in[1].func = func ? func : add_func(s, NULL); Case I_GVAR: if (debug && !strstr(dtext.c.s, in[1].ident)) { s_acat(&dtext, " "); s_acat(&dtext, in[1].ident); } in[1].tnum = get_vindex(in[1].ident); Case I_JMP: case I_JMPT: case I_JMPF: case I_JMPPT: case I_JMPPF: in[1].loc = newprog->code + jmptab[in[1].offset]; } } if (debug && *dtext.c.s) { if (*curfile) outputf("%s ", curfile); outputf("%s:%s\n", *curfunc ? curfunc : "Command", dtext.c.s); } s_free(&dtext); if (*curfunc) { add_func(curfunc, newprog); cleanup_parse(); } else { cleanup_parse(); run_prog(newprog); }}static void cleanup_parse(){ while (identpos--) Discardstring(idents[identpos]); while (sconstpos--) { if (sconsts[sconstpos].s) Discardarray(sconsts[sconstpos].s, char, sconsts[sconstpos].l + 1); } free_labels(); curfunc = ""; tokpos = loc = lvarc = avarc = errflag = identpos = sconstpos = 0; reqargs = 0; jmppos = 1;}static void lexerror(s) char *s;{ if (lexline != -1) outputf("%s line %d: ", curfile, lexline); outputf("%s\n", s); errflag = 1;}static void yyerror(msg) char *msg;{ if (parseline != -1) outputf("%s line %d: ", curfile, parseline); coutput(msg); if (*curfunc) outputf(" in function %s", curfunc); coutput("\n"); errflag = 1;}static int yylex(){ while (tokindex < tokpos && tokbuf[tokindex].type == '\n') { tokindex++; if (parseline != -1) parseline++; } if (tokindex < tokpos) { yylval = tokbuf[tokindex].val; return tokbuf[tokindex++].type; } return 0;}int load_file(name) char *name;{ int olline, opline; char *ocfile; FILE *fp; String freader; freader = empty_string; fp = fopen(expand(name), "r"); if (!fp) return -1; olline = lexline; opline = parseline; ocfile = curfile; lexline = parseline = 1; curfile = vtstrdup(name); while (s_fget(&freader, fp)) { if (freader.c.s[freader.c.l - 1] == '\n') freader.c.s[freader.c.l - 1] = '\0'; parse(freader.c.s); if (tokpos) Add_ntoken('\n'); else parseline++; lexline++; } lexline = olline; parseline = opline; Discardstring(curfile); curfile = ocfile; fclose(fp); s_free(&freader); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -