diff options
author | Neil <nyamatongwe@gmail.com> | 2014-04-29 08:35:12 +1000 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2014-04-29 08:35:12 +1000 |
commit | 54a59cf289b1af9ce32d79b60d90aa2e8b29fa4b (patch) | |
tree | 719256ee927df77e820ca778a8f8b7b0a0269ef7 /lexers/LexDMIS.cxx | |
parent | 6bf6dc4af23d63b608560e09cb5b382e496e1a19 (diff) | |
download | scintilla-mirror-54a59cf289b1af9ce32d79b60d90aa2e8b29fa4b.tar.gz |
Feature [feature-requests:#1049]. Lexer added for DMIS, a language for coordinate
measuring machines.
From Andreas Tscharner.
Diffstat (limited to 'lexers/LexDMIS.cxx')
-rw-r--r-- | lexers/LexDMIS.cxx | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/lexers/LexDMIS.cxx b/lexers/LexDMIS.cxx new file mode 100644 index 000000000..38526154d --- /dev/null +++ b/lexers/LexDMIS.cxx @@ -0,0 +1,355 @@ +// 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 "SciLexer.h" +#include "Scintilla.h" + +#include "LexerModule.h" +#include "LexAccessor.h" +#include "StyleContext.h" +#include "CharacterSet.h" +#include "WordList.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; + } + + int SCI_METHOD PropertySet(const char *, const char *) { + return -1; + } + + int 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(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess); + void SCI_METHOD Fold(unsigned int startPos, int 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; +} + +int 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(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) +{ + const unsigned int MAX_STR_LEN = 100; + + LexAccessor styler(pAccess); + StyleContext scCTX(startPos, lengthDoc, initStyle, styler); + CharacterSet setDMISNumber(CharacterSet::setDigits, ".-+eE"); + CharacterSet setDMISWordStart(CharacterSet::setAlpha, "-", 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(unsigned int startPos, int lengthDoc, int, IDocument *pAccess) +{ + const int MAX_STR_LEN = 100; + + LexAccessor styler(pAccess); + unsigned int endPos = startPos + lengthDoc; + char chNext = styler[startPos]; + int 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 (unsigned int 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); |