]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/lexer.ll
Run grand-replace (issue 3765)
[lilypond.git] / lily / lexer.ll
index 50b79a848810b57e7500764ae22029b11799ddce..ab6794a21ef138b8dce8488bb703a0fc375977bc 100644 (file)
@@ -2,7 +2,7 @@
 /*
   This file is part of LilyPond, the GNU music typesetter.
 
-  Copyright (C) 1996--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Copyright (C) 1996--2014 Han-Wen Nienhuys <hanwen@xs4all.nl>
                  Jan Nieuwenhuizen <janneke@gnu.org>
 
   LilyPond is free software: you can redistribute it and/or modify
@@ -91,6 +91,15 @@ bool is_valid_version (string s);
                 yylval = SCM_EOL;               \
         } while (0)
 
+/*
+  The inside of \"violin1" is marked by commandquote mode
+*/
+
+#define start_command_quote() do {             \
+                yy_push_state (commandquote);  \
+                yylval = SCM_EOL;               \
+        } while (0)
+
 #define yylval (*lexval_)
 
 #define yylloc (*lexloc_)
@@ -114,7 +123,6 @@ SCM (* scm_parse_error_handler) (void *);
 %option never-interactive 
 %option warn
 
-%x extratoken
 %x chords
 %x figures
 %x incl
@@ -124,6 +132,7 @@ SCM (* scm_parse_error_handler) (void *);
 %x markup
 %x notes
 %x quote
+%x commandquote
 %x sourcefileline
 %x sourcefilename
 %x version
@@ -176,36 +185,6 @@ BOM_UTF8   \357\273\277
        // swallow and ignore carriage returns
 }
 
-<extratoken>{ANY_CHAR} {
-  /* Generate a token without swallowing anything */
-
-  /* First unswallow the eaten character */
-  add_lexed_char (-YYLeng ());
-  yyless (0);
-
-  /* produce requested token */
-  int type = scm_to_int (scm_caar (extra_tokens_));
-  yylval = scm_cdar (extra_tokens_);
-  extra_tokens_ = scm_cdr (extra_tokens_);
-  if (scm_is_null (extra_tokens_))
-    yy_pop_state ();
-
-  return type;
-}
-
-<extratoken><<EOF>>    {
-  /* Generate a token without swallowing anything */
-
-  /* produce requested token */
-  int type = scm_to_int (scm_caar (extra_tokens_));
-  yylval = scm_cdar (extra_tokens_);
-  extra_tokens_ = scm_cdr (extra_tokens_);
-  if (scm_is_null (extra_tokens_))
-    yy_pop_state ();
-
-  return type;
-}
-
    /* Use the trailing context feature. Otherwise, the BOM will not be
       found if the file starts with an identifier definition. */
 <INITIAL,chords,lyrics,figures,notes>{BOM_UTF8}/.* {
@@ -503,7 +482,9 @@ BOM_UTF8    \357\273\277
        {WORD}  {
                return scan_bare_word (YYText_utf8 ());
        }
-
+       \\\"    {
+               start_command_quote ();
+       }
        {COMMAND}/[-_]  | // backup rule
        {COMMAND}       {
                return scan_escaped_word (YYText_utf8 () + 1); 
@@ -527,7 +508,7 @@ BOM_UTF8    \357\273\277
        }
 }
 
