123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- // Scintilla source code edit control
- /** @file LexDMIS.cxx
- ** Lexer for DMIS.
- **/
- // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
- // Copyright 2013-2014 by Andreas Tscharner <andy@vis.ethz.ch>
- // The License.txt file describes the conditions under which this software may be distributed.
- #include <cstdlib>
- #include <cassert>
- #include <cstring>
- #include <cctype>
- #include "ILexer.h"
- #include "Scintilla.h"
- #include "SciLexer.h"
- #include "WordList.h"
- #include "LexAccessor.h"
- #include "StyleContext.h"
- #include "CharacterSet.h"
- #include "LexerModule.h"
- #ifdef SCI_NAMESPACE
- using namespace Scintilla;
- #endif
- static const char *const DMISWordListDesc[] = {
- "DMIS Major Words",
- "DMIS Minor Words",
- "Unsupported DMIS Major Words",
- "Unsupported DMIS Minor Words",
- "Keywords for code folding start",
- "Corresponding keywords for code folding end",
- 0
- };
- class LexerDMIS : public ILexer
- {
- private:
- char *m_wordListSets;
- WordList m_majorWords;
- WordList m_minorWords;
- WordList m_unsupportedMajor;
- WordList m_unsupportedMinor;
- WordList m_codeFoldingStart;
- WordList m_codeFoldingEnd;
- char * SCI_METHOD UpperCase(char *item);
- void SCI_METHOD InitWordListSets(void);
- public:
- LexerDMIS(void);
- virtual ~LexerDMIS(void);
- int SCI_METHOD Version() const {
- return lvOriginal;
- }
- void SCI_METHOD Release() {
- delete this;
- }
- const char * SCI_METHOD PropertyNames() {
- return NULL;
- }
- int SCI_METHOD PropertyType(const char *) {
- return -1;
- }
- const char * SCI_METHOD DescribeProperty(const char *) {
- return NULL;
- }
- Sci_Position SCI_METHOD PropertySet(const char *, const char *) {
- return -1;
- }
- Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
- void * SCI_METHOD PrivateCall(int, void *) {
- return NULL;
- }
- static ILexer *LexerFactoryDMIS() {
- return new LexerDMIS;
- }
- const char * SCI_METHOD DescribeWordListSets();
- void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess);
- void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess);
- };
- char * SCI_METHOD LexerDMIS::UpperCase(char *item)
- {
- char *itemStart;
- itemStart = item;
- while (item && *item) {
- *item = toupper(*item);
- item++;
- };
- return itemStart;
- }
- void SCI_METHOD LexerDMIS::InitWordListSets(void)
- {
- size_t totalLen = 0;
- for (int i=0; DMISWordListDesc[i]; i++) {
- totalLen += strlen(DMISWordListDesc[i]);
- totalLen++;
- };
- totalLen++;
- this->m_wordListSets = new char[totalLen];
- memset(this->m_wordListSets, 0, totalLen);
- for (int i=0; DMISWordListDesc[i]; i++) {
- strcat(this->m_wordListSets, DMISWordListDesc[i]);
- strcat(this->m_wordListSets, "\n");
- };
- }
- LexerDMIS::LexerDMIS(void) {
- this->InitWordListSets();
- this->m_majorWords.Clear();
- this->m_minorWords.Clear();
- this->m_unsupportedMajor.Clear();
- this->m_unsupportedMinor.Clear();
- this->m_codeFoldingStart.Clear();
- this->m_codeFoldingEnd.Clear();
- }
- LexerDMIS::~LexerDMIS(void) {
- delete[] this->m_wordListSets;
- }
- Sci_Position SCI_METHOD LexerDMIS::WordListSet(int n, const char *wl)
- {
- switch (n) {
- case 0:
- this->m_majorWords.Clear();
- this->m_majorWords.Set(wl);
- break;
- case 1:
- this->m_minorWords.Clear();
- this->m_minorWords.Set(wl);
- break;
- case 2:
- this->m_unsupportedMajor.Clear();
- this->m_unsupportedMajor.Set(wl);
- break;
- case 3:
- this->m_unsupportedMinor.Clear();
- this->m_unsupportedMinor.Set(wl);
- break;
- case 4:
- this->m_codeFoldingStart.Clear();
- this->m_codeFoldingStart.Set(wl);
- break;
- case 5:
- this->m_codeFoldingEnd.Clear();
- this->m_codeFoldingEnd.Set(wl);
- break;
- default:
- return -1;
- break;
- }
- return 0;
- }
- const char * SCI_METHOD LexerDMIS::DescribeWordListSets()
- {
- return this->m_wordListSets;
- }
- void SCI_METHOD LexerDMIS::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess)
- {
- const Sci_PositionU MAX_STR_LEN = 100;
- LexAccessor styler(pAccess);
- StyleContext scCTX(startPos, lengthDoc, initStyle, styler);
- CharacterSet setDMISNumber(CharacterSet::setDigits, ".-+eE");
- CharacterSet setDMISWordStart(CharacterSet::setAlpha, "-234", 0x80, true);
- CharacterSet setDMISWord(CharacterSet::setAlpha);
- bool isIFLine = false;
- for (; scCTX.More(); scCTX.Forward()) {
- if (scCTX.atLineEnd) {
- isIFLine = false;
- };
- switch (scCTX.state) {
- case SCE_DMIS_DEFAULT:
- if (scCTX.Match('$', '$')) {
- scCTX.SetState(SCE_DMIS_COMMENT);
- scCTX.Forward();
- };
- if (scCTX.Match('\'')) {
- scCTX.SetState(SCE_DMIS_STRING);
- };
- if (IsADigit(scCTX.ch) || ((scCTX.Match('-') || scCTX.Match('+')) && IsADigit(scCTX.chNext))) {
- scCTX.SetState(SCE_DMIS_NUMBER);
- break;
- };
- if (setDMISWordStart.Contains(scCTX.ch)) {
- scCTX.SetState(SCE_DMIS_KEYWORD);
- };
- if (scCTX.Match('(') && (!isIFLine)) {
- scCTX.SetState(SCE_DMIS_LABEL);
- };
- break;
- case SCE_DMIS_COMMENT:
- if (scCTX.atLineEnd) {
- scCTX.SetState(SCE_DMIS_DEFAULT);
- };
- break;
- case SCE_DMIS_STRING:
- if (scCTX.Match('\'')) {
- scCTX.SetState(SCE_DMIS_DEFAULT);
- };
- break;
- case SCE_DMIS_NUMBER:
- if (!setDMISNumber.Contains(scCTX.ch)) {
- scCTX.SetState(SCE_DMIS_DEFAULT);
- };
- break;
- case SCE_DMIS_KEYWORD:
- if (!setDMISWord.Contains(scCTX.ch)) {
- char tmpStr[MAX_STR_LEN];
- memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
- scCTX.GetCurrent(tmpStr, (MAX_STR_LEN-1));
- strncpy(tmpStr, this->UpperCase(tmpStr), (MAX_STR_LEN-1));
- if (this->m_minorWords.InList(tmpStr)) {
- scCTX.ChangeState(SCE_DMIS_MINORWORD);
- };
- if (this->m_majorWords.InList(tmpStr)) {
- isIFLine = (strcmp(tmpStr, "IF") == 0);
- scCTX.ChangeState(SCE_DMIS_MAJORWORD);
- };
- if (this->m_unsupportedMajor.InList(tmpStr)) {
- scCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MAJOR);
- };
- if (this->m_unsupportedMinor.InList(tmpStr)) {
- scCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MINOR);
- };
- if (scCTX.Match('(') && (!isIFLine)) {
- scCTX.SetState(SCE_DMIS_LABEL);
- } else {
- scCTX.SetState(SCE_DMIS_DEFAULT);
- };
- };
- break;
- case SCE_DMIS_LABEL:
- if (scCTX.Match(')')) {
- scCTX.SetState(SCE_DMIS_DEFAULT);
- };
- break;
- };
- };
- scCTX.Complete();
- }
- void SCI_METHOD LexerDMIS::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *pAccess)
- {
- const int MAX_STR_LEN = 100;
- LexAccessor styler(pAccess);
- Sci_PositionU endPos = startPos + lengthDoc;
- char chNext = styler[startPos];
- Sci_Position lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- int strPos = 0;
- bool foldWordPossible = false;
- CharacterSet setDMISFoldWord(CharacterSet::setAlpha);
- char *tmpStr;
- tmpStr = new char[MAX_STR_LEN];
- memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
- for (Sci_PositionU i=startPos; i<endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i+1);
- bool atEOL = ((ch == '\r' && chNext != '\n') || (ch == '\n'));
- if (strPos >= (MAX_STR_LEN-1)) {
- strPos = MAX_STR_LEN-1;
- };
- int style = styler.StyleAt(i);
- bool noFoldPos = ((style == SCE_DMIS_COMMENT) || (style == SCE_DMIS_STRING));
- if (foldWordPossible) {
- if (setDMISFoldWord.Contains(ch)) {
- tmpStr[strPos++] = ch;
- } else {
- tmpStr = this->UpperCase(tmpStr);
- if (this->m_codeFoldingStart.InList(tmpStr) && (!noFoldPos)) {
- levelCurrent++;
- };
- if (this->m_codeFoldingEnd.InList(tmpStr) && (!noFoldPos)) {
- levelCurrent--;
- };
- memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
- strPos = 0;
- foldWordPossible = false;
- };
- } else {
- if (setDMISFoldWord.Contains(ch)) {
- tmpStr[strPos++] = ch;
- foldWordPossible = true;
- };
- };
- if (atEOL || (i == (endPos-1))) {
- int lev = levelPrev;
- if (levelCurrent > levelPrev) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- };
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- };
- lineCurrent++;
- levelPrev = levelCurrent;
- };
- };
- delete[] tmpStr;
- }
- LexerModule lmDMIS(SCLEX_DMIS, LexerDMIS::LexerFactoryDMIS, "DMIS", DMISWordListDesc);
|