X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=2ddc2c815f31b65c2c582e2e82de35de114d2803;hb=b76beb7b3bb1ee422ff9c4e35b486f26732cbe17;hp=be4e7e26e521cba2ff39792d7c14dcd8b475f0d8;hpb=20b8c1519bbba8728457aa98e59993837bedfb04;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index be4e7e26e5..2ddc2c815f 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1,10 +1,21 @@ /* - parser.yy -- Bison/C++ parser for LilyPond + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter - - (c) 1997--2007 Han-Wen Nienhuys + Copyright (C) 1997--2009 Han-Wen Nienhuys Jan Nieuwenhuizen + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ %{ @@ -44,7 +55,7 @@ of the parse stack onto the heap. */ or - \repeat { \repeat } \alternative + \repeat { \repeat } \alternative */ @@ -151,14 +162,15 @@ void set_music_properties (Music *p, SCM a); FIXME: Bison needs to translate some of these, eg, STRING. -*/ - +*/ + /* Keyword tokens with plain escaped name. */ %token ACCEPTS "\\accepts" %token ADDLYRICS "\\addlyrics" %token ALIAS "\\alias" %token ALTERNATIVE "\\alternative" %token BOOK "\\book" +%token BOOKPART "\\bookpart" %token CHANGE "\\change" %token CHORDMODE "\\chordmode" %token CHORDS "\\chords" @@ -265,6 +277,7 @@ If we give names, Bison complains. %token BOOK_IDENTIFIER %token CHORDMODIFIER_PITCH %token CHORD_MODIFIER +%token CHORD_REPETITION %token CONTEXT_DEF_IDENTIFIER %token DRUM_PITCH %token DURATION_IDENTIFIER @@ -306,6 +319,8 @@ If we give names, Bison complains. %type book_block %type book_body +%type bookpart_block +%type bookpart_body %type bare_unsigned %type figured_bass_alteration @@ -474,6 +489,12 @@ toplevel_expression: scm_call_2 (proc, PARSER->self_scm (), book->self_scm ()); book->unprotect (); } + | bookpart_block { + Book *bookpart = $1; + SCM proc = PARSER->lexer_->lookup_identifier ("toplevel-bookpart-handler"); + scm_call_2 (proc, PARSER->self_scm (), bookpart->self_scm ()); + bookpart->unprotect (); + } | score_block { Score *score = $1; @@ -565,6 +586,10 @@ identifier_init: $$ = $1->self_scm (); $1->unprotect (); } + | bookpart_block { + $$ = $1->self_scm (); + $1->unprotect (); + } | output_def { $$ = $1->self_scm (); $1->unprotect (); @@ -641,6 +666,8 @@ context_def_spec_body: book_block: BOOK '{' book_body '}' { $$ = $3; + pop_paper (PARSER); + PARSER->lexer_->set_identifier (ly_symbol2scm ("$current-book"), SCM_BOOL_F); } ; @@ -650,19 +677,32 @@ book_block: book_body: { $$ = new Book; + init_papers (PARSER); $$->origin ()->set_spot (@$); $$->paper_ = dynamic_cast (unsmob_output_def (PARSER->lexer_->lookup_identifier ("$defaultpaper"))->clone ()); $$->paper_->unprotect (); + push_paper (PARSER, $$->paper_); $$->header_ = PARSER->lexer_->lookup_identifier ("$defaultheader"); + PARSER->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $$->self_scm ()); + PARSER->lexer_->set_identifier (ly_symbol2scm ("book-output-suffix"), SCM_BOOL_F); + PARSER->lexer_->set_identifier (ly_symbol2scm ("book-filename"), SCM_BOOL_F); } | BOOK_IDENTIFIER { $$ = unsmob_book ($1); $$->protect (); $$->origin ()->set_spot (@$); + PARSER->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $1); } | book_body paper_block { $$->paper_ = $2; $2->unprotect (); + set_paper (PARSER, $2); + } + | book_body bookpart_block { + Book *bookpart = $2; + SCM proc = PARSER->lexer_->lookup_identifier ("book-bookpart-handler"); + scm_call_2 (proc, $$->self_scm (), bookpart->self_scm ()); + bookpart->unprotect (); } | book_body score_block { Score *score = $2; @@ -689,12 +729,67 @@ book_body: | book_body error { $$->paper_ = 0; $$->scores_ = SCM_EOL; + $$->bookparts_ = SCM_EOL; } | book_body object_id_setting { $$->user_key_ = ly_scm2string ($2); } ; +bookpart_block: + BOOKPART '{' bookpart_body '}' { + $$ = $3; + PARSER->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), SCM_BOOL_F); + } + ; + +bookpart_body: + { + $$ = new Book; + $$->origin ()->set_spot (@$); + PARSER->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $$->self_scm ()); + } + | BOOK_IDENTIFIER { + $$ = unsmob_book ($1); + $$->protect (); + $$->origin ()->set_spot (@$); + PARSER->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $1); + } + | bookpart_body paper_block { + $$->paper_ = $2; + $2->unprotect (); + } + | bookpart_body score_block { + Score *score = $2; + SCM proc = PARSER->lexer_->lookup_identifier ("bookpart-score-handler"); + scm_call_2 (proc, $$->self_scm (), score->self_scm ()); + score->unprotect (); + } + | bookpart_body composite_music { + Music *music = unsmob_music ($2); + SCM proc = PARSER->lexer_->lookup_identifier ("bookpart-music-handler"); + scm_call_3 (proc, PARSER->self_scm (), $$->self_scm (), music->self_scm ()); + } + | bookpart_body full_markup { + SCM proc = PARSER->lexer_->lookup_identifier ("bookpart-text-handler"); + scm_call_2 (proc, $$->self_scm (), scm_list_1 ($2)); + } + | bookpart_body full_markup_list { + SCM proc = PARSER->lexer_->lookup_identifier ("bookpart-text-handler"); + scm_call_2 (proc, $$->self_scm (), $2); + } + | bookpart_body lilypond_header { + $$->header_ = $2; + } + | bookpart_body error { + $$->paper_ = 0; + $$->scores_ = SCM_EOL; + } + | bookpart_body object_id_setting { + $$->user_key_ = ly_scm2string ($2); + } + ; + score_block: SCORE '{' score_body '}' { $$ = $3; @@ -970,6 +1065,9 @@ function_arglist_nonmusic_last: EXPECT_MARKUP function_arglist full_markup { $$ = scm_cons ($3, $2); } + | EXPECT_MARKUP function_arglist simple_string { + $$ = scm_cons ($3, $2); + } | EXPECT_SCM function_arglist function_scm_argument { $$ = scm_cons ($3, $2); } @@ -981,6 +1079,9 @@ function_arglist_nonmusic: EXPECT_NO_MORE_ARGS { | EXPECT_MARKUP function_arglist_nonmusic full_markup { $$ = scm_cons ($3, $2); } + | EXPECT_MARKUP function_arglist_nonmusic simple_string { + $$ = scm_cons ($3, $2); + } | EXPECT_SCM function_arglist_nonmusic function_scm_argument { $$ = scm_cons ($3, $2); } @@ -1185,7 +1286,7 @@ property_operation: $$ = scm_list_2 (ly_symbol2scm ("unset"), scm_string_to_symbol ($2)); } - | OVERRIDE simple_string property_path '=' embedded_scm { + | OVERRIDE simple_string property_path '=' scalar { $$ = scm_append (scm_list_2 (scm_list_3 (ly_symbol2scm ("push"), scm_string_to_symbol ($2), $5), $3)); @@ -1316,6 +1417,11 @@ event_chord: /* TODO: Create a special case that avoids the creation of EventChords around simple_elements that have no post_events? */ + /* event_chords like simple notes, note chords, etc, are + saved into PARSER->lexer_->chord_repetition_ so that + the chord repetition mechanism can copy them when a + chord repetition symbol is found + */ simple_chord_elements post_events { SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL)); @@ -1324,6 +1430,15 @@ event_chord: * i = @$; */ i.set_location (@1, @2); $$ = MAKE_SYNTAX ("event-chord", i, elts); + PARSER->lexer_->chord_repetition_.last_chord_ = $$; + } + | CHORD_REPETITION optional_notemode_duration post_events { + Input i; + i.set_location (@1, @3); + $$ = MAKE_SYNTAX ("repetition-chord", i, + PARSER->lexer_->chord_repetition_.last_chord_, + PARSER->lexer_->chord_repetition_.repetition_function_, + $2, $3); } | MULTI_MEASURE_REST optional_notemode_duration post_events { Input i; @@ -1331,7 +1446,9 @@ event_chord: $$ = MAKE_SYNTAX ("multi-measure-rest", i, $2, $3); } | command_element - | note_chord_element + | note_chord_element { + PARSER->lexer_->chord_repetition_.last_chord_ = $$; + } ;