/[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 2935 - (show annotations) (download)
Sun Jul 10 14:24:13 2016 UTC (7 years, 9 months ago) by schoenebeck
File size: 7855 byte(s)
* NKSP: Added & implemented built-in script function "change_cutoff()".
* NKSP: Added & implemented built-in script function "change_reso()".
* NKSP: Added & implemented built-in script function "event_status()".
* NKSP: Added built-in script constants "$EVENT_STATUS_INACTIVE" and
  "$EVENT_STATUS_NOTE_QUEUE" both for being used as flags for
  built-in "event_status()" script function.
* NKSP language: Added support for bitwise operators ".or.", ".and."
  and ".not.".
* NKSP language scanner: Fixed IDs matching to require at least one
  character (i.e. when matching function names or variable names).
* NKSP language scanner: disabled unusued rules.
* Bumped version (2.0.0.svn12).

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 /* there is currently no support for floating point numbers in NKSP yet */
77 /*{DIGIT}+"."{DIGIT}* {
78 yyextra->token = NumberLiteralToken(yytext);
79 return yyextra->token.baseType;
80 }*/
81
82
83 /* Preprocessor statement: SET_CONDITION(name) */
84
85 <*>"SET_CONDITION"[ \t]*"(" {
86 //printf("SET_CONDITION\n");
87 yy_push_state(PREPROC_SET_COND, yyscanner);
88 yyextra->token = PreprocessorToken(yytext);
89 return yyextra->token.baseType;
90 }
91 <PREPROC_SET_COND>{ID} {
92 //printf("preproc set condition '%s'\n", yytext);
93 yyextra->token = PreprocessorToken(yytext);
94 return yyextra->token.baseType;
95 }
96 <PREPROC_SET_COND>[ \t]*")" {
97 //printf("End of PREPROC_SET_COND\n");
98 yy_pop_state(yyscanner);
99 yyextra->token = PreprocessorToken(yytext);
100 return yyextra->token.baseType;
101 }
102
103
104 /* Preprocessor statement: RESET_CONDITION(name) */
105
106 <*>"RESET_CONDITION"[ \t]*"(" {
107 //printf("RESET_CONDITION\n");
108 yy_push_state(PREPROC_RESET_COND, yyscanner);
109 yyextra->token = PreprocessorToken(yytext);
110 return yyextra->token.baseType;
111 }
112 <PREPROC_RESET_COND>{ID} {
113 //printf("preproc reset condition '%s'\n", yytext);
114 yyextra->token = PreprocessorToken(yytext);
115 return yyextra->token.baseType;
116 }
117 <PREPROC_RESET_COND>[ \t]*")" {
118 //printf("End of RESET_CONDITION\n");
119 yy_pop_state(yyscanner);
120 yyextra->token = PreprocessorToken(yytext);
121 return yyextra->token.baseType;
122 }
123
124
125 /* Preprocessor conditional statements:
126
127 USE_CODE_IF(name)
128 ...
129 END_USE_CODE
130
131 and:
132
133 USE_CODE_IF_NOT(name)
134 ...
135 END_USE_CODE
136 */
137
138 <*>"USE_CODE_IF"[ \t]*"(" {
139 //printf("USE_CODE_IF\n");
140 yy_push_state(PREPROC_IF, yyscanner);
141 yyextra->token = PreprocessorToken(yytext);
142 return yyextra->token.baseType;
143 }
144 <*>"USE_CODE_IF_NOT"[ \t]*"(" {
145 //printf("USE_CODE_IF_NOT\n");
146 yy_push_state(PREPROC_IF_NOT, yyscanner);
147 yyextra->token = PreprocessorToken(yytext);
148 return yyextra->token.baseType;
149 }
150 <PREPROC_IF>{ID} {
151 //printf("preproc use code if '%s'\n", yytext);
152 yy_pop_state(yyscanner);
153 yy_push_state(PREPROC_PRE_BODY_USE, yyscanner);
154 //yy_push_state(PREPROC_PRE_BODY_EAT, yyscanner);
155 yyextra->token = PreprocessorToken(yytext);
156 return yyextra->token.baseType;
157 }
158 <PREPROC_IF_NOT>{ID} {
159 //printf("preproc use code if not '%s'\n", yytext);
160 yy_pop_state(yyscanner);
161 yy_push_state(PREPROC_PRE_BODY_USE, yyscanner);
162 //yy_push_state(PREPROC_PRE_BODY_EAT, yyscanner);
163 yyextra->token = PreprocessorToken(yytext);
164 return yyextra->token.baseType;
165 }
166 <PREPROC_PRE_BODY_USE>[ \t]*")" {
167 yy_pop_state(yyscanner);
168 yy_push_state(PREPROC_BODY_USE, yyscanner);
169 yyextra->token = PreprocessorToken(yytext);
170 return yyextra->token.baseType;
171 }
172 <PREPROC_PRE_BODY_EAT>[ \t]*")" {
173 //printf("PREPROCESSOR EAT : \n");
174 yy_pop_state(yyscanner);
175 yy_push_state(PREPROC_BODY_EAT, yyscanner);
176 yyextra->token = PreprocessorToken(yytext);
177 return yyextra->token.baseType;
178 }
179 <*>.*"END_USE_CODE" {
180 //printf("-->END_USE_CODE\n");
181 yy_pop_state(yyscanner);
182 yyextra->token = PreprocessorToken(yytext);
183 return yyextra->token.baseType;
184 }
185 <PREPROC_BODY_EAT>[ \t\r\n]* /* eat up code block filtered out by preprocessor */
186 <PREPROC_BODY_EAT>.* /* eat up code block filtered out by preprocessor */
187
188
189 /* Event Handler Names (only if they occur alone in a document!) */
190
191 ^\s*(init|note|release|controller) {
192 yyextra->token = EventHandlerNameToken(yytext);
193 return yyextra->token.baseType;
194 }
195
196
197 /* Language keywords */
198
199 on {
200 yy_push_state(PREPROC_EVENT_NAME, yyscanner);
201 yyextra->token = KeywordToken(yytext);
202 return yyextra->token.baseType;
203 }
204
205 <PREPROC_EVENT_NAME>[ \t]*{ID} {
206 yy_pop_state(yyscanner);
207 yyextra->token = EventHandlerNameToken(yytext);
208 return yyextra->token.baseType;
209 }
210
211 end {
212 yy_push_state(PREPROC_END_NAME, yyscanner);
213 yyextra->token = KeywordToken(yytext);
214 return yyextra->token.baseType;
215 }
216
217 <PREPROC_END_NAME>[ \t]*{ID} {
218 yy_pop_state(yyscanner);
219 yyextra->token = KeywordToken(yytext);
220 return yyextra->token.baseType;
221 }
222
223 ".or."|".and."|".not." {
224 yyextra->token = KeywordToken(yytext);
225 return yyextra->token.baseType;
226 }
227
228 declare|while|if|or|and|not|else|case|select|to|mod|const|polyphonic {
229 yyextra->token = KeywordToken(yytext);
230 return yyextra->token.baseType;
231 }
232
233
234 /* Variables */
235
236 "$"{ID} {
237 yyextra->token = IntegerVariableToken(yytext);
238 return yyextra->token.baseType;
239 }
240
241 "@"{ID} {
242 yyextra->token = StringVariableToken(yytext);
243 return yyextra->token.baseType;
244 }
245
246 "%"{ID} {
247 yyextra->token = ArrayVariableToken(yytext);
248 return yyextra->token.baseType;
249 }
250
251 {ID} {
252 yyextra->token = IdentifierToken(yytext);
253 return yyextra->token.baseType;
254 }
255
256
257 /* other */
258
259 <*>\n {
260 yyextra->token = NewLineToken();
261 ++yylineno;
262 yycolumn = 0;
263 return yyextra->token.baseType;
264 }
265
266 "{"[^}]*"}" {
267 yyextra->token = CommentToken(yytext);
268 yylineno += countNewLineChars(yytext);
269 return yyextra->token.baseType;
270 }
271
272 <*>\t {
273 yyextra->token = OtherToken(" ");
274 return yyextra->token.baseType;
275 }
276
277 \r+ /* eat up \r */
278
279 <<EOF>> {
280 yyextra->token = EofToken();
281 yyterminate();
282 }
283
284 <*>. {
285 yyextra->token = OtherToken(yytext);
286 return yyextra->token.baseType;
287 }
288
289
290 %%
291
292 namespace LinuxSampler {
293
294 int NkspScanner::processScanner() {
295 return Nksp_lex(scanner);
296 }
297
298 void NkspScanner::createScanner(std::istream* is) {
299 if (scanner) destroyScanner();
300 this->is = is;
301 Nksp_lex_init(&scanner);
302 Nksp_set_extra(this, scanner);
303 }
304
305 void NkspScanner::destroyScanner() {
306 if (!scanner) return;
307 Nksp_lex_destroy(scanner);
308 scanner = NULL;
309 }
310
311 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC