1 %
{ // -*-Fundamental-*-
4 #define MUDELA_VERSION "0.0.57"
6 #include "script-def.hh"
10 #include "my-lily-lexer.hh"
11 #include "paper-def.hh"
12 #include "midi-def.hh"
14 #include "input-score.hh"
15 #include "input-staff.hh"
16 #include "input-music.hh"
19 #include "parseconstruct.hh"
21 #include "identifier.hh"
22 #include "command-request.hh"
23 #include "musical-request.hh"
24 #include "voice-element.hh"
25 #include "my-lily-parser.hh"
26 #include "text-def.hh"
27 #include "input-register.hh"
33 #define YYERROR_VERBOSE 1
35 #define YYPARSE_PARAM my_lily_parser_l
36 #define YYLEX_PARAM my_lily_parser_l
37 #define THIS ((My_lily_parser *) my_lily_parser_l)
39 #define yyerror THIS->parser_error
45 Array
<Melodic_req
*> *melreqvec
;/* should clean up naming */
46 Array
<String
> * strvec
;
51 Input_register
* iregs
;
60 Music_general_chord
*chord
;
70 Symtables
* symtables
;
82 yylex(YYSTYPE *s
, void * v_l
)
84 My_lily_parser
*pars_l
= (My_lily_parser
*) v_l
;
85 My_lily_lexer
* lex_l
= pars_l
->lexer_p_
;
87 if
(pars_l
->first_b_
) {
88 pars_l
->first_b_
= false
;
89 pars_l
->do_init_file
();
92 lex_l
->lexval_l
= (void*) s
;
93 return lex_l
->yylex();
100 /* tokens which are not keywords */
108 %token DURATIONCOMMAND
121 %token MELODIC_REQUEST
153 %token E_EXCLAMATION E_SMALLER E_BIGGER E_CHAR
157 %token
<melreq
> NOTENAME_ID
158 %token
<id
> REGS_IDENTIFIER
159 %token
<id
> IDENTIFIER
160 %token
<id
> MELODIC_REQUEST_IDENTIFIER
161 %token
<id
> CHORD_IDENTIFIER
162 %token
<id
> VOICE_IDENTIFIER
163 %token
<id
> POST_REQUEST_IDENTIFIER
164 %token
<id
> SCRIPT_IDENTIFIER
165 %token
<id
> STAFF_IDENTIFIER
166 %token
<id
> REAL_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 close_plet_parens
178 %type
<chord
> music_chord music_chord_body init_music_chord
179 %type
<el
> voice_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_music
193 %type
<mvoice
> simple_horizontal_music horizontal_music horizontal_music_body
194 %type
<mvoice
> transposed_music_voice init_lyrics_voice
195 %type
<mvoice
> music_voice_body init_music_voice
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
> pure_post_request pure_post_request_choice
201 %type
<request
> script_req textscript_req dynamic_req
202 %type
<score
> score_block score_body
203 %type
<script
> script_definition script_body mudela_script
204 %type
<staff
> staff_block staff_init staff_body
205 %type
<string> declarable_identifier
206 %type
<string> script_abbreviation
207 %type
<id
> old_identifier
208 %type
<symbol
> symboldef
209 %type
<symtable
> symtable symtable_body
210 %type
<textdef
> mudela_text
211 %type
<iregs
> input_regs input_regs_body
215 %expect
1 /* have to fix this. */
220 | mudela score_block
{
223 | mudela add_declaration
{ }
225 | mudela check_version
{ }
226 | mudela add_notenames
{ }
230 init_end: INIT_END
';' {
231 THIS
->print_declarations
();
232 THIS
->init_parse_b_
= false
;
238 if
(*$2 != MUDELA_VERSION
) {
239 if
(THIS
->ignore_version_b_
) {
240 THIS
->here_input
().
error("Incorrect mudela version");
242 THIS
->fatal_error_i_
= 1;
243 THIS
->parser_error
("Incorrect mudela version");
250 NOTENAMES
'{' notenames_body
'}'
255 | notenames_body CLEAR
{
256 THIS
->clear_notenames
();
258 | notenames_body STRING
'=' melodic_request
{
259 THIS
->add_notename
(*$2, $4);
266 add_declaration: declaration
{
267 THIS
->lexer_p_
->add_identifier
($1);
268 $1->init_b_
= THIS
->init_parse_b_
;
269 $1->set_spot
(THIS
->pop_spot
());
273 declarable_identifier:
275 THIS
->remember_spot
();
279 THIS
->remember_spot
();
280 $$
= new String
($1->name_str_
);
281 THIS
->here_input
().warning
("redeclaration of `" + *$$
+ "'");
288 | MELODIC_REQUEST_IDENTIFIER
291 | POST_REQUEST_IDENTIFIER
301 declarable_identifier
'=' score_block
{
302 $$
= new Score_id
(*$1, $3, SCORE_IDENTIFIER
);
305 | declarable_identifier
'=' staff_block
{
306 $$
= new Staff_id
(*$1, $3, STAFF_IDENTIFIER
);
309 | declarable_identifier
'=' init_music_voice
{
310 $$
= new M_voice_id
(*$1, $3, VOICE_IDENTIFIER
);
313 | declarable_identifier
'=' init_lyrics_voice
{
314 $$
= new M_voice_id
(*$1, $3, VOICE_IDENTIFIER
);
317 | declarable_identifier
'=' script_definition
{
318 $$
= new Script_id
(*$1, $3, SCRIPT_IDENTIFIER
);
321 | declarable_identifier
'=' init_music_chord
{
322 $$
= new M_chord_id
(*$1, $3, CHORD_IDENTIFIER
);
325 | declarable_identifier
'=' symtables
{
326 $$
= new Lookup_id
(*$1, $3, IDENTIFIER
);
329 | declarable_identifier
'=' real
{
330 $$
= new Real_id
(*$1, new Real
($3), REAL_IDENTIFIER
);
334 | declarable_identifier
'=' pure_post_request
{
335 $$
= new Request_id
(*$1, $3, POST_REQUEST_IDENTIFIER
);
338 | declarable_identifier
'=' melodic_request
{
339 $$
= new Request_id
(*$1, $3, MELODIC_REQUEST_IDENTIFIER
);
342 | declarable_identifier
'=' input_regs
{
343 $$
= new Input_regs_id
(*$1, $3, REGS_IDENTIFIER
);
351 { THIS
->remember_spot
(); }
352 '{' input_regs_body
'}'
355 $$
->set_spot
(THIS
->pop_spot
());
361 $$
= $1->iregs
(true
);
364 $$
= new Input_register
;
367 | input_regs_body input_regs
{
376 SCORE
{ THIS
->remember_spot
(); }
377 /*cont*/ '{' score_body
'}' {
379 $$
->set_spot
(THIS
->pop_spot
());
380 if
(!$$
->paper_p_
&& ! $$
->midi_p_
)
381 $$
->paper_p_
= THIS
->default_paper
();
383 /* handle error levels. */
384 $$
->errorlevel_i_
= THIS
->error_level_i_
;
385 THIS
->error_level_i_
= 0;
390 $$
= new Input_score
;
393 $$
= $1->score
(true
);
395 | score_body staff_block
{ $$
->add
($2); }
396 | score_body paper_block
{ $$
->set
($2); }
397 | score_body midi_block
{ $$
->set
($2); }
404 /* */ { $$
=new Array
<int>; }
405 | intastint_list
int '*' int {
406 $$
->push
($2); $$
->push
($4);
416 '{' paper_body
'}' { $$
= $3; }
421 $$
= THIS
->default_paper
();
424 | paper_body WIDTH dim
{ $$
->linewidth
= $3;}
425 | paper_body OUTPUT STRING
{ $$
->outfile
= *$3;
428 | paper_body symtables
{ $$
->set
($2); }
429 | paper_body UNITSPACE dim
{ $$
->whole_width
= $3; }
430 | paper_body GEOMETRIC REAL
{ $$
->geometric_
= $3; }
442 '{' midi_body
'}' { $$
= $3; }
448 | midi_body OUTPUT STRING
{
449 $$
->outfile_str_
= *$3;
452 | midi_body TEMPO notemode_duration
':' int {
453 $$
->set_tempo
( $3->length
(), $5 );
464 STAFF
{ THIS
->remember_spot
(); }
465 /*cont*/ '{' staff_body
'}' {
467 $$
-> set_spot
(THIS
->pop_spot
());
469 |
{ THIS
->remember_spot
(); }
470 /*cont*/ STAFF_IDENTIFIER
{
471 $$
= $2->staff
(true
);
472 $$
-> set_spot
(THIS
->pop_spot
());
480 $$
= $1->staff
(true
);
483 $$
= new Input_staff
;
484 $$
->ireg_p_
= $1->iregs
(true
);
487 $$
= new Input_staff
;
494 | staff_body init_music
{
496 $2->set_default_group
( "staff_music" + String
($$
->music_.size
()));
504 let the lexer switch mode.
507 init_music_voice
{ $$
= $1; }
508 | init_music_chord
{ $$
= $1; }
509 | init_lyrics_voice
{ $$
= $1; }
511 $$
= $1->mvoice
(true
);
516 LYRIC
{ THIS
->lexer_p_
->push_lyric_state
(); }
517 horizontal_music
{ $$
= $3; THIS
->lexer_p_
->pop_state
(); }
521 MELODIC
{ THIS
->lexer_p_
->push_note_state
(); }
522 /* cont*/ horizontal_music
523 { $$
=$3; THIS
->lexer_p_
->pop_state
(); }
527 { THIS
->lexer_p_
->push_note_state
(); }
528 /* cont*/ music_chord
529 { $$
=$2; THIS
->lexer_p_
->pop_state
(); }
536 '{' horizontal_music_body
'}' {
541 horizontal_music_body:
542 simple_horizontal_music
{
545 | horizontal_music_body CONCAT simple_horizontal_music
{
546 $$
->add
($3);/* niet echt */
551 simple_horizontal_music:
552 TRANSPOSE
'{' transposed_music_voice
'}' {
556 $$
= $1->mvoice
(true
);
564 transposed_music_voice:
565 steno_melodic_req horizontal_music
{
575 $$
= new Music_voice
;
577 | music_voice_body full_element
{
580 | music_voice_body voice_command
';' {
582 | music_voice_body music_chord
{
585 | music_voice_body
error {
587 | music_voice_body
'>' {
588 THIS
->fatal_error_i_
= 1;
589 THIS
->parser_error
("Confused by errors: bailing out");
593 music_chord: '<' music_chord_body
'>' { $$
= $2; }
601 $$
= new Voice_group_chord
;
604 $$
= new Multi_voice_chord
;
606 | music_chord_body horizontal_music
{
609 | music_chord_body full_element
{
612 | music_chord_body
'}' {
613 THIS
->fatal_error_i_
= 1;
614 THIS
->parser_error
("Confused by errors: bailing out");
616 | music_chord_body
error {
623 full_element: pre_requests voice_elt post_requests
{
624 THIS
->add_requests
($2);
627 | pre_requests lyrics_elt post_requests
{
628 THIS
->add_requests
($2);
636 $$
= new Voice_element
;
637 $$
-> set_spot
( THIS
->here_input
());
641 $2-> set_spot
( THIS
->here_input
());
649 | verbose_command_req
';' { $$
= $1; }
654 $$
= new Barcheck_req
;
660 $$
= new Bar_req
(*$2);
663 | METER
int '/' int {
664 Meter_change_req
*m
= new Meter_change_req
;
666 // sorry hw, i need meter at output of track,
667 // but don-t know where to get it... statics should go.
668 // HW : default: 4/4, meterchange reqs may change it.
670 Midi_def
::num_i_s
= $2;
671 Midi_def
::den_i_s
= $4;
674 | SKIP duration_length
{
675 Skip_req
* skip_p
= new Skip_req
;
676 skip_p
->duration_
= *$2;
681 $$
= new Cadenza_req
($2);
683 | PARTIAL duration_length
{
684 $$
= new Partial_measure_req
(*$2);
688 $$
= get_stemdir_req
($2);
691 $$
= get_hshift_req
($2);
694 $$
= new Clef_change_req
(*$2);
698 Key_change_req
*key_p
= new Key_change_req
;
699 key_p
->melodic_p_arr_
= *$2;
703 | GROUPING intastint_list
{
704 $$
= get_grouping_req
(*$2); delete
$2;
707 $$
= new Group_change_req
;
708 $$
-> command
()->groupchange
()->newgroup_str_
= *$2;
715 assert
(THIS
->post_reqs.empty
());
717 | post_requests post_request
{
718 $2->set_spot
( THIS
->here_input
());
719 THIS
->post_reqs.push
($2);
721 | post_requests close_plet_parens INT
'/' INT
{
722 THIS
->post_reqs.push
( THIS
->get_parens_request
($2) );
723 THIS
->post_reqs.push
( get_plet_request
( $2, $3, $5 ) );
729 | POST_REQUEST_IDENTIFIER
{
730 $$
= $1->request
(false
)->clone
();
735 pure_post_request_choice
{
737 $$
->set_spot
( THIS
->here_input
());
740 pure_post_request_choice:
741 close_request_parens
{
742 $$
= THIS
->get_parens_request
($1);
756 $$
= $1->clone
()->melodic
();
757 $$
->octave_i_
+= THIS
->default_octave_i_
;
759 | steno_melodic_req POST_QUOTES
{
760 $$
-> octave_i_
+= $2;
762 | PRE_QUOTES steno_melodic_req
{
764 $2-> octave_i_
-= $1;
771 * (Melodic_req
*) $$
= *$1;
774 | steno_note_req
'!' {
775 $$
->forceacc_b_
= ! $$
->forceacc_b_
;
777 /* have to duration here. */
781 MELODIC_REQUEST
'{' int int int '}' {/* ugh */
782 $$
= new Melodic_req
;
784 $$
->notename_i_
= $4;
785 $$
->accidental_i_
= $5;
790 ABSDYNAMIC
'{' int '}' {
791 Absolute_dynamic_req
*ad_p
= new Absolute_dynamic_req
;
792 ad_p
->loudness_
= (Dynamic_req
::Loudness
)$3;
795 |SPANDYNAMIC
'{' int int '}' {
796 Span_dynamic_req
* sp_p
= new Span_dynamic_req
;
798 sp_p
-> dynamic_dir_i_
= $3;
809 close_request_parens:
842 SCRIPT
'{' script_body
'}' { $$
= $3; }
846 STRING
int int int int {
847 $$
= new Script_def
(*$1,$2, $3,$4,$5);
853 script_dir mudela_text
{ $$
= get_text_req
($1,$2); }
861 $$
->style_str_
= THIS
->textstyle_str_
;
866 script_dir mudela_script
{
867 $$
= get_script_req
($1, $2);
871 '^' { $$
= get_scriptdef
('^'); }
872 |
'+' { $$
= get_scriptdef
('+'); }
873 |
'-' { $$
= get_scriptdef
('-'); }
874 |
'|' { $$
= get_scriptdef
('|'); }
875 |
'o' { $$
= get_scriptdef
('o'); }
876 |
'>' { $$
= get_scriptdef
('>'); }
879 THIS
->here_input
().warning
( "too many staccato dots" );
880 $$
= get_scriptdef
('.');
885 SCRIPT_IDENTIFIER
{ $$
= $1->script
(true
); }
886 | script_definition
{ $$
= $1; }
887 | script_abbreviation
{
888 $$
= THIS
->lexer_p_
->lookup_identifier
(*$1)->script
(true
);
900 | pre_requests pre_request
{
901 THIS
->pre_reqs.push
($2);
902 $2->set_spot
( THIS
->here_input
());
907 open_request_parens
{
908 $$
= THIS
->get_parens_request
($1);
914 THIS
->default_duration_.set_plet
($2,$4);
916 | DURATIONCOMMAND STRING
{
917 THIS
->set_duration_mode
(*$2);
920 | DURATIONCOMMAND notemode_duration
{
921 THIS
->set_default_duration
($2);
926 This is weird, but default_octave_i_
927 is used in steno_note_req too
929 c' -> default_octave_i_ == 1
931 /* why can't we have \oct{0} iso \oct{c'}*/
932 THIS
->default_octave_i_
= 1; }
935 THIS
->default_octave_i_
= $3->octave_i_
;
939 THIS
->textstyle_str_
= *$2;
946 $$
= new Moment
(0,1);
948 | duration_length explicit_duration
{
955 $$
= new Duration
(THIS
->default_duration_
);
958 $$
= new Duration
(THIS
->default_duration_
);
961 | explicit_duration
{
962 THIS
->set_last_duration
($1);
970 if
( !Duration
::duration_type_b
($1) )
971 THIS
->parser_error
("Not a duration");
975 | explicit_duration DOTS
{
978 | explicit_duration
'*' int {
979 $$
->plet_.iso_i_
*= $3;
981 | explicit_duration
'/' int {
982 $$
->plet_.type_i_
*= $3;
988 steno_note_req notemode_duration
{
989 if
(!THIS
->lexer_p_
->note_state_b
())
990 THIS
->parser_error
("have to be in Note mode for notes");
991 $1->set_duration
(*$2);
992 $$
= THIS
->get_note_element
($1, $2);
994 | RESTNAME notemode_duration
{
995 $$
= THIS
->get_rest_element
(*$1, $2);
1001 mudela_text notemode_duration
{
1002 if
(!THIS
->lexer_p_
->lyric_state_b
())
1003 THIS
->parser_error
("Have to be in Lyric mode for lyrics");
1004 $$
= THIS
->get_word_element
($1, $2);
1012 $$
= new Array
<Melodic_req
*>;
1014 | pitch_list NOTENAME_ID
{
1015 $$
->push
($2->clone
()->melodic
());
1022 if
( distance
($1,Real
(int($$
)) ) > 1e-8)
1023 yyerror( "integer expected" );
1042 real unit
{ $$
= $1*$2; }
1046 unit: CM_T
{ $$
= 1 CM
; }
1047 |IN_T
{ $$
= 1 INCH
; }
1048 |MM_T
{ $$
= 1 MM
; }
1049 |PT_T
{ $$
= 1 PT
; }
1056 SYMBOLTABLES
'{' symtables_body
'}' { $$
= $3; }
1064 $$
= new Lookup
(*$1->lookup
(true
));
1066 | symtables_body TEXID STRING
{
1067 $$
->texsetting
= *$3;
1070 | symtables_body STRING
'=' symtable
{
1077 TABLE
'{' symtable_body
'}' { $$
= $3; }
1081 { $$
= new Symtable
; }
1082 | symtable_body STRING symboldef
{
1091 $$
= new Symbol
(*$1, *$2);
1096 Box b
(Interval
(0,0), Interval
(0,0));
1097 $$
= new Symbol
(*$1, b
);
1103 dinterval dinterval
{
1104 $$
= new Box
(*$1, *$2);
1110 dinterval: dim dim
{
1111 $$
= new Interval
($1, $2);
1118 My_lily_parser::set_yydebug
(bool b
)
1125 My_lily_parser::do_yyparse
()
1127 yyparse((void*)this
);
1131 My_lily_parser::default_paper
()
1133 return new Paper_def
(
1134 lexer_p_
->lookup_identifier
("default_table")->lookup
(true
));