Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(15)

Delta Between Two Patch Sets: lily/parser.yy

Issue 557410043: Special-case syntax error of duration before octave marks (Closed)
Left Patch Set: Created 5 years, 1 month ago
Right Patch Set: Han-Wen's suggestion of folding the parser rule was a lot more effort since duration is optional in… Created 5 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* -*- mode: c++; c-file-style: "linux"; indent-tabs-mode: t -*- */ 1 /* -*- mode: c++; c-file-style: "linux"; indent-tabs-mode: t -*- */
2 /* 2 /*
3 This file is part of LilyPond, the GNU music typesetter. 3 This file is part of LilyPond, the GNU music typesetter.
4 4
5 Copyright (C) 1997--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> 5 Copyright (C) 1997--2020 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 Jan Nieuwenhuizen <janneke@gnu.org> 6 Jan Nieuwenhuizen <janneke@gnu.org>
7 7
8 LilyPond is free software: you can redistribute it and/or modify 8 LilyPond is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or 10 the Free Software Foundation, either version 3 of the License, or
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 72
73 or 73 or
74 74
75 \repeat { \repeat } \alternative 75 \repeat { \repeat } \alternative
76 */ 76 */
77 77
78 %nonassoc COMPOSITE 78 %nonassoc COMPOSITE
79 %left ADDLYRICS 79 %left ADDLYRICS
80 80
81 %right ':' UNSIGNED REAL E_UNSIGNED EVENT_IDENTIFIER EVENT_FUNCTION '^' '_' 81 %right ':' UNSIGNED REAL E_UNSIGNED EVENT_IDENTIFIER EVENT_FUNCTION '^' '_'
82 HYPHEN EXTENDER DURATION_IDENTIFIER '!' 82 » HYPHEN EXTENDER DURATION_IDENTIFIER '!' '\'' ','
83 83
84 /* The above are needed for collecting tremoli and other items (that 84 /* The above are needed for collecting tremoli and other items (that
85 could otherwise be interpreted as belonging to the next function 85 could otherwise be interpreted as belonging to the next function
86 argument) greedily, and together with the next rule will serve to 86 argument) greedily, and together with the next rule will serve to
87 join numbers and units greedily instead of allowing them into 87 join numbers and units greedily instead of allowing them into
88 separate function arguments 88 separate function arguments
89 */ 89 */
90 90
91 %nonassoc NUMBER_IDENTIFIER 91 %nonassoc NUMBER_IDENTIFIER
92 92
(...skipping 3189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3282 3282
3283 octave_check: 3283 octave_check:
3284 /**/ { $$ = SCM_EOL; } 3284 /**/ { $$ = SCM_EOL; }
3285 | '=' quotes { $$ = $2; } 3285 | '=' quotes { $$ = $2; }
3286 ; 3286 ;
3287 3287
3288 quotes: 3288 quotes:
3289 /* empty */ 3289 /* empty */
3290 { 3290 {
3291 $$ = SCM_INUM0; 3291 $$ = SCM_INUM0;
3292 } 3292 » } %prec ':'
3293 » | sub_quotes 3293 » | sub_quotes %prec ':'
3294 | sup_quotes 3294 » | sup_quotes %prec ':'
3295 ; 3295 ;
3296 3296
3297 stray_quotes: 3297 // no quotes, no error: pass *undefined* in that case.
3298 » sub_quotes 3298 erroneous_quotes:
3299 » | sup_quotes 3299 » quotes {
3300 » » if (scm_is_eq (SCM_INUM0, $1))
3301 » » » $$ = SCM_UNDEFINED;
3302 » }
3300 ; 3303 ;
3301 3304
3302 sup_quotes: 3305 sup_quotes:
3303 '\'' { 3306 '\'' {
3304 $$ = scm_from_int (1); 3307 $$ = scm_from_int (1);
3305 } 3308 }
3306 | sup_quotes '\'' { 3309 | sup_quotes '\'' {
3307 $$ = scm_oneplus ($1); 3310 $$ = scm_oneplus ($1);
3308 } 3311 }
3309 ; 3312 ;
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
3620 $$ = scm_cons ($2, $1); 3623 $$ = scm_cons ($2, $1);
3621 } 3624 }
3622 ; 3625 ;
3623 3626
3624 optional_rest: 3627 optional_rest:
3625 /**/ { $$ = SCM_BOOL_F; } 3628 /**/ { $$ = SCM_BOOL_F; }
3626 | REST { $$ = SCM_BOOL_T; } 3629 | REST { $$ = SCM_BOOL_T; }
3627 ; 3630 ;
3628 3631
3629 pitch_or_music: 3632 pitch_or_music:
3630 » pitch exclamations questions octave_check maybe_notemode_duration option al_rest post_events { 3633 // The erroneous_quotes element is for input such as a1'' which is a
3634 // typical note entry error that we don't want the parser to get
3635 // confused about. The resulting grammar, however, is inconsistent
3636 // enough that accepting it is not doing anybody a favor.
3637 » pitch exclamations questions octave_check maybe_notemode_duration errone ous_quotes optional_rest post_events {
3631 if (!parser->lexer_->is_note_state ()) 3638 if (!parser->lexer_->is_note_state ())
3632 parser->parser_error (@1, _ ("have to be in Note mode fo r notes")); 3639 parser->parser_error (@1, _ ("have to be in Note mode fo r notes"));
3640 if (!SCM_UNBNDP ($6))
3641 {
3642 // It's possible to get here without a
3643 // duration, like when there is no
3644 // octave_check but a question mark. But we
3645 // point out the most frequent error of an
3646 // interspersed duration specifically
3647 if (!SCM_UNBNDP ($5))
3648 parser->parser_error (@6, _ ("octave marks must precede duration"));
3649 else
3650 parser->parser_error (@6, _ ("badly placed octav e marks"));
3651 // Try sorting the quotes to where they likely belong
3652 if (scm_is_number ($4)) {
3653 $4 = scm_sum ($4, $6);
3654 } else {
3655 $1 = unsmob<Pitch> ($1)->transposed
3656 (Pitch (scm_to_int ($6), 0)).smobbed_cop y ();
3657 }
3658 }
3659
3633 if (!SCM_UNBNDP ($2) 3660 if (!SCM_UNBNDP ($2)
3634 || !SCM_UNBNDP ($3) 3661 || !SCM_UNBNDP ($3)
3635 || scm_is_number ($4) 3662 || scm_is_number ($4)
3636 || !SCM_UNBNDP ($5) 3663 || !SCM_UNBNDP ($5)
3637 || scm_is_true ($6) 3664 » » || scm_is_true ($7)
3638 » » || scm_is_pair ($7)) 3665 » » || scm_is_pair ($8))
3639 { 3666 {
3640 Music *n = 0; 3667 Music *n = 0;
3641 » » » if (scm_is_true ($6)) 3668 » » » if (scm_is_true ($7))
3642 n = MY_MAKE_MUSIC ("RestEvent", @$); 3669 n = MY_MAKE_MUSIC ("RestEvent", @$);
3643 else 3670 else
3644 n = MY_MAKE_MUSIC ("NoteEvent", @$); 3671 n = MY_MAKE_MUSIC ("NoteEvent", @$);
3645 3672
3646 n->set_property ("pitch", $1); 3673 n->set_property ("pitch", $1);
3647 if (SCM_UNBNDP ($5)) 3674 if (SCM_UNBNDP ($5))
3648 n->set_property ("duration", 3675 n->set_property ("duration",
3649 parser->default_duration_.smobb ed_copy ()); 3676 parser->default_duration_.smobb ed_copy ());
3650 else 3677 else
3651 n->set_property ("duration", $5); 3678 n->set_property ("duration", $5);
3652 3679
3653 if (scm_is_number ($4)) 3680 if (scm_is_number ($4))
3654 { 3681 {
3655 int q = scm_to_int ($4); 3682 int q = scm_to_int ($4);
3656 n->set_property ("absolute-octave", scm_from_int (q-1)); 3683 n->set_property ("absolute-octave", scm_from_int (q-1));
3657 } 3684 }
3658
3659 if (to_boolean ($3))
3660 n->set_property ("cautionary", SCM_BOOL_T);
3661 if (to_boolean ($2) || to_boolean ($3))
3662 n->set_property ("force-accidental", SCM_BOOL_T) ;
3663 if (scm_is_pair ($7))
3664 n->set_property ("articulations",
3665 scm_reverse_x ($7, SCM_EOL));
3666 $$ = n->unprotect ();
3667 }
3668 } %prec ':'
3669 // Next rule is a frequent note entry error, like c4''
3670 //
3671 // It is quite unlikely that an octave check precedes a
3672 // duration, but we have to keep it in the rule in order not
3673 // to force the parser into early decisions before actually
3674 // seeing a stray quote. So we try to best interpret that
3675 // case as well, even though it's not a likely error case.
3676 | pitch exclamations questions octave_check duration stray_quotes option al_rest post_events {
hanwenn 2020/02/12 06:45:08 why can't this case be folded in to the preceding
dak 2020/02/12 10:38:16 Astute observation. We print out the grammar in t
3677 if (!parser->lexer_->is_note_state ())
3678 parser->parser_error (@1, _ ("have to be in Note mode fo r notes"));
3679 {
3680 Music *n = 0;
3681 if (scm_is_true ($7))
3682 n = MY_MAKE_MUSIC ("RestEvent", @$);
3683 else
3684 n = MY_MAKE_MUSIC ("NoteEvent", @$);
3685
3686 if (scm_is_number ($4))
3687 {
3688 int q = scm_to_int ($4) + scm_to_int ($6);
3689 n->set_property ("absolute-octave", scm_from_int (q-1));
3690 } else
3691 $1 = unsmob<Pitch> ($1)->transposed
3692 (Pitch (scm_to_int ($6), 0)).smobbed_cop y ();
3693
3694 n->set_property ("pitch", $1);
3695 n->set_property ("duration", $5);
3696 3685
3697 if (to_boolean ($3)) 3686 if (to_boolean ($3))
3698 n->set_property ("cautionary", SCM_BOOL_T); 3687 n->set_property ("cautionary", SCM_BOOL_T);
3699 if (to_boolean ($2) || to_boolean ($3)) 3688 if (to_boolean ($2) || to_boolean ($3))
3700 n->set_property ("force-accidental", SCM_BOOL_T) ; 3689 n->set_property ("force-accidental", SCM_BOOL_T) ;
3701 if (scm_is_pair ($8)) 3690 if (scm_is_pair ($8))
3702 n->set_property ("articulations", 3691 n->set_property ("articulations",
3703 scm_reverse_x ($8, SCM_EOL)); 3692 scm_reverse_x ($8, SCM_EOL));
3704 $$ = n->unprotect (); 3693 $$ = n->unprotect ();
3705 } 3694 }
3706 parser->parser_error (@6, _ ("octave marks must precede duration "));
hanwenn 2020/02/12 06:45:08 add a comment that we sholudn't drop this error, e
dak 2020/02/12 10:38:16 Accepting that "syntax" would give me a rash. I h
3707 } %prec ':' 3695 } %prec ':'
3708 | new_chord post_events { 3696 | new_chord post_events {
3709 if (!parser->lexer_->is_chord_state ()) 3697 if (!parser->lexer_->is_chord_state ())
3710 parser->parser_error (@1, _ ("have to be in Chord mode f or chords")); 3698 parser->parser_error (@1, _ ("have to be in Chord mode f or chords"));
3711 if (scm_is_pair ($2)) { 3699 if (scm_is_pair ($2)) {
3712 if (unsmob<Pitch> ($1)) 3700 if (unsmob<Pitch> ($1))
3713 $1 = make_chord_elements (@1, 3701 $1 = make_chord_elements (@1,
3714 $1, 3702 $1,
3715 parser->default_durati on_.smobbed_copy (), 3703 parser->default_durati on_.smobbed_copy (),
3716 SCM_EOL); 3704 SCM_EOL);
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after
4801 Lily_lexer *lex = parser->lexer_; 4789 Lily_lexer *lex = parser->lexer_;
4802 4790
4803 lex->lexval_ = s; 4791 lex->lexval_ = s;
4804 lex->lexloc_ = loc; 4792 lex->lexloc_ = loc;
4805 int tok = lex->pop_extra_token (); 4793 int tok = lex->pop_extra_token ();
4806 if (tok >= 0) 4794 if (tok >= 0)
4807 return tok; 4795 return tok;
4808 lex->prepare_for_next_token (); 4796 lex->prepare_for_next_token ();
4809 return lex->yylex (); 4797 return lex->yylex ();
4810 } 4798 }
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b