1 %{ // -*-Fundamental-*-
8 #include "inputscore.hh"
11 #include "inputcommand.hh"
13 #include "parseconstruct.hh"
15 #include "identifier.hh"
21 Array<Request*> pre_reqs, post_reqs;
22 Array<const char *> define_spots;
23 Paperdef*default_paper();
24 char const* defined_ch_c_l;
25 char const* req_defined_ch_c_l;
26 int fatal_error_i = 0;
34 Input_command *command;
42 Music_general_chord *chord;
49 Array<String> * strvec;
50 Array<Input_command*> *commandvec;
55 Symtables * symtables;
61 Notename_tab *notename_tab;
66 %token VOICE STAFF SCORE TITLE BAR OUTPUT MULTIVOICE
67 %token CM_T IN_T PT_T MM_T PAPER WIDTH METER UNITSPACE SKIP COMMANDS COMMAND
68 %token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
69 %token KEY CLEF TABLE VOICES STEM
70 %token PARTIAL MUSIC GROUPING CADENZA
71 %token END SYMBOLTABLES TEXID TABLE NOTENAMES SCRIPT TEXTSTYLE PLET
74 %token <id> IDENTIFIER
75 %token <string> PITCHMOD DURATION RESTNAME
78 %token <string> STRING
82 %type <intvec> pitch_list
83 %type <c> open_request_parens close_request_parens
84 %type <id> declaration
85 %type <string> declarable_identifier
86 %type <paper> paper_block paper_body
88 %type <ii> default_duration explicit_duration notemode_duration mudela_duration
90 %type <moment> duration_length
91 %type <el> voice_elt full_element lyrics_elt
92 %type <command> score_command staff_command position_command
93 %type <score> score_block score_body
94 %type <staff> staff_block staff_init staff_body
96 %type <intvec> int_list intastint_list
97 %type <commandvec> score_commands_block score_commands_body
98 %type <commandvec> staff_commands_block staff_commands_body
99 %type <request> post_request pre_request
100 %type <string> pitchmod
102 %type <chord> music_chord music_chord_body
104 %type <mvoice> music_voice_body music_voice
106 %type <interval> dinterval
108 %type <symtable> symtable symtable_body
109 %type <lookup> symtables symtables_body
110 %type <symbol> symboldef
111 %type <notename_tab> notename_tab notename_tab_body
113 %type <script> script_definition script_body mudela_script
114 %type <request> script_req textscript_req
115 %type <textdef> mudela_text
121 | mudela score_block {
124 | mudela add_declaration { }
125 | mudela mudela_command {}
129 notename_tab { lexer->set($1); }
135 add_declaration: declaration {
136 lexer->add_identifier($1);
140 declarable_identifier:
142 | IDENTIFIER { $$ = new String($1->name); }
146 declarable_identifier '=' staff_block {
147 $$ = new Staff_id(*$1, $3);
148 delete $1; // this sux
150 | declarable_identifier '=' music_voice {
151 $$ = new M_voice_id(*$1, $3);
154 | declarable_identifier '=' script_definition {
155 $$ = new Script_id(*$1, $3);
158 | declarable_identifier '=' music_chord {
159 $$ = new M_chord_id(*$1, $3);
162 | declarable_identifier '=' symtables {
163 $$ = new Lookup_id(*$1, $3);
166 | declarable_identifier '=' notename_tab {
167 $$ = new Notetab_id(*$1, $3);
170 | declarable_identifier '=' real {
171 $$ = new Real_id(*$1, new Real($3));
174 | declarable_identifier error '}' {
175 // warning( "parse error", lexer->here_ch_c_l() );
180 NOTENAMES '{' notename_tab_body '}' { $$ = $3; }
184 $$ = new Notename_tab;
187 $$ = $1->notename_tab(true);
189 | notename_tab_body STRING int int {
190 $$->set($3, $4, *$2);
199 { define_spots.push(lexer->here_ch_c_l()); }
202 $$->defined_ch_c_l_ = define_spots.pop();
204 $$->paper_ = default_paper();
206 /* handle error levels. */
207 $$->errorlevel_i_ = lexer->errorlevel_i_;
208 lexer->errorlevel_i_ = 0;
213 $$ = new Input_score;
215 | score_body staff_block { $$->add($2); }
216 | score_body score_commands_block {
220 | score_body paper_block { $$->set($2); }
225 score_commands_block:
226 COMMANDS '{' score_commands_body '}' { $$ =$3;}
227 | COMMANDS '{' error '}' {
228 // warning( "parse error", lexer->here_ch_c_l() );
232 score_commands_body: { $$ = new Array<Input_command*>; }
233 | score_commands_body score_command {
236 | score_commands_body position_command {
241 staff_commands_block: COMMANDS '{' staff_commands_body '}' {
246 /* empty */ { $$ = new Array<Input_command*>; }
247 | staff_commands_body staff_command {
250 | staff_commands_body position_command {
256 KEY pitch_list {/*UGH*/
257 $$ = get_key_interpret_command(*$2);
261 $$ = get_clef_interpret_command(*$2);
267 SKIP int ':' duration_length {
268 $$ = get_skip_command($2, *$4);
272 $$ = get_goto_command(*$2);
279 /* */ { $$ =new Array<int>; }
280 | intastint_list int '*' int {
281 $$->push($2); $$->push($4);
287 $$ = get_bar_command(*$2);
290 | METER int '*' int {
291 $$ = get_meterchange_command($2, $4);
293 | PARTIAL duration_length {
294 $$ = get_partial_command(*$2);
297 | GROUPING intastint_list {
298 $$ = get_grouping_command(*$2);
302 $$ = get_cadenza_toggle($2);
314 '{' paper_body '}' { $$ = $3; }
319 $$ = default_paper();
321 | paper_body WIDTH dim { $$->linewidth = $3;}
322 | paper_body OUTPUT STRING { $$->outfile = *$3;
325 | paper_body symtables { $$->set($2); }
326 | paper_body UNITSPACE dim { $$->whole_width = $3; }
327 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
329 // warning( "parse error", lexer->here_ch_c_l() );
337 STAFF { define_spots.push(lexer->here_ch_c_l()); }
338 /*cont*/ '{' staff_body '}' {
340 $$-> defined_ch_c_l_ = define_spots.pop();
347 IDENTIFIER { $$ = $1->staff(true); }
349 $$ = new Input_staff(*$1);
357 $2->set_default_group( "staff_music" + String($$->music_.size()));
360 | staff_body staff_commands_block {
365 // warning( "parse error", lexer->here_ch_c_l() );
373 music_voice { $$ = $1; }
374 | music_chord { $$ = $1; }
377 music_voice: MUSIC '{' music_voice_body '}' { $$ = $3; }
382 $$ = new Music_voice;
384 | music_voice_body IDENTIFIER {
385 $$->concatenate($2->mvoice(true));
387 | music_voice_body full_element {
390 | music_voice_body voice_command {
392 | music_voice_body music {
395 | music_voice_body error {
396 // warning( "parse error", lexer->here_ch_c_l() );
400 music_chord: '{' music_chord_body '}' { $$ = $2; }
405 $$ = new Voice_group_chord;
408 $$ = new Multi_voice_chord;
410 | music_chord_body IDENTIFIER {
411 $$->concatenate($2->mchord(true));
413 | music_chord_body music {
416 | music_chord_body full_element {
419 | music_chord_body error {
420 // warning( "parse error", lexer->here_ch_c_l() );
429 full_element: pre_requests voice_elt post_requests {
430 add_requests($2, pre_reqs);
431 add_requests($2, post_reqs);
435 $$ = get_mark_element(*$2);
438 | COMMAND '{' staff_command '}' { $$=get_command_element($3); }
439 | COMMAND '{' score_command '}' { $$=get_command_element($3); }
441 req_defined_ch_c_l = lexer->here_ch_c_l();
442 $$ = get_barcheck_element();
445 req_defined_ch_c_l = lexer->here_ch_c_l();
446 $$ = get_stemdir_element($3);
450 + | pre_requests voice_elt post_requests error '|' {
451 + warning( "parse error", lexer->here_ch_c_l() );
458 assert(post_reqs.empty());
460 | post_requests post_request {
466 close_request_parens {
467 req_defined_ch_c_l = lexer->here_ch_c_l();
468 $$ = get_request($1);
474 close_request_parens:
476 req_defined_ch_c_l = lexer->here_ch_c_l();
480 req_defined_ch_c_l = lexer->here_ch_c_l();
487 req_defined_ch_c_l = lexer->here_ch_c_l();
491 req_defined_ch_c_l = lexer->here_ch_c_l();
497 SCRIPT '{' script_body '}' { $$ = $3; }
502 $$ = new Script_def(*$1,$2, $3,$4);
508 script_dir mudela_text { $$ = get_text_req($1,$2); }
513 defined_ch_c_l = lexer->here_ch_c_l();
520 script_dir mudela_script {
521 $$ = get_script_req($1, $2);
526 IDENTIFIER { $$ = $1->script(true); }
527 | script_definition { $$ = $1; }
528 | '^' { $$ = get_scriptdef('^'); }
529 | '+' { $$ = get_scriptdef('+'); }
530 | '-' { $$ = get_scriptdef('-'); }
531 | '|' { $$ = get_scriptdef('|'); }
532 | 'o' { $$ = get_scriptdef('o'); }
533 | '>' { $$ = get_scriptdef('>'); }
534 | '.' { $$ = get_scriptdef('.'); }
537 warning( "too many staccato dots", lexer->here_ch_c_l() );
538 $$ = get_scriptdef('.');
541 $$ = get_scriptdef('.');
553 | pre_requests pre_request {
559 open_request_parens {
560 defined_ch_c_l = lexer->here_ch_c_l();
561 $$ = get_request($1);
566 PLET '{' INT '/' INT '}' {
569 | DURATIONCOMMAND '{' STRING '}' {
570 set_duration_mode(*$3);
573 | DURATIONCOMMAND '{' notemode_duration '}' {
574 set_default_duration($3);
576 | OCTAVECOMMAND '{' pitchmod '}' {
577 set_default_octave(*$3);
588 $$ = new Moment(wholes($1[0], $1[1]));
590 |int '*' mudela_duration {
591 $$ = new Moment(Rational($1) * wholes($3[0], $3[1]));
624 get_default_duration($$);
631 get_default_duration($$);
636 defined_ch_c_l = lexer->here_ch_c_l();
640 defined_ch_c_l = lexer->here_ch_c_l();
650 pitchmod notename notemode_duration {
651 $$ = get_note_element(*$1, $2, $3);
654 | RESTNAME notemode_duration {
655 $$ = get_rest_element(*$1, $2);
662 mudela_text notemode_duration {
663 $$ = get_word_element($1, $2);
672 | pitch_list NOTENAME {
681 if ( distance($1,Real(int($$)) ) > 1e-8)
682 error( "integer expected", lexer->here_ch_c_l() );
709 real unit { $$ = $1*$2; }
713 unit: CM_T { $$ = 1 CM; }
714 |IN_T { $$ = 1 INCH; }
723 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
731 $$ = new Lookup(*$1->lookup(true));
733 | symtables_body TEXID STRING {
734 $$->texsetting = *$3;
737 | symtables_body STRING '=' symtable {
744 TABLE '{' symtable_body '}' { $$ = $3; }
748 { $$ = new Symtable; }
749 | symtable_body STRING symboldef {
758 $$ = new Symbol(*$1, *$2);
764 $$ = new Symbol(*$1, b);
770 dinterval dinterval {
771 $$ = new Box(*$1, *$2);
778 $$ = new Interval($1, $2);
785 yyerror(const char *s)
787 // if ( YYRECOVERING() )
789 lexer->LexerError(s);
792 exit( fatal_error_i );
796 parse_file(String init, String s)
798 *mlog << "Parsing ... ";
799 lexer = new My_flex_lexer;
802 yydebug = !monitor.silence("InitParser") && check_debug;
803 lexer->set_debug( !monitor.silence("InitLexer") && check_debug);
806 lexer->new_input(init);
810 yydebug = !monitor.silence("Parser") && check_debug;
811 lexer->set_debug( !monitor.silence("Lexer") && check_debug);
819 assert(define_spots.empty());
826 lexer->lookup_identifier("default_table")->lookup(true));