static int yylex2(void) { int ch; int chkcomment = FALSE; yuk_a_goto: eatwhite(); if ((ch = GETC(fname)) == EOF) { if (firstsemi == 1) { firstsemi = 0; fclose(fname); fname = fnamesave; goto yuk_a_goto; } else { return(TENDOFFILE); } } do { if (ch == '/') if ((ch = GETC(fname)) == '*') { eatcomment(); eatwhite(); chkcomment = TRUE; if ((ch = GETC(fname)) == EOF) return(TENDOFFILE); } else { UNGETC(ch, fname); ch = '/'; chkcomment = FALSE; } else if (ch == '-') /* -- is a comment in our language */ { if ((ch = GETC(fname)) == '-') { eatline(); /* ignore rest of line */ if (firstsemi != 1) yylineno++; eatwhite(); chkcomment = TRUE; if ((ch = GETC(fname)) == EOF) return(TENDOFFILE); } else { UNGETC(ch, fname); ch = '-'; chkcomment = FALSE; } } else chkcomment = FALSE; } while (chkcomment); if (isalpha(ch) || ch == '_') return(eatident(ch)); if (isdigit(ch)) return(eatnumber(ch)); if (ch == '"') return(eatstring()); if (ch == '\'') { char ch2; char ch3; char chat; int ate; ch2 = GETC(fname); ch3 = GETC(fname); UNGETC(ch3,fname); UNGETC(ch2,fname); if (ch2 != ' ' || ch3 != '\'') { /* can't eat whitespace if char contains whitespace */ ate = eatwhite(); chat = GETC(fname); UNGETC(chat,fname); if (chat == '@') { if (ate || (ch2 != '@' && ch3 != '\'')) { return TPRIME; } } } return eatcharacter(); } if (ch == '.') { if (isdigit(ch = GETC(fname))) { UNGETC(ch, fname); ch = '.'; return(eatnumber(ch)); } else { UNGETC(ch, fname); ch = '.'; } } if (ch == '#') { char ch2; eatwhite(); /* remove "line" if it exists - some vers of cpp have this */ if ((ch2 = GETC(fname)) == '[') { UNGETC(ch2, fname); return eatleftovers(ch); } else { UNGETC(ch2, fname); } if (!isdigit(ch = GETC(fname))) { UNGETC(ch, fname); yylex2(); if (!strcmp(buffer,"pragma")) { for (ch = GETC(fname); ch != '\n'; ch = GETC(fname)) ; goto yuk_a_goto; } if (strcmp(buffer,"line")) { USR_FATALX(yylineno, in_file, "syntax error (appears to be a cpp directive: try -cpp)"); } eatwhite(); } else { UNGETC(ch, fname); } if (!isdigit(ch = GETC(fname))) { UNGETC(ch, fname); USR_FATALX(yylineno, in_file, "syntax error (appears to be a cpp directive: use -cpp)"); } else UNGETC(ch, fname); yylex2(); yylineno = atoi(buffer); for (ch = GETC(fname); ch != '"' && ch != '\n'; ch = GETC(fname)) ; if (ch != '"') { goto yuk_a_goto; } else UNGETC(ch, fname); yylex2(); in_file = (char *)PMALLOC((strlen(buffer) + 1)*sizeof(char)); strcpy(in_file, buffer); base_in_file = strrchr(in_file,'/'); if (base_in_file == NULL) { base_in_file = in_file; } else { base_in_file++; } for (ch = GETC(fname); ch != '\n'; ch = GETC(fname)) ; goto yuk_a_goto; } if (ispunct(ch)) return(eatleftovers(ch)); buffer[0] = ch; buffer[1] = '\0'; if (firstsemi == 1) { firstsemi = 0; fclose(fname); fname = fnamesave; goto yuk_a_goto; } return(-1); }
int yylex(void) { int c; extern char vfmt[]; loop: Bflush(bout); c = lexc(); switch(c) { case Eof: if(gotint) { gotint = 0; stacked = 0; Bprint(bout, "\nacid: "); goto loop; } return Eof; case '"': eatstring(); return Tstring; case ' ': case '\r': case '\t': goto loop; case '\n': line++; if(interactive == 0) goto loop; if(stacked) { print("\t"); goto loop; } return ';'; case '.': c = lexc(); unlexc(c); if(isdigit(c)) return numsym('.'); return '.'; case '(': case ')': case '[': case ']': case ';': case ':': case ',': case '~': case '?': case '*': case '@': case '^': case '%': return c; case '{': stacked++; return c; case '}': stacked--; return c; case '\\': c = lexc(); if(strchr(vfmt, c) == 0) { unlexc(c); return '\\'; } yylval.ival = c; return Tfmt; case '!': c = lexc(); if(c == '=') return Tneq; unlexc(c); return '!'; case '+': c = lexc(); if(c == '+') return Tinc; unlexc(c); return '+'; case '/': c = lexc(); if(c == '/') { eatnl(); goto loop; } unlexc(c); return '/'; case '\'': c = lexc(); if(c == '\\') yylval.ival = escchar(lexc()); else yylval.ival = c; c = lexc(); if(c != '\'') { error("missing '"); unlexc(c); } return Tconst; case '&': c = lexc(); if(c == '&') return Tandand; unlexc(c); return '&'; case '=': c = lexc(); if(c == '=') return Teq; unlexc(c); return '='; case '|': c = lexc(); if(c == '|') return Toror; unlexc(c); return '|'; case '<': c = lexc(); if(c == '=') return Tleq; if(c == '<') return Tlsh; unlexc(c); return '<'; case '>': c = lexc(); if(c == '=') return Tgeq; if(c == '>') return Trsh; unlexc(c); return '>'; case '-': c = lexc(); if(c == '>') return Tindir; if(c == '-') return Tdec; unlexc(c); return '-'; default: return numsym(c); } }
void CodeEditor::SyntaxState::ScanSyntax(const wchar *ln, const wchar *e, int tab_size) { Grounding(ln, e); if(!linecont) { linecomment = false; string = false; } linecont = e > ln && e[-1] == '\\'; const wchar *p = ln; int lindent = 0, pos = 0; while(p < e && (*p == '\t' || *p == ' ')) { if(*p++ == '\t' || ++pos >= tab_size) { pos = 0; lindent++; } } int n; Color c = GetUvsHighlight(p, n); if(n) { uvscolor = c; p += n; } if(!comment && *p == '#') { while(++p < e && (*p == ' ' || *p == '\t')) p++; const wchar *id = p; while(p < e && iscidl(*p)) p++; int idlen = int(p - id); if(id[0] == 'i' && id[1] == 'f' && (idlen == 2 || idlen == 5 && id[2] == 'd' && id[3] == 'e' && id[4] == 'f' || idlen == 6 && id[2] == 'n' && id[3] == 'd' && id[4] == 'e' && id[5] == 'f')) { IfState& ifstate = ifstack.Add(); ifstate.state = IfState::IF; ifstate.iftext = sReadLn(ln); ifstate.ifline = line + 1; } switch(idlen) { case 6: if(id[0] == 'd' && id[1] == 'e' && id[2] == 'f' && id[3] == 'i' && id[4] == 'n' && id[5] == 'e') macro = SyntaxState::MACRO_CONT; break; case 4: if(id[0] == 'e' && id[1] == 'l') if(id[2] == 'i' && id[3] == 'f') if(ifstack.GetCount() == 0) { IfState& ifstate = ifstack.Add(); ifstate.ifline = 0; ifstate.state = IfState::ELSE_ERROR; } else { IfState& ifstate = ifstack.Top(); if(ifstate.state == IfState::IF || ifstate.state == IfState::ELIF) { ifstate.state = IfState::ELIF; ifstate.iftext = WString().Cat() << sReadLn(ln) << ", " << ifstate.iftext; } else ifstate.state = IfState::ELSE_ERROR; } else if(id[2] == 's' && id[3] == 'e') if(ifstack.GetCount() == 0) { IfState& ifstate = ifstack.Add(); ifstate.ifline = 0; ifstate.state = IfState::ELSE_ERROR; } else { IfState& ifstate = ifstack.Top(); if(ifstate.state == IfState::IF || ifstate.state == IfState::ELIF) { ifstate.state = IfState::ELSE; ifstate.iftext = "#else, " + ifstate.iftext; } else ifstate.state = IfState::ELSE_ERROR; } break; case 5: if(id[0] == 'e' && id[1] == 'n' && id[2] == 'd' && id[3] == 'i' && id[4] == 'f') { int itop = ifstack.GetCount() - 1; if(itop < 0) { IfState& ifstate = ifstack.Add(); ifstate.ifline = 0; ifstate.state = IfState::ENDIF_ERROR; } else if(ifstack[itop].state != IfState::ENDIF_ERROR) ifstack.Trim(itop); } break; } } if(macro == SyntaxState::MACRO_CONT && !(p < e && e[-1] == '\\')) macro = SyntaxState::MACRO_END; for(;;) { if(comment) { p = strnext(p, e, '*'); if(!p) break; if(*++p == '/') { comment = false; p++; } } else { int pc = 0; for(;;) { if(p >= e) return; const wchar *pp; if(!iscidl(pc) && (pp = isstmt(p)) != NULL) { stmtline = line; spar = 0; pc = 0; p = pp; } else if(!iscidl(pc) && p[0] == 'n' && p[1] == 'a' && p[2] == 'm' && p[3] == 'e' && p[4] == 's' && p[5] == 'p' && p[6] == 'a' && p[7] == 'c' && p[8] == 'e' && !iscidl(p[9])) { was_namespace = true; p += 9; } else { int c = *p++; if(c == '/') break; if(c == '\'' || c == '\"') { p = eatstring(p - 1); if(p >= e) { string = true; return; } } else if(c == ';' && spar == 0) { seline = stmtline; endstmtline = line; stmtline = -1; was_namespace = false; } else if(c == '{') { if(was_namespace) { brk.Add(0); was_namespace = false; } else { cl++; brk.Add('}'); bid.Add(lindent + 1); } blk.Add() = line; stmtline = -1; par.Clear(); } else if(c == '}') { if(brk.GetCount()) { if(brk.Top()) { cl--; if(bid.GetCount() > 1) bid.Drop(); } brk.Drop(); } if(blk.GetCount()) blk.Drop(); stmtline = -1; par.Clear(); } else if(c == '(') { pl++; brk.Add(')'); Isx& m = par.Add(); m.line = line; m.pos = int(p - ln); spar++; } else if(c == '[') { bl++; brk.Add(']'); Isx& m = par.Add(); m.line = line; m.pos = int(p - ln); spar++; } else if(c == ')') { if(brk.GetCount()) { pl--; brk.Drop(); } if(par.GetCount()) par.Drop(); spar--; } else if(c == ']') { if(brk.GetCount()) { bl--; brk.Drop(); } if(par.GetCount()) par.Drop(); spar--; } pc = c; } } if(*p == '/') { linecomment = true; return; } if(*p == '*') { comment = true; p++; } } } }
int yylex(void) { int c; loop: c = Bgetc(bin); switch(c) { case Eof: return Eof; case '"': eatstring(); return TSTRING; case ' ': case '\t': case '\r': goto loop; case '\n': line++; goto loop; case '.': c = Bgetc(bin); Bungetc(bin); if(isdigit(c)) return numsym('.'); return '.'; case '#': eatnl(); goto loop; case '(': case ')': case ';': case ',': case '~': case '$': case '+': case '/': case '%': case '^': case '*': case '&': case '=': case '|': case '<': case '>': case '-': case ':': return c; case '\'': c = Bgetrune(bin); if(c == '\\') yylval.ival = escchar(Bgetc(bin)); else yylval.ival = c; c = Bgetc(bin); if(c != '\'') { diag("missing '"); Bungetc(bin); } return TCONST; default: return numsym(c); } }