]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/lexer.ll
* lily/include/my-lily-parser.hh: rename My_lily -> Lily
[lilypond.git] / lily / lexer.ll
index 7c622accd2600b1f6e8e0a59d7dbabacec79249b..b80af4b60ae87621c943993c9a138ffa52a5e986 100644 (file)
 
 #include <iostream>
 using namespace std;
-
+#include "music-function.hh"
 #include "source-file.hh"
 #include "parse-scm.hh"
 #include "lily-guile.hh"
 #include "string.hh"
 #include "string-convert.hh"
 #include "my-lily-lexer.hh"
-#include "input-file-results.hh"
 #include "interval.hh"
 #include "lily-guile.hh"
 #include "parser.hh"
@@ -58,19 +57,19 @@ RH 7 fix (?)
 void strip_trailing_white (String&);
 void strip_leading_white (String&);
 String lyric_fudge (String s);
-
-SCM
-lookup_markup_command (String s);
-
-bool
-valid_version_b (String s);
-
+int music_function_type (SCM);
+SCM lookup_markup_command (String s);
+bool is_valid_version (String s);
 
 
 #define start_quote()  \
        yy_push_state (quote);\
        yylval.string = new String
 
+#define start_lyric_quote()    \
+       yy_push_state (lyric_quote);\
+       yylval.string = new String
+
 #define yylval \
        (*(YYSTYPE*)lexval)
 
@@ -93,21 +92,23 @@ SCM (* scm_parse_error_handler) (void *);
 %option noyywrap
 %option nodefault
 %option debug
-%option yyclass="My_lily_lexer"
+%option yyclass="Lily_lexer"
 %option stack
 %option never-interactive 
 %option warn
 
-%x renameinput
-%x version
 %x chords
+%x encoding
+%x figures
 %x incl
 %x lyrics
-%x notes
-%x figures
-%x quote
+%x lyric_quote
 %x longcomment
 %x markup 
+%x notes
+%x quote
+%x renameinput
+%x version
 
 A              [a-zA-Z]
 AA             {A}|_
@@ -160,39 +161,53 @@ HYPHEN            --
   }
 }
 
+<INITIAL,notes>\\encoding{WHITE}* {
+       yy_push_state (encoding);
+}
 <INITIAL,chords,lyrics,notes,figures>\\version{WHITE}* {
        yy_push_state (version);
 }
 <INITIAL,chords,lyrics,notes,figures>\\renameinput{WHITE}*     {
        yy_push_state (renameinput);
 }
+<encoding>\"[^"]*\"     {
+       String s (YYText () + 1);
+       s = s.left_string (s.index_last ('\"'));
+       set_encoding (s);
+       yy_pop_state ();
+}
 <version>\"[^"]*\"     { /* got the version number */
-       String s (YYText ()+1);
+       String s (YYText () + 1);
        s = s.left_string (s.index_last ('\"'));
 
-       yy_pop_state();
-        if (!valid_version_b (s))
+       yy_pop_state ();
+       if (!is_valid_version (s))
                return INVALID;
 }
-<renameinput>\"[^"]*\"     { /* got the version number */
+<renameinput>\"[^"]*\"     {
        String s (YYText ()+1);
        s = s.left_string (s.index_last ('\"'));
 
        yy_pop_state();
        this->here_input().source_file_->name_ = s;
-       progress_indication (_f("\nRenamed input to `%s'\n", s.to_str0()));
-       scm_module_define (gh_car (scopes_),
+       progress_indication ("\n");
+       progress_indication (_f ("input renamed to: `%s'", s.to_str0 ()));
+       progress_indication ("\n");
+       scm_module_define (ly_car (scopes_),
                     ly_symbol2scm ("input-file-name"),
                     scm_makfrom0str (s.to_str0()));
 
 }
-
+<encoding>.    {
+       LexerError (_ ("No quoted string found after \\encoding").to_str0 ());
+       yy_pop_state ();
+}
 <version>.     {
-       LexerError ("No quoted string found after \\version");
+       LexerError (_ ("No quoted string found after \\version").to_str0 ());
        yy_pop_state ();
 }
 <renameinput>.         {
-       LexerError ("No quoted string found after \\renameinput");
+       LexerError (_ ("No quoted string found after \\renameinput").to_str0 ());
        yy_pop_state ();
 }
 <longcomment>{
@@ -227,21 +242,23 @@ HYPHEN            --
        yy_push_state (incl);
 }
 <incl>\"[^"]*\";?   { /* got the include file name */
+/* FIXME: semicolon? */
        String s (YYText ()+1);
        s = s.left_string (s.index_last ('"'));
 
