⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexruby.cxx

📁 porting scintilla to qt
💻 CXX
📖 第 1 页 / 共 5 页
字号:
static int skipWhitespace(int startPos,                           int endPos,                           Accessor &styler) {    for (int i = startPos; i < endPos; i++) {        if (!iswhitespace(styler[i])) {            return i;        }    }    return endPos;}    // This routine looks for false positives like// undef foo, <<// There aren't too many.//// iPrev points to the start of <<static bool sureThisIsHeredoc(int iPrev,                              Accessor &styler,                              char *prevWord) {                        // Not so fast, since Ruby's so dynamic.  Check the context    // to make sure we're OK.    int prevStyle;    int lineStart = styler.GetLine(iPrev);    int lineStartPosn = styler.LineStart(lineStart);    styler.Flush();    // Find the first word after some whitespace    int firstWordPosn = skipWhitespace(lineStartPosn, iPrev, styler);    if (firstWordPosn >= iPrev) {        // Have something like {^     <<}		//XXX Look at the first previous non-comment non-white line		// to establish the context.  Not too likely though.        return true;    } else {        switch (prevStyle = styler.StyleAt(firstWordPosn)) {        case SCE_RB_WORD:        case SCE_RB_WORD_DEMOTED:        case SCE_RB_IDENTIFIER:            break;        default:            return true;        }    }    int firstWordEndPosn = firstWordPosn;    char *dst = prevWord;    for (;;) {        if (firstWordEndPosn >= iPrev ||            styler.StyleAt(firstWordEndPosn) != prevStyle) {            *dst = 0;            break;        }        *dst++ = styler[firstWordEndPosn];        firstWordEndPosn += 1;    }    //XXX Write a style-aware thing to regex scintilla buffer objects    if (!strcmp(prevWord, "undef")        || !strcmp(prevWord, "def")        || !strcmp(prevWord, "alias")) {        // These keywords are what we were looking for        return false;    }    return true;}// Routine that saves us from allocating a buffer for the here-doc target// targetEndPos points one past the end of the current targetstatic bool haveTargetMatch(int currPos,                            int lengthDoc,                            int targetStartPos,                            int targetEndPos,                            Accessor &styler) {    if (lengthDoc - currPos < targetEndPos - targetStartPos) {        return false;    }    int i, j;    for (i = targetStartPos, j = currPos;         i < targetEndPos && j < lengthDoc;         i++, j++) {        if (styler[i] != styler[j]) {            return false;        }    }    return true;}// We need a check because the form// [identifier] <<[target]// is ambiguous.  The Ruby lexer/parser resolves it by// looking to see if [identifier] names a variable or a// function.  If it's the first, it's the start of a here-doc.// If it's a var, it's an operator.  This lexer doesn't// maintain a symbol table, so it looks ahead to see what's// going on, in cases where we have// ^[white-space]*[identifier([.|::]identifier)*][white-space]*<<[target]//// If there's no occurrence of [target] on a line, assume we don't.// return true == yes, we have no heredocsstatic bool sureThisIsNotHeredoc(int lt2StartPos,                                 Accessor &styler) {    int prevStyle;     // Use full document, not just part we're styling    int lengthDoc = styler.Length();    int lineStart = styler.GetLine(lt2StartPos);    int lineStartPosn = styler.LineStart(lineStart);    styler.Flush();    const bool definitely_not_a_here_doc = true;    const bool looks_like_a_here_doc = false;        // Find the first word after some whitespace    int firstWordPosn = skipWhitespace(lineStartPosn, lt2StartPos, styler);    if (firstWordPosn >= lt2StartPos) {        return definitely_not_a_here_doc;    }    prevStyle = styler.StyleAt(firstWordPosn);    // If we have '<<' following a keyword, it's not a heredoc    if (prevStyle != SCE_RB_IDENTIFIER) {        return definitely_not_a_here_doc;    }    int newStyle = prevStyle;    // Some compilers incorrectly warn about uninit newStyle    for (firstWordPosn += 1; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {        // Inner loop looks at the name        for (; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {            newStyle = styler.StyleAt(firstWordPosn);            if (newStyle != prevStyle) {                break;            }        }        // Do we have '::' or '.'?        if (firstWordPosn < lt2StartPos && newStyle == SCE_RB_OPERATOR) {            char ch = styler[firstWordPosn];            if (ch == '.') {                // yes            } else if (ch == ':') {                if (styler.StyleAt(++firstWordPosn) != SCE_RB_OPERATOR) {                    return definitely_not_a_here_doc;                } else if (styler[firstWordPosn] != ':') {                    return definitely_not_a_here_doc;                }            } else {                break;            }        } else {            break;        }    }    // Skip next batch of white-space    firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);    if (firstWordPosn != lt2StartPos) {        // Have [[^ws[identifier]ws[*something_else*]ws<<        return definitely_not_a_here_doc;    }    // OK, now 'j' will point to the current spot moving ahead	int j = firstWordPosn + 1;    if (styler.StyleAt(j) != SCE_RB_OPERATOR || styler[j] != '<') {        // This shouldn't happen        return definitely_not_a_here_doc;    }    int nextLineStartPosn = styler.LineStart(lineStart + 1);    if (nextLineStartPosn >= lengthDoc) {        return definitely_not_a_here_doc;    }    j = skipWhitespace(j + 1, nextLineStartPosn, styler);    if (j >= lengthDoc) {        return definitely_not_a_here_doc;    }    bool allow_indent;    int target_start, target_end;    // From this point on no more styling, since we're looking ahead    if (styler[j] == '-') {        allow_indent = true;        j++;    } else {        allow_indent = false;    }    // Allow for quoted targets.    char target_quote = 0;    switch (styler[j]) {    case '\'':    case '"':    case '`':        target_quote = styler[j];        j += 1;    }        if (isSafeAlnum(styler[j])) {        // Init target_end because some compilers think it won't        // be initialized by the time it's used        target_start = target_end = j;        j++;    } else {        return definitely_not_a_here_doc;    }    for (; j < lengthDoc; j++) {        if (!isSafeAlnum(styler[j])) {            if (target_quote && styler[j] != target_quote) {                // unquoted end                return definitely_not_a_here_doc;            }            // And for now make sure that it's a newline            // don't handle arbitrary expressions yet                        target_end = j;			if (target_quote) {				// Now we can move to the character after the string delimiter.				j += 1;			}            j = skipWhitespace(j, lengthDoc, styler);            if (j >= lengthDoc) {                return definitely_not_a_here_doc;            } else {                char ch = styler[j];                if (ch == '#' || isEOLChar(ch)) {                    // This is OK, so break and continue;                    break;                } else {                    return definitely_not_a_here_doc;                }            }        }    }    // Just look at the start of each line    int last_line = styler.GetLine(lengthDoc - 1);    // But don't go too far    if (last_line > lineStart + 50) {        last_line = lineStart + 50;    }    for (int line_num = lineStart + 1; line_num <= last_line; line_num++) {        if (allow_indent) {            j = skipWhitespace(styler.LineStart(line_num), lengthDoc, styler);        } else {            j = styler.LineStart(line_num);        }        // target_end is one past the end        if (haveTargetMatch(j, lengthDoc, target_start, target_end, styler)) {            // We got it            return looks_like_a_here_doc;        }    }    return definitely_not_a_here_doc;}//todo: if we aren't looking at a stdio character,// move to the start of the first line that is not in a // multi-line constructstatic void synchronizeDocStart(unsigned int& startPos,                                int &length,                                int &initStyle,                                Accessor &styler,                                bool skipWhiteSpace=false) {    styler.Flush();    int style = actual_style(styler.StyleAt(startPos));    switch (style) {        case SCE_RB_STDIN:        case SCE_RB_STDOUT:        case SCE_RB_STDERR:            // Don't do anything else with these.            return;    }        int pos = startPos;    // Quick way to characterize each line    int lineStart;    for (lineStart = styler.GetLine(pos); lineStart > 0; lineStart--) {        // Now look at the style before the previous line's EOL        pos = styler.LineStart(lineStart) - 1;        if (pos <= 10) {            lineStart = 0;            break;        }        char ch = styler.SafeGetCharAt(pos);        char chPrev = styler.SafeGetCharAt(pos - 1);        if (ch == '\n' && chPrev == '\r') {            pos--;        }        if (styler.SafeGetCharAt(pos - 1) == '\\') {            // Continuation line -- keep going        } else if (actual_style(styler.StyleAt(pos)) != SCE_RB_DEFAULT) {            // Part of multi-line construct -- keep going        } else if (currLineContainsHereDelims(pos, styler)) {            // Keep going, with pos and length now pointing            // at the end of the here-doc delimiter        } else if (skipWhiteSpace && isEmptyLine(pos, styler)) {            // Keep going        } else {            break;        }    }    pos = styler.LineStart(lineStart);    length += (startPos - pos);    startPos = pos;    initStyle = SCE_RB_DEFAULT;}static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,						   WordList *keywordlists[], Accessor &styler) {	// Lexer for Ruby often has to backtrack to start of current style to determine	// which characters are being used as quotes, how deeply nested is the	// start position and what the termination string is for here documents    	WordList &keywords = *keywordlists[0];	class HereDocCls {	public:		int State;        // States        // 0: '<<' encountered		// 1: collect the delimiter        // 1b: text between the end of the delimiter and the EOL		// 2: here doc text (lines after the delimiter)		char Quote;		// the char after '<<'		bool Quoted;		// true if Quote in ('\'','"','`')		int DelimiterLength;	// strlen(Delimiter)		char Delimiter[256];	// the Delimiter, limit of 256: from Perl        bool CanBeIndented;		HereDocCls() {			State = 0;			DelimiterLength = 0;			Delimiter[0] = '\0';            CanBeIndented = false;		}	};	HereDocCls HereDoc;		QuoteCls Quote;    int numDots = 0;  // For numbers --                      // Don't start lexing in the middle of a num    synchronizeDocStart(startPos, length, initStyle, styler, // ref args                        false);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -