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"
26 #include "input-register.hh"
32 #define YYERROR_VERBOSE 1
34 #define YYPARSE_PARAM my_lily_parser_l
35 #define YYLEX_PARAM my_lily_parser_l
36 #define THIS ((My_lily_parser *) my_lily_parser_l)
38 #define yyerror THIS->parser_error
44 Array<Melodic_req*> *melreqvec;/* should clean up naming */
45 Array<String> * strvec;
50 Input_register * iregs;
59 Music_general_chord *chord;
69 Symtables * symtables;
81 yylex(YYSTYPE *s, void * v_l)
83 My_lily_parser *pars_l = (My_lily_parser*) v_l;
84 My_lily_lexer * lex_l = pars_l->lexer_p_;
85 lex_l->lexval_l = (void*) s;
86 return lex_l->yylex();
93 /* tokens which are not keywords */
101 %token DURATIONCOMMAND
112 %token MELODIC_REQUEST
143 %token E_EXCLAMATION E_SMALLER E_BIGGER E_CHAR
147 %token <melreq> NOTENAME_ID
148 %token <id> REGS_IDENTIFIER
149 %token <id> IDENTIFIER
150 %token <id> MELODIC_REQUEST_IDENTIFIER
151 %token <id> CHORD_IDENTIFIER
152 %token <id> VOICE_IDENTIFIER
153 %token <id> POST_REQUEST_IDENTIFIER
154 %token <id> SCRIPT_IDENTIFIER
155 %token <id> STAFF_IDENTIFIER
156 %token <id> REAL_IDENTIFIER
157 %token <id> SCORE_IDENTIFIER
158 %token <id> REQUEST_IDENTIFIER
160 %token <string> DURATION RESTNAME
161 %token <string> STRING
162 %token <i> POST_QUOTES
163 %token <i> PRE_QUOTES
167 %type <c> open_request_parens close_request_parens close_plet_parens
168 %type <chord> music_chord music_chord_body init_music_chord
169 %type <el> voice_elt full_element lyrics_elt command_elt
172 %type <id> declaration
173 %type <duration> explicit_duration notemode_duration
174 %type <interval> dinterval
175 %type <intvec> intastint_list
176 %type <lookup> symtables symtables_body
177 %type <melreq> melodic_request steno_melodic_req
178 %type <notereq> steno_note_req
179 %type <melreqvec> pitch_list
180 %type <midi> midi_block midi_body
181 %type <moment> duration_length
182 %type <music> init_music
183 %type <mvoice> transposed_music_voice init_lyrics_voice
184 %type <mvoice> music_voice_body music_voice init_music_voice
185 %type <paper> paper_block paper_body
186 %type <real> dim real
188 %type <request> post_request pre_request command_req verbose_command_req abbrev_command_req
189 %type <request> pure_post_request pure_post_request_choice
190 %type <request> script_req textscript_req dynamic_req
191 %type <score> score_block score_body
192 %type <script> script_definition script_body mudela_script
193 %type <staff> staff_block staff_init staff_body
194 %type <string> declarable_identifier
195 %type <string> script_abbreviation
196 %type <id> old_identifier
197 %type <symbol> symboldef
198 %type <symtable> symtable symtable_body
199 %type <textdef> mudela_text
200 %type <iregs> input_regs input_regs_body
204 %expect 1 /* have to fix this. */
209 | mudela score_block {
212 | mudela add_declaration { }
214 | mudela add_notenames { }
218 NOTENAMES '{' notenames_body '}'
223 | notenames_body CLEAR {
224 THIS->clear_notenames();
226 | notenames_body STRING '=' melodic_request {
227 THIS->add_notename(*$2, $4);
234 add_declaration: declaration {
235 THIS->lexer_p_->add_identifier($1);
236 $1->init_b_ = THIS->init_parse_b_;
237 $1->set_spot(THIS->pop_spot());
241 declarable_identifier:
243 THIS->remember_spot();
247 THIS->remember_spot();
248 $$ = new String($1->name_str_);
249 THIS->here_input().warning("redeclaration of `" + *$$ + "'");
256 | MELODIC_REQUEST_IDENTIFIER
259 | POST_REQUEST_IDENTIFIER
269 declarable_identifier '=' score_block {
270 $$ = new Score_id(*$1, $3, SCORE_IDENTIFIER);
273 | declarable_identifier '=' staff_block {
274 $$ = new Staff_id(*$1, $3, STAFF_IDENTIFIER);
277 | declarable_identifier '=' init_music_voice {
278 $$ = new M_voice_id(*$1, $3, VOICE_IDENTIFIER);
281 | declarable_identifier '=' init_lyrics_voice {
282 $$ = new M_voice_id(*$1, $3, VOICE_IDENTIFIER);
285 | declarable_identifier '=' script_definition {
286 $$ = new Script_id(*$1, $3, SCRIPT_IDENTIFIER);
289 | declarable_identifier '=' init_music_chord {
290 $$ = new M_chord_id(*$1, $3, CHORD_IDENTIFIER);
293 | declarable_identifier '=' symtables {
294 $$ = new Lookup_id(*$1, $3, IDENTIFIER);
297 | declarable_identifier '=' real {
298 $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
302 | declarable_identifier '=' pure_post_request {
303 $$ = new Request_id(*$1, $3, POST_REQUEST_IDENTIFIER);
306 | declarable_identifier '=' melodic_request {
307 $$ = new Request_id(*$1, $3, MELODIC_REQUEST_IDENTIFIER);
310 | declarable_identifier '=' input_regs {
311 $$ = new Input_regs_id(*$1, $3, REGS_IDENTIFIER);
319 { THIS->remember_spot(); }
320 '{' input_regs_body '}'
323 $$->set_spot(THIS->pop_spot());
329 $$ = $1->iregs(true);
332 $$ = new Input_register;
335 | input_regs_body input_regs {
344 SCORE { THIS->remember_spot(); }
345 /*cont*/ '{' score_body '}' {
347 $$->set_spot(THIS->pop_spot());
348 if (!$$->paper_p_ && ! $$->midi_p_)
349 $$->paper_p_ = THIS->default_paper();
351 /* handle error levels. */
352 $$->errorlevel_i_ = THIS->error_level_i_;
353 THIS->error_level_i_ = 0;
358 $$ = new Input_score;
361 $$ = $1->score(true);
363 | score_body staff_block { $$->add($2); }
364 | score_body paper_block { $$->set($2); }
365 | score_body midi_block { $$->set($2); }
372 /* */ { $$ =new Array<int>; }
373 | intastint_list int '*' int {
374 $$->push($2); $$->push($4);
384 '{' paper_body '}' { $$ = $3; }
389 $$ = THIS->default_paper();
392 | paper_body WIDTH dim { $$->linewidth = $3;}
393 | paper_body OUTPUT STRING { $$->outfile = *$3;
396 | paper_body symtables { $$->set($2); }
397 | paper_body UNITSPACE dim { $$->whole_width = $3; }
398 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
410 '{' midi_body '}' { $$ = $3; }
416 | midi_body OUTPUT STRING {
417 $$->outfile_str_ = *$3;
420 | midi_body TEMPO notemode_duration ':' int {
421 $$->set_tempo( $3->length(), $5 );
432 STAFF { THIS->remember_spot(); }
433 /*cont*/ '{' staff_body '}' {
435 $$-> set_spot(THIS->pop_spot());
437 | { THIS->remember_spot(); }
438 /*cont*/ STAFF_IDENTIFIER {
439 $$ = $2->staff(true);
440 $$-> set_spot(THIS->pop_spot());
448 $$ = $1->staff(true);
451 $$ = new Input_staff;
452 $$->ireg_p_ = $1->iregs(true);
455 $$ = new Input_staff;
462 | staff_body init_music {
464 $2->set_default_group( "staff_music" + String($$->music_.size()));
472 let the lexer switch mode.
475 init_music_voice { $$ = $1; }
476 | init_music_chord { $$ = $1; }
477 | init_lyrics_voice { $$ = $1; }
479 $$ = $1->mvoice(true);
484 LYRIC { THIS->lexer_p_->push_lyric_state(); }
485 music_voice { $$ = $3; THIS->lexer_p_->pop_state(); }
489 MELODIC { THIS->lexer_p_->push_note_state(); }
490 /* cont*/ music_voice
491 { $$=$3; THIS->lexer_p_->pop_state(); }
494 { THIS->lexer_p_->push_note_state(); }
495 /* cont*/ music_chord
496 { $$=$2; THIS->lexer_p_->pop_state(); }
504 transposed_music_voice:
505 steno_melodic_req music_voice {
512 music_voice: '{' music_voice_body '}' { $$ = $2; }
513 | TRANSPOSE '{' transposed_music_voice '}' {
520 $$ = $1->mvoice(true);
523 $$ = new Music_voice;
525 | music_voice_body full_element {
528 | music_voice_body voice_command ';' {
530 | music_voice_body music_chord {
533 | music_voice_body CONCAT music_voice {
534 $$->add($3);/* niet echt */
536 | music_voice_body error {
538 | music_voice_body '>' {
539 THIS->fatal_error_i_ = 1;
540 THIS->parser_error("Confused by errors: bailing out");
544 music_chord: '<' music_chord_body '>' { $$ = $2; }
552 $$ = new Voice_group_chord;
555 $$ = new Multi_voice_chord;
557 | music_chord_body music_voice {
560 | music_chord_body full_element {
563 | music_chord_body '}' {
564 THIS->fatal_error_i_ = 1;
565 THIS->parser_error("Confused by errors: bailing out");
567 | music_chord_body error {
574 full_element: pre_requests voice_elt post_requests {
575 THIS->add_requests($2);
578 | pre_requests lyrics_elt post_requests {
579 THIS->add_requests($2);
587 $$ = new Voice_element;
588 $$-> set_spot( THIS->here_input());
592 $2-> set_spot( THIS->here_input());
600 | verbose_command_req ';' { $$ = $1; }
605 $$ = new Barcheck_req;
611 $$ = new Bar_req(*$2);
614 | METER int '/' int {
615 Meter_change_req *m = new Meter_change_req;
617 // sorry hw, i need meter at output of track,
618 // but don-t know where to get it... statics should go.
619 // HW : default: 4/4, meterchange reqs may change it.
621 Midi_def::num_i_s = $2;
622 Midi_def::den_i_s = $4;
625 | SKIP duration_length {
626 Skip_req * skip_p = new Skip_req;
627 skip_p->duration_ = *$2;
632 $$ = new Cadenza_req($2);
634 | PARTIAL duration_length {
635 $$ = new Partial_measure_req(*$2);
639 $$ = get_stemdir_req($2);
642 $$ = new Clef_change_req(*$2);
646 Key_change_req *key_p= new Key_change_req;
647 key_p->melodic_p_arr_ = *$2;
651 | GROUPING intastint_list {
652 $$ = get_grouping_req(*$2); delete $2;
655 $$ = new Group_change_req;
656 $$ -> command()->groupchange()->newgroup_str_ = *$2;
663 assert(THIS->post_reqs.empty());
665 | post_requests post_request {
666 $2->set_spot( THIS->here_input());
667 THIS->post_reqs.push($2);
669 | post_requests close_plet_parens INT '/' INT {
670 THIS->post_reqs.push( THIS->get_parens_request($2) );
671 THIS->post_reqs.push( get_plet_request( $2, $3, $5 ) );
677 | POST_REQUEST_IDENTIFIER {
678 $$ = $1->request(false)->clone();
683 pure_post_request_choice {
685 $$->set_spot( THIS->here_input());
688 pure_post_request_choice:
689 close_request_parens {
690 $$ = THIS->get_parens_request($1);
704 $$ = $1->clone()->melodic();
705 $$->octave_i_ += THIS->default_octave_i_;
707 | steno_melodic_req POST_QUOTES {
708 $$-> octave_i_ += $2;
710 | PRE_QUOTES steno_melodic_req {
712 $2-> octave_i_ -= $1;
719 * (Melodic_req *) $$ = *$1;
722 | steno_note_req '!' {
723 $$->forceacc_b_ = ! $$->forceacc_b_;
725 /* have to duration here. */
729 MELODIC_REQUEST '{' int int int '}' {/* ugh */
730 $$ = new Melodic_req;
732 $$->notename_i_ = $4;
733 $$->accidental_i_ = $5;
738 ABSDYNAMIC '{' int '}' {
739 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
740 ad_p ->loudness_ = (Dynamic_req::Loudness)$3;
743 |SPANDYNAMIC '{' int int '}' {
744 Span_dynamic_req * sp_p = new Span_dynamic_req;
746 sp_p-> dynamic_dir_i_ = $3;
757 close_request_parens:
787 SCRIPT '{' script_body '}' { $$ = $3; }
792 $$ = new Script_def(*$1,$2, $3,$4);
798 script_dir mudela_text { $$ = get_text_req($1,$2); }
806 $$->style_str_ = THIS->textstyle_str_;
811 script_dir mudela_script {
812 $$ = get_script_req($1, $2);
816 '^' { $$ = get_scriptdef('^'); }
817 | '+' { $$ = get_scriptdef('+'); }
818 | '-' { $$ = get_scriptdef('-'); }
819 | '|' { $$ = get_scriptdef('|'); }
820 | 'o' { $$ = get_scriptdef('o'); }
821 | '>' { $$ = get_scriptdef('>'); }
824 THIS->here_input().warning( "too many staccato dots" );
825 $$ = get_scriptdef('.');
830 SCRIPT_IDENTIFIER { $$ = $1->script(true); }
831 | script_definition { $$ = $1; }
832 | script_abbreviation {
833 $$ = THIS->lexer_p_->lookup_identifier(*$1)->script(true);
845 | pre_requests pre_request {
846 THIS->pre_reqs.push($2);
847 $2->set_spot( THIS->here_input());
852 open_request_parens {
853 $$ = THIS->get_parens_request($1);
859 THIS->default_duration_.set_plet($2,$4);
861 | DURATIONCOMMAND STRING {
862 THIS->set_duration_mode(*$2);
865 | DURATIONCOMMAND notemode_duration {
866 THIS->default_duration_ = *$2;
871 This is weird, but default_octave_i_
872 is used in steno_note_req too
874 c' -> default_octave_i_ == 1
876 /* why can't we have \oct{0} iso \oct{c'}*/
877 THIS->default_octave_i_ = 1; }
880 THIS->default_octave_i_ = $3->octave_i_;
884 THIS->textstyle_str_ = *$2;
891 $$ = new Moment(0,1);
893 | duration_length explicit_duration {
900 $$ = new Duration(THIS->default_duration_);
903 $$ = new Duration(THIS->default_duration_);
906 | explicit_duration {
907 THIS->set_last_duration($1);
915 if ( !Duration::duration_type_b($1) )
916 THIS->parser_error("Not a duration");
920 | explicit_duration DOTS {
923 | explicit_duration '*' int {
924 $$->plet_.iso_i_ *= $3;
926 | explicit_duration '/' int {
927 $$->plet_.type_i_ *= $3;
933 steno_note_req notemode_duration {
934 if (!THIS->lexer_p_->note_state_b())
935 THIS->parser_error("have to be in Note mode for notes");
936 $$ = THIS->get_note_element($1, $2);
938 | RESTNAME notemode_duration {
939 $$ = THIS->get_rest_element(*$1, $2);
945 mudela_text notemode_duration {
946 if (!THIS->lexer_p_->lyric_state_b())
947 THIS->parser_error("Have to be in Lyric mode for lyrics");
948 $$ = THIS->get_word_element($1, $2);
956 $$ = new Array<Melodic_req*>;
958 | pitch_list NOTENAME_ID {
959 $$->push($2->clone()->melodic());
966 if ( distance($1,Real(int($$)) ) > 1e-8)
967 yyerror( "integer expected" );
986 real unit { $$ = $1*$2; }
990 unit: CM_T { $$ = 1 CM; }
991 |IN_T { $$ = 1 INCH; }
1000 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
1008 $$ = new Lookup(*$1->lookup(true));
1010 | symtables_body TEXID STRING {
1011 $$->texsetting = *$3;
1014 | symtables_body STRING '=' symtable {
1021 TABLE '{' symtable_body '}' { $$ = $3; }
1025 { $$ = new Symtable; }
1026 | symtable_body STRING symboldef {
1035 $$ = new Symbol(*$1, *$2);
1041 $$ = new Symbol(*$1, b);
1047 dinterval dinterval {
1048 $$ = new Box(*$1, *$2);
1054 dinterval: dim dim {
1055 $$ = new Interval($1, $2);
1062 My_lily_parser::set_yydebug(bool b )
1069 My_lily_parser::do_yyparse()
1071 yyparse((void*)this);
1075 My_lily_parser::default_paper()
1077 return new Paper_def(
1078 lexer_p_->lookup_identifier("default_table")->lookup(true));