]> git.donarmstrong.com Git - lilypond.git/blob - src/midi-lexer.l
dfbafd5fbf6eb688de5a0770a13953404a59183c
[lilypond.git] / src / midi-lexer.l
1 %{
2 // midi-lexer.l
3
4 //#include <stdio.h>
5
6 #include "string.hh"
7 #include "proto.hh"
8 #include "midi-main.hh"
9 #include "my-midi-lexer.hh"
10 #include "midi-parser.hh"
11
12 %}
13
14 %option c++
15 %option noyywrap
16 %option nodefault
17 %option yylineno
18 %option debug
19 %option yyclass="My_midi_lexer"
20 %option stack
21
22 %x data
23 %x event
24 %x int8
25 %x int16
26 %x int32
27 %x meta_event
28 %x track
29
30 INT8            [\x00-\xff]
31 INT16           {INT8}{INT8}
32 INT32           {INT16}{INT16}
33 INT7_8UNSET     [\x00-\x7f]
34 INT7_8SET       [\x80-\xff]
35 VARINT          {INT7_8SET}{0,3}{INT7_8UNSET}
36
37 HEADER          MThd
38 TRACK           MTrk
39
40 XRUNNING_STATUS [\x30-\x4f]
41 RUNNING_STATUS  [\x00-\x5f]
42 DATA_ENTRY      [\x60-\x79]
43 ALL_NOTES_OFF   [\x7a-\x7f]
44 NOTE_OFF        [\x80-\x8f]
45 NOTE_ON         [\x90-\x9f]
46 POLYPHONIC_AFTERTOUCH   [\xa0-\xaf]
47 CONTROLMODE_CHANGE      [\xb0-\xbf]
48 PROGRAM_CHANGE  [\xc0-\xcf]
49 CHANNEL_AFTERTOUCH      [\xd0-\xdf]
50 PITCHWHEEL_RANGE        [\xe0-\xef]
51
52 SYSEX_EVENT1    [\xf0]
53 SYSEX_EVENT2    [\xf7]
54
55 META_EVENT      [\xff]
56
57 SEQUENCE        [\x00][\x02]
58 TEXT            [\x01] 
59 COPYRIGHT       [\x02]
60 TRACK_NAME      [\x03]
61 INSTRUMENT_NAME [\x04]
62 LYRIC           [\x05]
63 MARKER          [\x06]
64 CUE_POINT       [\x07]
65
66 END_OF_TRACK    [\x2f][\x00]
67 TEMPO           [\x51][\x03]
68 SMPTE_OFFSET    [\x54][\x05]
69 TIME            [\x58][\x04]
70 KEY             [\x59][\x02]
71 SSME            [\0x7f][\x03]
72
73 %%
74
75 {HEADER}/{INT32}        { // using /{INT32}; longer match than {INT32}
76         dtor << "lex: header" << endl;
77         yy_push_state( int16 ); 
78         yy_push_state( int16 ); 
79         yy_push_state( int16 ); 
80         yy_push_state( int32 ); 
81         return HEADER;
82 }
83
84 {TRACK}/{INT32} { // using /{INT32}; longer match than {INT32}
85         dtor << "lex: track" << endl;
86         yy_push_state( track ); 
87         yy_push_state( int32 ); 
88         return TRACK;
89 }
90 {INT8}  {
91         error( String( "top level: illegal byte: " )
92                 + StringConversion::bin2hex_str( String( *YYText() ) ) );
93         exit( 1 );
94 }
95 <int32>{INT32}  {
96         dtor << "lex: int32" << endl;
97         assert( YYLeng() == 4 );
98         String str( (Byte const*)YYText(), YYLeng() );
99         yylval.i = StringConversion::bin2int_i( str );
100         yy_pop_state();
101         return INT32;
102 }
103 <int16>{INT16}  {
104         dtor << "lex: int16" << endl;
105         assert( YYLeng() == 2 );
106         String str( (Byte const*)YYText(), YYLeng() );
107         yylval.i = StringConversion::bin2int_i( str );
108         yy_pop_state();
109         return INT16;
110 }
111 <int8>{INT8}    {
112         dtor << "lex: int8" << endl;
113         assert( YYLeng() == 1 );
114 //      yylval.byte = *(Byte*)YYText();
115         yylval.i = *(Byte*)YYText();
116         yy_pop_state(); 
117         return INT8;
118 }
119
120 <track>{VARINT} {
121         String str( (Byte const*)YYText(), YYLeng() );
122         yylval.i = My_midi_lexer::varint2int_i( str );
123         dtor << String( "lex: track: varint(" ) 
124                 + String( yylval.i ) + "): "
125                 + StringConversion::bin2hex_str( str ) << endl;
126         yy_push_state( event ); 
127         return VARINT;
128 }
129 <track>{INT8}   {
130         error( String( "track: illegal byte: " ) 
131                 + StringConversion::bin2hex_str( String( *YYText() ) ) );
132         exit( 1 );
133 }
134 <event>{RUNNING_STATUS} {
135 //      yylval.byte = *(Byte*)YYText();
136         yylval.i = *(Byte*)YYText();
137         dtor << String ( "lex: running status: " ) + String( yylval.i ) << endl;
138         yy_pop_state(); 
139 //      yy_push_state( int8 );
140         yy_push_state( int8 );
141         return RUNNING_STATUS;
142 }
143 <event>{DATA_ENTRY}     {
144 //      yylval.byte = *(Byte*)YYText();
145         yylval.i = *(Byte*)YYText();
146         dtor << String ( "lex: undefined data entry: " ) + String( yylval.i ) << endl;
147         yy_pop_state(); 
148         yy_push_state( int8 );
149         return DATA_ENTRY;
150 }
151 <event>{ALL_NOTES_OFF}  {
152         dtor << "lex: all note off" << endl;
153 //      yylval.byte = *(Byte*)YYText();
154         yylval.i = *(Byte*)YYText();
155         dtor << String ( "lex: all notes off: " ) + String( yylval.i ) << endl;
156         yy_pop_state(); 
157         yy_push_state( int8 );
158         yy_push_state( int8 );
159         return ALL_NOTES_OFF;
160 }
161 <event>{NOTE_OFF}       {
162         dtor << "lex: note off" << endl;
163 //      yylval.byte = *(Byte*)YYText();
164         yylval.i = *(Byte*)YYText();
165         yy_pop_state(); 
166         yy_push_state( int8 );
167         yy_push_state( int8 );
168         return NOTE_OFF;
169 }
170 <event>{NOTE_ON}        {
171         dtor << "lex: note on" << endl;
172 //      yylval.byte = *(Byte*)YYText();
173         yylval.i = *(Byte*)YYText();
174         yy_pop_state(); 
175         yy_push_state( int8 );
176         yy_push_state( int8 );
177         return NOTE_ON;
178 }
179 <event>{POLYPHONIC_AFTERTOUCH}  {
180         dtor << "lex: polyphonic aftertouch" << endl;
181 //      yylval.byte = *(Byte*)YYText();
182         yylval.i = *(Byte*)YYText();
183         yy_pop_state(); 
184         yy_push_state( int8 );
185         yy_push_state( int8 );
186         return POLYPHONIC_AFTERTOUCH;
187 }
188 <event>{CONTROLMODE_CHANGE}     {
189         dtor << "lex: controlmode change" << endl;
190 //      yylval.byte = *(Byte*)YYText();
191         yylval.i = *(Byte*)YYText();
192         yy_pop_state(); 
193         yy_push_state( int8 );
194         yy_push_state( int8 );
195         return CONTROLMODE_CHANGE;
196 }
197 <event>{PROGRAM_CHANGE} {
198         dtor << "lex: program change" << endl;
199 //      yylval.byte = *(Byte*)YYText();
200         yylval.i = *(Byte*)YYText();
201         yy_pop_state(); 
202         yy_push_state( int8 );
203         return PROGRAM_CHANGE;
204 }
205 <event>{CHANNEL_AFTERTOUCH}     {
206         dtor << "lex: channel aftertouch" << endl;
207 //      yylval.byte = *(Byte*)YYText();
208         yylval.i = *(Byte*)YYText();
209         yy_pop_state(); 
210         yy_push_state( int8 );
211         yy_push_state( int8 );
212         return CHANNEL_AFTERTOUCH;
213 }
214 <event>{PITCHWHEEL_RANGE} {
215         dtor << "lex: pitchwheel range" << endl;
216 //      yylval.byte = *(Byte*)YYText();
217         yylval.i = *(Byte*)YYText();
218         yy_pop_state(); 
219         yy_push_state( int8 );
220         yy_push_state( int8 );
221         return PITCHWHEEL_RANGE;
222 }
223 <event>{SYSEX_EVENT1} { // len data
224         dtor << "lex: sysex1" << endl;
225         yy_pop_state(); 
226         yy_push_state( data );
227         return SYSEX_EVENT1;
228 }
229 <event>{SYSEX_EVENT2} { // len data
230         dtor << "lex: sysex2" << endl;
231         yy_pop_state(); 
232 //      yy_push_state( int8 ); //?
233         yy_push_state( data );
234         return SYSEX_EVENT2;
235 }
236 <event>{META_EVENT}     {
237         dtor << "lex: meta" << endl;
238         yy_push_state( meta_event );
239         return META_EVENT;
240 }
241 <event>{INT8}   {
242         error( String( "event: illegal byte: " ) 
243                 + StringConversion::bin2hex_str( String( *YYText() ) ) );
244         exit( 1 );
245 }
246 <meta_event>{SEQUENCE}  {       // ssss sequence number
247         dtor << "lex: sequence" << endl;
248         yy_pop_state();
249         yy_pop_state();
250         yy_push_state( int16 );
251         return SEQUENCE;
252 }
253 <meta_event>{TEXT}      {               // len data
254         dtor << "lex: text" << endl;
255         yy_pop_state();
256         yy_pop_state();
257         yy_push_state( data );
258         return TEXT;
259 }
260 <meta_event>{COPYRIGHT} {
261         dtor << "lex: copyright" << endl;
262         yy_pop_state();
263         yy_pop_state();
264         yy_push_state( data );
265         return COPYRIGHT;
266 }
267 <meta_event>{TRACK_NAME}        {
268         dtor << "lex: track name" << endl;
269         yy_pop_state();
270         yy_pop_state();
271         yy_push_state( data );
272         return TRACK_NAME;
273 }
274 <meta_event>{INSTRUMENT_NAME}   {
275         dtor << "lex: instrument name" << endl;
276         yy_pop_state();
277         yy_pop_state();
278         yy_push_state( data );
279         return INSTRUMENT_NAME;
280 }
281 <meta_event>{LYRIC}     {
282         dtor << "lex: lyric" << endl;
283         yy_pop_state();
284         yy_pop_state();
285         yy_push_state( data );
286         return LYRIC;
287 }
288 <meta_event>{MARKER}    {
289         dtor << "lex: marker" << endl;
290         yy_pop_state();
291         yy_pop_state();
292         yy_push_state( data );
293         return MARKER;
294 }
295 <meta_event>{CUE_POINT} {
296         dtor << "lex: cue point" << endl;
297         yy_pop_state();
298         yy_pop_state();
299         yy_push_state( data );
300         return CUE_POINT;
301 }
302 <meta_event>{TEMPO}     {       // tttttt usec
303         dtor << "lex: tempo" << endl;
304         yy_pop_state();
305         yy_pop_state();
306         yy_push_state( int8 );
307         yy_push_state( int8 );
308         yy_push_state( int8 );
309         return TEMPO;
310 }
311 <meta_event>{SMPTE_OFFSET}      {               // hr mn se fr ff
312         dtor << "lex: smpte offset" << endl;
313         yy_pop_state();
314         yy_pop_state();
315         yy_push_state( int8 );
316         yy_push_state( int8 );
317         yy_push_state( int8 );
318         yy_push_state( int8 );
319         yy_push_state( int8 );
320         return SMPTE_OFFSET;
321 }
322 <meta_event>{TIME}      {               // nn dd cc bb
323         dtor << "lex: time" << endl;
324         yy_pop_state();
325         yy_pop_state();
326         yy_push_state( int8 );
327         yy_push_state( int8 );
328         yy_push_state( int8 );
329         yy_push_state( int8 );
330         return TIME;
331 }
332 <meta_event>{KEY}       {       // sf mi
333         dtor << "lex: key" << endl;
334         yy_pop_state();
335         yy_pop_state();
336         yy_push_state( int8 );
337         yy_push_state( int8 );
338         return KEY;
339 }
340 <meta_event>{SSME}      {       // len data
341         dtor << "lex: smme" << endl;
342         yy_pop_state();
343         yy_pop_state();
344         yy_push_state( data );
345         return SSME;
346 }
347 <meta_event>{END_OF_TRACK} {
348         dtor << "lex: end of track" << endl;
349         yy_pop_state();
350         yy_pop_state();
351         yy_pop_state();
352         return END_OF_TRACK;
353 }
354 <meta_event>{INT8} {
355         warning( String( "meta_event: unimplemented event: " )
356                 + StringConversion::bin2hex_str( String( *YYText() ) ),
357                 *this->here_ch_c_l() );
358         yy_pop_state();
359         yy_pop_state();
360         yy_push_state( int8 ); 
361         yy_push_state( int8 );
362         return INT8;
363 }
364
365 <data>{VARINT} {
366         dtor << "lex: data" << endl;
367         String str( (Byte const*)YYText(), YYLeng() );
368         int i = My_midi_lexer::varint2int_i( str );
369         String* str_p = new String;
370         while ( i-- )
371                 *str_p += (char)yyinput();
372         yylval.str_p = str_p;
373         yy_pop_state();
374         return DATA;
375 }
376 <data>{INT8}    {
377         error( String( "data: illegal byte: " )
378                 + StringConversion::bin2hex_str( String( *YYText() ) ) );
379         exit( 1 );
380 }
381
382 <<EOF>> {
383 //      mtor << "<<EOF>>";
384
385         if ( !close_i() )
386           yyterminate(); // can't move this, since it actually rets a YY_NULL
387 }
388
389 %%
390