]> git.donarmstrong.com Git - lilypond.git/blob - lily/parser.y
2480a041e6f0f0ecd026e4dd2b4f7a12fb0f2bb1
[lilypond.git] / lily / parser.y
1 %{ // -*-Fundamental-*-
2
3 /*
4   parser.y -- YACC parser for mudela
5
6   source file of the GNU LilyPond music typesetter
7
8   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
9            Jan Nieuwenhuizen <jan@digicash.com>
10 */
11
12 #include <iostream.h>
13
14 // mmm
15 #define MUDELA_VERSION "0.1.8"
16
17 #include "scalar.hh"
18 #include "translation-property.hh"
19 #include "script-def.hh"
20 #include "symtable.hh"
21 #include "lookup.hh"
22 #include "misc.hh"
23 #include "my-lily-lexer.hh"
24 #include "paper-def.hh"
25 #include "midi-def.hh"
26 #include "main.hh"
27 #include "keyword.hh"
28 #include "debug.hh"
29 #include "parseconstruct.hh"
30 #include "dimen.hh"
31 #include "identifier.hh"
32 #include "command-request.hh"
33 #include "musical-request.hh"
34 #include "my-lily-parser.hh"
35 #include "text-def.hh"
36 #include "translator-group.hh"
37 #include "score.hh"
38 #include "music-list.hh"
39 #include "header.hh"
40 #include "duration-convert.hh"
41 #include "change-translator.hh"
42
43 #ifndef NDEBUG
44 #define YYDEBUG 1
45 #endif
46
47 #define YYERROR_VERBOSE 1
48
49 #define YYPARSE_PARAM my_lily_parser_l
50 #define YYLEX_PARAM my_lily_parser_l
51 #define THIS ((My_lily_parser *) my_lily_parser_l)
52
53 #define yyerror THIS->parser_error
54
55 %}
56
57
58 %union {
59     Array<Interval>* intarr;
60     Array<Melodic_req*> *melreqvec;/* should clean up naming */
61     Array<String> * strvec;
62     Array<int> *intvec;
63     Box *box;
64     Chord * chord;
65     Duration *duration;
66     Identifier *id;
67     Translator* trans;
68     Music *music;
69     Music_list *musiclist;
70     Score *score;
71     Header *header;
72     Interval *interval;
73     Lookup*lookup;
74     Melodic_req * melreq;
75     Musical_req* musreq;
76     Music_output_def * outputdef;
77     Midi_def* midi;
78     Moment *moment;
79     Note_req *notereq;
80     Paper_def *paper;
81     Real real;
82     Request * request;
83     General_script_def * script;
84     Scalar *scalar;
85     String *string;
86     Atom * symbol;
87     Symtable * symtable;
88     Symtables * symtables;
89     Text_def * textdef;
90     Tempo_req *tempo;
91     char c;
92     const char *consstr;
93     int i;
94     int ii[10];
95 }
96 %{
97
98 int
99 yylex (YYSTYPE *s,  void * v_l)
100 {
101         My_lily_parser   *pars_l = (My_lily_parser*) v_l;
102         My_lily_lexer * lex_l = pars_l->lexer_p_;
103
104         lex_l->lexval_l = (void*) s;
105         return lex_l->yylex ();
106 }
107
108
109 %}
110
111 %pure_parser
112
113 /* tokens which are not keywords */
114
115 %token ALIAS
116 %token BAR
117 %token BEAMPLET
118 %token MAEBTELP
119 %token CADENZA
120 %token CLEAR
121 %token CLEF
122 %token CONTAINS
123 %token CONSISTS
124 %token ACCEPTS
125 %token CM_T
126 %token DURATION
127 %token ABSDYNAMIC
128 %token END
129 %token GROUPING
130 %token TRANSLATOR
131 %token HEADER
132 %token IN_T
133 %token LYRIC
134 %token KEY
135 %token MELODIC
136 %token MIDI
137 %token MELODIC_REQUEST
138 %token METER
139 %token MM_T
140 %token MULTI
141 %token NOTENAMES
142 %token OCTAVE
143 %token OUTPUT
144 %token PAPER
145 %token PARTIAL
146 %token PLET
147 %token TELP
148 %token PT_T
149 %token SCORE
150 %token SCRIPT
151 %token SHAPE
152 %token SKIP
153 %token SPANDYNAMIC
154 %token STAFF
155 %token START_T
156 %token SYMBOLTABLES
157 %token TABLE
158 %token TRANSPOSE
159 %token TEMPO
160 %token TYPE
161 %token TEXID
162 %token TEXTSTYLE
163 %token TITLE
164 %token PROPERTY
165 %token VERSION
166
167 /* escaped */
168 %token E_EXCLAMATION E_SMALLER E_BIGGER E_CHAR
169
170 %type <i>       dots
171 %token <i>      INT
172 %token <melreq> NOTENAME_ID
173 %token <id>     DURATION_IDENTIFIER
174 %token <id>     IDENTIFIER
175 %token <id>     MELODIC_REQUEST_IDENTIFIER
176 %token <id>     MUSIC_IDENTIFIER
177 %token <id>     VOICE_IDENTIFIER
178 %token <id>     POST_REQUEST_IDENTIFIER
179 %token <id>     SCRIPT_IDENTIFIER
180 %token <id>     COMMAND_IDENTIFIER
181 %token <id>     REAL_IDENTIFIER
182 %token <id>     TRANS_IDENTIFIER
183 %token <id>     INT_IDENTIFIER
184 %token <id>     SCORE_IDENTIFIER
185 %token <id>     MIDI_IDENTIFIER
186 %token <id>     PAPER_IDENTIFIER
187 %token <id>     REQUEST_IDENTIFIER
188 %token <real>   REAL
189 %token <string> DURATION RESTNAME
190 %token <string> STRING
191 %token <i>      POST_QUOTES
192 %token <i>      PRE_QUOTES
193
194 %type <outputdef> output_def
195 %type <header>  mudela_header mudela_header_body
196 %type <box>     box
197 %type <i>       open_request_parens close_request_parens
198 %type <c>       open_abbrev_parens
199 %type <i>       open_plet_parens close_plet_parens
200 %type <music>   simple_element music_elt full_element lyrics_elt command_elt
201 %type <i>       abbrev_type
202 %type <i>       int
203 %type <i>       script_dir
204 %type <id>      identifier_init
205 %type <duration> explicit_steno_duration notemode_duration
206 %type <duration> entered_notemode_duration explicit_duration
207 %type <interval>        dinterval
208 %type <intvec>  intastint_list
209 %type <lookup>  symtables symtables_body
210 %type <melreq>  melodic_request steno_melodic_req
211 %type <notereq> steno_note_req
212 %type <melreqvec>       pitch_list
213 %type <midi>    midi_block midi_body
214 %type <moment>  duration_length
215
216 %type <scalar>  scalar
217 %type <music>   Music transposed_music
218 %type <music>   property_def translator_change
219 %type <musiclist> Voice Voice_body
220 %type <chord>   Chord Chord_body
221 %type <paper>   paper_block paper_body
222 %type <real>    dim real
223 %type <real>    unit
224 %type <request> abbrev_command_req
225 %type <request> post_request command_req verbose_command_req
226 %type <request> script_req  dynamic_req
227 %type <score>   score_block score_body
228 %type <intarr>  shape_array
229 %type <script>  script_definition script_body mudela_script gen_script_def
230 %type <textdef> text_def
231 %type <string>  script_abbreviation
232 %type <symbol>  symboldef
233 %type <symtable>        symtable symtable_body
234 %type <trans>   translator_spec translator_spec_body
235 %type <tempo>   tempo_request
236 %type <string>  concat_strings
237
238 %expect 1
239
240
241 %%
242
243 mudela: /* empty */
244         | mudela mudela_header {
245                 delete THIS->default_header_p_ ;
246                 THIS->default_header_p_ = $2;
247         }
248         | mudela score_block {
249                 add_score ($2);
250         }
251         | mudela add_declaration { }
252         | mudela error
253         | mudela check_version { }
254         | mudela add_notenames { }
255         ;
256
257 check_version:
258         VERSION STRING ';'              {
259                 if (String (*$2) != MUDELA_VERSION) {
260                         if (THIS->ignore_version_b_) {
261                                 THIS->here_input ().error ("Incorrect mudela version");
262                         } else {
263                                 THIS->fatal_error_i_ = 1;
264                                 THIS->parser_error ("Incorrect mudela version");
265                         }
266                 }
267         }
268         ;
269
270 add_notenames:
271         NOTENAMES '{' notenames_body '}'
272         ;
273 notenames_body:
274         /**/    {
275         }
276         | notenames_body CLEAR  {
277                 THIS->clear_notenames ();
278         }
279         | notenames_body STRING '=' melodic_request {
280                 THIS->add_notename (*$2, $4);
281                 delete $2;
282         }
283         ;
284
285 mudela_header_body:
286                 {
287                 $$ = new Header;
288         }
289         | mudela_header_body STRING '=' concat_strings ';' {
290                 (*$$)[*$2] = *$4;
291                 delete $2;
292                 delete $4;
293         }
294         ;
295
296 mudela_header:
297         HEADER '{' mudela_header_body '}'       {
298                 $$ = $3;
299         }
300         ;
301
302
303 concat_strings:
304                 {
305                 $$ = new String;
306         }
307         | concat_strings STRING {
308                 *$$ += *$2;
309         }
310
311
312 /*
313         DECLARATIONS
314 */
315
316 add_declaration:
317         STRING {
318                 THIS->remember_spot ();
319         }
320         /* cont */ '=' identifier_init {
321             THIS->lexer_p_->set_identifier (*$1, $4);
322             $4->init_b_ = THIS->init_parse_b_;
323             $4->set_spot (THIS->pop_spot ());
324         }
325         ;
326 identifier_init:
327         score_block {
328                 $$ = new Score_id ($1, SCORE_IDENTIFIER);
329
330         }
331         | paper_block {
332                 $$ = new Paper_def_id ($1, PAPER_IDENTIFIER);
333
334         }
335         | midi_block {
336                 $$ = new Midi_def_id ($1, MIDI_IDENTIFIER);
337
338         }
339         | script_definition {
340                 $$ = new Script_id ($1, SCRIPT_IDENTIFIER);
341
342         }
343         | Music  {
344                 $$ = new Music_id ($1, MUSIC_IDENTIFIER);
345
346         }
347         | symtables {
348                 $$ = new Lookup_id ($1, IDENTIFIER);
349
350         }
351         | real  {
352                 $$ = new Real_id (new Real ($1), REAL_IDENTIFIER);
353
354         }
355         | int   {
356                 $$ = new Int_id (new int ($1), INT_IDENTIFIER);
357
358         }
359         | post_request {
360                 $$ = new Request_id ($1, POST_REQUEST_IDENTIFIER);
361
362         }
363         | melodic_request {
364                 $$ = new Request_id ($1, MELODIC_REQUEST_IDENTIFIER);
365
366         }
367         | translator_spec {
368                 $$ = new Translator_id ($1, TRANS_IDENTIFIER);
369         }
370         | explicit_duration {
371                 $$ = new Duration_id ($1, DURATION_IDENTIFIER);
372         }
373         ;
374
375
376
377 translator_spec:
378         TRANSLATOR '{' translator_spec_body '}'
379                 { $$ = $3; }
380         ;
381
382 translator_spec_body:
383         TRANS_IDENTIFIER        {
384                 $$ = $1->translator ();
385                 $$-> set_spot (THIS->here_input ());
386         }
387         | TYPE STRING ';'       {
388                 $$ = get_translator_l (*$2)->clone ();
389                 $$->set_spot (THIS->here_input ());
390                 delete $2;
391         }
392         | translator_spec_body STRING '=' scalar ';'    {
393                 $$-> set_property (*$2, *$4);
394                 delete $2;
395                 delete $4;
396         }
397         | translator_spec_body CONSISTS STRING ';'      {
398                 $$->group_l ()->consists_str_arr_.push (*$3);
399                 delete $3;
400         }
401         | translator_spec_body ACCEPTS STRING ';' {
402                 $$->group_l ()->accepts_str_arr_.push (*$3);
403                 delete $3;
404         }
405         ;
406
407 /*
408         SCORE
409 */
410 score_block:
411         SCORE { THIS->remember_spot ();
412                 THIS->error_level_i_ =0;
413         }
414         /*cont*/ '{' score_body '}'     {
415                 $$ = $4;
416                 $$->set_spot (THIS->pop_spot ());
417                 if (!$$->def_p_arr_.size ())
418                         $$->add (THIS->default_paper ());
419
420                 /* handle error levels. */
421                 $$->errorlevel_i_ = THIS->error_level_i_;
422                 THIS->error_level_i_ = 0;
423                 if (!$$->header_p_ && THIS->default_header_p_)
424                         $$->header_p_ = new Header (*THIS->default_header_p_);
425         }
426         ;
427
428 score_body:             {
429                 $$ = new Score;
430         }
431         | SCORE_IDENTIFIER {
432                 $$ = $1->score ();
433         }
434         | score_body mudela_header      {
435                 $$->header_p_ = $2;
436         }
437         | score_body Music      {
438                 if ($$->music_p_)
439                         $2->warning ("More than one music block");      
440                 $$->music_p_ = $2;
441         }
442         | score_body output_def {
443                 $$->add ($2);
444         }
445         | score_body error {
446
447         }
448         ;
449
450 output_def:
451         paper_block {
452                 $$ = $1;
453         }
454         |  midi_block           {
455                 $$= $1;
456         }
457         ;
458
459 intastint_list:
460         /* */   { $$ =new Array<int>; }
461         | intastint_list int '*' int    {
462                 $$->push ($2); $$->push ($4);
463         }
464         ;
465
466
467 /*
468         PAPER
469 */
470 paper_block:
471         PAPER
472         '{' paper_body '}'      { $$ = $3; }
473         ;
474
475 paper_body:
476         /* empty */                     {
477                 $$ = THIS->default_paper ();
478         }
479         | PAPER_IDENTIFIER      {
480                 $$ = $1->paperdef ();
481         }
482         | paper_body OUTPUT STRING ';'  { 
483                 $$->outfile_str_ = *$3;
484                 delete $3;
485         }
486         | paper_body symtables          { $$->set ($2); }
487         | paper_body STRING '=' dim ';'         {
488                 $$->set_var (*$2, $4);
489         }
490         | paper_body STRING '=' real ';' {
491                 $$->set_var (*$2, $4);
492         }
493         | paper_body STRING '=' translator_spec {
494                 $$-> assign_translator (*$2, $4);
495                 delete $2;
496         }
497         | paper_body SHAPE '=' shape_array ';' {
498                 $$->shape_int_a_ = *$4;
499                 delete $4;
500         }
501         | paper_body error {
502
503         }
504         ;
505
506 shape_array:
507         /* empty */ {
508                 $$ = new Array<Interval>;
509         }
510         | shape_array dim dim {
511                 $$->push(Interval($2, $2 + $3));
512         };
513
514 /*
515         MIDI
516 */
517 midi_block:
518         MIDI
519
520         '{' midi_body '}'       { $$ = $3; }
521         ;
522
523 midi_body: /* empty */          {
524                 $$ = THIS->default_midi ();
525         }
526         | midi_body STRING '=' translator_spec  {
527                 $$-> assign_translator (*$2, $4);
528                 delete $2;
529         }
530         | midi_body OUTPUT STRING ';'   {
531                 $$->outfile_str_ = *$3;
532                 delete $3;
533         }
534         | midi_body tempo_request ';' {
535                 $$->set_tempo ($2->dur_.length (), $2->metronome_i_);
536                 delete $2;
537         }
538         | midi_body error {
539
540         }
541         ;
542
543 tempo_request:
544         TEMPO entered_notemode_duration '=' int         {
545                 $$ = new Tempo_req;
546                 $$->dur_ = *$2;
547                 delete $2;
548                 $$-> metronome_i_ = $4;
549         }
550         ;
551
552 /*
553         MUSIC
554 */
555
556 Voice:
557         '{' Voice_body '}'      {
558                 $$ = $2;
559         }
560         ;
561
562 Voice_body:
563         /**/            {
564                 $$ = new Voice;
565                 $$->set_spot (THIS->here_input ());
566         }
567         | Voice_body Music              {
568                 $$->add ($2);
569         }
570         ;
571
572 Music:
573         full_element            { $$ = $1; }
574         | TYPE STRING Music     {
575                 $$ = $3;
576                 $$->translator_type_str_ = *$2;
577                 delete $2;
578         }
579         | TYPE STRING '=' STRING Music {
580                 $$ = $5;
581                 $$->translator_type_str_ = *$2;
582                 $$->translator_id_str_ = *$4;
583                 delete $2;
584                 delete $4;
585         }
586         | Voice         { $$ = $1; }
587         | Chord                 { $$ = $1; }
588         | transposed_music      { $$ = $1; }
589         | MUSIC_IDENTIFIER      { $$ = $1->music (); }
590         | MUSIC_IDENTIFIER ';'  { $$ = $1->music (); }
591         | MELODIC
592                 { THIS->lexer_p_->push_note_state (); }
593         Music
594                 { $$=$3; THIS->lexer_p_->pop_state (); }
595
596         | LYRIC
597                 { THIS->lexer_p_->push_lyric_state (); }
598         Music
599                 { $$ = $3; THIS->lexer_p_->pop_state (); }
600         | property_def
601         | translator_change
602         ;
603
604 translator_change:
605         TRANSLATOR STRING '=' STRING  {
606                 Change_translator * t = new Change_translator;
607                 t-> change_to_type_str_ = *$2;
608                 t-> change_to_id_str_ = *$4;
609
610                 $$ = t;
611                 $$->set_spot (THIS->here_input ());
612                 delete $2;
613                 delete $4;
614         }
615         ;
616
617 property_def:
618         PROPERTY STRING '.' STRING '=' scalar   {
619                 Translation_property *t = new Translation_property;
620                 t-> translator_type_str_ = *$2;
621                 t-> var_str_ = *$4;
622                 t-> value_ = *$6;
623                 $$ = t;
624                 $$->set_spot (THIS->here_input ());
625                 delete $2;
626                 delete $4;
627                 delete $6;
628         }
629         ;
630
631 scalar:
632         STRING          { $$ = new Scalar (*$1); delete $1; }
633         | int           { $$ = new Scalar ($1); }
634         ;
635
636
637 Chord:
638         '<' Chord_body '>'      { $$  = $2; }
639         | MULTI INT Chord {
640                 $$ = $3;
641                 $$->multi_level_i_=$2;
642         }
643         ;
644
645 Chord_body:
646         /**/    {
647                 $$ = new Chord;
648                 $$-> multi_level_i_ = 1;
649                 $$->set_spot (THIS->here_input ());
650         }
651         | Chord_body Music {
652                 $$->add ($2);
653         }
654         ;
655
656 transposed_music:
657         TRANSPOSE steno_melodic_req Music {
658                 $$ = $3;
659                 $$ -> transpose ($2);
660
661                 delete $2;
662         }
663         ;
664
665
666 /*
667         VOICE ELEMENTS
668 */
669 full_element:
670         pre_requests simple_element post_requests       {
671                 THIS->add_requests ((Chord*)$2);//ugh
672                 $$ = $2;
673         }
674         | command_elt
675         | voice_command ';'     { $$ = 0; }
676         ;
677
678 simple_element:
679         music_elt
680         | lyrics_elt
681         ;
682
683 command_elt:
684         command_req {
685                 $$ = new Request_chord;
686                 $$-> set_spot (THIS->here_input ());
687                 $1-> set_spot (THIS->here_input ());
688                 ((Chord*)$$) ->add ($1);//ugh
689
690         }
691         ;
692
693 command_req:
694         abbrev_command_req
695         | verbose_command_req ';'       { $$ = $1; }
696         ;
697
698 abbrev_command_req:
699          '|'                            {
700                 $$ = new Barcheck_req;
701         }
702         | COMMAND_IDENTIFIER    {
703                 $$ = $1->request ();
704         }
705         ;
706
707 verbose_command_req:
708         BAR STRING                      {
709                 $$ = new Bar_req (*$2);
710                 delete $2;
711         }
712         | METER int '/' int     {
713                 Meter_change_req *m = new Meter_change_req;
714                 m->set ($2,$4);
715                 $$ = m;
716         }
717         | SKIP duration_length {
718                 Skip_req * skip_p = new Skip_req;
719                 skip_p->duration_.set_plet ($2->numerator ().as_long (),
720                         $2->denominator ().as_long ());
721
722                 delete $2;
723                 $$ = skip_p;
724         }
725         | tempo_request {
726                 $$ = $1;
727         }
728         | CADENZA int   {
729                 $$ = new Cadenza_req ($2);
730         }
731         | PARTIAL duration_length       {
732                 $$ = new Partial_measure_req (*$2);
733                 delete $2;
734         }
735         | CLEF STRING {
736                 $$ = new Clef_change_req (*$2);
737                 delete $2;
738         }
739         | KEY pitch_list        {
740                 Key_change_req *key_p= new Key_change_req;
741                 key_p->melodic_p_arr_ = *$2;
742                 $$ = key_p;
743                 delete $2;
744         }
745         | GROUPING intastint_list {
746                 $$ = get_grouping_req (*$2); delete $2;
747         }
748         ;
749
750 post_requests:
751         {
752                 assert (THIS->post_reqs.empty ());
753         }
754         | post_requests post_request {
755                 $2->set_spot (THIS->here_input ());
756                 THIS->post_reqs.push ($2);
757         }
758         | post_requests close_request_parens    {
759                 Array<Request*>& r = *THIS->get_parens_request ($2);
760                 for (int i = 0; i < r.size (); i++ )
761                         r[i]->set_spot (THIS->here_input ());
762                 THIS->post_reqs.concat (r);
763                 delete &r;
764         }
765         ;
766
767
768 post_request:
769         POST_REQUEST_IDENTIFIER {
770                 $$ = (Request*)$1->request ();
771         }
772         | script_req
773         | dynamic_req
774         | abbrev_type   {
775                 Abbreviation_req* a = new Abbreviation_req;
776                 a->type_i_ = $1;
777                 $$ = a;
778         }
779         ;
780
781
782
783 /*
784         URG!!
785 */
786 steno_melodic_req:
787         NOTENAME_ID     {
788                 $$ = $1->clone ()->musical ()->melodic ();
789                 $$->octave_i_ += THIS->default_octave_i_;
790         }
791         | steno_melodic_req POST_QUOTES         {
792                 $$-> octave_i_ += $2;
793         }
794         | PRE_QUOTES steno_melodic_req   {
795                 $$ = $2;
796                 $2-> octave_i_ -= $1;
797         }
798         ;
799
800 steno_note_req:
801         steno_melodic_req       {
802                 $$ = new Note_req;
803                 * (Melodic_req *) $$ = *$1;
804                 delete $1;
805         }
806         | steno_note_req   '!'          {
807                 $$->forceacc_b_ = ! $$->forceacc_b_;
808         }
809         /* have to duration here. */
810         ;
811
812 melodic_request:
813         MELODIC_REQUEST '{' int int int '}'     {/* ugh */
814                 $$ = new Melodic_req;
815                 $$->octave_i_ = $3;
816                 $$->notename_i_ = $4;
817                 $$->accidental_i_ = $5;
818         }
819         ;
820
821 explicit_duration:
822         DURATION '{' int int '}'        {
823                 $$ = new Duration;
824                 $$-> durlog_i_ = $3;
825                 $$-> dots_i_ = $4;
826         }
827         ;
828
829 dynamic_req:
830         ABSDYNAMIC '{' int '}'  {
831                 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
832                 ad_p ->loudness_ = (Dynamic_req::Loudness)$3;
833                 $$ =ad_p;
834         }
835         | SPANDYNAMIC '{' int int '}' {
836                 Span_dynamic_req * sp_p = new Span_dynamic_req;
837                 sp_p->spantype = $4;
838                 sp_p-> dynamic_dir_  = $3;
839                 $$ = sp_p;
840         }
841         ;
842
843 close_plet_parens:
844         ']' INT '/' INT {
845                 $$ = MAEBTELP;
846                 THIS->plet_.type_i_ = $4;
847                 THIS->plet_.iso_i_ = $2;
848                 THIS->default_duration_.plet_.type_i_ = $4;
849                 THIS->default_duration_.plet_.iso_i_ = $2;
850         }
851         | TELP {
852                 $$ = TELP;
853                 THIS->plet_.type_i_ = 1;
854                 THIS->plet_.iso_i_ = 1;
855                 THIS->default_duration_.plet_.iso_i_ = 1;
856                 THIS->default_duration_.plet_.type_i_ = 1;
857         }
858         | TELP INT '/' INT {
859                 $$ = TELP;
860                 THIS->plet_.type_i_ = $4;
861                 THIS->plet_.iso_i_ = $2;
862                 THIS->default_duration_.plet_.type_i_ = $4;
863                 THIS->default_duration_.plet_.iso_i_ = $2;
864         }
865         ;
866
867 close_request_parens:
868         '~'     {
869                 $$ = '~';
870         }
871         | '('   {
872                 $$='(';
873         }
874         | ']'   {
875                 $$ = ']';
876         }
877         | E_SMALLER {
878                 $$ = '<';
879         }
880         | E_BIGGER {
881                 $$ = '>';
882         }
883         | close_plet_parens {
884         }
885         ;
886
887 open_abbrev_parens:
888         '[' ':' INT {
889                 $$ = '[';
890                 if (!Duration::duration_type_b ($3))
891                         THIS->parser_error ("Not a duration");
892                 else if ($3 < 8)
893                         THIS->parser_error ("Can't abbreviate");
894                 else
895                         THIS->set_abbrev_beam ($3);
896         }
897         ;
898
899 open_plet_parens:
900         '[' INT '/' INT {
901                 $$ = BEAMPLET;
902                 THIS->plet_.type_i_ = $4;
903                 THIS->plet_.iso_i_ = $2;
904                 THIS->default_duration_.plet_.type_i_ = $4;
905                 THIS->default_duration_.plet_.iso_i_ = $2;
906         }
907         | PLET INT '/' INT {
908                 $$ = PLET;
909                 THIS->plet_.type_i_ = $4;
910                 THIS->plet_.iso_i_ = $2;
911                 THIS->default_duration_.plet_.type_i_ = $4;
912                 THIS->default_duration_.plet_.iso_i_ = $2;
913         }
914         ;
915
916 open_request_parens:
917         E_EXCLAMATION   {
918                 $$ = '!';
919         }
920         | ')'   {
921                 $$=')';
922         }
923         | '['   {
924                 $$='[';
925         }
926         | open_abbrev_parens {
927         }
928         | open_plet_parens {
929         }
930         ;
931
932
933
934 script_definition:
935         SCRIPT '{' script_body '}'      { $$ = $3; }
936         ;
937
938 script_body:
939         STRING int int int int int              {
940                 Script_def *s = new Script_def;
941                 s->set_from_input (*$1,$2, $3,$4,$5, $6);
942                 $$  = s;
943                 delete $1;
944         }
945         ;
946
947 script_req:
948         script_dir gen_script_def               {
949                 Musical_script_req *m = new Musical_script_req;
950                 $$ = m;
951                 m-> scriptdef_p_ = $2;
952                 m-> set_spot (THIS->here_input ());
953                 m-> dir_  = $1;
954         }
955         ;
956
957 gen_script_def:
958         text_def        { $$ = $1;
959                 ((Text_def*) $$)->align_i_ = CENTER; /* UGH */
960         }
961         | mudela_script { $$ = $1;
962                 $$-> set_spot (THIS->here_input ());
963         }
964         ;
965
966 text_def:
967         STRING {
968                 Text_def *t  = new Text_def;
969                 $$ = t;
970                 t->text_str_ = *$1;
971                 delete $1;
972                 t->style_str_ = THIS->textstyle_str_;
973                 $$->set_spot (THIS->here_input ());
974         }
975         ;
976
977 script_abbreviation:
978         '^'             { $$ = get_scriptdef ('^'); }
979         | '+'           { $$ = get_scriptdef ('+'); }
980         | '-'           { $$ = get_scriptdef ('-'); }
981         | '|'           { $$ = get_scriptdef ('|'); }
982         | 'o'           { $$ = get_scriptdef ('o'); }
983         | '>'           { $$ = get_scriptdef ('>'); }
984         | '.'           {
985                 $$ = get_scriptdef ('.');
986         }
987         ;
988
989 mudela_script:
990         SCRIPT_IDENTIFIER               { $$ = $1->script (); }
991         | script_definition             { $$ = $1; }
992         | script_abbreviation           {
993                 $$ = THIS->lexer_p_->lookup_identifier (*$1)->script ();
994                 delete $1;
995         }
996         ;
997
998 script_dir:
999         '_'     { $$ = -1; }
1000         |'^'    { $$ = 1; }
1001         |'-'    { $$ = 0; }
1002         ;
1003
1004 pre_requests:
1005         {
1006         }
1007         | pre_requests open_request_parens {
1008                 Array<Request*>& r = *THIS->get_parens_request ($2);
1009                 for (int i = 0; i < r.size (); i++ )
1010                         r[i]->set_spot (THIS->here_input ());
1011                 THIS->pre_reqs.concat (r);
1012                 delete &r;
1013         }
1014         ;
1015
1016 voice_command:
1017         DURATION STRING {
1018                 THIS->set_duration_mode (*$2);
1019                 delete $2;
1020         }
1021         | DURATION entered_notemode_duration {
1022                 THIS->set_default_duration ($2);
1023                 delete $2;
1024         }
1025         | OCTAVE {
1026                 /*
1027                         This is weird, but default_octave_i_
1028                         is used in steno_note_req too
1029
1030                         c' -> default_octave_i_ == 1
1031                 */
1032                 /* why can't we have \oct 0 iso \oct{c'}*/
1033                 THIS->default_octave_i_ = 1; }
1034 /* cont */
1035         steno_melodic_req {
1036                 THIS->default_octave_i_ = $3->octave_i_;
1037                 delete $3;
1038         }
1039         | TEXTSTYLE STRING      {
1040                 THIS->textstyle_str_ = *$2;
1041                 delete $2;
1042         }
1043         ;
1044
1045 duration_length:
1046         {
1047                 $$ = new Moment (0,1);
1048         }
1049         | duration_length explicit_steno_duration               {
1050                 *$$ += $2->length ();
1051         }
1052         ;
1053
1054 dots:
1055         '.'             { $$ = 1; }
1056         | dots '.'      { $$ ++; }
1057         ;
1058
1059 entered_notemode_duration:
1060         /* */           {
1061                 $$ = new Duration (THIS->default_duration_);
1062         }
1063         | dots          {
1064                 $$ = new Duration (THIS->default_duration_);
1065                 $$->dots_i_  = $1;
1066         }
1067         | explicit_steno_duration       {
1068                 THIS->set_last_duration ($1);
1069                 $$ = $1;
1070         }
1071         ;
1072
1073 notemode_duration:
1074         entered_notemode_duration {
1075                 $$ = $1;
1076         }
1077         ;
1078
1079 explicit_steno_duration:
1080         int             {
1081                 $$ = new Duration;
1082                 if (!Duration::duration_type_b ($1))
1083                         THIS->parser_error ("Not a duration");
1084                 else {
1085                         $$->durlog_i_ = Duration_convert::i2_type ($1);
1086                         $$->set_plet (THIS->default_duration_);
1087                      }
1088         }
1089         | DURATION_IDENTIFIER   {
1090                 $$ = $1->duration ();
1091         }
1092         | explicit_steno_duration '.'   {
1093                 $$->dots_i_ ++;
1094         }
1095         | explicit_steno_duration '*' int  {
1096                 $$->plet_.iso_i_ = $3;
1097         }
1098         | explicit_steno_duration '/' int {
1099                 $$->plet_.type_i_ = $3;
1100         }
1101         ;
1102
1103
1104 abbrev_type: 
1105         ':'     {
1106                 $$ =0;
1107         }
1108         | ':' int {
1109                 if (!Duration::duration_type_b ($2))
1110                         THIS->parser_error ("Not a duration");
1111                 else if ($2 < 8)
1112                         THIS->parser_error ("Can't abbreviate");
1113                 $$ = $2;
1114         }
1115
1116         ;
1117
1118 music_elt:
1119         steno_note_req notemode_duration  {
1120                 if (!THIS->lexer_p_->note_state_b ())
1121                         THIS->parser_error ("have to be in Note mode for notes");
1122                 $1->set_duration (*$2);
1123                 int durlog_i = $2->durlog_i_;
1124                 $$ = THIS->get_note_element ($1, $2);
1125         }
1126         | RESTNAME notemode_duration            {
1127                 $$ = THIS->get_rest_element (*$1, $2);
1128                 delete $1;
1129         }
1130         ;
1131
1132 lyrics_elt:
1133         text_def notemode_duration                      {
1134         /* this sux! text-def should be feature of lyric-engraver. */
1135                 if (!THIS->lexer_p_->lyric_state_b ())
1136                         THIS->parser_error ("Have to be in Lyric mode for lyrics");
1137                 $$ = THIS->get_word_element ($1, $2);
1138
1139         };
1140
1141 /*
1142         UTILITIES
1143  */
1144 pitch_list:                     {
1145                 $$ = new Array<Melodic_req*>;
1146         }
1147         | pitch_list NOTENAME_ID        {
1148                 $$->push ($2->clone ()->musical ()->melodic ());
1149         }
1150         ;
1151
1152 int:
1153         INT                     {
1154                 $$ = $1;
1155         }
1156         | INT_IDENTIFIER        {
1157                 int *i_p = $1->intid ();
1158                 $$ = *i_p;
1159                 delete i_p;
1160         }
1161         ;
1162
1163
1164 real:
1165         REAL            {
1166                 $$ = $1;
1167         }
1168         | REAL_IDENTIFIER               {
1169                 Real *r_p = $1->real ();
1170                 $$ = * r_p;
1171                 delete r_p;
1172         }
1173         ;
1174
1175
1176
1177 dim:
1178         real unit       { $$ = $1*$2; }
1179         ;
1180
1181
1182 unit:   CM_T            { $$ = 1 CM; }
1183         |IN_T           { $$ = 1 INCH; }
1184         |MM_T           { $$ = 1 MM; }
1185         |PT_T           { $$ = 1 PT; }
1186         ;
1187
1188 /*
1189         symbol tables
1190 */
1191 symtables:
1192         SYMBOLTABLES '{' symtables_body '}'     { $$ = $3; }
1193         ;
1194
1195 symtables_body:
1196                         {
1197                 $$ = new Lookup;
1198         }
1199         | IDENTIFIER            {
1200                 $$ = $1->lookup ();
1201         }
1202         | symtables_body TEXID STRING           {
1203                 $$->texsetting = *$3;
1204                 delete $3;
1205         }
1206         | symtables_body STRING '=' symtable            {
1207                 $$->add (*$2, $4);
1208                 delete $2;
1209         }
1210         ;
1211
1212 symtable:
1213         TABLE '{' symtable_body '}' { $$ = $3; }
1214         ;
1215
1216 symtable_body:
1217                                 { $$ = new Symtable; }
1218         | symtable_body STRING  symboldef {
1219                 $$->add (*$2, *$3);
1220                 delete $2;
1221                 delete $3;
1222         }
1223         ;
1224
1225 symboldef:
1226         STRING  box             {
1227                 $$ = new Atom (*$1, *$2);
1228                 delete $1;
1229                 delete $2;
1230         }
1231         | STRING {
1232                 Box b (Interval (0,0), Interval (0,0));
1233                 $$ = new Atom (*$1, b);
1234                 delete $1;
1235         }
1236         ;
1237
1238 box:
1239         dinterval dinterval     {
1240                 $$ = new Box (*$1, *$2);
1241                 delete $1;
1242                 delete $2;
1243         }
1244         ;
1245
1246 dinterval: dim  dim             {
1247                 $$ = new Interval ($1, $2);
1248         }
1249         ;
1250
1251 %%
1252
1253 void
1254 My_lily_parser::set_yydebug (bool b)
1255 {
1256 #ifdef YYDEBUG
1257         yydebug = b;
1258 #endif
1259 }
1260 void
1261 My_lily_parser::do_yyparse ()
1262 {
1263         yyparse ((void*)this);
1264 }
1265
1266 Paper_def*
1267 My_lily_parser::default_paper ()
1268 {
1269         Identifier *id = lexer_p_->lookup_identifier ("default_paper");
1270         return id ? id->paperdef () : new Paper_def ;
1271 }
1272
1273 Midi_def*
1274 My_lily_parser::default_midi ()
1275 {
1276         Identifier *id = lexer_p_->lookup_identifier ("default_midi");
1277         return id ? id->mididef () : new Midi_def ;
1278 }
1279