1 %{ // -*-Fundamental-*-
4 #define MUDELA_VERSION "0.0.59"
6 #include "script-def.hh"
10 #include "my-lily-lexer.hh"
11 #include "paper-def.hh"
12 #include "midi-def.hh"
16 #include "parseconstruct.hh"
18 #include "identifier.hh"
19 #include "command-request.hh"
20 #include "musical-request.hh"
21 #include "my-lily-parser.hh"
22 #include "text-def.hh"
23 #include "input-register.hh"
25 #include "music-list.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;
50 Input_register * iregs;
52 Music_list *musiclist;
63 General_script_def * script;
67 Symtables * symtables;
77 yylex(YYSTYPE *s, void * v_l)
79 My_lily_parser *pars_l = (My_lily_parser*) v_l;
80 My_lily_lexer * lex_l = pars_l->lexer_p_;
82 if (pars_l->first_b_) {
83 pars_l->first_b_ = false;
84 pars_l->do_init_file();
87 lex_l->lexval_l = (void*) s;
88 return lex_l->yylex();
95 /* tokens which are not keywords */
107 %token DURATIONCOMMAND
113 %token REQUESTREGISTER
121 %token MELODIC_REQUEST
153 %token E_EXCLAMATION E_SMALLER E_BIGGER E_CHAR
157 %token <melreq> NOTENAME_ID
158 %token <id> IDENTIFIER
159 %token <id> MELODIC_REQUEST_IDENTIFIER
160 %token <id> MUSIC_IDENTIFIER
161 %token <id> VOICE_IDENTIFIER
162 %token <id> POST_REQUEST_IDENTIFIER
163 %token <id> SCRIPT_IDENTIFIER
164 %token <id> STAFF_IDENTIFIER
165 %token <id> REAL_IDENTIFIER
166 %token <id> INT_IDENTIFIER
167 %token <id> SCORE_IDENTIFIER
168 %token <id> REQUEST_IDENTIFIER
170 %token <string> DURATION RESTNAME
171 %token <string> STRING
172 %token <i> POST_QUOTES
173 %token <i> PRE_QUOTES
177 %type <c> open_request_parens close_request_parens
178 %type <c> open_plet_parens close_plet_parens
179 %type <music> simple_element music_elt full_element lyrics_elt command_elt
182 %type <id> declaration
183 %type <duration> explicit_duration notemode_duration
184 %type <interval> dinterval
185 %type <intvec> intastint_list
186 %type <lookup> symtables symtables_body
187 %type <melreq> melodic_request steno_melodic_req
188 %type <notereq> steno_note_req
189 %type <melreqvec> pitch_list
190 %type <midi> midi_block midi_body
191 %type <moment> duration_length
192 %type <music> init_melodic init_lyrics init_music
193 %type <music> Music transposed_music
194 %type <musiclist> Voice Voice_body
195 %type <chord> Chord Chord_body
196 %type <paper> paper_block paper_body
197 %type <real> dim real
199 %type <request> post_request pre_request command_req verbose_command_req abbrev_command_req
200 %type <request> script_req dynamic_req
201 %type <score> score_block score_body
202 %type <script> script_definition script_body mudela_script gen_script_def
203 %type <textdef> text_def
204 %type <string> declarable_identifier
205 %type <string> script_abbreviation
206 %type <id> old_identifier
207 %type <symbol> symboldef
208 %type <symtable> symtable symtable_body
209 %type <iregs> input_register_spec input_register_spec_body
216 | mudela score_block {
219 | mudela add_declaration { }
221 | mudela check_version { }
222 | mudela add_notenames { }
224 | mudela input_register_spec { add_global_input_register($2); }
227 init_end: INIT_END ';' {
228 THIS->print_declarations();
229 THIS->init_parse_b_ = false;
235 if (*$2 != MUDELA_VERSION) {
236 if (THIS->ignore_version_b_) {
237 THIS->here_input().error("Incorrect mudela version");
239 THIS->fatal_error_i_ = 1;
240 THIS->parser_error("Incorrect mudela version");
247 NOTENAMES '{' notenames_body '}'
252 | notenames_body CLEAR {
253 THIS->clear_notenames();
255 | notenames_body STRING '=' melodic_request {
256 THIS->add_notename(*$2, $4);
263 add_declaration: declaration {
264 THIS->lexer_p_->add_identifier($1);
265 $1->init_b_ = THIS->init_parse_b_;
266 $1->set_spot(THIS->pop_spot());
270 declarable_identifier:
272 THIS->remember_spot();
276 THIS->remember_spot();
277 $$ = new String($1->name_str_);
278 THIS->here_input().warning("redeclaration of `" + *$$ + "'");
285 | MELODIC_REQUEST_IDENTIFIER
286 | POST_REQUEST_IDENTIFIER
294 declarable_identifier '=' score_block {
295 $$ = new Score_id(*$1, $3, SCORE_IDENTIFIER);
298 | declarable_identifier '=' script_definition {
299 $$ = new Script_id(*$1, $3, SCRIPT_IDENTIFIER);
302 | declarable_identifier '=' init_music {
303 $$ = new Music_id(*$1, $3, MUSIC_IDENTIFIER);
306 | declarable_identifier '=' symtables {
307 $$ = new Lookup_id(*$1, $3, IDENTIFIER);
310 | declarable_identifier '=' real {
311 $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
315 | declarable_identifier '=' post_request {
316 $$ = new Request_id(*$1, $3, POST_REQUEST_IDENTIFIER);
319 | declarable_identifier '=' melodic_request {
320 $$ = new Request_id(*$1, $3, MELODIC_REQUEST_IDENTIFIER);
328 REQUESTREGISTER '{' input_register_spec_body '}'
332 input_register_spec_body:
334 $$ = new Input_register;
338 | input_register_spec_body ALIAS STRING ';' {
339 $$-> alias_str_arr_.push(*$3);
342 | input_register_spec_body CONSISTS STRING ';' {
343 $$-> consists_str_arr_.push(*$3);
346 | input_register_spec_body CONTAINS input_register_spec {
354 SCORE { THIS->remember_spot(); }
355 /*cont*/ '{' score_body '}' {
357 $$->set_spot(THIS->pop_spot());
358 if (!$$->paper_p_ && ! $$->midi_p_)
359 $$->paper_p_ = THIS->default_paper();
361 /* handle error levels. */
362 $$->errorlevel_i_ = THIS->error_level_i_;
363 THIS->error_level_i_ = 0;
371 $$ = $1->score(true);
373 | score_body init_music {
376 | score_body paper_block {
379 | score_body midi_block {
388 /* */ { $$ =new Array<int>; }
389 | intastint_list int '*' int {
390 $$->push($2); $$->push($4);
400 '{' paper_body '}' { $$ = $3; }
405 $$ = THIS->default_paper();
408 | paper_body WIDTH dim { $$->linewidth = $3;}
409 | paper_body OUTPUT STRING { $$->outfile = *$3;
412 | paper_body symtables { $$->set($2); }
413 | paper_body UNITSPACE dim { $$->whole_width = $3; }
414 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
426 '{' midi_body '}' { $$ = $3; }
432 | midi_body OUTPUT STRING {
433 $$->outfile_str_ = *$3;
436 | midi_body TEMPO notemode_duration ':' int {
437 $$->set_tempo( $3->length(), $5 );
447 let the lexer switch mode.
450 init_melodic { $$ = $1; }
451 | init_lyrics { $$ = $1; }
456 { THIS->lexer_p_->push_lyric_state(); }
458 { $$ = $3; THIS->lexer_p_->pop_state(); }
463 { THIS->lexer_p_->push_note_state(); }
465 { $$=$3; THIS->lexer_p_->pop_state(); }
482 | Voice_body ID STRING STRING ';' {
495 full_element { $$ = $1; }
498 | transposed_music { $$ = $1; }
499 | MUSIC_IDENTIFIER { $$ = $1->music(true); }
503 '<' Chord_body '>' { $$ = $2; }
509 $$-> multi_level_i_ = 1;
511 | Chord_body MULTI INT ';' {
512 $$->multi_level_i_=$3;
514 | Chord_body ID STRING STRING ';' {
526 TRANSPOSE steno_melodic_req Music {
538 pre_requests simple_element post_requests {
539 THIS->add_requests((Chord*)$2);//ugh
542 | voice_command ';' { $$ = 0; }
553 $$ = new Voice_element;
554 $$-> set_spot( THIS->here_input());
558 $2-> set_spot( THIS->here_input());
559 ((Chord*)$$) ->add($2);//ugh
562 | GROUP STRING ';' { // ugh ugh ugh
563 Change_reg *chr_p = new Change_reg;
565 chr_p-> type_str_ = "Voice_group_registers"; //ugh
566 chr_p-> id_str_ = *$2;
573 | verbose_command_req ';' { $$ = $1; }
578 $$ = new Barcheck_req;
584 $$ = new Bar_req(*$2);
587 | METER int '/' int {
588 Meter_change_req *m = new Meter_change_req;
590 // sorry hw, i need meter at output of track,
591 // but don-t know where to get it... statics should go.
592 // HW : default: 4/4, meterchange reqs may change it.
594 Midi_def::num_i_s = $2;
595 Midi_def::den_i_s = $4;
598 | SKIP duration_length {
599 Skip_req * skip_p = new Skip_req;
600 skip_p->duration_ = Duration(1,0);
601 skip_p->duration_.set_plet($2->numerator().as_long(),
602 $2->denominator().as_long());
608 $$ = new Cadenza_req($2);
610 | PARTIAL duration_length {
611 $$ = new Partial_measure_req(*$2);
615 $$ = get_stemdir_req($2);
618 $$ = get_hshift_req($2);
621 $$ = new Clef_change_req(*$2);
625 Key_change_req *key_p= new Key_change_req;
626 key_p->melodic_p_arr_ = *$2;
630 | GROUPING intastint_list {
631 $$ = get_grouping_req(*$2); delete $2;
638 assert(THIS->post_reqs.empty());
640 | post_requests post_request {
641 $2->set_spot( THIS->here_input());
642 THIS->post_reqs.push($2);
648 POST_REQUEST_IDENTIFIER {
649 $$ = (Request*)$1->request(true);
651 |close_request_parens {
652 $$ = THIS->get_parens_request($1);
665 $$ = $1->clone()->musical()->melodic();
666 $$->octave_i_ += THIS->default_octave_i_;
668 | steno_melodic_req POST_QUOTES {
669 $$-> octave_i_ += $2;
671 | PRE_QUOTES steno_melodic_req {
673 $2-> octave_i_ -= $1;
680 * (Melodic_req *) $$ = *$1;
683 | steno_note_req '!' {
684 $$->forceacc_b_ = ! $$->forceacc_b_;
686 /* have to duration here. */
690 MELODIC_REQUEST '{' int int int '}' {/* ugh */
691 $$ = new Melodic_req;
693 $$->notename_i_ = $4;
694 $$->accidental_i_ = $5;
699 ABSDYNAMIC '{' int '}' {
700 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
701 ad_p ->loudness_ = (Dynamic_req::Loudness)$3;
704 | SPANDYNAMIC '{' int int '}' {
705 Span_dynamic_req * sp_p = new Span_dynamic_req;
707 sp_p-> dynamic_dir_i_ = $3;
715 THIS->default_duration_.set_plet($2,$4);
719 close_request_parens:
729 | close_plet_parens {
743 THIS->default_duration_.set_plet($2,$4);
764 SCRIPT '{' script_body '}' { $$ = $3; }
768 STRING int int int int {
769 Script_def *s = new Script_def;
770 s->set_from_input(*$1,$2, $3,$4,$5);
777 script_dir gen_script_def {
778 Musical_script_req *m = new Musical_script_req;
780 m-> scriptdef_p_ = $2;
781 m-> set_spot ( THIS->here_input() );
787 text_def { $$ = $1; }
793 Text_def *t = new Text_def;
797 t->style_str_ = THIS->textstyle_str_;
798 $$->set_spot( THIS->here_input() );
803 '^' { $$ = get_scriptdef('^'); }
804 | '+' { $$ = get_scriptdef('+'); }
805 | '-' { $$ = get_scriptdef('-'); }
806 | '|' { $$ = get_scriptdef('|'); }
807 | 'o' { $$ = get_scriptdef('o'); }
808 | '>' { $$ = get_scriptdef('>'); }
810 $$ = get_scriptdef('.');
815 SCRIPT_IDENTIFIER { $$ = $1->script(true); }
816 | script_definition { $$ = $1; }
817 | script_abbreviation {
818 $$ = THIS->lexer_p_->lookup_identifier(*$1)->script(true);
830 | pre_requests pre_request {
831 THIS->pre_reqs.push($2);
832 $2->set_spot( THIS->here_input());
837 open_request_parens {
838 $$ = THIS->get_parens_request($1);
844 THIS->default_duration_.set_plet($2,$4);
846 | DURATIONCOMMAND STRING {
847 THIS->set_duration_mode(*$2);
850 | DURATIONCOMMAND notemode_duration {
851 THIS->set_default_duration($2);
856 This is weird, but default_octave_i_
857 is used in steno_note_req too
859 c' -> default_octave_i_ == 1
861 /* why can't we have \oct{0} iso \oct{c'}*/
862 THIS->default_octave_i_ = 1; }
865 THIS->default_octave_i_ = $3->octave_i_;
869 THIS->textstyle_str_ = *$2;
876 $$ = new Moment(0,1);
878 | duration_length explicit_duration {
885 | dots '.' { $$ ++; }
890 $$ = new Duration(THIS->default_duration_);
893 $$ = new Duration(THIS->default_duration_);
896 | explicit_duration {
897 THIS->set_last_duration($1);
905 if ( !Duration::duration_type_b($1) )
906 THIS->parser_error("Not a duration");
909 $$->set_plet(THIS->default_duration_);
912 | explicit_duration '.' {
915 | explicit_duration '*' int {
916 $$->plet_.iso_i_ *= $3;
918 | explicit_duration '/' int {
919 $$->plet_.type_i_ *= $3;
925 steno_note_req notemode_duration {
926 if (!THIS->lexer_p_->note_state_b())
927 THIS->parser_error("have to be in Note mode for notes");
928 $1->set_duration (*$2);
929 $$ = THIS->get_note_element($1, $2);
931 | RESTNAME notemode_duration {
932 $$ = THIS->get_rest_element(*$1, $2);
938 text_def notemode_duration {
939 if (!THIS->lexer_p_->lyric_state_b())
940 THIS->parser_error("Have to be in Lyric mode for lyrics");
941 $$ = THIS->get_word_element($1, $2);
949 $$ = new Array<Melodic_req*>;
951 | pitch_list NOTENAME_ID {
952 $$->push($2->clone()->musical()->melodic());
978 real unit { $$ = $1*$2; }
982 unit: CM_T { $$ = 1 CM; }
983 |IN_T { $$ = 1 INCH; }
992 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
1000 $$ = new Lookup(*$1->lookup(true));
1002 | symtables_body TEXID STRING {
1003 $$->texsetting = *$3;
1006 | symtables_body STRING '=' symtable {
1013 TABLE '{' symtable_body '}' { $$ = $3; }
1017 { $$ = new Symtable; }
1018 | symtable_body STRING symboldef {
1027 $$ = new Symbol(*$1, *$2);
1032 Box b(Interval(0,0), Interval(0,0));
1033 $$ = new Symbol(*$1, b);
1039 dinterval dinterval {
1040 $$ = new Box(*$1, *$2);
1046 dinterval: dim dim {
1047 $$ = new Interval($1, $2);
1054 My_lily_parser::set_yydebug(bool b )
1061 My_lily_parser::do_yyparse()
1063 yyparse((void*)this);
1067 My_lily_parser::default_paper()
1069 return new Paper_def(
1070 lexer_p_->lookup_identifier("default_table")->lookup(true));