1 %{ // -*-Fundamental-*-
3 #include "script-def.hh"
8 #include "paper-def.hh"
11 #include "input-score.hh"
12 #include "input-staff.hh"
13 #include "input-music.hh"
16 #include "parseconstruct.hh"
18 #include "identifier.hh"
19 #include "command-request.hh"
20 #include "musical-request.hh"
21 #include "voice-element.hh"
27 Array<Request*> pre_reqs, post_reqs;
28 Array<const char *> define_spots;
29 Paper_def*default_paper();
30 char const* defined_ch_c_l;
31 char const* req_defined_ch_c_l;
32 int fatal_error_i = 0;
38 Array<Melodic_req*> *melreqvec;
39 Array<String> * strvec;
51 Music_general_chord *chord;
61 Symtables * symtables;
78 %token DURATIONCOMMAND
119 %token <id> IDENTIFIER
120 %token <id> MELODIC_REQUEST_IDENTIFIER
121 %token <id> CHORD_IDENTIFIER
122 %token <id> VOICE_IDENTIFIER
123 %token <id> POST_REQUEST_IDENTIFIER
124 %token <id> SCRIPT_IDENTIFIER
125 %token <id> STAFF_IDENTIFIER
126 %token <id> REAL_IDENTIFIER
127 %token <id> SCORE_IDENTIFIER
128 %token <id> REQUEST_IDENTIFIER
130 %token <string> DURATION RESTNAME
131 %token <string> STRING
134 %type <c> open_request_parens close_request_parens close_plet_parens
135 %type <chord> music_chord music_chord_body init_music_chord
136 %type <el> voice_elt full_element lyrics_elt command_elt
138 %type <i> octave_quotes octave_quote
140 %type <id> declaration
141 %type <ii> default_duration explicit_duration notemode_duration
142 %type <ii> mudela_duration
143 %type <interval> dinterval
144 %type <intvec> intastint_list
145 %type <lookup> symtables symtables_body
146 %type <melreq> melodic_request
147 %type <notereq> steno_note_req
148 %type <melreqvec> pitch_list
149 %type <midi> midi_block midi_body
150 %type <moment> duration_length
151 %type <music> music init_music
152 %type <mvoice> music_voice_body music_voice init_music_voice init_lyrics_voice
154 %type <paper> paper_block paper_body
155 %type <real> dim real
157 %type <request> post_request pre_request command_req pure_post_request
158 %type <request> script_req textscript_req dynamic_req
159 %type <score> score_block score_body
160 %type <script> script_definition script_body mudela_script
161 %type <staff> staff_block staff_init staff_body
162 %type <string> declarable_identifier
163 %type <symbol> symboldef
164 %type <symtable> symtable symtable_body
165 %type <textdef> mudela_text
170 %expect 2 /* have to fix this. */
175 | mudela score_block {
178 | mudela add_declaration { }
185 add_declaration: declaration {
186 lexer->add_identifier($1);
190 declarable_identifier:
192 if (lexer->lookup_identifier(*$1))
193 warning("redeclaration of `" + *$1 + "'",
194 lexer->here_ch_c_l());
196 | IDENTIFIER { $$ = new String($1->name); }
200 declarable_identifier '=' score_block {
201 $$ = new Score_id(*$1, $3, SCORE_IDENTIFIER);
204 | declarable_identifier '=' staff_block {
205 $$ = new Staff_id(*$1, $3, STAFF_IDENTIFIER);
208 | declarable_identifier '=' init_music_voice {
209 $$ = new M_voice_id(*$1, $3, VOICE_IDENTIFIER);
212 | declarable_identifier '=' init_lyrics_voice {
213 $$ = new M_voice_id(*$1, $3, VOICE_IDENTIFIER);
216 | declarable_identifier '=' script_definition {
217 $$ = new Script_id(*$1, $3, SCRIPT_IDENTIFIER);
220 | declarable_identifier '=' init_music_chord {
221 $$ = new M_chord_id(*$1, $3, CHORD_IDENTIFIER);
224 | declarable_identifier '=' symtables {
225 $$ = new Lookup_id(*$1, $3, IDENTIFIER);
228 | declarable_identifier '=' real {
229 $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
232 | declarable_identifier error '}' {
235 | declarable_identifier '=' pure_post_request {
236 $$ = new Request_id(*$1, $3, POST_REQUEST_IDENTIFIER);
239 | declarable_identifier '=' melodic_request {
240 $$ = new Request_id(*$1, $3, MELODIC_REQUEST_IDENTIFIER);
250 SCORE { define_spots.push(lexer->here_ch_c_l()); }
251 /*cont*/ '{' score_body '}' {
253 $$->defined_ch_c_l_ = define_spots.pop();
254 if (!$$->paper_p_ && ! $$->midi_p_)
255 $$->paper_p_ = default_paper();
257 /* handle error levels. */
258 $$->errorlevel_i_ = lexer->errorlevel_i_;
259 lexer->errorlevel_i_ = 0;
265 $$ = new Input_score;
268 $$ = $1->score(true);
270 | score_body staff_block { $$->add($2); }
271 | score_body paper_block { $$->set($2); }
272 | score_body midi_block { $$->set($2); }
279 /* */ { $$ =new Array<int>; }
280 | intastint_list int '*' int {
281 $$->push($2); $$->push($4);
291 '{' paper_body '}' { $$ = $3; }
296 $$ = default_paper();
298 | paper_body WIDTH dim { $$->linewidth = $3;}
299 | paper_body OUTPUT STRING { $$->outfile = *$3;
302 | paper_body symtables { $$->set($2); }
303 | paper_body UNITSPACE dim { $$->whole_width = $3; }
304 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
316 '{' midi_body '}' { $$ = $3; }
322 | midi_body OUTPUT STRING {
323 $$->outfile_str_ = *$3;
326 | midi_body TEMPO mudela_duration ':' int {
327 $$->set_tempo( wholes( $3[0], $3[1] ), $5 );
338 STAFF { define_spots.push(lexer->here_ch_c_l()); }
339 /*cont*/ '{' staff_body '}' {
341 $$-> defined_ch_c_l_ = define_spots.pop();
348 STAFF_IDENTIFIER { $$ = $1->staff(true); }
350 $$ = new Input_staff(*$1);
354 $$ = new Input_staff("melodic");
360 | staff_body init_music {
361 $2->set_default_group( "staff_music" + String($$->music_.size()));
369 let the lexer switch mode.
372 init_music_voice { $$ = $1; }
373 | init_music_chord { $$ = $1; }
374 | init_lyrics_voice { $$ = $1; }
378 LYRICS { lexer->push_lyric_state(); }
379 music_voice { $$ = $3; lexer->pop_state(); }
383 MUSIC { lexer->push_note_state(); }
384 /* cont*/ music_voice
385 { $$=$3; lexer->pop_state(); }
388 MUSIC { lexer->push_note_state(); }
389 /* cont*/ music_chord
390 { $$=$3; lexer->pop_state(); }
396 music_voice { $$ = $1; }
397 | music_chord { $$ = $1; }
400 music_voice: '{' music_voice_body '}' { $$ = $2; }
405 $$ = $1->mvoice(true);
408 $$ = new Music_voice;
410 | music_voice_body full_element {
413 | music_voice_body voice_command {
415 | music_voice_body music {
418 | music_voice_body error {
420 | music_voice_body '>' {
421 error("Confused by earlier errors: bailing out");
424 music_chord: '<' music_chord_body '>' { $$ = $2; }
432 $$ = new Voice_group_chord;
435 $$ = new Multi_voice_chord;
437 | music_chord_body music {
440 | music_chord_body full_element {
443 | music_chord_body '}' {
444 error("Confused by earlier errors: bailing out");
446 | music_chord_body error {
453 full_element: pre_requests voice_elt post_requests {
454 add_requests($2, pre_reqs);
455 add_requests($2, post_reqs);
458 | pre_requests lyrics_elt post_requests {
459 add_requests($2, pre_reqs);
460 add_requests($2, post_reqs);
468 $$ = new Voice_element;
469 $$-> defined_ch_c_l_ = lexer->here_ch_c_l();
473 $2-> defined_ch_c_l_ = $$->defined_ch_c_l_;
481 $$ = new Barcheck_req;
484 $$ = new Bar_req(*$2);
487 | METER '{' int '/' int '}' {
488 Meter_change_req *m = new Meter_change_req;
490 // sorry hw, i need meter at output of track,
491 // but don-t know where to get it... statics should go.
492 // HW : default: 4/4, meterchange reqs may change it.
494 Midi_def::num_i_s = $3;
495 Midi_def::den_i_s = $5;
498 | SKIP '{' duration_length '}' {
499 Skip_req * skip_p = new Skip_req;
500 skip_p->duration_ = *$3;
504 | CADENZA '{' int '}' {
505 $$ = new Cadenza_req($3);
507 | PARTIAL '{' duration_length '}' {
508 $$ = new Partial_measure_req(*$3);
512 $$ = get_stemdir_req($3);
515 $$ = new Clef_change_req(*$2);
518 | KEY '{' pitch_list '}' {
519 Key_change_req *key_p= new Key_change_req;
520 key_p->melodic_p_arr_ = *$3;
524 | GROUPING '{' intastint_list '}' {
525 $$ = get_grouping_req(*$3); delete $3;
531 assert(post_reqs.empty());
533 | post_requests post_request {
534 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
537 | post_requests close_plet_parens INT '/' INT {
538 post_reqs.push( get_request($2) );
539 req_defined_ch_c_l = lexer->here_ch_c_l();
540 post_reqs.push( get_plet_request( $2, $3, $5 ) );
546 | POST_REQUEST_IDENTIFIER {
547 $$ = $1->request(false)->clone();
552 close_request_parens {
553 $$ = get_request($1);
568 | octave_quotes octave_quote{ $$ += $2; }
575 MELODIC_REQUEST_IDENTIFIER {
577 * (Melodic_req *) $$ = *$1->request(false)->melodic();
578 $$->octave_i_ += lexer->prefs.default_octave_i_;
580 | steno_note_req '\'' {
583 | '`' steno_note_req {
588 | steno_note_req '!' {
589 $$->forceacc_b_ = ! $$->forceacc_b_;
594 MELODIC '{' int int int '}' {/* ugh */
595 $$ = new Melodic_req;
597 $$->notename_i_ = $4;
598 $$->accidental_i_ = $5;
603 DYNAMIC '{' int '}' {
604 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
605 ad_p ->loudness_ = (Dynamic_req::Loudness)$3;
612 req_defined_ch_c_l = lexer->here_ch_c_l();
617 close_request_parens:
636 SCRIPT '{' script_body '}' { $$ = $3; }
641 $$ = new Script_def(*$1,$2, $3,$4);
647 script_dir mudela_text { $$ = get_text_req($1,$2); }
652 defined_ch_c_l = lexer->here_ch_c_l();
659 script_dir mudela_script {
660 $$ = get_script_req($1, $2);
665 SCRIPT_IDENTIFIER { $$ = $1->script(true); }
666 | script_definition { $$ = $1; }
667 | '^' { $$ = get_scriptdef('^'); }
668 | '+' { $$ = get_scriptdef('+'); }
669 | '-' { $$ = get_scriptdef('-'); }
670 | '|' { $$ = get_scriptdef('|'); }
671 | 'o' { $$ = get_scriptdef('o'); }
672 | '>' { $$ = get_scriptdef('>'); }
673 | '.' { $$ = get_scriptdef('.'); }
676 warning( "too many staccato dots", lexer->here_ch_c_l() );
677 $$ = get_scriptdef('.');
680 $$ = get_scriptdef('.');
692 | pre_requests pre_request {
694 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
699 open_request_parens {
700 defined_ch_c_l = lexer->here_ch_c_l();
701 $$ = get_request($1);
706 PLET '{' INT '/' INT '}' {
707 lexer->prefs.set_plet($3,$5);
709 | DURATIONCOMMAND '{' STRING '}' {
710 lexer->prefs.set_duration_mode(*$3);
713 | DURATIONCOMMAND '{' notemode_duration '}' {
714 lexer->prefs.set_default_duration($3);
716 | OCTAVECOMMAND '{' octave_quotes '}' {
717 lexer->prefs.default_octave_i_ = $3;
720 lexer->prefs.textstyle_str_ = *$2;
727 $$ = new Moment(wholes($1[0], $1[1]));
729 |int '*' mudela_duration {
730 $$ = new Moment(Rational($1) * wholes($3[0], $3[1]));
753 lexer->prefs.set_last_duration($1);
758 lexer->prefs.set_last_duration($1);
763 lexer->prefs.get_default_duration($$);
766 | INT '*' INT '/' INT {
767 // ugh, must use Duration
768 lexer->prefs.set_plet( $3, $5 );
771 lexer->prefs.set_plet( 1, 1 );
777 lexer->prefs.get_default_duration($$);
783 steno_note_req notemode_duration {
784 $$ = get_note_element($1, $2);
786 | RESTNAME notemode_duration {
787 $$ = get_rest_element(*$1, $2);
793 mudela_text notemode_duration {
794 $$ = get_word_element($1, $2);
801 $$ = new Array<Melodic_req*>;
803 | pitch_list MELODIC_REQUEST_IDENTIFIER {
804 $$->push($2->request(false)->clone()->melodic());
811 if ( distance($1,Real(int($$)) ) > 1e-8)
812 error( "integer expected", lexer->here_ch_c_l() );
831 real unit { $$ = $1*$2; }
835 unit: CM_T { $$ = 1 CM; }
836 |IN_T { $$ = 1 INCH; }
845 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
853 $$ = new Lookup(*$1->lookup(true));
855 | symtables_body TEXID STRING {
856 $$->texsetting = *$3;
859 | symtables_body STRING '=' symtable {
866 TABLE '{' symtable_body '}' { $$ = $3; }
870 { $$ = new Symtable; }
871 | symtable_body STRING symboldef {
880 $$ = new Symbol(*$1, *$2);
886 $$ = new Symbol(*$1, b);
892 dinterval dinterval {
893 $$ = new Box(*$1, *$2);
900 $$ = new Interval($1, $2);
907 yyerror(const char *s)
909 lexer->LexerError(s);
912 exit( fatal_error_i );
916 parse_file(String init, String s)
918 *mlog << "Parsing ... ";
919 lexer = new My_flex_lexer;
922 yydebug = !monitor->silence("InitParser") && check_debug;
923 lexer->set_debug( !monitor->silence("InitLexer") && check_debug);
926 lexer->new_input(init);
930 if (!monitor->silence("InitDeclarations") && check_debug)
931 lexer->print_declarations();
933 yydebug = !monitor->silence("Parser") && check_debug;
934 lexer->set_debug( !monitor->silence("Lexer") && check_debug);
940 if (!monitor->silence("Declarations") && check_debug)
941 lexer->print_declarations();
946 if(!define_spots.empty())
947 warning("Braces don't match.",0);
953 return new Paper_def(
954 lexer->lookup_identifier("defaulttable")->lookup(true));