]> git.donarmstrong.com Git - lilypond.git/blob - lily/parser.yy
release: 1.3.73
[lilypond.git] / lily / parser.yy
1 %{ // -*-Fundamental-*-
2
3 /*
4   parser.yy -- Bison/C++ parser for mudela
5
6   source file of the GNU LilyPond music typesetter
7
8   (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9            Jan Nieuwenhuizen <janneke@gnu.org>
10 */
11
12 #include <iostream.h>
13 #include "lily-guile.hh"
14 #include "translation-property.hh"
15 #include "lookup.hh"
16 #include "misc.hh"
17 #include "my-lily-lexer.hh"
18 #include "paper-def.hh"
19 #include "midi-def.hh"
20 #include "main.hh"
21 #include "file-path.hh"
22 #include "debug.hh"
23 #include "dimensions.hh"
24 #include "identifier.hh"
25 #include "command-request.hh"
26 #include "musical-request.hh"
27 #include "my-lily-parser.hh"
28 #include "context-specced-music.hh"
29 #include "translator-group.hh"
30 #include "score.hh"
31 #include "music-list.hh"
32 #include "change-translator.hh"
33 #include "file-results.hh"
34 #include "input.hh"
35 #include "scope.hh"
36 #include "relative-music.hh"
37 #include "lyric-combine-music.hh"
38 #include "transposed-music.hh"
39 #include "time-scaled-music.hh"
40 #include "repeated-music.hh"
41 #include "mudela-version.hh"
42 #include "grace-music.hh"
43 #include "auto-change-music.hh"
44 #include "output-property.hh"
45
46 bool
47 is_duration_b (int t)
48 {
49   return t && t == 1 << intlog2(t);
50 }
51
52
53 // mmm JUNKME ?
54 Mudela_version oldest_version ("1.3.59");
55
56 void
57 print_mudela_versions (ostream &os)
58 {
59   os << _f ("Oldest supported input version: %s", oldest_version.str ()) 
60     << endl;
61 }
62
63
64 // needed for bison.simple's malloc() and free()
65 #include <malloc.h>
66
67 #ifndef NDEBUG
68 #define YYDEBUG 1
69 #endif
70
71 #define YYERROR_VERBOSE 1
72
73 #define YYPARSE_PARAM my_lily_parser_l
74 #define YYLEX_PARAM my_lily_parser_l
75 #define THIS ((My_lily_parser *) my_lily_parser_l)
76
77 #define yyerror THIS->parser_error
78 #define ARRAY_SIZE(a,s)   if (a.size () != s) THIS->parser_error (_f ("Expecting %d arguments", s))
79
80 %}
81
82
83 %union {
84     Array<Musical_pitch> *pitch_arr;
85     Link_array<Request> *reqvec;
86     Duration *duration;
87     Identifier *id;
88     String * string;
89     Music *music;
90     Score *score;
91     Scope *scope;
92     Interval *interval;
93     Musical_req* musreq;
94     Music_output_def * outputdef;
95     Musical_pitch * pitch;
96     Midi_def* midi;
97     Moment *moment;
98     Real real;
99     Request * request;
100
101     /* We use SCMs to do strings, because it saves us the trouble of
102 deleting them.  Let's hope that a stack overflow doesnt trigger a move
103 of the parse stack onto the heap. */
104
105     SCM scm;
106
107     Tempo_req *tempo;
108     Translator_group* trans;
109     int i;
110 }
111 %{
112
113 int
114 yylex (YYSTYPE *s,  void * v_l)
115 {
116         My_lily_parser   *pars_l = (My_lily_parser*) v_l;
117         My_lily_lexer * lex_l = pars_l->lexer_p_;
118
119         lex_l->lexval_l = (void*) s;
120         return lex_l->yylex ();
121 }
122
123
124 %}
125
126 %pure_parser
127
128 /* tokens which are not keywords */
129 %token AUTOCHANGE
130 %token TEXTSCRIPT
131 %token ACCEPTS
132 %token ALTERNATIVE
133 %token BAR
134 %token BREATHE
135 %token CHORDMODIFIERS
136 %token CHORDS
137 %token CHAR_T
138 %token CLEF
139 %token CM_T
140 %token CONSISTS
141 %token SEQUENTIAL
142 %token SIMULTANEOUS
143 %token CONSISTSEND
144 %token DURATION
145 %token EXTENDER
146 %token FONT
147 %token GRACE
148 %token HEADER
149 %token HYPHEN
150 %token IN_T
151 %token INVALID
152 %token KEY
153 %token LYRICS
154 %token MARK
155 %token MEASURES
156 %token MIDI
157 %token MM_T
158 %token MUSICAL_PITCH
159 %token NAME
160 %token NOTENAMES
161 %token NOTES
162 %token PAPER
163 %token PARTIAL
164 %token PENALTY
165 %token PROPERTY
166 %token PT_T
167 %token RELATIVE
168 %token REMOVE
169 %token REPEAT
170 %token ADDLYRICS
171 %token SCM_T
172 %token SCORE
173 %token SCRIPT
174 %token SKIP
175 %token SPANREQUEST
176 %token COMMANDSPANREQUEST
177 %token TEMPO
178 %token OUTPUTPROPERTY
179 %token TIME_T
180 %token TIMES
181 %token TRANSLATOR
182 %token TRANSPOSE
183 %token TYPE
184 %token CONTEXT
185
186 /* escaped */
187 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER 
188 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET 
189
190 %type <i>       exclamations questions
191 %token <i>      DIGIT
192 %token <pitch>  NOTENAME_PITCH
193 %token <pitch>  TONICNAME_PITCH
194 %token <pitch>  CHORDMODIFIER_PITCH
195 %token <id>     DURATION_IDENTIFIER
196 %token <id>     IDENTIFIER
197 %token <id>     TRANS_IDENTIFIER
198
199 %token <id>     SCORE_IDENTIFIER
200 %token <id>     MUSIC_OUTPUT_DEF_IDENTIFIER
201
202 %token <scm>    NUMBER_IDENTIFIER
203 %token <scm>    REQUEST_IDENTIFIER
204 %token <scm>    MUSIC_IDENTIFIER
205 %token <scm>    STRING_IDENTIFIER SCM_IDENTIFIER 
206 %token <scm>    DURATION RESTNAME
207 %token <scm>    STRING 
208 %token <scm>    SCM_T
209 %token <i>      UNSIGNED
210 %token <real>   REAL
211
212 %type <outputdef> output_def
213 %type <scope>   mudela_header mudela_header_body
214 %type <request> open_request_parens close_request_parens open_request close_request
215 %type <request> request_with_dir request_that_take_dir verbose_request
216 %type <i>       sub_quotes sup_quotes
217 %type <music>   simple_element  request_chord command_element Simple_music  Composite_music 
218 %type <music>   Alternative_music Repeated_music
219 %type <i>       tremolo_type
220 %type <i>       bare_int  bare_unsigned
221 %type <i>       script_dir
222
223 %type <scm>     identifier_init 
224
225 %type <duration> steno_duration optional_notemode_duration
226 %type <duration> entered_notemode_duration explicit_duration
227         
228 %type <reqvec>  pre_requests post_requests
229 %type <request> gen_text_def
230 %type <pitch>   steno_musical_pitch musical_pitch absolute_musical_pitch
231 %type <pitch>   steno_tonic_pitch
232
233 %type <pitch_arr>       chord_additions chord_subtractions chord_notes chord_step
234 %type <music>   chord
235 %type <pitch>   chord_note chord_inversion chord_bass
236 %type <duration>        duration_length
237
238 %type <scm>  embedded_scm scalar
239 %type <music>   Music Sequential_music Simultaneous_music Music_sequence
240 %type <music>   relative_music re_rhythmed_music
241 %type <music>   property_def translator_change
242 %type <scm> Music_list
243 %type <outputdef>  music_output_def_body
244 %type <request> shorthand_command_req
245 %type <request> post_request 
246 %type <request> command_req verbose_command_req
247 %type <request> extender_req
248 %type <request> hyphen_req
249 %type <scm>     string bare_number number_expression
250 %type <score>   score_block score_body
251
252 %type <trans>   translator_spec_block translator_spec_body
253 %type <tempo>   tempo_request
254 %type <scm> notenames_body notenames_block chordmodifiers_block
255 %type <scm>     script_abbreviation
256
257
258
259 %left '-' '+'
260 %left '*' '/'
261 %left UNARY_MINUS
262
263 %%
264
265 mudela: /* empty */
266         | mudela toplevel_expression {}
267         | mudela assignment  { }
268         | mudela error
269         | mudela INVALID        {
270                 THIS->error_level_i_  =1;
271         }
272         ;
273
274 toplevel_expression:
275         notenames_block                 {
276                 THIS->lexer_p_->pitchname_tab_ =  $1;
277         }
278         | chordmodifiers_block                  {
279                 THIS->lexer_p_->chordmodifier_tab_  = $1;
280         }
281         | mudela_header {
282                 delete header_global_p;
283                 header_global_p = $1;
284         }
285         | score_block {
286                 score_global_array.push ($1);
287         }
288         | output_def {
289                 Identifier * id = new
290                         Music_output_def_identifier ($1, MUSIC_OUTPUT_DEF_IDENTIFIER);
291                 if (dynamic_cast<Paper_def*> ($1))
292                         THIS->lexer_p_->set_identifier ("$defaultpaper", smobify (id));
293                 else if (dynamic_cast<Midi_def*> ($1))
294                         THIS->lexer_p_->set_identifier ("$defaultmidi", smobify (id));
295         }
296         | embedded_scm {
297                 // junk value
298         }       
299         ;
300
301 embedded_scm:
302         SCM_T
303         | SCM_IDENTIFIER 
304         ;
305
306
307 chordmodifiers_block:
308         CHORDMODIFIERS notenames_body   {  $$ = $2; }
309         ;
310
311
312 notenames_block:
313         NOTENAMES notenames_body   {  $$ = $2; }
314         ;
315
316
317
318 notenames_body:
319         embedded_scm    {
320           int i = scm_ilength ($1);
321
322           SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL);
323           for (SCM s = $1; s != SCM_EOL; s = gh_cdr (s)) {
324                 SCM pt = gh_cdar (s);
325                 if (scm_ilength (pt) != 3)
326                         THIS->parser_error ("Need three args");
327                 scm_hashq_set_x (tab, gh_caar(s), pt);
328           }
329
330           $$ = tab;
331         }
332         ;
333
334 mudela_header_body:
335         {
336                 $$ = new Scope;
337                 THIS->lexer_p_-> scope_l_arr_.push ($$);
338         }
339         | mudela_header_body assignment semicolon { 
340
341         }
342         ;
343
344 mudela_header:
345         HEADER '{' mudela_header_body '}'       {
346                 $$ = $3;
347                 THIS->lexer_p_-> scope_l_arr_.pop ();           
348         }
349         ;
350
351
352 /*
353         DECLARATIONS
354 */
355 assignment:
356         STRING {
357                 THIS->remember_spot ();
358         }
359         /* cont */ '=' identifier_init  {
360             THIS->lexer_p_->set_identifier (ly_scm2string ($1), $4);
361
362                 Identifier * id =unsmob_identifier ($4);
363                 Input spot = THIS->pop_spot ();
364                 if (id) id->set_spot (spot);
365         }
366         ;
367
368
369
370 identifier_init:
371         score_block {
372                 $$ = smobify (new Score_identifier ($1, SCORE_IDENTIFIER));
373         }
374         | output_def {
375                 $$ = smobify (new Music_output_def_identifier ($1, MUSIC_OUTPUT_DEF_IDENTIFIER));
376         }
377         | translator_spec_block {
378                 $$ = smobify (new Translator_group_identifier ($1, TRANS_IDENTIFIER));
379         }
380         | Music  {
381                 $$ = $1->self_scm_;
382                 scm_unprotect_object ($$);
383         }
384         | post_request {
385                 $$ = $1->self_scm_;
386                 scm_unprotect_object ($$);
387         }
388         | explicit_duration {
389                 $$ = smobify (new Duration_identifier ($1, DURATION_IDENTIFIER));
390         }
391         | number_expression {
392                 $$ = $1;
393         }
394         | string {
395                 $$ = $1;
396         }
397         | embedded_scm  {
398                 $$ = $1;
399         }
400         ;
401
402 translator_spec_block:
403         TRANSLATOR '{' translator_spec_body '}'
404                 {
405                 $$ = $3;
406         }
407         ;
408
409 translator_spec_body:
410         TRANS_IDENTIFIER        {
411                 $$ = $1->access_content_Translator_group (true);
412                 $$-> set_spot (THIS->here_input ());
413         }
414         | TYPE STRING semicolon {
415                 Translator* t = get_translator_l (ly_scm2string ($2));
416                 Translator_group * tg = dynamic_cast<Translator_group*> (t);
417
418                 if (!tg)
419                         THIS->parser_error (_("Need a translator group for a context"));
420                 
421                 tg = dynamic_cast<Translator_group*> (t->clone ());
422                 tg->set_spot (THIS->here_input ());
423                 $$ = tg;
424         }
425         | translator_spec_body STRING '=' embedded_scm                  {
426                 Translator_group* tg = $$;
427                 tg->set_property (ly_scm2string ($2), $4);
428         }
429         | translator_spec_body STRING '=' identifier_init semicolon     { 
430                 SCM v = gh_int2scm (0);
431                 if (gh_string_p ($4) || gh_number_p ($4) || gh_boolean_p ($4))
432                         v = $4;
433                 else 
434                         THIS->parser_error (_("Wrong type for property value"));
435
436                 /* ugh*/
437                 Translator_group* tg = dynamic_cast<Translator_group*> ($$);
438                 
439                 tg->set_property (ly_scm2string ($2), v);
440         }
441         | translator_spec_body NAME STRING semicolon {
442                 $$->type_str_ = ly_scm2string ($3);
443         }
444         | translator_spec_body CONSISTS STRING semicolon {
445                 dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), true);
446         }
447         | translator_spec_body CONSISTSEND STRING semicolon {
448                 dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), true);
449         }
450         | translator_spec_body ACCEPTS STRING semicolon {
451                 dynamic_cast<Translator_group*> ($$)-> set_acceptor (ly_scm2string ($3), true);
452         }
453         | translator_spec_body REMOVE STRING semicolon {
454                 dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), false);
455         }
456         ;
457
458 /*
459         SCORE
460 */
461 score_block:
462         SCORE { 
463         }
464         /*cont*/ '{' score_body '}'     {
465                 $$ = $4;
466                 if (!$$->def_p_arr_.size ())
467                 {
468                   Identifier *id =
469                         unsmob_identifier (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
470                   $$->add_output (id ? id->access_content_Music_output_def (true) : new Paper_def );
471                 }
472         }
473         ;
474
475 score_body:
476         Music   {
477                 $$ = new Score;
478
479                 $$->set_spot (THIS->here_input ());
480                 SCM m = $1->self_scm_;
481                 scm_unprotect_object (m);
482                 $$->music_ = m;
483         }
484         | SCORE_IDENTIFIER {
485                 $$ = $1->access_content_Score (true);
486         }
487         | score_body mudela_header      {
488                 $$->header_p_ = $2;
489         }
490         | score_body output_def {
491                 $$->add_output ($2);
492         }
493         | score_body error {
494
495         }
496         ;
497
498
499 /*
500         MIDI
501 */
502 output_def:
503         music_output_def_body '}' {
504                 $$ = $1;
505                 THIS-> lexer_p_-> scope_l_arr_.pop();
506         }
507         ;
508
509 music_output_def_body:
510         MIDI '{'    {
511          Identifier *id = unsmob_identifier (THIS->lexer_p_->lookup_identifier ("$defaultmidi"));
512
513                 
514          Midi_def* p =0;
515         if (id)
516                 p = dynamic_cast<Midi_def*> (id->access_content_Music_output_def (true));
517         else
518                 p = new Midi_def;
519
520          $$ = p;
521          THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
522         }
523         | PAPER '{'     {
524                   Identifier *id = unsmob_identifier (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
525                   Paper_def *p = 0;
526                 if (id)
527                         p = dynamic_cast<Paper_def*> (id->access_content_Music_output_def (true));
528                 else
529                         p = new Paper_def;
530                 THIS-> lexer_p_-> scope_l_arr_.push (p->scope_p_);
531                 $$ = p;
532         }
533         | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER         {
534                 Music_output_def *p = $3->access_content_Music_output_def (true);
535                 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
536                 $$ = p;
537         }
538         | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER  {
539                 Music_output_def *p = $3->access_content_Music_output_def (true);
540                 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
541                 $$ = p;
542         }
543         | music_output_def_body assignment semicolon {
544
545         }
546         | music_output_def_body translator_spec_block   {
547                 $$-> assign_translator ($2);
548         }
549         | music_output_def_body tempo_request semicolon {
550                 /*
551                         junk this ? there already is tempo stuff in
552                         music.
553                 */
554                 dynamic_cast<Midi_def*> ($$)->set_tempo ($2->dur_.length_mom (), $2->metronome_i_);
555         }
556         | music_output_def_body bare_int '=' FONT STRING                { // ugh, what a syntax
557                 Lookup * l =unsmob_lookup (Lookup::make_lookup());
558                 l->font_name_ = ly_scm2string ($5);
559                 dynamic_cast<Paper_def*> ($$)->set_lookup ($2, l);
560         }
561         | music_output_def_body error {
562
563         }
564         ;
565
566 tempo_request:
567         TEMPO steno_duration '=' bare_unsigned  {
568                 $$ = new Tempo_req;
569                 $$->dur_ = *$2;
570                 delete $2;
571                 $$-> metronome_i_ = $4;
572         }
573         ;
574
575 Music_list: /* empty */ {
576                 $$ = gh_cons (SCM_EOL, SCM_EOL);
577         }
578         | Music_list Music {
579                 SCM s = $$;
580                 SCM c = gh_cons ($2->self_scm_, SCM_EOL);
581                 scm_unprotect_object ($2->self_scm_); /* UGH */
582
583         
584                 if (gh_pair_p (gh_cdr (s)))
585                         gh_set_cdr_x (gh_cdr (s), c); /* append */
586                 else
587                         gh_set_car_x (s, c); /* set first cons */
588                 gh_set_cdr_x (s, c) ;  /* remember last cell */ 
589         }
590         | Music_list error {
591         }
592         ;
593
594
595 Music:
596         Simple_music
597         | Composite_music
598         ;
599
600 Alternative_music:
601         /* empty */ {
602                 $$ = 0;
603         }
604         | ALTERNATIVE Music_sequence {
605                 $$ = $2;
606                 $2->set_spot (THIS->here_input ());
607         }
608         ;
609
610
611
612
613 Repeated_music:
614         REPEAT STRING bare_unsigned Music Alternative_music
615         {
616                 Music_sequence* m = dynamic_cast <Music_sequence*> ($5);
617                 if (m && $3 < m->length_i ())
618                         $5->origin ()->warning (_ ("More alternatives than repeats.  Junking excess alternatives."));
619
620                 Repeated_music * r = new Repeated_music ($4, $3 >? 1, m);
621                 $$ = r;
622                 r->type_ = ly_scm2string ($2);
623                 r->fold_b_ = (r->type_ == "fold");
624                 r->volta_fold_b_ =  (r->type_ == "volta");
625                 r->set_spot (*$4->origin ());
626         }
627         ;
628
629 Music_sequence: '{' Music_list '}'      {
630                 $$ = new Music_sequence (gh_car ($2));
631         }
632         ;
633
634 Sequential_music:
635         SEQUENTIAL '{' Music_list '}'           {
636                 $$ = new Sequential_music (gh_car ($3));
637         }
638         | '{' Music_list '}'            {
639                 $$ = new Sequential_music (gh_car ($2));
640         }
641         ;
642
643 Simultaneous_music:
644         SIMULTANEOUS '{' Music_list '}'{
645                 $$ = new Simultaneous_music (gh_car ($3));
646         }
647         | '<' Music_list '>'    {
648                 $$ = new Simultaneous_music (gh_car ($2));
649         }
650         ;
651
652 Simple_music:
653         request_chord           { $$ = $1; }
654         | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm     {
655                 SCM pred = $2;
656                 if (!gh_symbol_p ($3))
657                 {
658                         THIS->parser_error (_("Second argument must be a symbol")); 
659                 }
660                 /*hould check # args */
661                 if (!gh_procedure_p (pred))
662                 {
663                         THIS->parser_error (_("First argument must be a procedure taking 1 argument"));
664                 }
665         
666                 $$ = new Output_property (pred,$3, $5);
667         }
668         | MUSIC_IDENTIFIER { $$ = unsmob_music ($1)->clone (); }
669         | property_def
670         | translator_change
671         | Simple_music '*' bare_unsigned '/' bare_unsigned      {
672                 $$ = $1;
673                 $$->compress (Moment($3, $5 ));
674         }
675         | Simple_music '*' bare_unsigned                 {
676                 $$ = $1;
677                 $$->compress (Moment ($3, 1));
678         }
679         ;
680
681
682 Composite_music:
683         CONTEXT STRING Music    {
684                 Context_specced_music *csm =  new Context_specced_music ($3);
685
686                 csm->translator_type_str_ = ly_scm2string ($2);
687                 csm->translator_id_str_ = "";
688
689
690                 $$ = csm;
691         }
692         | AUTOCHANGE STRING Music       {
693                 Auto_change_music * chm = new Auto_change_music (ly_scm2string ($2), $3);
694
695                 $$ = chm;
696                 chm->set_spot (*$3->origin ());
697         }
698         | GRACE Music {
699                 $$ = new Grace_music ($2);
700         }
701         | CONTEXT STRING '=' STRING Music {
702                 Context_specced_music *csm =  new Context_specced_music ($5);
703
704                 csm->translator_type_str_ = ly_scm2string ($2);
705                 csm->translator_id_str_ = ly_scm2string ($4);
706
707                 $$ = csm;
708         }
709         | TIMES {
710                 THIS->remember_spot ();
711         }
712         /* CONTINUED */ 
713                 bare_unsigned '/' bare_unsigned Music   
714
715         {
716                 $$ = new Time_scaled_music ($3, $5, $6);
717                 $$->set_spot (THIS->pop_spot ());
718         }
719         | Repeated_music                { $$ = $1; }
720         | Simultaneous_music            { $$ = $1; }
721         | Sequential_music              { $$ = $1; }
722         | TRANSPOSE musical_pitch Music {
723                 $$ = new Transposed_music ($3, *$2);
724                 delete $2; // ugh
725         }
726         | TRANSPOSE steno_tonic_pitch Music {
727                 $$ = new Transposed_music ($3, *$2);
728                 delete $2; // ugh
729         }
730         | NOTES
731                 { THIS->lexer_p_->push_note_state (); }
732         Music
733                 { $$ = $3;
734                   THIS->lexer_p_->pop_state ();
735                 }
736         | CHORDS
737                 { THIS->lexer_p_->push_chord_state (); }
738         Music
739                 {
740                   $$ = $3;
741                   THIS->lexer_p_->pop_state ();
742         }
743         | LYRICS
744                 { THIS->lexer_p_->push_lyric_state (); }
745         Music
746                 {
747                   $$ = $3;
748                   THIS->lexer_p_->pop_state ();
749         }
750         | relative_music        { $$ = $1; }
751         | re_rhythmed_music     { $$ = $1; } 
752         ;
753
754 relative_music:
755         RELATIVE absolute_musical_pitch Music {
756                 $$ = new Relative_octave_music ($3, *$2);
757                 delete $2; // ugh
758         }
759         ;
760
761 re_rhythmed_music:
762         ADDLYRICS Music Music {
763                 Lyric_combine_music * l = new Lyric_combine_music ($2, $3);
764                 $$ = l;
765         }
766         ;
767
768 translator_change:
769         TRANSLATOR STRING '=' STRING  {
770                 Change_translator * t = new Change_translator;
771                 t-> change_to_type_str_ = ly_scm2string ($2);
772                 t-> change_to_id_str_ = ly_scm2string ($4);
773
774                 $$ = t;
775                 $$->set_spot (THIS->here_input ());
776         }
777         ;
778
779 property_def:
780         PROPERTY STRING '.' STRING '='  scalar {
781                 Translation_property *t = new Translation_property;
782
783                 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
784                 t->set_mus_property ("value", $6);
785
786                 Context_specced_music *csm = new Context_specced_music (t);
787                 $$ = csm;
788                 $$->set_spot (THIS->here_input ());
789
790                 csm-> translator_type_str_ = ly_scm2string ($2);
791         }
792         ;
793
794 scalar:
795         string          { $$ = $1; }
796         | bare_int      { $$ = gh_int2scm ($1); }
797         | embedded_scm  { $$ = $1; }
798         ;
799
800
801 request_chord:
802         pre_requests simple_element post_requests       {
803                 Music_sequence *l = dynamic_cast<Music_sequence*>($2);
804                 if (l) {
805                         for (int i=0; i < $1->size(); i++)
806                                 l->append_music ($1->elem(i));
807                         for (int i=0; i < $3->size(); i++)
808                                 l->append_music ($3->elem(i));
809                         }
810                 else
811                         programming_error ("Need Sequence to add music to");
812                 $$ = $2;
813                 
814         }
815         | command_element
816         ;
817
818 command_element:
819         command_req {
820                 $$ = new Request_chord (gh_cons ($1->self_scm_, SCM_EOL));
821                 $$-> set_spot (THIS->here_input ());
822                 $1-> set_spot (THIS->here_input ());
823         }
824         | PARTIAL duration_length ';'   {
825                 Translation_property * p = new Translation_property;
826                 p->set_mus_property ("symbol", ly_symbol2scm ( "measurePosition"));
827                 p->set_mus_property ("value", (new Moment (-$2->length_mom ()))->smobify_self ());
828                 delete $2; // ugh
829                 Context_specced_music * sp = new Context_specced_music (p);
830                 $$ =sp ;
831                 sp-> translator_type_str_ = "Score";
832         }
833         ;
834
835 command_req:
836         shorthand_command_req
837         | verbose_command_req semicolon { $$ = $1; }
838         ;
839
840 shorthand_command_req:
841         extender_req {
842                 $$ = $1;
843         }
844         | hyphen_req {
845                 $$ = $1;
846         }
847         | '|'                           {
848                 $$ = new Barcheck_req;
849         }
850         | '~'   {
851                 $$ = new Tie_req;
852         }
853         | '['           {
854                 Span_req*b= new Span_req;
855                 b->span_dir_ = START;
856                 b->span_type_str_ = "beam";
857                 $$ =b;
858         }
859         | ']'           {
860              Span_req*b= new Span_req;
861              b->span_dir_ = STOP;
862              b->span_type_str_ = "beam";
863              $$ = b;
864         }
865         | BREATHE {
866                 $$ = new Breathing_sign_req;
867         }
868         ;
869
870
871 verbose_command_req:
872         
873         BAR STRING                      {
874                 $$ = new Bar_req (ly_scm2string ($2));
875         }
876         | COMMANDSPANREQUEST bare_int STRING {
877                 Span_req * sp_p = new Span_req;
878                 sp_p-> span_dir_  = Direction($2);
879                 sp_p->span_type_str_ = ly_scm2string ($3);
880                 sp_p->set_spot (THIS->here_input ());
881                 $$ = sp_p;
882         }
883         | MARK  {
884                 Mark_req * m = new Mark_req;
885                 $$ = m;
886         }
887         | MARK STRING {
888                 Mark_req *m = new Mark_req;
889                 m->set_mus_property ("label", $2);
890                 $$ = m;
891
892         }
893         | MARK bare_unsigned {
894                 Mark_req *m = new Mark_req;
895                 m->set_mus_property ("label",  gh_int2scm ($2));
896                 $$ = m;
897         }
898
899         | TIME_T bare_unsigned '/' bare_unsigned        {
900                 Time_signature_change_req *m = new Time_signature_change_req;
901                 m->beats_i_ = $2;
902                 m->one_beat_i_=$4;
903                 $$ = m;
904         }
905         | PENALTY bare_int      {
906                 Break_req * b = new Break_req;
907                 b->penalty_f_ = $2 / 100.0;
908                 b->set_spot (THIS->here_input ());
909                 $$ = b;
910         }
911         | SKIP duration_length {
912                 Skip_req * skip_p = new Skip_req;
913                 skip_p->duration_ = *$2;
914                 delete $2; // ugh
915                 $$ = skip_p;
916         }
917         | tempo_request {
918                 $$ = $1;
919         }
920         | CLEF STRING {
921                 $$ = new Clef_change_req (ly_scm2string ($2));
922
923         }
924         | KEY {
925                 Key_change_req *key_p= new Key_change_req;
926                 $$ = key_p;
927         }
928         | KEY NOTENAME_PITCH SCM_IDENTIFIER     {
929                 Key_change_req *key_p= new Key_change_req;
930                 
931                 key_p->set_mus_property ("pitch-alist", $3);
932                 ((Music* )key_p)->transpose (* $2);
933                 $$ = key_p; 
934         }
935         ;
936
937 post_requests:
938         {
939                 $$ = new Link_array<Request>;
940         }
941         | post_requests post_request {
942                 $2->set_spot (THIS->here_input ());
943                 $$->push ($2);
944         }
945         ;
946
947 post_request:
948         verbose_request
949         | request_with_dir
950         | close_request
951         ;
952
953
954 request_that_take_dir:
955         gen_text_def
956         | verbose_request
957         | script_abbreviation {
958                 SCM s = THIS->lexer_p_->lookup_identifier ("dash-" + ly_scm2string ($1));
959                 Articulation_req *a = new Articulation_req;
960                 if (gh_string_p (s))
961                         a->articulation_str_ = ly_scm2string (s);
962                 else THIS->parser_error (_ ("Expecting string as script definition"));
963                 $$ = a;
964         }
965         ;
966
967 request_with_dir:
968         script_dir request_that_take_dir        {
969                 if (Script_req * gs = dynamic_cast<Script_req*> ($2))
970                         gs->dir_ = Direction ($1);
971                 else if ($1)
972                         $2->origin ()->warning (_ ("Can't specify direction for this request"));
973                 $$ = $2;
974         }
975         ;
976         
977 verbose_request:
978         REQUEST_IDENTIFIER      {
979                 $$ = dynamic_cast<Request*> (unsmob_music ($1)->clone ());
980                 $$->set_spot (THIS->here_input ());
981         }
982         | TEXTSCRIPT STRING STRING      {
983                 Text_script_req *ts_p = new Text_script_req;
984                 ts_p-> text_str_ = ly_scm2string ($2);
985                 ts_p-> style_str_ = ly_scm2string ($3);
986                 ts_p->set_spot (THIS->here_input ());
987
988                 $$ = ts_p;
989         }
990         | SPANREQUEST bare_int STRING {
991                 Span_req * sp_p = new Span_req;
992                 sp_p->span_dir_  = Direction($2);
993                 sp_p->span_type_str_ = ly_scm2string ($3);
994                 sp_p->set_spot (THIS->here_input ());
995                 $$ = sp_p;
996         }
997         | tremolo_type  {
998                 Tremolo_req* a = new Tremolo_req;
999                 a->set_spot (THIS->here_input ());
1000                 a->type_i_ = $1;
1001                 $$ = a;
1002         }
1003         | SCRIPT STRING         { 
1004                 Articulation_req * a = new Articulation_req;
1005                 a->articulation_str_ = ly_scm2string ($2);
1006                 a->set_spot (THIS->here_input ());
1007                 $$ = a;
1008         }
1009         ;
1010
1011 sup_quotes:
1012         '\'' {
1013                 $$ = 1;
1014         }
1015         | sup_quotes '\'' {
1016                 $$ ++;
1017         }
1018         ;
1019
1020 sub_quotes:
1021         ',' {
1022                 $$ = 1;
1023         }
1024         | sub_quotes ',' {
1025                 $$ ++ ;
1026         }
1027         ;
1028
1029 steno_musical_pitch:
1030         NOTENAME_PITCH  {
1031                 $$ = $1;
1032         }
1033         | NOTENAME_PITCH sup_quotes     {
1034                 $$ = $1;
1035                 $$->octave_i_ +=  $2;
1036         }
1037         | NOTENAME_PITCH sub_quotes      {
1038                 $$ = $1;
1039                 $$->octave_i_ += - $2;
1040         }
1041         ;
1042
1043 steno_tonic_pitch:
1044         TONICNAME_PITCH {
1045                 $$ = $1;
1046         }
1047         | TONICNAME_PITCH sup_quotes    {
1048                 $$ = $1;
1049                 $$->octave_i_ +=  $2;
1050         }
1051         | TONICNAME_PITCH sub_quotes     {
1052                 $$ = $1;
1053                 $$->octave_i_ += - $2;
1054         }
1055         ;
1056
1057 musical_pitch:
1058         steno_musical_pitch {
1059                 $$ = $1;
1060         }
1061         | MUSICAL_PITCH embedded_scm {
1062                 int sz = scm_ilength ($2);
1063                 if (sz != 3) {
1064                         THIS->parser_error (_f ("Expecting %d arguments", 3));
1065                         $2 = gh_list (gh_int2scm (0), gh_int2scm (0), gh_int2scm (0), SCM_UNDEFINED);
1066                 }
1067                 $$ = new Musical_pitch ($2);
1068         }
1069         ;
1070
1071 explicit_duration:
1072         DURATION embedded_scm   {
1073                 $$ = new Duration;
1074                 if (scm_ilength ($2) == 2)
1075                         {
1076                         $$-> durlog_i_ = gh_scm2int (gh_car($2));
1077                         $$-> dots_i_ = gh_scm2int (gh_cadr($2));
1078                         }
1079                 else
1080                         THIS->parser_error (_("Must have 2 arguments for duration"));
1081         }
1082         ;
1083
1084 extender_req:
1085         EXTENDER {
1086                 if (!THIS->lexer_p_->lyric_state_b ())
1087                         THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1088                 $$ = new Extender_req;
1089         }
1090         ;
1091
1092 hyphen_req:
1093         HYPHEN {
1094                 if (!THIS->lexer_p_->lyric_state_b ())
1095                         THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1096                 $$ = new Hyphen_req;
1097         }
1098         ;
1099
1100 close_request:
1101         close_request_parens {
1102                 $$ = $1;
1103                 dynamic_cast<Span_req*> ($$)->span_dir_ = START;
1104         }
1105         
1106 close_request_parens:
1107         '('     {
1108                 Span_req* s= new Span_req;
1109                 $$ = s;
1110                 s->span_type_str_ = "slur";
1111         }
1112         | E_SMALLER {
1113                 Span_req*s =new Span_req;
1114                 $$ = s;
1115                 s->span_type_str_ = "crescendo";
1116         }
1117         | E_BIGGER {
1118                 Span_req*s =new Span_req;
1119                 $$ = s;
1120                 s->span_type_str_ = "decrescendo";
1121         }
1122         ;
1123
1124
1125 open_request:
1126         open_request_parens {
1127                 $$ = $1;
1128                 dynamic_cast<Span_req*> ($$)->span_dir_ = STOP;
1129         }
1130         ;
1131
1132 open_request_parens:
1133         E_EXCLAMATION   {
1134                 Span_req *s =  new Span_req;
1135                 s->span_type_str_ = "crescendo";
1136                 $$ = s;
1137         }
1138         | ')'   {
1139                 Span_req* s= new Span_req;
1140                 $$ = s;
1141                 s->span_type_str_ = "slur";
1142         }
1143         ;
1144
1145 gen_text_def:
1146         string {
1147                 Text_script_req *t  = new Text_script_req;
1148                 $$ = t;
1149                 t->text_str_ = ly_scm2string ($1);
1150
1151                 $$->set_spot (THIS->here_input ());
1152         }
1153         | DIGIT {
1154                 Text_script_req* t  = new Text_script_req;
1155                 $$ = t;
1156                 t->text_str_ = to_str ($1);
1157                 t->style_str_ = "finger";
1158                 $$->set_spot (THIS->here_input ());
1159         }
1160         ;
1161
1162 script_abbreviation:
1163         '^'             {
1164                 $$ = gh_str02scm  ("hat");
1165         }
1166         | '+'           {
1167                 $$ = gh_str02scm("plus");
1168         }
1169         | '-'           {
1170                 $$ = gh_str02scm ("dash");
1171         }
1172         | '|'           {
1173                 $$ = gh_str02scm ("bar");
1174         }
1175         | '>'           {
1176                 $$ = gh_str02scm ("larger");
1177         }
1178         | '.'           {
1179                 $$ = gh_str02scm ("dot");
1180         }
1181         ;
1182
1183
1184 script_dir:
1185         '_'     { $$ = DOWN; }
1186         | '^'   { $$ = UP; }
1187         | '-'   { $$ = CENTER; }
1188         ;
1189
1190 pre_requests:
1191         {
1192                 $$ = new Link_array<Request>;
1193         }
1194         | pre_requests open_request {
1195                 $$->push ($2);
1196         }
1197         ;
1198
1199 absolute_musical_pitch:
1200         steno_musical_pitch     {
1201                 $$ = $1;
1202         }
1203         ;
1204
1205 duration_length:
1206         steno_duration {
1207                 $$ = $1;
1208         }
1209         | duration_length '*' bare_unsigned {
1210                 $$->tuplet_iso_i_ *= $3;
1211         }
1212         | duration_length '/' bare_unsigned {
1213                 $$->tuplet_type_i_ *= $3;
1214         }
1215         ;
1216
1217 entered_notemode_duration:
1218         steno_duration  {
1219                 THIS->set_last_duration ($1);
1220         }
1221         ;
1222
1223 optional_notemode_duration:
1224         {
1225                 $$ = new Duration (THIS->default_duration_);
1226         }
1227         | entered_notemode_duration {
1228                 $$ = $1;
1229         }
1230         ;
1231
1232 steno_duration:
1233         bare_unsigned           {
1234                 $$ = new Duration;
1235                 if (!is_duration_b ($1))
1236                         THIS->parser_error (_f ("not a duration: %d", $1));
1237                 else {
1238                         $$->durlog_i_ = intlog2 ($1);
1239                      }
1240         }
1241         | DURATION_IDENTIFIER   {
1242                 $$ = $1->access_content_Duration (true);
1243         }
1244         | steno_duration '.'    {
1245                 $$->dots_i_ ++;
1246         }
1247         ;
1248
1249
1250 tremolo_type: 
1251         ':'     {
1252                 $$ =0;
1253         }
1254         | ':' bare_unsigned {
1255                 if (!is_duration_b ($2))
1256                         THIS->parser_error (_f ("not a duration: %d", $2));
1257                 $$ = $2;
1258         }
1259         ;
1260
1261
1262 simple_element:
1263         musical_pitch exclamations questions optional_notemode_duration {
1264                 if (!THIS->lexer_p_->note_state_b ())
1265                         THIS->parser_error (_ ("Have to be in Note mode for notes"));
1266
1267
1268                 Note_req *n = new Note_req;
1269                 
1270                 n->pitch_ = *$1;
1271                 n->duration_ = *$4;
1272
1273                 n->cautionary_b_ = $3 % 2;
1274                 n->forceacc_b_ = $2 % 2 || n->cautionary_b_;
1275
1276
1277                 Simultaneous_music*v = new Request_chord (gh_list (n->self_scm_, SCM_UNDEFINED));
1278                 v->set_spot ($1->spot ());
1279                 n->set_spot ($1->spot ());
1280                 $$ = v;
1281
1282                 delete $1;
1283                 delete $4;
1284         }
1285         | RESTNAME optional_notemode_duration           {
1286
1287                 SCM e = SCM_UNDEFINED;
1288                   if (ly_scm2string ($1) =="s")
1289                     { /* Space */
1290                       Skip_req * skip_p = new Skip_req;
1291                       skip_p->duration_ = *$2;
1292
1293                       skip_p->set_spot (THIS->here_input());
1294                         e = skip_p->self_scm_;
1295                     }
1296                   else
1297                     {
1298                       Rest_req * rest_req_p = new Rest_req;
1299                       rest_req_p->duration_ = *$2;
1300                       rest_req_p->set_spot (THIS->here_input());
1301                         e = rest_req_p->self_scm_;
1302                     }
1303                   Simultaneous_music* velt_p = new Request_chord (gh_list (e,SCM_UNDEFINED));
1304                   velt_p->set_spot (THIS->here_input());
1305
1306                   delete $2; // ugh
1307                   $$ = velt_p;
1308         }
1309         | MEASURES optional_notemode_duration   {
1310                 Skip_req * sk = new Skip_req;
1311                 sk->duration_ = *$2;
1312                 
1313
1314                 Span_req *sp1 = new Span_req;
1315                 Span_req *sp2 = new Span_req;
1316                 sp1-> span_dir_ = START;
1317                 sp2-> span_dir_ = STOP;
1318                 sp1->span_type_str_ = sp2->span_type_str_ = "rest";
1319
1320                 Request_chord * rqc1 = new Request_chord (gh_list (sp1->self_scm_, SCM_UNDEFINED));
1321                 Request_chord * rqc2 = new Request_chord (gh_list (sk->self_scm_, SCM_UNDEFINED));;
1322                 Request_chord * rqc3 = new Request_chord(gh_list (sp2->self_scm_, SCM_UNDEFINED));;
1323
1324                 SCM ms = gh_list (rqc1->self_scm_, rqc2->self_scm_, rqc3->self_scm_, SCM_UNDEFINED);
1325
1326                 $$ = new Sequential_music (ms);
1327         }
1328         | STRING optional_notemode_duration     {
1329                 if (!THIS->lexer_p_->lyric_state_b ())
1330                         THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1331                 Lyric_req* lreq_p = new Lyric_req;
1332                 lreq_p ->text_str_ = ly_scm2string ($1);
1333                 lreq_p->duration_ = *$2;
1334                 lreq_p->set_spot (THIS->here_input());
1335                 Simultaneous_music* velt_p = new Request_chord (gh_list (lreq_p->self_scm_, SCM_UNDEFINED));
1336
1337                 delete  $2; // ugh
1338                 $$= velt_p;
1339
1340         }
1341         | chord {
1342                 if (!THIS->lexer_p_->chord_state_b ())
1343                         THIS->parser_error (_ ("Have to be in Chord mode for chords"));
1344                 $$ = $1;
1345         }
1346         ;
1347
1348
1349 chord:
1350         steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
1351                 $$ = THIS->get_chord (*$1, $3, $4, $5, $6, *$2);
1352         };
1353
1354 chord_additions: 
1355         {
1356                 $$ = new Array<Musical_pitch>;
1357         } 
1358         | CHORD_COLON chord_notes {
1359                 $$ = $2;
1360         }
1361         ;
1362
1363 chord_notes:
1364         chord_step {
1365                 $$ = $1
1366         }
1367         | chord_notes '.' chord_step {
1368                 $$ = $1;
1369                 $$->concat (*$3);
1370         }
1371         ;
1372
1373 chord_subtractions: 
1374         {
1375                 $$ = new Array<Musical_pitch>;
1376         } 
1377         | CHORD_CARET chord_notes {
1378                 $$ = $2;
1379         }
1380         ;
1381
1382
1383 chord_inversion:
1384         {
1385                 $$ = 0;
1386         }
1387         | '/' steno_tonic_pitch {
1388                 $$ = $2;
1389                 $$->set_spot (THIS->here_input ());
1390         }
1391         ;
1392
1393 chord_bass:
1394         {
1395                 $$ = 0;
1396         }
1397         | CHORD_BASS steno_tonic_pitch {
1398                 $$ = $2;
1399                 $$->set_spot (THIS->here_input ());
1400         }
1401         ;
1402
1403 chord_step:
1404         chord_note {
1405                 $$ = new Array<Musical_pitch>;
1406                 $$->push (*$1);
1407         }
1408         | CHORDMODIFIER_PITCH {
1409                 $$ = new Array<Musical_pitch>;
1410                 $$->push (*$1);
1411         }
1412         | CHORDMODIFIER_PITCH chord_note { /* Ugh. */
1413                 $$ = new Array<Musical_pitch>;
1414                 $$->push (*$1);
1415                 $$->push (*$2);
1416         }
1417         ;
1418
1419 chord_note:
1420         bare_unsigned {
1421                 $$ = new Musical_pitch;
1422                 $$->notename_i_ = ($1 - 1) % 7;
1423                 $$->octave_i_ = $1 > 7 ? 1 : 0;
1424                 $$->accidental_i_ = 0;
1425         } 
1426         | bare_unsigned '+' {
1427                 $$ = new Musical_pitch;
1428                 $$->notename_i_ = ($1 - 1) % 7;
1429                 $$->octave_i_ = $1 > 7 ? 1 : 0;
1430                 $$->accidental_i_ = 1;
1431         }
1432         | bare_unsigned CHORD_MINUS {
1433                 $$ = new Musical_pitch;
1434                 $$->notename_i_ = ($1 - 1) % 7;
1435                 $$->octave_i_ = $1 > 7 ? 1 : 0;
1436                 $$->accidental_i_ = -1;
1437         }
1438         ;
1439
1440 /*
1441         UTILITIES
1442  */
1443 number_expression:
1444         bare_number {
1445                 $$ = $1;
1446         }
1447         | '-'  number_expression %prec UNARY_MINUS {
1448                 $$ = scm_difference ($2, SCM_UNDEFINED);
1449         }
1450         | number_expression '*' number_expression {
1451                 $$ = scm_product ($1, $3);
1452         }
1453         | number_expression '/' number_expression {
1454                 $$ = scm_divide ($1, $3);
1455         }
1456         | number_expression '+' number_expression {
1457                 $$ = scm_sum ($1, $3);
1458         }
1459         | number_expression '-' number_expression {
1460                 $$ = scm_difference ($1, $3);
1461         }
1462         | '(' number_expression ')'     {
1463                 $$ = $2;
1464         }
1465         ;
1466
1467 bare_number:
1468         UNSIGNED        {
1469                 $$ = gh_int2scm ($1);
1470         }
1471         | DIGIT         {
1472                 $$ = gh_int2scm ($1);
1473         }
1474         | REAL          {
1475                 $$ = gh_double2scm ($1);
1476         }
1477         | NUMBER_IDENTIFIER             {
1478                 $$ = $1;
1479         }
1480         | REAL CM_T     {
1481                 $$ = gh_double2scm ($1 CM);
1482         }
1483         | REAL PT_T     {
1484                 $$ = gh_double2scm ($1 PT);
1485         }
1486         | REAL IN_T     {
1487                 $$ = gh_double2scm ($1 INCH);
1488         }
1489         | REAL MM_T     {
1490                 $$ = gh_double2scm ($1 MM);
1491         }
1492         | REAL CHAR_T   {
1493                 $$ = gh_double2scm ($1 CHAR);
1494         }
1495         ;
1496
1497
1498 bare_unsigned:
1499         bare_number {
1500                 if (scm_integer_p ($1) == SCM_BOOL_T) {
1501                         $$ = gh_scm2int ($1);
1502
1503                 } else {
1504                         THIS->parser_error (_("need integer number arg"));
1505                         $$ = 0;
1506                 }
1507                 if ($$ < 0) {
1508                         THIS->parser_error (_("Must be positive integer"));
1509                         $$ = -$$;
1510                         }
1511
1512         }
1513         ;
1514 bare_int:
1515         bare_number {
1516                 if (scm_integer_p ($1) == SCM_BOOL_T)
1517                 {
1518                         int k = gh_scm2int ($1);
1519                         $$ = k;
1520                 } else
1521                 {
1522                         THIS->parser_error (_("need integer number arg"));
1523                         $$ = 0;
1524                 }
1525         }
1526         | '-' bare_int {
1527                 $$ = -$2;
1528         }
1529         ;
1530
1531
1532 string:
1533         STRING          {
1534                 $$ = $1;
1535         }
1536         | STRING_IDENTIFIER     {
1537                 $$ = $1;
1538         }
1539         | string '+' string {
1540                 $$ = scm_string_append (scm_listify ($1, $3, SCM_UNDEFINED));
1541         }
1542         ;
1543
1544
1545 exclamations:
1546                 { $$ = 0; }
1547         | exclamations '!'      { $$ ++; }
1548         ;
1549
1550 questions:
1551                 { $$ = 0; }
1552         | questions '?' { $$ ++; }
1553         ;
1554
1555
1556 semicolon:
1557         ';'
1558         ;
1559
1560 %%
1561
1562 void
1563 My_lily_parser::set_yydebug (bool b)
1564 {
1565 #ifdef YYDEBUG
1566         yydebug = b;
1567 #endif
1568 }
1569 void
1570 My_lily_parser::do_yyparse ()
1571 {
1572         yyparse ((void*)this);
1573 }
1574
1575