X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=3e7625f45f8cafbbe578bfa803e2d2a4819bedbe;hb=1d9fc4b1512eb69a28677890dc26658c3552c6cd;hp=c60c6ed64c1157fa00e516efdcd98b8cb9e9eb0b;hpb=3c0f38115857598db730782b1d2ff0a19fd833af;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index c60c6ed64c..3e7625f45f 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -232,7 +232,7 @@ SCM loc_on_music (Lily_parser *parser, Input loc, SCM arg); SCM make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list); SCM make_chord_step (SCM step, Rational alter); SCM make_simple_markup (SCM a); -SCM make_duration (SCM t, int dots = 0); +SCM make_duration (SCM t, int dots = 0, SCM factor = SCM_UNDEFINED); bool is_regular_identifier (SCM id, bool multiple=false); SCM try_string_variants (SCM pred, SCM str); int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser); @@ -347,7 +347,8 @@ If we give names, Bison complains. %token CHORD_REPETITION %token CONTEXT_MOD_IDENTIFIER %token DRUM_PITCH -%token PITCH_IDENTIFIER + /* Artificial token for durations in argument lists */ +%token DURATION_ARG %token DURATION_IDENTIFIER %token EVENT_IDENTIFIER %token EVENT_FUNCTION @@ -361,6 +362,7 @@ If we give names, Bison complains. %token MUSIC_IDENTIFIER %token NOTENAME_PITCH %token NUMBER_IDENTIFIER +%token PITCH_IDENTIFIER %token REAL %token RESTNAME %token SCM_ARG @@ -1756,7 +1758,11 @@ function_arglist_nonbackup: (parser, @3, $3), $1, $2); } - | function_arglist_nonbackup_reparse REPARSE duration_length + | function_arglist_nonbackup_reparse REPARSE multiplied_duration + { + $$ = check_scheme_arg (parser, @3, $3, $1, $2); + } + | function_arglist_nonbackup_reparse REPARSE reparsed_rhythm { $$ = check_scheme_arg (parser, @3, $3, $1, $2); } @@ -1778,6 +1784,20 @@ function_arglist_nonbackup: } ; + +reparsed_rhythm: + DURATION_ARG dots multipliers post_events + { + $$ = make_music_from_simple (parser, @$, + make_duration ($1, scm_to_int ($2), $3)); + Music *m = unsmob ($$); + assert (m); + if (scm_is_pair ($4)) + m->set_property ("articulations", + scm_reverse_x ($4, SCM_EOL)); + } %prec ':' + ; + function_arglist_nonbackup_reparse: EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER { @@ -1852,18 +1872,34 @@ function_arglist_nonbackup_reparse: { $$ = $3; if (scm_is_true (scm_call_1 ($2, $4))) + // May be 3 \cm or similar MYREPARSE (@4, $2, REAL, $4); else { SCM d = make_duration ($4); - if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d))) - MYREPARSE (@4, $2, REAL, $4); // trigger error - else - MYREPARSE (@4, $2, DURATION_IDENTIFIER, d); + if (!SCM_UNBNDP (d)) { + if (scm_is_true (scm_call_1 ($2, d))) + MYREPARSE (@4, $2, DURATION_IDENTIFIER, d); + else if (scm_is_true + (scm_call_1 + ($2, make_music_from_simple (parser, @4, d)))) + MYREPARSE (@4, $2, DURATION_ARG, d); + else + MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error + } else + MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error } } - | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER { + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER + { $$ = $3; - MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4); + if (scm_is_true (scm_call_1 ($2, $4))) + MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4); + else if (scm_is_true + (scm_call_1 + ($2, make_music_from_simple (parser, @4, $4)))) + MYREPARSE (@4, $2, DURATION_ARG, $4); + else + MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error } ; @@ -1940,19 +1976,26 @@ function_arglist_backup: } | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup UNSIGNED { + $$ = $3; if (scm_is_true (scm_call_1 ($2, $4))) - { + // May be 3 \cm or similar MYREPARSE (@4, $2, REAL, $4); - $$ = $3; - } else { + else { SCM d = make_duration ($4); - if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d))) - { + if (!SCM_UNBNDP (d)) { + if (scm_is_true (scm_call_1 ($2, d))) + MYREPARSE (@4, $2, DURATION_IDENTIFIER, d); + else if (scm_is_true + (scm_call_1 + ($2, make_music_from_simple (parser, @4, d)))) + MYREPARSE (@4, $2, DURATION_ARG, d); + else { + $$ = scm_cons (loc_on_music (parser, @3, $1), $3); + MYBACKUP (UNSIGNED, $4, @4); + } + } else { $$ = scm_cons (loc_on_music (parser, @3, $1), $3); MYBACKUP (UNSIGNED, $4, @4); - } else { - MYREPARSE (@4, $2, DURATION_IDENTIFIER, d); - $$ = $3; } } } @@ -2019,11 +2062,14 @@ function_arglist_backup: } | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup DURATION_IDENTIFIER { + $$ = $3; if (scm_is_true (scm_call_1 ($2, $4))) - { MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4); - $$ = $3; - } else { + else if (scm_is_true + (scm_call_1 + ($2, make_music_from_simple (parser, @4, $4)))) + MYREPARSE (@4, $2, DURATION_ARG, $4); + else { $$ = scm_cons (loc_on_music (parser, @3, $1), $3); MYBACKUP (DURATION_IDENTIFIER, $4, @4); } @@ -2073,7 +2119,12 @@ function_arglist_backup: $$ = check_scheme_arg (parser, @3, $3, $1, $2); } - | function_arglist_backup REPARSE duration_length + | function_arglist_backup REPARSE multiplied_duration + { + $$ = check_scheme_arg (parser, @3, + $3, $1, $2); + } + | function_arglist_backup REPARSE reparsed_rhythm { $$ = check_scheme_arg (parser, @3, $3, $1, $2); @@ -2204,7 +2255,12 @@ function_arglist_common: $$ = check_scheme_arg (parser, @3, $3, $1, $2); } - | function_arglist_common_reparse REPARSE duration_length + | function_arglist_common_reparse REPARSE multiplied_duration + { + $$ = check_scheme_arg (parser, @3, + $3, $1, $2); + } + | function_arglist_common_reparse REPARSE reparsed_rhythm { $$ = check_scheme_arg (parser, @3, $3, $1, $2); @@ -2292,19 +2348,34 @@ function_arglist_common_reparse: { $$ = $2; if (scm_is_true (scm_call_1 ($1, $3))) + // May be 3 \cm or similar MYREPARSE (@3, $1, REAL, $3); else { SCM d = make_duration ($3); - if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($1, d))) - MYREPARSE (@3, $1, REAL, $3); - else - MYREPARSE (@3, $1, DURATION_IDENTIFIER, d); + if (!SCM_UNBNDP (d)) { + if (scm_is_true (scm_call_1 ($1, d))) + MYREPARSE (@3, $1, DURATION_IDENTIFIER, d); + else if (scm_is_true + (scm_call_1 + ($1, make_music_from_simple (parser, @3, d)))) + MYREPARSE (@3, $1, DURATION_ARG, d); + else + MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error + } else + MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error } } | EXPECT_SCM function_arglist_optional DURATION_IDENTIFIER { $$ = $2; - MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3); + if (scm_is_true (scm_call_1 ($1, $3))) + MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3); + else if (scm_is_true + (scm_call_1 + ($1, make_music_from_simple (parser, @3, $3)))) + MYREPARSE (@3, $1, DURATION_ARG, $3); + else + MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error } | EXPECT_SCM function_arglist_optional '-' UNSIGNED { @@ -3179,12 +3250,6 @@ script_dir: | '-' { $$ = SCM_UNDEFINED; } ; -duration_length: - multiplied_duration { - $$ = $1; - } - ; - maybe_notemode_duration: { $$ = SCM_UNDEFINED; @@ -3214,26 +3279,13 @@ steno_duration: } } | DURATION_IDENTIFIER dots { - Duration *d = unsmob ($1); - Duration k (d->duration_log (), - d->dot_count () + scm_to_int ($2)); - k = k.compressed (d->factor ()); - scm_remember_upto_here_1 ($1); - $$ = k.smobbed_copy (); + $$ = make_duration ($1, scm_to_int ($2)); } ; multiplied_duration: - steno_duration { - $$ = $1; - } - | multiplied_duration '*' UNSIGNED { - $$ = unsmob ($$)->compressed (scm_to_int ($3)).smobbed_copy (); - } - | multiplied_duration '*' FRACTION { - Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3))); - - $$ = unsmob ($$)->compressed (m).smobbed_copy (); + steno_duration multipliers { + $$ = make_duration ($1, 0, $2); } ; @@ -3246,6 +3298,28 @@ dots: } ; +multipliers: + /* empty */ + { + $$ = SCM_UNDEFINED; + } + | multipliers '*' UNSIGNED + { + if (!SCM_UNBNDP ($1)) + $$ = scm_product ($1, $3); + else + $$ = $3; + } + | multipliers '*' FRACTION + { + if (!SCM_UNBNDP ($1)) + $$ = scm_product ($1, scm_divide (scm_car ($3), + scm_cdr ($3))); + else + $$ = scm_divide (scm_car ($3), scm_cdr ($3)); + } + ; + tremolo_type: ':' { $$ = scm_from_int (parser->default_tremolo_type_); @@ -3693,7 +3767,7 @@ markup_top: ; markup_scm: - embedded_scm_bare + embedded_scm { if (Text_interface::is_markup ($1)) MYBACKUP (MARKUP_IDENTIFIER, $1, @1); @@ -4092,6 +4166,14 @@ make_music_from_simple (Lily_parser *parser, Input loc, SCM simple) n->set_property ("pitch", simple); return n->unprotect (); } + SCM d = simple; + if (scm_is_integer (simple)) + d = make_duration (simple); + if (unsmob (d)) { + Music *n = MY_MAKE_MUSIC ("NoteEvent", loc); + n->set_property ("duration", d); + return n->unprotect (); + } return simple; } else if (parser->lexer_->is_lyric_state ()) { if (Text_interface::is_markup (simple)) @@ -4124,13 +4206,29 @@ make_simple_markup (SCM a) } SCM -make_duration (SCM d, int dots) +make_duration (SCM d, int dots, SCM factor) { - int t = scm_to_int (d); - if (t > 0 && (t & (t-1)) == 0) - return Duration (intlog2 (t), dots).smobbed_copy (); - else - return SCM_UNDEFINED; + Duration k; + + if (Duration *dur = unsmob (d)) { + if (!dots && SCM_UNBNDP (factor)) + return d; + k = *dur; + if (dots) + k = Duration (k.duration_log (), k.dot_count () + dots) + .compressed (k.factor ()); + } else { + int t = scm_to_int (d); + if (t > 0 && (t & (t-1)) == 0) + k = Duration (intlog2 (t), dots); + else + return SCM_UNDEFINED; + } + + if (!SCM_UNBNDP (factor)) + k = k.compressed (ly_scm2rational (factor)); + + return k.smobbed_copy (); } SCM