]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/lexer.ll
release: 1.4.12
[lilypond.git] / lily / lexer.ll
index d08ee082cf30fd74f1ecd4f2cdc63d9a847789df..ea40d1d8caa5c2cfbc84ceba46b0c75a8c37ebe8 100644 (file)
@@ -24,6 +24,9 @@
 
 #include <stdio.h>
 #include <ctype.h>
+#include <iostream.h> /* gcc 3.0 */
+#include <errno.h>
+
 
 #include "score.hh"
 #include "lily-guile.hh"
@@ -49,6 +52,7 @@ RH 7 fix (?)
 
 void strip_trailing_white (String&);
 void strip_leading_white (String&);
+String lyric_fudge (String s);
 
 
 bool
@@ -70,6 +74,9 @@ LYRICS                ({AA}|{TEX})[^0-9 \t\n\f]*
 
 */
 
+
+SCM scan_fraction (String);
+
 %}
 
 %option c++
@@ -94,7 +101,7 @@ A            [a-zA-Z]
 AA             {A}|_
 N              [0-9]
 AN             {AA}|{N}
-PUNCT          [?!:']
+PUNCT          [?!:'`]
 ACCENT         \\[`'"^]
 NATIONAL       [\001-\006\021-\027\031\036\200-\377]
 TEX            {AA}|-|{PUNCT}|{ACCENT}|{NATIONAL}
@@ -102,6 +109,7 @@ WORD                {A}{AN}*
 ALPHAWORD      {A}+
 DIGIT          {N}
 UNSIGNED       {N}+
+FRACTION       {N}+\/{N}+
 INT            -?{UNSIGNED}
 REAL           ({INT}\.{N}*)|(-?\.{N}+)
 KEYWORD                \\{WORD}
@@ -141,10 +149,10 @@ HYPHEN            --
 <INITIAL,chords,lyrics,notes>\\version{WHITE}* {
        yy_push_state (version);
 }
-<version>\"[^"]*\";?   { /* got the include file name */
+<version>\"[^"]*\"     { /* got the version number */
        String s (YYText ()+1);
        s = s.left_str (s.index_last_i ('"'));
-       DEBUG_OUT << "#version `" << s << "'\n";
+
        yy_pop_state ();
        if (!valid_version_b (s))
                return INVALID;
@@ -186,7 +194,7 @@ HYPHEN              --
 <incl>\"[^"]*\";?   { /* got the include file name */
        String s (YYText ()+1);
        s = s.left_str (s.index_last_i ('"'));
-       DEBUG_OUT << "#include `" << s << "'\n";
+
        new_input (s,source_global_l);
        yy_pop_state ();
 }
@@ -195,14 +203,18 @@ HYPHEN            --
        strip_trailing_white (s);
        if (s.length_i () && (s[s.length_i () - 1] == ';'))
          s = s.left_str (s.length_i () - 1);
-       DEBUG_OUT << "#include `\\" << s << "'\n";
+
        SCM sid = lookup_identifier (s);
        if (gh_string_p (sid)) {
                new_input (ly_scm2string (sid), source_global_l);
                yy_pop_state ();
        } else { 
-           String msg (_f ("wrong or undefined identifier: `%s'", s ));        
+           String msg (_f ("wrong or undefined identifier: `%s'", s ));
+
            LexerError (msg.ch_C ());
+           SCM err = scm_current_error_port ();
+           scm_puts ("This value was found in the table: ", err);
+           scm_display (sid, err);
          }
 }
 <incl>\"[^"]*   { // backup rule
@@ -263,6 +275,10 @@ HYPHEN             --
        {NOTECOMMAND}   {
                return scan_escaped_word (YYText () + 1); 
        }
+       {FRACTION}      {
+               yylval.scm =  scan_fraction (YYText ());
+               return FRACTION;
+       }
 
        {DIGIT}         {
                yylval.i = String_convert::dec2_i (String (YYText ()));
@@ -289,7 +305,7 @@ HYPHEN              --
                *yylval.string += YYText ();
        }
        \"      {
-               DEBUG_OUT << "quoted string: `" << *yylval.string << "'\n";
+
                yy_pop_state ();
 
                /* yylval is union. Must remember STRING before setting SCM*/
@@ -307,6 +323,10 @@ HYPHEN             --
        \" {
                start_quote ();
        }
+       {FRACTION}      {
+               yylval.scm =  scan_fraction (YYText ());
+               return FRACTION;
+       }
        {UNSIGNED}              {
                yylval.i = String_convert::dec2_i (String (YYText ()));
                return UNSIGNED;
@@ -321,14 +341,7 @@ HYPHEN             --
                        return yylval.i = EXTENDER;
                if (s == "--")
                        return yylval.i = HYPHEN;
-               int i = 0;
-                       while ((i=s.index_i ("_")) != -1) // change word binding "_" to " "
-                       * (s.ch_l () + i) = ' ';
-               if ((i=s.index_i ("\\,")) != -1)   // change "\," to TeX's "\c "
-                       {
-                       * (s.ch_l () + i + 1) = 'c';
-                       s = s.left_str (i+2) + " " + s.right_str (s.length_i ()-i-2);
-                       }
+               s = lyric_fudge (s);
 
                char c = s[s.length_i () - 1];
                if (c == '{' ||  c == '}') // brace open is for not confusing dumb tools.
@@ -336,7 +349,7 @@ HYPHEN              --
                                _ ("Brace found at end of lyric. Did you forget a space?"));
                yylval.scm = ly_str02scm (s.ch_C ());
 
-               DEBUG_OUT << "lyric : `" << s << "'\n";
+
                return STRING;
        }
        . {
@@ -350,6 +363,10 @@ HYPHEN             --
        {NOTECOMMAND}   {
                return scan_escaped_word (YYText () + 1);
        }
+       {FRACTION}      {
+               yylval.scm =  scan_fraction (YYText ());
+               return FRACTION;
+       }
        {UNSIGNED}              {
                yylval.i = String_convert::dec2_i (String (YYText ()));
                return UNSIGNED;
@@ -375,7 +392,7 @@ HYPHEN              --
 }
 
 <<EOF>> {
-       DEBUG_OUT << "<<eof>>";
+
 
        if (! close_input ()) { 
          yyterminate (); // can't move this, since it actually rets a YY_NULL
@@ -393,8 +410,8 @@ HYPHEN              --
        Real r;
        int cnv=sscanf (YYText (), "%lf", &r);
        assert (cnv == 1);
-       DEBUG_OUT  << "REAL" << r<<'\n';
-       yylval.real = r;
+
+       yylval.scm = gh_double2scm (r);
        return REAL;
 }
 
@@ -404,12 +421,12 @@ HYPHEN            --
 }
 
 [{}]   {
-       DEBUG_OUT << "parens\n";
+
        return YYText ()[0];
 }
 [*:=]          {
        char c = YYText ()[0];
-       DEBUG_OUT << "misc char" <<c<<"\n";
+
        return c;
 }
 
@@ -427,6 +444,8 @@ HYPHEN              --
        return E_SMALLER;
     case '!':
        return E_EXCLAMATION;
+    case '\\':
+       return E_BACKSLASH;
     case '(':
        return E_OPEN;
     case ')':
@@ -592,6 +611,15 @@ strip_trailing_white (String&s)
 
 
 
+Lilypond_version oldest_version ("1.3.59");
+
+void
+print_lilypond_versions (ostream &os)
+{
+  os << _f ("Oldest supported input version: %s", oldest_version.str ()) 
+    << endl;
+}
+
 
 bool
 valid_version_b (String s)
@@ -607,3 +635,44 @@ valid_version_b (String s)
   return true;
 }
        
+
+String
+lyric_fudge (String s)
+{
+  char  * chars  =s.copy_ch_p ();
+
+  for (char * p = chars; *p ; p++)
+    {
+      if (*p == '_' && (p == chars || *(p-1) != '\\'))
+       *p = ' ';
+    }
+  
+  s = String (chars);
+  delete[] chars;
+
+  int i =0;    
+  if ((i=s.index_i ("\\,")) != -1)   // change "\," to TeX's "\c "
+    {
+      * (s.ch_l () + i + 1) = 'c';
+      s = s.left_str (i+2) + " " + s.right_str (s.length_i ()-i-2);
+    }
+
+  return s;
+}
+
+/*
+Convert "NUM/DEN" into a '(NUM . DEN) cons.
+*/
+SCM
+scan_fraction (String frac)
+{
+       int i = frac.index_i ('/');
+       int l = frac.length_i ();
+       String left = frac.left_str (i);
+       String right = frac.right_str (l - i - 1);
+
+       int n = String_convert::dec2_i (left);
+       int d = String_convert::dec2_i (right);
+       return gh_cons (gh_int2scm (n), gh_int2scm (d));
+}
+