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