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