/[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 3260 - (show annotations) (download)
Wed May 31 21:07:44 2017 UTC (6 years, 10 months ago) by schoenebeck
File size: 8028 byte(s)
* NKSP language: Added support for "synchronized .. end synchronized"
  code blocks.
* Bumped version (2.0.0.svn60).

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

  ViewVC Help
Powered by ViewVC