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