📄 lexperl.cxx
字号:
} // a keyword } else if (state == SCE_PL_WORD) { i = kw - 1; if (ch == '_' && chNext == '_' && (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__DATA__") || isMatch(styler, lengthDoc, styler.GetStartSegment(), "__END__"))) { styler.ColourTo(i, SCE_PL_DATASECTION); state = SCE_PL_DATASECTION; } else { styler.ColourTo(i, SCE_PL_WORD); state = SCE_PL_DEFAULT; backflag = BACK_KEYWORD; backPos = i; } ch = styler.SafeGetCharAt(i); chNext = styler.SafeGetCharAt(i + 1); // a repetition operator 'x' } else if (state == SCE_PL_OPERATOR) { styler.ColourTo(i, SCE_PL_OPERATOR); state = SCE_PL_DEFAULT; // quote-like delimiter, skip one char if double-char delimiter } else { i = kw - 1; chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '#') { state = SCE_PL_COMMENTLINE; } else if (ch == '\"') { state = SCE_PL_STRING; Quote.New(1); Quote.Open(ch); backflag = BACK_NONE; } else if (ch == '\'') { if (chPrev == '&') { // Archaic call styler.ColourTo(i, state); } else { state = SCE_PL_CHARACTER; Quote.New(1); Quote.Open(ch); } backflag = BACK_NONE; } else if (ch == '`') { state = SCE_PL_BACKTICKS; Quote.New(1); Quote.Open(ch); backflag = BACK_NONE; } else if (ch == '$') { if ((chNext == '{') || isspacechar(chNext)) { styler.ColourTo(i, SCE_PL_SCALAR); } else { state = SCE_PL_SCALAR; if (chNext == '`' && chNext2 == '`') { i += 2; ch = styler.SafeGetCharAt(i); chNext = styler.SafeGetCharAt(i + 1); } else { i++; ch = chNext; chNext = chNext2; } } backflag = BACK_NONE; } else if (ch == '@') { if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_' || chNext == '+' || chNext == '-') { state = SCE_PL_ARRAY; } else if (chNext != '{' && chNext != '[') { styler.ColourTo(i, SCE_PL_ARRAY); } else { styler.ColourTo(i, SCE_PL_ARRAY); } backflag = BACK_NONE; } else if (ch == '%') { if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_' || chNext == '!' || chNext == '^') { state = SCE_PL_HASH; i++; ch = chNext; chNext = chNext2; } else if (chNext == '{') { styler.ColourTo(i, SCE_PL_HASH); } else { styler.ColourTo(i, SCE_PL_OPERATOR); } backflag = BACK_NONE; } else if (ch == '*') { char strch[2]; strch[0] = chNext; strch[1] = '\0'; if (isalpha(chNext) || chNext == '_' || NULL != strstr("^/|,\\\";#%^:?<>)[]", strch)) { state = SCE_PL_SYMBOLTABLE; i++; ch = chNext; chNext = chNext2; } else if (chNext == '{') { styler.ColourTo(i, SCE_PL_SYMBOLTABLE); } else { if (chNext == '*') { // exponentiation i++; ch = chNext; chNext = chNext2; } styler.ColourTo(i, SCE_PL_OPERATOR); } backflag = BACK_NONE; } else if (ch == '/' || (ch == '<' && chNext == '<')) { // Explicit backward peeking to set a consistent preferRE for // any slash found, so no longer need to track preferRE state. // Find first previous significant lexed element and interpret. // Test for HERE doc start '<<' shares this code, helps to // determine if it should be an operator. bool preferRE = false; bool isHereDoc = (ch == '<'); bool hereDocSpace = false; // these are for corner case: bool hereDocScalar = false; // SCALAR [whitespace] '<<' unsigned int bk = (i > 0)? i - 1: 0; char bkch; styler.Flush(); if (styler.StyleAt(bk) == SCE_PL_DEFAULT) hereDocSpace = true; while ((bk > 0) && (styler.StyleAt(bk) == SCE_PL_DEFAULT || styler.StyleAt(bk) == SCE_PL_COMMENTLINE)) { bk--; } if (bk == 0) { // position 0 won't really be checked; rarely happens // hard to fix due to an unsigned index i preferRE = true; } else { int bkstyle = styler.StyleAt(bk); bkch = styler.SafeGetCharAt(bk); switch(bkstyle) { case SCE_PL_OPERATOR: preferRE = true; if (bkch == ')' || bkch == ']') { preferRE = false; } else if (bkch == '}') { // backtrack further, count balanced brace pairs // if a brace pair found, see if it's a variable int braceCount = 1; while (--bk > 0) { bkstyle = styler.StyleAt(bk); if (bkstyle == SCE_PL_OPERATOR) { bkch = styler.SafeGetCharAt(bk); if (bkch == ';') { // early out break; } else if (bkch == '}') { braceCount++; } else if (bkch == '{') { if (--braceCount == 0) break; } } } if (bk == 0) { // at beginning, true } else if (braceCount == 0) { // balanced { found, bk>0, skip more whitespace if (styler.StyleAt(--bk) == SCE_PL_DEFAULT) { while (bk > 0) { bkstyle = styler.StyleAt(--bk); if (bkstyle != SCE_PL_DEFAULT) break; } } bkstyle = styler.StyleAt(bk); if (bkstyle == SCE_PL_SCALAR || bkstyle == SCE_PL_ARRAY || bkstyle == SCE_PL_HASH || bkstyle == SCE_PL_SYMBOLTABLE || bkstyle == SCE_PL_OPERATOR) { preferRE = false; } } } break; case SCE_PL_IDENTIFIER: preferRE = true; if (bkch == '>') { // inputsymbol preferRE = false; break; } // backtrack to find "->" or "::" before identifier while (bk > 0 && styler.StyleAt(bk) == SCE_PL_IDENTIFIER) { bk--; } while (bk > 0) { bkstyle = styler.StyleAt(bk); if (bkstyle == SCE_PL_DEFAULT || bkstyle == SCE_PL_COMMENTLINE) { } else if (bkstyle == SCE_PL_OPERATOR) { // gcc 3.2.3 bloats if more compact form used bkch = styler.SafeGetCharAt(bk); if (bkch == '>') { // "->" if (styler.SafeGetCharAt(bk - 1) == '-') { preferRE = false; break; } } else if (bkch == ':') { // "::" if (styler.SafeGetCharAt(bk - 1) == ':') { preferRE = false; break; } } } else {// bare identifier, usually a function call but Perl // optimizes them as pseudo-constants, then the next // '/' will be a divide; favour divide over regex // if there is a whitespace after the '/' if (isspacechar(chNext)) { preferRE = false; } break; } bk--; } break; case SCE_PL_SCALAR: // for $var<< case hereDocScalar = true; break; // other styles uses the default, preferRE=false case SCE_PL_WORD: case SCE_PL_POD: case SCE_PL_POD_VERB: case SCE_PL_HERE_Q: case SCE_PL_HERE_QQ: case SCE_PL_HERE_QX: preferRE = true; break; } } if (isHereDoc) { // handle HERE doc // if SCALAR whitespace '<<', *always* a HERE doc if (preferRE || (hereDocSpace && hereDocScalar)) { state = SCE_PL_HERE_DELIM; HereDoc.State = 0; } else { // << operator i++; ch = chNext; chNext = chNext2; styler.ColourTo(i, SCE_PL_OPERATOR); } } else { // handle regexp if (preferRE) { state = SCE_PL_REGEX; Quote.New(1); Quote.Open(ch); } else { // / operator styler.ColourTo(i, SCE_PL_OPERATOR); } } backflag = BACK_NONE; } else if (ch == '<') { // looks forward for matching > on same line unsigned int fw = i + 1; while (fw < lengthDoc) { char fwch = styler.SafeGetCharAt(fw); if (fwch == ' ') { if (styler.SafeGetCharAt(fw-1) != '\\' || styler.SafeGetCharAt(fw-2) != '\\') break; } else if (isEOLChar(fwch) || isspacechar(fwch)) { break; } else if (fwch == '>') { if ((fw - i) == 2 && // '<=>' case styler.SafeGetCharAt(fw-1) == '=') { styler.ColourTo(fw, SCE_PL_OPERATOR); } else { styler.ColourTo(fw, SCE_PL_IDENTIFIER); } i = fw; ch = fwch; chNext = styler.SafeGetCharAt(i+1); } fw++; } styler.ColourTo(i, SCE_PL_OPERATOR); backflag = BACK_NONE; } else if (ch == '=' // POD && isalpha(chNext) && (isEOLChar(chPrev))) { state = SCE_PL_POD; backflag = BACK_NONE; //sookedpos = 0; //sooked[sookedpos] = '\0'; } else if (ch == '-' // file test operators && isSingleCharOp(chNext) && !isalnum((chNext2 = styler.SafeGetCharAt(i+2)))) { styler.ColourTo(i + 1, SCE_PL_WORD); state = SCE_PL_DEFAULT; i++; ch = chNext; chNext = chNext2; backflag = BACK_NONE; } else if (isPerlOperator(ch)) { if (ch == '.' && chNext == '.') { // .. and ... i++; if (chNext2 == '.') { i++; } state = SCE_PL_DEFAULT; ch = styler.SafeGetCharAt(i); chNext = styler.SafeGetCharAt(i + 1); } styler.ColourTo(i, SCE_PL_OPERATOR); backflag = BACK_OPERATOR; backPos = i; } else { // keep colouring defaults to make restart easier styler.ColourTo(i, SCE_PL_DEFAULT); } } else if (state == SCE_PL_NUMBER) { if (ch == '.') { if (chNext == '.') { // double dot is always an operator goto numAtEnd; } else if (numState <= PERLNUM_FLOAT) { // non-decimal number or float exponent, consume next dot styler.ColourTo(i - 1, SCE_PL_NUMBER); styler.ColourTo(i, SCE_PL_OPERATOR); state = SCE_PL_DEFAULT; } else { // decimal or vectors allows dots dotCount++; if (numState == PERLNUM_DECIMAL) { if (dotCount > 1) { if (isdigit(chNext)) { // really a vector numState = PERLNUM_VECTOR; } else // number then dot goto numAtEnd; } } else { // vectors if (!isdigit(chNext)) // vector then dot goto numAtEnd; } } } else if (ch == '_' && numState == PERLNUM_DECIMAL) { if (!isdigit(chNext)) { goto numAtEnd; } } else if (isalnum(ch)) { if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) { if (isalpha(ch)) { if (dotCount == 0) { // change to word state = SCE_PL_IDENTIFIER; } else { // vector then word goto numAtEnd; } } } else if (numState == PERLNUM_DECIMAL) { if (ch == 'E' || ch == 'e') { // exponent numState = PERLNUM_FLOAT; if (chNext == '+' || chNext == '-') { i++; ch = chNext; chNext = chNext2; } } else if (!isdigit(ch)) { // number then word goto numAtEnd; } } else if (numState == PERLNUM_FLOAT) { if (!isdigit(ch)) { // float then word goto numAtEnd; } } else if (numState == PERLNUM_OCTAL) { if (!isdigit(ch)) goto numAtEnd; else if (ch > '7') numState = PERLNUM_BAD; } else if (numState == PERLNUM_BINARY) { if (!isdigit(ch)) goto numAtEnd; else if (ch > '1') numState = PERLNUM_BAD; } else if (numState == PERLNUM_HEX) { int ch2 = toupper(ch); if (!isdigit(ch) && !(ch2 >= 'A' && ch2 <= 'F')) goto numAtEnd; } else {//(numState == PERLNUM_BAD) { if (!isdigit(ch)) goto numAtEnd; } } else { // complete current number or vector numAtEnd: styler.ColourTo(i - 1, actualNumStyle(numState)); state = SCE_PL_DEFAULT; goto restartLexer; } } else if (state == SCE_PL_IDENTIFIER) { if (!iswordstart(chNext) && chNext != '\'') { styler.ColourTo(i, SCE_PL_IDENTIFIER); state = SCE_PL_DEFAULT; ch = ' '; } } else { if (state == SCE_PL_COMMENTLINE) { if (isEOLChar(ch)) { styler.ColourTo(i - 1, state); state = SCE_PL_DEFAULT; goto restartLexer; } else if (isEOLChar(chNext)) { styler.ColourTo(i, state); state = SCE_PL_DEFAULT; } } else if (state == SCE_PL_HERE_DELIM) { // // From perldata.pod: // ------------------ // A line-oriented form of quoting is based on the shell ``here-doc'' // syntax. // Following a << you specify a string to terminate the quoted material,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -