1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4 -*- */
3 /* Parser for the Faust language */
12 #include "errormsg.hh"
13 #include "sourcereader.hh"
21 #define YYERROR_VERBOSE 1
22 #define YYMAXDEPTH 100000
27 extern const char* yyfilename;
31 extern bool gStripDocSwitch;
32 extern bool gLstDependenciesSwitch;
33 extern bool gLstDistributedSwitch;
34 extern bool gLstMdocTagsSwitch;
36 extern map<Tree, set<Tree> > gMetaDataSet;
37 extern vector<Tree> gDocVector;
42 //----------------------------------------------------------
43 // unquote() : remove enclosing quotes and carriage return
44 // characters from string. Returns a Tree
45 //----------------------------------------------------------
46 char replaceCR(char c)
48 return (c!='\n') ? c : ' ';
51 Tree unquote(char* str)
53 //-----------copy unquoted filename-------------
58 //it is a quoted string, we remove the quotes
59 for (int i=1; j<511 && str[i];) {
60 buf[j++] = replaceCR(str[i++]);
63 if (j>0) buf[j-1] = 0;
65 for (int i=0; j<511 && str[i];) {
66 buf[j++] = replaceCR(str[i++]);
72 //----------------------------------------------
87 /* With local environment (lowest priority)*/
90 /* Block Diagram Algebra */
91 /*%left SEQ SPLIT MIX*/
99 %left LT LE EQ GT GE NE
102 %left MUL DIV MOD AND XOR LSH RSH
213 /* Begin and End tags for documentations, equations and diagrams */
224 %token <cppstr> DOCCHAR
230 %token LSTDEPENDENCIES
232 %token LSTDISTRIBUTED
240 %type <exp> statement
243 %type <exp> definition
247 %type <exp> expression
251 %type <exp> primitive
258 %type <exp> ffunction
260 %type <exp> fvariable
261 %type <exp> signature
283 %type <exp> vbargraph
284 %type <exp> hbargraph
291 %type <cppstr> doctxt
298 %type <exp> lstattrlist
299 %type <exp> lstattrdef
306 %% /* grammar rules and actions follow */
308 program : stmtlist { $$ = $1; gResult = formatDefinitions($$); }
311 stmtlist : /*empty*/ { $$ = nil; }
312 | stmtlist statement { $$ = cons ($2,$1); }
314 deflist : /*empty*/ { $$ = nil; }
315 | deflist definition { $$ = cons ($2,$1); }
318 statement : IMPORT LPAR uqstring RPAR ENDDEF { $$ = importFile($3); }
319 | DECLARE name string ENDDEF { declareMetadata($2,$3); $$ = nil; }
320 | definition { $$ = $1; }
321 | BDOC doc EDOC { declareDoc($2); $$ = nil; /* cerr << "Yacc : doc : " << *$2 << endl; */ }
324 doc : /* empty */ { $$ = nil; }
325 | doc docelem { $$ = cons ($2,$1); }
328 docelem : doctxt { $$ = docTxt($1->c_str()); delete $1; }
329 | doceqn { $$ = docEqn($1); }
330 | docdgm { $$ = docDgm($1); }
331 | docntc { $$ = docNtc(); }
332 | doclst { $$ = docLst(); }
333 | docmtd { $$ = docMtd($1); }
336 doctxt : /* empty */ { $$ = new string(); }
337 | doctxt DOCCHAR { $$ = &($1->append(yytext)); }
340 doceqn : BEQN expression EEQN { $$ = $2; }
343 docdgm : BDGM expression EDGM { $$ = $2; }
349 doclst : BLST lstattrlist ELST { }
352 lstattrlist : /* empty */ { }
353 | lstattrlist lstattrdef { }
356 lstattrdef : LSTDEPENDENCIES LSTEQ LSTQ lstattrval LSTQ { gLstDependenciesSwitch = $4; }
357 | LSTMDOCTAGS LSTEQ LSTQ lstattrval LSTQ { gStripDocSwitch = $4; gStripDocSwitch==true ? gStripDocSwitch=false : gStripDocSwitch=true; }
358 | LSTDISTRIBUTED LSTEQ LSTQ lstattrval LSTQ { gLstDistributedSwitch = $4; }
361 lstattrval : LSTTRUE { $$ = true; }
362 | LSTFALSE { $$ = false; }
365 docmtd : BMETADATA name EMETADATA { $$ = $2; }
368 definition : defname LPAR arglist RPAR DEF expression ENDDEF { $$ = cons($1,cons($3,$6)); }
369 | defname DEF expression ENDDEF { $$ = cons($1,cons(nil,$3)); }
370 | error ENDDEF { $$ = nil; yyerr++; }
373 defname : ident { $$=$1; setDefProp($1, yyfilename, yylineno); }
376 params : ident { $$ = cons($1,nil); }
377 | params PAR ident { $$ = cons($3,$1); }
380 expression : expression WITH LBRAQ deflist RBRAQ { $$ = boxWithLocalDef($1,formatDefinitions($4)); }
381 | expression PAR expression { $$ = boxPar($1,$3); }
382 | expression SEQ expression { $$ = boxSeq($1,$3); }
383 | expression SPLIT expression { $$ = boxSplit($1,$3); }
384 | expression MIX expression { $$ = boxMerge($1,$3); }
385 | expression REC expression { $$ = boxRec($1,$3); }
386 | infixexp { $$ = $1; }
389 infixexp : infixexp ADD infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigAdd)); }
390 | infixexp SUB infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigSub)); }
391 | infixexp MUL infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigMul)); }
392 | infixexp DIV infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigDiv)); }
393 | infixexp MOD infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigRem)); }
394 | infixexp POWOP infixexp { $$ = boxSeq(boxPar($1,$3),gPowPrim->box()); }
395 | infixexp FDELAY infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigFixDelay)); }
396 | infixexp DELAY1 { $$ = boxSeq($1,boxPrim1(sigDelay1)); }
397 | infixexp DOT ident { $$ = boxAccess($1,$3); }
399 | infixexp AND infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigAND)); }
400 | infixexp OR infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigOR)); }
401 | infixexp XOR infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigXOR)); }
403 | infixexp LSH infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigLeftShift)); }
404 | infixexp RSH infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigRightShift)); }
406 | infixexp LT infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigLT)); }
407 | infixexp LE infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigLE)); }
408 | infixexp GT infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigGT)); }
409 | infixexp GE infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigGE)); }
410 | infixexp EQ infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigEQ)); }
411 | infixexp NE infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigNE)); }
413 | infixexp HASH infixexp { $$ = boxSeq(boxPar($1,$3),boxPrim2(sigConcat)); }
415 | infixexp LPAR arglist RPAR %prec APPL { $$ = buildBoxAppl($1,$3); }
416 | infixexp LCROC deflist RCROC %prec APPL { $$ = boxModifLocalDef($1,formatDefinitions($3)); }
418 | primitive { $$ = $1; }
421 primitive : INT { $$ = boxInt(atoi(yytext)); }
422 | FLOAT { $$ = boxReal(atof(yytext)); }
424 | ADD INT { $$ = boxInt (atoi(yytext)); }
425 | ADD FLOAT { $$ = boxReal(atof(yytext)); }
427 | SUB INT { $$ = boxInt ( -atoi(yytext) ); }
428 | SUB FLOAT { $$ = boxReal( -atof(yytext) ); }
430 | WIRE { $$ = boxWire(); }
431 | CUT { $$ = boxCut(); }
433 | MEM { $$ = boxPrim1(sigDelay1); }
434 | PREFIX { $$ = boxPrim2(sigPrefix); }
436 | INTCAST { $$ = boxPrim1(sigIntCast); }
437 | FLOATCAST { $$ = boxPrim1(sigFloatCast); }
439 | ADD { $$ = boxPrim2(sigAdd); }
440 | SUB { $$ = boxPrim2(sigSub); }
441 | MUL { $$ = boxPrim2(sigMul); }
442 | DIV { $$ = boxPrim2(sigDiv); }
443 | MOD { $$ = boxPrim2(sigRem); }
444 | FDELAY { $$ = boxPrim2(sigFixDelay); }
446 | AND { $$ = boxPrim2(sigAND); }
447 | OR { $$ = boxPrim2(sigOR); }
448 | XOR { $$ = boxPrim2(sigXOR); }
450 | LSH { $$ = boxPrim2(sigLeftShift); }
451 | RSH { $$ = boxPrim2(sigRightShift); }
453 | LT { $$ = boxPrim2(sigLT); }
454 | LE { $$ = boxPrim2(sigLE); }
455 | GT { $$ = boxPrim2(sigGT); }
456 | GE { $$ = boxPrim2(sigGE); }
457 | EQ { $$ = boxPrim2(sigEQ); }
458 | NE { $$ = boxPrim2(sigNE); }
460 | ATTACH { $$ = boxPrim2(sigAttach); }
462 | ACOS { $$ = gAcosPrim->box(); }
463 | ASIN { $$ = gAsinPrim->box(); }
464 | ATAN { $$ = gAtanPrim->box(); }
465 | ATAN2 { $$ = gAtan2Prim->box(); }
466 | COS { $$ = gCosPrim->box(); }
467 | SIN { $$ = gSinPrim->box(); }
468 | TAN { $$ = gTanPrim->box(); }
470 | EXP { $$ = gExpPrim->box(); }
471 | LOG { $$ = gLogPrim->box(); }
472 | LOG10 { $$ = gLog10Prim->box(); }
473 | POWOP { $$ = gPowPrim->box(); }
474 | POWFUN { $$ = gPowPrim->box(); }
475 | SQRT { $$ = gSqrtPrim->box(); }
477 | ABS { $$ = gAbsPrim->box(); }
478 | MIN { $$ = gMinPrim->box(); }
479 | MAX { $$ = gMaxPrim->box(); }
481 | FMOD { $$ = gFmodPrim->box(); }
482 | REMAINDER { $$ = gRemainderPrim->box(); }
484 | FLOOR { $$ = gFloorPrim->box(); }
485 | CEIL { $$ = gCeilPrim->box(); }
486 | RINT { $$ = gRintPrim->box(); }
489 | RDTBL { $$ = boxPrim3(sigReadOnlyTable); }
490 | RWTBL { $$ = boxPrim5(sigWriteReadTable); }
492 | SELECT2 { $$ = boxPrim3(sigSelect2); }
493 | SELECT3 { $$ = boxPrim4(sigSelect3); }
495 | VECTORIZE { $$ = boxPrim2(sigVectorize); }
496 | SERIALIZE { $$ = boxPrim1(sigSerialize); }
497 | HASH { $$ = boxPrim2(sigConcat); }
499 | UPSAMPLE { $$ = boxPrim2(sigUpSample); }
500 | DOWNSAMPLE { $$ = boxPrim2(sigDownSample); }
502 | LCROC RCROC { $$ = boxPrim2(sigVectorAt); }
503 | LCROC infixexp RCROC { $$ = boxSeq(boxPar(boxWire(),$2),boxPrim2(sigVectorAt)); }
506 | SUB ident { $$ = boxSeq(boxPar(boxInt(0),$2),boxPrim2(sigSub)); }
508 | LPAR expression RPAR { $$ = $2; }
509 | LAMBDA LPAR params RPAR DOT LPAR expression RPAR
510 { $$ = buildBoxAbstr($3,$7); }
512 | CASE LBRAQ rulelist RBRAQ { $$ = boxCase(checkRulelist($3)); }
514 | ffunction { $$ = boxFFun($1); }
515 | fconst { $$ = $1; }
516 | fvariable { $$ = $1; }
517 | COMPONENT LPAR uqstring RPAR { $$ = boxComponent($3); }
518 | LIBRARY LPAR uqstring RPAR { $$ = boxLibrary($3); }
519 | ENVIRONMENT LBRAQ deflist RBRAQ { $$ = boxWithLocalDef(boxEnvironment(),formatDefinitions($3)); }
521 | button { $$ = $1; }
522 | checkbox { $$ = $1; }
523 | vslider { $$ = $1; }
524 | hslider { $$ = $1; }
525 | nentry { $$ = $1; }
526 | vgroup { $$ = $1; }
527 | hgroup { $$ = $1; }
528 | tgroup { $$ = $1; }
529 | vbargraph { $$ = $1; }
530 | hbargraph { $$ = $1; }
539 ident : IDENT { $$ = boxIdent(yytext); }
542 name : IDENT { $$ = tree(yytext); }
547 arglist : argument { $$ = cons($1,nil); }
548 | arglist PAR argument { $$ = cons($3,$1); }
551 argument : argument SEQ argument { $$ = boxSeq($1,$3); }
552 | argument SPLIT argument { $$ = boxSplit($1,$3); }
553 | argument MIX argument { $$ = boxMerge($1,$3); }
554 | argument REC argument { $$ = boxRec($1,$3); }
555 | infixexp { $$ = $1; }
558 string : STRING { $$ = tree(yytext); }
561 uqstring : STRING { $$ = unquote(yytext); }
564 fstring : STRING { $$ = tree(yytext); }
565 | FSTRING { $$ = tree(yytext); }
568 /* description of iterative expressions */
570 fpar : IPAR LPAR ident PAR argument PAR expression RPAR
571 { $$ = boxIPar($3,$5,$7); }
574 fseq : ISEQ LPAR ident PAR argument PAR expression RPAR
575 { $$ = boxISeq($3,$5,$7); }
578 fsum : ISUM LPAR ident PAR argument PAR expression RPAR
579 { $$ = boxISum($3,$5,$7); }
582 fprod : IPROD LPAR ident PAR argument PAR expression RPAR
583 { $$ = boxIProd($3,$5,$7); }
587 /* description of foreign functions */
589 ffunction : FFUNCTION LPAR signature PAR fstring PAR string RPAR
590 { $$ = ffunction($3,$5,$7); }
593 fconst : FCONSTANT LPAR type name PAR fstring RPAR
594 { $$ = boxFConst($3,$4,$6); }
596 fvariable : FVARIABLE LPAR type name PAR fstring RPAR
597 { $$ = boxFVar($3,$4,$6); }
600 /* Description of user interface building blocks */
601 button : BUTTON LPAR uqstring RPAR { $$ = boxButton($3); }
604 checkbox : CHECKBOX LPAR uqstring RPAR { $$ = boxCheckbox($3); }
607 vslider : VSLIDER LPAR uqstring PAR argument PAR argument PAR argument PAR argument RPAR
608 { $$ = boxVSlider($3,$5,$7,$9,$11); }
610 hslider : HSLIDER LPAR uqstring PAR argument PAR argument PAR argument PAR argument RPAR
611 { $$ = boxHSlider($3,$5,$7,$9,$11); }
613 nentry : NENTRY LPAR uqstring PAR argument PAR argument PAR argument PAR argument RPAR
614 { $$ = boxNumEntry($3,$5,$7,$9,$11); }
616 vgroup : VGROUP LPAR uqstring PAR expression RPAR
617 { $$ = boxVGroup($3, $5); }
619 hgroup : HGROUP LPAR uqstring PAR expression RPAR
620 { $$ = boxHGroup($3, $5); }
622 tgroup : TGROUP LPAR uqstring PAR expression RPAR
623 { $$ = boxTGroup($3, $5); }
626 vbargraph : VBARGRAPH LPAR uqstring PAR argument PAR argument RPAR
627 { $$ = boxVBargraph($3,$5,$7); }
629 hbargraph : HBARGRAPH LPAR uqstring PAR argument PAR argument RPAR
630 { $$ = boxHBargraph($3,$5,$7); }
633 /* Description of foreign functions */
635 signature : type fun LPAR typelist RPAR { $$ = cons($1, cons($2, $4)); }
636 | type fun LPAR RPAR { $$ = cons($1, cons($2, nil)); }
639 fun : IDENT { $$ = tree(yytext); }
642 typelist : type { $$ = cons($1,nil); }
643 | typelist PAR type { $$ = cons($3,$1); }
646 rulelist : rule { $$ = cons($1,nil); }
647 | rulelist rule { $$ = cons($2,$1); }
650 rule : LPAR arglist RPAR ARROW expression ENDDEF
651 { $$ = cons($2,$5); }
654 type : INTCAST { $$ = tree(0); }
655 | FLOATCAST { $$ = tree(1); }