]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
Merge branch 'lilypond/translation'
[lilypond.git] / lily / parser.yy
index 224f6f30a49464f19fe1dbc79a89fbd7f16e6ad5..0adb95c2f55667155309e9025d0afd60ad8a635c 100644 (file)
@@ -58,7 +58,8 @@ or
 
 %right FUNCTION_ARGUMENTS
       MARKUP LYRICS_STRING MARKUP_IDENTIFIER STRING STRING_IDENTIFIER
-      MARKUPLINES WITH CONTEXT_MOD_IDENTIFIER MARKUPLINES_IDENTIFIER
+      MARKUPLIST WITH CONTEXT_MOD_IDENTIFIER MARKUPLIST_IDENTIFIER
+      SCORE BOOK BOOKPART PAPER LAYOUT MIDI
       SEQUENTIAL SIMULTANEOUS DOUBLE_ANGLE_OPEN MUSIC_IDENTIFIER '{'
       PITCH_IDENTIFIER NOTENAME_PITCH TONICNAME_PITCH
       SCM_FUNCTION SCM_IDENTIFIER SCM_TOKEN
@@ -178,6 +179,7 @@ SCM get_first_context_id (SCM type, Music *m);
 SCM make_chord_elements (SCM pitch, SCM dur, SCM modification_list);
 SCM make_chord_step (int step, Rational alter);
 SCM make_simple_markup (SCM a);
+SCM try_unpack_lyrics (SCM pred, SCM arg);
 bool is_duration (int t);
 bool is_regular_identifier (SCM id);
 bool ly_input_procedure_p (SCM x);
@@ -223,7 +225,7 @@ void set_music_properties (Music *p, SCM a);
 %token LYRICSTO "\\lyricsto"
 %token MARK "\\mark"
 %token MARKUP "\\markup"
-%token MARKUPLINES "\\markuplines"
+%token MARKUPLIST "\\markuplist"
 %token MIDI "\\midi"
 %token NAME "\\name"
 %token NOTEMODE "\\notemode"
@@ -291,7 +293,6 @@ If we give names, Bison complains.
 
 /* Artificial tokens, for more generic function syntax */
 %token <i> EXPECT_MARKUP "markup?"
-%token <i> EXPECT_MUSIC "ly:music?"
 %token <i> EXPECT_PITCH "ly:pitch?"
 %token <i> EXPECT_DURATION "ly:duration?"
 %token <scm> EXPECT_SCM "scheme?"
@@ -321,7 +322,7 @@ If we give names, Bison complains.
 %token <scm> MARKUP_FUNCTION
 %token <scm> MARKUP_LIST_FUNCTION
 %token <scm> MARKUP_IDENTIFIER
-%token <scm> MARKUPLINES_IDENTIFIER
+%token <scm> MARKUPLIST_IDENTIFIER
 %token <scm> MUSIC_FUNCTION
 %token <scm> MUSIC_IDENTIFIER
 %token <scm> NOTENAME_PITCH
@@ -591,10 +592,32 @@ embedded_scm_bare:
 
 embedded_scm_bare_arg:
        embedded_scm_bare
-       | simple_string
+       | STRING
+       | STRING_IDENTIFIER
        | full_markup
        | full_markup_list
        | context_modification
+       | score_block
+       {
+               $$ = $1->self_scm ();
+               $1->unprotect ();
+       }
+       | context_def_spec_block
+       | book_block
+       {
+               $$ = $1->self_scm ();
+               $1->unprotect ();
+       }
+       | bookpart_block
+       {
+               $$ = $1->self_scm ();
+               $1->unprotect ();
+       }
+       | output_def
+       {
+               $$ = $1->self_scm ();
+               $1->unprotect ();
+       }
        ;
 
 /* The generic version may end in music, or not */
@@ -607,6 +630,7 @@ embedded_scm:
 embedded_scm_arg:
        embedded_scm_bare_arg
        | scm_function_call
+       | music
        ;
 
 scm_function_call:
@@ -1166,29 +1190,27 @@ grouped_music_list:
        | sequential_music              { $$ = $1; }
        ;
 
-/* An argument list. If a function \foo expects scm scm music, then the lexer expands \foo into the token sequence:
- MUSIC_FUNCTION EXPECT_MUSIC EXPECT_SCM EXPECT_SCM EXPECT_NO_MORE_ARGS
+/* An argument list. If a function \foo expects scm scm pitch, then the lexer expands \foo into the token sequence:
+ MUSIC_FUNCTION EXPECT_PITCH EXPECT_SCM EXPECT_SCM EXPECT_NO_MORE_ARGS
 and this rule returns the reversed list of arguments. */
 
 
 function_arglist:
        function_arglist_bare
-       | EXPECT_MUSIC function_arglist_optional music
+       | EXPECT_SCM function_arglist_optional embedded_scm_arg
        {
-               $$ = scm_cons ($3, $2);
+               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED,
+                                      $3, $2, $1);
        }
