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

📄 lexruby.cxx

📁 porting scintilla to qt
💻 CXX
📖 第 1 页 / 共 5 页
字号:
// Scintilla source code edit control/** @file LexRuby.cxx ** Lexer for Ruby. **/// Copyright 2001- by Clemens Wyss <wys@helbling.ch>// The License.txt file describes the conditions under which this software may be distributed.#include <stdlib.h>#include <string.h>#include <ctype.h>#include <stdio.h>#include <stdarg.h>#include "Platform.h"#include "PropSet.h"#include "Accessor.h"#include "KeyWords.h"#include "Scintilla.h"#include "SciLexer.h"#ifdef SCI_NAMESPACEusing namespace Scintilla;#endif//XXX Identical to Perl, put in common areastatic inline bool isEOLChar(char ch) {	return (ch == '\r') || (ch == '\n');}#define isSafeASCII(ch) ((unsigned int)(ch) <= 127)// This one's redundant, but makes for more readable code#define isHighBitChar(ch) ((unsigned int)(ch) > 127)static inline bool isSafeAlpha(char ch) {    return (isSafeASCII(ch) && isalpha(ch)) || ch == '_';}static inline bool isSafeAlnum(char ch) {    return (isSafeASCII(ch) && isalnum(ch)) || ch == '_';}static inline bool isSafeAlnumOrHigh(char ch) {    return isHighBitChar(ch) || isalnum(ch) || ch == '_';}static inline bool isSafeDigit(char ch) {    return isSafeASCII(ch) && isdigit(ch);}static inline bool isSafeWordcharOrHigh(char ch) {    // Error: scintilla's KeyWords.h includes '.' as a word-char    // we want to separate things that can take methods from the    // methods.    return isHighBitChar(ch) || isalnum(ch) || ch == '_';}static bool inline iswhitespace(char ch) {	return ch == ' ' || ch == '\t';}#define MAX_KEYWORD_LENGTH 200#define STYLE_MASK 63#define actual_style(style) (style & STYLE_MASK)static bool followsDot(unsigned int pos, Accessor &styler) {    styler.Flush();    for (; pos >= 1; --pos) {        int style = actual_style(styler.StyleAt(pos));        char ch;        switch (style) {            case SCE_RB_DEFAULT:                ch = styler[pos];                if (ch == ' ' || ch == '\t') {                    //continue                } else {                    return false;                }                break;                            case SCE_RB_OPERATOR:                return styler[pos] == '.';            default:                return false;        }    }    return false;}// Forward declarationsstatic bool keywordIsAmbiguous(const char *prevWord);static bool keywordDoStartsLoop(int pos,                                Accessor &styler);static bool keywordIsModifier(const char *word,                              int pos,                              Accessor &styler);static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {	char s[MAX_KEYWORD_LENGTH];    unsigned int i, j;	unsigned int lim = end - start + 1; // num chars to copy	if (lim >= MAX_KEYWORD_LENGTH) {		lim = MAX_KEYWORD_LENGTH - 1;	}	for (i = start, j = 0; j < lim; i++, j++) {		s[j] = styler[i];	}    s[j] = '\0';	int chAttr;	if (0 == strcmp(prevWord, "class"))		chAttr = SCE_RB_CLASSNAME;	else if (0 == strcmp(prevWord, "module"))		chAttr = SCE_RB_MODULE_NAME;	else if (0 == strcmp(prevWord, "def"))		chAttr = SCE_RB_DEFNAME;    else if (keywords.InList(s) && !followsDot(start - 1, styler)) {        if (keywordIsAmbiguous(s)            && keywordIsModifier(s, start, styler)) {                        // Demoted keywords are colored as keywords,            // but do not affect changes in indentation.            //            // Consider the word 'if':            // 1. <<if test ...>> : normal            // 2. <<stmt if test>> : demoted            // 3. <<lhs = if ...>> : normal: start a new indent level            // 4. <<obj.if = 10>> : color as identifer, since it follows '.'                        chAttr = SCE_RB_WORD_DEMOTED;        } else {            chAttr = SCE_RB_WORD;        }	} else        chAttr = SCE_RB_IDENTIFIER;	styler.ColourTo(end, chAttr);	if (chAttr == SCE_RB_WORD) {		strcpy(prevWord, s);	} else {		prevWord[0] = 0;	}    return chAttr;}//XXX Identical to Perl, put in common areastatic bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {	if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {		return false;	}	while (*val) {		if (*val != styler[pos++]) {			return false;		}		val++;	}	return true;}// Do Ruby better -- find the end of the line, work back,// and then check for leading white space// Precondition: the here-doc target can be indentedstatic bool lookingAtHereDocDelim(Accessor	   &styler,                                  int 			pos,                                  int 			lengthDoc,                                  const char   *HereDocDelim){    if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) {        return false;    }    while (--pos > 0) {        char ch = styler[pos];        if (isEOLChar(ch)) {            return true;        } else if (ch != ' ' && ch != '\t') {            return false;        }    }    return false;}//XXX Identical to Perl, put in common areastatic char opposite(char ch) {	if (ch == '(')		return ')';	if (ch == '[')		return ']';	if (ch == '{')		return '}';	if (ch == '<')		return '>';	return ch;}// Null transitions when we see we've reached the end// and need to relex the curr char.static void redo_char(int &i, char &ch, char &chNext, char &chNext2,                      int &state) {    i--;    chNext2 = chNext;    chNext = ch;    state = SCE_RB_DEFAULT;}static void advance_char(int &i, char &ch, char &chNext, char &chNext2) {    i++;    ch = chNext;    chNext = chNext2;}// precondition: startPos points to one after the EOL charstatic bool currLineContainsHereDelims(int& startPos,                                       Accessor &styler) {    if (startPos <= 1)        return false;    int pos;    for (pos = startPos - 1; pos > 0; pos--) {        char ch = styler.SafeGetCharAt(pos);        if (isEOLChar(ch)) {            // Leave the pointers where they are -- there are no            // here doc delims on the current line, even if            // the EOL isn't default style                        return false;        } else {            styler.Flush();            if (actual_style(styler.StyleAt(pos)) == SCE_RB_HERE_DELIM) {                break;            }        }    }    if (pos == 0) {        return false;    }    // Update the pointers so we don't have to re-analyze the string    startPos = pos;    return true;}// This class is used by the enter and exit methods, so it needs// to be hoisted out of the function.class QuoteCls {    public:    int  Count;    char Up;    char Down;    QuoteCls() {        this->New();    }    void New() {        Count = 0;        Up    = '\0';        Down  = '\0';    }    void Open(char u) {        Count++;        Up    = u;        Down  = opposite(Up);    }    QuoteCls(const QuoteCls& q) {        // copy constructor -- use this for copying in        Count = q.Count;        Up    = q.Up;        Down  = q.Down;    }    QuoteCls& operator=(const QuoteCls& q) { // assignment constructor        if (this != &q) {            Count = q.Count;            Up    = q.Up;            Down  = q.Down;        }		return *this;    }            };static void enterInnerExpression(int  *p_inner_string_types,                                 int  *p_inner_expn_brace_counts,                                 QuoteCls *p_inner_quotes,                                 int&  inner_string_count,                                 int&  state,                                 int&  brace_counts,                                 QuoteCls curr_quote                                 ) {    p_inner_string_types[inner_string_count] = state;    state = SCE_RB_DEFAULT;    p_inner_expn_brace_counts[inner_string_count] = brace_counts;    brace_counts = 0;    p_inner_quotes[inner_string_count] = curr_quote;    ++inner_string_count;}static void exitInnerExpression(int *p_inner_string_types,                                 int *p_inner_expn_brace_counts,                                 QuoteCls *p_inner_quotes,                                 int& inner_string_count,                                 int& state,                                 int&  brace_counts,                                 QuoteCls& curr_quote                                ) {    --inner_string_count;    state = p_inner_string_types[inner_string_count];    brace_counts = p_inner_expn_brace_counts[inner_string_count];    curr_quote = p_inner_quotes[inner_string_count];}static bool isEmptyLine(int pos,                        Accessor &styler) {	int spaceFlags = 0;	int lineCurrent = styler.GetLine(pos);	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);    return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0;}static bool RE_CanFollowKeyword(const char *keyword) {    if (!strcmp(keyword, "and")        || !strcmp(keyword, "begin")        || !strcmp(keyword, "break")        || !strcmp(keyword, "case")        || !strcmp(keyword, "do")        || !strcmp(keyword, "else")        || !strcmp(keyword, "elsif")        || !strcmp(keyword, "if")        || !strcmp(keyword, "next")        || !strcmp(keyword, "return")        || !strcmp(keyword, "when")        || !strcmp(keyword, "unless")        || !strcmp(keyword, "until")        || !strcmp(keyword, "not")        || !strcmp(keyword, "or")) {        return true;    }    return false;}// Look at chars up to but not including endPos// Don't look at styles in case we're looking forward

⌨️ 快捷键说明

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