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