/[svn]/linuxsampler/trunk/src/scriptvm/editor/nksp.l
ViewVC logotype

Contents of /linuxsampler/trunk/src/scriptvm/editor/nksp.l

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2885 - (show annotations) (download)
Fri Apr 22 15:37:45 2016 UTC (8 years ago) by schoenebeck
File size: 7666 byte(s)
* Instrument script classes now exported with the liblinuxsampler C++ API.
* Added new API method ScriptVM::syntaxHighlighting() which provides
  a convenient syntax highlighting backend for external instrument
  script editor applications.
* Bumped version (2.0.0.svn5).

1 /*
2 * Copyright (c) 2015-2016 Christian Schoenebeck
3 *
4 * http://www.linuxsampler.org
5 *
6 * This file is part of LinuxSampler and released under the same terms.
7 * See README file for details.
8 */
9
10 /* Token scanner used for generating syntax highlighting for NKSP instrument
11 script language code (this is not used by the sampler itself, but rather
12 provided for external script editor applications). */
13
14 %{
15
16 #include "NkspScanner.h"
17 // reentrant scanner data context
18 #define YY_EXTRA_TYPE NkspScanner*
19 // custom (f)lex input for reading from std::istream object
20 #define YY_INPUT(buf,result,max_size) \
21 { \
22 char c = yyextra->is->get(); \
23 if (yyextra->is->eof()) \
24 result = YY_NULL; \
25 else { \
26 buf[0] = c; \
27 result = 1; \
28 } \
29 }
30 // handle position (line, column) for each recognized token
31 #define YY_USER_ACTION \
32 yyextra->line = yylineno - 1; \
33 yyextra->column = yycolumn; \
34 yycolumn += yyleng;
35
36 using namespace LinuxSampler;
37
38 static int countNewLineChars(const char* txt) {
39 int n = 0;
40 for (int i = 0; txt[i]; ++i)
41 if (txt[i] == '\n') ++n;
42 return n;
43 }
44
45 %}
46
47 /* generate a reentrant safe scanner */
48 %option reentrant
49 /* avoid symbol collision with ones of other scanners */
50 %option prefix="Nksp_"
51 /* yywrap() would be called at EOF, we don't need it */
52 %option noyywrap
53 /* enable functions yy_push_state(), yy_pop_state(), yy_top_state() */
54 %option stack
55
56 /* inclusive scanner conditions */
57 %s PREPROC_BODY_USE
58 /* exclusive scanner conditions */
59 %x PREPROC_SET_COND PREPROC_RESET_COND PREPROC_IF PREPROC_IF_NOT PREPROC_BODY_EAT PREPROC_PRE_BODY_USE PREPROC_PRE_BODY_EAT PREPROC_EVENT_NAME PREPROC_END_NAME
60
61 DIGIT [0-9]
62 ID [a-zA-Z0-9_]*
63
64 %%
65
66 \"[^"]*\" {
67 yyextra->token = StringLiteralToken(yytext);
68 return yyextra->token.baseType;
69 }
70
71 {DIGIT}+ {
72 yyextra->token = NumberLiteralToken(yytext);
73 return yyextra->token.baseType;
74 }
75
76 {DIGIT}+"."{DIGIT}* {
77 yyextra->token = NumberLiteralToken(yytext);
78 return yyextra->token.baseType;
79 }
80
81
82 /* Preprocessor statement: SET_CONDITION(name) */
83
84 <*>"SET_CONDITION"[ \t]*"(" {
85 //printf("SET_CONDITION\n");
86 yy_push_state(PREPROC_SET_COND, yyscanner);
87 yyextra->token = PreprocessorToken(yytext);
88 return yyextra->token.baseType;
89 }
90 <PREPROC_SET_COND>{ID} {
91 //printf("preproc set condition '%s'\n", yytext);
92 yyextra->token = PreprocessorToken(yytext);
93 return yyextra->token.baseType;
94 }
95 <PREPROC_SET_COND>[ \t]*")" {
96 //printf("End of PREPROC_SET_COND\n");
97 yy_pop_state(yyscanner);
98 yyextra->token = PreprocessorToken(yytext);
99 return yyextra->token.baseType;
100 }
101
102
103 /* Preprocessor statement: RESET_CONDITION(name) */
104
105 <*>"RESET_CONDITION"[ \t]*"(" {
106 //printf("RESET_CONDITION\n");
107 yy_push_state(PREPROC_RESET_COND, yyscanner);
108 yyextra->token = PreprocessorToken(yytext);
109 return yyextra->token.baseType;
110 }
111 <PREPROC_RESET_COND>{ID} {
112 //printf("preproc reset condition '%s'\n", yytext);
113 yyextra->token = PreprocessorToken(yytext);
114 return yyextra->token.baseType;
115 }
116 <PREPROC_RESET_COND>[ \t]*")" {
117 //printf("End of RESET_CONDITION\n");
118 yy_pop_state(yyscanner);
119 yyextra->token = PreprocessorToken(yytext);
120 return yyextra->token.baseType;
121 }
122
123
124 /* Preprocessor conditional statements:
125
126 USE_CODE_IF(name)
127 ...
128 END_USE_CODE
129
130 and:
131
132 USE_CODE_IF_NOT(name)
133 ...
134 END_USE_CODE
135 */
136
137 <*>"USE_CODE_IF"[ \t]*"(" {
138 //printf("USE_CODE_IF\n");
139 yy_push_state(PREPROC_IF, yyscanner);
140 yyextra->token = PreprocessorToken(yytext);
141 return yyextra->token.baseType;
142 }
143 <*>"USE_CODE_IF_NOT"[ \t]*"(" {
144 //printf("USE_CODE_IF_NOT\n");
145 yy_push_state(PREPROC_IF_NOT, yyscanner);
146 yyextra->token = PreprocessorToken(yytext);
147 return yyextra->token.baseType;
148 }
149 <PREPROC_IF>{ID} {
150 //printf("preproc use code if '%s'\n", yytext);
151 yy_pop_state(yyscanner);
152 yy_push_state(PREPROC_PRE_BODY_USE, yyscanner);
153 //yy_push_state(PREPROC_PRE_BODY_EAT, yyscanner);
154 yyextra->token = PreprocessorToken(yytext);
155 return yyextra->token.baseType;
156 }
157 <PREPROC_IF_NOT>{ID} {
158 //printf("preproc use code if not '%s'\n", yytext);
159 yy_pop_state(yyscanner);
160 yy_push_state(PREPROC_PRE_BODY_USE, yyscanner);
161 //yy_push_state(PREPROC_PRE_BODY_EAT, yyscanner);
162 yyextra->token = PreprocessorToken(yytext);
163 return yyextra->token.baseType;
164 }
165 <PREPROC_PRE_BODY_USE>[ \t]*")" {
166 yy_pop_state(yyscanner);
167 yy_push_state(PREPROC_BODY_USE, yyscanner);
168 yyextra->token = PreprocessorToken(yytext);
169 return yyextra->token.baseType;
170 }
171 <PREPROC_PRE_BODY_EAT>[ \t]*")" {
172 //printf("PREPROCESSOR EAT : \n");
173 yy_pop_state(yyscanner);
174 yy_push_state(PREPROC_BODY_EAT, yyscanner);
175 yyextra->token = PreprocessorToken(yytext);
176 return yyextra->token.baseType;
177 }
178 <*>.*"END_USE_CODE" {
179 //printf("-->END_USE_CODE\n");
180 yy_pop_state(yyscanner);
181 yyextra->token = PreprocessorToken(yytext);
182 return yyextra->token.baseType;
183 }
184 <PREPROC_BODY_EAT>[ \t\r\n]* /* eat up code block filtered out by preprocessor */
185 <PREPROC_BODY_EAT>.* /* eat up code block filtered out by preprocessor */
186
187
188 /* Event Handler Names (only if they occur alone in a document!) */
189
190 ^\s*(init|note|release|controller) {
191 yyextra->token = EventHandlerNameToken(yytext);
192 return yyextra->token.baseType;
193 }
194
195
196 /* Language keywords */
197
198 on {
199 yy_push_state(PREPROC_EVENT_NAME, yyscanner);
200 yyextra->token = KeywordToken(yytext);
201 return yyextra->token.baseType;
202 }
203
204 <PREPROC_EVENT_NAME>[ \t]*{ID} {
205 yy_pop_state(yyscanner);
206 yyextra->token = EventHandlerNameToken(yytext);
207 return yyextra->token.baseType;
208 }
209
210 end {
211 yy_push_state(PREPROC_END_NAME, yyscanner);
212 yyextra->token = KeywordToken(yytext);
213 return yyextra->token.baseType;
214 }
215
216 <PREPROC_END_NAME>[ \t]*{ID} {
217 yy_pop_state(yyscanner);
218 yyextra->token = KeywordToken(yytext);
219 return yyextra->token.baseType;
220 }
221
222 declare|while|if|or|and|not|else|case|select|to|mod|const|polyphonic {
223 yyextra->token = KeywordToken(yytext);
224 return yyextra->token.baseType;
225 }
226
227
228 /* Variables */
229
230 "$"{ID} {
231 yyextra->token = IntegerVariableToken(yytext);
232 return yyextra->token.baseType;
233 }
234
235 "@"{ID} {
236 yyextra->token = StringVariableToken(yytext);
237 return yyextra->token.baseType;
238 }
239
240 "%"{ID} {
241 yyextra->token = ArrayVariableToken(yytext);
242 return yyextra->token.baseType;
243 }
244
245 {ID} {
246 yyextra->token = IdentifierToken(yytext);
247 return yyextra->token.baseType;
248 }
249
250
251 /* other */
252
253 <*>\n {
254 yyextra->token = NewLineToken();
255 ++yylineno;
256 yycolumn = 0;
257 return yyextra->token.baseType;
258 }
259
260 "{"[^}]*"}" {
261 yyextra->token = CommentToken(yytext);
262 yylineno += countNewLineChars(yytext);
263 return yyextra->token.baseType;
264 }
265
266 <*>\t {
267 yyextra->token = OtherToken(" ");
268 return yyextra->token.baseType;
269 }
270
271 \r+ /* eat up \r */
272
273 <<EOF>> {
274 yyextra->token = EofToken();
275 yyterminate();
276 }
277
278 <*>. {
279 yyextra->token = OtherToken(yytext);
280 return yyextra->token.baseType;
281 }
282
283
284 %%
285
286 namespace LinuxSampler {
287
288 int NkspScanner::processScanner() {
289 return Nksp_lex(scanner);
290 }
291
292 void NkspScanner::createScanner(std::istream* is) {
293 if (scanner) destroyScanner();
294 this->is = is;
295 Nksp_lex_init(&scanner);
296 Nksp_set_extra(this, scanner);
297 }
298
299 void NkspScanner::destroyScanner() {
300 if (!scanner) return;
301 Nksp_lex_destroy(scanner);
302 scanner = NULL;
303 }
304
305 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC