]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/lexer.l
release: 0.0.47
[lilypond.git] / lily / lexer.l
index 8e9d503536162067d4f3dca998ec99532401105d..9ecc6f9e4d4d09bb852ad413a2b85ed01f699a7f 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "string.hh"
 #include "string-convert.hh"
-#include "lexer.hh"
+#include "my-lily-lexer.hh"
 #include "varray.hh"
 #include "parser.hh"
 #include "debug.hh"
        yy_push_state(quote);\
        yylval.string = new String
 
+#define yylval (*(YYSTYPE*)lexval_l)
 
+#define YY_USER_ACTION add_lexed_char(YYLeng());
 %}
 
 %option c++
 %option noyywrap
 %option nodefault
-%option yylineno
 %option debug
-%option yyclass="My_flex_lexer"
+%option yyclass="My_lily_lexer"
 %option stack
+%option never-interactive 
+%option warn
 
-%x notes
 %x incl
-%x quote
 %x lyrics
+%x notes
+%x quote
 
 
 
@@ -48,28 +51,32 @@ WORD                {A}{AN}*
 ALPHAWORD      {A}+
 INT            -?{N}+
 REAL           {INT}?(\.{N}*)?
-
-RESTNAME       r|s|p
+KEYWORD                \\{WORD}
+WHITE          [ \n\t\f]
+BLACK          [^ \n\t\f]
+RESTNAME       r
 NOTECOMMAND    \\{WORD}
 DOTS           \.+
-LYRICS         {TEX}+
+LYRICS         {AA}[^0-9 \t\n\f]*
 COMMENT                %.*\n
 
 %%
 
+<lyrics,INITIAL,notes>{COMMENT}        {
+}
 
 
 
 include           {
        yy_push_state(incl);
 }
-<incl>[ \t]*      { /* eat the whitespace */ }
-<incl>\"[^"]*\"+   { /* got the include file name */
-   String s (YYText()+1);
-   s = s.left_str(s.length_i()-1);
-   defined_ch_c_l = here_ch_c_l() - String( YYText() ).length_i() - 1;
-   new_input(s);
-   yy_pop_state();
+<incl>{WHITE}*      { /* eat the whitespace */ }
+<incl>\"[^"]*\"   { /* got the include file name */
+       String s (YYText()+1);
+       s = s.left_str(s.length_i()-1);
+       mtor << "#include `" << s << "\'\n";
+       new_input(s,source_l_g);
+       yy_pop_state();
 }
 
 <notes>{RESTNAME}      {
@@ -78,28 +85,35 @@ include           {
        mtor << "rest:"<< yylval.string;
        return RESTNAME;
 }
-<notes,INITIAL>{ALPHAWORD}     {
-       String str = YYText();
-       mtor << "word: `" << str<< "'\n";
-       Identifier * id = lookup_identifier(str);
-       if (id) {               
-               yylval.id = id;
-               return id->token_code_i_;
-       }
+<INITIAL,lyrics,notes>\\\${BLACK}*{WHITE}      {
+       String s=YYText() + 2;
+       s=s.left_str(s.length_i() - 1);
+       return scan_escaped_word(s);
+}
+<INITIAL,lyrics,notes>\${BLACK}*{WHITE}                {
+       String s=YYText() + 1;
+       s=s.left_str(s.length_i() - 1);
+       return scan_bare_word(s);
+}
+<notes>{ALPHAWORD}/\'  {
+       post_quotes_b_ = true;
+       return scan_bare_word(YYText());
+}
+<notes>\'+             {
+       yylval.i = YYLeng();
+       if (post_quotes_b_) {
+               post_quotes_b_ = false;
+               return POST_QUOTES;
+       } else
+               return PRE_QUOTES;
+}
+<notes>{ALPHAWORD}     {
+       return scan_bare_word(YYText());
 
-       yylval.string=new String( str );
-       return STRING;
 }
-<notes,INITIAL>{NOTECOMMAND}   {
-       String c = YYText() +1;
-       mtor << "\\word: `" << YYText()+1<<"'\n";
-       int l = lookup_keyword(c);
-       if (l != -1)
-               return l;
-       
-       String *sp = new String( c);
-       yylval.string=sp;
-       return STRING;
+
+<notes>{NOTECOMMAND}   {
+       return scan_escaped_word(YYText()+1);
 }
 
 <notes>{DOTS}          {
@@ -110,25 +124,24 @@ include           {
        yylval.i = String_convert::dec2_i( String( YYText() ) );
        return INT;
 }
-<notes>{COMMENT}       {
-}
-<notes>[ \t\n]+                {
 
-}
 <notes>\+\+            {
        return CONCAT;
 }
 <notes>\" {
        start_quote();
 }
-<notes>.       {
-       return yylval.c = YYText()[0];
-}
 
 
 \"             {
        start_quote();
 }
