]> git.donarmstrong.com Git - lilypond.git/blob - lily/lexer.l
release: 0.0.47
[lilypond.git] / lily / lexer.l
1 %{ // -*-Fundamental-*-
2
3 #include <stdio.h>
4
5 #include "string.hh"
6 #include "string-convert.hh"
7 #include "my-lily-lexer.hh"
8 #include "varray.hh"
9 #include "parser.hh"
10 #include "debug.hh"
11 #include "input-score.hh"
12 #include "parseconstruct.hh"
13 #include "main.hh"
14 #include "identifier.hh"
15
16 #define start_quote()   \
17         yy_push_state(quote);\
18         yylval.string = new String
19
20 #define yylval (*(YYSTYPE*)lexval_l)
21
22 #define YY_USER_ACTION  add_lexed_char(YYLeng());
23 %}
24
25 %option c++
26 %option noyywrap
27 %option nodefault
28 %option debug
29 %option yyclass="My_lily_lexer"
30 %option stack
31 %option never-interactive 
32 %option warn
33
34 %x incl
35 %x lyrics
36 %x notes
37 %x quote
38
39
40
41 A               [a-zA-Z]
42 AA              {A}|_
43 N               [0-9]
44 AN              {AA}|{N}
45 PUNCT           [?!,.:;']
46 ACCENT          \\[`'"^]
47 NATIONAL        [\241-\377]
48 TEX             {AA}|-|{PUNCT}|{ACCENT}|{NATIONAL}
49
50 WORD            {A}{AN}*
51 ALPHAWORD       {A}+
52 INT             -?{N}+
53 REAL            {INT}?(\.{N}*)?
54 KEYWORD         \\{WORD}
55 WHITE           [ \n\t\f]
56 BLACK           [^ \n\t\f]
57 RESTNAME        r
58 NOTECOMMAND     \\{WORD}
59 DOTS            \.+
60 LYRICS          {AA}[^0-9 \t\n\f]*
61 COMMENT         %.*\n
62
63 %%
64
65 <lyrics,INITIAL,notes>{COMMENT} {
66 }
67
68
69
70 include           {
71         yy_push_state(incl);
72 }
73 <incl>{WHITE}*      { /* eat the whitespace */ }
74 <incl>\"[^"]*\"   { /* got the include file name */
75         String s (YYText()+1);
76         s = s.left_str(s.length_i()-1);
77         mtor << "#include `" << s << "\'\n";
78         new_input(s,source_l_g);
79         yy_pop_state();
80 }
81
82 <notes>{RESTNAME}       {
83         const char *s = YYText();
84         yylval.string = new String (s); 
85         mtor << "rest:"<< yylval.string;
86         return RESTNAME;
87 }
88 <INITIAL,lyrics,notes>\\\${BLACK}*{WHITE}       {
89         String s=YYText() + 2;
90         s=s.left_str(s.length_i() - 1);
91         return scan_escaped_word(s);
92 }
93 <INITIAL,lyrics,notes>\${BLACK}*{WHITE}         {
94         String s=YYText() + 1;
95         s=s.left_str(s.length_i() - 1);
96         return scan_bare_word(s);
97 }
98 <notes>{ALPHAWORD}/\'   {
99         post_quotes_b_ = true;
100         return scan_bare_word(YYText());
101 }
102 <notes>\'+              {
103         yylval.i = YYLeng();
104         if (post_quotes_b_) {
105                 post_quotes_b_ = false;
106                 return POST_QUOTES;
107         } else
108                 return PRE_QUOTES;
109 }
110 <notes>{ALPHAWORD}      {
111         return scan_bare_word(YYText());
112
113 }
114
115 <notes>{NOTECOMMAND}    {
116         return scan_escaped_word(YYText()+1);
117 }
118
119 <notes>{DOTS}           {
120         yylval.i = strlen(YYText());
121         return DOTS;
122 }
123 <notes>{INT}            {
124         yylval.i = String_convert::dec2_i( String( YYText() ) );
125         return INT;
126 }
127
128 <notes>\+\+             {
129         return CONCAT;
130 }
131 <notes>\" {
132         start_quote();
133 }
134
135
136 \"              {
137         start_quote();
138 }
139 <quote>\\\\     {
140         *yylval.string += '\\';
141 }
142 <quote>\\\"     {
143         *yylval.string +='\"';
144 }
145 <quote>[^"]+    {
146         *yylval.string += YYText();
147 }
148 <quote>\"       {
149         mtor << "quoted string: `" << *yylval.string << "'\n";
150         yy_pop_state();
151         return STRING;
152 }
153
154 <lyrics>\" {
155         start_quote();
156 }
157 <lyrics>{DOTS}          {
158         yylval.i = strlen(YYText());
159         return DOTS;
160 }
161 <lyrics>{INT}           {
162         yylval.i = String_convert::dec2_i( String( YYText() ) );
163         return INT;
164 }
165 <lyrics>{NOTECOMMAND}   {
166         return scan_escaped_word(YYText()+1);
167 }
168 <lyrics>{LYRICS} {
169         /* ugr. This sux. */
170         String s (YYText()); 
171         int i = 0;
172         while ((i=s.index_i("_")) != -1) // change word binding "_" to " "
173                 *(s.ch_l() + i) = ' ';
174         if ((i=s.index_i("\\,")) != -1)   // change "\," to TeX's "\c "
175                 {
176                 *(s.ch_l() + i + 1) = 'c';
177                 s = s.left_str(i+2) + " " + s.right_str(s.length_i()-i-2);
178                 }
179         yylval.string = new String(s);
180         mtor << "lyric : `" << s << "'\n";
181         return STRING;
182 }
183 <lyrics>\|      {
184         return YYText()[0];
185 }
186 <lyrics>[{}]    {
187         return YYText()[0];
188 }
189 <lyrics>[()\[\]|/.^>_-] {
190         return yylval.c = YYText()[0];
191 }
192
193 <<EOF>> {
194         mtor << "<<eof>>";
195
196         if (! close_input()) { 
197           yyterminate(); // can't move this, since it actually rets a YY_NULL
198         }
199 }
200 {WORD}  {
201         return scan_bare_word(YYText());
202 }
203 {KEYWORD}       {
204         return scan_escaped_word(YYText()+1);
205 }
206 {REAL}          {
207         Real r;
208         int cnv=sscanf (YYText(), "%lf", &r);
209         assert(cnv == 1);
210         mtor  << "REAL" << r<<'\n';
211         yylval.real = r;
212         return REAL;
213 }
214
215 [{}]    {
216
217         mtor << "parens\n";
218         return YYText()[0];
219 }
220 [*:=]           {
221         char c = YYText()[0];
222         mtor << "misc char" <<c<<"\n";
223         return c;
224 }
225 <*>{WHITE}+     {
226         
227 }
228 <notes>.        {
229         return yylval.c = YYText()[0];
230 }
231
232 <*>.            {
233         LexerError( String( "illegal character: " ) +String( YYText()[0] ));
234         return YYText()[0];
235 }
236
237 %%
238
239 void
240 My_lily_lexer::push_note_state()
241 {
242         yy_push_state(notes);
243 }
244
245 void
246 My_lily_lexer::push_lyric_state()
247 {
248         yy_push_state(lyrics);
249 }
250 void
251 My_lily_lexer::pop_state()
252 {
253         yy_pop_state();
254 }
255
256 int
257 My_lily_lexer::scan_escaped_word(String str)
258 {       
259         mtor << "\\word: `" << str<<"'\n";
260         int l = lookup_keyword(str);
261         if (l != -1) {
262                 mtor << "(keyword)\n";
263                 return l;
264         }
265         String *sp = new String( str);
266         yylval.string=sp;
267         return STRING;
268 }
269 int
270 My_lily_lexer::scan_bare_word(String str)
271 {
272         mtor << "word: `" << str<< "'\n";       
273         Identifier * id = lookup_identifier(str);
274         if (id) {
275                 mtor << "(identifier)\n";
276                 yylval.id = id;
277                 return id->token_code_i_;
278         }
279
280         yylval.string=new String( str );
281         return STRING;
282 }
283
284 bool
285 My_lily_lexer::note_state_b() const
286 {
287         return YY_START == notes;
288 }
289
290 bool
291 My_lily_lexer::lyric_state_b() const
292 {
293         return YY_START == lyrics;
294 }