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