1 %
{ // -*-Fundamental-*-
7 #include "paper-def.hh"
9 #include "input-score.hh"
13 #include "parseconstruct.hh"
15 #include "identifier.hh"
16 #include "commandrequest.hh"
17 #include "musicalrequest.hh"
18 #include "voice-element.hh"
24 Array
<Request
*> pre_reqs
, post_reqs
;
25 Array
<const char *> define_spots
;
26 Paper_def
*default_paper
();
27 char const* defined_ch_c_l
;
28 char const* req_defined_ch_c_l
;
29 int fatal_error_i
= 0;
45 Music_general_chord
*chord
;
52 Array
<String
> * strvec
;
54 Array
<Melodic_req
*> *melreqvec
;
57 Symtables
* symtables
;
63 Notename_tab
*notename_tab
;
68 %token VOICE STAFF SCORE TITLE BAR OUTPUT MULTIVOICE DYNAMIC
69 %token CM_T IN_T PT_T MM_T PAPER WIDTH METER UNITSPACE SKIP COMMANDS COMMAND
70 %token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
71 %token KEY CLEF TABLE VOICES STEM
72 %token PARTIAL MUSIC GROUPING CADENZA
73 %token END SYMBOLTABLES TEXID TABLE NOTENAMES SCRIPT TEXTSTYLE PLET
77 %token
<id
> IDENTIFIER REAL_IDENTIFIER REQUEST_IDENTIFIER
78 %token
<string> PITCHMOD DURATION RESTNAME
81 %token
<string> STRING
85 %type
<melreqvec
> pitch_list
86 %type
<c
> open_request_parens close_request_parens close_plet_parens
87 %type
<id
> declaration
88 %type
<string> declarable_identifier
89 %type
<paper
> paper_block paper_body
90 %type
<midi
> midi_block midi_body
92 %type
<ii
> default_duration explicit_duration notemode_duration mudela_duration
94 %type
<moment
> duration_length
95 %type
<el
> voice_elt full_element lyrics_elt command_elt
97 %type
<score
> score_block score_body
98 %type
<staff
> staff_block staff_init staff_body
100 %type
<intvec
> intastint_list
101 %type
<request
> post_request pre_request command_req
102 %type
<string> pitchmod
104 %type
<chord
> music_chord music_chord_body
106 %type
<mvoice
> music_voice_body music_voice
108 %type
<interval
> dinterval
110 %type
<symtable
> symtable symtable_body
111 %type
<lookup
> symtables symtables_body
112 %type
<symbol
> symboldef
113 %type
<notename_tab
> notename_tab notename_tab_body
115 %type
<script
> script_definition script_body mudela_script
116 %type
<request
> script_req textscript_req dynamic_req basic_request
117 %type
<textdef
> mudela_text
123 | mudela score_block
{
126 | mudela add_declaration
{ }
127 | mudela mudela_command
{}
131 notename_tab
{ lexer
->set
($1); }
137 add_declaration: declaration
{
138 lexer
->add_identifier
($1);
142 declarable_identifier:
144 | IDENTIFIER
{ $$
= new String
($1->name
); }
148 declarable_identifier
'=' staff_block
{
149 $$
= new Staff_id
(*$1, $3, IDENTIFIER
);
152 | declarable_identifier
'=' music_voice
{
153 $$
= new M_voice_id
(*$1, $3, IDENTIFIER
);
156 | declarable_identifier
'=' script_definition
{
157 $$
= new Script_id
(*$1, $3, IDENTIFIER
);
160 | declarable_identifier
'=' music_chord
{
161 $$
= new M_chord_id
(*$1, $3, IDENTIFIER
);
164 | declarable_identifier
'=' symtables
{
165 $$
= new Lookup_id
(*$1, $3, IDENTIFIER
);
168 | declarable_identifier
'=' notename_tab
{
169 $$
= new Notetab_id
(*$1, $3, IDENTIFIER
);
172 | declarable_identifier
'=' real
{
173 $$
= new Real_id
(*$1, new Real
($3), REAL_IDENTIFIER
);
176 | declarable_identifier
error '}' {
179 | declarable_identifier
'=' basic_request
{
180 $$
= new Request_id
(*$1, $3, REQUEST_IDENTIFIER
);
186 NOTENAMES
'{' notename_tab_body
'}' { $$
= $3; }
190 $$
= new Notename_tab
;
193 $$
= $1->notename_tab
(true
);
195 | notename_tab_body STRING
int int {
196 $$
->set
($3, $4, *$2);
205 SCORE
{ define_spots.push
(lexer
->here_ch_c_l
()); }
206 /*cont*/ '{' score_body
'}' {
208 $$
->defined_ch_c_l_
= define_spots.pop
();
209 if
(!$$
->paper_p_
&& ! $$
->midi_p_
)
210 $$
->paper_p_
= default_paper
();
212 /* handle error levels. */
213 $$
->errorlevel_i_
= lexer
->errorlevel_i_
;
214 lexer
->errorlevel_i_
= 0;
219 $$
= new Input_score
;
221 | score_body staff_block
{ $$
->add
($2); }
222 | score_body COMMANDS
'{' music_voice_body
'}' {
225 | score_body paper_block
{ $$
->set
($2); }
226 | score_body midi_block
{ $$
->set
($2); }
233 /* */ { $$
=new Array
<int>; }
234 | intastint_list
int '*' int {
235 $$
->push
($2); $$
->push
($4);
246 '{' paper_body
'}' { $$
= $3; }
251 $$
= default_paper
();
253 | paper_body WIDTH dim
{ $$
->linewidth
= $3;}
254 | paper_body OUTPUT STRING
{ $$
->outfile
= *$3;
257 | paper_body symtables
{ $$
->set
($2); }
258 | paper_body UNITSPACE dim
{ $$
->whole_width
= $3; }
259 | paper_body GEOMETRIC REAL
{ $$
->geometric_
= $3; }
271 '{' midi_body
'}' { $$
= $3; }
277 | midi_body OUTPUT STRING
{
278 $$
->outfile_str_
= *$3;
281 | midi_body TEMPO mudela_duration
':' int {
282 $$
->set_tempo
( wholes
( $3[0], $3[1] ), $5 );
293 STAFF
{ define_spots.push
(lexer
->here_ch_c_l
()); }
294 /*cont*/ '{' staff_body
'}' {
296 $$
-> defined_ch_c_l_
= define_spots.pop
();
303 IDENTIFIER
{ $$
= $1->staff
(true
); }
305 $$
= new Input_staff
(*$1);
312 | staff_body COMMANDS
'{' music_voice_body
'}' {
313 $$
->set_score_wide
($4);
316 $2->set_default_group
( "staff_music" + String
($$
->music_.size
()));
327 music_voice
{ $$
= $1; }
328 | music_chord
{ $$
= $1; }
331 music_voice: MUSIC
'{' music_voice_body
'}' { $$
= $3; }
336 $$
= $1->mvoice
(true
);
339 $$
= new Music_voice
;
341 | music_voice_body
'+' IDENTIFIER
{
342 $$
->concatenate
($3->mvoice
(true
));
344 | music_voice_body full_element
{
347 | music_voice_body voice_command
{
349 | music_voice_body music
{
352 | music_voice_body
error {
356 music_chord: '{' music_chord_body
'}' { $$
= $2; }
364 $$
= new Voice_group_chord
;
367 $$
= new Multi_voice_chord
;
369 | music_chord_body
'+' IDENTIFIER
{
370 $$
->concatenate
($3->mchord
(true
));
372 | music_chord_body music
{
375 | music_chord_body full_element
{
378 | music_chord_body
error {
391 full_element: pre_requests voice_elt post_requests
{
392 add_requests
($2, pre_reqs
);
393 add_requests
($2, post_reqs
);
396 | pre_requests lyrics_elt post_requests
{
397 add_requests
($2, pre_reqs
);
398 add_requests
($2, post_reqs
);
406 $$
= new Voice_element
;
407 $$
-> defined_ch_c_l_
= lexer
->here_ch_c_l
();
411 $2-> defined_ch_c_l_
= $$
->defined_ch_c_l_
;
419 $$
= new Barcheck_req
;
422 $$
= new Bar_req
(*$2);
425 | METER
'{' int '*' int '}' {
426 Meter_change_req
*m
= new Meter_change_req
;
430 | SKIP
'{' duration_length
'}' {
431 Skip_req
* skip_p
= new Skip_req
;
432 skip_p
->duration_
= *$3;
436 | CADENZA
'{' int '}' {
437 $$
= new Cadenza_req
($3);
439 | PARTIAL
'{' duration_length
'}' {
440 $$
= new Partial_measure_req
(*$3);
444 $$
= get_stemdir_req
($3);
447 $$
= new Clef_change_req
(*$2);
450 | KEY
'{' pitch_list
'}' {
451 Key_change_req
*key_p
= new Key_change_req
;
452 key_p
->melodic_p_arr_
= *$3;
456 | GROUPING
'{' intastint_list
'}' {
457 $$
= get_grouping_req
(*$3); delete
$3;
463 assert
(post_reqs.empty
());
465 | post_requests post_request
{
466 $2->defined_ch_c_l_
= lexer
->here_ch_c_l
();
469 | post_requests close_plet_parens INT
'/' INT
{
470 post_reqs.push
( get_request
($2) );
471 req_defined_ch_c_l
= lexer
->here_ch_c_l
();
472 post_reqs.push
( get_plet_request
( $2, $3, $5 ) );
477 close_request_parens
{
478 $$
= get_request
($1);
483 | REQUEST_IDENTIFIER
{
484 $$
= $1->request
(false
)->clone
();
489 DYNAMIC
'{' int '}' {
490 Absolute_dynamic_req
*ad_p
= new Absolute_dynamic_req
;
491 ad_p
->loudness_
= $3;
498 req_defined_ch_c_l
= lexer
->here_ch_c_l
();
503 close_request_parens:
522 SCRIPT
'{' script_body
'}' { $$
= $3; }
527 $$
= new Script_def
(*$1,$2, $3,$4);
533 script_dir mudela_text
{ $$
= get_text_req
($1,$2); }
538 defined_ch_c_l
= lexer
->here_ch_c_l
();
545 script_dir mudela_script
{
546 $$
= get_script_req
($1, $2);
551 IDENTIFIER
{ $$
= $1->script
(true
); }
552 | script_definition
{ $$
= $1; }
553 |
'^' { $$
= get_scriptdef
('^'); }
554 |
'+' { $$
= get_scriptdef
('+'); }
555 |
'-' { $$
= get_scriptdef
('-'); }
556 |
'|' { $$
= get_scriptdef
('|'); }
557 |
'o' { $$
= get_scriptdef
('o'); }
558 |
'>' { $$
= get_scriptdef
('>'); }
559 |
'.' { $$
= get_scriptdef
('.'); }
562 warning
( "too many staccato dots", lexer
->here_ch_c_l
() );
563 $$
= get_scriptdef
('.');
566 $$
= get_scriptdef
('.');
578 | pre_requests pre_request
{
580 $2->defined_ch_c_l_
= lexer
->here_ch_c_l
();
585 open_request_parens
{
586 defined_ch_c_l
= lexer
->here_ch_c_l
();
587 $$
= get_request
($1);
592 PLET
'{' INT
'/' INT
'}' {
595 | DURATIONCOMMAND
'{' STRING
'}' {
596 set_duration_mode
(*$3);
599 | DURATIONCOMMAND
'{' notemode_duration
'}' {
600 set_default_duration
($3);
602 | OCTAVECOMMAND
'{' pitchmod
'}' {
603 set_default_octave
(*$3);
614 $$
= new Moment
(wholes
($1[0], $1[1]));
616 |
int '*' mudela_duration
{
617 $$
= new Moment
(Rational
($1) * wholes
($3[0], $3[1]));
650 get_default_duration
($$
);
653 | INT
'*' INT
'/' INT
{
654 // ugh, must use Duration
664 get_default_duration
($$
);
669 defined_ch_c_l
= lexer
->here_ch_c_l
();
673 defined_ch_c_l
= lexer
->here_ch_c_l
();
683 pitchmod notename notemode_duration
{
684 $$
= get_note_element
(*$1, $2, $3);
687 | RESTNAME notemode_duration
{
688 $$
= get_rest_element
(*$1, $2);
695 mudela_text notemode_duration
{
696 $$
= get_word_element
($1, $2);
703 $$
= new Array
<Melodic_req
*>;
705 | pitch_list NOTENAME
{
706 Melodic_req
*m_p
= new Melodic_req
;
707 m_p
->notename_i_
= $2[0];
708 m_p
->accidental_i_
= $2[1];
716 if
( distance
($1,Real
(int($$
)) ) > 1e-8)
717 error( "integer expected", lexer
->here_ch_c_l
() );
736 real unit
{ $$
= $1*$2; }
740 unit: CM_T
{ $$
= 1 CM
; }
741 |IN_T
{ $$
= 1 INCH
; }
750 SYMBOLTABLES
'{' symtables_body
'}' { $$
= $3; }
758 $$
= new Lookup
(*$1->lookup
(true
));
760 | symtables_body TEXID STRING
{
761 $$
->texsetting
= *$3;
764 | symtables_body STRING
'=' symtable
{
771 TABLE
'{' symtable_body
'}' { $$
= $3; }
775 { $$
= new Symtable
; }
776 | symtable_body STRING symboldef
{
785 $$
= new Symbol
(*$1, *$2);
791 $$
= new Symbol
(*$1, b
);
797 dinterval dinterval
{
798 $$
= new Box
(*$1, *$2);
805 $$
= new Interval
($1, $2);
812 yyerror(const char *s
)
814 lexer
->LexerError
(s
);
817 exit
( fatal_error_i
);
821 parse_file
(String init
, String s
)
823 *mlog
<< "Parsing ... ";
824 lexer
= new My_flex_lexer
;
827 yydebug = !monitor
->silence
("InitParser") && check_debug
;
828 lexer
->set_debug
( !monitor
->silence
("InitLexer") && check_debug
);
831 lexer
->new_input
(init
);
835 yydebug = !monitor
->silence
("Parser") && check_debug
;
836 lexer
->set_debug
( !monitor
->silence
("Lexer") && check_debug
);
844 if
(!define_spots.empty
())
845 warning
("Braces don't match.",0);
851 return new Paper_def
(
852 lexer
->lookup_identifier
("default_table")->lookup
(true
));