+<quote>\\\\    {
+       *yylval.string += '\\';
+}
+<quote>\\\"    {
+       *yylval.string +='\"';
+}
 <quote>[^"]+   {
        *yylval.string += YYText();
 }
@@ -150,30 +163,7 @@ include           {
        return INT;
 }
 <lyrics>{NOTECOMMAND}  {
-       String c = YYText() +1;
-       mtor << "\\word: `" << YYText()+1<<"'\n";
-       int l = lookup_keyword(c);
-       if (l != -1)
-               return l;
-
-/* let's try passing tex's typesetting macros like \ss \alpha \c */
-       String* str_p = new String(YYText());
-       yylval.string=str_p;
-       mtor << "\\word: `" << *str_p << "'\n";
-       return STRING;  
-
-/* and skip identifiers...
-       Identifier * id = lookup_identifier(c);
-       if (id) {               
-               yylval.id = id;
-               return IDENTIFIER;
-       }
-       String *sp = new String( c);
-
-       yylval.string=sp;
-
-       return STRING;
-*/
+       return scan_escaped_word(YYText()+1);
 }
 <lyrics>{LYRICS} {
        /* ugr. This sux. */
@@ -192,9 +182,6 @@ include           {
 }
 <lyrics>\|     {
        return YYText()[0];
-}
-<lyrics>{COMMENT}              { 
-
 }
 <lyrics>[{}]   {
        return YYText()[0];
@@ -202,14 +189,19 @@ include           {
 <lyrics>[()\[\]|/.^>_-] {
        return yylval.c = YYText()[0];
 }
-<lyrics>[ \t\n]+               {
-}
 
 <<EOF>> {
-       mtor << "<<EOF>>";
+       mtor << "<<eof>>";
 
-       if (! close_input())
+       if (! close_input()) { 
          yyterminate(); // can't move this, since it actually rets a YY_NULL
+       }
+}
+{WORD} {
+       return scan_bare_word(YYText());
+}
+{KEYWORD}      {
+       return scan_escaped_word(YYText()+1);
 }
 {REAL}         {
        Real r;
@@ -230,33 +222,73 @@ include           {
        mtor << "misc char" <<c<<"\n";
        return c;
 }
-[ \t\n]+       {
+<*>{WHITE}+    {
        
 }
-
-{COMMENT}              {
-       //ignore
+<notes>.       {
+       return yylval.c = YYText()[0];
 }
-.              {
-       error( String( "illegal character: " ) + String( YYText()[0] ), here_ch_c_l() );
+
+<*>.           {
+       LexerError( String( "illegal character: " ) +String( YYText()[0] ));
        return YYText()[0];
 }
 
 %%
 
 void
-My_flex_lexer::push_note_state()
+My_lily_lexer::push_note_state()
 {
        yy_push_state(notes);
 }
 
 void
-My_flex_lexer::push_lyric_state()
+My_lily_lexer::push_lyric_state()
 {
        yy_push_state(lyrics);
 }
 void
-My_flex_lexer::pop_state()
+My_lily_lexer::pop_state()
 {
        yy_pop_state();
 }
+
+int
+My_lily_lexer::scan_escaped_word(String str)
+{      
+       mtor << "\\word: `" << str<<"'\n";
+       int l = lookup_keyword(str);
+       if (l != -1) {
+               mtor << "(keyword)\n";
+               return l;
+       }
+       String *sp = new String( str);
+       yylval.string=sp;
+       return STRING;
+}
+int
+My_lily_lexer::scan_bare_word(String str)
+{
+       mtor << "word: `" << str<< "'\n";       
+       Identifier * id = lookup_identifier(str);
+       if (id) {
+               mtor << "(identifier)\n";
+               yylval.id = id;
+               return id->token_code_i_;
+       }
+
+       yylval.string=new String( str );
+       return STRING;
+}
+
+bool
+My_lily_lexer::note_state_b() const
+{
+       return YY_START == notes;
+}
+
+bool
+My_lily_lexer::lyric_state_b() const
+{
+       return YY_START == lyrics;
+}