-       | EXPECT_SCM function_arglist_optional embedded_scm_arg
+       | EXPECT_SCM function_arglist_optional SKIPPED_SCM
        {
-               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED, $3, $2, $1);
+               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED,
+                                      $3, $2, $1);
        }
        ;
 
 function_arglist_optional:
        function_arglist_keep %prec FUNCTION_ARGUMENTS
-       | EXPECT_OPTIONAL EXPECT_MUSIC function_arglist_optional
-       {
-               $$ = scm_cons (loc_on_music (@3, $1), $3);
-       }
        | EXPECT_OPTIONAL EXPECT_PITCH function_arglist_optional
        {
                $$ = scm_cons ($1, $3);
@@ -1210,42 +1232,41 @@ function_arglist_keep:
        | EXPECT_OPTIONAL EXPECT_DURATION function_arglist_closed_keep duration_length {
                $$ = scm_cons ($4, $3);
        }
-       | EXPECT_OPTIONAL EXPECT_MUSIC function_arglist_keep closed_music
-       {
-               $$ = scm_cons ($4, $3);
-       }
-       | function_arglist
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep embedded_scm_arg_closed
        {
                if (scm_is_true (scm_call_1 ($2, $4)))
                {
                        $$ = scm_cons ($4, $3);
                } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (SKIPPED_SCM, $4, @4);
+                       $$ = try_unpack_lyrics ($2, $4);
+                       if (!SCM_UNBNDP ($$))
+                               $$ = scm_cons ($$, $3);
+                       else {
+                               $$ = scm_cons (loc_on_music (@3, $1), $3);
+                               MYBACKUP (SKIPPED_SCM, $4, @4);
+                       }
                }
        }
+       | function_arglist
        ;
 
 
 function_arglist_closed:
        function_arglist_bare
-       | EXPECT_MUSIC function_arglist_optional closed_music
+       | EXPECT_SCM function_arglist_optional embedded_scm_arg_closed
        {
-               $$ = scm_cons ($3, $2);
+               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED,
+                                      $3, $2, $1);
        }
-       | EXPECT_SCM function_arglist_optional embedded_scm_arg_closed
+       | EXPECT_SCM function_arglist_optional SKIPPED_SCM
        {
-               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED, $3, $2, $1);
+               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED,
+                                      $3, $2, $1);
        }
        ;
 
 function_arglist_closed_optional:
        function_arglist_closed_keep %prec FUNCTION_ARGUMENTS
-       | EXPECT_OPTIONAL EXPECT_MUSIC function_arglist_closed_optional
-       {
-               $$ = scm_cons (loc_on_music (@3, $1), $3);
-       }
        | EXPECT_OPTIONAL EXPECT_PITCH function_arglist_closed_optional
        {
                $$ = scm_cons ($1, $3);
@@ -1267,18 +1288,19 @@ function_arglist_closed_keep:
        | EXPECT_OPTIONAL EXPECT_DURATION function_arglist_closed_keep duration_length {
                $$ = scm_cons ($4, $3);
        }
-       | EXPECT_OPTIONAL EXPECT_MUSIC function_arglist_keep closed_music
-       {
-               $$ = scm_cons ($4, $3);
-       }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep embedded_scm_arg_closed
        {
                if (scm_is_true (scm_call_1 ($2, $4)))
                {
                        $$ = scm_cons ($4, $3);
                } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (SKIPPED_SCM, $4, @4);
+                       $$ = try_unpack_lyrics ($2, $4);
+                       if (!SCM_UNBNDP ($$))
+                               $$ = scm_cons ($$, $3);
+                       else {
+                               $$ = scm_cons (loc_on_music (@3, $1), $3);
+                               MYBACKUP (SKIPPED_SCM, $4, @4);
+                       }
                }
        }
        | function_arglist_closed
@@ -1292,6 +1314,7 @@ embedded_scm_closed:
 embedded_scm_arg_closed:
        embedded_scm_bare_arg
        | scm_function_call_closed
+       | closed_music
        ;
 
 scm_function_call_closed:
@@ -1311,10 +1334,6 @@ function_arglist_bare:
        | EXPECT_DURATION function_arglist_closed_optional duration_length {
                $$ = scm_cons ($3, $2);
        }
-       | EXPECT_SCM function_arglist_optional SKIPPED_SCM
-       {
-               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED, $3, $2, $1);
-       }
        ;
 
 music_function_call:
@@ -1641,6 +1660,10 @@ scalar_bare:
        | full_markup {
                $$ = $1;
        }
+       | full_markup_list
+       {
+               $$ = $1;
+       }
        ;
 
 scalar:
@@ -1775,11 +1798,10 @@ chord_body_element:
 
 music_function_chord_body_arglist:
        function_arglist_bare
