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