]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
* stepmake/aclocal.m4 (STEPMAKE_PANGO_FT2): Define HAVE_PANGO16 too.
[lilypond.git] / lily / parser.yy
index 722f299c83cc05cd36c9aa02acd68dcec42c8bee..f55a4c76e4be9edb7915265a51b7abf1568ea5d1 100644 (file)
 */
 
 /*
+FIXME:
 
-TODO:
-
-* The rules for who is protecting what are very shady. Uniformise
-  this.
-
-* There are too many lexical modes?
+   * The rules for who is protecting what are very shady.  Uniformise
+     this.
 
+   * There are too many lexical modes?
 */
 
+#include "config.hh"
+
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -53,6 +53,14 @@ Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
 SCM get_next_unique_context_id ();
 SCM get_next_unique_lyrics_context_id ();
 
+#undef _
+#if !HAVE_GETTEXT
+#define _(x) x
+#else
+#include <libintl.h>
+#define _(x) gettext (x)
+#endif
+
 #define YYERROR_VERBOSE 1
 
 #define YYPARSE_PARAM my_lily_parser
@@ -79,7 +87,7 @@ tag_music (Music *m, SCM tag, Input ip)
        else if (ly_c_list_p (tag))
                tags = ly_append2 (tag, tags);
        else
-               ip.warning (_ ("Tag must be symbol or list of symbols."));
+               ip.warning (_ ("tag must be symbol or list of symbols"));
 
        m->set_property ("tags", tags);
 }
@@ -231,141 +239,152 @@ yylex (YYSTYPE *s, YYLTYPE *l, void *v)
 
 %}
 
-%expect 3
-
-/*
-  Three shift/reduce problems:
-
-2. \markup identifier.
-
-  (what? --hwn)
-
-3. \markup { }
-
-  (what? --hwn)
+%expect 1
 
+/* One shift/reduce problem
 
-4.  \repeat
+1.  \repeat
        \repeat .. \alternative
 
-
     \repeat { \repeat .. \alternative }
 
 or
 
     \repeat { \repeat } \alternative 
-
-)
- */
+*/
 
 
 %pure_parser
 %locations
 
