X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=1c7fb5b0d10418decfd04339e1dc7ff87868ee11;hb=7ea5c74058200ace4b405de82e1088560aeaacb2;hp=9e57da52ec72a3d790340d5427b8af34a4197496;hpb=858d0f2c153228aa9088824a89f3dfcb54a3a0a4;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index 9e57da52ec..1c7fb5b0d1 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -5,25 +5,50 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2001 Han-Wen Nienhuys + (c) 1997--2003 Han-Wen Nienhuys Jan Nieuwenhuizen */ /* Two shift/reduce problems: - - - - + +1. foo = bar. + + "bar" -> String -> Lyric -> Music -> music-assignment + + "bar" -> String -> string-assignment + + +2. \repeat + \repeat .. \alternative + + + \repeat { \repeat .. \alternative } + +or + + \repeat { \repeat } \alternative + +) + +--hwn + */ /* -the rules for who is protecting what are very shady. TODO: uniformise -this. +TODO: + +* The rules for who is protecting what are very shady. Uniformise + this. + +* There are too many lexical modes? */ #include +#include #include "translator-def.hh" #include "lily-guile.hh" @@ -45,6 +70,29 @@ this. #include "chord.hh" #include "ly-modules.hh" #include "music-sequence.hh" +#include "input-smob.hh" +#include "event.hh" +#include "text-item.hh" + + + +#define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x)) + + + +#define YYERROR_VERBOSE 1 + +My_lily_parser* my_lily_parser; +#define YYPARSE_PARAM my_lily_parser +#define YYLEX_PARAM my_lily_parser +#define THIS\ + ((My_lily_parser *) my_lily_parser) + +#define yyerror THIS->parser_error + + + + bool regular_identifier_b (SCM id) @@ -61,6 +109,15 @@ regular_identifier_b (SCM id) return v; } +SCM +make_simple_markup (SCM a) +{ + static SCM simple; + if (!simple) + simple = scm_c_eval_string ("simple-markup"); + + return scm_list_n (simple, a, SCM_UNDEFINED); +} bool @@ -80,8 +137,6 @@ set_music_properties (Music *p, SCM a) -#define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x)) - Music* set_property_music (SCM sym, SCM value) { @@ -91,34 +146,6 @@ set_property_music (SCM sym, SCM value) return p; } -Music* -make_span_req (SCM name) -{ - static SCM proc; - if (!proc) - proc = scm_c_eval_string ("old-span-event->event"); - SCM m = scm_call_1 (proc, name); - scm_gc_protect_object (m); - return unsmob_music (m); -} - -// needed for bison.simple's malloc () and free () - -// #include -#include - - - -#define YYERROR_VERBOSE 1 - -My_lily_parser* my_lily_parser; -#define YYPARSE_PARAM my_lily_parser -#define YYLEX_PARAM my_lily_parser -#define THIS\ - ((My_lily_parser *) my_lily_parser) - -#define yyerror THIS->parser_error - %} /* We use SCMs to do strings, because it saves us the trouble of @@ -127,13 +154,9 @@ of the parse stack onto the heap. */ %union { - - Link_array *reqvec; - - String *string; // needed by the lexer as temporary scratch area. + String * string; Music *music; Score *score; - Scheme_hash_table *scmhash; Music_output_def * outputdef; SCM scm; int i; @@ -147,6 +170,7 @@ yylex (YYSTYPE *s, void * v) My_lily_lexer * lex = pars->lexer_; lex->lexval = (void*) s; + lex->prepare_for_next_token(); return lex->yylex (); } @@ -158,17 +182,15 @@ yylex (YYSTYPE *s, void * v) /* tokens which are not keywords */ %token AUTOCHANGE %token ALIAS +%token APPLYCONTEXT %token APPLY -%token ARPEGGIO %token ACCEPTS %token ALTERNATIVE %token BAR %token BREATHE %token CHORDMODIFIERS %token CHORDS -%token CHAR_T %token CLEF -%token CM_T %token CONSISTS %token DURATION %token SEQUENTIAL @@ -176,22 +198,18 @@ yylex (YYSTYPE *s, void * v) %token SIMULTANEOUS %token CONSISTSEND %token DENIES -%token DURATION %token EXTENDER %token FIGURES FIGURE_OPEN FIGURE_CLOSE %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN -%token GLISSANDO %token GRACE %token HEADER %token HYPHEN -%token IN_T %token INVALID %token KEY %token LYRICS %token MARK %token MULTI_MEASURE_REST %token MIDI -%token MM_T %token PITCH %token DEFAULT %token NAME @@ -200,10 +218,8 @@ yylex (YYSTYPE *s, void * v) %token ONCE %token PAPER %token PARTIAL -%token PENALTY %token PROPERTY %token OVERRIDE SET REVERT -%token PT_T %token RELATIVE %token REMOVE %token REPEAT @@ -211,10 +227,8 @@ yylex (YYSTYPE *s, void * v) %token PARTCOMBINE %token SCM_T %token SCORE -%token SCRIPT %token SKIP %token SPANREQUEST -%token STYLESHEET %token COMMANDSPANREQUEST %token TEMPO %token OUTPUTPROPERTY @@ -227,6 +241,10 @@ yylex (YYSTYPE *s, void * v) %token CONTEXT %token REST +%token CHORD_OPEN +%token CHORD_CLOSE + + /* escaped */ %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE @@ -245,11 +263,12 @@ yylex (YYSTYPE *s, void * v) %token DURATION_IDENTIFIER %token FRACTION %token IDENTIFIER +%token CHORDNAMES CHORDNAMES_IDENTIFIER +%type chordnames_block chordnames_list chord_scm %token SCORE_IDENTIFIER %token MUSIC_OUTPUT_DEF_IDENTIFIER - %token NUMBER_IDENTIFIER %token EVENT_IDENTIFIER %token MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER @@ -260,6 +279,17 @@ yylex (YYSTYPE *s, void * v) %token UNSIGNED %token REAL +%token MARKUP +%token MARKUP_HEAD_MARKUP0 +%token MARKUP_HEAD_MARKUP0_MARKUP1 +%token MARKUP_HEAD_SCM0 +%token MARKUP_HEAD_SCM0_MARKUP1 +%token MARKUP_HEAD_SCM0_SCM1 +%token MARKUP_HEAD_SCM0_SCM1_MARKUP2 + +%token MARKUP_IDENTIFIER MARKUP_HEAD_LIST0 +%type markup markup_line markup_list markup_list_body full_markup + %type output_def %type lilypond_header lilypond_header_body %type open_event_parens close_event_parens open_event close_event @@ -273,12 +303,14 @@ yylex (YYSTYPE *s, void * v) %type script_dir %type identifier_init +%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 pre_events post_events +%type pre_events post_events %type gen_text_def -%type steno_pitch pitch absolute_pitch +%type steno_pitch pitch absolute_pitch pitch_also_in_chords %type explicit_pitch steno_tonic_pitch %type chord_additions chord_subtractions chord_notes chord_step @@ -299,7 +331,6 @@ yylex (YYSTYPE *s, void * v) %type hyphen_req %type string_event %type string bare_number number_expression number_term number_factor - %type score_block score_body %type translator_spec_block translator_spec_body @@ -348,9 +379,6 @@ toplevel_expression: else if (dynamic_cast ($1)) THIS->lexer_->set_identifier (scm_makfrom0str ("$defaultmidi"), $1->self_scm ()); } - | embedded_scm { - // junk value - } ; embedded_scm: @@ -379,7 +407,6 @@ notenames_body: else scm_hashq_set_x (tab, ly_caar (s), pt); } - $$ = tab; } ; @@ -430,6 +457,7 @@ all objects can be unprotected as soon as they're here. */ } + | embedded_scm { } ; @@ -439,6 +467,9 @@ identifier_init: $$ = $1->self_scm (); scm_gc_unprotect_object ($$); } + | full_markup { + $$ = $1; + } | output_def { $$ = $1->self_scm (); scm_gc_unprotect_object ($$); @@ -466,8 +497,39 @@ identifier_init: | embedded_scm { $$ = $1; } + | chordnames_block { + $$ = $1; + } ; +chordnames_block: + CHORDNAMES '{' + { THIS->lexer_->push_chord_state (); } + chordnames_list + { THIS->lexer_->pop_state (); } + '}' + { + $$ = $4; + } + ; + +chordnames_list: + /* empty */ { + $$ = SCM_EOL; + } + | CHORDNAMES_IDENTIFIER chordnames_list { + $$ = scm_append (scm_list_2 ($1, $2)); + } + | chord_scm '=' full_markup chordnames_list { + $$ = scm_cons (scm_cons ($1, $3), $4); + }; + +chord_scm: + steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass { + $$ = Chord::tonic_add_sub_to_pitches ($1, $3, $4); + /* junk bass and inversion for now */ + }; + translator_spec_block: TRANSLATOR '{' translator_spec_body '}' { @@ -477,7 +539,7 @@ translator_spec_block: translator_spec_body: TRANSLATOR_IDENTIFIER { - $$ = unsmob_translator_def ($1)->clone_scm (); + $$ = $1; unsmob_translator_def ($$)-> set_spot (THIS->here_input ()); } | TYPE STRING { @@ -568,7 +630,7 @@ score_body: } | SCORE_IDENTIFIER { - $$ = new Score (*unsmob_score ($1)); + $$ = unsmob_score ($1); $$->set_spot (THIS->here_input ()); } | score_body lilypond_header { @@ -614,21 +676,21 @@ music_output_def_body: p = dynamic_cast (id->clone ()); else p = new Paper_def; - THIS-> lexer_->add_scope (p->scope_); + + THIS->lexer_->add_scope (p->scope_); $$ = p; } | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER { - Music_output_def *p = unsmob_music_output_def ($3); - p = p->clone (); - THIS->lexer_->add_scope (p->scope_); - $$ = p; + Music_output_def * o = unsmob_music_output_def ($3); + $$ =o; + + THIS->lexer_->add_scope (o->scope_); } | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER { - Music_output_def *p = unsmob_music_output_def ($3); - p = p->clone (); + Music_output_def * o = unsmob_music_output_def ($3); + $$ = o; - THIS->lexer_->add_scope (p->scope_); - $$ = p; + THIS->lexer_->add_scope (o->scope_); } | music_output_def_body assignment { @@ -636,16 +698,13 @@ music_output_def_body: | music_output_def_body translator_spec_block { $$->assign_translator ($2); } - | music_output_def_body STYLESHEET embedded_scm { - dynamic_cast ($$)-> style_sheet_ = $3; - } | music_output_def_body tempo_event { /* junk this ? there already is tempo stuff in music. */ int m = gh_scm2int ( $2->get_mus_property ("metronome-count")); - Duration *d = unsmob_duration ($2->get_mus_property ("duration")); + Duration *d = unsmob_duration ($2->get_mus_property ("tempo-unit")); Midi_def * md = dynamic_cast ($$); if (md) md->set_tempo (d->get_length (), m); @@ -658,7 +717,7 @@ music_output_def_body: tempo_event: TEMPO steno_duration '=' bare_unsigned { $$ = MY_MAKE_MUSIC("TempoEvent"); - $$->set_mus_property ("duration", $2); + $$->set_mus_property ("tempo-unit", $2); $$->set_mus_property ("metronome-count", gh_int2scm ( $4)); } ; @@ -670,12 +729,13 @@ The representation of a list is the to have efficient append. */ -Music_list: /* empty */ { +Music_list: + /* empty */ { $$ = scm_cons (SCM_EOL, SCM_EOL); } | Music_list Music { SCM s = $$; - SCM c = scm_cons ($2->self_scm (), SCM_EOL); + SCM c = scm_cons ($2->self_scm (), SCM_EOL); scm_gc_unprotect_object ($2->self_scm ()); /* UGH */ if (gh_pair_p (ly_cdr (s))) gh_set_cdr_x (ly_cdr (s), c); /* append */ @@ -778,6 +838,13 @@ Simultaneous_music: Simple_music: event_chord { $$ = $1; } + | APPLYCONTEXT embedded_scm { + if (!gh_procedure_p ($2)) + THIS->parser_error (_ ("\applycontext takes function argument")); + $$ = MY_MAKE_MUSIC ("ApplyContext"); + $$->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)) @@ -798,9 +865,7 @@ Simple_music: $$ = m; } | MUSIC_IDENTIFIER { - $$ = unsmob_music ($1)->clone (); - - $$->set_spot (THIS->here_input()); + $$ = unsmob_music ($1); } | property_def | translator_change @@ -904,25 +969,16 @@ Composite_music: | Repeated_music { $$ = $1; } | Simultaneous_music { $$ = $1; } | Sequential_music { $$ = $1; } - | TRANSPOSE pitch Music { + | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music { $$ = MY_MAKE_MUSIC("TransposedMusic"); - Music *p = $3; - Pitch pit = *unsmob_pitch ($2); + Music *p = $4; + Pitch from = *unsmob_pitch ($2); + Pitch to = *unsmob_pitch ($3); - p->transpose (pit); + p->transpose (interval (from, to)); $$->set_mus_property ("element", p->self_scm ()); scm_gc_unprotect_object (p->self_scm ()); } - | TRANSPOSE steno_tonic_pitch Music { - $$ = MY_MAKE_MUSIC("TransposedMusic"); - Music *p = $3; - Pitch pit = *unsmob_pitch ($2); - - p->transpose (pit); - $$->set_mus_property ("element", p->self_scm ()); - scm_gc_unprotect_object (p->self_scm ()); - - } | APPLY embedded_scm Music { SCM ret = gh_call1 ($2, $3->self_scm ()); Music *m = unsmob_music (ret); @@ -1136,6 +1192,7 @@ scalar: string { $$ = $1; } | bare_int { $$ = gh_int2scm ($1); } | embedded_scm { $$ = $1; } + | full_markup { $$ = $1; } ; @@ -1143,19 +1200,67 @@ event_chord: pre_events { THIS->push_spot (); } /*cont */ simple_element post_events { - Music_sequence *l = dynamic_cast ($3); - - $1->concat (*$4); - for (int i=0; i < $1->size (); i++) { - Music * m = $1->elem (i); - l->append_music (m); - } - $$ = $3; + SCM elts = $3-> get_mus_property ("elements"); + + elts = gh_append3 (elts, scm_reverse_x ($1, SCM_EOL), + scm_reverse_x ($4, SCM_EOL)); - delete $1; - delete $4; + $3-> set_mus_property ("elements", elts); + $$ = $3; } | command_element + | note_chord_element + ; + + +note_chord_element: + chord_body optional_notemode_duration post_events + { + SCM dur = unsmob_duration ($2)->smobbed_copy(); + SCM es = $1->get_mus_property ("elements"); + SCM postevs = scm_reverse_x ($3, SCM_EOL); + + for (SCM s = es; gh_pair_p (s); s = gh_cdr (s)) + unsmob_music (gh_car(s))->set_mus_property ("duration", dur); + es = gh_append2 (es, postevs); + + $1-> set_mus_property ("elements", es); + $$ = $1; + } + ; + +chord_body: + CHORD_OPEN chord_body_elements CHORD_CLOSE + { + $$ = MY_MAKE_MUSIC("EventChord"); + $$->set_mus_property ("elements", + scm_reverse_x ($2, SCM_EOL)); + } + ; + +chord_body_elements: + /* empty */ { $$ = SCM_EOL; } + | chord_body_elements chord_body_element { + $$ = gh_cons ($2->self_scm(), $1); + scm_gc_unprotect_object ($2->self_scm()); + } + ; + +chord_body_element: + pitch exclamations questions post_events + { + Music * n = MY_MAKE_MUSIC("NoteEvent"); + n->set_mus_property ("pitch", $1); + if ($3 % 2) + n->set_mus_property ("cautionary", SCM_BOOL_T); + 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); + + $$ = n; + } ; command_element: @@ -1174,7 +1279,7 @@ command_element: $$ = MY_MAKE_MUSIC("EventChord"); $$->set_mus_property ("elements", scm_cons (l->self_scm (), SCM_EOL)); - scm_gc_unprotect_object (l->self_scm()); + scm_gc_unprotect_object (l->self_scm()); $$->set_spot (THIS->here_input ()); } | E_RIGHTSQUARE { @@ -1185,8 +1290,7 @@ command_element: $$ = MY_MAKE_MUSIC("EventChord"); $$->set_mus_property ("elements", scm_cons (l->self_scm (), SCM_EOL)); $$->set_spot (THIS->here_input ()); - scm_gc_unprotect_object (l->self_scm()); - + scm_gc_unprotect_object (l->self_scm()); } | E_BACKSLASH { $$ = MY_MAKE_MUSIC("VoiceSeparator"); @@ -1230,34 +1334,13 @@ command_element: $$ = unsmob_music (result); } | TIME_T fraction { - Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2); - - int l = gh_scm2int (ly_car ($2)); - int o = gh_scm2int (ly_cdr ($2)); - - Moment one_beat = Moment (1)/Moment (o); - Moment len = Moment (l) * one_beat; - - - Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ()); - Music *p3 = set_property_music (ly_symbol2scm ("beatLength"), one_beat.smobbed_copy ()); - - SCM list = scm_list_n (p1->self_scm (), p2->self_scm (), p3->self_scm(), SCM_UNDEFINED); - Music *seq = MY_MAKE_MUSIC("SequentialMusic"); - seq->set_mus_property ("elements", list); - - - Music * sp = MY_MAKE_MUSIC("ContextSpeccedMusic"); - sp->set_mus_property ("element", seq->self_scm ()); - - scm_gc_unprotect_object (p3->self_scm ()); - scm_gc_unprotect_object (p2->self_scm ()); - scm_gc_unprotect_object (p1->self_scm ()); - scm_gc_unprotect_object (seq->self_scm ()); - - $$ = sp; + static SCM proc; + if (!proc) + proc = scm_c_eval_string ("make-time-signature-set"); - sp-> set_mus_property ("context-type", scm_makfrom0str ( "Timing")); + SCM result = scm_apply_2 (proc, gh_car ($2), gh_cdr ($2), SCM_EOL); + scm_gc_protect_object (result); + $$ = unsmob_music (result); } ; @@ -1278,10 +1361,8 @@ shorthand_command_req: } | '[' { Music *b= MY_MAKE_MUSIC("BeamEvent"); - b->set_mus_property ("span-direction", gh_int2scm (START)) -; - $$ =b; - + b->set_mus_property ("span-direction", gh_int2scm (START)); + $$ = b; THIS->last_beam_start_ = b->self_scm (); } @@ -1299,13 +1380,7 @@ shorthand_command_req: ; verbose_command_req: - COMMANDSPANREQUEST bare_int STRING { - Music *sp = make_span_req ($3); - sp->set_mus_property ("span-direction", gh_int2scm (Direction ($2))); - sp->set_spot (THIS->here_input ()); - $$ = sp; - } - | MARK DEFAULT { + MARK DEFAULT { Music * m = MY_MAKE_MUSIC("MarkEvent"); $$ = m; } @@ -1314,16 +1389,6 @@ verbose_command_req: m->set_mus_property ("label", $2); $$ = m; } - | PENALTY SCM_T { - Music * b = MY_MAKE_MUSIC("BreakEvent"); - SCM s = $2; - if (!gh_number_p (s)) - s = gh_int2scm (0); - - b->set_mus_property ("penalty", s); - b->set_spot (THIS->here_input ()); - $$ = b; - } | SKIP duration_length { Music * skip = MY_MAKE_MUSIC("SkipEvent"); skip->set_mus_property ("duration", $2); @@ -1341,18 +1406,21 @@ verbose_command_req: Music *key= MY_MAKE_MUSIC("KeyChangeEvent"); key->set_mus_property ("pitch-alist", $3); + key->set_mus_property ("tonic", Pitch (0,0,0).smobbed_copy()); ((Music*)key)->transpose (* unsmob_pitch ($2)); - $$ = key; + + $$ = key; } ; post_events: - { - $$ = new Link_array; + /* empty */ { + $$ = SCM_EOL; } | post_events post_event { $2->set_spot (THIS->here_input ()); - $$->push ($2); + $$ = gh_cons ($2->self_scm(), $$); + scm_gc_unprotect_object ($2->self_scm()); } ; @@ -1363,7 +1431,6 @@ post_event: | string_event ; - string_event: E_UNSIGNED { Music * s = MY_MAKE_MUSIC("StringNumberEvent"); @@ -1379,6 +1446,23 @@ event_that_take_dir: | verbose_event | close_event | open_event + | '[' { + Music * m = MY_MAKE_MUSIC ("NewBeamEvent"); + m->set_spot (THIS->here_input()); + m->set_mus_property ("span-direction" , gh_int2scm (START)); + $$ = m; + } + | ']' { + Music * m = MY_MAKE_MUSIC ("NewBeamEvent"); + m->set_spot (THIS->here_input()); + m->set_mus_property ("span-direction" , gh_int2scm (STOP)); + $$ = m; + } + | '~' { + Music * m = MY_MAKE_MUSIC ("NewTieEvent"); + m->set_spot (THIS->here_input()); + $$ = m; + } | script_abbreviation { SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1)); Music *a = MY_MAKE_MUSIC("ArticulationEvent"); @@ -1398,14 +1482,7 @@ event_with_dir: verbose_event: EVENT_IDENTIFIER { - $$ = unsmob_music ($1)->clone (); - $$->set_spot (THIS->here_input ()); - } - | SPANREQUEST bare_int STRING { - Music * sp = make_span_req ($3); - sp->set_mus_property ("span-direction", gh_int2scm ( $2)); - sp->set_spot (THIS->here_input ()); - $$ = sp; + $$ = unsmob_music ($1); } | tremolo_type { Music * a = MY_MAKE_MUSIC("TremoloEvent"); @@ -1413,26 +1490,6 @@ verbose_event: a->set_mus_property ("tremolo-type", gh_int2scm ($1)); $$ = a; } - | SCRIPT STRING { - Music * a = MY_MAKE_MUSIC("ArticulationEvent"); - a->set_mus_property ("articulation-type", $2); - a->set_spot (THIS->here_input ()); - $$ = a; - } - - /* - duh, junk this syntax from the parser, if possible. - */ - | ARPEGGIO { - Music *a = MY_MAKE_MUSIC("ArpeggioEvent"); - a->set_spot (THIS->here_input ()); - $$ = a; - } - | GLISSANDO { - Music *g = MY_MAKE_MUSIC("GlissandoEvent"); - g->set_spot /* No pun intended */ (THIS->here_input ()); - $$ = g; - } ; sup_quotes: @@ -1459,15 +1516,13 @@ steno_pitch: } | NOTENAME_PITCH sup_quotes { Pitch p = *unsmob_pitch ($1); - p.octave_ += $2; + p = p.transposed (Pitch ($2,0,0)); $$ = p.smobbed_copy (); } | NOTENAME_PITCH sub_quotes { Pitch p =* unsmob_pitch ($1); - - p.octave_ += -$2; + p = p.transposed (Pitch (-$2,0,0)); $$ = p.smobbed_copy (); - } ; @@ -1481,15 +1536,14 @@ steno_tonic_pitch: } | TONICNAME_PITCH sup_quotes { Pitch p = *unsmob_pitch ($1); - p.octave_ += $2; + p = p.transposed (Pitch ($2,0,0)); $$ = p.smobbed_copy (); } | TONICNAME_PITCH sub_quotes { Pitch p =* unsmob_pitch ($1); - p.octave_ += -$2; + p = p.transposed (Pitch (-$2,0,0)); $$ = p.smobbed_copy (); - } ; @@ -1502,6 +1556,11 @@ pitch: } ; +pitch_also_in_chords: + pitch + | steno_tonic_pitch + ; + explicit_pitch: PITCH embedded_scm { $$ = $2; @@ -1607,18 +1666,22 @@ gen_text_def: t->set_spot (THIS->here_input ()); $$ = t; } - | string { + | full_markup { Music *t = MY_MAKE_MUSIC("TextScriptEvent"); t->set_mus_property ("text", $1); t->set_spot (THIS->here_input ()); + $$ = t; + } + | string { + Music *t = MY_MAKE_MUSIC("TextScriptEvent"); + t->set_mus_property ("text", make_simple_markup ($1)); + t->set_spot (THIS->here_input ()); $$ = t; + } | DIGIT { - String ds = to_string ($1); - Music * t = MY_MAKE_MUSIC("TextScriptEvent"); - SCM finger = ly_symbol2scm ("finger"); - t->set_mus_property ("text", scm_makfrom0str (ds.to_str0 ())); - t->set_mus_property ("text-type" , finger); + Music * t = MY_MAKE_MUSIC("FingerEvent"); + t->set_mus_property ("digit", gh_int2scm ($1)); t->set_spot (THIS->here_input ()); $$ = t; } @@ -1655,11 +1718,12 @@ script_dir: ; pre_events: - { - $$ = new Link_array; + /* empty */ { + $$ = SCM_EOL; } | pre_events open_event { - $$->push ($2); + $$ = gh_cons ($2->self_scm(), $$); + scm_gc_unprotect_object ($2->self_scm()); } ; @@ -1710,7 +1774,9 @@ steno_duration: | DURATION_IDENTIFIER dots { Duration *d =unsmob_duration ($1); Duration k (d->duration_log (),d->dot_count () + $2); - $$ = k.smobbed_copy (); + + *d = k; + $$ = $1; } ; @@ -1760,6 +1826,10 @@ tremolo_type: ; + +/***************************************************************** + BASS FIGURES +*****************************************************************/ bass_number: DIGIT | UNSIGNED @@ -1871,30 +1941,27 @@ simple_element: Input i = THIS->pop_spot (); m->set_spot (i); for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = ly_cdr (s)) - { - unsmob_music (ly_car (s))->set_mus_property ("duration", $2); - } + { + unsmob_music (ly_car (s))->set_mus_property ("duration", $2); + } $$ = m; } | RESTNAME optional_notemode_duration { Input i = THIS->pop_spot (); - SCM e = SCM_UNDEFINED; + Music * ev = 0; if (ly_scm2string ($1) =="s") { /* Space */ - Music * skip = MY_MAKE_MUSIC("SkipEvent"); - skip->set_mus_property ("duration" ,$2); - skip->set_spot (i); - e = skip->self_scm (); + ev = MY_MAKE_MUSIC("SkipEvent"); } - else { - Music * rest_req = MY_MAKE_MUSIC("RestEvent"); - rest_req->set_mus_property ("duration", $2); - rest_req->set_spot (i); - e = rest_req->self_scm (); + else { + ev = MY_MAKE_MUSIC("RestEvent"); + } + ev->set_mus_property ("duration" ,$2); + ev->set_spot (i); Music * velt = MY_MAKE_MUSIC("EventChord"); - velt-> set_mus_property ("elements", scm_list_n (e,SCM_UNDEFINED)); + velt->set_mus_property ("elements", scm_list_n (ev->self_scm (),SCM_UNDEFINED)); velt->set_spot (i); $$ = velt; @@ -1902,25 +1969,14 @@ simple_element: | MULTI_MEASURE_REST optional_notemode_duration { THIS->pop_spot (); - Music * sk = MY_MAKE_MUSIC("SkipEvent"); - sk->set_mus_property ("duration", $2); - Music *sp1 = MY_MAKE_MUSIC("MultiMeasureRestEvent"); - Music *sp2 = MY_MAKE_MUSIC("MultiMeasureRestEvent"); - sp1-> set_mus_property ("span-direction", gh_int2scm (START)) -; - sp2-> set_mus_property ("span-direction", gh_int2scm (STOP)) -; - Music *rqc1 = MY_MAKE_MUSIC("EventChord"); - rqc1->set_mus_property ("elements", scm_list_n (sp1->self_scm (), SCM_UNDEFINED)); - Music *rqc2 = MY_MAKE_MUSIC("EventChord"); - rqc2->set_mus_property ("elements", scm_list_n (sk->self_scm (), SCM_UNDEFINED));; - Music *rqc3 = MY_MAKE_MUSIC("EventChord"); - rqc3->set_mus_property ("elements", scm_list_n (sp2->self_scm (), SCM_UNDEFINED));; - - SCM ms = scm_list_n (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED); + static SCM proc ; + if (!proc) + proc = scm_c_eval_string ("make-multi-measure-rest"); - $$ = MY_MAKE_MUSIC("SequentialMusic"); - $$->set_mus_property ("elements", ms); + SCM mus = scm_call_2 (proc, $2, + make_input (THIS->here_input())); + scm_gc_protect_object (mus); + $$ = unsmob_music (mus); } | STRING optional_notemode_duration { Input i = THIS->pop_spot (); @@ -2011,27 +2067,17 @@ chord_step: chord_note: bare_unsigned { - Pitch m; - m.notename_ = ($1 - 1) % 7; - m.octave_ = $1 > 7 ? 1 : 0; - m.alteration_ = 0; + Pitch m($1 > 7 ? 1 : 0, ($1 - 1) % 7, 0); $$ = m.smobbed_copy (); } | bare_unsigned '+' { - Pitch m; - m.notename_ = ($1 - 1) % 7; - m.octave_ = $1 > 7 ? 1 : 0; - m.alteration_ = 1; - + Pitch m( $1 > 7 ? 1 : 0,($1 - 1) % 7, 1); $$ = m.smobbed_copy (); } | bare_unsigned CHORD_MINUS { - Pitch m; - m.notename_ = ($1 - 1) % 7; - m.octave_ = $1 > 7 ? 1 : 0; - m.alteration_ = -1; + Pitch m( $1 > 7 ? 1 : 0,($1 - 1) % 7, -1); $$ = m.smobbed_copy (); } @@ -2080,20 +2126,11 @@ bare_number: | NUMBER_IDENTIFIER { $$ = $1; } - | REAL CM_T { - $$ = gh_double2scm (gh_scm2double ($1) CM ); - } - | REAL PT_T { - $$ = gh_double2scm (gh_scm2double ($1) PT); - } - | REAL IN_T { - $$ = gh_double2scm (gh_scm2double ($1) INCH); - } - | REAL MM_T { - $$ = gh_double2scm (gh_scm2double ($1) MM); + | REAL NUMBER_IDENTIFIER { + $$ = gh_double2scm (gh_scm2double ($1) * gh_scm2double ($2)); } - | REAL CHAR_T { - $$ = gh_double2scm (gh_scm2double ($1) CHAR); + | UNSIGNED NUMBER_IDENTIFIER { + $$ = gh_double2scm ($1 * gh_scm2double ($2)); } ; @@ -2149,13 +2186,79 @@ questions: ; + +full_markup: + MARKUP_IDENTIFIER { + $$ = $1; + } + | MARKUP + { THIS->lexer_->push_markup_state (); } + markup + { $$ = $3; + THIS->lexer_->pop_state (); + } + ; + +markup: + STRING { + $$ = make_simple_markup ($1); + } + | MARKUP_HEAD_MARKUP0 markup { + $$ = scm_list_n ($1, $2, SCM_UNDEFINED); + } + | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup { + $$ = scm_list_n ($1, $2, $3, SCM_UNDEFINED); + } + | MARKUP_HEAD_SCM0_MARKUP1 SCM_T markup { + $$ = scm_list_n ($1, $2, $3, SCM_UNDEFINED); + } + | markup_line { + $$ = $1; + } + | MARKUP_HEAD_LIST0 markup_list { + $$ = scm_list_n ($1,$2, SCM_UNDEFINED); + } + | MARKUP_HEAD_SCM0 embedded_scm { + $$ = scm_list_n ($1, $2, SCM_UNDEFINED); + } + | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm markup { + $$ = scm_list_n ($1, $2, $3, $4, SCM_UNDEFINED); + } + | MARKUP_IDENTIFIER { + $$ = $1; + } + + ; + +markup_list: + CHORD_OPEN markup_list_body CHORD_CLOSE { $$ = scm_reverse_x ($2, SCM_EOL); } + ; + +markup_line: + '{' markup_list_body '}' { + static SCM line ; + if (!line) + line = scm_c_eval_string ("line-markup"); + + $$ = scm_list_n (line, scm_reverse_x ($2, SCM_EOL), SCM_UNDEFINED); + } + ; + +markup_list_body: + /**/ { $$ = SCM_EOL; } + | markup_list_body markup { + $$ = gh_cons ($2, $1) ; + } + ; + + %% void My_lily_parser::set_yydebug (bool ) { #if 0 - yydebug = b; + yydebug = 1; #endif } @@ -2164,7 +2267,6 @@ extern My_lily_parser * current_parser; void My_lily_parser::do_yyparse () { - current_parser = this;; yyparse ((void*)this); } @@ -2180,6 +2282,7 @@ which is entirely legitimate. Or we can scrap it. Barchecks should detect wrong durations, and skipTypesetting speeds it up a lot. */ + void My_lily_parser::beam_check (SCM dur) { @@ -2191,3 +2294,55 @@ My_lily_parser::beam_check (SCM dur) } last_beam_start_ = SCM_EOL; } + + + +bool +markup_p (SCM x) +{ + return gh_pair_p (x) + && SCM_BOOL_F != scm_object_property (gh_car (x), ly_symbol2scm ("markup-signature")); +} +/* +It is a little strange, to have this function in this file, but +otherwise, we have to import music classes into the lexer. + +*/ +int +My_lily_lexer::try_special_identifiers (SCM * destination, SCM sid) +{ + if (gh_string_p (sid)) { + *destination = sid; + return STRING_IDENTIFIER; + } else if (gh_number_p (sid)) { + *destination = sid; + return NUMBER_IDENTIFIER; + } else if (unsmob_translator_def (sid)) { + *destination = unsmob_translator_def (sid)->clone_scm(); + return TRANSLATOR_IDENTIFIER; + } else if (unsmob_score (sid)) { + Score *sc = new Score (*unsmob_score (sid)); + *destination =sc->self_scm (); + return SCORE_IDENTIFIER; + } else if (Music * mus =unsmob_music (sid)) { + *destination = unsmob_music (sid)->clone ()->self_scm(); + unsmob_music (*destination)-> + set_mus_property ("origin", make_input (last_input_)); + return dynamic_cast (mus) + ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER; + } else if (unsmob_duration (sid)) { + *destination = unsmob_duration (sid)->smobbed_copy(); + return DURATION_IDENTIFIER; + } else if (unsmob_music_output_def (sid)) { + Music_output_def *p = unsmob_music_output_def (sid); + p = p->clone (); + + *destination = p->self_scm(); + return MUSIC_OUTPUT_DEF_IDENTIFIER; + } else if (new_markup_p (sid)) { + *destination = sid; + return MARKUP_IDENTIFIER; + } + + return -1; +}