-<quote>{
+<quote,commandquote>{
        \\{ESCAPED}     {
                 char c = escaped_char (YYText ()[1]);
                yylval = scm_cons (scm_from_locale_stringn (&c, 1),
@@ -539,14 +520,19 @@ BOM_UTF8  \357\273\277
        }
        \"      {
 
-               yy_pop_state ();
-
                /* yylval is union. Must remember STRING before setting SCM*/
 
                 yylval = scm_string_concatenate_reverse (yylval,
                                                          SCM_UNDEFINED,
                                                          SCM_UNDEFINED);
 
+               if (get_state () == commandquote) {
+                       yy_pop_state ();
+                       return scan_escaped_word (ly_scm2string (yylval));
+               }
+
+               yy_pop_state ();
+
                return STRING;
        }
        \\      {
@@ -572,6 +558,9 @@ BOM_UTF8    \357\273\277
                yylval = scm_c_read_string (YYText ());
                return UNSIGNED;
        }
+       \\\"    {
+               start_command_quote ();
+       }
        {COMMAND}/[-_]  | // backup rule
        {COMMAND}       {
                return scan_escaped_word (YYText_utf8 () + 1);
@@ -585,7 +574,7 @@ BOM_UTF8    \357\273\277
                 yylval = SCM_UNSPECIFIED;
                return YYText ()[0];
        }
-       [^$#{}\"\\ \t\n\r\f0-9]+ {
+       [^|*.=$#{}\"\\ \t\n\r\f0-9][^$#{}\"\\ \t\n\r\f0-9]* {
                /* ugr. This sux. */
                string s (YYText_utf8 ());
                 yylval = SCM_UNSPECIFIED;
@@ -609,6 +598,9 @@ BOM_UTF8    \357\273\277
        {WORD}  {
                return scan_bare_word (YYText_utf8 ());
        }
+       \\\"    {
+               start_command_quote ();
+       }
        {COMMAND}/[-_]  | // backup rule
        {COMMAND}       {
                return scan_escaped_word (YYText_utf8 () + 1);
@@ -650,6 +642,13 @@ BOM_UTF8   \357\273\277
                 yylval = SCM_UNSPECIFIED;
                return SCORE;
        }
+       \\score-lines {
+               yylval = SCM_UNSPECIFIED;
+               return SCORELINES;
+       }
+       \\\"    {
+               start_command_quote ();
+       }
        {COMMAND}/[-_]  | // backup rule
        {COMMAND} {
                string str (YYText_utf8 () + 1);
@@ -687,17 +686,17 @@ BOM_UTF8  \357\273\277
                // value (for token type MARKUP_FUNCTION or
                // MARKUP_LIST_FUNCTION).
 
-               push_extra_token(EXPECT_NO_MORE_ARGS);
+               push_extra_token (here_input (), EXPECT_NO_MORE_ARGS);
                s = scm_cdr(s);
                for (; scm_is_pair(s); s = scm_cdr(s)) {
                  SCM predicate = scm_car(s);
 
                  if (predicate == ly_lily_module_constant ("markup-list?"))
-                   push_extra_token(EXPECT_MARKUP_LIST);
+                   push_extra_token (here_input (), EXPECT_MARKUP_LIST);
                  else if (predicate == ly_lily_module_constant ("markup?"))
-                   push_extra_token(EXPECT_MARKUP);
+                   push_extra_token (here_input (), EXPECT_MARKUP);
                  else
-                   push_extra_token(EXPECT_SCM, predicate);
+                   push_extra_token (here_input (), EXPECT_SCM, predicate);
                }
                return token_type;
        }
@@ -718,7 +717,7 @@ BOM_UTF8    \357\273\277
                yy_pop_state ();
        }
 
-<quote><<EOF>> {
+<quote,commandquote><<EOF>> {
        LexerError (_ ("EOF found inside string").c_str ());
        yy_pop_state ();
 }
@@ -736,10 +735,11 @@ BOM_UTF8  \357\273\277
                        {
                                LexerError (_ ("Unfinished main input").c_str ());
                                do {
-                                       pop_state ();
+                                       yy_pop_state ();
                                } while (YYSTATE != maininput);
                        }
-                       pop_state ();
+                       extra_tokens_ = SCM_EOL;
+                       yy_pop_state ();
                }
                if (!close_input () || !is_main_input_)
                /* Returns YY_NULL */
@@ -762,6 +762,9 @@ BOM_UTF8    \357\273\277
        {WORD}  {
                return scan_bare_word (YYText_utf8 ());
        }
+       \\\"    {
+               start_command_quote ();
+       }
        {COMMAND}/[-_]  | // backup rule
        {COMMAND}       {
                return scan_escaped_word (YYText_utf8 () + 1);
@@ -812,15 +815,25 @@ BOM_UTF8  \357\273\277
 /* Make the lexer generate a token of the given type as the next token. 
  TODO: make it possible to define a value for the token as well */
 void
-Lily_lexer::push_extra_token (int token_type, SCM scm)
+Lily_lexer::push_extra_token (Input const &where, int token_type, SCM scm)
+{
+       extra_tokens_ = scm_cons (scm_cons2 (make_input (where),
+                                            scm_from_int (token_type),
+                                            scm), extra_tokens_);
+}
+
+int
+Lily_lexer::pop_extra_token ()
 {
        if (scm_is_null (extra_tokens_))
-       {
-               if (YY_START != extratoken)
-                       hidden_state_ = YY_START;
-               yy_push_state (extratoken);
-       }
-       extra_tokens_ = scm_acons (scm_from_int (token_type), scm, extra_tokens_);
+               return -1;
+
+  /* produce requested token */
+       yylloc = *unsmob_input (scm_caar (extra_tokens_));
+       int type = scm_to_int (scm_cadar (extra_tokens_));
+       yylval = scm_cddar (extra_tokens_);
+       extra_tokens_ = scm_cdr (extra_tokens_);
+       return type;
 }
 
 void
@@ -861,41 +874,24 @@ Lily_lexer::push_markup_state ()
 void
 Lily_lexer::push_note_state (SCM alist)
 {
-       bool extra = (YYSTATE == extratoken);
-
        SCM p = scm_assq (alist, pitchname_tab_stack_);
 
-       if (extra)
-               yy_pop_state ();
-
        if (scm_is_false (p))
                p = scm_cons (alist, alist_to_hashq (alist));
        pitchname_tab_stack_ = scm_cons (p, pitchname_tab_stack_);
        yy_push_state (notes);
-
-       if (extra) {
-               hidden_state_ = YYSTATE;
-               yy_push_state (extratoken);
-       }
 }
 
 void
 Lily_lexer::pop_state ()
 {
-       bool extra = (YYSTATE == extratoken);
-
-       if (extra)
-               yy_pop_state ();
-
        if (YYSTATE == notes || YYSTATE == chords)
                pitchname_tab_stack_ = scm_cdr (pitchname_tab_stack_);
 
-       yy_pop_state ();
+       // don't cross the maininput threshold
+       if (YYSTATE != maininput)
+               yy_pop_state ();
 
-       if (extra) {
-               hidden_state_ = YYSTATE;
-               yy_push_state (extratoken);
-       }
 }
 
 int
@@ -907,7 +903,7 @@ Lily_lexer::identifier_type (SCM sid)
 
 
 int
-Lily_lexer::scan_escaped_word (string str)
+Lily_lexer::scan_escaped_word (const string &str)
 {
        // use more SCM for this.
 
@@ -922,7 +918,7 @@ Lily_lexer::scan_escaped_word (string str)
        SCM sid = lookup_identifier (str);
        if (Music *m = unsmob_music (sid))
        {
-               m->set_spot (override_input (last_input_));
+               m->set_spot (override_input (here_input ()));
        }
 
        if (sid != SCM_UNDEFINED)
@@ -937,12 +933,12 @@ Lily_lexer::scan_escaped_word (string str)
 }
 
 int
-Lily_lexer::scan_shorthand (string str)
+Lily_lexer::scan_shorthand (const string &str)
 {
        SCM sid = lookup_identifier (str);
        if (Music *m = unsmob_music (sid))
        {
-               m->set_spot (override_input (last_input_));
+               m->set_spot (override_input (here_input ()));
        }
 
        if (sid != SCM_UNDEFINED)
@@ -981,7 +977,7 @@ Lily_lexer::scan_scm_id (SCM sid)
                        funtype = SCM_FUNCTION;
                else programming_error ("Bad syntax function predicate");
 
-               push_extra_token (EXPECT_NO_MORE_ARGS);
+               push_extra_token (here_input (), EXPECT_NO_MORE_ARGS);
                for (s = scm_cdr (s); scm_is_pair (s); s = scm_cdr (s))
                {
                        SCM optional = SCM_UNDEFINED;
@@ -993,19 +989,15 @@ Lily_lexer::scan_scm_id (SCM sid)
                                cs = SCM_CAR (cs);
                        }
                        
-                       if (cs == Pitch_type_p_proc)
-                               push_extra_token (EXPECT_PITCH);
-                       else if (cs == Duration_type_p_proc)
-                               push_extra_token (EXPECT_DURATION);
-                       else if (ly_is_procedure (cs))
-                               push_extra_token (EXPECT_SCM, cs);
+                       if (ly_is_procedure (cs))
+                               push_extra_token (here_input (), EXPECT_SCM, cs);
                        else
                        {
                                programming_error ("Function parameter without type-checking predicate");
                                continue;
                        }
                        if (!scm_is_eq (optional, SCM_UNDEFINED))
-                               push_extra_token (EXPECT_OPTIONAL, optional);
+                               push_extra_token (here_input (), EXPECT_OPTIONAL, optional);
                }
                return funtype;
        }
@@ -1014,7 +1006,7 @@ Lily_lexer::scan_scm_id (SCM sid)
 }
 
 int
-Lily_lexer::scan_bare_word (string str)
+Lily_lexer::scan_bare_word (const string &str)
 {
        SCM sym = ly_symbol2scm (str.c_str ());
        if ((YYSTATE == notes) || (YYSTATE == chords)) {
@@ -1043,10 +1035,7 @@ Lily_lexer::scan_bare_word (string str)
 int
 Lily_lexer::get_state () const
 {
-       if (YY_START == extratoken)
-               return hidden_state_;
-       else
-               return YY_START;
+       return YY_START;
 }
 
 bool
@@ -1112,7 +1101,7 @@ Lily_lexer::eval_scm (SCM readerdata, char extra_token)
                                if (Music *m = unsmob_music (v))
                                {
                                        if (!unsmob_input (m->get_property ("origin")))
-                                               m->set_spot (override_input (last_input_));
+                                               m->set_spot (override_input (here_input ()));
                                }
                                        
                                int token;
@@ -1120,10 +1109,12 @@ Lily_lexer::eval_scm (SCM readerdata, char extra_token)
                                case '$':
                                        token = scan_scm_id (v);
                                        if (!scm_is_eq (yylval, SCM_UNSPECIFIED))
-                                               push_extra_token (token, yylval);
+                                               push_extra_token (here_input (),
+                                                                 token, yylval);
                                        break;
                                case '#':
-                                       push_extra_token (SCM_IDENTIFIER, v);
+                                       push_extra_token (here_input (),
+                                                         SCM_IDENTIFIER, v);
                                        break;
                                }
                        }
@@ -1135,7 +1126,7 @@ Lily_lexer::eval_scm (SCM readerdata, char extra_token)
        if (Music *m = unsmob_music (sval))
        {
                if (!unsmob_input (m->get_property ("origin")))
-                       m->set_spot (override_input (last_input_));
+                       m->set_spot (override_input (here_input ()));
        }
 
        return sval;