📄 lextads3.cxx.svn-base
字号:
sc.Forward(2);
sc.SetState(endState);
return;
}
sc.Forward();
}
}
static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) {
sc.SetState(initState);
while (sc.More()) {
if (sc.ch == '\\') {
sc.Forward();
if (IsEOLSkip(sc)) {
return;
}
}
if (IsEOL(sc.ch, sc.chNext)) {
sc.SetState(endState);
return;
}
sc.Forward();
}
}
static void ColouriseTADS3Number(StyleContext &sc) {
int endState = sc.state;
bool inHexNumber = false;
bool seenE = false;
bool seenDot = sc.ch == '.';
sc.SetState(SCE_T3_NUMBER);
if (sc.More()) {
sc.Forward();
}
if (sc.chPrev == '0' && tolower(sc.ch) == 'x') {
inHexNumber = true;
sc.Forward();
}
while (sc.More()) {
if (inHexNumber) {
if (!IsAHexDigit(sc.ch)) {
break;
}
} else if (!isdigit(sc.ch)) {
if (!seenE && tolower(sc.ch) == 'e') {
seenE = true;
seenDot = true;
if (sc.chNext == '+' || sc.chNext == '-') {
sc.Forward();
}
} else if (!seenDot && sc.ch == '.') {
seenDot = true;
} else {
break;
}
}
sc.Forward();
}
sc.SetState(endState);
}
static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
int visibleChars = 0;
int bracketLevel = 0;
int lineState = 0;
unsigned int endPos = startPos + length;
int lineCurrent = styler.GetLine(startPos);
if (lineCurrent > 0) {
lineState = styler.GetLineState(lineCurrent-1);
}
StyleContext sc(startPos, length, initStyle, styler);
while (sc.More()) {
if (IsEOL(sc.ch, sc.chNext)) {
styler.SetLineState(lineCurrent, lineState);
lineCurrent++;
visibleChars = 0;
sc.Forward();
if (sc.ch == '\n') {
sc.Forward();
}
}
switch(sc.state) {
case SCE_T3_PREPROCESSOR:
case SCE_T3_LINE_COMMENT:
ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ?
SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
break;
case SCE_T3_S_STRING:
case SCE_T3_D_STRING:
case SCE_T3_X_STRING:
ColouriseTADS3String(sc, lineState);
visibleChars++;
break;
case SCE_T3_MSG_PARAM:
ColouriseTADS3MsgParam(sc, lineState);
break;
case SCE_T3_LIB_DIRECTIVE:
ColouriseTADS3LibDirective(sc, lineState);
break;
case SCE_T3_HTML_DEFAULT:
ColouriseTADS3HTMLTag(sc, lineState);
break;
case SCE_T3_HTML_STRING:
ColouriseTADSHTMLString(sc, lineState);
break;
case SCE_T3_BLOCK_COMMENT:
ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ?
SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
break;
case SCE_T3_DEFAULT:
case SCE_T3_X_DEFAULT:
if (IsASpaceOrTab(sc.ch)) {
sc.Forward();
} else if (sc.ch == '#' && visibleChars == 0) {
ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state);
} else if (sc.Match('/', '*')) {
ColouriseTADS3Comment(sc, sc.state);
visibleChars++;
} else if (sc.Match('/', '/')) {
ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state);
} else if (sc.ch == '"') {
bracketLevel = 0;
ColouriseTADS3String(sc, lineState);
visibleChars++;
} else if (sc.ch == '\'') {
ColouriseTADS3String(sc, lineState);
visibleChars++;
} else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0
&& sc.Match('>', '>')) {
sc.Forward(2);
sc.SetState(SCE_T3_D_STRING);
if (lineState & T3_INT_EXPRESSION_IN_TAG)
sc.SetState(SCE_T3_HTML_STRING);
lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION
|T3_INT_EXPRESSION_IN_TAG);
} else if (IsATADS3Operator(sc.ch)) {
if (sc.state == SCE_T3_X_DEFAULT) {
if (sc.ch == '(') {
bracketLevel++;
} else if (sc.ch == ')' && bracketLevel > 0) {
bracketLevel--;
}
}
ColouriseTADS3Operator(sc);
visibleChars++;
} else if (IsANumberStart(sc)) {
ColouriseTADS3Number(sc);
visibleChars++;
} else if (IsAWordStart(sc.ch)) {
ColouriseTADS3Keyword(sc, keywordlists, endPos);
visibleChars++;
} else if (sc.Match("...")) {
sc.SetState(SCE_T3_IDENTIFIER);
sc.Forward(3);
sc.SetState(SCE_T3_DEFAULT);
} else {
sc.Forward();
visibleChars++;
}
break;
default:
sc.SetState(SCE_T3_DEFAULT);
sc.Forward();
}
}
sc.Complete();
}
/*
TADS3 has two styles of top level block (TLB). Eg
// default style
silverKey : Key 'small silver key' 'small silver key'
"A small key glints in the sunlight. "
;
and
silverKey : Key {
'small silver key'
'small silver key'
"A small key glints in the sunlight. "
}
Some constructs mandate one or the other, but usually the author has may choose
either.
T3_SEENSTART is used to indicate that a braceless TLB has been (potentially)
seen and is also used to match the closing ';' of the default style.
T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of
what characters may be seen without incrementing the block level. The general
pattern is identifier <punc> identifier, acceptable punctuation characters
are ':', ',', '(' and ')'. No attempt is made to ensure that punctuation
characters are syntactically correct, eg parentheses match. A ')' always
signifies the start of a block. We just need to check if it is followed by a
'{', in which case we let the brace handling code handle the folding level.
expectingIdentifier == false && expectingIdentifier == false
Before the start of a TLB.
expectingIdentifier == true && expectingIdentifier == true
Currently in an identifier. Will accept identifier or punctuation.
expectingIdentifier == true && expectingIdentifier == false
Just seen a punctuation character & now waiting for an identifier to start.
expectingIdentifier == false && expectingIdentifier == truee
We were in an identifier and have seen space. Now waiting to see a punctuation
character
Space, comments & preprocessor directives are always acceptable and are
equivalent.
*/
static const int T3_SEENSTART = 1 << 12;
static const int T3_EXPECTINGIDENTIFIER = 1 << 13;
static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
static inline bool IsStringTransition(int s1, int s2) {
return s1 != s2
&& (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
|| s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT)
&& s2 != SCE_T3_LIB_DIRECTIVE
&& s2 != SCE_T3_MSG_PARAM
&& s2 != SCE_T3_HTML_TAG
&& s2 != SCE_T3_HTML_STRING;
}
static inline bool IsATADS3Punctuation(const int ch) {
return ch == ':' || ch == ',' || ch == '(' || ch == ')';
}
static inline bool IsAnIdentifier(const int style) {
return style == SCE_T3_IDENTIFIER
|| style == SCE_T3_USER1
|| style == SCE_T3_USER2
|| style == SCE_T3_USER3;
}
static inline bool IsAnOperator(const int style) {
return style == SCE_T3_OPERATOR || SCE_T3_BRACE;
}
static inline bool IsSpaceEquivalent(const int ch, const int style) {
return isspace(ch)
|| style == SCE_T3_BLOCK_COMMENT
|| style == SCE_T3_LINE_COMMENT
|| style == SCE_T3_PREPROCESSOR;
}
static char peekAhead(unsigned int startPos, unsigned int endPos,
Accessor &styler) {
for (unsigned int i = startPos; i < endPos; i++) {
int style = styler.StyleAt(i);
char ch = styler[i];
if (!IsSpaceEquivalent(ch, style)) {
if (IsAnIdentifier(style)) {
return 'a';
}
if (IsATADS3Punctuation(ch)) {
return ':';
}
if (ch == '{') {
return '{';
}
return '*';
}
}
return ' ';
}
static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
unsigned int endPos = startPos + length;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int seenStart = levelCurrent & T3_SEENSTART;
int expectingIdentifier = levelCurrent & T3_EXPECTINGIDENTIFIER;
int expectingPunctuation = levelCurrent & T3_EXPECTINGPUNCTUATION;
levelCurrent &= SC_FOLDLEVELNUMBERMASK;
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
char ch = chNext;
int stylePrev = style;
bool redo = false;
for (unsigned int i = startPos; i < endPos; i++) {
if (redo) {
redo = false;
i--;
} else {
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
}
bool atEOL = IsEOL(ch, chNext);
if (levelNext == SC_FOLDLEVELBASE) {
if (IsSpaceEquivalent(ch, style)) {
if (expectingPunctuation) {
expectingIdentifier = 0;
}
if (style == SCE_T3_BLOCK_COMMENT) {
levelNext++;
}
} else if (ch == '{') {
levelNext++;
seenStart = 0;
} else if (ch == '\'' || ch == '"' || ch == '[') {
levelNext++;
if (seenStart) {
redo = true;
}
} else if (ch == ';') {
seenStart = 0;
expectingIdentifier = 0;
expectingPunctuation = 0;
} else if (expectingIdentifier && expectingPunctuation) {
if (IsATADS3Punctuation(ch)) {
if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
levelNext++;
} else {
expectingPunctuation = 0;
}
} else if (!IsAnIdentifier(style)) {
levelNext++;
}
} else if (expectingIdentifier && !expectingPunctuation) {
if (!IsAnIdentifier(style)) {
levelNext++;
} else {
expectingPunctuation = T3_EXPECTINGPUNCTUATION;
}
} else if (!expectingIdentifier && expectingPunctuation) {
if (!IsATADS3Punctuation(ch)) {
levelNext++;
} else {
if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
levelNext++;
} else {
expectingIdentifier = T3_EXPECTINGIDENTIFIER;
expectingPunctuation = 0;
}
}
} else if (!expectingIdentifier && !expectingPunctuation) {
if (IsAnIdentifier(style)) {
seenStart = T3_SEENSTART;
expectingIdentifier = T3_EXPECTINGIDENTIFIER;
expectingPunctuation = T3_EXPECTINGPUNCTUATION;
}
}
if (levelNext != SC_FOLDLEVELBASE && style != SCE_T3_BLOCK_COMMENT) {
expectingIdentifier = 0;
expectingPunctuation = 0;
}
} else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart
&& ch == ';' && IsAnOperator(style)) {
levelNext--;
seenStart = 0;
} else if (style == SCE_T3_BLOCK_COMMENT) {
if (stylePrev != SCE_T3_BLOCK_COMMENT) {
levelNext++;
} else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelNext--;
}
} else if (ch == '\'' || ch == '"') {
if (IsStringTransition(style, stylePrev)) {
if (levelMinCurrent > levelNext) {
levelMinCurrent = levelNext;
}
levelNext++;
} else if (IsStringTransition(style, styleNext)) {
levelNext--;
}
} else if (IsAnOperator(style)) {
if (ch == '{' || ch == '[') {
// Measure the minimum before a '{' to allow
// folding on "} else {"
if (levelMinCurrent > levelNext) {
levelMinCurrent = levelNext;
}
levelNext++;
} else if (ch == '}' || ch == ']') {
levelNext--;
}
}
if (atEOL) {
if (seenStart && levelNext == SC_FOLDLEVELBASE) {
switch (peekAhead(i+1, endPos, styler)) {
case ' ':
case '{':
break;
case '*':
levelNext++;
break;
case 'a':
if (expectingPunctuation) {
levelNext++;
}
break;
case ':':
if (expectingIdentifier) {
levelNext++;
}
break;
}
if (levelNext != SC_FOLDLEVELBASE) {
expectingIdentifier = 0;
expectingPunctuation = 0;
}
}
int lev = levelMinCurrent | (levelNext | expectingIdentifier
| expectingPunctuation | seenStart) << 16;
if (levelMinCurrent < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelCurrent = levelNext;
levelMinCurrent = levelCurrent;
}
}
}
static const char * const tads3WordList[] = {
"TADS3 Keywords",
"User defined 1",
"User defined 2",
"User defined 3",
0
};
LexerModule lmTADS3(SCLEX_TADS3, ColouriseTADS3Doc, "tads3", FoldTADS3Doc, tads3WordList);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -