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
107 %token MELODIC_REQUEST
137 %token <id> IDENTIFIER
138 %token <id> MELODIC_REQUEST_IDENTIFIER
139 %token <id> CHORD_IDENTIFIER
140 %token <id> VOICE_IDENTIFIER
141 %token <id> POST_REQUEST_IDENTIFIER
142 %token <id> SCRIPT_IDENTIFIER
143 %token <id> STAFF_IDENTIFIER
144 %token <id> REAL_IDENTIFIER
145 %token <id> SCORE_IDENTIFIER
146 %token <id> REQUEST_IDENTIFIER
148 %token <string> DURATION RESTNAME
149 %token <string> STRING
150 %token <i> POST_QUOTES
151 %token <i> PRE_QUOTES
155 %type <c> open_request_parens close_request_parens close_plet_parens
156 %type <chord> music_chord music_chord_body init_music_chord
157 %type <el> voice_elt full_element lyrics_elt command_elt
160 %type <id> declaration
161 %type <duration> explicit_duration notemode_duration
162 %type <interval> dinterval
163 %type <intvec> intastint_list
164 %type <lookup> symtables symtables_body
165 %type <melreq> melodic_request steno_melodic_req
166 %type <notereq> steno_note_req
167 %type <melreqvec> pitch_list
168 %type <midi> midi_block midi_body
169 %type <moment> duration_length
170 %type <music> init_music
171 %type <mvoice> transposed_music_voice init_lyrics_voice
172 %type <mvoice> music_voice_body music_voice init_music_voice
173 %type <paper> paper_block paper_body
174 %type <real> dim real
176 %type <request> post_request pre_request command_req pure_post_request
177 %type <request> script_req textscript_req dynamic_req
178 %type <score> score_block score_body
179 %type <script> script_definition script_body mudela_script
180 %type <staff> staff_block staff_init staff_body
181 %type <string> declarable_identifier
182 %type <string> script_abbreviation
183 %type <id> old_identifier
184 %type <symbol> symboldef
185 %type <symtable> symtable symtable_body
186 %type <textdef> mudela_text
191 %expect 1 /* have to fix this. */
196 | mudela score_block {
199 | mudela add_declaration { }
207 add_declaration: declaration {
208 THIS->lexer_p_->add_identifier($1);
209 $1->init_b_ = THIS->init_parse_b_;
210 $1->defined_ch_C_ = THIS->define_spot_array_.pop();
214 declarable_identifier:
216 THIS->remember_spot();
220 THIS->remember_spot();
221 $$ = new String($1->name);
222 warning("redeclaration of `" + *$$ + "'", THIS->here_ch_C());
229 | MELODIC_REQUEST_IDENTIFIER
232 | POST_REQUEST_IDENTIFIER
241 declarable_identifier '=' score_block {
242 $$ = new Score_id(*$1, $3, SCORE_IDENTIFIER);
245 | declarable_identifier '=' staff_block {
246 $$ = new Staff_id(*$1, $3, STAFF_IDENTIFIER);
249 | declarable_identifier '=' init_music_voice {
250 $$ = new M_voice_id(*$1, $3, VOICE_IDENTIFIER);
253 | declarable_identifier '=' init_lyrics_voice {
254 $$ = new M_voice_id(*$1, $3, VOICE_IDENTIFIER);
257 | declarable_identifier '=' script_definition {
258 $$ = new Script_id(*$1, $3, SCRIPT_IDENTIFIER);
261 | declarable_identifier '=' init_music_chord {
262 $$ = new M_chord_id(*$1, $3, CHORD_IDENTIFIER);
265 | declarable_identifier '=' symtables {
266 $$ = new Lookup_id(*$1, $3, IDENTIFIER);
269 | declarable_identifier '=' real {
270 $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
274 | declarable_identifier '=' pure_post_request {
275 $$ = new Request_id(*$1, $3, POST_REQUEST_IDENTIFIER);
278 | declarable_identifier '=' melodic_request {
279 $$ = new Request_id(*$1, $3, MELODIC_REQUEST_IDENTIFIER);
289 SCORE { THIS->remember_spot(); }
290 /*cont*/ '{' score_body '}' {
292 $$->defined_ch_C_ = THIS->define_spot_array_.pop();
293 if (!$$->paper_p_ && ! $$->midi_p_)
294 $$->paper_p_ = THIS->default_paper();
296 /* handle error levels. */
297 $$->errorlevel_i_ = THIS->error_level_i_;
298 THIS->error_level_i_ = 0;
303 $$ = new Input_score;
306 $$ = $1->score(true);
308 | score_body staff_block { $$->add($2); }
309 | score_body paper_block { $$->set($2); }
310 | score_body midi_block { $$->set($2); }
317 /* */ { $$ =new Array<int>; }
318 | intastint_list int '*' int {
319 $$->push($2); $$->push($4);
329 '{' paper_body '}' { $$ = $3; }
334 $$ = THIS->default_paper();
337 | paper_body WIDTH dim { $$->linewidth = $3;}
338 | paper_body OUTPUT STRING { $$->outfile = *$3;
341 | paper_body symtables { $$->set($2); }
342 | paper_body UNITSPACE dim { $$->whole_width = $3; }
343 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
355 '{' midi_body '}' { $$ = $3; }
361 | midi_body OUTPUT STRING {
362 $$->outfile_str_ = *$3;
365 | midi_body TEMPO notemode_duration ':' int {
366 $$->set_tempo( $3->length(), $5 );
377 STAFF { THIS->remember_spot(); }
378 /*cont*/ '{' staff_body '}' {
380 $$-> defined_ch_C_ = THIS->define_spot_array_.pop();
382 | { THIS->remember_spot(); }
383 /*cont*/ STAFF_IDENTIFIER {
384 $$ = $2->staff(true);
385 $$-> defined_ch_C_ = THIS->define_spot_array_.pop();
393 $$ = new Input_staff( "melodic" );
396 $$ = new Input_staff(*$1);
403 | staff_body init_music {
405 $2->set_default_group( "staff_music" + String($$->music_.size()));
413 let the lexer switch mode.
416 init_music_voice { $$ = $1; }
417 | init_music_chord { $$ = $1; }
418 | init_lyrics_voice { $$ = $1; }
420 $$ = $1->mvoice(true);
425 LYRIC { THIS->lexer_p_->push_lyric_state(); }
426 music_voice { $$ = $3; THIS->lexer_p_->pop_state(); }
430 MELODIC { THIS->lexer_p_->push_note_state(); }
431 /* cont*/ music_voice
432 { $$=$3; THIS->lexer_p_->pop_state(); }
435 { THIS->lexer_p_->push_note_state(); }
436 /* cont*/ music_chord
437 { $$=$2; THIS->lexer_p_->pop_state(); }
445 transposed_music_voice:
446 steno_melodic_req music_voice {
453 music_voice: '{' music_voice_body '}' { $$ = $2; }
454 | TRANSPOSE '{' transposed_music_voice '}' {
461 $$ = $1->mvoice(true);
464 $$ = new Music_voice;
466 | music_voice_body full_element {
469 | music_voice_body voice_command {
471 | music_voice_body music_chord {
474 | music_voice_body CONCAT music_voice {
475 $$->add($3);/* niet echt */
477 | music_voice_body error {
479 | music_voice_body '>' {
480 THIS->fatal_error_i_ = 1;
481 THIS->parser_error("Confused by errors: bailing out");
485 music_chord: '<' music_chord_body '>' { $$ = $2; }
493 $$ = new Voice_group_chord;
496 $$ = new Multi_voice_chord;
498 | music_chord_body music_voice {
501 | music_chord_body full_element {
504 | music_chord_body '}' {
505 THIS->fatal_error_i_ = 1;
506 THIS->parser_error("Confused by errors: bailing out");
508 | music_chord_body error {
515 full_element: pre_requests voice_elt post_requests {
516 THIS->add_requests($2);
519 | pre_requests lyrics_elt post_requests {
520 THIS->add_requests($2);
528 $$ = new Voice_element;
529 $$-> defined_ch_C_ = THIS->here_ch_C();
533 $2-> defined_ch_C_ = $$->defined_ch_C_;
541 $$ = new Barcheck_req;
544 $$ = new Bar_req(*$2);
547 | METER '{' int '/' int '}' {
548 Meter_change_req *m = new Meter_change_req;
550 // sorry hw, i need meter at output of track,
551 // but don-t know where to get it... statics should go.
552 // HW : default: 4/4, meterchange reqs may change it.
554 Midi_def::num_i_s = $3;
555 Midi_def::den_i_s = $5;
558 | SKIP '{' duration_length '}' {
559 Skip_req * skip_p = new Skip_req;
560 skip_p->duration_ = *$3;
564 | CADENZA '{' int '}' {
565 $$ = new Cadenza_req($3);
567 | PARTIAL '{' duration_length '}' {
568 $$ = new Partial_measure_req(*$3);
572 $$ = get_stemdir_req($3);
575 $$ = new Clef_change_req(*$2);
578 | KEY '{' pitch_list '}' {
579 Key_change_req *key_p= new Key_change_req;
580 key_p->melodic_p_arr_ = *$3;
584 | GROUPING '{' intastint_list '}' {
585 $$ = get_grouping_req(*$3); delete $3;
591 assert(THIS->post_reqs.empty());
593 | post_requests post_request {
594 $2->defined_ch_C_ = THIS->here_ch_C();
595 THIS->post_reqs.push($2);
597 | post_requests close_plet_parens INT '/' INT {
598 THIS->post_reqs.push( THIS->get_parens_request($2) );
599 THIS->post_reqs.push( get_plet_request( $2, $3, $5 ) );
605 | POST_REQUEST_IDENTIFIER {
606 $$ = $1->request(false)->clone();
611 close_request_parens {
612 $$ = THIS->get_parens_request($1);
625 MELODIC_REQUEST_IDENTIFIER {
626 $$ = $1->request(false)->clone()->melodic();
627 $$->octave_i_ += THIS->default_octave_i_;
629 | steno_melodic_req POST_QUOTES {
630 $$-> octave_i_ += $2;
632 | PRE_QUOTES steno_melodic_req {
634 $2-> octave_i_ -= $1;
641 * (Melodic_req *) $$ = *$1;
644 | steno_note_req '!' {
645 $$->forceacc_b_ = ! $$->forceacc_b_;
647 /* have to duration here. */
651 MELODIC_REQUEST '{' int int int '}' {/* ugh */
652 $$ = new Melodic_req;
654 $$->notename_i_ = $4;
655 $$->accidental_i_ = $5;
660 DYNAMIC '{' int '}' {
661 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
662 ad_p ->loudness_ = (Dynamic_req::Loudness)$3;
669 //req_defined_ch_C = THIS->here_ch_C();
674 close_request_parens:
693 SCRIPT '{' script_body '}' { $$ = $3; }
698 $$ = new Script_def(*$1,$2, $3,$4);
704 script_dir mudela_text { $$ = get_text_req($1,$2); }
709 //defined_ch_C = THIS->here_ch_C();
713 $$->style_str_ = THIS->textstyle_str_;
718 script_dir mudela_script {
719 $$ = get_script_req($1, $2);
723 '^' { $$ = get_scriptdef('^'); }
724 | '+' { $$ = get_scriptdef('+'); }
725 | '-' { $$ = get_scriptdef('-'); }
726 | '|' { $$ = get_scriptdef('|'); }
727 | 'o' { $$ = get_scriptdef('o'); }
728 | '>' { $$ = get_scriptdef('>'); }
731 warning( "too many staccato dots", THIS->here_ch_C() );
732 $$ = get_scriptdef('.');
737 SCRIPT_IDENTIFIER { $$ = $1->script(true); }
738 | script_definition { $$ = $1; }
739 | script_abbreviation {
740 $$ = THIS->lexer_p_->lookup_identifier(*$1)->script(true);
752 | pre_requests pre_request {
753 THIS->pre_reqs.push($2);
754 $2->defined_ch_C_ = THIS->here_ch_C();
759 open_request_parens {
760 //defined_ch_C = THIS->here_ch_C();
761 $$ = THIS->get_parens_request($1);
766 PLET '{' INT '/' INT '}' {
767 THIS->default_duration_.set_plet($3,$5);
769 | DURATIONCOMMAND '{' STRING '}' {
770 THIS->set_duration_mode(*$3);
773 | DURATIONCOMMAND '{' notemode_duration '}' {
774 THIS->default_duration_ = *$3;
777 | OCTAVECOMMAND { THIS->default_octave_i_ = 2; }
779 '{' steno_melodic_req '}' {
780 THIS->default_octave_i_ = $4->octave_i_;
783 THIS->textstyle_str_ = *$2;
790 $$ = new Moment(0,1);
792 | duration_length explicit_duration {
799 $$ = new Duration(THIS->default_duration_);
802 $$ = new Duration(THIS->default_duration_);
805 | explicit_duration {
806 THIS->set_last_duration($1);
816 | explicit_duration DOTS {
819 | explicit_duration '*' int {
820 $$->plet_.iso_i_ *= $3;
822 | explicit_duration '/' int {
823 $$->plet_.type_i_ *= $3;
829 steno_note_req notemode_duration {
830 if (!THIS->lexer_p_->note_state_b())
831 THIS->parser_error("have to be in Note mode for notes");
832 $$ = THIS->get_note_element($1, $2);
834 | RESTNAME notemode_duration {
835 $$ = THIS->get_rest_element(*$1, $2);
841 mudela_text notemode_duration {
842 if (!THIS->lexer_p_->lyric_state_b())
843 THIS->parser_error("Have to be in Lyric mode for lyrics");
844 $$ = THIS->get_word_element($1, $2);
852 $$ = new Array<Melodic_req*>;
854 | pitch_list MELODIC_REQUEST_IDENTIFIER {
855 $$->push($2->request(false)->clone()->melodic());
862 if ( distance($1,Real(int($$)) ) > 1e-8)
863 yyerror( "integer expected" );
882 real unit { $$ = $1*$2; }
886 unit: CM_T { $$ = 1 CM; }
887 |IN_T { $$ = 1 INCH; }
896 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
904 $$ = new Lookup(*$1->lookup(true));
906 | symtables_body TEXID STRING {
907 $$->texsetting = *$3;
910 | symtables_body STRING '=' symtable {
917 TABLE '{' symtable_body '}' { $$ = $3; }
921 { $$ = new Symtable; }
922 | symtable_body STRING symboldef {
931 $$ = new Symbol(*$1, *$2);
937 $$ = new Symbol(*$1, b);
943 dinterval dinterval {
944 $$ = new Box(*$1, *$2);
951 $$ = new Interval($1, $2);
958 My_lily_parser::set_yydebug(bool b )
965 My_lily_parser::do_yyparse()
967 yyparse((void*)this);
971 My_lily_parser::default_paper()
973 return new Paper_def(
974 lexer_p_->lookup_identifier("default_table")->lookup(true));