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