]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/lexer.ll
Merge branch 'master' into translation
[lilypond.git] / lily / lexer.ll
index 60a41943a61ce2b2148e2717fa5d972370d7ea87..c1a6e4b0f43665380e51fca28eec4d19895725ab 100644 (file)
@@ -91,11 +91,6 @@ bool is_valid_version (string s);
                 yylval = SCM_EOL;               \
         } while (0)
 
-#define start_lyric_quote() do {                \
-                yy_push_state (lyric_quote);    \
-                yylval = SCM_EOL;               \
-        } while (0)
-
 #define yylval (*lexval_)
 
 #define yylloc (*lexloc_)
@@ -124,8 +119,8 @@ SCM (* scm_parse_error_handler) (void *);
 %x figures
 %x incl
 %x lyrics
-%x lyric_quote
 %x longcomment
+%x maininput
 %x markup
 %x notes
 %x quote
@@ -165,7 +160,7 @@ WHITE               [ \n\t\f\r]
 HORIZONTALWHITE                [ \t]
 BLACK          [^ \n\t\f\r]
 RESTNAME       [rs]
-ESCAPED                [nt\\'"]
+ESCAPED                [nt\\''""]
 EXTENDER       __
 HYPHEN         --
 BOM_UTF8       \357\273\277
@@ -222,16 +217,10 @@ BOM_UTF8  \357\273\277
   "%{" {
        yy_push_state (longcomment);
   }
-  %[^{\n\r][^\n\r]*[\n\r]      {
-         (void) YYText_utf8 ();
-  }
-  %[^{\n\r]    { // backup rule
+  %[^{\n\r][^\n\r]*[\n\r]?     {
          (void) YYText_utf8 ();
   }
-  %[\n\r]      {
-  }
-  %[^{\n\r][^\n\r]*    {
-         (void) YYText_utf8 ();
+  %[\n\r]?     {
   }
   {WHITE}+     {
 
@@ -253,7 +242,7 @@ BOM_UTF8    \357\273\277
 <INITIAL,chords,lyrics,notes,figures>\\sourcefileline{WHITE}*  {
        yy_push_state (sourcefileline);
 }
-<version>\"[^"]*\"     { /* got the version number */
+<version>\"[^""]*\"     { /* got the version number */
        string s (YYText_utf8 () + 1);
        s = s.substr (0, s.rfind ('\"'));
 
@@ -318,10 +307,14 @@ BOM_UTF8  \357\273\277
        if (!is_main_input_)
        {
                start_main_input ();
+               main_input_level_ = include_stack_.size ();
                is_main_input_ = true;
+               int state = YYSTATE;
+               yy_push_state (maininput);
+               yy_push_state (state);
        }
        else
-               error (_ ("\\maininput not allowed outside init files"));
+               LexerError (_ ("\\maininput not allowed outside init files").c_str ());
 }
 
 <INITIAL,chords,lyrics,figures,notes>\\include           {
@@ -381,8 +374,8 @@ BOM_UTF8    \357\273\277
 }
 
 <incl,version,sourcefilename>\"[^""]*   { // backup rule
-       error (_ ("end quote missing"));
-       exit (1);
+       LexerError (_ ("end quote missing").c_str ());
+       yy_pop_state ();
 }
 
     /* Flex picks the longest matching pattern including trailing
@@ -510,7 +503,7 @@ BOM_UTF8    \357\273\277
        }
 }
 
-<quote,lyric_quote>{
+<quote>{
        \\{ESCAPED}     {
                 char c = escaped_char (YYText ()[1]);
                yylval = scm_cons (scm_from_locale_stringn (&c, 1),
@@ -530,7 +523,7 @@ BOM_UTF8    \357\273\277
                                                          SCM_UNDEFINED,
                                                          SCM_UNDEFINED);
 
-               return is_lyric_state () ? LYRICS_STRING : STRING;
+               return STRING;
        }
        \\      {
                 yylval = scm_cons (scm_from_locale_string (YYText ()),
@@ -540,7 +533,7 @@ BOM_UTF8    \357\273\277
 
 <lyrics>{
        \" {
-               start_lyric_quote ();
+               start_quote ();
        }
        {FRACTION}      {
                yylval =  scan_fraction (YYText ());
@@ -571,7 +564,7 @@ BOM_UTF8    \357\273\277
                s = lyric_fudge (s);
                yylval = ly_string2scm (s);
 
-               return LYRICS_STRING;
+               return STRING;
        }
        /* This should really just cover {} */
        . {
@@ -694,21 +687,32 @@ BOM_UTF8  \357\273\277
 
 <longcomment><<EOF>> {
                LexerError (_ ("EOF found inside a comment").c_str ());
-               is_main_input_ = false; // should be safe , can't have \include in --safe.
-                yylval = SCM_UNSPECIFIED;
-               if (!close_input ())
-                 yyterminate (); // can't move this, since it actually rets a YY_NULL
+               yy_pop_state ();
        }
 
+<quote><<EOF>> {
+       LexerError (_ ("EOF found inside string").c_str ());
+       yy_pop_state ();
+}
+
 <<EOF>> {
         yylval = SCM_UNSPECIFIED;
         if (is_main_input_)
        {
-               /* 2 = init.ly + current file.
-                  > because we're before closing, but is_main_input_ should
-                  reflect after.
-               */ 
-               is_main_input_ = include_stack_.size () > 2;
+               is_main_input_ = include_stack_.size () > main_input_level_;
+               if (!is_main_input_)
+               {
+                       main_input_level_ = 0;
+                       pop_state ();
+                       if (YYSTATE != maininput)
+                       {
+                               LexerError (_ ("Unfinished main input").c_str ());
+                               do {
+                                       pop_state ();
+                               } while (YYSTATE != maininput);
+                       }
+                       pop_state ();
+               }
                if (!close_input () || !is_main_input_)
                /* Returns YY_NULL */
                        yyterminate ();
@@ -718,6 +722,13 @@ BOM_UTF8   \357\273\277
                yyterminate ();
 }
 
+<maininput>{ANY_CHAR} {
+       while (include_stack_.size () > main_input_level_
+              && close_input ())
+               ;
+       yyterminate ();
+}
+
 <INITIAL>{
        {WORD}/[-_]     | // backup rule
        {WORD}  {
@@ -909,12 +920,16 @@ Lily_lexer::scan_escaped_word (string str)
 
         yylval = SCM_UNSPECIFIED;
        int i = lookup_keyword (str);
-       if (i == MARKUP && is_lyric_state ())
-               return LYRIC_MARKUP;
+
        if (i != -1)
                return i;
 
        SCM sid = lookup_identifier (str);
+       if (Music *m = unsmob_music (sid))
+       {
+               m->set_spot (override_input (last_input_));
+       }
+
        if (sid != SCM_UNDEFINED)
                return scan_scm_id (sid);
 
@@ -1074,19 +1089,26 @@ Lily_lexer::eval_scm (SCM readerdata, char extra_token)
                sval = scm_struct_ref (sval, SCM_INUM0);
 
                if (scm_is_pair (sval)) {
-                       for (SCM v = scm_reverse (scm_cdr (sval));
-                            scm_is_pair (v);
-                            v = scm_cdr (v))
+                       for (SCM p = scm_reverse (scm_cdr (sval));
+                            scm_is_pair (p);
+                            p = scm_cdr (p))
                        {
+                               SCM v = scm_car (p);
+                               if (Music *m = unsmob_music (v))
+                               {
+                                       if (!unsmob_input (m->get_property ("origin")))
+                                               m->set_spot (override_input (last_input_));
+                               }
+                                       
                                int token;
                                switch (extra_token) {
                                case '$':
-                                       token = scan_scm_id (scm_car (v));
+                                       token = scan_scm_id (v);
                                        if (!scm_is_eq (yylval, SCM_UNSPECIFIED))
                                                push_extra_token (token, yylval);
                                        break;
                                case '#':
-                                       push_extra_token (SCM_IDENTIFIER, scm_car (v));
+                                       push_extra_token (SCM_IDENTIFIER, v);
                                        break;
                                }
                        }
@@ -1095,6 +1117,12 @@ Lily_lexer::eval_scm (SCM readerdata, char extra_token)
                        sval = SCM_UNSPECIFIED;
        }
 
+       if (Music *m = unsmob_music (sval))
+       {
+               if (!unsmob_input (m->get_property ("origin")))
+                       m->set_spot (override_input (last_input_));
+       }
+
        return sval;
 }