-       new_input (s, &global_input_file->sources_ );
+       new_input (s, sources_);
        yy_pop_state ();
 }
 <incl>\\{BLACK}*;?{WHITE} { /* got the include identifier */
+/* FIXME: semicolon? */
        String s = YYText () + 1;
        strip_trailing_white (s);
        if (s.length () && (s[s.length () - 1] == ';'))
          s = s.left_string (s.length () - 1);
 
        SCM sid = lookup_identifier (s);
-       if (gh_string_p (sid)) {
-               new_input (ly_scm2string (sid), &global_input_file->sources_);
+       if (ly_c_string_p (sid)) {
+               new_input (ly_scm2string (sid), sources_);
                yy_pop_state ();
        } else { 
            String msg (_f ("wrong or undefined identifier: `%s'", s ));
@@ -264,25 +281,6 @@ HYPHEN             --
 <chords,notes,figures>R                {
        return MULTI_MEASURE_REST;
 }
-<INITIAL,chords,lyrics,notes,figures>\\\${BLACK}*{WHITE}       {
-       String s=YYText () + 2;
-       s=s.left_string (s.length () - 1);
-       return scan_escaped_word (s); 
-}
-<INITIAL,chords,lyrics,notes,figures>\${BLACK}*{WHITE}         {
-       String s=YYText () + 1;
-       s=s.left_string (s.length () - 1);
-       return scan_bare_word (s);
-}
-<INITIAL,chords,lyrics,notes,figures>\\\${BLACK}*              { // backup rule
-       error (_("white expected"));
-       exit (1);
-}
-<INITIAL,chords,lyrics,notes,figures>\${BLACK}*                { // backup rule
-       error (_("white expected"));
-       exit (1);
-}
-
 <INITIAL,markup,chords,lyrics,notes,figures>#  { //embedded scm
        //char const* s = YYText () + 1;
        char const* s = here_str0 ();
@@ -293,7 +291,7 @@ HYPHEN              --
        if (sval == SCM_UNDEFINED)
        {
                sval = SCM_UNSPECIFIED;
-               errorlevel_ = 1;
+               error_level_ = 1;
        }
 
        for (int i=0; i < n; i++)
@@ -313,10 +311,10 @@ HYPHEN            --
 }
 <INITIAL,notes,lyrics>{ 
        \<\<   {
-               return LESSLESS;
+               return DOUBLE_ANGLE_OPEN;
        }
        \>\>   {
-               return MOREMORE;
+               return DOUBLE_ANGLE_CLOSE;
        }
 }
 <figures>{
@@ -386,10 +384,31 @@ HYPHEN            --
                *yylval.string += YYText ();
        }
 }
+<lyric_quote>{
+       \\{ESCAPED}     {
+               *yylval.string += to_string (escaped_char (YYText ()[1]));
+       }
+       [^\\"]+ {
+               *yylval.string += YYText ();
+       }
+       \"      {
+
+               yy_pop_state ();
+
+               /* yylval is union. Must remember STRING before setting SCM*/
+               String *sp = yylval.string;
+               yylval.scm = scm_makfrom0str (sp->to_str0 ());
+               delete sp;
+               return LYRICS_STRING;
+       }
+       .       {
+               *yylval.string += YYText ();
+       }
+}
 
 <lyrics>{
        \" {
-               start_quote ();
+               start_lyric_quote ();
        }
        {FRACTION}      {
                yylval.scm =  scan_fraction (YYText ());
@@ -418,7 +437,7 @@ HYPHEN              --
                yylval.scm = scm_makfrom0str (s.to_str0 ());
 
 
-               return STRING;
+               return LYRICS_STRING;
        }
        . {
                return YYText ()[0];
@@ -473,13 +492,16 @@ HYPHEN            --
        \> {
                return '>';
        }
+       \\score {
+               return SCORE;
+       }
        {MARKUPCOMMAND} {
-               String str (YYText() + 1);
+               String str (YYText () + 1);
                SCM s = lookup_markup_command (str);
 
-               if (gh_pair_p (s) && gh_symbol_p (gh_cdr (s)) ) {
-                       yylval.scm = gh_car(s);
-                       SCM tag = gh_cdr(s);
+               if (ly_c_pair_p (s) && ly_c_symbol_p (ly_cdr (s)) ) {
+                       yylval.scm = ly_car(s);
+                       SCM tag = ly_cdr(s);
                        if (tag == ly_symbol2scm("markup0"))
                                return MARKUP_HEAD_MARKUP0;
                        if (tag == ly_symbol2scm("empty"))
@@ -507,13 +529,14 @@ HYPHEN            --
                        return scan_escaped_word (str);
        }
        [{}]    {
-               return YYText()[0];
+               return YYText ()[0];
        }
        [^#{}"\\ \t\n\r\f]+ {
                String s (YYText ()); 
 
                char c = s[s.length () - 1];
-               if (c == '{' ||  c == '}') // brace open is for not confusing dumb tools.
+               /* brace open is for not confusing dumb tools.  */
+               if (c == '{' ||  c == '}')
                        here_input ().warning (
                                _ ("Brace found at end of markup.  Did you forget a space?"));
                yylval.scm = scm_makfrom0str (s.to_str0 ());
@@ -527,10 +550,16 @@ HYPHEN            --
 }
 
 <<EOF>> {
-       main_input_b_ = false;
-       if (! close_input ()) { 
-         yyterminate (); // can't move this, since it actually rets a YY_NULL
+       if (main_input_b_)
+       {
+               main_input_b_ = false;
+               if (!close_input ())
+               /* Returns YY_NULL */
+                       yyterminate ();
        }
+       else if (!close_input ())
+               /* Returns YY_NULL */
+               yyterminate ();
 }
 
 
@@ -545,7 +574,7 @@ HYPHEN              --
        int cnv=sscanf (YYText (), "%lf", &r);
        assert (cnv == 1);
 
-       yylval.scm = gh_double2scm (r);
+       yylval.scm = scm_make_real (r);
        return REAL;
 }
 
@@ -606,54 +635,61 @@ HYPHEN            --
 %%
 
 void
-My_lily_lexer::push_note_state (SCM tab)
+Lily_lexer::push_chord_state (SCM tab)
 {
-       pitchname_tab_stack_ = gh_cons (tab, pitchname_tab_stack_);
-       yy_push_state (notes);
+       pitchname_tab_stack_ = scm_cons (tab, pitchname_tab_stack_);
+       yy_push_state (chords);
 }
 
 void
-My_lily_lexer::push_figuredbass_state()
+Lily_lexer::push_figuredbass_state ()
 {
        yy_push_state (figures);
 }
+
 void
-My_lily_lexer::push_chord_state (SCM tab)
+Lily_lexer::push_initial_state ()
 {
-       pitchname_tab_stack_ = gh_cons (tab, pitchname_tab_stack_);
-       yy_push_state (chords);
+       yy_push_state (INITIAL);
 }
 
 void
-My_lily_lexer::push_lyric_state ()
+Lily_lexer::push_lyric_state ()
 {
        yy_push_state (lyrics);
 }
 
 void
-My_lily_lexer::push_markup_state ()
+Lily_lexer::push_markup_state ()
 {
        yy_push_state (markup);
 }
 
 void
-My_lily_lexer::pop_state ()
+Lily_lexer::push_note_state (SCM tab)
+{
+       pitchname_tab_stack_ = scm_cons (tab, pitchname_tab_stack_);
+       yy_push_state (notes);
+}
+
+void
+Lily_lexer::pop_state ()
 {
        if (YYSTATE == notes || YYSTATE == chords)
-               pitchname_tab_stack_ = gh_cdr (pitchname_tab_stack_);
+               pitchname_tab_stack_ = ly_cdr (pitchname_tab_stack_);
        yy_pop_state ();
 }
 
 int
-My_lily_lexer::identifier_type(SCM sid)
+Lily_lexer::identifier_type (SCM sid)
 {
-       int k = try_special_identifiers(&yylval.scm , sid);
+       int k = try_special_identifiers (&yylval.scm , sid);
        return k >= 0  ? k : SCM_IDENTIFIER;
 }
 
 
 int
-My_lily_lexer::scan_escaped_word (String str)
+Lily_lexer::scan_escaped_word (String str)
 {
        // use more SCM for this.
 
@@ -664,6 +700,13 @@ My_lily_lexer::scan_escaped_word (String str)
                return l;
        }
        SCM sid = lookup_identifier (str);
+       if (is_music_function (sid))
+       {
+               yylval.scm = get_music_function_transform (sid);
+               
+               return music_function_type (yylval.scm);
+       }
+
        if (sid != SCM_UNDEFINED)
        {
                yylval.scm = sid;
@@ -679,19 +722,19 @@ My_lily_lexer::scan_escaped_word (String str)
 }
 
 int
-My_lily_lexer::scan_bare_word (String str)
+Lily_lexer::scan_bare_word (String str)
 {
        SCM sym = ly_symbol2scm (str.to_str0 ());
        if ((YYSTATE == notes) || (YYSTATE == chords)) {
                SCM handle = SCM_BOOL_F;
-               if (gh_pair_p (pitchname_tab_stack_))
-                       handle = scm_hashq_get_handle (gh_car (pitchname_tab_stack_), sym);
+               if (ly_c_pair_p (pitchname_tab_stack_))
+                       handle = scm_hashq_get_handle (ly_car (pitchname_tab_stack_), sym);
                
-               if (gh_pair_p (handle)) {
+               if (ly_c_pair_p (handle)) {
                        yylval.scm = ly_cdr (handle);
                        if (unsmob_pitch (yylval.scm)) 
                            return (YYSTATE == notes) ? NOTENAME_PITCH : TONICNAME_PITCH;
-                       else if (gh_symbol_p (yylval.scm))
+                       else if (ly_c_symbol_p (yylval.scm))
                            return DRUM_PITCH;
                }
                else if ((handle = scm_hashq_get_handle (chordmodifier_tab_, sym))!= SCM_BOOL_F)
@@ -706,25 +749,25 @@ My_lily_lexer::scan_bare_word (String str)
 }
 
 bool
-My_lily_lexer::note_state_b () const
+Lily_lexer::is_note_state () const
 {
        return YY_START == notes;
 }
 
 bool
-My_lily_lexer::chord_state_b () const
+Lily_lexer::is_chord_state () const
 {
        return YY_START == chords;
 }
 
 bool
-My_lily_lexer::lyric_state_b () const
+Lily_lexer::is_lyric_state () const
 {
        return YY_START == lyrics;
 }
 
 bool
-My_lily_lexer::figure_state_b () const
+Lily_lexer::is_figure_state () const
 {
        return YY_START == figures;
 }
@@ -757,12 +800,12 @@ strip_trailing_white (String&s)
 
 
 
-/* 1.9.0 == postfix articulations */ 
-Lilypond_version oldest_version ("1.9.0");
+/* 2.1.2x something -> \property -> \set. */ 
+Lilypond_version oldest_version ("2.2.0");
 
 
 bool
-valid_version_b (String s)
+is_valid_version (String s)
 {
   Lilypond_version current ( MAJOR_VERSION "." MINOR_VERSION "." PATCH_LEVEL );
   Lilypond_version ver (s);
@@ -777,7 +820,7 @@ valid_version_b (String s)
        
 
 /*
-  substittute _ adn \,
+  substitute _ and \,
 */
 String
 lyric_fudge (String s)
@@ -816,7 +859,7 @@ scan_fraction (String frac)
 
        int n = String_convert::dec2int (left);
        int d = String_convert::dec2int (right);
-       return gh_cons (gh_int2scm (n), gh_int2scm (d));
+       return scm_cons (scm_int2num (n), scm_int2num (d));
 }
 
 // Breaks for flex 2.5.31
@@ -842,9 +885,52 @@ avoid_silly_flex_induced_gcc_warnings ()
 SCM
 lookup_markup_command (String s)
 {
-       static SCM proc ;
-       if (!proc)
-               proc = scm_c_eval_string ("lookup-markup-command");
-
+       SCM proc = ly_scheme_function ("lookup-markup-command");
        return scm_call_1 (proc, scm_makfrom0str (s.to_str0 ()));
 }
+
+
+int
+music_function_type (SCM func)
+{
+       SCM type= scm_object_property (func, ly_symbol2scm ("music-function-signature-keyword"));
+       if (type == ly_symbol2scm ("scm"))
+       {
+               return MUSIC_FUNCTION_SCM;
+       }
+       else if (type == ly_symbol2scm ("music"))
+       {
+               return MUSIC_FUNCTION_MUSIC;
+       }
+       else if (type == ly_symbol2scm ("scm-music"))
+       {
+               return MUSIC_FUNCTION_SCM_MUSIC;
+       }
+       else if (type == ly_symbol2scm ("scm-scm"))
+       {
+               return MUSIC_FUNCTION_SCM_SCM;
+       }
+       else if (type == ly_symbol2scm ("music-music"))
+       {
+               return MUSIC_FUNCTION_MUSIC_MUSIC;
+       }
+       else if (type == ly_symbol2scm ("scm-music-music"))
+       {
+               return MUSIC_FUNCTION_SCM_MUSIC_MUSIC;
+       }
+       else if (type == ly_symbol2scm ("scm-scm-music"))
+       {
+               return MUSIC_FUNCTION_SCM_SCM_MUSIC;
+       }
+       else if (type == ly_symbol2scm ("noarg"))
+       {
+               return MUSIC_FUNCTION;
+       }
+       else
+               {
+               /* TODO: print location */
+               error ("Can not find signature for music function.");
+               }
+
+       return MUSIC_FUNCTION_SCM;
+}