📄 clex.c
字号:
return terminate(LBRACK_S); }void Clex::block_comment(Clex_mode m) { eat_one(); // eat the '*' while (! (look == '*' && (eat_one(), look == '/')) ) { if (look == EOF) return; if (look == '\n') { eat_one(); eoln(m|CL_COMMENT); } else if (look != '*') eat_one(); } eat_one(); // eat the '/' }void Clex::line_comment() { do { eat_one(); } while (look != '\n' && look != EOF); }// eat_return() is intended to save space in Clex::next() -- the// inline function eat_one() produces quite a lot of code.Clex_sym Clex::eat_return(Clex_sym s) { eat_one(); return s; }Clex_sym Clex::next() { short val; while (val = look, eat_one(), val != EOF) { char ch = char(val); switch (ch) { case ' ' : continue; case '_' : case '$' : return ident(ch); case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : return num(ch); case ',' : return COMMA_S; case ';' : return SEMI_S; case '[' : if (block_brack) return lbrack(CL_NONE); else return LBRACK_S; case ']' : return RBRACK_S; case '{' : return LBRACE_S; case '}' : return RBRACE_S; case '(' : return LPAR_S; case ')' : return RPAR_S; case '~' : return TILDE_S; case '?' : return QUEST_S; case '"' : return quote(ch, QUOTE_S, CL_NONE); case '\'': return quote(ch, APOS_S, CL_NONE); case '=' : // '=', '==' if (look != '=') return AS_S; else return eat_return(EQ_S); case ':' : // ":", "::" if (look != ':') return COLON_S; else return eat_return(SCOPE_S); case '!' : // "!", "!=" if (look != '=') return BANG_S; else return eat_return(NE_S); case '^' : // "^", "^=" if (look != '=') return CARET_S; else return eat_return(XORAS_S); case '*' : // '*', '*=' if (look != '=') return STAR_S; else return eat_return(MULAS_S); case '%' : // '%', '%=' if (look != '=') return MOD_S; else return eat_return(MODAS_S); case '|' : // "|=", "||", "|" if (look == '|') return eat_return(LOR_S); else if (look == '=') return eat_return(ORAS_S); else return VBAR_S; case '&' : // "&", "&=", "&&" if (look == '&') return eat_return(LAND_S); else if (look == '=') return eat_return(ANDAS_S); else return AMPER_S; case '+' : // '+', '++', '+=' if (look == '+') return eat_return(INCRE_S); else if (look == '=') return eat_return(ADDAS_S); else return PLUS_S; case '-' : // '--', '-=', '->', '-', if (look == '-') return eat_return(DECRE_S); else if (look == '=') return eat_return(SUBAS_S); else if (look == '>') return eat_return(DEREF_S); else return MINUS_S; case '/' : // '/*', '//', '/=', '/' if (look == '*') { block_comment(CL_NONE); if (look == EOF) // almost certainly a mistake: return ERROR_EOF_S; else continue; } else if (look == '/') { line_comment(); continue; } else if (look == '=') return eat_return(DIVAS_S); else return SLASH_S; case '.' : // ".", "..." if (isdigit(look)) return num(ch); else if (look == '.') { eat_one(); // check for "..", undefined. if (look != '.') return ERROR_UNKN_S; else return eat_return(ELLIP_S); } else return DOT_S; case '<' : // '<=', '<', '<<', '<<=' if (look == '=') return eat_return(LE_S); else if (look == '<') { eat_one(); if (look != '=') return SHL_S; else return eat_return(SHLAS_S); } else return LT_S; case '>' : // '>=', '>', '>>', '>>=' if (look == '=') return eat_return(GE_S); else if (look == '>') { eat_one(); if (look != '=') return SHR_S; else return eat_return(SHRAS_S); } else return GT_S; default: if (isalpha(ch)) return ident(ch); if (ch == '\n') eoln(CL_NONE); else if (iscntrl(ch)) continue; else return ERROR_UNKN_S; } } return EOF_S; }struct Quickbuf { short len; char line[10240]; void put_in(char c) { if (len < sizeof(line)-1) line[len++] = c; } void terminate() { line[len] = '\0'; } Quickbuf() { len = 0; } };void Clex::eoln(Clex_mode m) { // assume NL character already eaten. ++line_num; // don't process '#' lines in quotes, comments, or '#' continuations. if (m & (CL_QUOTE|CL_POUND|CL_COMMENT)) return; // eat whitespace while (look != EOF && look != '\n') { if (look == ' ' || iscntrl(char(look))) eat_one(); else break; } if (look != '#') return; // eat the '#' and subsequent whitespace do { eat_one(); if (look == EOF || look == '\n') break; } while (look == ' ' || iscntrl(char(look))); // collect the '#' line Quickbuf b; do { // record line if (look == '\\') // check for continuation line { eat_one(); if (look == '\n') { eat_one(); eoln(m|CL_POUND); } else { b.put_in('\\'); } } else if (look == '/') // check for comment in '#' line { eat_one(); if (look == '*') { block_comment(m|CL_POUND); if (look == EOF) break; } else if (look == '/') line_comment(); else { b.put_in('/'); } } else { if (iscntrl(char(look))) look = ' '; b.put_in(look); eat_one(); } } while (look != '\n' && look != EOF); b.terminate(); (void) pound(m, b.line, b.len); // call virtual handler }Boolean Clex::pound (Clex_mode m, char* line, short len) { void(m); // to keep cfront blissful char* cp = line; if (!isdigit(*cp)) { if (len < 5) return FALSE; if (strncmp(cp, "line ", 5) != 0) return FALSE; // don't know what it is cp += 4; while (*cp == ' ') ++cp; if (!isdigit(*cp)) return FALSE; } // # <line> "<filename>" or #line <line> "<filename>" line_num = atoi(cp) - 1; // will be incremented by eoln() later while (isdigit(*cp)) ++cp; while (*cp == ' ') ++cp; if (*cp == '"') { char* cpq = cp; do { ++cpq; } while (*cpq != '"' && *cpq != '\0'); strncpy(filename, cp+1, cpq - cp - 1); filename[cpq - cp - 1] = '\0'; } return TRUE; }const char* Clex::debug (Clex_sym s) { return (s >= KEYWORD_S) ? keywords[s - KEYWORD_S] : sym_str[s] ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -