]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/lexer.ll
Doc-de: change appearences of Linux into GNU/Linux
[lilypond.git] / lily / lexer.ll
index bdbf1283141e643d28d2216b381cddd5184586a9..57b9a599678027aa95bde7c06854beeeb65893f8 100644 (file)
@@ -150,19 +150,14 @@ SCM (* scm_parse_error_handler) (void *);
 A              [a-zA-Z\200-\377]
 AA             {A}|_
 N              [0-9]
-AN             {AA}|{N}
 ANY_CHAR       (.|\n)
-PUNCT          [?!:'`]
-ACCENT         \\[`'"^]
+PUNCT          [][()?!:'`]
 SPECIAL_CHAR           [&@]
 NATIONAL       [\001-\006\021-\027\031\036]
-TEX            {AA}|-|{PUNCT}|{ACCENT}|{NATIONAL}|{SPECIAL_CHAR}
-DASHED_WORD            {A}({AN}|-)*
-DASHED_KEY_WORD                \\{DASHED_WORD}
+TEX            {AA}|-|{PUNCT}|{NATIONAL}|{SPECIAL_CHAR}
+WORD           {A}([-_]{A}|{A})*
+COMMAND                \\{WORD}
 
-
-
-ALPHAWORD      {A}+
 UNSIGNED       {N}+
 E_UNSIGNED     \\{N}+
 FRACTION       {N}+\/{N}+
@@ -172,8 +167,6 @@ WHITE               [ \n\t\f\r]
 HORIZONTALWHITE                [ \t]
 BLACK          [^ \n\t\f\r]
 RESTNAME       [rs]
-NOTECOMMAND    \\{A}+
-MARKUPCOMMAND  \\({A}|[-_])+
 LYRICS         ({AA}|{TEX})[^0-9 \t\n\r\f]*
 ESCAPED                [nt\\'"]
 EXTENDER       __
@@ -277,7 +270,7 @@ BOM_UTF8    \357\273\277
 
 
 }
-<sourcefilename>\"[^"]*\"     {
+<sourcefilename>\"[^""]*\"     {
        string s (YYText_utf8 () + 1);
        s = s.substr (0, s.rfind ('\"'));
 
@@ -394,15 +387,25 @@ BOM_UTF8  \357\273\277
        error (_ ("end quote missing"));
        exit (1);
 }
+
+    /* Flex picks the longest matching pattern including trailing
+     * contexts.  Without the backup pattern, r-. does not trigger the
+     * {RESTNAME} rule but rather the {WORD}/[-_] rule coming later,
+     * needed for avoiding backup states.
+     */
+
+<chords,notes,figures>{RESTNAME}/[-_]  |  // pseudo backup rule
 <chords,notes,figures>{RESTNAME}       {
        char const *s = YYText ();
        yylval.scm = scm_from_locale_string (s);
        return RESTNAME;
 }
+<chords,notes,figures>q/[-_]   | // pseudo backup rule
 <chords,notes,figures>q        {
        return CHORD_REPETITION;
 }
 
+<chords,notes,figures>R/[-_]   | // pseudo backup rule
 <chords,notes,figures>R                {
        return MULTI_MEASURE_REST;
 }
@@ -439,11 +442,11 @@ BOM_UTF8  \357\273\277
        }
        char_count_stack_.back () += n;
 
-       sval = eval_scm (sval);
-               
+       sval = eval_scm (sval, '$');
+
        int token = scan_scm_id (sval);
        if (!scm_is_eq (yylval.scm, SCM_UNSPECIFIED))
-         return token;
+               return token;
 }
 
 <INITIAL,notes,lyrics>{ 
@@ -477,11 +480,13 @@ BOM_UTF8  \357\273\277
 }
 
 <notes,figures>{
-       {ALPHAWORD}     {
+       {WORD}/[-_]     | // backup rule
+       {WORD}  {
                return scan_bare_word (YYText_utf8 ());
        }
 
-       {NOTECOMMAND}   {
+       {COMMAND}/[-_]  | // backup rule
+       {COMMAND}       {
                return scan_escaped_word (YYText_utf8 () + 1); 
        }
        {FRACTION}      {
@@ -529,16 +534,13 @@ BOM_UTF8  \357\273\277
                yylval.scm =  scan_fraction (YYText ());
                return FRACTION;
        }
-       {UNSIGNED}/\/[^0-9] { // backup rule
-               yylval.scm = scm_c_read_string (YYText ());
-               return UNSIGNED;
-       }
        {UNSIGNED}/\/   | // backup rule
        {UNSIGNED}              {
                yylval.scm = scm_c_read_string (YYText ());
                return UNSIGNED;
        }
-       {NOTECOMMAND}   {
+       {COMMAND}/[-_]  | // backup rule
+       {COMMAND}       {
                return scan_escaped_word (YYText_utf8 () + 1);
        }
        {LYRICS} {
@@ -564,20 +566,18 @@ BOM_UTF8  \357\273\277
        }
 }
 <chords>{
-       {ALPHAWORD}     {
+       {WORD}/[-_]     | // backup rule
+       {WORD}  {
                return scan_bare_word (YYText_utf8 ());
        }
-       {NOTECOMMAND}   {
+       {COMMAND}/[-_]  | // backup rule
+       {COMMAND}       {
                return scan_escaped_word (YYText_utf8 () + 1);
        }
        {FRACTION}      {
                yylval.scm =  scan_fraction (YYText ());
                return FRACTION;
        }
-       {UNSIGNED}/\/[^0-9] { // backup rule
-               yylval.scm = scm_c_read_string (YYText ());
-               return UNSIGNED;
-       }
        {UNSIGNED}/\/   | // backup rule
        {UNSIGNED}              {
                yylval.scm = scm_c_read_string (YYText ());
@@ -599,7 +599,7 @@ BOM_UTF8    \357\273\277
                return CHORD_CARET;
        }
        . {
-               return YYText ()[0]; // ALPHAWORD catches all multibyte.
+               return YYText ()[0]; // WORD catches all multibyte.
        }
 }
 
@@ -608,7 +608,8 @@ BOM_UTF8    \357\273\277
        \\score {
                return SCORE;
        }
-       {MARKUPCOMMAND} {
+       {COMMAND}/[-_]  | // backup rule
+       {COMMAND} {
                string str (YYText_utf8 () + 1);
 
                 int token_type = MARKUP_FUNCTION;
@@ -703,10 +704,12 @@ BOM_UTF8  \357\273\277
 }
 
 <INITIAL>{
-       {DASHED_WORD}   {
+       {WORD}/[-_]     | // backup rule
+       {WORD}  {
                return scan_bare_word (YYText_utf8 ());
        }
-       {DASHED_KEY_WORD}       {
+       {COMMAND}/[-_]  | // backup rule
+       {COMMAND}       {
                return scan_escaped_word (YYText_utf8 () + 1);
        }
 }
@@ -721,10 +724,6 @@ BOM_UTF8   \357\273\277
        yylval.scm = scm_c_read_string (YYText ());
        return REAL;
 }
--\.    { // backup rule
-       yylval.scm = scm_from_double (0.0);
-       return REAL;
-}
 
 {UNSIGNED}/\/  | // backup rule
 {UNSIGNED}     {
@@ -737,6 +736,8 @@ BOM_UTF8    \357\273\277
 
        return YYText ()[0];
 }
+
+-/\.   | // backup rule
 [*:=]          {
        char c = YYText ()[0];
 
@@ -800,9 +801,13 @@ Lily_lexer::push_extra_token (int token_type, SCM scm)
 }
 
 void
-Lily_lexer::push_chord_state (SCM tab)
+Lily_lexer::push_chord_state (SCM alist)
 {
-       pitchname_tab_stack_ = scm_cons (tab, pitchname_tab_stack_);
+       SCM p = scm_assq (alist, pitchname_tab_stack_);
+
+       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 (chords);
 }
 
@@ -831,10 +836,24 @@ Lily_lexer::push_markup_state ()
 }
 
 void
-Lily_lexer::push_note_state (SCM tab)
+Lily_lexer::push_note_state (SCM alist)
 {
-       pitchname_tab_stack_ = scm_cons (tab, pitchname_tab_stack_);
+       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
@@ -953,7 +972,7 @@ Lily_lexer::scan_bare_word (string str)
        if ((YYSTATE == notes) || (YYSTATE == chords)) {
                SCM handle = SCM_BOOL_F;
                if (scm_is_pair (pitchname_tab_stack_))
-                       handle = scm_hashq_get_handle (scm_car (pitchname_tab_stack_), sym);
+                       handle = scm_hashq_get_handle (scm_cdar (pitchname_tab_stack_), sym);
                
                if (scm_is_pair (handle)) {
                        yylval.scm = scm_cdr (handle);
@@ -1006,8 +1025,15 @@ Lily_lexer::is_figure_state () const
        return get_state () == figures;
 }
 
+// The extra_token parameter specifies how to convert multiple values
+// into additional tokens.  For '#', additional values get pushed as
+// SCM_IDENTIFIER.  For '$', they get checked for their type and get
+// pushed as a corresponding *_IDENTIFIER token.  Since the latter
+// tampers with yylval, it can only be done from the lexer itself, so
+// this function is private.
+
 SCM
-Lily_lexer::eval_scm (SCM readerdata)
+Lily_lexer::eval_scm (SCM readerdata, char extra_token)
 {
        SCM sval = SCM_UNDEFINED;
 
@@ -1024,6 +1050,33 @@ Lily_lexer::eval_scm (SCM readerdata)
                error_level_ = 1;
                return SCM_UNSPECIFIED;
        }
+
+       if (extra_token && SCM_VALUESP (sval))
+       {
+               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))
+                       {
+                               int token;
+                               switch (extra_token) {
+                               case '$':
+                                       token = scan_scm_id (scm_car (v));
+                                       if (!scm_is_eq (yylval.scm, SCM_UNSPECIFIED))
+                                               push_extra_token (token, yylval.scm);
+                                       break;
+                               case '#':
+                                       push_extra_token (SCM_IDENTIFIER, scm_car (v));
+                                       break;
+                               }
+                       }
+                       sval = scm_car (sval);
+               } else
+                       sval = SCM_UNSPECIFIED;
+       }
+
        return sval;
 }