#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
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} {
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} {
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();
}
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. */
}
<lyrics>\| {
return YYText()[0];
-}
-<lyrics>{COMMENT} {
-
}
<lyrics>[{}] {
return YYText()[0];
<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;
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;
+}