]> git.donarmstrong.com Git - lilypond.git/blob - lily/my-lily-parser.cc
patch::: 1.1.5.jcn2: extender
[lilypond.git] / lily / my-lily-parser.cc
1 /*
2   my-lily-parser.cc -- implement My_lily_parser
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "my-lily-parser.hh"
10 #include "my-lily-lexer.hh"
11 #include "debug.hh"
12 #include "main.hh"
13 #include "music-list.hh"
14 #include "musical-request.hh"
15 #include "command-request.hh"
16 #include "parser.hh"
17 #include "scope.hh"
18 #include "file-results.hh"
19 #include "midi-def.hh"
20 #include "paper-def.hh"
21 #include "identifier.hh"
22
23 My_lily_parser::My_lily_parser (Sources * source_l)
24 {
25   first_b_ = true;
26   source_l_ = source_l;
27   lexer_p_ = 0;
28   abbrev_beam_type_i_ = 0;
29   default_duration_.durlog_i_ = 2;
30   default_abbrev_i_ = 0;
31   error_level_i_ = 0;
32   extender_req = 0;
33   fatal_error_i_ = 0;
34   default_header_p_ =0;
35 }
36
37 My_lily_parser::~My_lily_parser()
38 {
39   delete lexer_p_;
40   delete default_header_p_;
41 }
42
43
44
45 void
46 My_lily_parser::set_version_check (bool ig)
47 {
48   ignore_version_b_ = ig;
49 }
50
51 void
52 My_lily_parser::parse_file (String init, String s)
53 {
54   lexer_p_ = new My_lily_lexer;
55   init_str_ = init;
56   lexer_p_->main_input_str_ = s;
57
58   *mlog << _ ("Parsing...");
59
60   init_parse_b_ = false;
61   set_yydebug (!monitor->silent_b ("Parser") && check_debug);
62   lexer_p_->new_input (init, source_l_);
63   do_yyparse ();
64
65   if (!define_spot_array_.empty())
66     {
67       warning (_ ("braces don't match"));
68       error_level_i_ = 1;
69     }
70
71   inclusion_global_array = lexer_p_->filename_str_arr_;
72 }
73
74 void
75 My_lily_parser::remember_spot()
76 {
77   define_spot_array_.push (here_input());
78 }
79
80 char const *
81 My_lily_parser::here_ch_C() const
82 {
83   return lexer_p_->here_ch_C();
84 }
85
86 void
87 My_lily_parser::parser_error (String s)
88 {
89   here_input().error (s);
90   if (fatal_error_i_)
91     exit (fatal_error_i_);
92   error_level_i_ = 1;
93   exit_status_i_ = 1;
94 }
95
96 void
97 My_lily_parser::set_abbrev_beam (int type_i)
98 {
99   abbrev_beam_type_i_ = type_i;
100 }
101
102
103 void
104 My_lily_parser::set_last_duration (Duration const *d)
105 {
106   default_duration_ = *d;
107
108   /* 
109      forget plet part,
110      but keep sticky plet factor within plet brackets
111     */  
112   default_duration_.plet_ = plet_;
113 }
114
115
116 Simultaneous_music*
117 My_lily_parser::get_word_element (String s, Duration * duration_p)
118 {
119   Simultaneous_music* velt_p = new Request_chord;
120
121   Lyric_req* lreq_p = new Lyric_req;
122   lreq_p ->text_str_ = s;
123   lreq_p->duration_ = *duration_p;
124   lreq_p->set_spot (here_input());
125
126   velt_p->add_music (lreq_p);
127
128   delete  duration_p;
129   return velt_p;
130 }
131
132
133 Simultaneous_music *
134 My_lily_parser::get_rest_element (String s,  Duration * duration_p)
135 {
136   Simultaneous_music* velt_p = new Request_chord;
137   velt_p->set_spot (here_input());
138
139   if (s=="s")
140     { /* Space */
141       Skip_req * skip_p = new Skip_req;
142       skip_p->duration_ = *duration_p;
143
144       skip_p->set_spot (here_input());
145       velt_p->add_music (skip_p);
146     }
147   else
148     {
149       Rest_req * rest_req_p = new Rest_req;
150       rest_req_p->duration_ = *duration_p;
151       rest_req_p->set_spot (here_input());
152
153       velt_p->add_music (rest_req_p);
154     }
155
156   delete duration_p;
157   return velt_p;
158 }
159
160 Simultaneous_music *
161 My_lily_parser::get_note_element (Note_req *rq, Duration * duration_p)
162 {
163   Simultaneous_music*v = new Request_chord;
164   v->set_spot (here_input ());
165
166   v->add_music (rq);
167
168   // too bad parser reads (default) duration via member access,
169   // this hack will do for now..
170   if (abbrev_beam_type_i_)
171     {
172       assert (!duration_p->plet_b ());
173       duration_p->set_plet (1, 2);
174     }
175   rq->duration_ = *duration_p;
176   rq->set_spot (here_input ());
177   delete duration_p ;
178   return v;
179 }
180
181
182 /*
183   UGH.
184  */
185 Array<Request*>*
186 My_lily_parser::get_parens_request (int t)
187 {
188   Array<Request*>& reqs = *new Array<Request*>;
189   switch (t)
190     {
191     case '~':
192       reqs.push (new Tie_req);
193       break;
194     case BEAMPLET:
195     case MAEBTELP:
196       {
197         Plet_req* p = new Plet_req;
198         p->plet_i_ = plet_.type_i_;
199         reqs.push (p);
200       }
201       /* fall through */
202     case '[':
203     case ']':
204       {
205         if (!abbrev_beam_type_i_)
206           {
207             reqs.push (new Beam_req);
208           }
209         else
210           {
211             Abbreviation_beam_req* a = new Abbreviation_beam_req;
212             a->type_i_ = abbrev_beam_type_i_;
213             if (t==']')
214               abbrev_beam_type_i_ = 0;
215             reqs.push (a);
216           }
217       }
218       break;
219
220     case '>':
221     case '!':
222     case '<':
223       reqs.push (new Span_dynamic_req);
224       break;
225
226     case PLET:  
227     case TELP:
228       {
229         Plet_req* p = new Plet_req;
230         p->plet_i_ = plet_.type_i_;
231         reqs.push (p);
232       }
233       break;
234     case ')':
235     case '(':
236       {
237         reqs.push (new Slur_req);
238       }
239       break;
240     default:
241       assert (false);
242       break;
243     }
244
245   switch (t)
246     {
247     case BEAMPLET:
248       dynamic_cast<Span_req*> (reqs.top ())->spantype = Span_req::START;
249       /* fall through */
250     case '<':
251     case '>':
252     case '(':
253     case '[':
254     case PLET:
255       dynamic_cast<Span_req*> (reqs.top ())->spantype = Span_req::START;
256       break;
257     case MAEBTELP:
258       dynamic_cast<Span_req*> (reqs.top ())->spantype = Span_req::STOP;
259       /* fall through */
260     case '!':
261     case ')':
262     case ']':
263       dynamic_cast<Span_req*> (reqs[0])->spantype = Span_req::STOP;
264       break;
265
266     default:
267       break;
268     }
269
270   for (int i = 0; i < reqs.size (); i++)
271     if (dynamic_cast<Span_dynamic_req*> (reqs[i]))
272       {
273         Span_dynamic_req* s_l= dynamic_cast<Span_dynamic_req*> (reqs[i]);
274         s_l->dynamic_dir_ = (t == '<') ? UP:DOWN;
275       }
276
277   // ugh? don't we do this in the parser too?
278   reqs[0]->set_spot (here_input());
279   return &reqs;
280 }
281
282 void
283 My_lily_parser::add_requests (Simultaneous_music*v)
284 {
285   for (int i = 0; i < pre_reqs.size(); i++)
286     {
287       v->add_music (pre_reqs[i]);
288     }
289   pre_reqs.clear();
290   for (int i = 0; i <post_reqs.size(); i++)
291     {
292       v->add_music (post_reqs[i]);
293     }
294
295   post_reqs.clear();
296 }
297
298 Input
299 My_lily_parser::pop_spot()
300 {
301   return define_spot_array_.pop();
302 }
303
304 Input
305 My_lily_parser::here_input() const
306 {
307   Source_file * f_l= lexer_p_->source_file_l();
308   return Input (f_l, here_ch_C());
309 }
310
311 void
312 My_lily_parser::add_notename (String s, Musical_pitch p)
313 {
314   lexer_p_->add_notename (s, p);
315
316 }
317
318 Paper_def*
319 My_lily_parser::default_paper_p ()
320 {
321   Identifier *id = lexer_p_->lookup_identifier ("$defaultpaper");
322   return id ? id->access_content_Paper_def (true) : new Paper_def ;
323 }
324
325 Midi_def*
326 My_lily_parser::default_midi_p ()
327 {
328   Identifier *id = lexer_p_->lookup_identifier ("$defaultmidi");
329   return id ? id->access_content_Midi_def (true) : new Midi_def ;
330 }
331