/[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 3054 - (hide annotations) (download)
Thu Dec 15 12:47:45 2016 UTC (7 years, 4 months ago) by schoenebeck
File size: 8015 byte(s)
* Fixed numerous compiler warnings.
* Bumped version (2.0.0.svn32).

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 schoenebeck 3054 // 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 schoenebeck 2885 %}
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 schoenebeck 2935 ID [a-zA-Z0-9_]+
68 schoenebeck 2885
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 schoenebeck 2935 /* there is currently no support for floating point numbers in NKSP yet */
82     /*{DIGIT}+"."{DIGIT}* {
83 schoenebeck 2885 yyextra->token = NumberLiteralToken(yytext);
84     return yyextra->token.baseType;
85 schoenebeck 2935 }*/
86 schoenebeck 2885
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 schoenebeck 2935 ".or."|".and."|".not." {
229     yyextra->token = KeywordToken(yytext);
230     return yyextra->token.baseType;
231     }
232    
233 schoenebeck 2951 declare|while|if|or|and|not|else|case|select|to|mod|const|polyphonic|function|call {
234 schoenebeck 2885 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