-       | EXPECT_MUSIC music_function_chord_body_arglist chord_body_element {
-               $$ = scm_cons ($3, $2);
-       }
-       | EXPECT_SCM function_arglist_optional embedded_scm_chord_body {
-               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED, $3, $2, $1);
+       | EXPECT_SCM music_function_chord_body_arglist embedded_scm_chord_body
+       {
+               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED,
+                                      $3, $2, $1);
        }
        ;
 
@@ -1789,6 +1811,8 @@ embedded_scm_chord_body:
                $$ = MAKE_SYNTAX ("music-function", @$,
                                         $1, $2);
        }
+       | chord_body_element
+       | SKIPPED_SCM
        ;
 
 music_function_chord_body:
@@ -1805,11 +1829,10 @@ music_function_chord_body:
  */
 music_function_event_arglist:
        function_arglist_bare
-       | EXPECT_MUSIC music_function_event_arglist post_event {
-               $$ = scm_cons ($3, $2);
-       }
-       | EXPECT_SCM function_arglist_optional embedded_scm_event {
-               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED, $3, $2, $1);
+       | EXPECT_SCM music_function_event_arglist embedded_scm_event
+       {
+               $$ = check_scheme_arg (PARSER, @3, SCM_UNDEFINED,
+                                      $3, $2, $1);
        }
        ;
 
@@ -1819,6 +1842,8 @@ embedded_scm_event:
                $$ = MAKE_SYNTAX ("music-function", @$,
                                         $1, $2);
        }
+       | post_event
+       | SKIPPED_SCM
        ;
 
 music_function_event:
@@ -2621,10 +2646,10 @@ lyric_markup:
        ;
 
 full_markup_list:
-       MARKUPLINES_IDENTIFIER {
+       MARKUPLIST_IDENTIFIER {
                $$ = $1;
        }
-       | MARKUPLINES
+       | MARKUPLIST
                { PARSER->lexer_->push_markup_state (); }
        markup_list {
                $$ = $3;
@@ -2657,7 +2682,7 @@ markup_top:
        ;
 
 markup_list:
-       MARKUPLINES_IDENTIFIER {
+       MARKUPLIST_IDENTIFIER {
                $$ = $1;
        }
        | markup_composed_list {
@@ -2858,7 +2883,7 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
                return MARKUP_IDENTIFIER;
        } else if (Text_interface::is_markup_list (sid)) {
                *destination = sid;
-               return MARKUPLINES_IDENTIFIER;
+               return MARKUPLIST_IDENTIFIER;
        }
 
        return -1;
@@ -2880,24 +2905,26 @@ get_next_unique_lyrics_context_id ()
        return scm_from_locale_string (s);
 }
 
-
-SCM check_scheme_arg (Lily_parser *parser, Input loc, SCM fallback,
+SCM check_scheme_arg (Lily_parser *my_lily_parser, Input loc, SCM fallback,
                      SCM arg, SCM args, SCM pred)
 {
-       SCM type_check_arg = ly_lily_module_constant ("type-check-arg");
-       if (scm_is_false (scm_call_4 (type_check_arg, make_input (loc),
-                                     arg, args, pred)))
-       {
-               if (SCM_UNBNDP (fallback))
-                       fallback = SCM_BOOL_F;
-               else
-                       fallback = loc_on_music (loc, fallback);
-                       
-               parser->error_level_ = 1;
-
-               return scm_cons (fallback, args);
-       }
-       return scm_cons (arg, args);
+       SCM unwrap = SCM_UNDEFINED;
+       if (scm_is_true (scm_call_1 (pred, arg)))
+               return scm_cons (arg, args);
+       unwrap = try_unpack_lyrics (pred, arg);
+       if (!SCM_UNBNDP (unwrap))
+               return scm_cons (unwrap, args);
+       if (SCM_UNBNDP (fallback)) {
+               args = scm_cons (SCM_BOOL_F, args);
+               fallback = SCM_BOOL_F;
+       } else {
+               args = scm_cons (loc_on_music (loc, fallback), args);
+               fallback = SCM_CDR (scm_last_pair (args));
+       }
+       scm_set_cdr_x (scm_last_pair (args), SCM_EOL);
+       MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred, arg);
+       scm_set_cdr_x (scm_last_pair (args), fallback);
+       return args;
 }
 
 SCM loc_on_music (Input loc, SCM arg)
@@ -2991,6 +3018,17 @@ make_chord_elements (SCM pitch, SCM dur, SCM modification_list)
        return scm_call_3 (chord_ctor, pitch, dur, modification_list);
 }
 
+SCM
+try_unpack_lyrics (SCM pred, SCM arg)
+{
+       if (Music *m = unsmob_music (arg))
+               if (m->is_mus_type ("lyric-event")) {
+                       SCM text = m->get_property ("text");
+                       if (scm_is_true (scm_call_1 (pred, text)))
+                                       return text;
+                       }
+       return SCM_UNDEFINED;
+}      
 
 /* Todo: actually also use apply iso. call too ...  */
 bool