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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2885 - (hide 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 schoenebeck 2885 /*
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