1 |
/* |
/* |
2 |
* Copyright (c) 2014-2016 Christian Schoenebeck and Andreas Persson |
* Copyright (c) 2014-2017 Christian Schoenebeck and Andreas Persson |
3 |
* |
* |
4 |
* http://www.linuxsampler.org |
* http://www.linuxsampler.org |
5 |
* |
* |
76 |
if (nl) yycolumn = countCharsPastLastNewLine(yytext); \ |
if (nl) yycolumn = countCharsPastLastNewLine(yytext); \ |
77 |
} |
} |
78 |
|
|
79 |
|
// if compiled for debugging, throw an exception instead of exiting on fatal |
80 |
|
// lexer errors (so the debugger may pause with the appropriate back trace) |
81 |
|
#if DEBUG |
82 |
|
# include <stdexcept> |
83 |
|
# define YY_FATAL_ERROR(msg) throw std::runtime_error(msg) |
84 |
|
#endif |
85 |
|
|
86 |
%} |
%} |
87 |
|
|
88 |
/* use Flex's built-in support for line numbers |
/* use Flex's built-in support for line numbers |
108 |
%x PREPROC_SET_COND PREPROC_RESET_COND PREPROC_IF PREPROC_IF_NOT PREPROC_BODY_EAT PREPROC_PRE_BODY_USE PREPROC_PRE_BODY_EAT |
%x PREPROC_SET_COND PREPROC_RESET_COND PREPROC_IF PREPROC_IF_NOT PREPROC_BODY_EAT PREPROC_PRE_BODY_USE PREPROC_PRE_BODY_EAT |
109 |
|
|
110 |
DIGIT [0-9] |
DIGIT [0-9] |
111 |
ID [a-zA-Z0-9_]+ |
ID [a-zA-Z][a-zA-Z0-9_]* |
112 |
|
METRIC (k|h|(da)|d|c|m|u) |
113 |
|
UNIT (s|(Hz)|B) |
114 |
|
|
115 |
%% |
%% |
116 |
|
|
121 |
} |
} |
122 |
|
|
123 |
{DIGIT}+ { |
{DIGIT}+ { |
124 |
yylval->iValue = atoi(yytext); |
if (sizeof(vmint) < 8) |
125 |
|
yylval->iValue = atoi(yytext); |
126 |
|
else |
127 |
|
yylval->iValue = atoll(yytext); |
128 |
return INTEGER; |
return INTEGER; |
129 |
} |
} |
130 |
|
|
131 |
/* there is currently no support for floating point numbers in NKSP yet */ |
{DIGIT}+"."{DIGIT}+ { |
132 |
/*{DIGIT}+"."{DIGIT}* { |
yylval->fValue = atof(yytext); |
133 |
printf("A float: %s (%g)\n", yytext, atof(yytext)); |
return REAL; |
134 |
}*/ |
} |
135 |
|
|
136 |
|
{DIGIT}+({METRIC}{1,2}|({METRIC}{0,2}{UNIT}?)) { |
137 |
|
int pos = 0; |
138 |
|
|
139 |
|
// parse number portion |
140 |
|
vmint value = 0; |
141 |
|
for (; yytext[pos] >= '0' && yytext[pos] <= '9'; ++pos) { |
142 |
|
value *= 10; |
143 |
|
value += yytext[pos] - '0'; |
144 |
|
} |
145 |
|
yylval->iUnitValue.iValue = value; |
146 |
|
|
147 |
|
// parse metric prefix portion |
148 |
|
for (int i = 0; i < 2; ++i, ++pos) { |
149 |
|
switch (yytext[pos]) { |
150 |
|
case 'k': yylval->iUnitValue.prefix[i] = VM_KILO; continue; |
151 |
|
case 'h': yylval->iUnitValue.prefix[i] = VM_HECTO; continue; |
152 |
|
case 'c': yylval->iUnitValue.prefix[i] = VM_CENTI; continue; |
153 |
|
case 'm': yylval->iUnitValue.prefix[i] = VM_MILLI; continue; |
154 |
|
case 'u': yylval->iUnitValue.prefix[i] = VM_MICRO; continue; |
155 |
|
case 'd': |
156 |
|
if (yytext[pos+1] == 'a') { |
157 |
|
yylval->iUnitValue.prefix[i] = VM_DECA; |
158 |
|
++pos; |
159 |
|
} else { |
160 |
|
yylval->iUnitValue.prefix[i] = VM_DECI; |
161 |
|
} |
162 |
|
continue; |
163 |
|
default: |
164 |
|
yylval->iUnitValue.prefix[i] = VM_NO_PREFIX; |
165 |
|
goto parseIntStdUnit; |
166 |
|
} |
167 |
|
} |
168 |
|
|
169 |
|
parseIntStdUnit: |
170 |
|
|
171 |
|
// parse standard measurement unit |
172 |
|
switch (yytext[pos]) { |
173 |
|
case 's': yylval->iUnitValue.unit = VM_SECOND; break; |
174 |
|
case 'H': yylval->iUnitValue.unit = VM_HERTZ; break; |
175 |
|
case 'B': yylval->iUnitValue.unit = VM_BEL; break; |
176 |
|
default: yylval->iUnitValue.unit = VM_NO_UNIT; break; |
177 |
|
} |
178 |
|
|
179 |
|
return INTEGER_UNIT; |
180 |
|
} |
181 |
|
|
182 |
|
{DIGIT}+"."{DIGIT}+({METRIC}{1,2}|({METRIC}{0,2}{UNIT}?)) { |
183 |
|
int pos = 0; |
184 |
|
|
185 |
|
// parse number portion |
186 |
|
for (; (yytext[pos] >= '0' && yytext[pos] <= '9') || yytext[pos] == '.'; ++pos) { |
187 |
|
} |
188 |
|
{ |
189 |
|
const char tmp = yytext[pos]; |
190 |
|
yytext[pos] = 0; // mark temporary end of string |
191 |
|
yylval->fUnitValue.fValue = atof(yytext); |
192 |
|
yytext[pos] = tmp; // restore |
193 |
|
} |
194 |
|
|
195 |
|
// parse metric prefix portion |
196 |
|
for (int i = 0; i < 2; ++i, ++pos) { |
197 |
|
switch (yytext[pos]) { |
198 |
|
case 'k': yylval->fUnitValue.prefix[i] = VM_KILO; continue; |
199 |
|
case 'h': yylval->fUnitValue.prefix[i] = VM_HECTO; continue; |
200 |
|
case 'c': yylval->fUnitValue.prefix[i] = VM_CENTI; continue; |
201 |
|
case 'm': yylval->fUnitValue.prefix[i] = VM_MILLI; continue; |
202 |
|
case 'u': yylval->fUnitValue.prefix[i] = VM_MICRO; continue; |
203 |
|
case 'd': |
204 |
|
if (yytext[pos+1] == 'a') { |
205 |
|
yylval->fUnitValue.prefix[i] = VM_DECA; |
206 |
|
++pos; |
207 |
|
} else { |
208 |
|
yylval->fUnitValue.prefix[i] = VM_DECI; |
209 |
|
} |
210 |
|
continue; |
211 |
|
default: |
212 |
|
yylval->fUnitValue.prefix[i] = VM_NO_PREFIX; |
213 |
|
goto parseRealStdUnit; |
214 |
|
} |
215 |
|
} |
216 |
|
|
217 |
|
parseRealStdUnit: |
218 |
|
|
219 |
|
// parse standard measurement unit |
220 |
|
switch (yytext[pos]) { |
221 |
|
case 's': yylval->fUnitValue.unit = VM_SECOND; break; |
222 |
|
case 'H': yylval->fUnitValue.unit = VM_HERTZ; break; |
223 |
|
case 'B': yylval->fUnitValue.unit = VM_BEL; break; |
224 |
|
default: yylval->fUnitValue.unit = VM_NO_UNIT; break; |
225 |
|
} |
226 |
|
|
227 |
|
return REAL_UNIT; |
228 |
|
} |
229 |
|
|
230 |
|
|
231 |
/* Preprocessor statement: SET_CONDITION(name) */ |
/* Preprocessor statement: SET_CONDITION(name) */ |
282 |
*/ |
*/ |
283 |
|
|
284 |
<*>"USE_CODE_IF"[ \t]*"(" { |
<*>"USE_CODE_IF"[ \t]*"(" { |
285 |
//printf("USE_CODE_IF\n"); |
//printf("{%s}\n", yytext); |
286 |
yy_push_state(PREPROC_IF, yyscanner); |
yy_push_state(PREPROC_IF, yyscanner); |
287 |
} |
} |
288 |
|
<PREPROC_BODY_EAT>"USE_CODE_IF"[ \t]*"("{ID}")" { |
289 |
|
//printf("[EAT{%s}\n", yytext); |
290 |
|
yy_push_state(PREPROC_BODY_EAT, yyscanner); |
291 |
|
} |
292 |
<*>"USE_CODE_IF_NOT"[ \t]*"(" { |
<*>"USE_CODE_IF_NOT"[ \t]*"(" { |
293 |
//printf("USE_CODE_IF_NOT\n"); |
//printf("USE_CODE_IF_NOT\n"); |
294 |
yy_push_state(PREPROC_IF_NOT, yyscanner); |
yy_push_state(PREPROC_IF_NOT, yyscanner); |
295 |
} |
} |
296 |
|
<PREPROC_BODY_EAT>"USE_CODE_IF_NOT"[ \t]*"("{ID}")" { |
297 |
|
//printf("[EAT{%s}\n", yytext); |
298 |
|
yy_push_state(PREPROC_BODY_EAT, yyscanner); |
299 |
|
} |
300 |
<PREPROC_IF>{ID} { |
<PREPROC_IF>{ID} { |
301 |
//printf("preproc use code if '%s'\n", yytext); |
//printf("preproc use code if '%s'\n", yytext); |
302 |
yy_pop_state(yyscanner); |
yy_pop_state(yyscanner); |
318 |
yy_push_state(PREPROC_BODY_USE, yyscanner); |
yy_push_state(PREPROC_BODY_USE, yyscanner); |
319 |
} |
} |
320 |
<PREPROC_PRE_BODY_EAT>[ \t]*")" { |
<PREPROC_PRE_BODY_EAT>[ \t]*")" { |
321 |
//printf("PREPROCESSOR EAT : \n"); |
//printf("PREPROCESSOR EAT : {%s}\n", yytext); |
322 |
yy_pop_state(yyscanner); |
yy_pop_state(yyscanner); |
323 |
yy_push_state(PREPROC_BODY_EAT, yyscanner); |
yy_push_state(PREPROC_BODY_EAT, yyscanner); |
324 |
} |
} |
325 |
<*>.*"END_USE_CODE" { |
<PREPROC_BODY_EAT,PREPROC_BODY_USE>"END_USE_CODE" { |
326 |
//printf("-->END_USE_CODE\n"); |
//printf("-->END_USE_CODE\n"); |
327 |
yy_pop_state(yyscanner); |
yy_pop_state(yyscanner); |
328 |
} |
} |
329 |
<PREPROC_BODY_EAT>[ \t\r\n]* { /* eat up code block filtered out by preprocessor */ |
<PREPROC_BODY_EAT>[ \t\r\n]* { /* eat up code block filtered out by preprocessor */ |
330 |
|
//printf("PREPROCESSOR EAT2 : {%s}\n", yytext); |
331 |
processLocation(); |
processLocation(); |
332 |
} |
} |
333 |
<PREPROC_BODY_EAT>.* { /* eat up code block filtered out by preprocessor */ |
<PREPROC_BODY_EAT>.* { /* eat up code block filtered out by preprocessor */ |
334 |
processLocation(); |
//printf("PREPROCESSOR EAT3 : {%s}\n", yytext); |
335 |
|
yyextra->addPreprocessorComment(yylloc->first_line, yylloc->last_line, |
336 |
|
yylloc->first_column+1, yylloc->last_column+1); |
337 |
} |
} |
338 |
|
|
339 |
|
|
365 |
"mod" return MOD; |
"mod" return MOD; |
366 |
"function" return FUNCTION; |
"function" return FUNCTION; |
367 |
"call" return CALL; |
"call" return CALL; |
368 |
|
"synchronized" return SYNCHRONIZED; |
369 |
|
|
370 |
[&,()[\]<>=*+#/-] { |
[&,!()[\]<>=*+#\/-] { |
371 |
return *yytext; |
return *yytext; |
372 |
} |
} |
373 |
|
|
374 |
("$"|"@"|"%"){ID} { |
("$"|"@"|"%"|"~"|"?"){ID} { |
375 |
yylval->sValue = strdup(yytext); |
yylval->sValue = strdup(yytext); |
376 |
return VARIABLE; |
return VARIABLE; |
377 |
} |
} |
396 |
|
|
397 |
[ \t\r]+ /* eat up whitespace */ |
[ \t\r]+ /* eat up whitespace */ |
398 |
|
|
399 |
. printf( "Unrecognized character: '%s' (line %d, column %d)\n", yytext, yylineno, yycolumn); |
. { |
400 |
|
printf( "Unrecognized character: '%s' (line %d, column %d)\n", yytext, yylineno, yycolumn); |
401 |
|
return UNKNOWN_CHAR; |
402 |
|
} |
403 |
|
|
404 |
%% |
%% |
405 |
|
|