X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=dfbe3dfc32118fcab336f3b7680a54f662398258;hb=5cc390968095201b69f142ad01842ac3f08144a2;hp=239b8f68f18446b0a09517a9e8568040c35bc4da;hpb=d6ea2dbcdb39dd65c7fd423782fa31ccbdaf34a9;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index 239b8f68f1..dfbe3dfc32 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -5,12 +5,12 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2003 Han-Wen Nienhuys + (c) 1997--2004 Han-Wen Nienhuys Jan Nieuwenhuizen */ /* - Two shift/reduce problems: + Four shift/reduce problems: 1. foo = bar. @@ -19,6 +19,12 @@ "bar" -> String -> string-assignment +Similar problem for + + * \markup identifier. + * \markup { } + + 2. \repeat \repeat .. \alternative @@ -48,10 +54,11 @@ TODO: #include #include +#include #include "scm-option.hh" -#include "translator-def.hh" +#include "context-def.hh" #include "lily-guile.hh" #include "misc.hh" #include "my-lily-lexer.hh" @@ -67,7 +74,6 @@ TODO: #include "input.hh" #include "lilypond-input-version.hh" #include "scm-hash.hh" -#include "auto-change-iterator.hh" #include "ly-modules.hh" #include "music-sequence.hh" #include "input-smob.hh" @@ -75,10 +81,11 @@ TODO: #include "text-item.hh" #include "music-list.hh" - #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x)) - +Music *property_op_to_music (SCM op); +Music *context_spec_music (SCM type, SCM id, Music * m, SCM ops_); +SCM get_next_unique_context (); #define YYERROR_VERBOSE 1 @@ -90,7 +97,23 @@ My_lily_parser* my_lily_parser; #define yyerror THIS->parser_error +/* + Add symbols to the TAGS field of a music object. +*/ +void +tag_music (Music*m, SCM tag, Input ip) +{ + SCM tags = m->get_mus_property ("tags"); + if (gh_symbol_p (tag)) + tags = scm_cons (tag, tags); + else if (gh_list_p (tag)) + tags = gh_append2 (tag, tags); + else + ip.warning (_("Tag must be symbol or list of symbols.")); + + m->set_mus_property ("tags", tags); +} @@ -139,10 +162,11 @@ SCM make_chord_step (int step, int alter) { if (step == 7) - alter--; + alter += FLAT; - /* ugh: fucks up above 13 */ - Pitch m(step > 7 ? 1 : 0,(step - 1) % 7, alter); + while(step < 0) + step += 7; + Pitch m((step -1) / 7 , (step - 1) % 7, alter); return m.smobbed_copy (); } @@ -213,6 +237,7 @@ yylex (YYSTYPE *s, void * v) %token ACCEPTS %token ADDLYRICS +%token NEWADDLYRICS %token ALIAS %token ALTERNATIVE %token APPLY @@ -221,10 +246,11 @@ yylex (YYSTYPE *s, void * v) %token AUTOCHANGE %token BAR %token BREATHE +%token CHANGE %token CHORDMODIFIERS %token CHORDS -%token CHORD_CLOSE -%token CHORD_OPEN +%token LESSLESS +%token MOREMORE %token CLEF %token COMMANDSPANREQUEST %token CONSISTS @@ -233,11 +259,12 @@ yylex (YYSTYPE *s, void * v) %token DEFAULT %token DENIES %token DESCRIPTION -%token DURATION %token EXTENDER %token FIGURES FIGURE_OPEN FIGURE_CLOSE %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN %token GRACE +%token ACCIACCATURA +%token APPOGGIATURA %token GROBDESCRIPTIONS %token HEADER %token HYPHEN @@ -252,13 +279,10 @@ yylex (YYSTYPE *s, void * v) %token NOTES %token OCTAVE %token ONCE -%token OUTPUTPROPERTY %token OVERRIDE SET REVERT %token PAPER %token PARTCOMBINE %token PARTIAL -%token PITCH -%token PITCHNAMES %token PROPERTY %token RELATIVE %token REMOVE @@ -270,6 +294,7 @@ yylex (YYSTYPE *s, void * v) %token SIMULTANEOUS %token SKIP %token SPANREQUEST +%token TAG %token TEMPO %token TIMES %token TIME_T @@ -277,7 +302,7 @@ yylex (YYSTYPE *s, void * v) %token TRANSPOSE %token TYPE %token UNSET - +%token WITH /* escaped */ %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE @@ -289,6 +314,10 @@ yylex (YYSTYPE *s, void * v) %type exclamations questions dots optional_rest %type bass_mod +%type grace_head +%type oct_check +%type context_mod_list +%type lyric_element %type bass_number br_bass_figure bass_figure figure_list figure_spec %token DIGIT %token NOTENAME_PITCH @@ -297,10 +326,9 @@ yylex (YYSTYPE *s, void * v) %token DURATION_IDENTIFIER %token FRACTION %token IDENTIFIER -%token CHORDNAMES - -%token CHORD_MODIFIER - +%token DRUMS +%token DRUM_PITCH +%token CHORD_MODIFIER %token SCORE_IDENTIFIER %token MUSIC_OUTPUT_DEF_IDENTIFIER %token NUMBER_IDENTIFIER @@ -315,6 +343,7 @@ yylex (YYSTYPE *s, void * v) %token MARKUP %token MARKUP_HEAD_MARKUP0 +%token MARKUP_HEAD_EMPTY %token MARKUP_HEAD_MARKUP0_MARKUP1 %token MARKUP_HEAD_SCM0 %token MARKUP_HEAD_SCM0_MARKUP1 @@ -340,34 +369,30 @@ yylex (YYSTYPE *s, void * v) %type note_chord_element chord_body chord_body_element %type chord_body_elements %type steno_duration optional_notemode_duration multiplied_duration -%type verbose_duration -%type post_events +%type post_events %type gen_text_def direction_less_event direction_reqd_event %type steno_pitch pitch absolute_pitch pitch_also_in_chords -%type explicit_pitch steno_tonic_pitch +%type steno_tonic_pitch %type duration_length fraction %type new_chord step_number chord_items chord_item chord_separator step_numbers %type embedded_scm scalar %type Music Sequential_music Simultaneous_music -%type relative_music re_rhythmed_music part_combined_music -%type property_def translator_change simple_property_def +%type relative_music re_rhythmed_music +%type music_property_def context_change %type Music_list -%type music_output_def_body -%type shorthand_command_req -%type post_event -%type command_req verbose_command_req -%type extender_req -%type hyphen_req +%type property_operation context_mod translator_mod optional_context_mod +%type music_output_def_body music_output_def_head +%type post_event tagged_post_event +%type command_req %type string_number_event %type string bare_number number_expression number_term number_factor %type score_block score_body %type translator_spec_block translator_spec_body %type tempo_event -%type notenames_body notenames_block chordmodifiers_block %type script_abbreviation @@ -393,23 +418,49 @@ lilypond: /* empty */ ; toplevel_expression: - notenames_block { - THIS->lexer_->pitchname_tab_ = $1; - } - | chordmodifiers_block { - THIS->lexer_->chordmodifier_tab_ = $1; - } - | lilypond_header { + lilypond_header { THIS->input_file_->header_ = $1; } | score_block { - THIS->input_file_->scores_.push ($1); + Score * sc = $1; + + SCM head = ly_module_p (sc->header_) ? sc->header_ : THIS->input_file_->header_.to_SCM (); + + Path p = split_path (THIS->output_basename_); + int *c = &THIS->input_file_->score_count_; + if (*c) + { + p.base += "-" + to_string (*c); + } + + (*c)++; + SCM outname = scm_makfrom0str (p.to_string ().to_str0()); + + for (int i=0; i < sc->defs_.size (); i++) + default_rendering (sc->music_, sc->defs_[i]->self_scm(),head, outname); + + if (sc->defs_.is_empty ()) + { + Music_output_def *id = + unsmob_music_output_def (THIS->lexer_->lookup_identifier + ("$defaultpaper")); + + id = id ? id->clone () : new Paper_def; + + default_rendering (sc->music_, id->self_scm(), head, outname); + + scm_gc_unprotect_object (id->self_scm ()); + } + scm_gc_unprotect_object (sc->self_scm()); } | output_def { + SCM id = SCM_EOL; if (dynamic_cast ($1)) - THIS->lexer_->set_identifier (scm_makfrom0str ("$defaultpaper"), $1->self_scm ()); + id = scm_makfrom0str ("$defaultpaper"); else if (dynamic_cast ($1)) - THIS->lexer_->set_identifier (scm_makfrom0str ("$defaultmidi"), $1->self_scm ()); + id = scm_makfrom0str ("$defaultmidi"); + THIS->lexer_->set_identifier (id, $1->self_scm ()); + scm_gc_unprotect_object ($1->self_scm ()); } ; @@ -419,26 +470,7 @@ embedded_scm: ; -chordmodifiers_block: - CHORDMODIFIERS notenames_body { $$ = $2; } - ; - -notenames_block: - PITCHNAMES notenames_body { $$ = $2; } - ; -notenames_body: - embedded_scm { - int i = scm_ilength ($1); - - SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL); - for (SCM s = $1; gh_pair_p (s); s = ly_cdr (s)) { - SCM pt = ly_cdar (s); - scm_hashq_set_x (tab, ly_caar (s), pt); - } - $$ = tab; - } - ; lilypond_header_body: { @@ -490,7 +522,6 @@ all objects can be unprotected as soon as they're here. ; - identifier_init: score_block { $$ = $1->self_scm (); @@ -514,9 +545,6 @@ identifier_init: $$ = $1->self_scm (); scm_gc_unprotect_object ($$); } - | verbose_duration { - $$ = $1; - } | number_expression { $$ = $1; } @@ -536,61 +564,27 @@ translator_spec_block: ; translator_spec_body: - TRANSLATOR_IDENTIFIER { - $$ = $1; - unsmob_translator_def ($$)-> set_spot (THIS->here_input ()); - } - | TYPE STRING { - $$ = Translator_def::make_scm (); - Translator_def*td = unsmob_translator_def ($$); - td->translator_group_type_ = $2; - td->set_spot (THIS->here_input ()); - } - | translator_spec_body DESCRIPTION string { - unsmob_translator_def ($$)->description_ = $3; - } - | translator_spec_body STRING '=' embedded_scm { - unsmob_translator_def ($$)->add_property_assign ($2, $4); - } - | translator_spec_body STRING OVERRIDE embedded_scm '=' embedded_scm { - unsmob_translator_def ($$) - ->add_push_property (scm_string_to_symbol ($2), $4, $6); - } - | translator_spec_body STRING SET embedded_scm '=' embedded_scm { - unsmob_translator_def ($$) - ->add_push_property (scm_string_to_symbol ($2), $4, $6); - } - | translator_spec_body STRING REVERT embedded_scm { - unsmob_translator_def ($$)->add_pop_property ( - scm_string_to_symbol ($2), $4); - } - | translator_spec_body NAME STRING { - unsmob_translator_def ($$)->type_name_ = $3; - } - | translator_spec_body CONSISTS STRING { - unsmob_translator_def ($$)->add_element ($3); + /**/ { + $$ = Context_def::make_scm (); + unsmob_context_def ($$)->set_spot (THIS->here_input ()); } - | translator_spec_body ALIAS STRING { - Translator_def*td = unsmob_translator_def ($$); - td->type_aliases_ = scm_cons ($3, td->type_aliases_); + | TRANSLATOR_IDENTIFIER { + $$ = $1; + unsmob_context_def ($$)->set_spot (THIS->here_input ()); } | translator_spec_body GROBDESCRIPTIONS embedded_scm { - Translator_def*td = unsmob_translator_def($$); - // td->add_property_assign (ly_symbol2scm ("allGrobDescriptions"), $3); - for (SCM p = $3; gh_pair_p (p); p = ly_cdr (p)) - td->add_property_assign (scm_symbol_to_string (ly_caar (p)), ly_cdar (p)); - } - | translator_spec_body CONSISTSEND STRING { - unsmob_translator_def ($$)->add_last_element ( $3); - } - | translator_spec_body ACCEPTS STRING { - unsmob_translator_def ($$)->set_acceptor ($3,true); - } - | translator_spec_body DENIES STRING { - unsmob_translator_def ($$)->set_acceptor ($3,false); + Context_def*td = unsmob_context_def($$); + + for (SCM p = $3; gh_pair_p (p); p = ly_cdr (p)) { + SCM tag = gh_caar (p); + + /* TODO: should make new tag "grob-definition" ? */ + td->add_context_mod (scm_list_n (ly_symbol2scm ("assign"), + tag, gh_cons (ly_cdar (p), SCM_EOL), SCM_UNDEFINED)); + } } - | translator_spec_body REMOVE STRING { - unsmob_translator_def ($$)->remove_element ($3); + | translator_spec_body context_mod { + unsmob_context_def ($$)->add_context_mod ($2); } ; @@ -604,12 +598,7 @@ score_block: /*cont*/ '{' score_body '}' { THIS->pop_spot (); $$ = $4; - if (!$$->defs_.size ()) - { - Music_output_def *id = - unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper")); - $$->add_output (id ? id->clone () : new Paper_def ); - } + } ; @@ -631,14 +620,15 @@ score_body: } | SCORE_IDENTIFIER { - $$ = unsmob_score ($1); + $$ = new Score ( *unsmob_score ($1)); $$->set_spot (THIS->here_input ()); } | score_body lilypond_header { $$->header_ = $2; } | score_body output_def { - $$->add_output ($2); + $$->defs_.push ($2); + scm_gc_unprotect_object ($2->self_scm ()); } | score_body error { @@ -656,8 +646,8 @@ output_def: } ; -music_output_def_body: - MIDI '{' { +music_output_def_head: + MIDI { Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultmidi")); @@ -670,7 +660,7 @@ music_output_def_body: $$ = p; THIS->lexer_->add_scope (p->scope_); } - | PAPER '{' { + | PAPER { Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper")); Paper_def *p = 0; if (id) @@ -681,16 +671,18 @@ music_output_def_body: THIS->lexer_->add_scope (p->scope_); $$ = p; } - | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER { - Music_output_def * o = unsmob_music_output_def ($3); - $$ =o; + ; - THIS->lexer_->add_scope (o->scope_); + +music_output_def_body: + music_output_def_head '{' { + } - | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER { + | music_output_def_head '{' MUSIC_OUTPUT_DEF_IDENTIFIER { + scm_gc_unprotect_object ($1->self_scm ()); Music_output_def * o = unsmob_music_output_def ($3); $$ = o; - + THIS->lexer_->remove_scope (); THIS->lexer_->add_scope (o->scope_); } | music_output_def_body assignment { @@ -709,6 +701,7 @@ music_output_def_body: Midi_def * md = dynamic_cast ($$); if (md) md->set_tempo (d->get_length (), m); + scm_gc_unprotect_object ($2->self_scm ()); } | music_output_def_body error { @@ -843,7 +836,7 @@ Simultaneous_music: $$->set_spot(THIS->here_input()); } - | '<' Music_list '>' { + | simul_open Music_list simul_close { $$ = MY_MAKE_MUSIC("SimultaneousMusic"); $$->set_mus_property ("elements", ly_car ($2)); $$->set_spot(THIS->here_input()); @@ -866,65 +859,77 @@ Simple_music: $$->set_mus_property ("procedure", $2); $$->set_spot (THIS->here_input()); } - | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm { - SCM pred = $2; - if (!gh_symbol_p ($3)) - { - THIS->parser_error (_ ("Second argument must be a symbol")); - } - /* Should check # args */ - if (!gh_procedure_p (pred)) - { - THIS->parser_error (_ ("First argument must be a procedure taking one argument")); - } - - Music*m = MY_MAKE_MUSIC("OutputPropertySetMusic"); - m->set_mus_property ("predicate", pred); - m->set_mus_property ("grob-property", $3); - m->set_mus_property ("grob-value", $5); - - $$ = m; - } | MUSIC_IDENTIFIER { $$ = unsmob_music ($1); } - | property_def - | translator_change + | music_property_def + | context_change ; -Composite_music: - CONTEXT STRING Music { - Music*csm =MY_MAKE_MUSIC("ContextSpeccedMusic"); +optional_context_mod: + /**/ { $$ = SCM_EOL; } + | WITH '{' context_mod_list '}' { $$ = $3; } + ; - csm->set_mus_property ("element", $3->self_scm ()); - scm_gc_unprotect_object ($3->self_scm ()); +grace_head: + GRACE { $$ = scm_makfrom0str ("Grace"); } + | ACCIACCATURA { $$ = scm_makfrom0str ("Acciaccatura"); } + | APPOGGIATURA { $$ = scm_makfrom0str ("Appoggiatura"); } + ; - csm->set_mus_property ("context-type",$2); - csm->set_mus_property ("context-id", scm_makfrom0str ("")); +context_mod_list: + /* */ { $$ = SCM_EOL; } + | context_mod_list context_mod { + $$ = gh_cons ($2, $1); + } + ; - $$ = csm; +Composite_music: + AUTOCHANGE Music { + static SCM proc ; + if (!proc) + proc = scm_c_eval_string ("make-autochange-music"); + + SCM res = scm_call_1 (proc, $2->self_scm ()); + scm_gc_unprotect_object ($2->self_scm ()); + $$ = unsmob_music (res); + scm_gc_protect_object (res); + $$->set_spot (THIS->here_input()); } - | AUTOCHANGE STRING Music { - Music*chm = MY_MAKE_MUSIC("AutoChangeMusic"); - chm->set_mus_property ("element", $3->self_scm ()); - chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_proc); + | PARTCOMBINE Music Music { + static SCM proc; + if (!proc) + proc = scm_c_eval_string ("make-part-combine-music"); + SCM res = scm_call_1 (proc, gh_list ($2->self_scm (), + $3->self_scm (), SCM_UNDEFINED)); scm_gc_unprotect_object ($3->self_scm ()); - chm->set_mus_property ("what", $2); - - $$ = chm; - chm->set_spot (*$3->origin ()); + scm_gc_unprotect_object ($2->self_scm ()); + $$ = unsmob_music (res); + scm_gc_protect_object (res); + $$->set_spot (THIS->here_input()); } - | GRACE Music { + | grace_head Music { #if 1 /* The other version is for easier debugging of Sequential_music_iterator in combination with grace notes. */ - SCM start = THIS->lexer_->lookup_identifier ("startGraceMusic"); - SCM stop = THIS->lexer_->lookup_identifier ("stopGraceMusic"); +/* + +TODO: should distinguish between both grace types in the +basic music objects too, since the meaning is different. + +*/ + + String start_str = "start" + ly_scm2string ($1) + "Music"; + String stop_str = "stop" + ly_scm2string ($1) + "Music"; + + SCM start = THIS->lexer_->lookup_identifier (start_str); + SCM stop = THIS->lexer_->lookup_identifier (stop_str); + Music *startm = unsmob_music (start); Music *stopm = unsmob_music (stop); @@ -942,7 +947,6 @@ Composite_music: scm_gc_unprotect_object (startm->self_scm ()); } - Music* seq = MY_MAKE_MUSIC("SequentialMusic"); seq->set_mus_property ("elements", ms); @@ -956,32 +960,18 @@ Composite_music: scm_gc_unprotect_object ($2->self_scm ()); #endif } - | CONTEXT string '=' string Music { - Music * csm = MY_MAKE_MUSIC("ContextSpeccedMusic"); - - csm->set_mus_property ("element", $5->self_scm ()); - scm_gc_unprotect_object ($5->self_scm ()); + | CONTEXT string '=' string optional_context_mod Music { + $$ = context_spec_music ($2, $4, $6, $5); - csm->set_mus_property ("context-type", $2); - csm->set_mus_property ("context-id", $4); - - $$ = csm; } - | NEWCONTEXT string Music { - static int new_context_count; - - Music * csm = MY_MAKE_MUSIC("ContextSpeccedMusic"); - - csm->set_mus_property ("element", $3->self_scm ()); - scm_gc_unprotect_object ($3->self_scm ()); - - csm->set_mus_property ("context-type", $2); - - SCM new_id = scm_number_to_string (gh_int2scm (new_context_count ++), - gh_int2scm (10)); - csm->set_mus_property ("context-id", new_id); - $$ = csm; + | CONTEXT STRING optional_context_mod Music { + $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3); + } + | NEWCONTEXT string optional_context_mod Music { + $$ = context_spec_music ($2, get_next_unique_context (), + $4, $3); } + | TIMES { THIS->push_spot (); } @@ -991,9 +981,9 @@ Composite_music: { int n = gh_scm2int (ly_car ($3)); int d = gh_scm2int (ly_cdr ($3)); Music *mp = $4; - $$= MY_MAKE_MUSIC("TimeScaledMusic"); - $$->set_spot (THIS->pop_spot ()); + $$= MY_MAKE_MUSIC("TimeScaledMusic"); + $$->set_spot (THIS->pop_spot ()); $$->set_mus_property ("element", mp->self_scm ()); scm_gc_unprotect_object (mp->self_scm ()); @@ -1017,18 +1007,35 @@ Composite_music: } | APPLY embedded_scm Music { if (!ly_input_procedure_p ($2)) + { THIS->parser_error (_ ("\\apply takes function argument")); - - SCM ret = gh_call1 ($2, $3->self_scm ()); - Music *m = unsmob_music (ret); - if (!m) { - THIS->parser_error ("\\apply must return a Music"); - m = MY_MAKE_MUSIC("Music"); + $$ = $3; + } + else + { + SCM ret = gh_call1 ($2, $3->self_scm ()); + Music *m = unsmob_music (ret); + if (!m) { + THIS->parser_error ("\\apply must return a Music"); + m = MY_MAKE_MUSIC("Music"); + } + $$ = m; } - $$ = m; } | NOTES - { THIS->lexer_->push_note_state (); } + { + SCM nn = THIS->lexer_->lookup_identifier ("pitchnames"); + THIS->lexer_->push_note_state (alist_to_hashq (nn)); + } + Music + { $$ = $3; + THIS->lexer_->pop_state (); + } + | DRUMS + { + SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames"); + THIS->lexer_->push_note_state (alist_to_hashq (nn)); + } Music { $$ = $3; THIS->lexer_->pop_state (); @@ -1044,10 +1051,13 @@ Composite_music: THIS->lexer_->pop_state (); } - | CHORDS - { THIS->lexer_->push_chord_state (); } - Music - { + | CHORDS { + SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers"); + THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn); + nn = THIS->lexer_->lookup_identifier ("pitchnames"); + THIS->lexer_->push_chord_state (alist_to_hashq (nn)); + + } Music { Music * chm = MY_MAKE_MUSIC("UnrelativableMusic"); chm->set_mus_property ("element", $3->self_scm ()); scm_gc_unprotect_object ($3->self_scm()); @@ -1064,7 +1074,10 @@ Composite_music: } | relative_music { $$ = $1; } | re_rhythmed_music { $$ = $1; } - | part_combined_music { $$ = $1; } + | TAG embedded_scm Music { + tag_music ($3, $2, THIS->here_input ()); + $$ = $3; + } ; relative_music: @@ -1077,9 +1090,9 @@ relative_music: scm_gc_unprotect_object (p->self_scm ()); + Pitch retpitch = p->to_relative_octave (pit); if (lily_1_8_relative) - $$->set_mus_property ("last-pitch", p->to_relative_octave (pit).smobbed_copy ()); - + $$->set_mus_property ("last-pitch", retpitch.smobbed_copy ()); } ; @@ -1091,25 +1104,19 @@ re_rhythmed_music: scm_gc_unprotect_object ($2->self_scm ()); $$ = l; } - ; - -part_combined_music: - PARTCOMBINE STRING Music Music { - Music * p= MY_MAKE_MUSIC("PartCombineMusic"); - p->set_mus_property ("what", $2); - p->set_mus_property ("elements", gh_list ($3->self_scm (),$4->self_scm (), SCM_UNDEFINED)); - - scm_gc_unprotect_object ($3->self_scm ()); - scm_gc_unprotect_object ($4->self_scm ()); - - $$ = p; + | NEWADDLYRICS string Music { + Music*l =MY_MAKE_MUSIC("NewLyricCombineMusic"); + l->set_mus_property ("element", $3->self_scm ()); + scm_gc_unprotect_object ($3->self_scm ()); + $$ = l; + l->set_mus_property ("associated-context", $2); } ; -translator_change: - TRANSLATOR STRING '=' STRING { +context_change: + CHANGE STRING '=' STRING { Music*t= MY_MAKE_MUSIC("TranslatorChange"); - t-> set_mus_property ("change-to-type", $2); + t-> set_mus_property ("change-to-type", scm_string_to_symbol ($2)); t-> set_mus_property ("change-to-id", $4); $$ = t; @@ -1117,114 +1124,67 @@ translator_change: } ; -property_def: - simple_property_def - | ONCE simple_property_def { - $$ = $2; - SCM e = $2->get_mus_property ("element"); - unsmob_music (e)->set_mus_property ("once", SCM_BOOL_T); +property_operation: + STRING '=' scalar { + $$ = scm_list_n (ly_symbol2scm ("assign"), + scm_string_to_symbol ($1), $3, SCM_UNDEFINED); } - ; - -simple_property_def: - PROPERTY STRING '.' STRING '=' scalar { - Music *t = set_property_music (scm_string_to_symbol ($4), $6); - Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic"); - - csm->set_mus_property ("element", t->self_scm ()); - scm_gc_unprotect_object (t->self_scm ()); - - $$ = csm; - $$->set_spot (THIS->here_input ()); - - csm-> set_mus_property ("context-type", $2); + | STRING UNSET { + $$ = scm_list_n (ly_symbol2scm ("unset"), + scm_string_to_symbol ($1), SCM_UNDEFINED); } - | PROPERTY STRING '.' STRING UNSET { - - Music *t = MY_MAKE_MUSIC("PropertyUnset"); - t->set_mus_property ("symbol", scm_string_to_symbol ($4)); - - Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic"); - csm->set_mus_property ("element", t->self_scm ()); - scm_gc_unprotect_object (t->self_scm ()); - - $$ = csm; - $$->set_spot (THIS->here_input ()); - - csm-> set_mus_property ("context-type", $2); + | STRING SET embedded_scm '=' embedded_scm { + $$ = scm_list_n (ly_symbol2scm ("poppush"), + scm_string_to_symbol ($1), $3, $5, SCM_UNDEFINED); } - | PROPERTY STRING '.' STRING SET embedded_scm '=' embedded_scm { - bool autobeam - = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings")); - bool itc = internal_type_checking_global_b; - Music *t = MY_MAKE_MUSIC("OverrideProperty"); - t->set_mus_property ("symbol", scm_string_to_symbol ($4)); - t->set_mus_property ("pop-first", SCM_BOOL_T); - if (autobeam) - internal_type_checking_global_b = false; - t->set_mus_property ("grob-property", $6); - if (autobeam) - internal_type_checking_global_b = itc; - t->set_mus_property ("grob-value", $8); - - Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic"); - csm->set_mus_property ("element", t->self_scm ()); - scm_gc_unprotect_object (t->self_scm ()); - $$ = csm; - $$->set_spot (THIS->here_input ()); - - csm-> set_mus_property ("context-type", $2); + | STRING OVERRIDE embedded_scm '=' embedded_scm { + $$ = scm_list_n (ly_symbol2scm ("push"), + scm_string_to_symbol ($1), $3, $5, SCM_UNDEFINED); } - | PROPERTY STRING '.' STRING OVERRIDE - embedded_scm '=' embedded_scm - { - /* - UGH UGH UGH UGH. - */ - bool autobeam - = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings")); - bool itc = internal_type_checking_global_b; - - Music *t = MY_MAKE_MUSIC("OverrideProperty"); - t->set_mus_property ("symbol", scm_string_to_symbol ($4)); - if (autobeam) - internal_type_checking_global_b = false; - t->set_mus_property ("grob-property", $6); - t->set_mus_property ("grob-value", $8); - if (autobeam) - internal_type_checking_global_b = itc; + | STRING REVERT embedded_scm { + $$ = scm_list_n (ly_symbol2scm ("pop"), + scm_string_to_symbol ($1), $3, SCM_UNDEFINED); + } + ; - Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic"); - csm->set_mus_property ("element", t->self_scm ()); - scm_gc_unprotect_object (t->self_scm ()); +translator_mod: + CONSISTSEND { $$ = ly_symbol2scm ("consists-end"); } + | CONSISTS { $$ = ly_symbol2scm ("consists"); } + | REMOVE { $$ = ly_symbol2scm ("remove"); } - $$ = csm; - $$->set_spot (THIS->here_input ()); + | ACCEPTS { $$ = ly_symbol2scm ("accepts"); } + | DENIES { $$ = ly_symbol2scm ("denies"); } - csm-> set_mus_property ("context-type", $2); + | ALIAS { $$ = ly_symbol2scm ("alias"); } + | TYPE { $$ = ly_symbol2scm ("translator-type"); } + | DESCRIPTION { $$ = ly_symbol2scm ("description"); } + | NAME { $$ = ly_symbol2scm ("context-name"); } + ; +context_mod: + property_operation { $$ = $1; } + | translator_mod STRING { + $$ = scm_list_n ($1, $2, SCM_UNDEFINED); } - | PROPERTY STRING '.' STRING REVERT embedded_scm { - Music *t = MY_MAKE_MUSIC("RevertProperty"); - bool autobeam - = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings")); - bool itc = internal_type_checking_global_b; + ; - t->set_mus_property ("symbol", scm_string_to_symbol ($4)); - if (autobeam) - internal_type_checking_global_b = false; - t->set_mus_property ("grob-property", $6); - if (autobeam) - internal_type_checking_global_b = itc; - +music_property_def: + PROPERTY STRING '.' property_operation { + Music * t = property_op_to_music ($4); Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic"); + csm->set_mus_property ("element", t->self_scm ()); scm_gc_unprotect_object (t->self_scm ()); $$ = csm; $$->set_spot (THIS->here_input ()); - csm-> set_mus_property ("context-type", $2); + csm-> set_mus_property ("context-type", scm_string_to_symbol ($2)); + } + | ONCE music_property_def { + $$ = $2; + SCM e = $2->get_mus_property ("element"); + unsmob_music (e)->set_mus_property ("once", SCM_BOOL_T); } ; @@ -1237,8 +1197,6 @@ scalar: | DIGIT { $$ = gh_int2scm ($1); } ; - - /* This is a trick: @@ -1292,8 +1250,20 @@ note_chord_element: } ; +chord_open: '<' + ; + +chord_close: '>' + ; + +simul_open: LESSLESS + ; + +simul_close: MOREMORE + ; + chord_body: - CHORD_OPEN chord_body_elements CHORD_CLOSE + chord_open chord_body_elements chord_close { $$ = MY_MAKE_MUSIC("EventChord"); $$->set_mus_property ("elements", @@ -1319,9 +1289,22 @@ chord_body_element: if ($2 % 2 || $3 % 2) n->set_mus_property ("force-accidental", SCM_BOOL_T); - SCM arts = scm_reverse_x ($4, SCM_EOL); - n->set_mus_property ("articulations", arts); + if (gh_pair_p ($4)) { + SCM arts = scm_reverse_x ($4, SCM_EOL); + n->set_mus_property ("articulations", arts); + } + $$ = n; + } + | DRUM_PITCH post_events { + Music *n = MY_MAKE_MUSIC("NoteEvent"); + n->set_mus_property ("duration" ,$2); + n->set_mus_property ("drum-type" , $1); + n->set_spot (THIS->here_input()); + if (gh_pair_p ($2)) { + SCM arts = scm_reverse_x ($2, SCM_EOL); + n->set_mus_property ("articulations", arts); + } $$ = n; } ; @@ -1335,6 +1318,12 @@ command_element: $$-> set_spot (THIS->here_input ()); $1-> set_spot (THIS->here_input ()); } + | SKIP duration_length { + Music * skip = MY_MAKE_MUSIC("SkipMusic"); + skip->set_mus_property ("duration", $2); + + $$ = skip; + } | OCTAVE { THIS->push_spot (); } pitch { Music *l = MY_MAKE_MUSIC("RelativeOctaveCheck"); @@ -1381,7 +1370,7 @@ command_element: $$ = csm; $$->set_spot (THIS->here_input ()); - csm->set_mus_property ("context-type", scm_makfrom0str ("Timing")); + csm->set_mus_property ("context-type", ly_symbol2scm ("Timing")); } | PARTIAL duration_length { Moment m = - unsmob_duration ($2)->get_length (); @@ -1392,7 +1381,7 @@ command_element: scm_gc_unprotect_object (p->self_scm ()); $$ =sp ; - sp-> set_mus_property ("context-type", scm_makfrom0str ("Timing")); + sp-> set_mus_property ("context-type", ly_symbol2scm ("Timing")); } | CLEF STRING { static SCM proc ; @@ -1412,44 +1401,28 @@ command_element: scm_gc_protect_object (result); $$ = unsmob_music (result); } - ; + | MARK scalar { + static SCM proc; + if (!proc) + proc = scm_c_eval_string ("make-mark-set"); -command_req: - shorthand_command_req { $$ = $1; } - | verbose_command_req { $$ = $1; } + SCM result = scm_call_1 (proc, $2); + scm_gc_protect_object (result); + $$ = unsmob_music (result); + } ; -shorthand_command_req: - extender_req { - $$ = $1; - } - | hyphen_req { - $$ = $1; - } - | BREATHE { +command_req: + BREATHE { $$ = MY_MAKE_MUSIC("BreathingSignEvent"); } | E_TILDE { $$ = MY_MAKE_MUSIC("PesOrFlexaEvent"); } - ; - -verbose_command_req: - MARK DEFAULT { + | MARK DEFAULT { Music * m = MY_MAKE_MUSIC("MarkEvent"); $$ = m; } - | MARK scalar { - Music *m = MY_MAKE_MUSIC("MarkEvent"); - m->set_mus_property ("label", $2); - $$ = m; - } - | SKIP duration_length { - Music * skip = MY_MAKE_MUSIC("SkipEvent"); - skip->set_mus_property ("duration", $2); - - $$ = skip; - } | tempo_event { $$ = $1; } @@ -1482,20 +1455,43 @@ post_events: $$ = gh_cons ($2->self_scm(), $$); scm_gc_unprotect_object ($2->self_scm()); } + | post_events tagged_post_event { + $2 -> set_spot (THIS->here_input ()); + $$ = scm_cons ($2->self_scm(), $$); + scm_gc_unprotect_object ($2->self_scm()); + } ; +tagged_post_event: + '-' TAG embedded_scm post_event { + tag_music ($4, $3, THIS->here_input ()); + $$ = $4; + } + ; post_event: direction_less_event { $$ = $1; } + | HYPHEN { + if (!THIS->lexer_->lyric_state_b ()) + THIS->parser_error (_ ("Have to be in Lyric mode for lyrics")); + $$ = MY_MAKE_MUSIC("HyphenEvent"); + } + | EXTENDER { + if (!THIS->lexer_->lyric_state_b ()) + THIS->parser_error (_ ("Have to be in Lyric mode for lyrics")); + $$ = MY_MAKE_MUSIC("ExtenderEvent"); + } | script_dir direction_reqd_event { - $2->set_mus_property ("direction", gh_int2scm ($1)); + if ($1) + $2->set_mus_property ("direction", gh_int2scm ($1)); $$ = $2; } | script_dir direction_less_event { - $2->set_mus_property ("direction", gh_int2scm ($1)); + if ($1) + $2->set_mus_property ("direction", gh_int2scm ($1)); $$ = $2; } | string_number_event @@ -1524,29 +1520,31 @@ configurable, i.e. (set-articulation '~ "trill") */ - Music * m = MY_MAKE_MUSIC ("NewBeamEvent"); + Music * m = MY_MAKE_MUSIC ("BeamEvent"); m->set_spot (THIS->here_input()); m->set_mus_property ("span-direction" , gh_int2scm (START)); $$ = m; } | ']' { - Music * m = MY_MAKE_MUSIC ("NewBeamEvent"); + Music * m = MY_MAKE_MUSIC ("BeamEvent"); m->set_spot (THIS->here_input()); m->set_mus_property ("span-direction" , gh_int2scm (STOP)); $$ = m; } | '~' { - Music * m = MY_MAKE_MUSIC ("NewTieEvent"); + Music * m = MY_MAKE_MUSIC ("TieEvent"); m->set_spot (THIS->here_input()); $$ = m; } | close_event { $$ = $1; - dynamic_cast ($$)->set_mus_property ("span-direction", gh_int2scm (START)); + dynamic_cast ($$)->set_mus_property ("span-direction", + gh_int2scm (START)); } | open_event { $$ = $1; - dynamic_cast ($$)->set_mus_property ("span-direction", gh_int2scm (STOP)) + dynamic_cast ($$)->set_mus_property ("span-direction", + gh_int2scm (STOP)); } | EVENT_IDENTIFIER { $$ = unsmob_music ($1); @@ -1572,7 +1570,14 @@ direction_reqd_event: $$ = a; } ; - + +oct_check: + /**/ { $$ = SCM_EOL; } + | '=' { $$ = gh_int2scm (0); } + | '=' sub_quotes { $$ = gh_int2scm ($2); } + | '=' sup_quotes { $$ = gh_int2scm ($2); } + ; + sup_quotes: '\'' { $$ = 1; @@ -1632,9 +1637,6 @@ pitch: steno_pitch { $$ = $1; } - | explicit_pitch { - $$ = $1; - } ; pitch_also_in_chords: @@ -1642,43 +1644,6 @@ pitch_also_in_chords: | steno_tonic_pitch ; -explicit_pitch: - PITCH embedded_scm { - $$ = $2; - if (!unsmob_pitch ($2)) { - THIS->parser_error (_f ("Expecting musical-pitch value", 3)); - $$ = Pitch ().smobbed_copy (); - } - } - ; - -verbose_duration: - DURATION embedded_scm { - $$ = $2; - if (!unsmob_duration ($2)) - { - THIS->parser_error (_ ("Must have duration object")); - $$ = Duration ().smobbed_copy (); - } - } - ; - -extender_req: - EXTENDER { - if (!THIS->lexer_->lyric_state_b ()) - THIS->parser_error (_ ("Have to be in Lyric mode for lyrics")); - $$ = MY_MAKE_MUSIC("ExtenderEvent"); - } - ; - -hyphen_req: - HYPHEN { - if (!THIS->lexer_->lyric_state_b ()) - THIS->parser_error (_ ("Have to be in Lyric mode for lyrics")); - $$ = MY_MAKE_MUSIC("HyphenEvent"); - } - ; - close_event: '(' { Music * s= MY_MAKE_MUSIC("SlurEvent"); @@ -1787,9 +1752,6 @@ duration_length: multiplied_duration { $$ = $1; } - | verbose_duration { - $$ = $1; - } ; optional_notemode_duration: @@ -1805,10 +1767,6 @@ optional_notemode_duration: THIS->beam_check ($$); } - | verbose_duration { - $$ = $1; - THIS->default_duration_ = *unsmob_duration ($$); - } ; steno_duration: @@ -1887,12 +1845,12 @@ bass_number: | UNSIGNED { $$ = scm_number_to_string (gh_int2scm ($1), gh_int2scm (10)); } - | STRING { $$ = $1 } + | STRING { $$ = $1; } ; bass_mod: - '-' { $$ = -1; } - | '+' { $$ = 1; } + '-' { $$ = -2; } + | '+' { $$ = 2; } | '!' { $$ = 0; } ; @@ -1962,21 +1920,26 @@ optional_rest: ; simple_element: - pitch exclamations questions optional_notemode_duration optional_rest { + pitch exclamations questions oct_check optional_notemode_duration optional_rest { Input i = THIS->pop_spot (); if (!THIS->lexer_->note_state_b ()) THIS->parser_error (_ ("Have to be in Note mode for notes")); Music *n = 0; - if ($5) + if ($6) n = MY_MAKE_MUSIC("RestEvent"); else n = MY_MAKE_MUSIC("NoteEvent"); n->set_mus_property ("pitch", $1); - n->set_mus_property ("duration", $4); + n->set_mus_property ("duration", $5); + if (gh_number_p ($4)) + { + int q = gh_scm2int ($4); + n->set_mus_property ("absolute-octave", gh_int2scm (q-1)); + } if ($3 % 2) n->set_mus_property ("cautionary", SCM_BOOL_T); @@ -1991,6 +1954,21 @@ simple_element: n->set_spot (i); $$ = v; } + | DRUM_PITCH optional_notemode_duration { + Input i = THIS->pop_spot (); + + Music *n = MY_MAKE_MUSIC("NoteEvent"); + n->set_mus_property ("duration" ,$2); + n->set_mus_property ("drum-type" , $1); + + Music *v = MY_MAKE_MUSIC("EventChord"); + v->set_mus_property ("elements", scm_list_n (n->self_scm (), SCM_UNDEFINED)); + scm_gc_unprotect_object (n->self_scm()); + v->set_spot (i); + n->set_spot (i); + $$ = v; + + } | figure_spec optional_notemode_duration { Music * m = unsmob_music ($1); Input i = THIS->pop_spot (); @@ -2019,6 +1997,8 @@ simple_element: velt->set_mus_property ("elements", scm_list_n (ev->self_scm (),SCM_UNDEFINED)); velt->set_spot (i); + scm_gc_unprotect_object (ev->self_scm()); + $$ = velt; } | MULTI_MEASURE_REST optional_notemode_duration { @@ -2033,8 +2013,11 @@ simple_element: scm_gc_protect_object (mus); $$ = unsmob_music (mus); } - | STRING optional_notemode_duration { + + | lyric_element optional_notemode_duration { Input i = THIS->pop_spot (); + if (!THIS->lexer_->lyric_state_b ()) + THIS->parser_error (_ ("Have to be in Lyric mode for lyrics")); Music * lreq = MY_MAKE_MUSIC("LyricEvent"); lreq->set_mus_property ("text", $1); @@ -2054,6 +2037,11 @@ simple_element: } ; +lyric_element: + full_markup { $$ = $1; } + | STRING { $$ = $1 ; } + ; + new_chord: steno_tonic_pitch optional_notemode_duration { $$ = make_chord ($1, $2, SCM_EOL); @@ -2112,10 +2100,10 @@ step_number: $$ = make_chord_step ($1, 0); } | bare_unsigned '+' { - $$ = make_chord_step ($1, 1); + $$ = make_chord_step ($1, SHARP); } | bare_unsigned CHORD_MINUS { - $$ = make_chord_step ($1,-1); + $$ = make_chord_step ($1, FLAT); } ; @@ -2246,6 +2234,9 @@ markup: STRING { $$ = make_simple_markup ($1); } + | MARKUP_HEAD_EMPTY { + $$ = scm_list_n ($1, SCM_UNDEFINED); + } | MARKUP_HEAD_MARKUP0 markup { $$ = scm_list_n ($1, $2, SCM_UNDEFINED); } @@ -2270,6 +2261,9 @@ markup: | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm { $$ = scm_list_n ($1, $2, $3, $4, SCM_UNDEFINED); } + | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm { + $$ = scm_list_n ($1, $2, $3, SCM_UNDEFINED); + } | MARKUP_IDENTIFIER { $$ = $1; } @@ -2277,7 +2271,7 @@ markup: ; markup_list: - CHORD_OPEN markup_list_body CHORD_CLOSE { $$ = scm_reverse_x ($2, SCM_EOL); } + chord_open markup_list_body chord_close { $$ = scm_reverse_x ($2, SCM_EOL); } ; markup_line: @@ -2359,8 +2353,8 @@ My_lily_lexer::try_special_identifiers (SCM * destination, SCM sid) } else if (gh_number_p (sid)) { *destination = sid; return NUMBER_IDENTIFIER; - } else if (unsmob_translator_def (sid)) { - *destination = unsmob_translator_def (sid)->clone_scm(); + } else if (unsmob_context_def (sid)) { + *destination = unsmob_context_def (sid)->clone_scm(); return TRANSLATOR_IDENTIFIER; } else if (unsmob_score (sid)) { Score *sc = new Score (*unsmob_score (sid)); @@ -2388,3 +2382,89 @@ My_lily_lexer::try_special_identifiers (SCM * destination, SCM sid) return -1; } + +Music * +property_op_to_music (SCM op) +{ + Music * m = 0; + SCM tag = gh_car (op); + SCM symbol = gh_cadr (op); + SCM args = gh_cddr (op); + SCM grob_val = SCM_UNDEFINED; + SCM grob_sym = SCM_UNDEFINED; + SCM val = SCM_UNDEFINED; + + if (tag == ly_symbol2scm ("assign")) + { + m = MY_MAKE_MUSIC("PropertySet"); + val = gh_car (args); + } + else if (tag == ly_symbol2scm ("unset")) + m = MY_MAKE_MUSIC("PropertyUnset"); + else if (tag == ly_symbol2scm ("poppush") + || tag == ly_symbol2scm ("push")) + { + m = MY_MAKE_MUSIC("OverrideProperty"); + grob_sym = gh_car (args); + grob_val = gh_cadr (args); + } + else if (tag == ly_symbol2scm ("pop")) { + m = MY_MAKE_MUSIC("RevertProperty"); + grob_sym = gh_car (args); + } + + m->set_mus_property ("symbol", symbol); + + if (val != SCM_UNDEFINED) + m->set_mus_property ("value", val); + if (grob_val != SCM_UNDEFINED) + m->set_mus_property ("grob-value", grob_val); + + if (grob_sym != SCM_UNDEFINED) + { + bool itc = internal_type_checking_global_b; + /* UGH. + */ + bool autobeam = gh_equal_p (symbol, ly_symbol2scm ("autoBeamSettings")); + if (autobeam) + internal_type_checking_global_b = false; + m->set_mus_property ("grob-property", grob_sym); + if (autobeam) + internal_type_checking_global_b = itc; + } + + if (op == ly_symbol2scm ("poppush")) + m->set_mus_property ("pop-first", SCM_BOOL_T); + + + return m; +} + +Music* +context_spec_music (SCM type, SCM id, Music * m, SCM ops) +{ + Music * csm = MY_MAKE_MUSIC("ContextSpeccedMusic"); + + csm->set_mus_property ("element", m->self_scm ()); + scm_gc_unprotect_object (m->self_scm ()); + + csm->set_mus_property ("context-type", scm_string_to_symbol (type)); + csm->set_mus_property ("property-operations", ops); + + if (gh_string_p (id)) + csm->set_mus_property ("context-id", id); + return csm; +} + + +SCM +get_next_unique_context () +{ + static int new_context_count; + + char s[1024]; + snprintf (s, 1024, "uniqueContext%d", new_context_count ++); + + return scm_makfrom0str (s); +} +