📄 lex.c
字号:
get(lxchar); switch( (p=lxcp[lxchar+1])->lxact ){ case A_1C: // eat up a single character, and return an opcode reti(p->lxtok,p->lxtok); case A_EOF: if (br_level || bl_level) error("'%s' missing at end of input",(bl_level) ? "}" : ")"); reti(EOFTOK,0); case A_ERR: if (lxchar == '#') { // cope with header file not ended // with '\n' unget('#'); saved = lxtitle(); continue; } if (' '<=lxchar && lxchar<='~') // ASCII printable error("illegal character '%c' (ignored)",lxchar); else error("illegal character '0%o' (ignored)",lxchar); continue; case A_LET: /* collect an identifier, check for reserved word, and return */ lxget( lxchar, LEXLET|LEXDIG ); if (n = ktbl->look(txtstart,0)) { TOK x; del_txt(); switch (x=n->base) { case TNAME: retn(TNAME,n); break; case LOC: retl(n->syn_class); default: reti(n->syn_class,x); } } else { rets(ID,txtstart); } case A_DIG: ret = ICON; if (lxchar=='0') { /* octal or hexadecimal number */ pch('0'); switch (get(lxchar)) { case 'l': case 'L': pch('L'); pch(0); rets(ICON,txtstart); case 'x': case 'X': lxget('X',LEXHEX); if (txtfree-txtstart<4) // minimum "0Xd\0" error("hexadecimal digitX after \"0x\""); switch (get(lxchar)) { case 'l': case 'L': txtfree--; pch('L'); pch(0); break; default: saved = lxchar; } rets(ICON,txtstart); case '8': case '9': error("8 or 9 used as octal digit"); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': pch(lxchar); ox: switch (get(lxchar)) { case '8': case '9': error("8 or 9 used as octal digit"); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': pch(lxchar); goto ox; case 'l': case 'L': pch('L'); pch(0); break; default: pch(0); saved = lxchar; } rets(ICON,txtstart); case '.': lxget('.',LEXDIG); goto getfp; default: saved = lxchar; reti(ZERO,0); } } else lxget(lxchar,LEXDIG); if (get(lxchar) == '.') { txtfree--; lxget('.', LEXDIG ); getfp: ret = FCON; get(lxchar); }; switch (lxchar) { case 'e': case 'E': txtfree--; switch (get(lxchar)) { case '-': case '+': pch('e'); break; default: unget(lxchar); lxchar = 'e'; }; lxget( lxchar, LEXDIG ); ret = FCON; break; case 'l': case 'L': txtfree--; pch('L'); break; default: saved = lxchar; }; pch(0); rets(ret,txtstart); case A_DOT: if (get(lxchar) == '.') { /* look for ellipsis */ if (get(lxchar) != '.') { error("token .. ?"); saved = lxchar; } reti(ELLIPSIS,0); } if( lxmask[lxchar+1] & LEXDIG ){/* look for floating constant */ unget(lxchar); lxget( '.', LEXDIG ); goto getfp; } saved = lxchar; reti(DOT,0); case A_STR: /* save string constant in buffer */ forever switch (get(lxchar)) { case '\\': pch('\\'); get(lxchar); if (lxchar == 'x') hex_to_oct(); else pch(lxchar); break; case '"': pch(0); rets(STRING,txtstart); case '\n': error("newline in string"); pch(0); rets(STRING,txtstart); case EOF: error("eof in string"); pch(0); rets(STRING,txtstart); default: pch(lxchar); } case A_CC: /* character constant */ rets(CCON,chconst()); case A_BCD: { register i; int j; pch('`'); for (i=0; i<7; ++i) { pch(get(j)); if (j == '`' ) break; } pch(0); if (6<i) error("bcd constant exceeds 6 characters" ); rets(CCON,txtstart); } case A_SL: /* / */ switch (get(lxchar)) { case '*': lxcom(); break; case '/': linecom(); break; case '=': reti(ASOP,ASDIV); default: saved = lxchar; reti(DIVOP,DIV); } case A_WS: continue; case A_NL: ++curloc.line; Nline++; saved = lxtitle(); continue; case A_LC: if (BLMAX <= bl_level++) { error('s',"blocks too deaply nested"); ext(3); } retl(LC); case A_RC: if (bl_level-- <= 0) { error("unX '}'"); bl_level = 0; } retl(RC); case A_L: br_level++; reti(LP,0); case A_R: if (br_level-- <= 0) { error("unX ')'"); br_level = 0; } reti(RP,0); case A_ASS: switch (get(lxchar)) { case '=': reti(EQUOP,EQ); default: saved = lxchar; reti(ASSIGN,ASSIGN); } case A_COL: switch (get(lxchar)) { case ':': reti(MEM,0); case '=': error("':=' is not a c++ operator"); reti(ASSIGN,ASSIGN); default: saved = lxchar; reti(COLON,COLON); } case A_NOT: switch (get(lxchar)) { case '=': reti(EQUOP,NE); default: saved = lxchar; reti(NOT,NOT); } case A_GT: switch(get(lxchar)) { case '>': switch (get(lxchar)) { case '=': reti(ASOP,ASRS); break; default: saved = lxchar; reti(SHIFTOP,RS); } case '=': reti(RELOP,GE); default: saved = lxchar; reti(RELOP,GT); } case A_LT: switch (get(lxchar)) { case '<': switch (get(lxchar)) { case '=': reti(ASOP,ASLS); default: saved = lxchar; reti(SHIFTOP,LS); } case '=': reti(RELOP,LE); default: saved = lxchar; reti(RELOP,LT); } case A_AND: switch (get(lxchar)) { case '&': reti(ANDAND,ANDAND); case '=': reti(ASOP,ASAND); default: saved = lxchar; reti(AND,AND); } case A_OR: switch (get(lxchar)) { case '|': reti(OROR,OROR); case '=': reti(ASOP,ASOR); default: saved = lxchar; reti(OR,OR); } case A_ER: switch (get(lxchar)) { case '=': reti(ASOP,ASER); default: saved = lxchar; reti(ER,ER); } case A_PL: switch (get(lxchar)) { case '=': reti(ASOP,ASPLUS); case '+': reti(ICOP,INCR); default: saved = lxchar; reti(PLUS,PLUS); } case A_MIN: switch (get(lxchar)) { case '=': reti(ASOP,ASMINUS); case '-': reti(ICOP,DECR); case '>': reti(REF,REF); default: saved = lxchar; reti(MINUS,MINUS); } case A_MUL: switch (get(lxchar)) { case '=': reti(ASOP,ASMUL); case '/': error('w',"*/ not as end of comment"); default: saved = lxchar; reti(MUL,MUL); } case A_MOD: switch (get(lxchar)) { case '=': reti(ASOP,ASMOD); default: saved = lxchar; reti(DIVOP,MOD); } default: error('i',"lex act==%d getc()->%d",p,lxchar); } error('i',"lex, main switch"); }}int lxtitle()/* called after a newline; set linenumber and file name*/{ register c; forever switch ( get(c) ) { default: return c;/* case EOF: return EOF; */ case '\n': curloc.line++; Nline++; break; ll: break; case '#': /* # lineno "filename" */ curloc.line = 0; forever switch (get(c)) { case '"': start_txt(); forever switch (get(c)) { case '"': pch('\0'); if (get(c) != '\n') error("unX eol on # line"); if (*txtstart) { // stack file name if (curr_file == 0) goto push; char* fn; if ( (fn=file_name[file_stack[curr_file]]) && (strcmp(txtstart,fn)==0) ) { // same file: ignore } else if ( (fn=file_name[file_stack[curr_file-1]]) && (strcmp(txtstart,fn)==0) ) { // previous file: pop curr_file--; } else { // new file name: push push: if (MAXFILE*4<Nfile++) error('i',"fileN buffer overflow"); if (MAXFILE<curr_file++) error('i',"fileN stack overflow"); file_stack[curr_file] = Nfile; char* p = new char[txtfree-txtstart+1]; (void) strcpy(p,txtstart); file_name[Nfile] = p; Nstr++; } } else { // back to the original .c file: "" curr_file = 0; } del_txt(); curloc.file = file_stack[curr_file]; goto ll; case '\n': error("unX end of line on '# line'"); default: pch(c); } case ' ': break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': curloc.line = curloc.line*10+c-'0'; break; default: /* pass #rubbish through */ pch('#'); pch('i'); while (get(c) != '\n') pch(c); pch('\0'); fprintf(out_file,"\n%s\n",txtstart); curloc.line++; Nline++; goto ll; case '\n': curloc.putline(); goto ll; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -