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