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