1 %{ // -*-Fundamental-*-
9 #include "inputscore.hh"
13 #include "parseconstruct.hh"
15 #include "identifier.hh"
16 #include "commandrequest.hh"
17 #include "musicalrequest.hh"
23 Array<Request*> pre_reqs, post_reqs;
24 Array<const char *> define_spots;
25 Paperdef*default_paper();
26 char const* defined_ch_c_l;
27 char const* req_defined_ch_c_l;
28 int fatal_error_i = 0;
44 Music_general_chord *chord;
51 Array<String> * strvec;
53 Array<Melodic_req*> *melreqvec;
56 Symtables * symtables;
62 Notename_tab *notename_tab;
67 %token VOICE STAFF SCORE TITLE BAR OUTPUT MULTIVOICE
68 %token CM_T IN_T PT_T MM_T PAPER WIDTH METER UNITSPACE SKIP COMMANDS COMMAND
69 %token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
70 %token KEY CLEF TABLE VOICES STEM
71 %token PARTIAL MUSIC GROUPING CADENZA
72 %token END SYMBOLTABLES TEXID TABLE NOTENAMES SCRIPT TEXTSTYLE PLET
76 %token <id> IDENTIFIER
77 %token <string> PITCHMOD DURATION RESTNAME
80 %token <string> STRING
84 %type <melreqvec> pitch_list
85 %type <c> open_request_parens close_request_parens close_plet_parens
86 %type <id> declaration
87 %type <string> declarable_identifier
88 %type <paper> paper_block paper_body
89 %type <midi> midi_block midi_body
91 %type <ii> default_duration explicit_duration notemode_duration mudela_duration
93 %type <moment> duration_length
94 %type <el> voice_elt full_element lyrics_elt command_elt
96 %type <score> score_block score_body
97 %type <staff> staff_block staff_init staff_body
99 %type <intvec> intastint_list
100 %type <request> post_request pre_request command_req
101 %type <string> pitchmod
103 %type <chord> music_chord music_chord_body
105 %type <mvoice> music_voice_body music_voice
107 %type <interval> dinterval
109 %type <symtable> symtable symtable_body
110 %type <lookup> symtables symtables_body
111 %type <symbol> symboldef
112 %type <notename_tab> notename_tab notename_tab_body
114 %type <script> script_definition script_body mudela_script
115 %type <request> script_req textscript_req
116 %type <textdef> mudela_text
122 | mudela score_block {
125 | mudela add_declaration { }
126 | mudela mudela_command {}
130 notename_tab { lexer->set($1); }
136 add_declaration: declaration {
137 lexer->add_identifier($1);
141 declarable_identifier:
143 | IDENTIFIER { $$ = new String($1->name); }
147 declarable_identifier '=' staff_block {
148 $$ = new Staff_id(*$1, $3);
151 | declarable_identifier '=' music_voice {
152 $$ = new M_voice_id(*$1, $3);
155 | declarable_identifier '=' script_definition {
156 $$ = new Script_id(*$1, $3);
159 | declarable_identifier '=' music_chord {
160 $$ = new M_chord_id(*$1, $3);
163 | declarable_identifier '=' symtables {
164 $$ = new Lookup_id(*$1, $3);
167 | declarable_identifier '=' notename_tab {
168 $$ = new Notetab_id(*$1, $3);
171 | declarable_identifier '=' real {
172 $$ = new Real_id(*$1, new Real($3));
175 | declarable_identifier error '}' {
181 NOTENAMES '{' notename_tab_body '}' { $$ = $3; }
185 $$ = new Notename_tab;
188 $$ = $1->notename_tab(true);
190 | notename_tab_body STRING int int {
191 $$->set($3, $4, *$2);
200 SCORE { define_spots.push(lexer->here_ch_c_l()); }
201 /*cont*/ '{' score_body '}' {
203 $$->defined_ch_c_l_ = define_spots.pop();
204 if (!$$->paper_p_ && ! $$->midi_p_)
205 $$->paper_p_ = default_paper();
207 /* handle error levels. */
208 $$->errorlevel_i_ = lexer->errorlevel_i_;
209 lexer->errorlevel_i_ = 0;
214 $$ = new Input_score;
216 | score_body staff_block { $$->add($2); }
217 | score_body COMMANDS '{' music_voice_body '}' {
220 | score_body paper_block { $$->set($2); }
221 | score_body midi_block { $$->set($2); }
228 /* */ { $$ =new Array<int>; }
229 | intastint_list int '*' int {
230 $$->push($2); $$->push($4);
241 '{' paper_body '}' { $$ = $3; }
246 $$ = default_paper();
248 | paper_body WIDTH dim { $$->linewidth = $3;}
249 | paper_body OUTPUT STRING { $$->outfile = *$3;
252 | paper_body symtables { $$->set($2); }
253 | paper_body UNITSPACE dim { $$->whole_width = $3; }
254 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
266 '{' midi_body '}' { $$ = $3; }
272 | midi_body OUTPUT STRING {
273 $$->outfile_str_ = *$3;
276 | midi_body TEMPO mudela_duration ':' int {
277 $$->set_tempo( wholes( $3[0], $3[1] ), $5 );
288 STAFF { define_spots.push(lexer->here_ch_c_l()); }
289 /*cont*/ '{' staff_body '}' {
291 $$-> defined_ch_c_l_ = define_spots.pop();
298 IDENTIFIER { $$ = $1->staff(true); }
300 $$ = new Input_staff(*$1);
307 | staff_body COMMANDS '{' music_voice_body '}' {
308 $$->set_score_wide($4);
311 $2->set_default_group( "staff_music" + String($$->music_.size()));
322 music_voice { $$ = $1; }
323 | music_chord { $$ = $1; }
326 music_voice: MUSIC '{' music_voice_body '}' { $$ = $3; }
331 $$ = new Music_voice;
333 | music_voice_body IDENTIFIER {
334 $$->concatenate($2->mvoice(true));
336 | music_voice_body full_element {
339 | music_voice_body voice_command {
341 | music_voice_body music {
344 | music_voice_body error {
348 music_chord: '{' music_chord_body '}' { $$ = $2; }
353 $$ = new Voice_group_chord;
356 $$ = new Multi_voice_chord;
358 | music_chord_body IDENTIFIER {
359 $$->concatenate($2->mchord(true));
361 | music_chord_body music {
364 | music_chord_body full_element {
367 | music_chord_body error {
375 full_element: pre_requests voice_elt post_requests {
376 add_requests($2, pre_reqs);
377 add_requests($2, post_reqs);
380 | pre_requests lyrics_elt post_requests {
381 add_requests($2, pre_reqs);
382 add_requests($2, post_reqs);
390 $$ = new Voice_element;
391 $$-> defined_ch_c_l_ = lexer->here_ch_c_l();
395 $2-> defined_ch_c_l_ = $$->defined_ch_c_l_;
403 $$ = new Barcheck_req;
406 $$ = new Bar_req(*$2);
409 | METER '{' int '*' int '}' {
410 Meter_change_req *m = new Meter_change_req;
414 | SKIP '{' duration_length '}' {
415 Skip_req * skip_p = new Skip_req;
416 skip_p->duration_ = *$3;
420 | CADENZA '{' int '}' {
421 $$ = new Cadenza_req($3);
423 | PARTIAL '{' duration_length '}' {
424 $$ = new Partial_measure_req(*$3);
428 $$ = get_stemdir_req($3);
431 $$ = new Clef_change_req(*$2);
434 | KEY '{' pitch_list '}' {
435 Key_change_req *key_p= new Key_change_req;
436 key_p->melodic_p_arr_ = *$3;
440 | GROUPING '{' intastint_list '}' {
441 $$ = get_grouping_req(*$3); delete $3;
447 assert(post_reqs.empty());
449 | post_requests post_request {
450 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
453 | post_requests close_plet_parens INT '/' INT {
454 post_reqs.push( get_request($2) );
455 req_defined_ch_c_l = lexer->here_ch_c_l();
456 post_reqs.push( get_plet_request( $2, $3, $5 ) );
461 close_request_parens {
462 $$ = get_request($1);
470 req_defined_ch_c_l = lexer->here_ch_c_l();
475 close_request_parens:
494 SCRIPT '{' script_body '}' { $$ = $3; }
499 $$ = new Script_def(*$1,$2, $3,$4);
505 script_dir mudela_text { $$ = get_text_req($1,$2); }
510 defined_ch_c_l = lexer->here_ch_c_l();
517 script_dir mudela_script {
518 $$ = get_script_req($1, $2);
523 IDENTIFIER { $$ = $1->script(true); }
524 | script_definition { $$ = $1; }
525 | '^' { $$ = get_scriptdef('^'); }
526 | '+' { $$ = get_scriptdef('+'); }
527 | '-' { $$ = get_scriptdef('-'); }
528 | '|' { $$ = get_scriptdef('|'); }
529 | 'o' { $$ = get_scriptdef('o'); }
530 | '>' { $$ = get_scriptdef('>'); }
531 | '.' { $$ = get_scriptdef('.'); }
534 warning( "too many staccato dots", lexer->here_ch_c_l() );
535 $$ = get_scriptdef('.');
538 $$ = get_scriptdef('.');
550 | pre_requests pre_request {
552 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
557 open_request_parens {
558 defined_ch_c_l = lexer->here_ch_c_l();
559 $$ = get_request($1);
564 PLET '{' INT '/' INT '}' {
567 | DURATIONCOMMAND '{' STRING '}' {
568 set_duration_mode(*$3);
571 | DURATIONCOMMAND '{' notemode_duration '}' {
572 set_default_duration($3);
574 | OCTAVECOMMAND '{' pitchmod '}' {
575 set_default_octave(*$3);
586 $$ = new Moment(wholes($1[0], $1[1]));
588 |int '*' mudela_duration {
589 $$ = new Moment(Rational($1) * wholes($3[0], $3[1]));
622 get_default_duration($$);
625 | INT '*' INT '/' INT {
626 // ugh, must use Duration
636 get_default_duration($$);
641 defined_ch_c_l = lexer->here_ch_c_l();
645 defined_ch_c_l = lexer->here_ch_c_l();
655 pitchmod notename notemode_duration {
656 $$ = get_note_element(*$1, $2, $3);
659 | RESTNAME notemode_duration {
660 $$ = get_rest_element(*$1, $2);
667 mudela_text notemode_duration {
668 $$ = get_word_element($1, $2);
675 $$ = new Array<Melodic_req*>;
677 | pitch_list NOTENAME {
678 Melodic_req *m_p = new Melodic_req;
679 m_p->notename_i_ = $2[0];
680 m_p->accidental_i_ = $2[1];
688 if ( distance($1,Real(int($$)) ) > 1e-8)
689 error( "integer expected", lexer->here_ch_c_l() );
708 real unit { $$ = $1*$2; }
712 unit: CM_T { $$ = 1 CM; }
713 |IN_T { $$ = 1 INCH; }
722 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
730 $$ = new Lookup(*$1->lookup(true));
732 | symtables_body TEXID STRING {
733 $$->texsetting = *$3;
736 | symtables_body STRING '=' symtable {
743 TABLE '{' symtable_body '}' { $$ = $3; }
747 { $$ = new Symtable; }
748 | symtable_body STRING symboldef {
757 $$ = new Symbol(*$1, *$2);
763 $$ = new Symbol(*$1, b);
769 dinterval dinterval {
770 $$ = new Box(*$1, *$2);
777 $$ = new Interval($1, $2);
784 yyerror(const char *s)
786 lexer->LexerError(s);
789 exit( fatal_error_i );
793 parse_file(String init, String s)
795 *mlog << "Parsing ... ";
796 lexer = new My_flex_lexer;
799 yydebug = !monitor->silence("InitParser") && check_debug;
800 lexer->set_debug( !monitor->silence("InitLexer") && check_debug);
803 lexer->new_input(init);
807 yydebug = !monitor->silence("Parser") && check_debug;
808 lexer->set_debug( !monitor->silence("Lexer") && check_debug);
816 if(!define_spots.empty())
817 warning("Braces don't match.",0);
824 lexer->lookup_identifier("default_table")->lookup(true));