diff options
-rw-r--r-- | Source/CMTextView.m | 4 | ||||
-rw-r--r-- | Source/SPEditorTokens.h | 1 | ||||
-rw-r--r-- | Source/SPEditorTokens.l | 251 |
3 files changed, 148 insertions, 108 deletions
diff --git a/Source/CMTextView.m b/Source/CMTextView.m index a1b6c9fe..336d3669 100644 --- a/Source/CMTextView.m +++ b/Source/CMTextView.m @@ -925,6 +925,7 @@ SYNTAX HIGHLIGHTING! NSColor *keywordColor = [NSColor colorWithDeviceRed:0.200 green:0.250 blue:1.000 alpha:1.000]; NSColor *backtickColor = [NSColor colorWithDeviceRed:0.0 green:0.0 blue:0.658 alpha:1.000]; NSColor *numericColor = [NSColor colorWithDeviceRed:0.506 green:0.263 blue:0.0 alpha:1.000]; + NSColor *variableColor = [NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:1.000]; NSColor *tokenColor; @@ -963,6 +964,9 @@ SYNTAX HIGHLIGHTING! case SPT_COMMENT: tokenColor = commentColor; break; + case SPT_VARIABLE: + tokenColor = variableColor; + break; default: tokenColor = nil; } diff --git a/Source/SPEditorTokens.h b/Source/SPEditorTokens.h index e4c8cc6b..44d0340f 100644 --- a/Source/SPEditorTokens.h +++ b/Source/SPEditorTokens.h @@ -16,3 +16,4 @@ #define SPT_WORD 7 #define SPT_OTHER 8 #define SPT_NUMERIC 9 +#define SPT_VARIABLE 10 diff --git a/Source/SPEditorTokens.l b/Source/SPEditorTokens.l index f9ca6608..8db6934a 100644 --- a/Source/SPEditorTokens.l +++ b/Source/SPEditorTokens.l @@ -31,8 +31,111 @@ alpha [a-z_\.À-゚] numeric ([+-]?(([0-9]+\.[0-9]+)|([0-9]*\.[0-9]+)|([0-9]+))(e[+-]?[0-9]+)?) ops "+"|"-"|"*"|"/" word [a-z_\.0-9À-゚@] -nonword [^a-z_0-9À-゚©#\n\t] -keyword (R(IGHT|E(GEXP|STRICT|NAME|TURN|P(EAT|LACE)|VOKE|QUIRE|FERENCES|LEASE|A(D(S|_WRITE)?|L))|LIKE|ANGE)|GR(OUP{s}BY|ANT)|XOR|M(I(NUTE_(MICROSECOND|SECOND)|DDLEINT)|OD(IFIES)?|EDIUM(BLOB|TEXT|INT)|A(STER_SSL_VERIFY_SERVER_CERT|TCH))|B(Y|I(GINT|NARY)|OTH|E(TWEEN|FORE)|LOB)|S(MALLINT|SL|HOW|CHEMA(S)?|T(RAIGHT_JOIN|ARTING)|P(ECIFIC|ATIAL)|E(NSITIVE|COND_MICROSECOND|T|PARATOR|LECT)|QL(STATE|_(BIG_RESULT|SMALL_RESULT|CALC_FOUND_ROWS)|EXCEPTION|WARNING)?)|H(IGH_PRIORITY|OUR_(MI(NUTE|CROSECOND)|SECOND)|AVING)|YEAR_MONTH|N(O(_WRITE_TO_BINLOG|T)|U(MERIC|LL)|ATURAL)|C(R(OSS|EATE)|H(ECK|A(R(ACTER)?|NGE))|O(N(STRAINT|TINUE|DITION|VERT)|L(UMN|LATE))|UR(RENT_(TIME(STAMP)?|DATE|USER)|SOR)|A(S(CADE|E)|LL))|T(R(IGGER|UE|AILING)|HEN|INY(BLOB|TEXT|INT)|O|ERMINATED|ABLE)|I(GNORE|S|N(SE(RT|NSITIVE)|NER|T(1|2|8|3|O|4|E(RVAL|GER))?|OUT|DEX|FILE)?|TERATE|F)|ZEROFILL|O(R(DER{s}BY)?|N|UT(ER|FILE)?|PTI(MIZE|ON(ALLY)?))|D(ROP|I(STINCT(ROW)?|V)|OUBLE|UAL|E(SC(RIBE)?|C(IMAL|LARE)?|TERMINISTIC|FAULT|L(ETE|AYED))|A(Y_(MI(NUTE|CROSECOND)|SECOND|HOUR)|TABASE(S)?))|U(S(ING|E|AGE)|N(SIGNED|I(ON|QUE)|DO|LOCK)|TC_(TIME(STAMP)?|DATE)|PDATE)|JOIN|P(R(IMARY|OCEDURE|ECISION)|URGE)|E(X(I(STS|T)|PLAIN)|SCAPED|NCLOSED|LSE(IF)?|ACH)|VA(R(BINARY|YING|CHAR(ACTER)?)|LUES)|K(ILL|EY(S)?)|F(ROM|OR(CE|EIGN)?|ULLTEXT|ETCH|LOAT(8|4)?|ALSE)|W(RITE|H(ILE|E(RE|N))|ITH)|L(I(MIT|NE(S|AR)|KE)|O(NG(BLOB|TEXT)?|C(K|ALTIME(STAMP)?)|OP|W_PRIORITY|AD)|E(FT|A(DING|VE)))|A(S(C|ENSITIVE)?|N(D|ALYZE)|CCESSIBLE|DD|L(TER|L))) +variable @{1,2}[a-z_\.0-9À-゚$]+ +nonword [^a-z_0-9À-゚#\n\t] +keyword (R(IGHT|E(GEXP|S(T(RICT|ORE{s}TABLE)|ET)|NAME|TURN|P(EAT|LACE|AIR)|VOKE|QUIRE|FERENCES|LEASE|A(D(S|_WRITE)?|L))|LIKE|ANGE)|G(R(OUP{s}BY|ANT)|LOBAL)|XOR|M(I(NUTE_(MICROSECOND|SECOND)|DDLEINT)|OD(IFIES)?|EDIUM(BLOB|TEXT|INT)|A(STER_SSL_VERIFY_SERVER_CERT|TCH))|B(Y|I(GINT|NARY)|OTH|E(TWEEN|FORE)|LOB|ACKUP{s}TABLE)|S(MALLINT|SL|HOW({s}(E(NGINE(S)?|RRORS)|M(ASTER|UTEX)|BINLOG|GRANTS|INNODB|P(RIVILEGES|ROFILE(S)?|ROCEDURE{s}CODE)|SLAVE{s}(HOSTS|STATUS)|TRIGGERS|VARIABLES|WARNINGS))?|CHEMA(S)?|T(RAIGHT_JOIN|A(RTING{s}BY|TUS))|P(ECIFIC|ATIAL)|E(SSION|NSITIVE|COND_MICROSECOND|T({s}(PASSWORD|NAMES|ONE_SHOT))?|PARATOR|LECT)|QL(STATE|_(B(IG_RESULT|UFFER_RESULT)|SMALL_RESULT|NO_CACHE|CA(CHE|LC_FOUND_ROWS))|EXCEPTION|WARNING)?)|H(IGH_PRIORITY|OUR_(MI(NUTE|CROSECOND)|SECOND)|A(NDLER|VING))|YEAR_MONTH|N(O(_WRITE_TO_BINLOG|T)|U(MERIC|LL)|EXT|ATURAL)|C(R(OSS|EATE)|H(ECK(SUM{s}TABLE)?|A(R(ACTER)?|NGE))|O(N(STRAINT|CURRENT|TINUE|DITION|VERT)|L(UMN|LATE))|UR(RENT_(TIME(STAMP)?|DATE|USER)|SOR)|LOSE|A(S(CADE|E)|CHE{s}INDEX|LL))|T(R(IGGER|UE|AILING)|HEN|INY(BLOB|TEXT|INT)|O|ERMINATED{s}BY|ABLE)|I(GNORE|S|N(SE(RT|NSITIVE)|NER|T(1|2|8|3|O({s}(DUMP|OUT)FILE)?|4|E(RVAL|GER))?|OUT|DEX|FILE)?|TERATE|F)|ZEROFILL|O(R(DER{s}BY)?|N{s}(DUPLICATE{s}KEY{s}UPDATE)?|UT(ER|FILE)?|P(TI(MIZE|ON(ALLY)?)|EN)|FFSET)|D(ROP|I(STINCT(ROW)?|V)|O(UBLE)?|UAL|E(SC(RIBE)?|C(IMAL|LARE)?|TERMINISTIC|FAULT|L(ETE|AYED))|A(Y_(MI(NUTE|CROSECOND)|SECOND|HOUR)|TABASE(S)?))|U(S(ING|E|AGE)|N(SIGNED|I(ON|QUE)|DO|LOCK)|TC_(TIME(STAMP)?|DATE)|PDATE)|JOIN|P(R(IMARY|OCEDURE|E(CISION|PARE|V))|URGE)|E(X(I(STS|T)|PLAIN|ECUTE)|SCAPED{s}BY|NCLOSED{s}BY|LSE(IF)?|ACH)|VA(R(BINARY|YING|CHAR(ACTER)?)|LUES)|K(ILL({s}(CONNECTION|QUERY))?|EY(S)?)|QUICK|F(ROM|IRST|OR(CE|EIGN)?|ULLTEXT|ETCH|L(OAT(8|4)?|USH)|ALSE)|W(RITE|H(ILE|E(RE|N))|ITH)|L(I(MIT|NE(S|AR)|KE)|O(GS|NG(BLOB|TEXT)?|C(K|AL(TIME(STAMP)?)?)|OP|W_PRIORITY|AD{s}(DATA|INDEX{s}INTO{s}CACHE))|E(FT|A(DING|VE))|AST)|A(S(C|ENSITIVE)?|N(D|ALYZE)|CCESSIBLE|DD|L(TER|L))) + + +%x comment +%x equation +%x varequation +%% +\"([^"\\]|\\(.|\n))*\"? { return SPT_DOUBLE_QUOTED_TEXT; } /* double quoted strings */ +'([^'\\]|\\(.|\n))*'? { return SPT_SINGLE_QUOTED_TEXT; } /* single quoted strings */ +`[^`]*`? { return SPT_BACKTICK_QUOTED_TEXT; } /* identifier quoting */ + +"/*" { BEGIN(comment); return SPT_COMMENT; } /* beginning of a c style comment */ +<comment>[^*]* { return SPT_COMMENT; } /* anything except * in a c cmnt */ +<comment>"*"+ { return SPT_COMMENT; } /* a range of * */ +<comment>"*"+"/" { BEGIN(INITIAL); return SPT_COMMENT; } /* a range of * with trailing / + Thanks to John Dickinson for publishing + this method of parsing C comments on + http://www.stillhq.com/pdfdb/000561/data.pdf + */ + +#[^\n]*\n? | /* # Comments */ +--[ \t][^\n]*\n? { return SPT_COMMENT; } /* -- Comments */ + +{variable}/{ops} { BEGIN(varequation); return SPT_VARIABLE; }/* SQL variables before operator*/ +<varequation>{ops} { BEGIN(INITIAL); return SPT_OTHER; } +{variable} { return SPT_VARIABLE; } /* SQL variables */ + +{numeric}/{ops} { BEGIN(equation); return SPT_NUMERIC; } /* numeric before operator */ +<equation>{ops} { BEGIN(INITIAL); return SPT_OTHER; } /* set operator after a numeric */ +{numeric}/{alpha} { return SPT_WORD; } /* catch numeric followed by char */ + +{s}+ { return SPT_WHITESPACE; } /* ignore spaces */ + +{keyword} { return SPT_RESERVED_WORD; } /* all the mysql reserved words */ + +{numeric} { return SPT_NUMERIC; } /* single numeric value */ + +{word}+ { return SPT_WORD; } /* return any word */ + +{nonword} { return SPT_OTHER; } /* return anything else */ + + + +<<EOF>> { + BEGIN(INITIAL); /* make sure we return to initial state when finished! */ + yy_delete_buffer(YY_CURRENT_BUFFER); + return 0; + } +%% + +#define ONEMASK ((size_t)(-1) / 0xFF) +// adapted from http://www.daemonology.net/blog/2008-06-05-faster-utf8-strlen.html +int utf8strlen(const char * _s) +{ + const char * s; + size_t count = 0; + size_t u; + unsigned char b; + + /* Handle any initial misaligned bytes. */ + for (s = _s; (uintptr_t)(s) & (sizeof(size_t) - 1); s++) { + b = *s; + + /* Exit if we hit a zero byte. */ + if (b == '\0') + goto done; + + /* Is this byte NOT the first byte of a character? */ + count += (b >> 7) & ((~b) >> 6); + } + + /* Handle complete blocks. */ + for (; ; s += sizeof(size_t)) { + /* Prefetch 256 bytes ahead. */ + __builtin_prefetch(&s[256], 0, 0); + + /* Grab 4 or 8 bytes of UTF-8 data. */ + u = *(size_t *)(s); + + /* Exit the loop if there are any zero bytes. */ + if ((u - ONEMASK) & (~u) & (ONEMASK * 0x80)) + break; + + /* Count bytes which are NOT the first byte of a character. */ + u = ((u & (ONEMASK * 0x80)) >> 7) & ((~u) >> 6); + count += (u * ONEMASK) >> ((sizeof(size_t) - 1) * 8); + } + + /* Take care of any left-over bytes. */ + for (; ; s++) { + b = *s; + + /* Exit if we hit a zero byte. */ + if (b == '\0') + break; + + /* Is this byte NOT the first byte of a character? */ + count += (b >> 7) & ((~b) >> 6); + } + +done: + return ((s - _s) - count); +} /* un-optimized keywords: ADD @@ -45,6 +148,7 @@ AND AS ASC ASENSITIVE +BACKUP{s}TABLE BEFORE BETWEEN BIGINT @@ -53,14 +157,18 @@ BLOB BOTH BY CALL +CACHE{s}INDEX CASCADE CASE CHANGE CHAR CHARACTER CHECK +CHECKSUM{s}TABLE +CLOSE COLLATE COLUMN +CONCURRENT CONDITION CONSTRAINT CONTINUE @@ -90,29 +198,35 @@ DETERMINISTIC DISTINCT DISTINCTROW DIV +DO DOUBLE DROP DUAL EACH ELSE ELSEIF -ENCLOSED -ESCAPED +ENCLOSED{s}BY +ESCAPED{s}BY +EXECUTE EXISTS EXIT EXPLAIN FALSE FETCH +FIRST FLOAT FLOAT4 FLOAT8 +FLUSH FOR FORCE FOREIGN FROM FULLTEXT +GLOBAL GRANT GROUP{s}BY +HANDLER HAVING HIGH_PRIORITY HOUR_MICROSECOND @@ -135,13 +249,14 @@ INT4 INT8 INTEGER INTERVAL -INTO +INTO({s}(DUMP|OUT)FILE)? IS ITERATE JOIN KEY KEYS -KILL +KILL({s}(CONNECTION|QUERY))? +LAST LEADING LEAVE LEFT @@ -149,10 +264,12 @@ LIKE LIMIT LINEAR LINES -LOAD +LOAD{s}(DATA|INDEX{s}INTO{s}CACHE) +LOCAL LOCALTIME LOCALTIMESTAMP LOCK +LOGS LONG LONGBLOB LONGTEXT @@ -169,11 +286,14 @@ MINUTE_SECOND MOD MODIFIES NATURAL +NEXT NOT NO_WRITE_TO_BINLOG NULL NUMERIC -ON +OFFSET +ON{s}(DUPLICATE{s}KEY{s}UPDATE)? +OPEN OPTIMIZE OPTION OPTIONALLY @@ -183,9 +303,12 @@ OUT OUTER OUTFILE PRECISION +PREPARE +PREV PRIMARY PROCEDURE PURGE +QUICK RANGE READ READS @@ -195,9 +318,12 @@ REFERENCES REGEXP RELEASE RENAME +REPAIR REPEAT REPLACE REQUIRE +RESET +RESTORE{s}TABLE RESTRICT RETURN REVOKE @@ -209,8 +335,9 @@ SECOND_MICROSECOND SELECT SENSITIVE SEPARATOR -SET -SHOW +SESSION +SET({s}(PASSWORD|NAMES|ONE_SHOT))? +SHOW({s}(E(NGINE(S)?|RRORS)|M(ASTER|UTEX)|BINLOG|GRANTS|INNODB|P(RIVILEGES|ROFILE(S)?|ROCEDURE{s}CODE)|SLAVE{s}(HOSTS|STATUS)|TRIGGERS|VARIABLES|WARNINGS))? SMALLINT SPATIAL SPECIFIC @@ -219,13 +346,17 @@ SQLEXCEPTION SQLSTATE SQLWARNING SQL_BIG_RESULT +SQL_BUFFER_RESULT +SQL_CACHE SQL_CALC_FOUND_ROWS +SQL_NO_CACHE SQL_SMALL_RESULT SSL -STARTING +STARTING{s}BY +STATUS STRAIGHT_JOIN TABLE -TERMINATED +TERMINATED{s}BY THEN TINYBLOB TINYINT @@ -260,99 +391,3 @@ XOR YEAR_MONTH ZEROFILL */ - -%x comment -%x equation -%% -\"([^"\\]|\\(.|\n))*\"? { return SPT_DOUBLE_QUOTED_TEXT; } /* double quoted strings */ -'([^'\\]|\\(.|\n))*'? { return SPT_SINGLE_QUOTED_TEXT; } /* single quoted strings */ -`[^`]*`? { return SPT_BACKTICK_QUOTED_TEXT; } /* identifier quoting */ - -"/*" { BEGIN(comment); return SPT_COMMENT; } /* beginning of a c style comment */ -<comment>[^*]* { return SPT_COMMENT; } /* anything except * in a c cmnt */ -<comment>"*"+ { return SPT_COMMENT; } /* a range of * */ -<comment>"*"+"/" { BEGIN(INITIAL); return SPT_COMMENT; } /* a range of * with trailing / - Thanks to John Dickinson for publishing - this method of parsing C comments on - http://www.stillhq.com/pdfdb/000561/data.pdf - */ - -#[^\n]*\n? | /* # Comments */ ---[ \t][^\n]*\n? { return SPT_COMMENT; } /* -- Comments */ - -{numeric}/{ops} { BEGIN(equation); return SPT_NUMERIC; } /* numeric before operator */ -<equation>{ops} { BEGIN(INITIAL); return SPT_OTHER; } /* set operator after a numeric */ -{numeric}/{alpha} { return SPT_WORD; } /* catch numeric followed by char */ - -{s}+ { return SPT_WHITESPACE; } /* ignore spaces */ - -{keyword} { return SPT_RESERVED_WORD; } /* all the mysql reserved words */ - -{numeric} { return SPT_NUMERIC; } /* single numeric value */ - -{word}+ { return SPT_WORD; } /* return any word */ - -{nonword} { return SPT_OTHER; } /* return anything else */ - - - -<<EOF>> { - BEGIN(INITIAL); /* make sure we return to initial state when finished! */ - yy_delete_buffer(YY_CURRENT_BUFFER); - return 0; - } -%% - -#define ONEMASK ((size_t)(-1) / 0xFF) -// adapted from http://www.daemonology.net/blog/2008-06-05-faster-utf8-strlen.html -int utf8strlen(const char * _s) -{ - const char * s; - size_t count = 0; - size_t u; - unsigned char b; - - /* Handle any initial misaligned bytes. */ - for (s = _s; (uintptr_t)(s) & (sizeof(size_t) - 1); s++) { - b = *s; - - /* Exit if we hit a zero byte. */ - if (b == '\0') - goto done; - - /* Is this byte NOT the first byte of a character? */ - count += (b >> 7) & ((~b) >> 6); - } - - /* Handle complete blocks. */ - for (; ; s += sizeof(size_t)) { - /* Prefetch 256 bytes ahead. */ - __builtin_prefetch(&s[256], 0, 0); - - /* Grab 4 or 8 bytes of UTF-8 data. */ - u = *(size_t *)(s); - - /* Exit the loop if there are any zero bytes. */ - if ((u - ONEMASK) & (~u) & (ONEMASK * 0x80)) - break; - - /* Count bytes which are NOT the first byte of a character. */ - u = ((u & (ONEMASK * 0x80)) >> 7) & ((~u) >> 6); - count += (u * ONEMASK) >> ((sizeof(size_t) - 1) * 8); - } - - /* Take care of any left-over bytes. */ - for (; ; s++) { - b = *s; - - /* Exit if we hit a zero byte. */ - if (b == '\0') - break; - - /* Is this byte NOT the first byte of a character? */ - count += (b >> 7) & ((~b) >> 6); - } - -done: - return ((s - _s) - count); -} |