1
// Scintilla source code edit control
3
** Lexer for APDL. Based on the lexer for Assembler by The Black Horus.
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.
17
#include "Scintilla.h"
21
#include "LexAccessor.h"
23
#include "StyleContext.h"
24
#include "CharacterSet.h"
25
#include "LexerModule.h"
28
using namespace Scintilla;
31
static inline bool IsAWordChar(const int ch) {
32
return (ch < 0x80 && (isalnum(ch) || ch == '_'));
35
static inline bool IsAnOperator(char ch) {
36
// '.' left out as it is used to make up numbers
37
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
38
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
39
ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
40
ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
41
ch == '$' || ch == ':' || ch == '%')
46
static void ColouriseAPDLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
49
int stringStart = ' ';
51
WordList &processors = *keywordlists[0];
52
WordList &commands = *keywordlists[1];
53
WordList &slashcommands = *keywordlists[2];
54
WordList &starcommands = *keywordlists[3];
55
WordList &arguments = *keywordlists[4];
56
WordList &functions = *keywordlists[5];
58
// Do not leak onto next line
59
initStyle = SCE_APDL_DEFAULT;
60
StyleContext sc(startPos, length, initStyle, styler);
62
for (; sc.More(); sc.Forward()) {
63
// Determine if the current state should terminate.
64
if (sc.state == SCE_APDL_NUMBER) {
65
if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
66
((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
67
sc.SetState(SCE_APDL_DEFAULT);
69
} else if (sc.state == SCE_APDL_COMMENT) {
71
sc.SetState(SCE_APDL_DEFAULT);
73
} else if (sc.state == SCE_APDL_COMMENTBLOCK) {
78
sc.ForwardSetState(SCE_APDL_DEFAULT);
80
} else if (sc.state == SCE_APDL_STRING) {
82
sc.SetState(SCE_APDL_DEFAULT);
83
} else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
84
sc.ForwardSetState(SCE_APDL_DEFAULT);
86
} else if (sc.state == SCE_APDL_WORD) {
87
if (!IsAWordChar(sc.ch)) {
89
sc.GetCurrentLowered(s, sizeof(s));
90
if (processors.InList(s)) {
91
sc.ChangeState(SCE_APDL_PROCESSOR);
92
} else if (slashcommands.InList(s)) {
93
sc.ChangeState(SCE_APDL_SLASHCOMMAND);
94
} else if (starcommands.InList(s)) {
95
sc.ChangeState(SCE_APDL_STARCOMMAND);
96
} else if (commands.InList(s)) {
97
sc.ChangeState(SCE_APDL_COMMAND);
98
} else if (arguments.InList(s)) {
99
sc.ChangeState(SCE_APDL_ARGUMENT);
100
} else if (functions.InList(s)) {
101
sc.ChangeState(SCE_APDL_FUNCTION);
103
sc.SetState(SCE_APDL_DEFAULT);
105
} else if (sc.state == SCE_APDL_OPERATOR) {
106
if (!IsAnOperator(static_cast<char>(sc.ch))) {
107
sc.SetState(SCE_APDL_DEFAULT);
111
// Determine if a new state should be entered.
112
if (sc.state == SCE_APDL_DEFAULT) {
113
if (sc.ch == '!' && sc.chNext == '!') {
114
sc.SetState(SCE_APDL_COMMENTBLOCK);
115
} else if (sc.ch == '!') {
116
sc.SetState(SCE_APDL_COMMENT);
117
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
118
sc.SetState(SCE_APDL_NUMBER);
119
} else if (sc.ch == '\'' || sc.ch == '\"') {
120
sc.SetState(SCE_APDL_STRING);
122
} else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
123
sc.SetState(SCE_APDL_WORD);
124
} else if (IsAnOperator(static_cast<char>(sc.ch))) {
125
sc.SetState(SCE_APDL_OPERATOR);
132
//------------------------------------------------------------------------------
133
// 06-27-07 Sergio Lucato
134
// - Included code folding for Ansys APDL lexer
135
// - Copyied from LexBasic.cxx and modified for APDL
136
//------------------------------------------------------------------------------
146
static int character_classification[128] =
148
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
149
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
150
1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
151
60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
152
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
153
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
154
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
155
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
158
static bool IsSpace(int c) {
159
return c < 128 && (character_classification[c] & 1);
162
static bool IsIdentifier(int c) {
163
return c < 128 && (character_classification[c] & 4);
166
static int LowerCase(int c)
168
if (c >= 'A' && c <= 'Z')
169
return 'a' + c - 'A';
173
static int CheckAPDLFoldPoint(char const *token, int &level) {
174
if (!strcmp(token, "*if") ||
175
!strcmp(token, "*do") ||
176
!strcmp(token, "*dowhile") ) {
177
level |= SC_FOLDLEVELHEADERFLAG;
180
if (!strcmp(token, "*endif") ||
181
!strcmp(token, "*enddo") ) {
187
static void FoldAPDLDoc(unsigned int startPos, int length, int,
188
WordList *[], Accessor &styler) {
190
int line = styler.GetLine(startPos);
191
int level = styler.LevelAt(line);
192
int go = 0, done = 0;
193
int endPos = startPos + length;
197
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
198
// Scan for tokens at the start of the line (they may include
199
// whitespace, for tokens like "End Function"
200
for (i = startPos; i < endPos; i++) {
201
int c = styler.SafeGetCharAt(i);
203
if (wordlen) { // are we scanning a token already?
204
word[wordlen] = static_cast<char>(LowerCase(c));
205
if (!IsIdentifier(c)) { // done with token
206
word[wordlen] = '\0';
207
go = CheckAPDLFoldPoint(word, level);
209
// Treat any whitespace as single blank, for
210
// things like "End Function".
211
if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
216
else // done with this line
219
} else if (wordlen < 255) {
222
} else { // start scanning at first non-whitespace character
224
if (IsIdentifier(c)) {
225
word[0] = static_cast<char>(LowerCase(c));
227
} else // done with this line
232
if (c == '\n') { // line end
233
if (!done && wordlen == 0 && foldCompact) // line was only space
234
level |= SC_FOLDLEVELWHITEFLAG;
235
if (level != styler.LevelAt(line))
236
styler.SetLevel(line, level);
241
level &= ~SC_FOLDLEVELHEADERFLAG;
242
level &= ~SC_FOLDLEVELWHITEFLAG;
249
static const char * const apdlWordListDesc[] = {
259
LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", FoldAPDLDoc, apdlWordListDesc);