1 // Scintilla source code edit control
2 /** @file LexAPDL.cxx
3 ** Lexer for APDL. Based on the lexer for Assembler by The Black Horus.
4 ** By Hadar Raz.
5 **/
6 // Copyright 1998-2003 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
15 #include "Platform.h"
16
17 #include "PropSet.h"
18 #include "Accessor.h"
19 #include "StyleContext.h"
20 #include "KeyWords.h"
21 #include "Scintilla.h"
22 #include "SciLexer.h"
23
24
IsAWordChar(const int ch)25 static inline bool IsAWordChar(const int ch) {
26 return (ch < 0x80 && (isalnum(ch) || ch == '_'));
27 }
28
IsAnOperator(char ch)29 static inline bool IsAnOperator(char ch) {
30 // '.' left out as it is used to make up numbers
31 if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
32 ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
33 ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
34 ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
35 ch == '$' || ch == ':' || ch == '%')
36 return true;
37 return false;
38 }
39
ColouriseAPDLDoc(unsigned int startPos,int length,int initStyle,WordList * keywordlists[],Accessor & styler)40 static void ColouriseAPDLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
41 Accessor &styler) {
42
43 int stringStart = ' ';
44
45 WordList &processors = *keywordlists[0];
46 WordList &commands = *keywordlists[1];
47 WordList &slashcommands = *keywordlists[2];
48 WordList &starcommands = *keywordlists[3];
49 WordList &arguments = *keywordlists[4];
50 WordList &functions = *keywordlists[5];
51
52 // Do not leak onto next line
53 initStyle = SCE_APDL_DEFAULT;
54 StyleContext sc(startPos, length, initStyle, styler);
55
56 for (; sc.More(); sc.Forward()) {
57 // Determine if the current state should terminate.
58 if (sc.state == SCE_APDL_NUMBER) {
59 if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
60 ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
61 sc.SetState(SCE_APDL_DEFAULT);
62 }
63 } else if (sc.state == SCE_APDL_COMMENT) {
64 if (sc.atLineEnd) {
65 sc.SetState(SCE_APDL_DEFAULT);
66 }
67 } else if (sc.state == SCE_APDL_COMMENTBLOCK) {
68 if (sc.atLineEnd) {
69 if (sc.ch == '\r') {
70 sc.Forward();
71 }
72 sc.ForwardSetState(SCE_APDL_DEFAULT);
73 }
74 } else if (sc.state == SCE_APDL_STRING) {
75 if (sc.atLineEnd) {
76 sc.SetState(SCE_APDL_DEFAULT);
77 } else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
78 sc.ForwardSetState(SCE_APDL_DEFAULT);
79 }
80 } else if (sc.state == SCE_APDL_WORD) {
81 if (!IsAWordChar(sc.ch)) {
82 char s[100];
83 sc.GetCurrentLowered(s, sizeof(s));
84 if (processors.InList(s)) {
85 sc.ChangeState(SCE_APDL_PROCESSOR);
86 } else if (slashcommands.InList(s)) {
87 sc.ChangeState(SCE_APDL_SLASHCOMMAND);
88 } else if (starcommands.InList(s)) {
89 sc.ChangeState(SCE_APDL_STARCOMMAND);
90 } else if (commands.InList(s)) {
91 sc.ChangeState(SCE_APDL_COMMAND);
92 } else if (arguments.InList(s)) {
93 sc.ChangeState(SCE_APDL_ARGUMENT);
94 } else if (functions.InList(s)) {
95 sc.ChangeState(SCE_APDL_FUNCTION);
96 }
97 sc.SetState(SCE_APDL_DEFAULT);
98 }
99 } else if (sc.state == SCE_APDL_OPERATOR) {
100 if (!IsAnOperator(static_cast<char>(sc.ch))) {
101 sc.SetState(SCE_APDL_DEFAULT);
102 }
103 }
104
105 // Determine if a new state should be entered.
106 if (sc.state == SCE_APDL_DEFAULT) {
107 if (sc.ch == '!' && sc.chNext == '!') {
108 sc.SetState(SCE_APDL_COMMENTBLOCK);
109 } else if (sc.ch == '!') {
110 sc.SetState(SCE_APDL_COMMENT);
111 } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
112 sc.SetState(SCE_APDL_NUMBER);
113 } else if (sc.ch == '\'' || sc.ch == '\"') {
114 sc.SetState(SCE_APDL_STRING);
115 stringStart = sc.ch;
116 } else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
117 sc.SetState(SCE_APDL_WORD);
118 } else if (IsAnOperator(static_cast<char>(sc.ch))) {
119 sc.SetState(SCE_APDL_OPERATOR);
120 }
121 }
122 }
123 sc.Complete();
124 }
125
126 static const char * const apdlWordListDesc[] = {
127 "processors",
128 "commands",
129 "slashommands",
130 "starcommands",
131 "arguments",
132 "functions",
133 0
134 };
135
136 LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", 0, apdlWordListDesc);
137