]> git.donarmstrong.com Git - lilypond.git/blob - lily/my-lily-parser.cc
bdb3846692003dac5a24ce6120e32048102db489
[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 "header.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   fatal_error_i_ = 0;
33   default_header_p_ =0;
34 }
35
36 My_lily_parser::~My_lily_parser()
37 {
38   delete lexer_p_;
39   delete default_header_p_;
40 }
41
42
43 void
44 My_lily_parser::clear_notenames()
45 {
46   lexer_p_->clear_notenames();
47 }
48
49 void
50 My_lily_parser::set_version_check (bool ig)
51 {
52   ignore_version_b_ = ig;
53 }
54
55 void
56 My_lily_parser::parse_file (String init, String s)
57 {
58   lexer_p_ = new My_lily_lexer;
59   init_str_ = init;
60   lexer_p_->main_input_str_ = s;
61
62   *mlog << _ ("Parsing...");
63
64   init_parse_b_ = false;
65   set_yydebug (!monitor->silent_b ("Parser") && check_debug);
66   lexer_p_->new_input (init, source_l_);
67   do_yyparse ();
68
69   if (!define_spot_array_.empty())
70     {
71       warning (_ ("braces don't match"));
72       error_level_i_ = 1;
73     }
74
75   inclusion_global_array = lexer_p_->filename_str_arr_;
76 }
77
78 void
79 My_lily_parser::remember_spot()
80 {
81   define_spot_array_.push (here_input());
82 }
83
84 char const *
85 My_lily_parser::here_ch_C() const
86 {
87   return lexer_p_->here_ch_C();
88 }
89
90 void
91 My_lily_parser::parser_error (String s)
92 {
93   here_input().error (s);
94   if (fatal_error_i_)
95     exit (fatal_error_i_);
96   error_level_i_ = 1;
97   exit_status_i_ = 1;
98 }
99
100 void
101 My_lily_parser::set_abbrev_beam (int type_i)
102 {
103   abbrev_beam_type_i_ = type_i;
104 }
105
106
107 void
108 My_lily_parser::set_last_duration (Duration const *d)
109 {
110   default_duration_ = *d;
111
112   /* 
113      forget plet part,
114      but keep sticky plet factor within plet brackets
115     */  
116   default_duration_.plet_ = plet_;
117 }
118
119
120 Chord*
121 My_lily_parser::get_word_element (String s, Duration * duration_p)
122 {
123   Chord* velt_p = new Request_chord;
124
125   Lyric_req* lreq_p = new Lyric_req;
126   lreq_p ->text_str_ = s;
127   lreq_p->duration_ = *duration_p;
128   lreq_p->set_spot (here_input());
129
130   velt_p->add (lreq_p);
131
132   delete  duration_p;
133   return velt_p;
134 }
135
136
137 Chord *
138 My_lily_parser::get_rest_element (String s,  Duration * duration_p)
139 {
140   Chord* velt_p = new Request_chord;
141   velt_p->set_spot (here_input());
142
143   if (s=="s")
144     { /* Space */
145       Skip_req * skip_p = new Skip_req;
146       skip_p->duration_ = *duration_p;
147
148       skip_p->set_spot (here_input());
149       velt_p->add (skip_p);
150     }
151   else
152     {
153       Rest_req * rest_req_p = new Rest_req;
154       rest_req_p->duration_ = *duration_p;
155       rest_req_p->set_spot (here_input());
156
157       velt_p->add (rest_req_p);
158     }
159
160   delete duration_p;
161   return velt_p;
162 }
163
164 Chord *
165 My_lily_parser::get_note_element (Note_req *rq, Duration * duration_p)
166 {
167   Chord*v = new Request_chord;
168   v->set_spot (here_input ());
169
170   v->add (rq);
171
172   // too bad parser reads (default) duration via member access,
173   // this hack will do for now..
174   if (abbrev_beam_type_i_)
175     {
176       assert (!duration_p->plet_b ());
177       duration_p->set_plet (1, 2);
178     }
179   rq->set_duration (*duration_p);
180   rq->set_spot (here_input ());
181   delete duration_p ;
182   return v;
183 }
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       reqs.top ()->access_Span_req ()->spantype = Span_req::START;
249       /* fall through */
250     case '<':
251     case '>':
252     case '(':
253     case '[':
254     case PLET:
255       reqs[0]->access_Span_req ()->spantype = Span_req::START;
256       break;
257     case MAEBTELP:
258       reqs.top ()->access_Span_req ()->spantype = Span_req::STOP;
259       /* fall through */
260     case '!':
261     case ')':
262     case ']':
263       reqs[0]->access_Span_req ()->spantype = Span_req::STOP;
264       break;
265
266     default:
267       break;
268     }
269
270   for (int i = 0; i < reqs.size (); i++)
271     if (reqs[i]->access_Musical_req ()->access_Span_dynamic_req ())
272       {
273         Span_dynamic_req* s_l= (reqs[i]->access_Musical_req ()->access_Span_dynamic_req ()) ;
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 (Chord*v)
284 {
285   for (int i = 0; i < pre_reqs.size(); i++)
286     {
287       v->add (pre_reqs[i]);
288     }
289   pre_reqs.clear();
290   for (int i = 0; i <post_reqs.size(); i++)
291     {
292       v->add (post_reqs[i]);
293     }
294 #if 0 //disabling...
295   if (default_abbrev_i_)
296     {
297       Abbreviation_req* a = new Abbreviation_req;
298       a->type_i_ = default_abbrev_i_;
299       v->add (a);
300     }
301 #endif
302   post_reqs.clear();
303 }
304
305 Input
306 My_lily_parser::pop_spot()
307 {
308   return define_spot_array_.pop();
309 }
310
311 Input
312 My_lily_parser::here_input() const
313 {
314   Source_file * f_l= lexer_p_->source_file_l();
315   return Input (f_l, here_ch_C());
316 }
317
318 void
319 My_lily_parser::add_notename (String s, Musical_pitch p)
320 {
321   lexer_p_->add_notename (s, p);
322
323 }
324
325 Paper_def*
326 My_lily_parser::default_paper_p ()
327 {
328   Identifier *id = lexer_p_->lookup_identifier ("default_paper");
329   return id ? id->access_Paper_def () : new Paper_def ;
330 }
331
332 Midi_def*
333 My_lily_parser::default_midi_p ()
334 {
335   Identifier *id = lexer_p_->lookup_identifier ("default_midi");
336   return id ? id->access_Midi_def () : new Midi_def ;
337 }
338