%{ // -*-Fundamental-*-
+/*
+ lexer.l -- implement the Flex lexer
+
+ source file of the LilyPond music typesetter
+
+ (c) 1996,1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+
+/*
+ backup rules
+
+ after making a change to the lexer rules, run
+ flex -b <this lexer file>
+ and make sure that
+ lex.backup
+ contains no backup states, but only the reminder
+ Compressed tables always back up.
+ (don-t forget to rm lex.yy.cc :-)
+ */
+
#include <stdio.h>
%x lyrics
%x notes
%x quote
-
+%x longcomment
A [a-zA-Z]
KEYWORD \\{WORD}
WHITE [ \n\t\f]
BLACK [^ \n\t\f]
-RESTNAME r
-NOTECOMMAND \\{WORD}
+RESTNAME [rs]
+NOTECOMMAND \\{A}+
DOTS \.+
-LYRICS {AA}[^0-9 \t\n\f]*
-COMMENT %.*\n
+LYRICS ({AA}|{NATIONAL})[^0-9 \t\n\f]*
%%
-<lyrics,INITIAL,notes>{COMMENT} {
-}
+<notes,incl,INITIAL,lyrics>{
+ "%{" {
+ yy_push_state(longcomment);
+ }
+ %[^{\n].*\n {
+ }
+ %[^{\n] { // backup rule
+ }
+ %\n {
+ }
+ %[^{\n].* {
+ }
+ {WHITE}+ {
+
+ }
+}
+<longcomment>{
+ [^\%]* {
+ }
+ \%*[^}%]* {
+ }
+ "%"+"}" {
+ yy_pop_state();
+ }
+}
+<longcomment><<EOF>> {
+ LexerError("EOF found inside a comment");
+ if (! close_input()) {
+ yyterminate(); // can't move this, since it actually rets a YY_NULL
+ }
+}
<notes,INITIAL,lyrics>
\\include {
yy_push_state(incl);
}
-<incl>{WHITE}* { /* eat the whitespace */ }
<incl>\"[^"]*\" { /* got the include file name */
String s (YYText()+1);
s = s.left_str(s.length_i()-1);
new_input(s,source_l_g);
yy_pop_state();
}
-
+<incl>\"[^"]* { // backup rule
+ cerr << "missing end quote" << endl;
+ exit( 1 );
+}
<notes>{RESTNAME} {
const char *s = YYText();
yylval.string = new String (s);
s=s.left_str(s.length_i() - 1);
return scan_bare_word(s);
}
-<notes>{ALPHAWORD}/\' {
- post_quotes_b_ = true;
- return scan_bare_word(YYText());
+<INITIAL,lyrics,notes>\\\${BLACK}* { // backup rule
+ cerr << "white expected" << endl;
+ exit( 1 );
}
-<notes>\'+ {
- yylval.i = YYLeng();
- if (post_quotes_b_) {
- post_quotes_b_ = false;
- return POST_QUOTES;
- } else
- return PRE_QUOTES;
+<INITIAL,lyrics,notes>\${BLACK}* { // backup rule
+ cerr << "white expected" << endl;
+ exit( 1 );
}
-<notes>{ALPHAWORD} {
- return scan_bare_word(YYText());
+<notes>{
+ {ALPHAWORD}/\' {
+ post_quotes_b_ = true;
+ return scan_bare_word(YYText());
+ }
+ \'+ {
+ yylval.i = YYLeng();
+ if (post_quotes_b_) {
+ post_quotes_b_ = false;
+ return POST_QUOTES;
+ } else
+ return PRE_QUOTES;
+ }
+ {ALPHAWORD} {
+ return scan_bare_word(YYText());
-}
+ }
-<notes>{NOTECOMMAND} {
- return scan_escaped_word(YYText()+1);
-}
+ {NOTECOMMAND} {
+ return scan_escaped_word(YYText()+1);
+ }
-<notes>{DOTS} {
- yylval.i = strlen(YYText());
- return DOTS;
-}
-<notes>{INT} {
- yylval.i = String_convert::dec2_i( String( YYText() ) );
- return INT;
-}
+ {DOTS} {
+ yylval.i = strlen(YYText());
+ return DOTS;
+ }
+ {INT} {
+ yylval.i = String_convert::dec2_i( String( YYText() ) );
+ return INT;
+ }
-<notes>\+\+ {
- return CONCAT;
-}
-<notes>\" {
- start_quote();
+ \+\+ {
+ return CONCAT;
+ }
+ \" {
+ start_quote();
+ }
}
-
\" {
start_quote();
}
-<quote>\\\\ {
- *yylval.string += '\\';
-}
-<quote>\\\" {
- *yylval.string +='\"';
-}
-<quote>[^"]+ {
- *yylval.string += YYText();
-}
-<quote>\" {
- mtor << "quoted string: `" << *yylval.string << "'\n";
- yy_pop_state();
- return STRING;
+<quote>{
+ \\\\ {
+ *yylval.string += '\\';
+ }
+ \\\" {
+ *yylval.string +='\"';
+ }
+ [^"]+ {
+ *yylval.string += YYText();
+ }
+ \" {
+ mtor << "quoted string: `" << *yylval.string << "'\n";
+ yy_pop_state();
+ return STRING;
+ }
}
-<lyrics>\" {
- start_quote();
-}
-<lyrics>{DOTS} {
- yylval.i = strlen(YYText());
- return DOTS;
-}
-<lyrics>{INT} {
- yylval.i = String_convert::dec2_i( String( YYText() ) );
- return INT;
-}
-<lyrics>{NOTECOMMAND} {
- return scan_escaped_word(YYText()+1);
-}
-<lyrics>{LYRICS} {
- /* ugr. This sux. */
- String s (YYText());
- 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);
- }
- yylval.string = new String(s);
- mtor << "lyric : `" << s << "'\n";
- return STRING;
-}
-<lyrics>\| {
- return YYText()[0];
-}
-<lyrics>[{}] {
- return YYText()[0];
-}
-<lyrics>[()\[\]|/.^>;_-] {
- return yylval.c = YYText()[0];
+<lyrics>{
+
+ \" {
+ start_quote();
+ }
+ {DOTS} {
+ yylval.i = strlen(YYText());
+ return DOTS;
+ }
+ {INT} {
+ yylval.i = String_convert::dec2_i( String( YYText() ) );
+ return INT;
+ }
+ {NOTECOMMAND} {
+ return scan_escaped_word(YYText()+1);
+ }
+ {LYRICS} {
+ /* ugr. This sux. */
+ String s (YYText());
+ 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);
+ }
+ yylval.string = new String(s);
+ mtor << "lyric : `" << s << "'\n";
+ return STRING;
+ }
+ . {
+ return yylval.c = YYText()[0];
+ }
}
<<EOF>> {
return REAL;
}
+{INT}\. { // backup rule
+ cerr << "int. encountered" << endl;
+ exit( 1 );
+}
+
[{}] {
mtor << "parens\n";
mtor << "misc char" <<c<<"\n";
return c;
}
-<*>{WHITE}+ {
-
-}
+
<INITIAL,notes>. {
return yylval.c = YYText()[0];
}
+
<INITIAL,lyrics,notes>\\. {
char c= YYText()[1];
yylval.c = c;