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