mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-10-31 11:34:05 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			234 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // SciTE - Scintilla based Text Editor
 | |
| // LexBullant.cxx - lexer for Bullant
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <stdio.h>
 | |
| #include <stdarg.h>
 | |
| #include <assert.h>
 | |
| #include <ctype.h>
 | |
| 
 | |
| #include "ILexer.h"
 | |
| #include "Scintilla.h"
 | |
| #include "SciLexer.h"
 | |
| 
 | |
| #include "WordList.h"
 | |
| #include "LexAccessor.h"
 | |
| #include "Accessor.h"
 | |
| #include "StyleContext.h"
 | |
| #include "CharacterSet.h"
 | |
| #include "LexerModule.h"
 | |
| 
 | |
| #ifdef SCI_NAMESPACE
 | |
| using namespace Scintilla;
 | |
| #endif
 | |
| 
 | |
| static int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
 | |
| 	char s[100];
 | |
| 	s[0] = '\0';
 | |
| 	for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
 | |
| 		s[i] = static_cast<char>(tolower(styler[start + i]));
 | |
| 		s[i + 1] = '\0';
 | |
| 	}
 | |
| 	int lev= 0;
 | |
| 	char chAttr = SCE_C_IDENTIFIER;
 | |
| 	if (isdigit(s[0]) || (s[0] == '.')){
 | |
| 		chAttr = SCE_C_NUMBER;
 | |
| 	}
 | |
| 	else {
 | |
| 		if (keywords.InList(s)) {
 | |
| 			chAttr = SCE_C_WORD;
 | |
| 			if (strcmp(s, "end") == 0)
 | |
| 				lev = -1;
 | |
| 			else if (strcmp(s, "method") == 0 ||
 | |
| 				strcmp(s, "case") == 0 ||
 | |
| 				strcmp(s, "class") == 0 ||
 | |
| 				strcmp(s, "debug") == 0 ||
 | |
| 				strcmp(s, "test") == 0 ||
 | |
| 				strcmp(s, "if") == 0 ||
 | |
| 				strcmp(s, "lock") == 0 ||
 | |
| 				strcmp(s, "transaction") == 0 ||
 | |
| 				strcmp(s, "trap") == 0 ||
 | |
| 				strcmp(s, "until") == 0 ||
 | |
| 				strcmp(s, "while") == 0)
 | |
| 				lev = 1;
 | |
| 		}
 | |
| 	}
 | |
| 	styler.ColourTo(end, chAttr);
 | |
| 	return lev;
 | |
| }
 | |
| 
 | |
| static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
 | |