-%token ACCEPTS
-%token ADDQUOTE
-%token LYRICSTO
-%token ALIAS
-%token ALTERNATIVE
-%token BAR
-%token BOOK
-%token CHANGE
+/* The third option is an alias that will be used to display the
+   syntax error.  Bison CVS now correctly handles backslash escapes.
+
+   FIXME: Bison needs to translate some of these, eg, STRING.
+
+*/     
+   
+/* Keyword tokens with plain escaped name.  */
+%token ACCEPTS "\\accepts"
+%token ADDLYRICS "\\addlyrics"
+%token ADDQUOTE "\\addquote"
+%token ALIAS "\\alias"
+%token ALTERNATIVE "\\alternative"
+%token BAR "\\bar"
+%token BOOK "\book"
+%token CHANGE "\\change"
+%token CHORDMODE "\\chordmode"
+%token CHORDS "\\chords"
+%token CLEF "\\clef"
+%token CONSISTS "\\consists"
+%token CONTEXT "\\context"
+%token DEFAULT "\\default"
+%token DENIES "\\denies"
+%token DESCRIPTION "\\description"
+%token DRUMMODE "\\drummode"
+%token DRUMS "\\drums"
+%token FIGUREMODE "\\figuremode"
+%token FIGURES "\\figures"
+%token GROBDESCRIPTIONS "\\grobdescriptions"
+%token HEADER "\\header"
+%token INVALID "\\invalid"
+%token KEY "\\key"
+%token LAYOUT "\\layout"
+%token LYRICMODE "\\lyricmode"
+%token LYRICS "\\lyrics"
+%token LYRICSTO "\\lyricsto"
+%token MARK "\\mark"
+%token MARKUP "\\markup"
+%token MIDI "\\midi"
+%token NAME "\\name"
+%token NOTEMODE "\\notemode"
+%token OBJECTID "\\objectid"   
+%token OCTAVE "\\octave"
+%token ONCE "\\once"
+%token OVERRIDE "\\override"
+%token PAPER "\\paper"
+%token PARTIAL "\\partial"
+%token RELATIVE "\\relative"
+%token REMOVE "\\remove"
+%token REPEAT "\\repeat"
+%token REST "\\rest"
+%token REVERT "\\revert"
+%token SCORE "\\score"
+%token SEQUENTIAL "\\sequential"
+%token SET "\\set"
+%token SIMULTANEOUS "\\simultaneous"
+%token SKIP "\\skip"
+%token TAG "\\tag"
+%token TEMPO "\\tempo"
+%token TIMES "\\times"
+%token TRANSPOSE "\\transpose"
+%token TRANSPOSITION "\\transposition"
+%token TYPE "\\type"
+%token UNSET "\\unset"
+%token WITH "\\with"
+
+/* Keyword token exceptions.  */
+%token TIME_T "\\time"
+%token NEWCONTEXT "\\new"
+
+
+/* Other string tokens.  */
+
+%token CHORD_BASS "/+"
+%token CHORD_CARET "^"
+%token CHORD_COLON ":"
+%token CHORD_MINUS "-"
+%token CHORD_SLASH "/"
+%token DOUBLE_ANGLE_CLOSE ">>"
+%token DOUBLE_ANGLE_OPEN "<<"
+%token E_BACKSLASH "\\"
+%token E_ANGLE_CLOSE "\\>"
+%token E_CHAR "\\C[haracter]"
+%token E_CLOSE "\\)"
+%token E_EXCLAMATION "\\!"
+%token E_BRACKET_OPEN "\\["
+%token E_OPEN "\\("
+%token E_BRACKET_CLOSE "\\]"
+%token E_ANGLE_OPEN "\\<"
+%token E_TILDE "\\~"
+%token EXTENDER "__"
+/*  These used at all?
+  %token FIGURE_BRACKET_CLOSE 
+  %token FIGURE_BRACKET_OPEN
+
+parser.yy:348.8-25: warning: symbol `"\\>"' used more than once as a literal string
+parser.yy:352.8-24: warning: symbol `"\\<"' used more than once as a literal string
+
+*/
+%token FIGURE_CLOSE /* "\\>" */
+%token FIGURE_OPEN /* "\\<" */
+%token FIGURE_SPACE "_"
+%token HYPHEN "--"
+
 %token CHORDMODIFIERS
-%token CHORDS
-%token CHORDMODE
-%token DOUBLE_ANGLE_OPEN
-%token DOUBLE_ANGLE_CLOSE
-%token CLEF
 %token COMMANDSPANREQUEST
-%token CONSISTS
-%token CONTEXT
-%token DEFAULT
-%token DENIES
-%token DESCRIPTION
-%token EXTENDER
-%token FIGURES
-%token FIGUREMODE
-%token FIGURE_OPEN FIGURE_CLOSE
-%token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
-%token GROBDESCRIPTIONS
-%token HEADER
-%token HYPHEN
-%token INVALID
-%token KEY
-%token LAYOUT
-%token LYRICS
-%token LYRICMODE
-%token MARK
-%token MIDI
+%token LYRIC_MARKUP
 %token MULTI_MEASURE_REST
-%token NAME
-%token NEWCONTEXT
-%token NOTEMODE
-%token OBJECTID        
-%token OCTAVE
-%token ONCE
-%token OVERRIDE SET REVERT
-%token PAPER
-%token PARTIAL
-%token QUOTE
-%token RELATIVE
-%token REMOVE
-%token REPEAT
-%token REST
 %token SCM_T
-%token SCORE
-%token SEQUENTIAL
-%token ADDLYRICS
-%token SIMULTANEOUS
-%token SKIP
-%token SPANREQUEST
-%token TAG
-%token TEMPO
-%token TIMES
-%token TIME_T
-%token TRANSPOSE
-%token TRANSPOSITION
-%token TYPE
-%token UNSET
-%token WITH
-%token MARKUP
-
-/* escaped */
-/* FIXME: this sucks.  The user will get to see these names:
-    syntax error, unexpected E_CHAR:
-               \
-                 %%
-  */
-
-%token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
-%token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
-%token E_BACKSLASH
-%token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET  CHORD_SLASH
-%token FIGURE_SPACE
-
-%token <i>     DIGIT
-%token <i>     UNSIGNED
+
+
+%token <i> DIGIT
 %token <i> E_UNSIGNED
-%token <id>    IDENTIFIER
-%token <scm>   CHORDMODIFIER_PITCH
-%token <scm>   DRUM_PITCH
-%token <scm>   DURATION_IDENTIFIER
-%token <scm>   EVENT_IDENTIFIER
-%token <scm>   MUSIC_IDENTIFIER CONTEXT_DEF_IDENTIFIER
-%token <scm>   NOTENAME_PITCH
-%token <scm>   NUMBER_IDENTIFIER
-%token <scm>   OUTPUT_DEF_IDENTIFIER
-%token <scm>   RESTNAME
+%token <i> UNSIGNED
+
+%token <id> IDENTIFIER
+
+%token <scm> CHORDMODIFIER_PITCH
+%token <scm> CHORD_MODIFIER
+%token <scm> CONTEXT_DEF_IDENTIFIER
+%token <scm> DRUM_PITCH
+%token <scm> DURATION_IDENTIFIER
+%token <scm> EVENT_IDENTIFIER
+%token <scm> FRACTION
 %token <scm> LYRICS_STRING
-%token <scm>   SCM_T
-%token <scm>   SCORE_IDENTIFIER
-%token <scm>   STRING
-%token <scm>   STRING_IDENTIFIER SCM_IDENTIFIER
-%token <scm>   TONICNAME_PITCH
-%token <scm>   CHORD_MODIFIER
-%token <scm>    FRACTION
-%token <scm>   REAL
+%token <scm> LYRIC_MARKUP_IDENTIFIER
 %token <scm> MARKUP_HEAD_EMPTY
+%token <scm> MARKUP_HEAD_LIST0
 %token <scm> MARKUP_HEAD_MARKUP0
 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
 %token <scm> MARKUP_HEAD_SCM0
@@ -373,86 +392,151 @@ or
 %token <scm> MARKUP_HEAD_SCM0_SCM1
 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
-%token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
+%token <scm> MARKUP_IDENTIFIER
 %token <scm> MUSIC_FUNCTION
+%token <scm> MUSIC_FUNCTION_MARKUP 
+%token <scm> MUSIC_FUNCTION_MARKUP_MARKUP 
+%token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC 
+%token <scm> MUSIC_FUNCTION_MARKUP_MUSIC 
+%token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC 
 %token <scm> MUSIC_FUNCTION_MUSIC 
 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC 
 %token <scm> MUSIC_FUNCTION_SCM 
-%token <scm> MUSIC_FUNCTION_SCM_SCM 
 %token <scm> MUSIC_FUNCTION_SCM_MUSIC 
 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC 
+%token <scm> MUSIC_FUNCTION_SCM_SCM 
 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC 
-%token <scm> MUSIC_FUNCTION_MARKUP 
-%token <scm> MUSIC_FUNCTION_MARKUP_MARKUP 
-%token <scm> MUSIC_FUNCTION_MARKUP_MUSIC 
-%token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC 
-%token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC 
-
-%token DRUMS
-%token DRUMMODE
-
-
-%type <book>   book_block book_body
-%type <i>      bare_int  bare_unsigned
-%type <i>      exclamations questions dots optional_rest
-%type <i>      script_dir
-%type <i>      sub_quotes sup_quotes
-%type <i>      tremolo_type
-%type <i>      bass_mod
-
-%type <music>  Composite_music Simple_music Prefix_composite_music Generic_prefix_music
-%type <music>  Grouped_music_list
-%type <music>  Music Sequential_music Simultaneous_music
-%type <music>  Repeated_music
-%type <music>  command_req
-%type <music>  gen_text_def direction_less_event direction_reqd_event
-%type <music>  music_property_def context_change
-%type <music>  note_chord_element chord_body chord_body_element
-%type <music>  post_event tagged_post_event
-%type <music>  relative_music re_rhythmed_music
-%type <music>  simple_element event_chord command_element
-%type <music>  string_number_event
-%type <music>  toplevel_music
-%type <music>  tempo_event
-
-%type <outputdef>      output_def_body output_def_head
-%type <outputdef> output_def paper_block 
-
-%type <scm>     assignment_id
-%type <scm>    Music_list
-%type <scm>    chord_body_elements
-%type <scm>    chord_item chord_items chord_separator new_chord
-%type <scm>    context_def_spec_block context_def_spec_body
-%type <scm>    context_mod context_def_mod optional_context_mod
-%type <scm>    context_prop_spec
-%type <scm>    direction_less_char
-%type <scm>    duration_length fraction
-%type <scm>    embedded_scm scalar
-%type <scm>    identifier_init
-%type <scm>    lilypond_header lilypond_header_body
-%type <scm>    new_lyrics
-%type <scm>    post_events
-%type <scm>    property_operation
-%type <scm>    script_abbreviation
-%type <scm>    simple_string
-%type <scm>    steno_pitch pitch absolute_pitch pitch_also_in_chords
-%type <scm>    steno_tonic_pitch
-%type <scm>    step_number step_numbers 
-%type <scm>    string bare_number number_expression number_term number_factor
-%type <scm>    bass_number br_bass_figure bass_figure figure_list figure_spec
-%type <scm>    context_mod_list
-%type <scm>    octave_check
-%type <scm>    steno_duration optional_notemode_duration multiplied_duration
-%type <scm>    Generic_prefix_music_scm 
-%type <scm>    lyric_element
-%type <scm>     Alternative_music
-%type <scm>    full_markup markup_list markup_composed_list markup_braced_list markup_braced_list_body 
-%type <scm>    markup_head_1_item markup_head_1_list markup simple_markup markup_top
-%type <scm>    mode_changing_head
-%type <scm>    mode_changing_head_with_context
-%type <scm>     object_id_setting 
-
-%type <score>  score_block score_body
+%token <scm> MUSIC_IDENTIFIER
+%token <scm> NOTENAME_PITCH
+%token <scm> NUMBER_IDENTIFIER
+%token <scm> OUTPUT_DEF_IDENTIFIER
+%token <scm> REAL
+%token <scm> RESTNAME
+%token <scm> SCM_IDENTIFIER
+%token <scm> SCM_T
+%token <scm> SCORE_IDENTIFIER
+%token <scm> STRING
+%token <scm> STRING_IDENTIFIER
+%token <scm> TONICNAME_PITCH
+
+
+%type <book> book_block
+%type <book> book_body
+
+%type <i> bare_int
+%type <i> bare_unsigned
+%type <i> bass_mod
+%type <i> dots
+%type <i> exclamations
+%type <i> optional_rest
+%type <i> questions
+%type <i> script_dir
+%type <i> sub_quotes
+%type <i> sup_quotes
+%type <i> tremolo_type
+
+%type <music> Composite_music
+%type <music> Generic_prefix_music
+%type <music> Grouped_music_list
+%type <music> Music
+%type <music> Prefix_composite_music
+%type <music> Repeated_music
+%type <music> Sequential_music
+%type <music> Simple_music
+%type <music> Simultaneous_music
+%type <music> chord_body
+%type <music> chord_body_element
+%type <music> command_element
+%type <music> command_req
+%type <music> context_change
+%type <music> direction_less_event
+%type <music> direction_reqd_event
+%type <music> event_chord
+%type <music> gen_text_def
+%type <music> music_property_def
+%type <music> note_chord_element
+%type <music> post_event
+%type <music> re_rhythmed_music
+%type <music> relative_music
+%type <music> simple_element
+%type <music> string_number_event
+%type <music> tagged_post_event
+%type <music> tempo_event
+%type <music> toplevel_music
+
+%type <outputdef> output_def_body
+%type <outputdef> output_def_head
+%type <outputdef> output_def
+%type <outputdef> paper_block 
+
+%type <scm> Alternative_music
+%type <scm> Generic_prefix_music_scm 
+%type <scm> Music_list
+%type <scm> absolute_pitch
+%type <scm> assignment_id
+%type <scm> bare_number
+%type <scm> bass_figure
+%type <scm> bass_number
+%type <scm> br_bass_figure
+%type <scm> chord_body_elements
+%type <scm> chord_item
+%type <scm> chord_items
+%type <scm> chord_separator
+%type <scm> context_def_mod
+%type <scm> context_def_spec_block
+%type <scm> context_def_spec_body
+%type <scm> context_mod
+%type <scm> context_mod_list
+%type <scm> context_prop_spec
+%type <scm> direction_less_char
+%type <scm> duration_length
+%type <scm> embedded_scm
+%type <scm> figure_list
+%type <scm> figure_spec
+%type <scm> fraction
+%type <scm> full_markup
+%type <scm> identifier_init
+%type <scm> lilypond_header
+%type <scm> lilypond_header_body
+%type <scm> lyric_element
+%type <scm> lyric_markup
+%type <scm> markup
+%type <scm> markup_braced_list
+%type <scm> markup_braced_list_body 
+%type <scm> markup_composed_list
+%type <scm> markup_head_1_item
+%type <scm> markup_head_1_list
+%type <scm> markup_list
+%type <scm> markup_top
+%type <scm> mode_changing_head
+%type <scm> mode_changing_head_with_context
+%type <scm> multiplied_duration
+%type <scm> new_chord
+%type <scm> new_lyrics
+%type <scm> number_expression
+%type <scm> number_factor
+%type <scm> number_term
+%type <scm> object_id_setting
+%type <scm> octave_check
+%type <scm> optional_context_mod
+%type <scm> optional_notemode_duration
+%type <scm> pitch
+%type <scm> pitch_also_in_chords
+%type <scm> post_events
+%type <scm> property_operation
+%type <scm> scalar
+%type <scm> script_abbreviation
+%type <scm> simple_markup
+%type <scm> simple_string
+%type <scm> steno_duration
+%type <scm> steno_pitch
+%type <scm> steno_tonic_pitch
+%type <scm> step_number
+%type <scm> step_numbers 
+%type <scm> string
+
+%type <score> score_block
+%type <score> score_body
 
 
 %left '-' '+'
@@ -508,6 +592,10 @@ toplevel_expression:
                scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
                scm_gc_unprotect_object (music->self_scm ());
        }
+       | full_markup {
+               SCM proc = THIS->lexer_->lookup_identifier ("toplevel-text-handler");
+               scm_call_2 (proc, THIS->self_scm (), $1);
+       }
        | output_def {
                SCM id = SCM_EOL;
                Output_def * od = $1;
@@ -551,7 +639,6 @@ lilypond_header:
        }
        ;
 
-
 /*
        DECLARATIONS
 */
@@ -564,7 +651,7 @@ assignment:
        assignment_id '=' identifier_init  {
                if (! is_regular_identifier ($1))
                {
-                       @1.warning (_ ("Identifier should have alphabetic characters only"));
+                       @1.warning (_ ("identifier should have alphabetic characters only"));
                }
 
                THIS->lexer_->set_identifier ($1, $3);
@@ -674,15 +761,19 @@ book_body:
                scm_gc_unprotect_object ($2->self_scm ());
        }
        | book_body score_block {
-               Score *score = $2;
-               $$->add_score (score);
+               SCM s = $2->self_scm ();
+               $$->add_score (s);
+               scm_gc_unprotect_object (s);
+       }
+       | book_body full_markup {
+               $$->add_score ($2);
        }
        | book_body lilypond_header {
                $$->header_ = $2;
        }
        | book_body error {
                $$->paper_ = 0;
-               $$->scores_.clear();
+               $$->scores_ = SCM_EOL;
        }
        | book_body object_id_setting {
                $$->user_key_ = ly_scm2string ($2);
@@ -718,7 +809,7 @@ score_body:
        | score_body output_def {
                if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
                {
-                       THIS->parser_error (@2, _("\\paper cannot be in \\score. Use \\layout instead"));
+                       THIS->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
                
                }
                else
@@ -742,7 +833,7 @@ paper_block:
                $$ = $1;
                if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
                {
-                       THIS->parser_error (@1, _("Need \\paper for paper block."));
+                       THIS->parser_error (@1, _ ("need \\paper for paper block"));
                        $$ = get_paper (THIS);
                }
        }
@@ -887,7 +978,8 @@ Repeated_music:
                if (times < scm_ilength (alts)) {
                  unsmob_music (scm_car (alts))
                    ->origin ()->warning (
-                   _ ("More alternatives than repeats.  Junking excess alternatives."));
+                   _ ("more alternatives than repeats"));
+                   warning ("junking excess alternatives");
                  alts = ly_truncate_list (times, alts);
                }
 
@@ -910,10 +1002,9 @@ Repeated_music:
                        TODO: move this code to Scheme.
                        */
 
-                       /*
-                       we can not get durations and other stuff correct down the line, so we have to
-                       add to the duration log here.
-                       */
+                       /* we cannot get durations and other stuff
+                          correct down the line,
+                          so we have to add to the duration log here. */
                        SCM func = ly_lily_module_constant ("shift-duration-log");
 
                        int dots = ($3 % 3) ? 0 : 1;
@@ -924,7 +1015,7 @@ Repeated_music:
                        {
                                int list_len = scm_ilength ($4->get_property ("elements"));
                                if (list_len != 2)
-                                       $4->origin ()->warning ("Chord tremolo must have 2 elements.");
+                                       $4->origin ()->warning (_f ("expect 2 elements for Chord tremolo, found %d", list_len));
                                shift -= 1;
                                r->compress (Moment (Rational (1, list_len)));
                        }
@@ -1079,7 +1170,7 @@ Generic_prefix_music:
                else
                        {
                        if (ok)
-                               loc->error (_ ("Music head function should return Music object.")); 
+                               loc->error (_ ("music head function must return Music object")); 
                        $$ = MY_MAKE_MUSIC ("Music");
                        }
                $$->set_spot (*loc);
@@ -1602,7 +1693,7 @@ command_element:
                $$->set_spot (@$);
                $$->set_property ("pitch", $2);
        }
-       | E_LEFTSQUARE {
+       | E_BRACKET_OPEN {
                Music *m = MY_MAKE_MUSIC ("LigatureEvent");
                m->set_property ("span-direction", scm_int2num (START));
                m->set_spot (@$);
@@ -1612,7 +1703,7 @@ command_element:
                scm_gc_unprotect_object (m->self_scm ());
                $$->set_spot (@$);
        }
-       | E_RIGHTSQUARE {
+       | E_BRACKET_CLOSE {
                Music *m = MY_MAKE_MUSIC ("LigatureEvent");
                m->set_property ("span-direction", scm_int2num (STOP));
                m->set_spot (@$);
@@ -1708,10 +1799,10 @@ command_req:
                if (scm_ilength ($3) > 0)
                {               
                        key->set_property ("pitch-alist", $3);
-                       key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
+                       key->set_property ("tonic", Pitch (0, 0, 0).smobbed_copy ());
                        key->transpose (* unsmob_pitch ($2));
                } else {
-                       THIS->parser_error (@3, _ ("Second argument must be pitch list."));
+                       THIS->parser_error (@3, _ ("second argument must be pitch list"));
                }
 
                $$ = key;
@@ -1750,12 +1841,12 @@ post_event:
        }
        | HYPHEN {
                if (!THIS->lexer_->is_lyric_state ())
-                       THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
+                       THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
                $$ = MY_MAKE_MUSIC ("HyphenEvent");
        }
        | EXTENDER {
                if (!THIS->lexer_->is_lyric_state ())
-                       THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
+                       THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
                $$ = MY_MAKE_MUSIC ("ExtenderEvent");
        }
        | script_dir direction_reqd_event {
@@ -1805,10 +1896,10 @@ direction_less_char:
        | E_CLOSE  {
                $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
        }
-       | E_BIGGER  {
+       | E_ANGLE_CLOSE  {
                $$ = ly_symbol2scm ("escapedBiggerSymbol");
        }
-       | E_SMALLER  {
+       | E_ANGLE_OPEN  {
                $$ = ly_symbol2scm ("escapedSmallerSymbol");
        }
        ;
@@ -1848,7 +1939,7 @@ direction_reqd_event:
                Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
                if (scm_is_string (s))
                        a->set_property ("articulation-type", s);
-               else THIS->parser_error (@1, _ ("Expecting string as script definition"));
+               else THIS->parser_error (@1, _ ("expecting string as script definition"));
                $$ = a;
        }
        ;
@@ -2078,6 +2169,7 @@ bass_number:
                                $$);
        }
        | STRING { $$ = $1; }
+       | full_markup { $$ = $1; }
        ;
 
 bass_mod:
@@ -2154,7 +2246,7 @@ optional_rest:
 simple_element:
        pitch exclamations questions octave_check optional_notemode_duration optional_rest {
                if (!THIS->lexer_->is_note_state ())
-                       THIS->parser_error (@1, _ ("Have to be in Note mode for notes"));
+                       THIS->parser_error (@1, _ ("have to be in Note mode for notes"));
 
                Music *n = 0;
                if ($6)
@@ -2235,7 +2327,7 @@ simple_element:
        
        | lyric_element optional_notemode_duration      {
                if (!THIS->lexer_->is_lyric_state ())
-                       THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
+                       THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
 
                Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
                lreq->set_property ("text", $1);
@@ -2248,14 +2340,13 @@ simple_element:
        }
        | new_chord {
                 if (!THIS->lexer_->is_chord_state ())
-                        THIS->parser_error (@1, _ ("Have to be in Chord mode for chords"));
+                        THIS->parser_error (@1, _ ("have to be in Chord mode for chords"));
                 $$ = unsmob_music ($1);
        }
        ;
 
 lyric_element:
-       /* FIXME: lyric flavoured markup would be better */
-       full_markup {
+       lyric_markup {
                $$ = $1;
        }
        | LYRICS_STRING {
@@ -2423,6 +2514,18 @@ questions:
 This should be done more dynamically if possible.
 */
 
+lyric_markup:
+       LYRIC_MARKUP_IDENTIFIER {
+               $$ = $1;
+       }
+       | LYRIC_MARKUP
+               { THIS->lexer_->push_markup_state (); }
+       markup_top {
+               $$ = $3;
+               THIS->lexer_->pop_state ();
+       }
+       ;
+
 full_markup:
        MARKUP_IDENTIFIER {
                $$ = $1;
@@ -2507,6 +2610,9 @@ simple_markup:
        | MARKUP_IDENTIFIER {
                $$ = $1;
        }
+       | LYRIC_MARKUP_IDENTIFIER {
+               $$ = $1;
+       }
        | STRING_IDENTIFIER {
                $$ = $1;
        }
@@ -2583,7 +2689,8 @@ Lily_parser::beam_check (SCM dur)
   if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
     {
       Music *m = unsmob_music (last_beam_start_);
-      m->origin ()->warning (_ ("Suspect duration found following this beam"));
+      m->origin ()->warning (_f ("suspect duration in beam: %s",
+      d->to_string ()));
     }
   last_beam_start_ = SCM_EOL;
 }
@@ -2631,6 +2738,8 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
                return OUTPUT_DEF_IDENTIFIER;
        } else if (Text_interface::markup_p (sid)) {
                *destination = sid;
+               if (is_lyric_state ())
+                       return LYRIC_MARKUP_IDENTIFIER;
                return MARKUP_IDENTIFIER;
        }