From: David Kastrup <dak@gnu.org>
Date: Mon, 8 Sep 2014 09:01:56 +0000 (+0200)
Subject: Refactor grammar to give \addlyrics a good target to attach to
X-Git-Tag: release/2.19.14-1~6^2~4
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=4015468c822eae4e9421ca6640b0ecf6e75e8d7d;p=lilypond.git

Refactor grammar to give \addlyrics a good target to attach to

So far,

    \new Staff \new Voice { c1 } \addlyrics { Oh } \addlyrics { Ah }

was factored as

    \new Staff \new Voice { { c1 } \addlyrics { Oh } \addlyrics { Ah } }

which resulted in something like

   \new Staff \new Voice
     << \context Voice = "uniqueContext0" { c1 }
        \new Lyrics \lyricsto "uniqueContext0" { Oh }
        \new Lyrics \lyricsto "uniqueContext0" { Ah }
     >>

This made it impossible to work with the likes of

  \new Staff \new Voice \with { \stemUp } { c1 } \addlyrics ...

since the voice the lyrics attached to was always a new voice.
Fixing the grouping in the grammar is a first required step for getting
this under control.
---

diff --git a/lily/parser.yy b/lily/parser.yy
index e523c2da48..b41aff64c8 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -1222,7 +1222,11 @@ braced_music_list:
 
 music:	music_assign
 	| lyric_element_music
-	| pitch_or_music
+	| pitch_as_music
+	;
+
+pitch_as_music:
+	pitch_or_music
 	{
 	        $$ = make_music_from_simple (parser, @1, $1);
                 if (!Music::unsmob ($$))
@@ -1430,20 +1434,62 @@ new_lyrics:
 	}
 	;
 
-composite_music:
+/* basic_music is basically the same as composite_music but with
+ * context-prefixed music and lyricized music explicitly removed.  The
+ * reason is that in a sequence
+ *
+ *   \new Staff \new Voice { ... } \addlyrics { ... } \addlyrics { ... }
+ *
+ * we need to group both \addlyrics together (as they go with the same
+ * voice) but then combine them with \new Voice { ... }, meaning that
+ * combining \new Voice { ... } needs higher priority than
+ * { ... } \addlyrics, and *not* have \new Staff \new Voice { ... }
+ * combine before combining \new Voice { ... } \addlyrics: only one
+ * layer of context-prefixed music should assemble before \addlyrics
+ * is integrated.  Total mess, and we sort this mess out with explicit
+ * rules preferring a single context-prefix.
+ */
+
+basic_music:
 	music_function_call
-	| repeated_music		{ $$ = $1; }
-	| context_prefix music
+	| repeated_music
+	| music_bare
+	;
+
+contextable_music:
+	basic_music
+	| pitch_as_music
+	| event_chord
+	;
+
+contexted_basic_music:
+	context_prefix contextable_music new_lyrics
+	{
+		Input i;
+		i.set_location (@1, @2);
+		$$ = FINISH_MAKE_SYNTAX ($1, i, $2);
+		$$ = MAKE_SYNTAX ("add-lyrics", @$, $$, scm_reverse_x ($3, SCM_EOL));
+	} %prec COMPOSITE
+	| context_prefix contextable_music
+	{
+		$$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
+	} %prec COMPOSITE
+	| context_prefix contexted_basic_music
 	{
 		$$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
 	}
-	| composite_music new_lyrics {
+	;
+
+composite_music:
+	basic_music %prec COMPOSITE
+	| contexted_basic_music
+	| basic_music new_lyrics
+	{
 		$$ = MAKE_SYNTAX ("add-lyrics", @$, $1, scm_reverse_x ($2, SCM_EOL));
 	} %prec COMPOSITE
 	| LYRICSTO simple_string lyric_mode_music {
 		$$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $3);
 	}
-	| music_bare
 	;
 
 music_bare: