1 %{ // -*-Fundamental-*-
7 #include "paper-def.hh"
9 #include "input-score.hh"
13 #include "parseconstruct.hh"
15 #include "identifier.hh"
16 #include "command-request.hh"
17 #include "musical-request.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;
35 Array<Melodic_req*> *melreqvec;
36 Array<String> * strvec;
48 Music_general_chord *chord;
58 Symtables * symtables;
74 %token DURATIONCOMMAND
114 %token <id> IDENTIFIER
115 %token <id> MELODIC_REQUEST_IDENTIFIER
116 %token <id> POST_REQUEST_IDENTIFIER
117 %token <id> REAL_IDENTIFIER
118 %token <id> REQUEST_IDENTIFIER
120 %token <string> DURATION RESTNAME
121 %token <string> STRING
124 %type <c> open_request_parens close_request_parens close_plet_parens
125 %type <chord> music_chord music_chord_body
126 %type <el> voice_elt full_element lyrics_elt command_elt
128 %type <i> octave_quotes octave_quote
130 %type <id> declaration
131 %type <ii> default_duration explicit_duration notemode_duration
132 %type <ii> mudela_duration
133 %type <interval> dinterval
134 %type <intvec> intastint_list
135 %type <lookup> symtables symtables_body
136 %type <melreq> melodic_request
137 %type <notereq> steno_note_req
138 %type <melreqvec> pitch_list
139 %type <midi> midi_block midi_body
140 %type <moment> duration_length
142 %type <mvoice> music_voice_body music_voice
144 %type <paper> paper_block paper_body
145 %type <real> dim real
147 %type <request> post_request pre_request command_req pure_post_request
148 %type <request> script_req textscript_req dynamic_req
149 %type <score> score_block score_body
150 %type <script> script_definition script_body mudela_script
151 %type <staff> staff_block staff_init staff_body
152 %type <string> declarable_identifier
153 %type <symbol> symboldef
154 %type <symtable> symtable symtable_body
155 %type <textdef> mudela_text
160 | mudela score_block {
163 | mudela add_declaration { }
170 add_declaration: declaration {
171 lexer->add_identifier($1);
175 declarable_identifier:
177 if (lexer->lookup_identifier(*$1))
178 warning("redeclaration of `" + *$1 + "'",
179 lexer->here_ch_c_l());
181 | IDENTIFIER { $$ = new String($1->name); }
185 declarable_identifier '=' staff_block {
186 $$ = new Staff_id(*$1, $3, IDENTIFIER);
189 | declarable_identifier '=' music_voice {
190 $$ = new M_voice_id(*$1, $3, IDENTIFIER);
193 | declarable_identifier '=' script_definition {
194 $$ = new Script_id(*$1, $3, IDENTIFIER);
197 | declarable_identifier '=' music_chord {
198 $$ = new M_chord_id(*$1, $3, IDENTIFIER);
201 | declarable_identifier '=' symtables {
202 $$ = new Lookup_id(*$1, $3, IDENTIFIER);
205 | declarable_identifier '=' real {
206 $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
209 | declarable_identifier error '}' {
212 | declarable_identifier '=' pure_post_request {
213 $$ = new Request_id(*$1, $3, POST_REQUEST_IDENTIFIER);
216 | declarable_identifier '=' melodic_request {
217 $$ = new Request_id(*$1, $3, MELODIC_REQUEST_IDENTIFIER);
227 SCORE { define_spots.push(lexer->here_ch_c_l()); }
228 /*cont*/ '{' score_body '}' {
230 $$->defined_ch_c_l_ = define_spots.pop();
231 if (!$$->paper_p_ && ! $$->midi_p_)
232 $$->paper_p_ = default_paper();
234 /* handle error levels. */
235 $$->errorlevel_i_ = lexer->errorlevel_i_;
236 lexer->errorlevel_i_ = 0;
238 /* unbarf score without global music. */
239 if (!$$-> score_wide_music_p_) {
240 $$-> score_wide_music_p_ = new Music_voice;
246 $$ = new Input_score;
248 | score_body staff_block { $$->add($2); }
249 | score_body COMMANDS '{' music_voice_body '}' {
252 | score_body paper_block { $$->set($2); }
253 | score_body midi_block { $$->set($2); }
260 /* */ { $$ =new Array<int>; }
261 | intastint_list int '*' int {
262 $$->push($2); $$->push($4);
273 '{' paper_body '}' { $$ = $3; }
278 $$ = default_paper();
280 | paper_body WIDTH dim { $$->linewidth = $3;}
281 | paper_body OUTPUT STRING { $$->outfile = *$3;
284 | paper_body symtables { $$->set($2); }
285 | paper_body UNITSPACE dim { $$->whole_width = $3; }
286 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
298 '{' midi_body '}' { $$ = $3; }
304 | midi_body OUTPUT STRING {
305 $$->outfile_str_ = *$3;
308 | midi_body TEMPO mudela_duration ':' int {
309 $$->set_tempo( wholes( $3[0], $3[1] ), $5 );
320 STAFF { define_spots.push(lexer->here_ch_c_l()); }
321 /*cont*/ '{' staff_body '}' {
323 $$-> defined_ch_c_l_ = define_spots.pop();
330 IDENTIFIER { $$ = $1->staff(true); }
332 $$ = new Input_staff(*$1);
336 $$ = new Input_staff("melodic");
342 | staff_body COMMANDS '{' music_voice_body '}' {
343 $$->set_score_wide($4);
346 $2->set_default_group( "staff_music" + String($$->music_.size()));
357 music_voice { $$ = $1; }
358 | music_chord { $$ = $1; }
361 music_voice: MUSIC '{' music_voice_body '}' { $$ = $3; }
366 $$ = $1->mvoice(true);
369 $$ = new Music_voice;
371 | music_voice_body '+' IDENTIFIER {
372 $$->concatenate($3->mvoice(true));
374 | music_voice_body full_element {
377 | music_voice_body voice_command {
379 | music_voice_body music {
382 | music_voice_body error {
386 music_chord: '{' music_chord_body '}' { $$ = $2; }
394 $$ = new Voice_group_chord;
397 $$ = new Multi_voice_chord;
399 | music_chord_body '+' IDENTIFIER {
400 $$->concatenate($3->mchord(true));
402 | music_chord_body music {
405 | music_chord_body full_element {
408 | music_chord_body error {
415 full_element: pre_requests voice_elt post_requests {
416 add_requests($2, pre_reqs);
417 add_requests($2, post_reqs);
420 | pre_requests lyrics_elt post_requests {
421 add_requests($2, pre_reqs);
422 add_requests($2, post_reqs);
430 $$ = new Voice_element;
431 $$-> defined_ch_c_l_ = lexer->here_ch_c_l();
435 $2-> defined_ch_c_l_ = $$->defined_ch_c_l_;
443 $$ = new Barcheck_req;
446 $$ = new Bar_req(*$2);
449 | METER '{' int '*' int '}' {
450 Meter_change_req *m = new Meter_change_req;
452 // sorry hw, i need meter at output of track,
453 // but don-t know where to get it... statics should go.
454 Midi_def::num_i_s = $3;
455 Midi_def::den_i_s = $5;
458 | SKIP '{' duration_length '}' {
459 Skip_req * skip_p = new Skip_req;
460 skip_p->duration_ = *$3;
464 | CADENZA '{' int '}' {
465 $$ = new Cadenza_req($3);
467 | PARTIAL '{' duration_length '}' {
468 $$ = new Partial_measure_req(*$3);
472 $$ = get_stemdir_req($3);
475 $$ = new Clef_change_req(*$2);
478 | KEY '{' pitch_list '}' {
479 Key_change_req *key_p= new Key_change_req;
480 key_p->melodic_p_arr_ = *$3;
484 | GROUPING '{' intastint_list '}' {
485 $$ = get_grouping_req(*$3); delete $3;
491 assert(post_reqs.empty());
493 | post_requests post_request {
494 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
497 | post_requests close_plet_parens INT '/' INT {
498 post_reqs.push( get_request($2) );
499 req_defined_ch_c_l = lexer->here_ch_c_l();
500 post_reqs.push( get_plet_request( $2, $3, $5 ) );
506 | POST_REQUEST_IDENTIFIER {
507 $$ = $1->request(false)->clone();
512 close_request_parens {
513 $$ = get_request($1);
528 | octave_quotes octave_quote{ $$ += $2; }
535 MELODIC_REQUEST_IDENTIFIER {
537 * (Melodic_req *) $$ = *$1->request(false)->melodic();
538 $$->octave_i_ += lexer->prefs.default_octave_i_;
540 | octave_quote steno_note_req {
541 $2-> octave_i_ += $1;
544 | '!' steno_note_req {
546 $2->forceacc_b_ = ! $2->forceacc_b_;
551 MELODIC '{' int int int int '}' {/* ugh */
552 $$ = new Melodic_req;
554 $$->notename_i_ = $4;
555 $$->accidental_i_ = $5;
556 $$->forceacc_b_ = $6;
561 DYNAMIC '{' int '}' {
562 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
563 ad_p ->loudness_ = $3;
570 req_defined_ch_c_l = lexer->here_ch_c_l();
575 close_request_parens:
594 SCRIPT '{' script_body '}' { $$ = $3; }
599 $$ = new Script_def(*$1,$2, $3,$4);
605 script_dir mudela_text { $$ = get_text_req($1,$2); }
610 defined_ch_c_l = lexer->here_ch_c_l();
617 script_dir mudela_script {
618 $$ = get_script_req($1, $2);
623 IDENTIFIER { $$ = $1->script(true); }
624 | script_definition { $$ = $1; }
625 | '^' { $$ = get_scriptdef('^'); }
626 | '+' { $$ = get_scriptdef('+'); }
627 | '-' { $$ = get_scriptdef('-'); }
628 | '|' { $$ = get_scriptdef('|'); }
629 | 'o' { $$ = get_scriptdef('o'); }
630 | '>' { $$ = get_scriptdef('>'); }
631 | '.' { $$ = get_scriptdef('.'); }
634 warning( "too many staccato dots", lexer->here_ch_c_l() );
635 $$ = get_scriptdef('.');
638 $$ = get_scriptdef('.');
650 | pre_requests pre_request {
652 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
657 open_request_parens {
658 defined_ch_c_l = lexer->here_ch_c_l();
659 $$ = get_request($1);
664 PLET '{' INT '/' INT '}' {
665 lexer->prefs.set_plet($3,$5);
667 | DURATIONCOMMAND '{' STRING '}' {
668 lexer->prefs.set_duration_mode(*$3);
671 | DURATIONCOMMAND '{' notemode_duration '}' {
672 lexer->prefs.set_default_duration($3);
674 | OCTAVECOMMAND '{' octave_quotes '}' {
675 lexer->prefs.default_octave_i_ = $3;
678 lexer->prefs.textstyle_str_ = *$2;
685 $$ = new Moment(wholes($1[0], $1[1]));
687 |int '*' mudela_duration {
688 $$ = new Moment(Rational($1) * wholes($3[0], $3[1]));
711 lexer->prefs.set_last_duration($1);
716 lexer->prefs.set_last_duration($1);
721 lexer->prefs.get_default_duration($$);
724 | INT '*' INT '/' INT {
725 // ugh, must use Duration
726 lexer->prefs.set_plet( $3, $5 );
729 lexer->prefs.set_plet( 1, 1 );
735 lexer->prefs.get_default_duration($$);
741 steno_note_req notemode_duration {
742 $$ = get_note_element($1, $2);
744 | RESTNAME notemode_duration {
745 $$ = get_rest_element(*$1, $2);
751 mudela_text notemode_duration {
752 $$ = get_word_element($1, $2);
759 $$ = new Array<Melodic_req*>;
761 | pitch_list MELODIC_REQUEST_IDENTIFIER {
762 $$->push($2->request(false)->clone()->melodic());
769 if ( distance($1,Real(int($$)) ) > 1e-8)
770 error( "integer expected", lexer->here_ch_c_l() );
789 real unit { $$ = $1*$2; }
793 unit: CM_T { $$ = 1 CM; }
794 |IN_T { $$ = 1 INCH; }
803 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
811 $$ = new Lookup(*$1->lookup(true));
813 | symtables_body TEXID STRING {
814 $$->texsetting = *$3;
817 | symtables_body STRING '=' symtable {
824 TABLE '{' symtable_body '}' { $$ = $3; }
828 { $$ = new Symtable; }
829 | symtable_body STRING symboldef {
838 $$ = new Symbol(*$1, *$2);
844 $$ = new Symbol(*$1, b);
850 dinterval dinterval {
851 $$ = new Box(*$1, *$2);
858 $$ = new Interval($1, $2);
865 yyerror(const char *s)
867 lexer->LexerError(s);
870 exit( fatal_error_i );
874 parse_file(String init, String s)
876 *mlog << "Parsing ... ";
877 lexer = new My_flex_lexer;
880 yydebug = !monitor->silence("InitParser") && check_debug;
881 lexer->set_debug( !monitor->silence("InitLexer") && check_debug);
884 lexer->new_input(init);
888 if (!monitor->silence("InitDeclarations") && check_debug)
889 lexer->print_declarations();
891 yydebug = !monitor->silence("Parser") && check_debug;
892 lexer->set_debug( !monitor->silence("Lexer") && check_debug);
898 if (!monitor->silence("Declarations") && check_debug)
899 lexer->print_declarations();
904 if(!define_spots.empty())
905 warning("Braces don't match.",0);
911 return new Paper_def(
912 lexer->lookup_identifier("default_table")->lookup(true));