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 sstack<String> define_spots;
23 Paperdef*default_paper();
24 char const* defined_ch_c_l;
25 char const* req_defined_ch_c_l;
33 Input_command *command;
41 Music_general_chord *chord;
48 Array<String> * strvec;
49 Array<Input_command*> *commandvec;
54 Symtables * symtables;
60 Notename_tab *notename_tab;
65 %token VOICE STAFF SCORE TITLE BAR OUTPUT MULTIVOICE
66 %token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS COMMAND
67 %token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
68 %token KEY CLEF TABLE VOICES STEM
69 %token PARTIAL MUSIC GROUPING CADENZA
70 %token END SYMBOLTABLES TEXID TABLE NOTENAMES SCRIPT TEXTSTYLE PLET
73 %token <id> IDENTIFIER
74 %token <string> PITCHMOD DURATION RESTNAME
77 %token <string> STRING
81 %type <intvec> pitch_list
82 %type <c> open_request_parens close_request_parens
83 %type <id> declaration
84 %type <string> declarable_identifier
85 %type <paper> paper_block paper_body
87 %type <ii> default_duration explicit_duration notemode_duration mudela_duration
89 %type <moment> duration_length
90 %type <el> voice_elt full_element lyrics_elt
91 %type <command> score_command staff_command position_command
92 %type <score> score_block score_body
93 %type <staff> staff_block staff_init staff_body
95 %type <intvec> int_list intastint_list
96 %type <commandvec> score_commands_block score_commands_body
97 %type <commandvec> staff_commands_block staff_commands_body
98 %type <request> post_request pre_request
99 %type <string> pitchmod
101 %type <chord> music_chord music_chord_body
103 %type <mvoice> music_voice_body music_voice
105 %type <interval> dinterval
107 %type <symtable> symtable symtable_body
108 %type <lookup> symtables symtables_body
109 %type <symbol> symboldef
110 %type <notename_tab> notename_tab notename_tab_body
112 %type <script> script_definition script_body mudela_script
113 %type <request> script_req textscript_req
114 %type <textdef> mudela_text
120 | mudela score_block {
123 | mudela add_declaration { }
124 | mudela mudela_command {}
128 notename_tab { lexer->set($1); }
134 add_declaration: declaration {
135 lexer->add_identifier($1);
139 declarable_identifier:
141 | IDENTIFIER { $$ = new String($1->name); }
145 declarable_identifier '=' staff_block {
146 $$ = new Staff_id(*$1, $3);
147 delete $1; // this sux
149 | declarable_identifier '=' music_voice {
150 $$ = new M_voice_id(*$1, $3);
153 | declarable_identifier '=' script_definition {
154 $$ = new Script_id(*$1, $3);
157 | declarable_identifier '=' music_chord {
158 $$ = new M_chord_id(*$1, $3);
161 | declarable_identifier '=' symtables {
162 $$ = new Lookup_id(*$1, $3);
165 | declarable_identifier '=' notename_tab {
166 $$ = new Notetab_id(*$1, $3);
169 | declarable_identifier '=' real {
170 $$ = new Real_id(*$1, new Real($3));
173 | declarable_identifier error '}' {
174 warning( "parse error", lexer->here_ch_c_l() );
179 NOTENAMES '{' notename_tab_body '}' { $$ = $3; }
183 $$ = new Notename_tab;
186 $$ = $1->notename_tab(true);
188 | notename_tab_body STRING int int {
189 $$->set($3, $4, *$2);
198 { define_spots.push(lexer->spot()); }
201 $$->define_spot_str_ = define_spots.pop();
203 $$->paper_ = default_paper();
205 /* handle error levels. */
206 $$->errorlevel_i_ = lexer->errorlevel_i_;
207 lexer->errorlevel_i_ = 0;
212 $$ = new Input_score;
214 | score_body staff_block { $$->add($2); }
215 | score_body score_commands_block {
219 | score_body paper_block { $$->set($2); }
224 score_commands_block:
225 COMMANDS '{' score_commands_body '}' { $$ =$3;}
226 | COMMANDS '{' error '}' {
227 warning( "parse error", lexer->here_ch_c_l() );
231 score_commands_body: { $$ = new Array<Input_command*>; }
232 | score_commands_body score_command {
235 | score_commands_body position_command {
240 staff_commands_block: COMMANDS '{' staff_commands_body '}' {
245 /* empty */ { $$ = new Array<Input_command*>; }
246 | staff_commands_body staff_command {
249 | staff_commands_body position_command {
255 KEY pitch_list {/*UGH*/
256 $$ = get_key_interpret_command(*$2);
260 $$ = get_clef_interpret_command(*$2);
266 SKIP int ':' duration_length {
267 $$ = get_skip_command($2, *$4);
271 $$ = get_goto_command(*$2);
278 /* */ { $$ =new Array<int>; }
279 | intastint_list int '*' int {
280 $$->push($2); $$->push($4);
286 $$ = get_bar_command(*$2);
289 | METER int '*' int {
290 $$ = get_meterchange_command($2, $4);
292 | PARTIAL duration_length {
293 $$ = get_partial_command(*$2);
296 | GROUPING intastint_list {
297 $$ = get_grouping_command(*$2);
301 $$ = get_cadenza_toggle($2);
313 '{' paper_body '}' { $$ = $3; }
318 $$ = default_paper();
320 | paper_body WIDTH dim { $$->linewidth = $3;}
321 | paper_body OUTPUT STRING { $$->outfile = *$3;
324 | paper_body symtables { $$->set($2); }
325 | paper_body UNITSPACE dim { $$->whole_width = $3; }
326 | paper_body GEOMETRIC REAL { $$->geometric_ = $3; }
328 warning( "parse error", lexer->here_ch_c_l() );
336 STAFF { define_spots.push(lexer->spot()); }
337 /*cont*/ '{' staff_body '}' {
339 $$->define_spot_str_ = define_spots.pop();
346 IDENTIFIER { $$ = $1->staff(true); }
348 $$ = new Input_staff(*$1);
356 $2->set_default_group( "staff_music" + String($$->music_.size()));
359 | staff_body staff_commands_block {
364 warning( "parse error", lexer->here_ch_c_l() );
372 music_voice { $$ = $1; }
373 | music_chord { $$ = $1; }
376 music_voice: MUSIC '{' music_voice_body '}' { $$ = $3; }
381 $$ = new Music_voice;
383 | music_voice_body IDENTIFIER {
384 $$->concatenate($2->mvoice(true));
386 | music_voice_body full_element {
389 | music_voice_body voice_command {
391 | music_voice_body music {
394 | music_voice_body error {
395 warning( "parse error", lexer->here_ch_c_l() );
399 music_chord: '{' music_chord_body '}' { $$ = $2; }
404 $$ = new Voice_group_chord;
407 $$ = new Multi_voice_chord;
409 | music_chord_body IDENTIFIER {
410 $$->concatenate($2->mchord(true));
412 | music_chord_body music {
415 | music_chord_body full_element {
418 | music_chord_body error {
419 warning( "parse error", lexer->here_ch_c_l() );
428 full_element: pre_requests voice_elt post_requests {
429 add_requests($2, pre_reqs);
430 add_requests($2, post_reqs);
434 $$ = get_mark_element(*$2);
437 | COMMAND '{' staff_command '}' { $$=get_command_element($3); }
438 | COMMAND '{' score_command '}' { $$=get_command_element($3); }
439 | '|' { $$ = get_barcheck_element(); }
441 $$ = get_stemdir_element($3);
445 + | pre_requests voice_elt post_requests error '|' {
446 + warning( "parse error", lexer->here_ch_c_l() );
453 assert(post_reqs.empty());
455 | post_requests post_request {
461 close_request_parens {
462 $$ = get_request($1);
463 req_defined_ch_c_l = lexer->here_ch_c_l();
469 close_request_parens:
472 req_defined_ch_c_l = lexer->here_ch_c_l();
476 req_defined_ch_c_l = lexer->here_ch_c_l();
483 req_defined_ch_c_l = lexer->here_ch_c_l();
487 req_defined_ch_c_l = lexer->here_ch_c_l();
492 SCRIPT '{' script_body '}' { $$ = $3; }
497 $$ = new Script_def(*$1,$2, $3,$4);
503 script_dir mudela_text { $$ = get_text_req($1,$2); }
510 defined_ch_c_l = lexer->here_ch_c_l();
515 script_dir mudela_script { $$ = get_script_req($1, $2); }
519 IDENTIFIER { $$ = $1->script(true); }
520 | script_definition { $$ = $1; }
521 | '^' { $$ = get_scriptdef('^'); }
522 | '+' { $$ = get_scriptdef('+'); }
523 | '-' { $$ = get_scriptdef('-'); }
524 | '|' { $$ = get_scriptdef('|'); }
525 | 'o' { $$ = get_scriptdef('o'); }
526 | '>' { $$ = get_scriptdef('>'); }
527 | '.' { $$ = get_scriptdef('.'); }
530 warning( "too many staccato dots", lexer->here_ch_c_l() );
531 $$ = get_scriptdef('.');
542 | pre_requests pre_request {
548 open_request_parens {
549 $$ = get_request($1);
550 defined_ch_c_l = lexer->here_ch_c_l();
555 PLET '{' INT '/' INT '}' {
558 | DURATIONCOMMAND '{' STRING '}' {
559 set_duration_mode(*$3);
562 | DURATIONCOMMAND '{' notemode_duration '}' {
563 set_default_duration($3);
565 | OCTAVECOMMAND '{' pitchmod '}' {
566 set_default_octave(*$3);
577 $$ = new Moment(wholes($1[0], $1[1]));
579 |int '*' mudela_duration {
580 $$ = new Moment(Rational($1) * wholes($3[0], $3[1]));
613 get_default_duration($$);
620 get_default_duration($$);
626 defined_ch_c_l = lexer->here_ch_c_l();
630 defined_ch_c_l = lexer->here_ch_c_l();
639 pitchmod notename notemode_duration {
640 $$ = get_note_element(*$1, $2, $3);
643 | RESTNAME notemode_duration {
644 $$ = get_rest_element(*$1, $2);
651 mudela_text notemode_duration {
652 $$ = get_word_element($1, $2);
661 | pitch_list NOTENAME {
670 if ( distance($1,Real(int($$)) ) > 1e-8)
671 error( "integer expected", lexer->here_ch_c_l() );
698 real unit { $$ = convert_dimen($1,$2); }
702 unit: CM { $$ = "cm"; }
712 SYMBOLTABLES '{' symtables_body '}' { $$ = $3; }
720 $$ = new Lookup(*$1->lookup(true));
722 | symtables_body TEXID STRING {
723 $$->texsetting = *$3;
726 | symtables_body STRING '=' symtable {
733 TABLE '{' symtable_body '}' { $$ = $3; }
737 { $$ = new Symtable; }
738 | symtable_body STRING symboldef {
747 $$ = new Symbol(*$1, *$2);
753 $$ = new Symbol(*$1, b);
759 dinterval dinterval {
760 $$ = new Box(*$1, *$2);
767 $$ = new Interval($1, $2);
774 parse_file(String init, String s)
776 *mlog << "Parsing ... ";
777 lexer = new My_flex_lexer;
780 yydebug = !monitor.silence("InitParser") && check_debug;
781 lexer->set_debug( !monitor.silence("InitLexer") && check_debug);
784 lexer->new_input(init);
788 yydebug = !monitor.silence("Parser") && check_debug;
789 lexer->set_debug( !monitor.silence("Lexer") && check_debug);
797 assert(define_spots.empty());
804 lexer->lookup_identifier("default_table")->lookup(true));