]> git.donarmstrong.com Git - lilypond.git/blob - lily/lexer.l
release: 0.0.54
[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 <notes,INITIAL,lyrics>
71 \\include           {
72         yy_push_state(incl);
73 }
74 <incl>{WHITE}*      { /* eat the whitespace */ }
75 <incl>\"[^"]*\"   { /* got the include file name */
76         String s (YYText()+1);
77         s = s.left_str(s.length_i()-1);
78         mtor << "#include `" << s << "\'\n";
79         new_input(s,source_l_g);
80         yy_pop_state();
81 }
82 <*>{WHITE}+     {
83         
84 }
85 <notes>{RESTNAME}       {
86         const char *s = YYText();
87         yylval.string = new String (s); 
88         mtor << "rest:"<< yylval.string;
89         return RESTNAME;
90 }
91 <INITIAL,lyrics,notes>\\\${BLACK}*{WHITE}       {
92         String s=YYText() + 2;
93         s=s.left_str(s.length_i() - 1);
94         return scan_escaped_word(s);
95 }
96 <INITIAL,lyrics,notes>\${BLACK}*{WHITE}         {
97         String s=YYText() + 1;
98         s=s.left_str(s.length_i() - 1);
99         return scan_bare_word(s);
100 }
101 <notes>{ALPHAWORD}/\'   {
102         post_quotes_b_ = true;
103         return scan_bare_word(YYText());
104 }
105 <notes>\'+              {
106         yylval.i = YYLeng();
107         if (post_quotes_b_) {
108                 post_quotes_b_ = false;
109                 return POST_QUOTES;
110         } else
111                 return PRE_QUOTES;
112 }
113 <notes>{ALPHAWORD}      {
114         return scan_bare_word(YYText());
115
116 }
117
118 <notes>{NOTECOMMAND}    {
119         return scan_escaped_word(YYText()+1);
120 }
121
122 <notes>{DOTS}           {
123         yylval.i = strlen(YYText());
124         return DOTS;
125 }
126 <notes>{INT}            {
127         yylval.i = String_convert::dec2_i( String( YYText() ) );
128         return INT;
129 }
130
131 <notes>\+\+             {
132         return CONCAT;
133 }
134 <notes>\" {
135         start_quote();
136 }
137
138
139 \"              {
140         start_quote();
141 }
142 <quote>\\\\     {
143         *yylval.string += '\\';
144 }
145 <quote>\\\"     {
146         *yylval.string +='\"';
147 }
148 <quote>[^"]+    {
149         *yylval.string += YYText();
150 }
151 <quote>\"       {
152         mtor << "quoted string: `" << *yylval.string << "'\n";
153         yy_pop_state();
154         return STRING;
155 }
156
157 <lyrics>\" {
158         start_quote();
159 }
160 <lyrics>{DOTS}          {
161         yylval.i = strlen(YYText());
162         return DOTS;
163 }
164 <lyrics>{INT}           {
165         yylval.i = String_convert::dec2_i( String( YYText() ) );
166         return INT;
167 }
168 <lyrics>{NOTECOMMAND}   {
169         return scan_escaped_word(YYText()+1);
170 }
171 <lyrics>{LYRICS} {
172         /* ugr. This sux. */
173         String s (YYText()); 
174         int i = 0;
175         while ((i=s.index_i("_")) != -1) // change word binding "_" to " "
176                 *(s.ch_l() + i) = ' ';
177         if ((i=s.index_i("\\,")) != -1)   // change "\," to TeX's "\c "
178                 {
179                 *(s.ch_l() + i + 1) = 'c';
180                 s = s.left_str(i+2) + " " + s.right_str(s.length_i()-i-2);
181                 }
182         yylval.string = new String(s);
183         mtor << "lyric : `" << s << "'\n";
184         return STRING;
185 }
186 <lyrics>\|      {
187         return YYText()[0];
188 }
189 <lyrics>[{}]    {
190         return YYText()[0];
191 }
192 <lyrics>. {
193         return yylval.c = YYText()[0];
194 }
195
196 <<EOF>> {
197         mtor << "<<eof>>";
198
199         if (! close_input()) { 
200           yyterminate(); // can't move this, since it actually rets a YY_NULL
201         }
202 }
203 {WORD}  {
204         return scan_bare_word(YYText());
205 }
206 {KEYWORD}       {
207         return scan_escaped_word(YYText()+1);
208 }
209 {REAL}          {
210         Real r;
211         int cnv=sscanf (YYText(), "%lf", &r);
212         assert(cnv == 1);
213         mtor  << "REAL" << r<<'\n';
214         yylval.real = r;
215         return REAL;
216 }
217
218 [{}]    {
219
220         mtor << "parens\n";
221         return YYText()[0];
222 }
223 [*:=]           {
224         char c = YYText()[0];
225         mtor << "misc char" <<c<<"\n";
226         return c;
227 }
228
229 <INITIAL,notes>.        {
230         return yylval.c = YYText()[0];
231 }
232 <INITIAL,lyrics,notes>\\. {
233     char c= YYText()[1];
234     yylval.c = c;
235     switch (c) {
236     case '>':
237         return E_BIGGER;
238     case '<':
239         return E_SMALLER;
240     case '!':
241         return E_EXCLAMATION;
242     default:
243         return E_CHAR;
244     }
245 }
246
247 <*>.            {
248         LexerError( String( "illegal character: " ) +String( YYText()[0] ));
249         return YYText()[0];
250 }
251
252 %%
253
254 void
255 My_lily_lexer::push_note_state()
256 {
257         yy_push_state(notes);
258 }
259
260 void
261 My_lily_lexer::push_lyric_state()
262 {
263         yy_push_state(lyrics);
264 }
265 void
266 My_lily_lexer::pop_state()
267 {
268         yy_pop_state();
269 }
270
271 int
272 My_lily_lexer::scan_escaped_word(String str)
273 {       
274         mtor << "\\word: `" << str<<"'\n";
275         int l = lookup_keyword(str);
276         if (l != -1) {
277                 mtor << "(keyword)\n";
278                 return l;
279         }
280         Identifier * id = lookup_identifier(str);
281         if (id) {
282                 mtor << "(identifier)\n";
283                 yylval.id = id;
284                 return id->token_code_i_;
285         }
286         mtor << "(string)";
287         String *sp = new String( str);
288         yylval.string=sp;
289         return STRING;
290 }
291
292 int
293 My_lily_lexer::scan_bare_word(String str)
294 {
295         mtor << "word: `" << str<< "'\n";       
296         if (YYSTATE == notes){
297                 Melodic_req * mel_l = lookup_melodic_req_l(str);
298                 if (mel_l) {
299                     mtor << "(notename)\n";
300                     yylval.melreq = mel_l;
301                     return NOTENAME_ID;
302                 }
303         }
304         if (YYSTATE != notes) {
305                 // ugr. Should do this in note mode?
306                 Identifier * id = lookup_identifier(str);
307                 if (id) {
308                         mtor << "(identifier)\n";
309                         yylval.id = id;
310                         return id->token_code_i_;
311                 }
312         }
313         yylval.string=new String( str );
314         return STRING;
315 }
316
317 bool
318 My_lily_lexer::note_state_b() const
319 {
320         return YY_START == notes;
321 }
322
323 bool
324 My_lily_lexer::lyric_state_b() const
325 {
326         return YY_START == lyrics;
327 }