📄 lexperl.cxx.svn-base
字号:
}
// 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 == '`')
|| (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 (!isascii(chNext) || isalpha(chNext) || chNext == '#' || chNext == '$'
|| chNext == '_' || chNext == '+' || chNext == '-') {
state = SCE_PL_ARRAY;
} else if (chNext == ':' && chNext2 == ':') {
state = SCE_PL_ARRAY;
i += 2;
ch = styler.SafeGetCharAt(i);
chNext = styler.SafeGetCharAt(i + 1);
} else if (chNext != '{' && chNext != '[') {
styler.ColourTo(i, SCE_PL_ARRAY);
} else {
styler.ColourTo(i, SCE_PL_ARRAY);
}
backflag = BACK_NONE;
} else if (ch == '%') {
if (!isascii(chNext) || isalpha(chNext) || chNext == '#' || chNext == '$'
|| chNext == '_' || chNext == '!' || chNext == '^') {
state = SCE_PL_HASH;
i++;
ch = chNext;
chNext = chNext2;
} else if (chNext == ':' && chNext2 == ':') {
state = SCE_PL_HASH;
i += 2;
ch = styler.SafeGetCharAt(i);
chNext = styler.SafeGetCharAt(i + 1);
} 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 (chNext == ':' && chNext2 == ':') {
state = SCE_PL_SYMBOLTABLE;
i += 2;
ch = styler.SafeGetCharAt(i);
chNext = styler.SafeGetCharAt(i + 1);
} else if (!isascii(chNext) || 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 (!isascii(ch) || isalnum(ch)) {
if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
if (!isascii(ch) || 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 (!isascii(ch) || !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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -