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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2888 - (hide annotations) (download)
Sun Apr 24 18:16:10 2016 UTC (7 years, 11 months ago) by schoenebeck
File size: 27429 byte(s)
* Instrument Scripts: Fixed line numbers on parser error/warning messages.
* Instrument Scripts: Added output of precise column on parser
  error/warning messages.
* Shut up some irrelevant errors of parser generating shell scripts.
* Bumped version (2.0.0.svn6).

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

  ViewVC Help
Powered by ViewVC