| 	Accessor &styler) {
 | |
| 	WordList &keywords = *keywordlists[0];
 | |
| 
 | |
| 	styler.StartAt(startPos);
 | |
| 
 | |
| 	bool fold = styler.GetPropertyInt("fold") != 0;
 | |
| 	int lineCurrent = styler.GetLine(startPos);
 | |
| 	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 | |
| 	int levelCurrent = levelPrev;
 | |
| 
 | |
| 	int state = initStyle;
 | |
| 	if (state == SCE_C_STRINGEOL)	// Does not leak onto next line
 | |
| 		state = SCE_C_DEFAULT;
 | |
| 	char chPrev = ' ';
 | |
| 	char chNext = styler[startPos];
 | |
| 	unsigned int lengthDoc = startPos + length;
 | |
| 	int visibleChars = 0;
 | |
| 	styler.StartSegment(startPos);
 | |
| 	int endFoundThisLine = 0;
 | |
| 	for (unsigned int i = startPos; i < lengthDoc; i++) {
 | |
| 		char ch = chNext;
 | |
| 		chNext = styler.SafeGetCharAt(i + 1);
 | |
| 
 | |
| 		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
 | |
| 			// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
 | |
| 			// Avoid triggering two times on Dos/Win
 | |
| 			// End of line
 | |
| 			endFoundThisLine = 0;
 | |
| 			if (state == SCE_C_STRINGEOL) {
 | |
| 				styler.ColourTo(i, state);
 | |
| 				state = SCE_C_DEFAULT;
 | |
| 			}
 | |
| 			if (fold) {
 | |
| 				int lev = levelPrev;
 | |
| 				if (visibleChars == 0)
 | |
| 					lev |= SC_FOLDLEVELWHITEFLAG;
 | |
| 				if ((levelCurrent > levelPrev) && (visibleChars > 0))
 | |
| 					lev |= SC_FOLDLEVELHEADERFLAG;
 | |
| 				styler.SetLevel(lineCurrent, lev);
 | |
| 				lineCurrent++;
 | |
| 				levelPrev = levelCurrent;
 | |
| 			}
 | |
| 			visibleChars = 0;
 | |
| 
 | |
| /*			int indentBlock = GetLineIndentation(lineCurrent);
 | |
| 			if (blockChange==1){
 | |
| 				lineCurrent++;
 | |
| 				int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize);
 | |
| 			} else if (blockChange==-1) {
 | |
| 				indentBlock -= indentSize;
 | |
| 				if (indentBlock < 0)
 | |
| 					indentBlock = 0;
 | |
| 				SetLineIndentation(lineCurrent, indentBlock);
 | |
| 				lineCurrent++;
 | |
| 			}
 | |
| 			blockChange=0;
 | |
| */		}
 | |
| 		if (!(IsASCII(ch) && isspace(ch)))
 | |
| 			visibleChars++;
 | |
| 
 | |
| 		if (styler.IsLeadByte(ch)) {
 | |
| 			chNext = styler.SafeGetCharAt(i + 2);
 | |
| 			chPrev = ' ';
 | |
| 			i += 1;
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		if (state == SCE_C_DEFAULT) {
 | |
| 			if (iswordstart(ch)) {
 | |
| 				styler.ColourTo(i-1, state);
 | |
| 					state = SCE_C_IDENTIFIER;
 | |
| 			} else if (ch == '@' && chNext == 'o') {
 | |
| 				if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) {
 | |
| 					styler.ColourTo(i-1, state);
 | |
| 					state = SCE_C_COMMENT;
 | |
| 				}
 | |
| 			} else if (ch == '#') {
 | |
| 				styler.ColourTo(i-1, state);
 | |
| 				state = SCE_C_COMMENTLINE;
 | |
| 			} else if (ch == '\"') {
 | |
| 				styler.ColourTo(i-1, state);
 | |
| 				state = SCE_C_STRING;
 | |
| 			} else if (ch == '\'') {
 | |
| 				styler.ColourTo(i-1, state);
 | |
| 				state = SCE_C_CHARACTER;
 | |
| 			} else if (isoperator(ch)) {
 | |
| 				styler.ColourTo(i-1, state);
 | |
| 				styler.ColourTo(i, SCE_C_OPERATOR);
 | |
| 			}
 | |
| 		} else if (state == SCE_C_IDENTIFIER) {
 | |
| 			if (!iswordchar(ch)) {
 | |
| 				int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler);
 | |
| 				state = SCE_C_DEFAULT;
 | |
| 				chNext = styler.SafeGetCharAt(i + 1);
 | |
| 				if (ch == '#') {
 | |
| 					state = SCE_C_COMMENTLINE;
 | |
| 				} else if (ch == '\"') {
 | |
| 					state = SCE_C_STRING;
 | |
| 				} else if (ch == '\'') {
 | |
| 					state = SCE_C_CHARACTER;
 | |
| 				} else if (isoperator(ch)) {
 | |
| 					styler.ColourTo(i, SCE_C_OPERATOR);
 | |
| 				}
 | |
| 				if (endFoundThisLine == 0)
 | |
| 					levelCurrent+=levelChange;
 | |
| 				if (levelChange == -1)
 | |
| 					endFoundThisLine=1;
 | |
| 			}
 | |
| 		} else if (state == SCE_C_COMMENT) {
 | |
| 			if (ch == '@' && chNext == 'o') {
 | |
| 				if (styler.SafeGetCharAt(i+2) == 'n') {
 | |
| 					styler.ColourTo(i+2, state);
 | |
| 					state = SCE_C_DEFAULT;
 | |
| 					i+=2;
 | |
| 				}
 | |
| 			}
 | |
| 		} else if (state == SCE_C_COMMENTLINE) {
 | |
| 			if (ch == '\r' || ch == '\n') {
 | |
| 				endFoundThisLine = 0;
 | |
| 				styler.ColourTo(i-1, state);
 | |
| 				state = SCE_C_DEFAULT;
 | |
| 			}
 | |
| 		} else if (state == SCE_C_STRING) {
 | |
| 			if (ch == '\\') {
 | |
| 				if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
 | |
| 					i++;
 | |
| 					ch = chNext;
 | |
| 					chNext = styler.SafeGetCharAt(i + 1);
 | |
| 				}
 | |
| 			} else if (ch == '\"') {
 | |
| 				styler.ColourTo(i, state);
 | |
| 				state = SCE_C_DEFAULT;
 | |
| 			} else if (chNext == '\r' || chNext == '\n') {
 | |
| 				endFoundThisLine = 0;
 | |
| 				styler.ColourTo(i-1, SCE_C_STRINGEOL);
 | |
| 				state = SCE_C_STRINGEOL;
 | |
| 			}
 | |
| 		} else if (state == SCE_C_CHARACTER) {
 | |
| 			if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
 | |
| 				endFoundThisLine = 0;
 | |
| 				styler.ColourTo(i-1, SCE_C_STRINGEOL);
 | |
| 				state = SCE_C_STRINGEOL;
 | |
| 			} else if (ch == '\\') {
 | |
| 				if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
 | |
| 					i++;
 | |
| 					ch = chNext;
 | |
| 					chNext = styler.SafeGetCharAt(i + 1);
 | |
| 				}
 | |
| 			} else if (ch == '\'') {
 | |
| 				styler.ColourTo(i, state);
 | |
| 				state = SCE_C_DEFAULT;
 | |
| 			}
 | |
| 		}
 | |
| 		chPrev = ch;
 | |
| 	}
 | |
| 	styler.ColourTo(lengthDoc - 1, state);
 | |
| 
 | |
| 	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
 | |
| 	if (fold) {
 | |
| 		int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 | |
| 		//styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
 | |
| 		styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 | |
| 
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static const char * const bullantWordListDesc[] = {
 | |
| 	"Keywords",
 | |
| 	0
 | |
| };
 | |
| 
 | |
| LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
 |