1 %{ // -*-Fundamental-*-
5 #include "script-def.hh"
9 #include "my-lily-lexer.hh"
10 #include "paper-def.hh"
11 #include "midi-def.hh"
13 #include "input-score.hh"
14 #include "input-staff.hh"
15 #include "input-music.hh"
18 #include "parseconstruct.hh"
20 #include "identifier.hh"
21 #include "command-request.hh"
22 #include "musical-request.hh"
23 #include "voice-element.hh"
24 #include "my-lily-parser.hh"
25 #include "text-def.hh"
31 #define YYERROR_VERBOSE 1
33 #define YYPARSE_PARAM my_lily_parser_l
34 #define YYLEX_PARAM my_lily_parser_l
35 #define THIS ((My_lily_parser *) my_lily_parser_l)
37 #define yyerror THIS->parser_error
43 Array<Melodic_req*> *melreqvec;/* should clean up naming */
44 Array<String> * strvec;
57 Music_general_chord *chord;
67 Symtables * symtables;
79 yylex(YYSTYPE *s, void * v_l)
81 My_lily_parser *pars_l = (My_lily_parser*) v_l;
82 My_lily_lexer * lex_l = pars_l->lexer_p_;
83 lex_l->lexval_l = (void*) s;
84 return lex_l->yylex();
91 /* tokens which are not keywords */
98 %token DURATIONCOMMAND
136 %token <id> IDENTIFIER
137 %token <id> MELODIC_REQUEST_IDENTIFIER
138 %token <id> CHORD_IDENTIFIER
139 %token <id> VOICE_IDENTIFIER
140 %token <id> POST_REQUEST_IDENTIFIER
141 %token <id> SCRIPT_IDENTIFIER
142 %token <id> STAFF_IDENTIFIER
143 %token <id> REAL_IDENTIFIER
144 %token <id> SCORE_IDENTIFIER
145 %token <id> REQUEST_IDENTIFIER
147 %token <string> DURATION RESTNAME
148 %token <string> STRING
149 %token <i> POST_QUOTES
150 %token <i> PRE_QUOTES
154 %type <c> open_request_parens close_request_parens close_plet_parens
155 %type <chord> music_chord music_chord_body init_music_chord
156 %type <el> voice_elt full_element lyrics_elt command_elt
159 %type <id> declaration
160 %type <duration> explicit_duration notemode_duration
161 %type <interval> dinterval
162 %type <intvec> intastint_list
163 %type <lookup> symtables symtables_body
164 %type <melreq> melodic_request steno_melodic_req
165 %type <notereq> steno_note_req
166 %type <melreqvec> pitch_list
167 %type <midi> midi_block midi_body
168 %type <moment> duration_length
169 %type <music> init_music
170 %type <mvoice> transposed_music_voice init_lyrics_voice
171 %type <mvoice> music_voice_body music_voice init_music_voice
172 %type <paper> paper_block paper_body
173 %type <real> dim real
175 %type <request> post_request pre_request command_req pure_post_request
176 %type <request> script_req textscript_req dynamic_req
177 %type <score> score_block score_body
178 %type <script> script_definition script_body mudela_script
179 %type <staff> staff_block staff_init staff_body
180 %type <string> declarable_identifier
181 %type <string> script_abbreviation
182 %type <id> old_identifier
183 %type <symbol> symboldef
184 %type <symtable> symtable symtable_body
185 %type <textdef> mudela_text
190 %expect 1 /* have to fix this. */
195 | mudela score_block {
198 | mudela add_declaration { }
206 add_declaration: declaration {
207 THIS->lexer_p_->add_identifier($1);
208 $1->init_b_ = THIS->init_parse_b_;
209 $1->defined_ch_C_ = THIS->define_spot_array_.pop();
213 declarable_identifier:
215 THIS->remember_spot();
219 THIS->remember_spot();
220 $$ = new String($1->name);
221 warning("redeclaration of `" + *$$ + "'", THIS->here_ch_C());
228 | MELODIC_REQUEST_IDENTIFIER
231 | POST_REQUEST_IDENTIFIER
240 declarable_identifier '=' score_block {
241 $$ = new Score_id(*$1, $3, SCORE_IDENTIFIER);
244 | declarable_identifier '=' staff_block {
245 $$ = new Staff_id(*$1, $3, STAFF_IDENTIFIER);
248 | declarable_identifier '=' init_music_voice {
249 $$ = new M_voice_id(*$1, $3, VOICE_IDENTIFIER);
252 | declarable_identifier '=' init_lyrics_voice {
253 $$ = new M_voice_id(*$1, $3, VOICE_IDENTIFIER);
256 | declarable_identifier '=' script_definition {
257 $$ = new Script_id(*$1, $3, SCRIPT_IDENTIFIER);
260 | declarable_identifier '=' init_music_chord {
261 $$ = new M_chord_id(*$1, $3, CHORD_IDENTIFIER);
264 | declarable_identifier '=' symtables {
265 $$ = new Lookup_id(*$1, $3, IDENTIFIER);
268 | declarable_identifier '=' real {
269 $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
273 | declarable_identifier '=' pure_post_request {
274 $$ = new Request_id(*$1, $3, POST_REQUEST_IDENTIFIER);
277 | declarable_identifier '=' melodic_request {
278 $$ = new Request_id(*$1, $3, MELODIC_REQUEST_IDENTIFIER);
288 SCORE { THIS->remember_spot(); }
289 /*cont*/ '{' score_body '}' {
291 $$->defined_ch_C_ = THIS->define_spot_array_.pop();
292 if (!$$->paper_p_ && ! $$->midi_p_)
293 $$->paper_p_ = THIS->default_paper();
295 /* handle error levels. */
296 $$->errorlevel_i_ = THIS->error_level_i_;
297 THIS->error_level_i_ = 0;
302 $$ = new Input_score;
305 $$ = $1->score(true);
307 | score_body staff_block { $$->add($2); }
308 | score_body paper_block { $$->set($2); }
309 | score_body midi_block { $$->set($2); }
316 /* */ { $$ =new Array<int>; }
317 | intastint_list int '*' int {
318 $$->push($2); $$->push($4);
328 '{' paper_body '}' { $$ = $3; }
333 $$ = THIS->default_paper();
336 | paper_body WIDTH dim { $$->linewidth = $3;}
337 | paper_body OUTPUT STRING { $$->outfile = *$3;
340 | paper_body symtables { $$->set($2); }
341 | paper_body UNITSPACE dim { $$->whole_width = $3; }
342 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
354 '{' midi_body '}' { $$ = $3; }
360 | midi_body OUTPUT STRING {
361 $$->outfile_str_ = *$3;
364 | midi_body TEMPO notemode_duration ':' int {
365 $$->set_tempo( $3->length(), $5 );
376 STAFF { THIS->remember_spot(); }
377 /*cont*/ '{' staff_body '}' {
379 $$-> defined_ch_C_ = THIS->define_spot_array_.pop();
386 STAFF_IDENTIFIER { $$ = $1->staff(true); }
388 $$ = new Input_staff(*$1);
392 $$ = new Input_staff("melodic");
398 | staff_body init_music {
399 $2->set_default_group( "staff_music" + String($$->music_.size()));
407 let the lexer switch mode.
410 init_music_voice { $$ = $1; }
411 | init_music_chord { $$ = $1; }
412 | init_lyrics_voice { $$ = $1; }
416 LYRICS { THIS->lexer_p_->push_lyric_state(); }
417 music_voice { $$ = $3; THIS->lexer_p_->pop_state(); }
421 MUSIC { THIS->lexer_p_->push_note_state(); }
422 /* cont*/ music_voice
423 { $$=$3; THIS->lexer_p_->pop_state(); }
426 MUSIC { THIS->lexer_p_->push_note_state(); }
427 /* cont*/ music_chord
428 { $$=$3; THIS->lexer_p_->pop_state(); }
436 transposed_music_voice:
437 steno_melodic_req music_voice {
444 music_voice: '{' music_voice_body '}' { $$ = $2; }
445 | TRANSPOSE '{' transposed_music_voice '}' {
452 $$ = $1->mvoice(true);
455 $$ = new Music_voice;
457 | music_voice_body full_element {
460 | music_voice_body voice_command {
462 | music_voice_body music_chord {
465 | music_voice_body CONCAT music_voice {
466 $$->add($3);/* niet echt */
468 | music_voice_body error {
470 | music_voice_body '>' {
471 THIS->fatal_error_i_ = 1;
472 THIS->parser_error("Confused by errors: bailing out");
475 music_chord: '<' music_chord_body '>' { $$ = $2; }
483 $$ = new Voice_group_chord;
486 $$ = new Multi_voice_chord;
488 | music_chord_body music_voice {
491 | music_chord_body full_element {
494 | music_chord_body '}' {
495 THIS->fatal_error_i_ = 1;
496 THIS->parser_error("Confused by errors: bailing out");
498 | music_chord_body error {
505 full_element: pre_requests voice_elt post_requests {
506 THIS->add_requests($2);
509 | pre_requests lyrics_elt post_requests {
510 THIS->add_requests($2);
518 $$ = new Voice_element;
519 $$-> defined_ch_C_ = THIS->here_ch_C();
523 $2-> defined_ch_C_ = $$->defined_ch_C_;
531 $$ = new Barcheck_req;
534 $$ = new Bar_req(*$2);
537 | METER '{' int '/' int '}' {
538 Meter_change_req *m = new Meter_change_req;
540 // sorry hw, i need meter at output of track,
541 // but don-t know where to get it... statics should go.
542 // HW : default: 4/4, meterchange reqs may change it.
544 Midi_def::num_i_s = $3;
545 Midi_def::den_i_s = $5;
548 | SKIP '{' duration_length '}' {
549 Skip_req * skip_p = new Skip_req;
550 skip_p->duration_ = *$3;
554 | CADENZA '{' int '}' {
555 $$ = new Cadenza_req($3);
557 | PARTIAL '{' duration_length '}' {
558 $$ = new Partial_measure_req(*$3);
562 $$ = get_stemdir_req($3);
565 $$ = new Clef_change_req(*$2);
568 | KEY '{' pitch_list '}' {
569 Key_change_req *key_p= new Key_change_req;
570 key_p->melodic_p_arr_ = *$3;
574 | GROUPING '{' intastint_list '}' {
575 $$ = get_grouping_req(*$3); delete $3;
581 assert(THIS->post_reqs.empty());
583 | post_requests post_request {
584 $2->defined_ch_C_ = THIS->here_ch_C();
585 THIS->post_reqs.push($2);
587 | post_requests close_plet_parens INT '/' INT {
588 THIS->post_reqs.push( THIS->get_parens_request($2) );
589 THIS->post_reqs.push( get_plet_request( $2, $3, $5 ) );
595 | POST_REQUEST_IDENTIFIER {
596 $$ = $1->request(false)->clone();
601 close_request_parens {
602 $$ = THIS->get_parens_request($1);
615 MELODIC_REQUEST_IDENTIFIER {
616 $$ = $1->request(false)->clone()->melodic();
617 $$->octave_i_ += THIS->default_octave_i_;
619 | steno_melodic_req POST_QUOTES {
620 $$-> octave_i_ += $2;
622 | PRE_QUOTES steno_melodic_req {
624 $2-> octave_i_ -= $1;
631 * (Melodic_req *) $$ = *$1;
634 | steno_note_req '!' {
635 $$->forceacc_b_ = ! $$->forceacc_b_;
637 /* have to duration here. */
641 MELODIC '{' int int int '}' {/* ugh */
642 $$ = new Melodic_req;
644 $$->notename_i_ = $4;
645 $$->accidental_i_ = $5;
650 DYNAMIC '{' int '}' {
651 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
652 ad_p ->loudness_ = (Dynamic_req::Loudness)$3;
659 //req_defined_ch_C = THIS->here_ch_C();
664 close_request_parens:
683 SCRIPT '{' script_body '}' { $$ = $3; }
688 $$ = new Script_def(*$1,$2, $3,$4);
694 script_dir mudela_text { $$ = get_text_req($1,$2); }
699 //defined_ch_C = THIS->here_ch_C();
703 $$->style_str_ = THIS->textstyle_str_;
708 script_dir mudela_script {
709 $$ = get_script_req($1, $2);
713 '^' { $$ = get_scriptdef('^'); }
714 | '+' { $$ = get_scriptdef('+'); }
715 | '-' { $$ = get_scriptdef('-'); }
716 | '|' { $$ = get_scriptdef('|'); }
717 | 'o' { $$ = get_scriptdef('o'); }
718 | '>' { $$ = get_scriptdef('>'); }
721 warning( "too many staccato dots", THIS->here_ch_C() );
722 $$ = get_scriptdef('.');
727 SCRIPT_IDENTIFIER { $$ = $1->script(true); }
728 | script_definition { $$ = $1; }
729 | script_abbreviation {
730 $$ = THIS->lexer_p_->lookup_identifier(*$1)->script(true);
742 | pre_requests pre_request {
743 THIS->pre_reqs.push($2);
744 $2->defined_ch_C_ = THIS->here_ch_C();
749 open_request_parens {
750 //defined_ch_C = THIS->here_ch_C();
751 $$ = THIS->get_parens_request($1);
756 PLET '{' INT '/' INT '}' {
757 THIS->default_duration_.set_plet($3,$5);
759 | DURATIONCOMMAND '{' STRING '}' {
760 THIS->set_duration_mode(*$3);
763 | DURATIONCOMMAND '{' notemode_duration '}' {
764 THIS->default_duration_ = *$3;
767 | OCTAVECOMMAND '{' int '}' {
768 THIS->default_octave_i_ = $3;
771 THIS->textstyle_str_ = *$2;
778 $$ = new Moment(0,1);
780 | duration_length explicit_duration {
787 $$ = new Duration(THIS->default_duration_);
790 $$ = new Duration(THIS->default_duration_);
793 | explicit_duration {
794 THIS->set_last_duration($1);
804 | explicit_duration DOTS {
807 | explicit_duration '*' int {
808 $$->plet_.iso_i_ *= $3;
810 | explicit_duration '/' int {
811 $$->plet_.type_i_ *= $3;
817 steno_note_req notemode_duration {
818 if (!THIS->lexer_p_->note_state_b())
819 THIS->parser_error("have to be in Note mode for notes");
820 $$ = THIS->get_note_element($1, $2);
822 | RESTNAME notemode_duration {
823 $$ = THIS->get_rest_element(*$1, $2);
829 mudela_text notemode_duration {
830 if (!THIS->lexer_p_->lyric_state_b())
831 THIS->parser_error("Have to be in Lyric mode for lyrics");
832 $$ = THIS->get_word_element($1, $2);
840 $$ = new Array<Melodic_req*>;
842 | pitch_list MELODIC_REQUEST_IDENTIFIER {
843 $$->push($2->request(false)->clone()->melodic());
850 if ( distance($1,Real(int($$)) ) > 1e-8)
851 yyerror( "integer expected" );
870 real unit { $$ = $1*$2; }
874 unit: CM_T { $$ = 1 CM; }
875 |IN_T { $$ = 1 INCH; }
884 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
892 $$ = new Lookup(*$1->lookup(true));
894 | symtables_body TEXID STRING {
895 $$->texsetting = *$3;
898 | symtables_body STRING '=' symtable {
905 TABLE '{' symtable_body '}' { $$ = $3; }
909 { $$ = new Symtable; }
910 | symtable_body STRING symboldef {
919 $$ = new Symbol(*$1, *$2);
925 $$ = new Symbol(*$1, b);
931 dinterval dinterval {
932 $$ = new Box(*$1, *$2);
939 $$ = new Interval($1, $2);
946 My_lily_parser::set_yydebug(bool b )
953 My_lily_parser::do_yyparse()
955 yyparse((void*)this);
959 My_lily_parser::default_paper()
961 return new Paper_def(
962 lexer_p_->lookup_identifier("default_table")->lookup(true));