1 %{ // -*-Fundamental-*-
7 #include "paper-def.hh"
9 #include "input-score.hh"
13 #include "parseconstruct.hh"
15 #include "identifier.hh"
16 #include "commandrequest.hh"
17 #include "musicalrequest.hh"
18 #include "voice-element.hh"
24 Array<Request*> pre_reqs, post_reqs;
25 Array<const char *> define_spots;
26 Paper_def*default_paper();
27 char const* defined_ch_c_l;
28 char const* req_defined_ch_c_l;
29 int fatal_error_i = 0;
45 Music_general_chord *chord;
52 Array<String> * strvec;
54 Array<Melodic_req*> *melreqvec;
57 Symtables * symtables;
63 Notename_tab *notename_tab;
68 %token VOICE STAFF SCORE TITLE BAR OUTPUT MULTIVOICE DYNAMIC
69 %token CM_T IN_T PT_T MM_T PAPER WIDTH METER UNITSPACE SKIP COMMANDS COMMAND
70 %token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
71 %token KEY CLEF TABLE VOICES STEM
72 %token PARTIAL MUSIC GROUPING CADENZA
73 %token END SYMBOLTABLES TEXID TABLE NOTENAMES SCRIPT TEXTSTYLE PLET
77 %token <id> IDENTIFIER REAL_IDENTIFIER REQUEST_IDENTIFIER
78 %token <string> PITCHMOD DURATION RESTNAME
81 %token <string> STRING
85 %type <melreqvec> pitch_list
86 %type <c> open_request_parens close_request_parens close_plet_parens
87 %type <id> declaration
88 %type <string> declarable_identifier
89 %type <paper> paper_block paper_body
90 %type <midi> midi_block midi_body
92 %type <ii> default_duration explicit_duration notemode_duration mudela_duration
94 %type <moment> duration_length
95 %type <el> voice_elt full_element lyrics_elt command_elt
97 %type <score> score_block score_body
98 %type <staff> staff_block staff_init staff_body
100 %type <intvec> intastint_list
101 %type <request> post_request pre_request command_req
102 %type <string> pitchmod
104 %type <chord> music_chord music_chord_body
106 %type <mvoice> music_voice_body music_voice
108 %type <interval> dinterval
110 %type <symtable> symtable symtable_body
111 %type <lookup> symtables symtables_body
112 %type <symbol> symboldef
113 %type <notename_tab> notename_tab notename_tab_body
115 %type <script> script_definition script_body mudela_script
116 %type <request> script_req textscript_req dynamic_req basic_request
117 %type <textdef> mudela_text
123 | mudela score_block {
126 | mudela add_declaration { }
127 | mudela mudela_command {}
131 notename_tab { lexer->set($1); }
137 add_declaration: declaration {
138 lexer->add_identifier($1);
142 declarable_identifier:
144 | IDENTIFIER { $$ = new String($1->name); }
148 declarable_identifier '=' staff_block {
149 $$ = new Staff_id(*$1, $3, IDENTIFIER);
152 | declarable_identifier '=' music_voice {
153 $$ = new M_voice_id(*$1, $3, IDENTIFIER);
156 | declarable_identifier '=' script_definition {
157 $$ = new Script_id(*$1, $3, IDENTIFIER);
160 | declarable_identifier '=' music_chord {
161 $$ = new M_chord_id(*$1, $3, IDENTIFIER);
164 | declarable_identifier '=' symtables {
165 $$ = new Lookup_id(*$1, $3, IDENTIFIER);
168 | declarable_identifier '=' notename_tab {
169 $$ = new Notetab_id(*$1, $3, IDENTIFIER);
172 | declarable_identifier '=' real {
173 $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
176 | declarable_identifier error '}' {
179 | declarable_identifier '=' basic_request {
180 $$ = new Request_id(*$1, $3, REQUEST_IDENTIFIER);
186 NOTENAMES '{' notename_tab_body '}' { $$ = $3; }
190 $$ = new Notename_tab;
193 $$ = $1->notename_tab(true);
195 | notename_tab_body STRING int int {
196 $$->set($3, $4, *$2);
205 SCORE { define_spots.push(lexer->here_ch_c_l()); }
206 /*cont*/ '{' score_body '}' {
208 $$->defined_ch_c_l_ = define_spots.pop();
209 if (!$$->paper_p_ && ! $$->midi_p_)
210 $$->paper_p_ = default_paper();
212 /* handle error levels. */
213 $$->errorlevel_i_ = lexer->errorlevel_i_;
214 lexer->errorlevel_i_ = 0;
219 $$ = new Input_score;
221 | score_body staff_block { $$->add($2); }
222 | score_body COMMANDS '{' music_voice_body '}' {
225 | score_body paper_block { $$->set($2); }
226 | score_body midi_block { $$->set($2); }
233 /* */ { $$ =new Array<int>; }
234 | intastint_list int '*' int {
235 $$->push($2); $$->push($4);
246 '{' paper_body '}' { $$ = $3; }
251 $$ = default_paper();
253 | paper_body WIDTH dim { $$->linewidth = $3;}
254 | paper_body OUTPUT STRING { $$->outfile = *$3;
257 | paper_body symtables { $$->set($2); }
258 | paper_body UNITSPACE dim { $$->whole_width = $3; }
259 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
271 '{' midi_body '}' { $$ = $3; }
277 | midi_body OUTPUT STRING {
278 $$->outfile_str_ = *$3;
281 | midi_body TEMPO mudela_duration ':' int {
282 $$->set_tempo( wholes( $3[0], $3[1] ), $5 );
293 STAFF { define_spots.push(lexer->here_ch_c_l()); }
294 /*cont*/ '{' staff_body '}' {
296 $$-> defined_ch_c_l_ = define_spots.pop();
303 IDENTIFIER { $$ = $1->staff(true); }
305 $$ = new Input_staff(*$1);
312 | staff_body COMMANDS '{' music_voice_body '}' {
313 $$->set_score_wide($4);
316 $2->set_default_group( "staff_music" + String($$->music_.size()));
327 music_voice { $$ = $1; }
328 | music_chord { $$ = $1; }
331 music_voice: MUSIC '{' music_voice_body '}' { $$ = $3; }
336 $$ = $1->mvoice(true);
339 $$ = new Music_voice;
341 | music_voice_body '+' IDENTIFIER {
342 $$->concatenate($3->mvoice(true));
344 | music_voice_body full_element {
347 | music_voice_body voice_command {
349 | music_voice_body music {
352 | music_voice_body error {
356 music_chord: '{' music_chord_body '}' { $$ = $2; }
364 $$ = new Voice_group_chord;
367 $$ = new Multi_voice_chord;
369 | music_chord_body '+' IDENTIFIER {
370 $$->concatenate($3->mchord(true));
372 | music_chord_body music {
375 | music_chord_body full_element {
378 | music_chord_body error {
391 full_element: pre_requests voice_elt post_requests {
392 add_requests($2, pre_reqs);
393 add_requests($2, post_reqs);
396 | pre_requests lyrics_elt post_requests {
397 add_requests($2, pre_reqs);
398 add_requests($2, post_reqs);
406 $$ = new Voice_element;
407 $$-> defined_ch_c_l_ = lexer->here_ch_c_l();
411 $2-> defined_ch_c_l_ = $$->defined_ch_c_l_;
419 $$ = new Barcheck_req;
422 $$ = new Bar_req(*$2);
425 | METER '{' int '*' int '}' {
426 Meter_change_req *m = new Meter_change_req;
430 | SKIP '{' duration_length '}' {
431 Skip_req * skip_p = new Skip_req;
432 skip_p->duration_ = *$3;
436 | CADENZA '{' int '}' {
437 $$ = new Cadenza_req($3);
439 | PARTIAL '{' duration_length '}' {
440 $$ = new Partial_measure_req(*$3);
444 $$ = get_stemdir_req($3);
447 $$ = new Clef_change_req(*$2);
450 | KEY '{' pitch_list '}' {
451 Key_change_req *key_p= new Key_change_req;
452 key_p->melodic_p_arr_ = *$3;
456 | GROUPING '{' intastint_list '}' {
457 $$ = get_grouping_req(*$3); delete $3;
463 assert(post_reqs.empty());
465 | post_requests post_request {
466 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
469 | post_requests close_plet_parens INT '/' INT {
470 post_reqs.push( get_request($2) );
471 req_defined_ch_c_l = lexer->here_ch_c_l();
472 post_reqs.push( get_plet_request( $2, $3, $5 ) );
477 close_request_parens {
478 $$ = get_request($1);
483 | REQUEST_IDENTIFIER {
484 $$ = $1->request(false)->clone();
489 DYNAMIC '{' int '}' {
490 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
491 ad_p ->loudness_ = $3;
498 req_defined_ch_c_l = lexer->here_ch_c_l();
503 close_request_parens:
522 SCRIPT '{' script_body '}' { $$ = $3; }
527 $$ = new Script_def(*$1,$2, $3,$4);
533 script_dir mudela_text { $$ = get_text_req($1,$2); }
538 defined_ch_c_l = lexer->here_ch_c_l();
545 script_dir mudela_script {
546 $$ = get_script_req($1, $2);
551 IDENTIFIER { $$ = $1->script(true); }
552 | script_definition { $$ = $1; }
553 | '^' { $$ = get_scriptdef('^'); }
554 | '+' { $$ = get_scriptdef('+'); }
555 | '-' { $$ = get_scriptdef('-'); }
556 | '|' { $$ = get_scriptdef('|'); }
557 | 'o' { $$ = get_scriptdef('o'); }
558 | '>' { $$ = get_scriptdef('>'); }
559 | '.' { $$ = get_scriptdef('.'); }
562 warning( "too many staccato dots", lexer->here_ch_c_l() );
563 $$ = get_scriptdef('.');
566 $$ = get_scriptdef('.');
578 | pre_requests pre_request {
580 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
585 open_request_parens {
586 defined_ch_c_l = lexer->here_ch_c_l();
587 $$ = get_request($1);
592 PLET '{' INT '/' INT '}' {
595 | DURATIONCOMMAND '{' STRING '}' {
596 set_duration_mode(*$3);
599 | DURATIONCOMMAND '{' notemode_duration '}' {
600 set_default_duration($3);
602 | OCTAVECOMMAND '{' pitchmod '}' {
603 set_default_octave(*$3);
614 $$ = new Moment(wholes($1[0], $1[1]));
616 |int '*' mudela_duration {
617 $$ = new Moment(Rational($1) * wholes($3[0], $3[1]));
650 get_default_duration($$);
653 | INT '*' INT '/' INT {
654 // ugh, must use Duration
664 get_default_duration($$);
669 defined_ch_c_l = lexer->here_ch_c_l();
673 defined_ch_c_l = lexer->here_ch_c_l();
683 pitchmod notename notemode_duration {
684 $$ = get_note_element(*$1, $2, $3);
687 | RESTNAME notemode_duration {
688 $$ = get_rest_element(*$1, $2);
695 mudela_text notemode_duration {
696 $$ = get_word_element($1, $2);
703 $$ = new Array<Melodic_req*>;
705 | pitch_list NOTENAME {
706 Melodic_req *m_p = new Melodic_req;
707 m_p->notename_i_ = $2[0];
708 m_p->accidental_i_ = $2[1];
716 if ( distance($1,Real(int($$)) ) > 1e-8)
717 error( "integer expected", lexer->here_ch_c_l() );
736 real unit { $$ = $1*$2; }
740 unit: CM_T { $$ = 1 CM; }
741 |IN_T { $$ = 1 INCH; }
750 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
758 $$ = new Lookup(*$1->lookup(true));
760 | symtables_body TEXID STRING {
761 $$->texsetting = *$3;
764 | symtables_body STRING '=' symtable {
771 TABLE '{' symtable_body '}' { $$ = $3; }
775 { $$ = new Symtable; }
776 | symtable_body STRING symboldef {
785 $$ = new Symbol(*$1, *$2);
791 $$ = new Symbol(*$1, b);
797 dinterval dinterval {
798 $$ = new Box(*$1, *$2);
805 $$ = new Interval($1, $2);
812 yyerror(const char *s)
814 lexer->LexerError(s);
817 exit( fatal_error_i );
821 parse_file(String init, String s)
823 *mlog << "Parsing ... ";
824 lexer = new My_flex_lexer;
827 yydebug = !monitor->silence("InitParser") && check_debug;
828 lexer->set_debug( !monitor->silence("InitLexer") && check_debug);
831 lexer->new_input(init);
835 yydebug = !monitor->silence("Parser") && check_debug;
836 lexer->set_debug( !monitor->silence("Lexer") && check_debug);
844 if(!define_spots.empty())
845 warning("Braces don't match.",0);
851 return new Paper_def(
852 lexer->lookup_identifier("default_table")->lookup(true));