Advertisement
Guest User

Untitled

a guest
Jul 30th, 2015
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.75 KB | None | 0 0
  1. // Scintilla source code edit control
  2. /** @file LexTorqueScript.cxx
  3. ** Lexer for C++, C, Java, and JavaScript.
  4. ** Further folding features and configuration properties added by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  5. **/
  6. // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
  7. // The License.txt file describes the conditions under which this software may be distributed.
  8.  
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. #include <stdio.h>
  13. #include <stdarg.h>
  14. #include <assert.h>
  15.  
  16. #include <string>
  17. #include <vector>
  18. #include <map>
  19. #include <algorithm>
  20.  
  21. #include "ILexer.h"
  22. #include "Scintilla.h"
  23. #include "SciLexer.h"
  24.  
  25. #include "WordList.h"
  26. #include "LexAccessor.h"
  27. #include "Accessor.h"
  28. #include "StyleContext.h"
  29. #include "CharacterSet.h"
  30. #include "LexerModule.h"
  31. #include "OptionSet.h"
  32. #include "SparseState.h"
  33.  
  34. #ifdef SCI_NAMESPACE
  35. using namespace Scintilla;
  36. #endif
  37.  
  38. // An individual named option for use in an OptionSet
  39.  
  40. // Options used for LexerTorqueScript
  41. struct OptionsTorqueScript {
  42. bool fold;
  43. bool foldCompact;
  44. OptionsTorqueScript() {
  45. fold = false;
  46. foldCompact = false;
  47. }
  48. };
  49.  
  50. static const char *const TorqueScriptWordLists[] = {
  51. "Primary keywords and identifiers",
  52. "Secondary keywords and identifiers",
  53. "Documentation comment keywords",
  54. "Global classes and typedefs",
  55. "Preprocessor definitions",
  56. 0,
  57. };
  58.  
  59. struct OptionSetTorqueScript : public OptionSet<OptionsTorqueScript> {
  60. OptionSetTorqueScript() {
  61. DefineProperty("fold", &OptionsTorqueScript::fold);
  62.  
  63. DefineProperty("fold.compact", &OptionsTorqueScript::foldCompact);
  64. DefineWordListSets(TorqueScriptWordLists);
  65. }
  66. };
  67.  
  68. class LexerTorqueScript : public ILexer {
  69. bool caseSensitive;
  70. CharacterSet setWord;
  71. CharacterSet setBinOp;
  72. WordList declarationKeywords;
  73. WordList keywords;
  74. WordList stringcats;
  75. WordList keywords4;
  76. OptionsTorqueScript options;
  77. OptionSetTorqueScript osTorqueScript;
  78. SparseState<std::string> rawStringTerminators;
  79. enum { activeFlag = 0x40 };
  80. enum Token{
  81. VAR,
  82. BINOP,
  83. DECLARATION,
  84. KEYWORD,
  85. LITERAL,
  86. IDENTIFIER,
  87. UNDEFINED
  88. };
  89. public:
  90. LexerTorqueScript() :
  91. setWord(CharacterSet::setAlphaNum, "_", 0x80, true),
  92. setBinOp(CharacterSet::setNone, "=+-*/%&|") {
  93. }
  94. virtual ~LexerTorqueScript() {
  95. }
  96. void SCI_METHOD Release() {
  97. delete this;
  98. }
  99. int SCI_METHOD Version() const {
  100. return lvOriginal;
  101. }
  102. const char * SCI_METHOD PropertyNames() {
  103. return osTorqueScript.PropertyNames();
  104. }
  105. int SCI_METHOD PropertyType(const char *name) {
  106. return osTorqueScript.PropertyType(name);
  107. }
  108. const char * SCI_METHOD DescribeProperty(const char *name) {
  109. return osTorqueScript.DescribeProperty(name);
  110. }
  111. int SCI_METHOD PropertySet(const char *key, const char *val);
  112. const char * SCI_METHOD DescribeWordListSets() {
  113. return osTorqueScript.DescribeWordListSets();
  114. }
  115. int SCI_METHOD WordListSet(int n, const char *wl);
  116. void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
  117. void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
  118.  
  119. void * SCI_METHOD PrivateCall(int, void *) {
  120. return 0;
  121. }
  122.  
  123. static ILexer *LexerFactoryTorqueScript() {
  124. return new LexerTorqueScript();
  125. }
  126. static int MaskActive(int style) {
  127. return style & ~activeFlag;
  128. }
  129. bool TSWordlistContainsKey(WordList &list, int length, LexAccessor &styler, int i);
  130. int TraceToEnd(int i, LexAccessor &styler, CharacterSet charSet);
  131. int FindMatching(int i, LexAccessor &styler, char character, bool singleLine = true);
  132. Token FindPreviousToken(int i, LexAccessor &styler);
  133. };
  134.  
  135. int SCI_METHOD LexerTorqueScript::PropertySet(const char *key, const char *val) {
  136. if (osTorqueScript.PropertySet(&options, key, val)) {
  137. return 0;
  138. }
  139. return -1;
  140. }
  141.  
  142. int SCI_METHOD LexerTorqueScript::WordListSet(int n, const char *wl) {
  143. WordList *wordListN = 0;
  144. switch (n) {
  145. case 0:
  146. wordListN = &keywords;
  147. break;
  148. case 1:
  149. wordListN = &declarationKeywords;
  150. break;
  151. case 2:
  152. wordListN = &stringcats;
  153. break;
  154. case 3:
  155. wordListN = &keywords4;
  156. break;
  157. }
  158. int firstModification = -1;
  159. if (wordListN) {
  160. WordList wlNew;
  161. wlNew.Set(wl);
  162. if (*wordListN != wlNew) {
  163. wordListN->Set(wl);
  164. firstModification = 0;
  165. }
  166. }
  167. return firstModification;
  168. }
  169.  
  170. bool LexerTorqueScript::TSWordlistContainsKey(WordList &list, int length, LexAccessor &styler, int i)
  171. {
  172. for (int jj = 0; jj < list.len; jj++)
  173. if (strlen(list.words[jj]) == length)
  174. if (styler.Match(i, list.words[jj]))
  175. return true;
  176. return false;
  177. }
  178.  
  179. int LexerTorqueScript::TraceToEnd(int i, LexAccessor &styler, CharacterSet charSet)
  180. {
  181. int end = i;
  182. char tstChar = styler.SafeGetCharAt(end + 1);
  183. while (charSet.Contains(tstChar))
  184. {
  185. end++;
  186. tstChar = styler.SafeGetCharAt(end + 1);
  187. }
  188. return end;
  189. }
  190.  
  191. int LexerTorqueScript::FindMatching(int i, LexAccessor &styler, char character, bool singleLine)
  192. {
  193. int end = i + 1;
  194. char tstChar = styler.SafeGetCharAt(end, '\0');
  195. while (tstChar != character
  196. && tstChar != '\0')
  197. {
  198. if (singleLine && (tstChar == '\r' || tstChar == '\n'))
  199. return -end;
  200. end++;
  201. tstChar = styler.SafeGetCharAt(end, '\0');
  202. }
  203. return end;
  204. }
  205.  
  206. LexerTorqueScript::Token LexerTorqueScript::FindPreviousToken(int i, LexAccessor &styler)
  207. {
  208. Token result = Token::UNDEFINED;
  209. while (i >= 0 && result == Token::UNDEFINED)
  210. {
  211. int state = styler.StyleAt(i);
  212. switch (state)
  213. {
  214. case SCE_TORQUESCRIPT_BINOP:
  215. case SCE_TORQUESCRIPT_STRINGCAT:
  216. result = Token::BINOP;
  217. break;
  218. case SCE_TORQUESCRIPT_STRING:
  219. case SCE_TORQUESCRIPT_NUMBER:
  220. result = Token::LITERAL;
  221. break;
  222. case SCE_TORQUESCRIPT_LOCALVAR:
  223. case SCE_TORQUESCRIPT_GLOBALVAR:
  224. result = Token::VAR;
  225. break;
  226. case SCE_TORQUESCRIPT_IDENTIFIER:
  227. result = Token::IDENTIFIER;
  228. break;
  229. case SCE_TORQUESCRIPT_KEYWORD:
  230. result = Token::KEYWORD;
  231. break;
  232. case SCE_TORQUESCRIPT_DECLARATIONKEYWORD:
  233. result = Token::DECLARATION;
  234. break;
  235. case SCE_TORQUESCRIPT_DELIMITER:
  236. return Token::UNDEFINED;
  237. }
  238. i--;
  239. }
  240. return result;
  241. }
  242.  
  243. void SCI_METHOD LexerTorqueScript::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
  244. LexAccessor styler(pAccess);
  245.  
  246. CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
  247. CharacterSet setDeclarationWord(CharacterSet::setAlpha, "_:", 0x80, true);
  248. CharacterSet setKeywords(CharacterSet::setAlphaNum, "_$");
  249. CharacterSet setNumbers(CharacterSet::setDigits, ".");
  250.  
  251. Token previousToken = FindPreviousToken(startPos-1, styler);
  252.  
  253. styler.StartAt(startPos);
  254.  
  255. int state = initStyle;
  256. char chNext = styler.SafeGetCharAt(startPos);
  257. styler.StartSegment(startPos);
  258. int lengthDoc = startPos + length;
  259. char chVerbatimDelim = '\0';
  260.  
  261. for (int i = startPos; i <= lengthDoc; i++) {
  262. char ch = chNext;
  263. chNext = styler.SafeGetCharAt(i + 1);
  264.  
  265. if (styler.IsLeadByte(ch)) {
  266. i++;
  267. chNext = styler.SafeGetCharAt(i + 1);
  268. continue;
  269. }
  270. int end;
  271. switch (state) {
  272. case SCE_TORQUESCRIPT_DEFAULT:
  273. switch (ch){
  274. case '/':
  275. if (chNext == '/')
  276. state = SCE_TORQUESCRIPT_COMMENT;
  277. if (chNext == '*')
  278. state = SCE_TORQUESCRIPT_BLOCKCOMMENT;
  279. styler.ColourTo(i, state);
  280. break;
  281. case '%':
  282. end = TraceToEnd(i, styler, setWord);
  283. styler.StartSegment(i);
  284. if (previousToken == Token::DECLARATION
  285. || previousToken == Token::VAR)
  286. styler.ColourTo(end, SCE_TORQUESCRIPT_ERROR);
  287. else
  288. styler.ColourTo(end, SCE_TORQUESCRIPT_LOCALVAR);
  289. i = end;
  290. chNext = styler.SafeGetCharAt(i + 1);
  291. previousToken = Token::VAR;
  292. break;
  293. case '$':
  294. end = TraceToEnd(i, styler, setWord);
  295. styler.StartSegment(i);
  296. if (previousToken == Token::DECLARATION
  297. || previousToken == Token::VAR)
  298. styler.ColourTo(end, SCE_TORQUESCRIPT_ERROR);
  299. else
  300. styler.ColourTo(end, SCE_TORQUESCRIPT_GLOBALVAR);
  301. i = end;
  302. chNext = styler.SafeGetCharAt(i + 1);
  303. previousToken = Token::VAR;
  304. break;
  305. case '"':
  306. case '\'':
  307. end = FindMatching(i, styler, ch);
  308. i = end;
  309. if (end < 0)
  310. {
  311. i = -end;
  312. styler.ColourTo(i, SCE_TORQUESCRIPT_ERROR);
  313. }
  314. else
  315. if (previousToken == Token::DECLARATION
  316. || previousToken == Token::VAR
  317. || previousToken == Token::IDENTIFIER
  318. || previousToken == Token::KEYWORD
  319. || previousToken == Token::LITERAL)
  320. styler.ColourTo(i, SCE_TORQUESCRIPT_ERROR);
  321. else
  322. styler.ColourTo(i, ch == '"' ? SCE_TORQUESCRIPT_STRING : SCE_TORQUESCRIPT_TAG);
  323. previousToken = Token::LITERAL;
  324. chNext = styler.SafeGetCharAt(i + 1);
  325. break;
  326. case '\r':
  327. case '\n':
  328. styler.ColourTo(i, state);
  329. break;
  330. case ';':
  331. case ',':
  332. case '{':
  333. case '}':
  334. case '.':
  335. case '(':
  336. case ')':
  337. if (previousToken == Token::DECLARATION)
  338. styler.ColourTo(i, SCE_TORQUESCRIPT_ERROR);
  339. else
  340. styler.ColourTo(i, SCE_TORQUESCRIPT_DELIMITER);
  341. previousToken = Token::UNDEFINED;
  342. break;
  343. case '@':
  344. styler.ColourTo(i, SCE_TORQUESCRIPT_STRINGCAT);
  345. previousToken = Token::BINOP;
  346. break;
  347. default:
  348. if (setBinOp.Contains(ch))
  349. {
  350. if (previousToken == Token::DECLARATION
  351. || previousToken == Token::BINOP)
  352. {
  353. if ((ch == '+' || ch == '-')
  354. && styler.SafeGetCharAt(i - 1) == ch)
  355. styler.ColourTo(i, SCE_TORQUESCRIPT_DEFAULT);
  356. else
  357. styler.ColourTo(i, SCE_TORQUESCRIPT_ERROR);
  358. }
  359. else
  360. styler.ColourTo(i, SCE_TORQUESCRIPT_BINOP);
  361. previousToken = Token::BINOP;
  362. break;
  363. }
  364. if (setNumbers.Contains(ch))
  365. {
  366. end = TraceToEnd(i, styler, setNumbers);
  367. if (previousToken == Token::DECLARATION
  368. || previousToken == Token::VAR
  369. || previousToken == Token::IDENTIFIER
  370. || previousToken == Token::LITERAL
  371. || previousToken == Token::KEYWORD)
  372. styler.ColourTo(i, SCE_TORQUESCRIPT_ERROR);
  373. else
  374. styler.ColourTo(end, SCE_TORQUESCRIPT_NUMBER);
  375. previousToken = Token::LITERAL;
  376. i = end;
  377. chNext = styler.SafeGetCharAt(i + 1);
  378. }
  379. if (setWordStart.Contains(ch))
  380. {
  381. end = TraceToEnd(i, styler, setKeywords);
  382. bool foundKeyword = false;
  383. if (TSWordlistContainsKey(declarationKeywords, (end - i) + 1, styler, i))
  384. {
  385. styler.StartSegment(i);
  386. state = SCE_TORQUESCRIPT_DEFAULT;
  387. if (previousToken == Token::DECLARATION
  388. || previousToken == Token::VAR)
  389. styler.ColourTo(end, SCE_TORQUESCRIPT_ERROR);
  390. else
  391. styler.ColourTo(end, SCE_TORQUESCRIPT_DECLARATIONKEYWORD);
  392. i = end;
  393. chNext = styler.SafeGetCharAt(i + 1);
  394. foundKeyword = true;
  395. previousToken = Token::DECLARATION;
  396. break;
  397. }
  398. if (TSWordlistContainsKey(keywords, (end - i) + 1, styler, i))
  399. {
  400. styler.StartSegment(i);
  401. state = SCE_TORQUESCRIPT_DEFAULT;
  402. if (previousToken == Token::DECLARATION)
  403. styler.ColourTo(end, SCE_TORQUESCRIPT_ERROR);
  404. else
  405. styler.ColourTo(end, SCE_TORQUESCRIPT_KEYWORD);
  406. i = end;
  407. chNext = styler.SafeGetCharAt(i + 1);
  408. foundKeyword = true;
  409. previousToken = Token::KEYWORD;
  410. break;
  411. }
  412. if (TSWordlistContainsKey(stringcats, (end - i) + 1, styler, i))
  413. {
  414. styler.StartSegment(i);
  415. state = SCE_TORQUESCRIPT_DEFAULT;
  416. if (previousToken == Token::DECLARATION
  417. || Token::UNDEFINED)
  418. styler.ColourTo(end, SCE_TORQUESCRIPT_ERROR);
  419. else
  420. styler.ColourTo(end, SCE_TORQUESCRIPT_STRINGCAT);
  421. i = end;
  422. chNext = styler.SafeGetCharAt(i + 1);
  423. foundKeyword = true;
  424. previousToken = Token::BINOP;
  425. break;
  426. }
  427. if (foundKeyword)
  428. break;
  429.  
  430. if (previousToken == Token::DECLARATION)
  431. end = TraceToEnd(i, styler, setDeclarationWord);
  432. else
  433. end = TraceToEnd(i, styler, setWord);
  434.  
  435. styler.StartSegment(i);
  436. if (previousToken == Token::LITERAL
  437. || previousToken == Token::VAR
  438. || previousToken == Token::LITERAL
  439. || previousToken == Token::IDENTIFIER)
  440. styler.ColourTo(end, SCE_TORQUESCRIPT_ERROR);
  441. else
  442. styler.ColourTo(end, SCE_TORQUESCRIPT_IDENTIFIER);
  443. i = end;
  444. chNext = styler.SafeGetCharAt(i + 1);
  445. previousToken = Token::IDENTIFIER;
  446. break;
  447. }
  448. styler.ColourTo(i, state);
  449. break;
  450. }
  451. break;
  452. case SCE_TORQUESCRIPT_COMMENT:
  453. switch (ch){
  454. case '\r':
  455. case '\n':
  456. state = SCE_TORQUESCRIPT_DEFAULT;
  457. styler.ColourTo(i, state);
  458. break;
  459. default:
  460. styler.ColourTo(i, state);
  461. break;
  462. }
  463. break;
  464. case SCE_TORQUESCRIPT_BLOCKCOMMENT:
  465. switch (ch){
  466. case '*':
  467. if (chNext == '/')
  468. {
  469. styler.ColourTo(++i, state);
  470. state = SCE_TORQUESCRIPT_DEFAULT;
  471. }
  472. break;
  473. default:
  474. styler.ColourTo(i, state);
  475. break;
  476. }
  477. break;
  478. case SCE_TORQUESCRIPT_IDENTIFIER:
  479. if (IsAlphaNumeric(ch)
  480. || ch == '_')
  481. {
  482. styler.ColourTo(i, state);
  483. break;
  484. }
  485. state = SCE_TORQUESCRIPT_DEFAULT;
  486. styler.ColourTo(i, state);
  487. break;
  488. }
  489. }
  490. styler.Flush();
  491. }
  492.  
  493. // Store both the current line's fold level and the next lines in the
  494. // level store to make it easy to pick up with each increment
  495. // and to make it possible to fiddle the current level for "} else {".
  496.  
  497. void SCI_METHOD LexerTorqueScript::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
  498.  
  499. if (!options.fold)
  500. return;
  501.  
  502. LexAccessor styler(pAccess);
  503.  
  504. int curLine = styler.GetLine(startPos);
  505. int curLineStart = styler.LineStart(curLine);
  506. int currLevel = curLine > 0 ? styler.LevelAt(curLine) & SC_FOLDLEVELNUMBERMASK : SC_FOLDLEVELBASE;
  507. int nextLevel = currLevel;
  508. int i = curLineStart;
  509.  
  510. do {
  511. int lineType = styler.StyleAt(curLineStart);
  512.  
  513. int visChars = 0;
  514. while (styler.GetLine(i) == curLine && i < startPos + length)
  515. {
  516. char ch = styler.SafeGetCharAt(i);
  517. switch (ch)
  518. {
  519. case '{':
  520. nextLevel++;
  521. visChars++;
  522. break;
  523. case '}':
  524. currLevel--;
  525. nextLevel--;
  526. visChars++;
  527. break;
  528. case '\t':
  529. case ' ':
  530. case '\r':
  531. case '\n':
  532. break;
  533. default:
  534. visChars++;
  535. }
  536. i++;
  537. }
  538.  
  539. int lev = currLevel;
  540.  
  541. // Set the "all whitespace" bit if the line is blank.
  542. if (visChars == 0)
  543. lev |= SC_FOLDLEVELWHITEFLAG;
  544.  
  545. // Set the "header" bit if needed.
  546. if ((nextLevel > currLevel) && (visChars > 0))
  547. lev |= SC_FOLDLEVELHEADERFLAG;
  548. styler.SetLevel(curLine, lev);
  549. currLevel = nextLevel;
  550.  
  551. curLineStart = styler.LineStart(++curLine);
  552. } while (static_cast<int>(startPos)+length > curLineStart);
  553. styler.Flush();
  554. }
  555.  
  556. LexerModule lmTorqueScript(SCLEX_TORQUESCRIPT, LexerTorqueScript::LexerFactoryTorqueScript, "TorqueScript", TorqueScriptWordLists);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement