/[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 2935 - (show annotations) (download)
Sun Jul 10 14:24:13 2016 UTC (7 years, 9 months ago) by schoenebeck
File size: 29586 byte(s)
* NKSP: Added & implemented built-in script function "change_cutoff()".
* NKSP: Added & implemented built-in script function "change_reso()".
* NKSP: Added & implemented built-in script function "event_status()".
* NKSP: Added built-in script constants "$EVENT_STATUS_INACTIVE" and
  "$EVENT_STATUS_NOTE_QUEUE" both for being used as flags for
  built-in "event_status()" script function.
* NKSP language: Added support for bitwise operators ".or.", ".and."
  and ".not.".
* NKSP language scanner: Fixed IDs matching to require at least one
  character (i.e. when matching function names or variable names).
* NKSP language scanner: disabled unusued rules.
* Bumped version (2.0.0.svn12).

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->exprType() != $3->exprType())
419 PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' is of type " + typeStr(var->exprType()) + ", assignment is of type " + typeStr($3->exprType()) + " though.").c_str());
420 $$ = new Assignment(var, $3);
421 }
422 | VARIABLE '[' expr ']' ASSIGNMENT expr {
423 const char* name = $1;
424 VariableRef var = context->variableByName(name);
425 if (!var)
426 PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
427 else if (var->exprType() != INT_ARR_EXPR)
428 PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str());
429 else if ($3->exprType() != INT_EXPR)
430 PARSE_ERR(@3, (String("Array variable '") + name + "' accessed with non integer expression.").c_str());
431 else if ($6->exprType() != INT_EXPR)
432 PARSE_ERR(@5, (String("Value assigned to array variable '") + name + "' must be an integer expression.").c_str());
433 IntArrayElementRef element = new IntArrayElement(var, $3);
434 $$ = new Assignment(element, $6);
435 }
436
437 unary_expr:
438 INTEGER {
439 $$ = new IntLiteral($1);
440 }
441 | STRING {
442 $$ = new StringLiteral($1);
443 }
444 | VARIABLE {
445 //printf("variable lookup with name '%s' as unary expr\n", $1);
446 VariableRef var = context->variableByName($1);
447 if (var)
448 $$ = var;
449 else {
450 PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str());
451 $$ = new IntLiteral(0);
452 }
453 }
454 | VARIABLE '[' expr ']' {
455 const char* name = $1;
456 VariableRef var = context->variableByName(name);
457 if (!var) {
458 PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
459 $$ = new IntLiteral(0);
460 } else if (var->exprType() != INT_ARR_EXPR) {
461 PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str());
462 $$ = new IntLiteral(0);
463 } else if ($3->exprType() != INT_EXPR) {
464 PARSE_ERR(@3, (String("Array variable '") + name + "' accessed with non integer expression.").c_str());
465 $$ = new IntLiteral(0);
466 } else {
467 $$ = new IntArrayElement(var, $3);
468 }
469 }
470 | '(' expr ')' {
471 $$ = $2;
472 }
473 | functioncall {
474 $$ = $1;
475 }
476 | '-' unary_expr {
477 $$ = new Neg($2);
478 }
479 | BITWISE_NOT unary_expr {
480 if ($2->exprType() != INT_EXPR) {
481 PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
482 $$ = new IntLiteral(0);
483 } else {
484 $$ = new BitwiseNot($2);
485 }
486 }
487 | NOT unary_expr {
488 if ($2->exprType() != INT_EXPR) {
489 PARSE_ERR(@2, (String("Right operand of operator 'not' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
490 $$ = new IntLiteral(0);
491 } else {
492 $$ = new Not($2);
493 }
494 }
495
496 expr:
497 concat_expr
498
499 concat_expr:
500 logical_or_expr
501 | concat_expr '&' logical_or_expr {
502 ExpressionRef lhs = $1;
503 ExpressionRef rhs = $3;
504 if (lhs->isConstExpr() && rhs->isConstExpr()) {
505 $$ = new StringLiteral(
506 lhs->evalCastToStr() + rhs->evalCastToStr()
507 );
508 } else {
509 $$ = new ConcatString(lhs, rhs);
510 }
511 }
512
513 logical_or_expr:
514 logical_and_expr
515 | logical_or_expr OR logical_and_expr {
516 ExpressionRef lhs = $1;
517 ExpressionRef rhs = $3;
518 if (lhs->exprType() != INT_EXPR) {
519 PARSE_ERR(@1, (String("Left operand of operator 'or' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
520 $$ = new IntLiteral(0);
521 } else if (rhs->exprType() != INT_EXPR) {
522 PARSE_ERR(@3, (String("Right operand of operator 'or' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
523 $$ = new IntLiteral(0);
524 } else {
525 $$ = new Or(lhs, rhs);
526 }
527 }
528
529 logical_and_expr:
530 bitwise_or_expr {
531 $$ = $1;
532 }
533 | logical_and_expr AND bitwise_or_expr {
534 ExpressionRef lhs = $1;
535 ExpressionRef rhs = $3;
536 if (lhs->exprType() != INT_EXPR) {
537 PARSE_ERR(@1, (String("Left operand of operator 'and' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
538 $$ = new IntLiteral(0);
539 } else if (rhs->exprType() != INT_EXPR) {
540 PARSE_ERR(@3, (String("Right operand of operator 'and' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
541 $$ = new IntLiteral(0);
542 } else {
543 $$ = new And(lhs, rhs);
544 }
545 }
546
547 bitwise_or_expr:
548 bitwise_and_expr
549 | bitwise_or_expr BITWISE_OR bitwise_and_expr {
550 ExpressionRef lhs = $1;
551 ExpressionRef rhs = $3;
552 if (lhs->exprType() != INT_EXPR) {
553 PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
554 $$ = new IntLiteral(0);
555 } else if (rhs->exprType() != INT_EXPR) {
556 PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
557 $$ = new IntLiteral(0);
558 } else {
559 $$ = new BitwiseOr(lhs, rhs);
560 }
561 }
562
563 bitwise_and_expr:
564 rel_expr {
565 $$ = $1;
566 }
567 | bitwise_and_expr BITWISE_AND rel_expr {
568 ExpressionRef lhs = $1;
569 ExpressionRef rhs = $3;
570 if (lhs->exprType() != INT_EXPR) {
571 PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
572 $$ = new IntLiteral(0);
573 } else if (rhs->exprType() != INT_EXPR) {
574 PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
575 $$ = new IntLiteral(0);
576 } else {
577 $$ = new BitwiseAnd(lhs, rhs);
578 }
579 }
580
581 rel_expr:
582 add_expr
583 | rel_expr '<' add_expr {
584 ExpressionRef lhs = $1;
585 ExpressionRef rhs = $3;
586 if (lhs->exprType() != INT_EXPR) {
587 PARSE_ERR(@1, (String("Left operand of operator '<' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
588 $$ = new IntLiteral(0);
589 } else if (rhs->exprType() != INT_EXPR) {
590 PARSE_ERR(@3, (String("Right operand of operator '<' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
591 $$ = new IntLiteral(0);
592 } else {
593 $$ = new Relation(lhs, Relation::LESS_THAN, rhs);
594 }
595 }
596 | rel_expr '>' add_expr {
597 ExpressionRef lhs = $1;
598 ExpressionRef rhs = $3;
599 if (lhs->exprType() != INT_EXPR) {
600 PARSE_ERR(@1, (String("Left operand of operator '>' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
601 $$ = new IntLiteral(0);
602 } else if (rhs->exprType() != INT_EXPR) {
603 PARSE_ERR(@3, (String("Right operand of operator '>' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
604 $$ = new IntLiteral(0);
605 } else {
606 $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);
607 }
608 }
609 | rel_expr LE add_expr {
610 ExpressionRef lhs = $1;
611 ExpressionRef rhs = $3;
612 if (lhs->exprType() != INT_EXPR) {
613 PARSE_ERR(@1, (String("Left operand of operator '<=' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
614 $$ = new IntLiteral(0);
615 } else if (rhs->exprType() != INT_EXPR) {
616 PARSE_ERR(@3, (String("Right operand of operator '<=' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
617 $$ = new IntLiteral(0);
618 } else {
619 $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);
620 }
621 }
622 | rel_expr GE add_expr {
623 ExpressionRef lhs = $1;
624 ExpressionRef rhs = $3;
625 if (lhs->exprType() != INT_EXPR) {
626 PARSE_ERR(@1, (String("Left operand of operator '>=' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
627 $$ = new IntLiteral(0);
628 } else if (rhs->exprType() != INT_EXPR) {
629 PARSE_ERR(@3, (String("Right operand of operator '>=' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
630 $$ = new IntLiteral(0);
631 } else {
632 $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);
633 }
634 }
635 | rel_expr '=' add_expr {
636 $$ = new Relation($1, Relation::EQUAL, $3);
637 }
638 | rel_expr '#' add_expr {
639 $$ = new Relation($1, Relation::NOT_EQUAL, $3);
640 }
641
642 add_expr:
643 mul_expr
644 | add_expr '+' mul_expr {
645 ExpressionRef lhs = $1;
646 ExpressionRef rhs = $3;
647 if (lhs->exprType() != INT_EXPR) {
648 PARSE_ERR(@1, (String("Left operand of operator '+' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
649 $$ = new IntLiteral(0);
650 } else if (rhs->exprType() != INT_EXPR) {
651 PARSE_ERR(@3, (String("Right operand of operator '+' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
652 $$ = new IntLiteral(0);
653 } else {
654 $$ = new Add(lhs,rhs);
655 }
656 }
657 | add_expr '-' mul_expr {
658 ExpressionRef lhs = $1;
659 ExpressionRef rhs = $3;
660 if (lhs->exprType() != INT_EXPR) {
661 PARSE_ERR(@1, (String("Left operand of operator '-' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
662 $$ = new IntLiteral(0);
663 } else if (rhs->exprType() != INT_EXPR) {
664 PARSE_ERR(@3, (String("Right operand of operator '-' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
665 $$ = new IntLiteral(0);
666 } else {
667 $$ = new Sub(lhs,rhs);
668 }
669 }
670
671 mul_expr:
672 unary_expr
673 | mul_expr '*' unary_expr {
674 ExpressionRef lhs = $1;
675 ExpressionRef rhs = $3;
676 if (lhs->exprType() != INT_EXPR) {
677 PARSE_ERR(@1, (String("Left operand of operator '*' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
678 $$ = new IntLiteral(0);
679 } else if (rhs->exprType() != INT_EXPR) {
680 PARSE_ERR(@3, (String("Right operand of operator '*' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
681 $$ = new IntLiteral(0);
682 } else {
683 $$ = new Mul(lhs,rhs);
684 }
685 }
686 | mul_expr '/' unary_expr {
687 ExpressionRef lhs = $1;
688 ExpressionRef rhs = $3;
689 if (lhs->exprType() != INT_EXPR) {
690 PARSE_ERR(@1, (String("Left operand of operator '/' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
691 $$ = new IntLiteral(0);
692 } else if (rhs->exprType() != INT_EXPR) {
693 PARSE_ERR(@3, (String("Right operand of operator '/' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
694 $$ = new IntLiteral(0);
695 } else {
696 $$ = new Div(lhs,rhs);
697 }
698 }
699 | mul_expr MOD unary_expr {
700 ExpressionRef lhs = $1;
701 ExpressionRef rhs = $3;
702 if (lhs->exprType() != INT_EXPR) {
703 PARSE_ERR(@1, (String("Left operand of modulo operator must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
704 $$ = new IntLiteral(0);
705 } else if (rhs->exprType() != INT_EXPR) {
706 PARSE_ERR(@3, (String("Right operand of modulo operator must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
707 $$ = new IntLiteral(0);
708 } else {
709 $$ = new Mod(lhs,rhs);
710 }
711 }
712
713 %%
714
715 void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {
716 //fprintf(stderr, "%d: %s\n", locp->first_line, err);
717 context->addErr(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, err);
718 }
719
720 void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {
721 //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);
722 context->addWrn(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, txt);
723 }

  ViewVC Help
Powered by ViewVC