]> git.donarmstrong.com Git - lilypond.git/blob - src/midi-lexer.l
d95696dbb5a10c24237404e56f3bac0241e53039
[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 "my-midi-lexer.hh"
9 #include "midi-parser.hh"
10
11 #ifndef MIDI_LEX_DEBUG
12 #define puts( x )
13 #endif
14
15 %}
16
17 %option c++
18 %option noyywrap
19 %option nodefault
20 %option yylineno
21 %option debug
22 %option yyclass="My_midi_lexer"
23 %option stack
24
25 %x data
26 %x event
27 %x int8
28 %x int16
29 %x int32
30 %x meta_event
31 %x track
32
33 INT8            [\x00-\xff]
34 INT16           {INT8}{INT8}
35 INT32           {INT16}{INT16}
36 INT7_8UNSET     [\x00-\x7f]
37 INT7_8SET       [\x80-\xff]
38 VARINT          {INT7_8SET}{0,3}{INT7_8UNSET}
39
40 HEADER          MThd
41 TRACK           MTrk
42
43 RUNNING_STATUS  [\x30-\x4f]
44 NOTE_OFF        [\x80-\x8f]
45 NOTE_ON         [\x90-\x9f]
46 PROGRAM_CHANGE  [\xc0-\xcf]
47
48 SYSEX_EVENT1    [\xf0]
49 SYSEX_EVENT2    [\xf7]
50
51 META_EVENT      [\xff]
52
53 SEQUENCE        [\x00][\x02]
54 TEXT            [\x01] 
55 COPYRIGHT       [\x02]
56 TRACK_NAME      [\x03]
57 INSTRUMENT_NAME [\x04]
58 LYRIC           [\x05]
59 MARKER          [\x06]
60 CUE_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         puts( "lex: header" );
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         puts( "lex: track" );
82         yy_push_state( track ); 
83         yy_push_state( int32 ); 
84         return TRACK;
85 }
86
87 <int32>{INT32}  {
88         puts( "lex: int32" );
89         assert( YYLeng() == 4 );
90         String str( (Byte const*)YYText(), YYLeng() );
91         yylval.i = StringConversion::bin2int_i( str );
92         yy_pop_state();
93         return INT32;
94 }
95 <int16>{INT16}  {
96         puts( "lex: int16" );
97         assert( YYLeng() == 2 );
98         String str( (Byte const*)YYText(), YYLeng() );
99         yylval.i = StringConversion::bin2int_i( str );
100         yy_pop_state();
101         return INT16;
102 }
103 <int8>{INT8}    {
104         puts( "lex: int8" );
105         assert( YYLeng() == 1 );
106 //      yylval.byte = *(Byte*)YYText();
107         yylval.i = *(Byte*)YYText();
108         yy_pop_state(); 
109         return INT8;
110 }
111
112 <track>{VARINT} {
113         puts( "lex: track: varint" );
114         String str( (Byte const*)YYText(), YYLeng() );
115         yylval.i = My_midi_lexer::varint2int_i( str );
116         yy_push_state( event ); 
117         return VARINT;
118 }
119
120 <event>{RUNNING_STATUS} {
121         yylval.byte = *(Byte*)YYText();
122         yy_pop_state(); 
123         yy_push_state( int8 );
124         return RUNNING_STATUS;
125 }
126 <event>{NOTE_OFF}       {
127         puts( "lex: note off" );
128         yylval.byte = *(Byte*)YYText();
129         yy_pop_state(); 
130         yy_push_state( int8 );
131         yy_push_state( int8 );
132         return NOTE_OFF;
133 }
134 <event>{NOTE_ON}        {
135         puts( "lex: note on" );
136         yylval.byte = *(Byte*)YYText();
137         yy_pop_state(); 
138         yy_push_state( int8 );
139         yy_push_state( int8 );
140         return NOTE_ON;
141 }
142 <event>{PROGRAM_CHANGE} {
143         yylval.byte = *(Byte*)YYText();
144         yy_pop_state(); 
145         yy_push_state( int8 );
146         return PROGRAM_CHANGE;
147 }
148 <event>{META_EVENT}     {
149         yy_push_state( meta_event );
150         return META_EVENT;
151 }
152
153 <meta_event>{SEQUENCE}  {       // ssss sequence number
154         yy_push_state( int16 );
155         return SEQUENCE;
156 }
157 <meta_event>{TEXT}      {               // len data
158         yy_push_state( data );
159         return TEXT;
160 }
161 <meta_event>{COPYRIGHT} {
162         yy_push_state( data );
163         return COPYRIGHT;
164 }
165 <meta_event>{TRACK_NAME}        {
166         yy_push_state( data );
167         return TRACK_NAME;
168 }
169 <meta_event>{INSTRUMENT_NAME}   {
170         yy_push_state( data );
171         return INSTRUMENT_NAME;
172 }
173 <meta_event>{LYRIC}     {
174         yy_push_state( data );
175         return LYRIC;
176 }
177 <meta_event>{MARKER}    {
178         yy_push_state( data );
179         return MARKER;
180 }
181 <meta_event>{CUE_POINT} {
182         yy_push_state( data );
183         return CUE_POINT;
184 }
185 <meta_event>{TEMPO}     {       // tttttt usec
186         puts( "lex: tempo" );
187         yy_pop_state();
188         yy_pop_state();
189         yy_push_state( int8 );
190         yy_push_state( int8 );
191         yy_push_state( int8 );
192         return TEMPO;
193 }
194 <meta_event>{SMPTE_OFFSET}      {               // hr mn se fr ff
195         yy_pop_state();
196         yy_pop_state();
197         yy_push_state( int8 );
198         yy_push_state( int8 );
199         yy_push_state( int8 );
200         yy_push_state( int8 );
201         yy_push_state( int8 );
202         return SMPTE_OFFSET;
203 }
204 <meta_event>{TIME}      {               // nn dd cc bb
205         puts( "lex: time" );
206         yy_pop_state();
207         yy_pop_state();
208         yy_push_state( int8 );
209         yy_push_state( int8 );
210         yy_push_state( int8 );
211         yy_push_state( int8 );
212         return TIME;
213 }
214 <meta_event>{KEY}       {       // sf mi
215         puts( "lex: key" );
216         yy_pop_state();
217         yy_pop_state();
218         yy_push_state( int8 );
219         yy_push_state( int8 );
220         return KEY;
221 }
222 <meta_event>{SSME}      {       // len data
223         yy_pop_state();
224         yy_pop_state();
225         yy_push_state( data );
226         return SSME;
227 }
228 <meta_event>{END_OF_TRACK} {
229         puts( "lex: end of track" );
230         yy_pop_state();
231         yy_pop_state();
232         yy_pop_state();
233         return END_OF_TRACK;
234 }
235 <meta_event>{INT8} {
236         yylval.byte = *(Byte*)YYText();
237         return INT8;
238 }
239
240 <data>{VARINT} {
241         String str( (Byte const*)YYText(), YYLeng() );
242         int i = My_midi_lexer::varint2int_i( str );
243         String* str_p = new String;
244         while ( i-- )
245                 *str_p += (char)yyinput();
246         yylval.str_p = str_p;
247         yy_pop_state();
248         yy_pop_state();
249         return DATA;
250 }
251
252
253 <<EOF>> {
254 //      mtor << "<<EOF>>";
255
256         if ( !close_i() )
257           yyterminate(); // can't move this, since it actually rets a YY_NULL
258 }
259
260 %%
261