aboutsummaryrefslogtreecommitdiffhomepage
path: root/lexers/LexDMIS.cxx
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2014-04-29 08:35:12 +1000
committerNeil <nyamatongwe@gmail.com>2014-04-29 08:35:12 +1000
commit54a59cf289b1af9ce32d79b60d90aa2e8b29fa4b (patch)
tree719256ee927df77e820ca778a8f8b7b0a0269ef7 /lexers/LexDMIS.cxx
parent6bf6dc4af23d63b608560e09cb5b382e496e1a19 (diff)
downloadscintilla-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.cxx355
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);