/[svn]/linuxsampler/trunk/src/scriptvm/parser.y
ViewVC logotype

Contents of /linuxsampler/trunk/src/scriptvm/parser.y

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2942 - (show annotations) (download)
Wed Jul 13 15:51:06 2016 UTC (7 years, 9 months ago) by schoenebeck
File size: 29737 byte(s)
* NKSP: Implemented built-in script variable "$KSP_TIMER".
* NKSP: Implemented built-in script variable "$NKSP_REAL_TIMER".
* NKSP: Implemented built-in script variable "$NKSP_PERF_TIMER".
* NKSP: Implemented built-in script variable "$ENGINE_UPTIME".
* Bumped version (2.0.0.svn14).

1 /*
2 * Copyright (c) 2014-2016 Christian Schoenebeck and Andreas Persson
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 /* Parser for NKSP real-time instrument script language. */
11
12 %{
13 #define YYERROR_VERBOSE 1
14 #include "parser_shared.h"
15 #include <string>
16 #include <map>
17 using namespace LinuxSampler;
18
19 void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err);
20 void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt);
21 int InstrScript_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
22 #define scanner context->scanner
23 #define PARSE_ERR(loc,txt) yyerror(&loc, context, txt)
24 #define PARSE_WRN(loc,txt) InstrScript_warning(&loc, context, txt)
25 %}
26
27 // generate reentrant safe parser
28 %pure-parser
29 %parse-param { LinuxSampler::ParserContext* context }
30 %lex-param { void* scanner }
31 // avoid symbol collision with other (i.e. future) auto generated (f)lex scanners
32 %name-prefix "InstrScript_"
33 %locations
34 %defines
35 %error-verbose
36
37 %token <iValue> INTEGER
38 %token <sValue> STRING
39 %token <sValue> IDENTIFIER
40 %token <sValue> VARIABLE
41 %token ON END INIT NOTE DECLARE ASSIGNMENT WHILE IF OR RELEASE AND ELSE
42 %token BITWISE_OR BITWISE_AND BITWISE_NOT
43 %token CONTROLLER SELECT CASE TO NOT CONST_ POLYPHONIC MOD
44 %token LE GE
45
46 %type <nEventHandlers> script eventhandlers
47 %type <nEventHandler> eventhandler
48 %type <nStatements> statements body
49 %type <nStatement> statement assignment
50 %type <nFunctionCall> functioncall
51 %type <nArgs> args
52 %type <nExpression> arg expr logical_or_expr logical_and_expr bitwise_or_expr bitwise_and_expr rel_expr add_expr mul_expr unary_expr concat_expr
53 %type <nCaseBranch> caseclause
54 %type <nCaseBranches> caseclauses
55
56 %start script
57
58 %%
59
60 script:
61 eventhandlers {
62 $$ = context->handlers = $1;
63 }
64
65 eventhandlers:
66 eventhandler {
67 $$ = new EventHandlers();
68 $$->add($1);
69 }
70 | eventhandlers eventhandler {
71 $$ = $1;
72 $$->add($2);
73 }
74
75 eventhandler:
76 ON NOTE body END ON {
77 if (context->onNote)
78 PARSE_ERR(@2, "Redeclaration of 'note' event handler.");
79 context->onNote = new OnNote($3);
80 $$ = context->onNote;
81 }
82 | ON INIT body END ON {
83 if (context->onInit)
84 PARSE_ERR(@2, "Redeclaration of 'init' event handler.");
85 context->onInit = new OnInit($3);
86 $$ = context->onInit;
87 }
88 | ON RELEASE body END ON {
89 if (context->onRelease)
90 PARSE_ERR(@2, "Redeclaration of 'release' event handler.");
91 context->onRelease = new OnRelease($3);
92 $$ = context->onRelease;
93 }
94 | ON CONTROLLER body END ON {
95 if (context->onController)
96 PARSE_ERR(@2, "Redeclaration of 'controller' event handler.");
97 context->onController = new OnController($3);
98 $$ = context->onController;
99 }
100
101 body:
102 /* epsilon (empty argument) */ {
103 $$ = new Statements();
104 }
105 | statements {
106 $$ = $1;
107 }
108
109 statements:
110 statement {
111 $$ = new Statements();
112 if ($1) {
113 if (!isNoOperation($1)) $$->add($1); // filter out NoOperation statements
114 } else
115 PARSE_WRN(@1, "Not a statement.");
116 }
117 | statements statement {
118 $$ = $1;
119 if ($2) {
120 if (!isNoOperation($2)) $$->add($2); // filter out NoOperation statements
121 } else
122 PARSE_WRN(@2, "Not a statement.");
123 }
124
125 statement:
126 functioncall {
127 $$ = $1;
128 }
129 | DECLARE VARIABLE {
130 const char* name = $2;
131 //printf("declared var '%s'\n", name);
132 if (context->variableByName(name))
133 PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
134 if (name[0] == '@') {
135 context->vartable[name] = new StringVariable(context);
136 $$ = new NoOperation;
137 } else {
138 context->vartable[name] = new IntVariable(context);
139 $$ = new NoOperation;
140 }
141 }
142 | DECLARE POLYPHONIC VARIABLE {
143 const char* name = $3;
144 //printf("declared polyphonic var '%s'\n", name);
145 if (context->variableByName(name))
146 PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str());
147 if (name[0] != '$') {
148 PARSE_ERR(@3, "Polyphonic variables may only be declared as integers.");
149 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
150 } else {
151 context->vartable[name] = new PolyphonicIntVariable(context);
152 $$ = new NoOperation;
153 }
154 }
155 | DECLARE VARIABLE ASSIGNMENT expr {
156 const char* name = $2;
157 //printf("declared assign var '%s'\n", name);
158 if (context->variableByName(name))
159 PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
160 if ($4->exprType() == STRING_EXPR) {
161 if (name[0] == '$')
162 PARSE_WRN(@2, (String("Variable '") + name + "' declared as integer, string expression assigned though.").c_str());
163 StringExprRef expr = $4;
164 if (expr->isConstExpr()) {
165 const String s = expr->evalStr();
166 StringVariableRef var = new StringVariable(context);
167 context->vartable[name] = var;
168 $$ = new Assignment(var, new StringLiteral(s));
169 } else {
170 StringVariableRef var = new StringVariable(context);
171 context->vartable[name] = var;
172 $$ = new Assignment(var, expr);
173 }
174 } else {
175 if (name[0] == '@')
176 PARSE_WRN(@2, (String("Variable '") + name + "' declared as string, integer expression assigned though.").c_str());
177 IntExprRef expr = $4;
178 if (expr->isConstExpr()) {
179 const int i = expr->evalInt();
180 IntVariableRef var = new IntVariable(context);
181 context->vartable[name] = var;
182 $$ = new Assignment(var, new IntLiteral(i));
183 } else {
184 IntVariableRef var = new IntVariable(context);
185 context->vartable[name] = var;
186 $$ = new Assignment(var, expr);
187 }
188 }
189 }
190 | DECLARE VARIABLE '[' expr ']' {
191 //printf("declare array without args\n");
192 const char* name = $2;
193 if (!$4->isConstExpr()) {
194 PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());
195 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
196 } else if ($4->exprType() != INT_EXPR) {
197 PARSE_ERR(@4, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());
198 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
199 } else if (context->variableByName(name)) {
200 PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
201 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
202 } else {
203 IntExprRef expr = $4;
204 int size = expr->evalInt();
205 if (size <= 0) {
206 PARSE_ERR(@4, (String("Array variable '") + name + "' declared with array size " + ToString(size) + ".").c_str());
207 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
208 } else {
209 context->vartable[name] = new IntArrayVariable(context, size);
210 $$ = new NoOperation;
211 }
212 }
213 }
214 | DECLARE VARIABLE '[' expr ']' ASSIGNMENT '(' args ')' {
215 const char* name = $2;
216 if (!$4->isConstExpr()) {
217 PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());
218 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
219 } else if ($4->exprType() != INT_EXPR) {
220 PARSE_ERR(@4, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());
221 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
222 } else if (context->variableByName(name)) {
223 PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
224 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
225 } else {
226 IntExprRef sizeExpr = $4;
227 ArgsRef args = $8;
228 int size = sizeExpr->evalInt();
229 if (size <= 0) {
230 PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with positive array size.").c_str());
231 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
232 } else if (args->argsCount() > size) {
233 PARSE_ERR(@8, (String("Variable '") + name +
234 "' was declared with size " + ToString(size) +
235 " but " + ToString(args->argsCount()) +
236 " values were assigned." ).c_str());
237 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
238 } else {
239 bool argsOK = true;
240 for (int i = 0; i < args->argsCount(); ++i) {
241 if (args->arg(i)->exprType() != INT_EXPR) {
242 PARSE_ERR(
243 @8,
244 (String("Array variable '") + name +
245 "' declared with invalid assignment values. Assigned element " +
246 ToString(i+1) + " is not an integer expression.").c_str()
247 );
248 argsOK = false;
249 break;
250 }
251 }
252 if (argsOK)
253 $$ = context->vartable[name] = new IntArrayVariable(context, size, args);
254 else
255 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
256 }
257 }
258 }
259 | DECLARE CONST_ VARIABLE ASSIGNMENT expr {
260 const char* name = $3;
261 if ($5->exprType() == STRING_EXPR) {
262 if (name[0] == '$')
263 PARSE_WRN(@5, "Variable declared as integer, string expression assigned though.");
264 String s;
265 StringExprRef expr = $5;
266 if (expr->isConstExpr())
267 s = expr->evalStr();
268 else
269 PARSE_ERR(@5, (String("Assignment to const string variable '") + name + "' requires const expression.").c_str());
270 ConstStringVariableRef var = new ConstStringVariable(context, s);
271 context->vartable[name] = var;
272 //$$ = new Assignment(var, new StringLiteral(s));
273 $$ = new NoOperation();
274 } else {
275 if (name[0] == '@')
276 PARSE_WRN(@5, "Variable declared as string, integer expression assigned though.");
277 int i = 0;
278 IntExprRef expr = $5;
279 if (expr->isConstExpr())
280 i = expr->evalInt();
281 else
282 PARSE_ERR(@5, (String("Assignment to const integer variable '") + name + "' requires const expression.").c_str());
283 ConstIntVariableRef var = new ConstIntVariable(i);
284 context->vartable[name] = var;
285 //$$ = new Assignment(var, new IntLiteral(i));
286 $$ = new NoOperation();
287 }
288 }
289 | assignment {
290 $$ = $1;
291 }
292 | WHILE '(' expr ')' statements END WHILE {
293 if ($3->exprType() == INT_EXPR) {
294 $$ = new While($3, $5);
295 } else {
296 PARSE_ERR(@3, "Condition for 'while' loops must be integer expression.");
297 $$ = new While(new IntLiteral(0), $5);
298 }
299 }
300 | IF '(' expr ')' statements ELSE statements END IF {
301 $$ = new If($3, $5, $7);
302 }
303 | IF '(' expr ')' statements END IF {
304 $$ = new If($3, $5);
305 }
306 | SELECT expr caseclauses END SELECT {
307 if ($2->exprType() == INT_EXPR) {
308 $$ = new SelectCase($2, $3);
309 } else {
310 PARSE_ERR(@2, "Statement 'select' can only by applied to integer expressions.");
311 $$ = new SelectCase(new IntLiteral(0), $3);
312 }
313 }
314
315 caseclauses:
316 caseclause {
317 $$ = CaseBranches();
318 $$.push_back($1);
319 }
320 | caseclauses caseclause {
321 $$ = $1;
322 $$.push_back($2);
323 }
324
325 caseclause:
326 CASE INTEGER statements {
327 $$ = CaseBranch();
328 $$.from = new IntLiteral($2);
329 $$.statements = $3;
330 }
331 | CASE INTEGER TO INTEGER statements {
332 $$ = CaseBranch();
333 $$.from = new IntLiteral($2);
334 $$.to = new IntLiteral($4);
335 $$.statements = $5;
336 }
337
338 functioncall:
339 IDENTIFIER '(' args ')' {
340 const char* name = $1;
341 //printf("function call of '%s' with args\n", name);
342 ArgsRef args = $3;
343 VMFunction* fn = context->functionProvider->functionByName(name);
344 if (!fn) {
345 PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
346 $$ = new FunctionCall(name, args, NULL);
347 } else if (args->argsCount() < fn->minRequiredArgs()) {
348 PARSE_ERR(@3, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
349 $$ = new FunctionCall(name, args, NULL);
350 } else if (args->argsCount() > fn->maxAllowedArgs()) {
351 PARSE_ERR(@3, (String("Built-in function '") + name + "' accepts max. " + ToString(fn->maxAllowedArgs()) + " arguments.").c_str());
352 $$ = new FunctionCall(name, args, NULL);
353 } else {
354 bool argsOK = true;
355 for (int i = 0; i < args->argsCount(); ++i) {
356 if (args->arg(i)->exprType() != fn->argType(i) && !fn->acceptsArgType(i, args->arg(i)->exprType())) {
357 PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects " + typeStr(fn->argType(i)) + " type, but type " + typeStr(args->arg(i)->exprType()) + " was given instead.").c_str());
358 argsOK = false;
359 break;
360 }
361 }
362 $$ = new FunctionCall(name, args, argsOK ? fn : NULL);
363 }
364 }
365 | IDENTIFIER '(' ')' {
366 const char* name = $1;
367 //printf("function call of '%s' (with empty args)\n", name);
368 ArgsRef args = new Args;
369 VMFunction* fn = context->functionProvider->functionByName(name);
370 if (!fn) {
371 PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
372 $$ = new FunctionCall(name, args, NULL);
373 } else if (fn->minRequiredArgs() > 0) {
374 PARSE_ERR(@3, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
375 $$ = new FunctionCall(name, args, NULL);
376 } else {
377 $$ = new FunctionCall(name, args, fn);
378 }
379 }
380 | IDENTIFIER {
381 const char* name = $1;
382 //printf("function call of '%s' (without args)\n", name);
383 ArgsRef args = new Args;
384 VMFunction* fn = context->functionProvider->functionByName(name);
385 if (!fn) {
386 PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
387 $$ = new FunctionCall(name, args, NULL);
388 } else if (fn->minRequiredArgs() > 0) {
389 PARSE_ERR(@1, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
390 $$ = new FunctionCall(name, args, NULL);
391 } else {
392 $$ = new FunctionCall(name, args, fn);
393 }
394 }
395
396 args:
397 arg {
398 $$ = new Args();
399 $$->add($1);
400 }
401 | args ',' arg {
402 $$ = $1;
403 $$->add($3);
404 }
405
406 arg:
407 expr
408
409 assignment:
410 VARIABLE ASSIGNMENT expr {
411 //printf("variable lookup with name '%s' as assignment expr\n", $1);
412 const char* name = $1;
413 VariableRef var = context->variableByName(name);
414 if (!var)
415 PARSE_ERR(@1, (String("Variable assignment: No variable declared with name '") + name + "'.").c_str());
416 else if (var->isConstExpr())
417 PARSE_ERR(@2, (String("Variable assignment: Cannot modify const variable '") + name + "'.").c_str());
418 else if (!var->isAssignable())
419 PARSE_ERR(@2, (String("Variable assignment: Variable '") + name + "' is not assignable.").c_str());
420 else if (var->exprType() != $3->exprType())
421 PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' is of type " + typeStr(var->exprType()) + ", assignment is of type " + typeStr($3->exprType()) + " though.").c_str());
422 $$ = new Assignment(var, $3);
423 }
424 | VARIABLE '[' expr ']' ASSIGNMENT expr {
425 const char* name = $1;
426 VariableRef var = context->variableByName(name);
427 if (!var)
428 PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
429 else if (var->exprType() != INT_ARR_EXPR)
430 PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str());
431 else if ($3->exprType() != INT_EXPR)
432 PARSE_ERR(@3, (String("Array variable '") + name + "' accessed with non integer expression.").c_str());
433 else if ($6->exprType() != INT_EXPR)
434 PARSE_ERR(@5, (String("Value assigned to array variable '") + name + "' must be an integer expression.").c_str());
435 IntArrayElementRef element = new IntArrayElement(var, $3);
436 $$ = new Assignment(element, $6);
437 }
438
439 unary_expr:
440 INTEGER {
441 $$ = new IntLiteral($1);
442 }
443 | STRING {
444 $$ = new StringLiteral($1);
445 }
446 | VARIABLE {
447 //printf("variable lookup with name '%s' as unary expr\n", $1);
448 VariableRef var = context->variableByName($1);
449 if (var)
450 $$ = var;
451 else {
452 PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str());
453 $$ = new IntLiteral(0);
454 }
455 }
456 | VARIABLE '[' expr ']' {
457 const char* name = $1;
458 VariableRef var = context->variableByName(name);
459 if (!var) {
460 PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
461 $$ = new IntLiteral(0);
462 } else if (var->exprType() != INT_ARR_EXPR) {
463 PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str());
464 $$ = new IntLiteral(0);
465 } else if ($3->exprType() != INT_EXPR) {
466 PARSE_ERR(@3, (String("Array variable '") + name + "' accessed with non integer expression.").c_str());
467 $$ = new IntLiteral(0);
468 } else {
469 $$ = new IntArrayElement(var, $3);
470 }
471 }
472 | '(' expr ')' {
473 $$ = $2;
474 }
475 | functioncall {
476 $$ = $1;
477 }
478 | '-' unary_expr {
479 $$ = new Neg($2);
480 }
481 | BITWISE_NOT unary_expr {
482 if ($2->exprType() != INT_EXPR) {
483 PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
484 $$ = new IntLiteral(0);
485 } else {
486 $$ = new BitwiseNot($2);
487 }
488 }
489 | NOT unary_expr {
490 if ($2->exprType() != INT_EXPR) {
491 PARSE_ERR(@2, (String("Right operand of operator 'not' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
492 $$ = new IntLiteral(0);
493 } else {
494 $$ = new Not($2);
495 }
496 }
497
498 expr:
499 concat_expr
500
501 concat_expr:
502 logical_or_expr
503 | concat_expr '&' logical_or_expr {
504 ExpressionRef lhs = $1;
505 ExpressionRef rhs = $3;
506 if (lhs->isConstExpr() && rhs->isConstExpr()) {
507 $$ = new StringLiteral(
508 lhs->evalCastToStr() + rhs->evalCastToStr()
509 );
510 } else {
511 $$ = new ConcatString(lhs, rhs);
512 }
513 }
514
515 logical_or_expr:
516 logical_and_expr
517 | logical_or_expr OR logical_and_expr {
518 ExpressionRef lhs = $1;
519 ExpressionRef rhs = $3;
520 if (lhs->exprType() != INT_EXPR) {
521 PARSE_ERR(@1, (String("Left operand of operator 'or' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
522 $$ = new IntLiteral(0);
523 } else if (rhs->exprType() != INT_EXPR) {
524 PARSE_ERR(@3, (String("Right operand of operator 'or' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
525 $$ = new IntLiteral(0);
526 } else {
527 $$ = new Or(lhs, rhs);
528 }
529 }
530
531 logical_and_expr:
532 bitwise_or_expr {
533 $$ = $1;
534 }
535 | logical_and_expr AND bitwise_or_expr {
536 ExpressionRef lhs = $1;
537 ExpressionRef rhs = $3;
538 if (lhs->exprType() != INT_EXPR) {
539 PARSE_ERR(@1, (String("Left operand of operator 'and' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
540 $$ = new IntLiteral(0);
541 } else if (rhs->exprType() != INT_EXPR) {
542 PARSE_ERR(@3, (String("Right operand of operator 'and' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
543 $$ = new IntLiteral(0);
544 } else {
545 $$ = new And(lhs, rhs);
546 }
547 }
548
549 bitwise_or_expr:
550 bitwise_and_expr
551 | bitwise_or_expr BITWISE_OR bitwise_and_expr {
552 ExpressionRef lhs = $1;
553 ExpressionRef rhs = $3;
554 if (lhs->exprType() != INT_EXPR) {
555 PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
556 $$ = new IntLiteral(0);
557 } else if (rhs->exprType() != INT_EXPR) {
558 PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
559 $$ = new IntLiteral(0);
560 } else {
561 $$ = new BitwiseOr(lhs, rhs);
562 }
563 }
564
565 bitwise_and_expr:
566 rel_expr {
567 $$ = $1;
568 }
569 | bitwise_and_expr BITWISE_AND rel_expr {
570 ExpressionRef lhs = $1;
571 ExpressionRef rhs = $3;
572 if (lhs->exprType() != INT_EXPR) {
573 PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
574 $$ = new IntLiteral(0);
575 } else if (rhs->exprType() != INT_EXPR) {
576 PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
577 $$ = new IntLiteral(0);
578 } else {
579 $$ = new BitwiseAnd(lhs, rhs);
580 }
581 }
582
583 rel_expr:
584 add_expr
585 | rel_expr '<' add_expr {
586 ExpressionRef lhs = $1;
587 ExpressionRef rhs = $3;
588 if (lhs->exprType() != INT_EXPR) {
589 PARSE_ERR(@1, (String("Left operand of operator '<' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
590 $$ = new IntLiteral(0);
591 } else if (rhs->exprType() != INT_EXPR) {
592 PARSE_ERR(@3, (String("Right operand of operator '<' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
593 $$ = new IntLiteral(0);
594 } else {
595 $$ = new Relation(lhs, Relation::LESS_THAN, rhs);
596 }
597 }
598 | rel_expr '>' add_expr {
599 ExpressionRef lhs = $1;
600 ExpressionRef rhs = $3;
601 if (lhs->exprType() != INT_EXPR) {
602 PARSE_ERR(@1, (String("Left operand of operator '>' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
603 $$ = new IntLiteral(0);
604 } else if (rhs->exprType() != INT_EXPR) {
605 PARSE_ERR(@3, (String("Right operand of operator '>' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
606 $$ = new IntLiteral(0);
607 } else {
608 $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);
609 }
610 }
611 | rel_expr LE add_expr {
612 ExpressionRef lhs = $1;
613 ExpressionRef rhs = $3;
614 if (lhs->exprType() != INT_EXPR) {
615 PARSE_ERR(@1, (String("Left operand of operator '<=' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
616 $$ = new IntLiteral(0);
617 } else if (rhs->exprType() != INT_EXPR) {
618 PARSE_ERR(@3, (String("Right operand of operator '<=' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
619 $$ = new IntLiteral(0);
620 } else {
621 $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);
622 }
623 }
624 | rel_expr GE add_expr {
625 ExpressionRef lhs = $1;
626 ExpressionRef rhs = $3;
627 if (lhs->exprType() != INT_EXPR) {
628 PARSE_ERR(@1, (String("Left operand of operator '>=' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
629 $$ = new IntLiteral(0);
630 } else if (rhs->exprType() != INT_EXPR) {
631 PARSE_ERR(@3, (String("Right operand of operator '>=' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
632 $$ = new IntLiteral(0);
633 } else {
634 $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);
635 }
636 }
637 | rel_expr '=' add_expr {
638 $$ = new Relation($1, Relation::EQUAL, $3);
639 }
640 | rel_expr '#' add_expr {
641 $$ = new Relation($1, Relation::NOT_EQUAL, $3);
642 }
643
644 add_expr:
645 mul_expr
646 | add_expr '+' mul_expr {
647 ExpressionRef lhs = $1;
648 ExpressionRef rhs = $3;
649 if (lhs->exprType() != INT_EXPR) {
650 PARSE_ERR(@1, (String("Left operand of operator '+' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
651 $$ = new IntLiteral(0);
652 } else if (rhs->exprType() != INT_EXPR) {
653 PARSE_ERR(@3, (String("Right operand of operator '+' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
654 $$ = new IntLiteral(0);
655 } else {
656 $$ = new Add(lhs,rhs);
657 }
658 }
659 | add_expr '-' mul_expr {
660 ExpressionRef lhs = $1;
661 ExpressionRef rhs = $3;
662 if (lhs->exprType() != INT_EXPR) {
663 PARSE_ERR(@1, (String("Left operand of operator '-' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
664 $$ = new IntLiteral(0);
665 } else if (rhs->exprType() != INT_EXPR) {
666 PARSE_ERR(@3, (String("Right operand of operator '-' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
667 $$ = new IntLiteral(0);
668 } else {
669 $$ = new Sub(lhs,rhs);
670 }
671 }
672
673 mul_expr:
674 unary_expr
675 | mul_expr '*' unary_expr {
676 ExpressionRef lhs = $1;
677 ExpressionRef rhs = $3;
678 if (lhs->exprType() != INT_EXPR) {
679 PARSE_ERR(@1, (String("Left operand of operator '*' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
680 $$ = new IntLiteral(0);
681 } else if (rhs->exprType() != INT_EXPR) {
682 PARSE_ERR(@3, (String("Right operand of operator '*' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
683 $$ = new IntLiteral(0);
684 } else {
685 $$ = new Mul(lhs,rhs);
686 }
687 }
688 | mul_expr '/' unary_expr {
689 ExpressionRef lhs = $1;
690 ExpressionRef rhs = $3;
691 if (lhs->exprType() != INT_EXPR) {
692 PARSE_ERR(@1, (String("Left operand of operator '/' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
693 $$ = new IntLiteral(0);
694 } else if (rhs->exprType() != INT_EXPR) {
695 PARSE_ERR(@3, (String("Right operand of operator '/' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
696 $$ = new IntLiteral(0);
697 } else {
698 $$ = new Div(lhs,rhs);
699 }
700 }
701 | mul_expr MOD unary_expr {
702 ExpressionRef lhs = $1;
703 ExpressionRef rhs = $3;
704 if (lhs->exprType() != INT_EXPR) {
705 PARSE_ERR(@1, (String("Left operand of modulo operator must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
706 $$ = new IntLiteral(0);
707 } else if (rhs->exprType() != INT_EXPR) {
708 PARSE_ERR(@3, (String("Right operand of modulo operator must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
709 $$ = new IntLiteral(0);
710 } else {
711 $$ = new Mod(lhs,rhs);
712 }
713 }
714
715 %%
716
717 void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {
718 //fprintf(stderr, "%d: %s\n", locp->first_line, err);
719 context->addErr(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, err);
720 }
721
722 void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {
723 //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);
724 context->addWrn(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, txt);
725 }

  ViewVC Help
Powered by ViewVC