diff options
author | mjroberts <devnull@localhost> | 2007-02-21 00:36:50 +0000 |
---|---|---|
committer | mjroberts <devnull@localhost> | 2007-02-21 00:36:50 +0000 |
commit | c01f866544c0dd428ef37baa24952e547f9da9de (patch) | |
tree | 9058c611acf342f6ee81aa6832b749ea15d1c193 /src | |
parent | 5657ed9c68de4ba1c324493a3d8262be89c56b9f (diff) | |
download | scintilla-mirror-c01f866544c0dd428ef37baa24952e547f9da9de.tar.gz |
fixed the lexer to handle many tads 3 syntax constructs better;
fixed some folding problems; added a separate 'brace' style
Diffstat (limited to 'src')
-rw-r--r-- | src/LexTADS3.cxx | 99 |
1 files changed, 83 insertions, 16 deletions
diff --git a/src/LexTADS3.cxx b/src/LexTADS3.cxx index 77c438510..85a669589 100644 --- a/src/LexTADS3.cxx +++ b/src/LexTADS3.cxx @@ -48,11 +48,43 @@ static const int T3_SINGLE_QUOTE = 1; static const int T3_INT_EXPRESSION = 2; +static const int T3_INT_EXPRESSION_IN_TAG = 4; +static const int T3_HTML_SQUOTE = 8; static inline bool IsEOL(const int ch, const int chNext) { return (ch == '\r' && chNext != '\n') || (ch == '\n'); } +/* + * Test the current character to see if it's the START of an EOL sequence; + * if so, skip ahead to the last character of the sequence and return true, + * and if not just return false. There are a few places where we want to + * check to see if a newline sequence occurs at a particular point, but + * where a caller expects a subroutine to stop only upon reaching the END + * of a newline sequence (in particular, CR-LF on Windows). That's why + * IsEOL() above only returns true on CR if the CR isn't followed by an LF + * - it doesn't want to admit that there's a newline until reaching the END + * of the sequence. We meet both needs by saying that there's a newline + * when we see the CR in a CR-LF, but skipping the CR before returning so + * that the caller's caller will see that we've stopped at the LF. + */ +static inline bool IsEOLSkip(StyleContext &sc) +{ + /* test for CR-LF */ + if (sc.ch == '\r' && sc.chNext == '\n') + { + /* got CR-LF - skip the CR and indicate that we're at a newline */ + sc.Forward(); + return true; + } + + /* + * in other cases, we have at most a 1-character newline, so do the + * normal IsEOL test + */ + return IsEOL(sc.ch, sc.chNext); +} + static inline bool IsASpaceOrTab(const int ch) { return ch == ' ' || ch == '\t'; } @@ -94,29 +126,35 @@ static inline bool IsANumberStart(StyleContext &sc) { inline static void ColouriseTADS3Operator(StyleContext &sc) { int initState = sc.state; - sc.SetState(SCE_T3_OPERATOR); + int c = sc.ch; + sc.SetState(c == '{' || c == '}' ? SCE_T3_BRACE : SCE_T3_OPERATOR); sc.ForwardSetState(initState); } static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) { int endState = sc.state; int chQuote = sc.ch; + int chString = (lineState & T3_SINGLE_QUOTE) ? '\'' : '"'; if (endState == SCE_T3_HTML_STRING) { if (lineState&T3_SINGLE_QUOTE) { endState = SCE_T3_S_STRING; - chQuote = '"'; + chString = '\''; } else if (lineState&T3_INT_EXPRESSION) { endState = SCE_T3_X_STRING; - chQuote = '\''; + chString = '"'; } else { - endState = SCE_T3_D_STRING; - chQuote = '\''; + endState = SCE_T3_HTML_DEFAULT; + chString = '"'; } + chQuote = (lineState & T3_HTML_SQUOTE) ? '\'' : '"'; } else { sc.SetState(SCE_T3_HTML_STRING); sc.Forward(); } - int chString = chQuote == '"'? '\'': '"'; + if (chQuote == '"') + lineState &= ~T3_HTML_SQUOTE; + else + lineState |= T3_HTML_SQUOTE; while (sc.More()) { if (IsEOL(sc.ch, sc.chNext)) { @@ -126,12 +164,26 @@ static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) { sc.ForwardSetState(endState); return; } + if (sc.Match('\\', chQuote)) { + sc.Forward(2); + sc.SetState(endState); + return; + } if (sc.ch == chString) { - sc.SetState(endState); + sc.SetState(SCE_T3_DEFAULT); return; } + + if (sc.Match('<', '<')) { + lineState |= T3_INT_EXPRESSION | T3_INT_EXPRESSION_IN_TAG; + sc.SetState(SCE_T3_X_DEFAULT); + sc.Forward(2); + return; + } + if (sc.Match('\\', static_cast<char>(chQuote)) - || sc.Match('\\', static_cast<char>(chString))) { + || sc.Match('\\', static_cast<char>(chString)) + || sc.Match('\\', '\\')) { sc.Forward(2); } else { sc.Forward(); @@ -198,7 +250,12 @@ static void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) { sc.SetState(endState); return; } - if (sc.ch == chString) { + if (sc.Match('\\', chQuote)) { + sc.Forward(); + ColouriseTADSHTMLString(sc, lineState); + if (sc.state == SCE_T3_X_DEFAULT) + break; + } else if (sc.ch == chString) { ColouriseTADSHTMLString(sc, lineState); } else if (sc.ch == '=') { ColouriseTADS3Operator(sc); @@ -368,14 +425,17 @@ static void ColouriseTADS3String(StyleContext &sc, int &lineState) { sc.Forward(2); return; } - if (sc.Match('\\', static_cast<char>(chQuote))) { + if (sc.Match('\\', static_cast<char>(chQuote)) + || sc.Match('\\', '\\')) { sc.Forward(2); } else if (sc.ch == '{') { ColouriseTADS3MsgParam(sc, lineState); } else if (sc.Match('<', '.')) { ColouriseTADS3LibDirective(sc, lineState); } else if (sc.ch == '<') { - ColouriseTADS3HTMLTag(sc, lineState); + ColouriseTADS3HTMLTag(sc, lineState); + if (sc.state == SCE_T3_X_DEFAULT) + return; } else { sc.Forward(); } @@ -402,7 +462,7 @@ static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) while (sc.More()) { if (sc.ch == '\\') { sc.Forward(); - if (IsEOL(sc.ch, sc.chNext)) { + if (IsEOLSkip(sc)) { return; } } @@ -524,12 +584,15 @@ static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle, && sc.Match('>', '>')) { sc.Forward(2); sc.SetState(SCE_T3_D_STRING); - lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION); + 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 == ')') { + } else if (sc.ch == ')' && bracketLevel > 0) { bracketLevel--; } } @@ -630,6 +693,10 @@ static inline bool IsAnIdentifier(const int style) { || 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 @@ -751,7 +818,7 @@ static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle, } } else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart - && ch == ';' && style == SCE_T3_OPERATOR ) { + && ch == ';' && IsAnOperator(style)) { levelNext--; seenStart = 0; } else if (style == SCE_T3_BLOCK_COMMENT) { @@ -770,7 +837,7 @@ static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle, } else if (IsStringTransition(style, styleNext)) { levelNext--; } - } else if (style == SCE_T3_OPERATOR) { + } else if (IsAnOperator(style)) { if (ch == '{' || ch == '[') { // Measure the minimum before a '{' to allow // folding on "} else {" |