]> git.donarmstrong.com Git - lilypond.git/blob - lily/parser.yy
release: 1.0.8
[lilypond.git] / lily / parser.yy
1 %{ // -*-Fundamental-*-
2
3 /*
4   parser.yy -- Bison/C++ parser for mudela
5
6   source file of the GNU LilyPond music typesetter
7
8   (c) 1997 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9            Jan Nieuwenhuizen <janneke@gnu.org>
10 */
11
12 #include <iostream.h>
13
14 #include "scalar.hh"
15 #include "translation-property.hh"
16 #include "script-def.hh"
17 #include "symtable.hh"
18 #include "lookup.hh"
19 #include "misc.hh"
20 #include "my-lily-lexer.hh"
21 #include "paper-def.hh"
22 #include "midi-def.hh"
23 #include "main.hh"
24 #include "file-path.hh"
25 #include "keyword.hh"
26 #include "debug.hh"
27 #include "parseconstruct.hh"
28 #include "dimension.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 "translator-group.hh"
35 #include "score.hh"
36 #include "music-list.hh"
37 #include "header.hh"
38 #include "duration-convert.hh"
39 #include "change-translator.hh"
40 #include "file-results.hh"
41 #include "mudela-version.hh"
42 #include "scope.hh"
43 #include "relative-music.hh"
44
45
46 // mmm
47 Mudela_version oldest_version ("1.0.1");
48 Mudela_version version ("1.0.2");
49
50
51 // needed for bison.simple's malloc() and free()
52 #include <malloc.h>
53
54 int const GUESS_PLET = 5;
55 int guess_plet_a[GUESS_PLET] =
56
57   1,
58   3,
59   2,
60   3,
61   4
62 };
63
64 Paper_def* current_paper = 0;
65
66 #ifndef NDEBUG
67 #define YYDEBUG 1
68 #endif
69
70 #define YYERROR_VERBOSE 1
71
72 #define YYPARSE_PARAM my_lily_parser_l
73 #define YYLEX_PARAM my_lily_parser_l
74 #define THIS ((My_lily_parser *) my_lily_parser_l)
75
76 #define yyerror THIS->parser_error
77
78 %}
79
80
81 %union {
82     Array<Interval>* intarr;
83     Array<Musical_pitch> *pitch_arr;
84     Array<String> * strvec;
85     Array<int> *intvec;
86     Box *box;
87     Simultaneous_music *chord;
88     Duration *duration;
89     Identifier *id;
90     Translator* trans;
91     Music *music;
92     Music_list *music_list;
93     Score *score;
94     Header *header;
95     Interval *interval;
96     Lookup*lookup;
97
98     Musical_req* musreq;
99     Music_output_def * outputdef;
100     Musical_pitch * pitch;
101     Midi_def* midi;
102     Moment *moment;
103     Note_req *notereq;
104     Paper_def *paper;
105     Real real;
106     Request * request;
107     General_script_def * script;
108     Scalar *scalar;
109     String *string;
110     Atom * symbol;
111     Symtable * symtable;
112     Symtables * symtables;
113     Text_def * textdef;
114     Tempo_req *tempo;
115     char c;
116     const char *consstr;
117     int i;
118     int pair[2];
119     int ii[10];
120 }
121 %{
122
123 int
124 yylex (YYSTYPE *s,  void * v_l)
125 {
126         My_lily_parser   *pars_l = (My_lily_parser*) v_l;
127         My_lily_lexer * lex_l = pars_l->lexer_p_;
128
129         lex_l->lexval_l = (void*) s;
130         return lex_l->yylex ();
131 }
132
133
134 %}
135
136 %pure_parser
137
138 /* tokens which are not keywords */
139
140 %token ALIAS
141 %token BAR
142 %token BEAMPLET
143 %token MAEBTELP
144 %token PENALTY
145 %token CADENZA
146 %token CLEAR
147 %token CLEF
148 %token CONTAINS
149 %token RELATIVE
150 %token CONSISTS
151 %token ACCEPTS
152 %token CM_T
153 %token DURATION
154 %token ABSDYNAMIC
155 %token END
156 %token GROUPING
157 %token TRANSLATOR
158 %token HEADER
159 %token IN_T
160 %token LYRIC
161 %token KEY
162 %token KEYSIGNATURE
163 %token MARK
164 %token MUSIC
165 %token MUSICAL_PITCH
166 %token MELODIC
167 %token MIDI
168 %token TIME_T
169 %token MM_T
170 %token MULTI
171 %token NOTENAMES
172 %token OCTAVE
173 %token OUTPUT
174 %token PAPER
175 %token PARTIAL
176 %token PLET
177 %token TELP
178 %token PT_T
179 %token SCORE
180 %token SCRIPT
181 %token SHAPE
182 %token SKIP
183 %token SPANDYNAMIC
184 %token STAFF
185 %token START_T
186 %token SYMBOLTABLES
187 %token TABLE
188 %token TRANSPOSE
189 %token TEMPO
190 %token TYPE
191 %token FONT
192 %token MEASURES
193 %token TITLE
194 %token PROPERTY
195 %token VERSION
196
197 /* escaped */
198 %token E_EXCLAMATION E_SMALLER E_BIGGER E_CHAR
199
200 %type <i>       dots
201 %token <i>      DIGIT
202 %token <pitch>  NOTENAME_PITCH
203 %token <id>     DURATION_IDENTIFIER
204 %token <id>     IDENTIFIER
205
206 %token <id>     MUSIC_IDENTIFIER
207 %token <id>     POST_REQUEST_IDENTIFIER
208 %token <id>     SCRIPT_IDENTIFIER
209 %token <id>     COMMAND_IDENTIFIER
210 %token <id>     REAL_IDENTIFIER
211 %token <id>     STRING_IDENTIFIER
212 %token <id>     TRANS_IDENTIFIER
213 %token <id>     INT_IDENTIFIER
214 %token <id>     SCORE_IDENTIFIER
215 %token <id>     MIDI_IDENTIFIER
216 %token <id>     PAPER_IDENTIFIER
217 %token <id>     REQUEST_IDENTIFIER
218 %token <real>   REAL
219 %token <string> DURATION RESTNAME
220 %token <string> STRING
221 %token <i>      UNSIGNED
222
223
224 %type <outputdef> output_def
225 %type <header>  mudela_header mudela_header_body
226 %type <box>     box
227 %type <i>       open_request_parens close_request_parens
228 %type <i>       open_abbrev_parens
229 %type <i>       open_plet_parens close_plet_parens
230 %type <i>       sub_quotes sup_quotes
231 %type <music>   simple_element  request_chord command_element
232 %type <i>       abbrev_type
233 %type <i>       int unsigned
234 %type <i>       script_dir
235 %type <id>      identifier_init simple_identifier_init
236 %type <duration> steno_duration notemode_duration
237 %type <duration> entered_notemode_duration explicit_duration
238 %type <interval>        dinterval
239 %type <intvec>  intastint_list
240 %type <lookup>  symtables symtables_body
241
242 %type <pitch>   explicit_musical_pitch steno_musical_pitch musical_pitch absolute_musical_pitch
243 %type <notereq> steno_notepitch
244 %type <pitch_arr>       pitch_list
245 %type <midi>    midi_block midi_body
246 %type <duration>        duration_length
247
248 %type <scalar>  scalar
249 %type <music>   Music transposed_music relative_music Sequential_music Simultaneous_music
250 %type <music>   property_def translator_change
251 %type <music_list> Music_list
252 %type <paper>   paper_block paper_body
253 %type <real>    dim real
254 %type <real>    real_mult_expression real_primary
255 %type <real>    unit
256 %type <request> abbrev_command_req
257 %type <request> post_request structured_post_request
258 %type <pair>    plet_fraction
259 %type <request> command_req verbose_command_req
260 %type <request> script_req  dynamic_req
261 %type <string>  string
262 %type <string>  string_primary
263 %type <score>   score_block score_body
264 %type <intarr>  shape_array
265 %type <script>  script_definition script_body mudela_script gen_script_def
266 %type <textdef> text_def finger
267 %type <string>  script_abbreviation
268 %type <symbol>  symboldef
269 %type <symtable>        symtable symtable_body
270 %type <trans>   translator_spec translator_spec_body
271 %type <tempo>   tempo_request
272
273 %expect 1
274
275
276 %%
277
278 mudela: /* empty */
279         | mudela mudela_header {
280                 delete header_global_p;
281                 header_global_p = $2;
282         }
283         | mudela score_block {
284                 score_global_array.push ($2);
285         }
286         | mudela add_declaration { }
287         | mudela error
288         | mudela check_version { }
289         | mudela add_notenames { }
290         ;
291
292 check_version:
293         VERSION STRING ';'              {
294                 Mudela_version ver (*$2);
295                 if (!((ver >= oldest_version) && (ver <= version))) {
296                         if (THIS->ignore_version_b_) {
297                                 THIS->here_input ().error (_f ("incorrect mudela version: %s (%s, %s)", ver.str (), oldest_version.str (), version.str ()));
298                         } else {
299                                 THIS->fatal_error_i_ = 1;
300                                 THIS->parser_error (_f ("incorrect mudela version: %s (%s, %s)", ver.str (), oldest_version.str (), version.str ()));
301                         }
302                 }
303         }
304         ;
305
306 add_notenames:
307         NOTENAMES '{' notenames_body '}'
308         ;
309 notenames_body:
310         /**/    {
311         }
312         | notenames_body CLEAR  {
313                 THIS->clear_notenames ();
314         }
315         | notenames_body STRING '=' explicit_musical_pitch {
316                 THIS->add_notename (*$2, *$4);
317                 delete $4;
318                 delete $2;
319         }
320         ;
321
322 mudela_header_body:
323                 {
324                 $$ = new Header;
325         }
326         | mudela_header_body STRING '=' string ';' {
327                 (*$$)[*$2] = *$4;
328                 delete $2;
329                 delete $4;
330         }
331         ;
332
333 mudela_header:
334         HEADER '{' mudela_header_body '}'       {
335                 $$ = $3;
336         }
337         ;
338
339
340 /*
341         DECLARATIONS
342 */
343
344 add_declaration:
345         STRING {
346                 THIS->remember_spot ();
347         }
348         /* cont */ '=' identifier_init optional_semicolon {
349             THIS->lexer_p_->set_identifier (*$1, $4);
350             $4->init_b_ = THIS->init_parse_b_;
351             $4->set_spot (THIS->pop_spot ());
352         }
353         ;
354
355 identifier_init:
356         score_block {
357                 $$ = new Score_identifier ($1, SCORE_IDENTIFIER);
358
359         }
360         | paper_block {
361                 $$ = new Paper_def_identifier ($1, PAPER_IDENTIFIER);
362         }
363         | midi_block {
364                 $$ = new Midi_def_identifier ($1, MIDI_IDENTIFIER);
365
366         }
367         | script_definition {
368                 $$ = new General_script_def_identifier ($1, SCRIPT_IDENTIFIER);
369
370         }
371         | Music  {
372                 $$ = new Music_identifier ($1, MUSIC_IDENTIFIER);
373
374         }
375         | symtables {
376                 $$ = new Lookup_identifier ($1, IDENTIFIER);
377
378         }
379         | post_request {
380                 $$ = new Request_identifier ($1, POST_REQUEST_IDENTIFIER);
381         }
382         | explicit_duration {
383                 $$ = new Duration_identifier ($1, DURATION_IDENTIFIER);
384         }
385         | simple_identifier_init
386         ;
387
388 simple_identifier_init:
389         real {
390                 $$ = new Real_identifier (new Real ($1), REAL_IDENTIFIER);
391         }
392         | string {
393                 $$ = new String_identifier ($1, STRING_IDENTIFIER);
394         }
395         | int   {
396                 $$ = new int_identifier (new int ($1), INT_IDENTIFIER);
397         }
398         | translator_spec {
399                 $$ = new Translator_identifier ($1, TRANS_IDENTIFIER);
400         }
401         ;
402
403 translator_spec:
404         TRANSLATOR '{' translator_spec_body '}'
405                 { $$ = $3; }
406         ;
407
408 translator_spec_body:
409         TRANS_IDENTIFIER        {
410                 $$ = $1->access_Translator ();
411                 $$-> set_spot (THIS->here_input ());
412         }
413         | TYPE STRING ';'       {
414                 Translator* t = get_translator_l (*$2);
415                 t = t->clone ();
416                 t->set_spot (THIS->here_input ());
417                 $$ = t;
418                 delete $2;
419         }
420         | translator_spec_body STRING '=' simple_identifier_init ';'    { 
421                 Identifier* id = $4;
422                 String_identifier *s = id->access_String_identifier ();
423                 Real_identifier *r= id->access_Real_identifier ();
424                 int_identifier *i = id->access_int_identifier ();
425         
426                 String str;
427                 if (s) str = *s->access_String (false); 
428                 if (i) str = to_str (*i->access_int (false));
429                 if (r) str = to_str (*r->access_Real (false));
430                 if (!s && !i && !r)
431                         THIS->parser_error (_("Wrong type for property value"));
432
433                 delete $4;
434                 $$->set_property (*$2, str);
435         }
436         | translator_spec_body CONSISTS STRING ';' {
437                 $$->group_l ()->consists_str_arr_.push (*$3);
438                 delete $3;
439         }
440         | translator_spec_body ACCEPTS STRING ';' {
441                 $$->group_l ()->accepts_str_arr_.push (*$3);
442                 delete $3;
443         }
444         ;
445
446 /*
447         SCORE
448 */
449 score_block:
450         SCORE { THIS->remember_spot ();
451                 THIS->error_level_i_ =0;
452         }
453         /*cont*/ '{' score_body '}'     {
454                 $$ = $4;
455                 $$->set_spot (THIS->pop_spot ());
456                 if (!$$->def_p_arr_.size ())
457                         $$->add_output (THIS->default_paper_p ());
458
459                 /* handle error levels. */
460                 $$->errorlevel_i_ = THIS->error_level_i_;
461                 THIS->error_level_i_ = 0;
462         }
463         ;
464
465 score_body:             {
466                 $$ = new Score;
467         }
468         | SCORE_IDENTIFIER {
469                 $$ = $1->access_Score ();
470         }
471         | score_body mudela_header      {
472                 $$->header_p_ = $2;
473         }
474         | score_body Music      {
475                 if ($$->music_p_)
476                         $2->warning (_ ("More than one music block"));  
477                 $$->music_p_ = $2;
478         }
479         | score_body output_def {
480                 $$->add_output ($2);
481         }
482         | score_body error {
483
484         }
485         ;
486
487 output_def:
488         paper_block {
489                 $$ = $1;
490         }
491         |  midi_block           {
492                 $$= $1;
493         }
494         ;
495
496 intastint_list:
497         /* */   { $$ =new Array<int>; }
498         | intastint_list int '*' int    {
499                 $$->push ($2); $$->push ($4);
500         }
501         | intastint_list int    {
502                 $$->push ($2); $$->push (1);
503         }
504         ;       
505
506
507 /*
508         PAPER
509 */
510 paper_block:
511         PAPER '{' paper_body '}'        { 
512                 $$ = $3;
513                 THIS-> lexer_p_->scope_l_arr_.pop ();
514         }
515         ;
516
517 optional_semicolon:
518         /* empty */
519         | ';'
520         ;
521
522 paper_body:
523         /* empty */                     {
524                 Paper_def *p = THIS->default_paper_p ();
525                 THIS-> lexer_p_-> scope_l_arr_.push (p->scope_p_);
526                 $$ = p;
527         }
528         | PAPER_IDENTIFIER optional_semicolon   {
529                 Paper_def *p = $1->access_Paper_def ();
530                 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
531                 $$ = p;
532         }
533         | paper_body OUTPUT STRING ';'  { 
534                 $$->outfile_str_ = *$3;
535                 delete $3;
536         }
537         | paper_body int '=' symtables          { // ugh, what a syntax
538                 $$->set_lookup ($2, $4);
539         }
540         | paper_body STRING '=' simple_identifier_init optional_semicolon {
541             Identifier* id = $4;
542             id->init_b_ = THIS->init_parse_b_;
543             if (id->is_type_b (Translator_identifier::static_name ()))
544               {
545                 $$->assign_translator (*$2, id->access_Translator ());
546                 delete id;
547               }
548             else
549               THIS->lexer_p_->set_identifier (*$2, id);
550               delete $2;
551         }
552         | paper_body SHAPE '=' shape_array ';' {
553                 $$->shape_int_a_ = *$4;
554                 delete $4;
555         }
556         | paper_body error {
557
558         }
559         ;
560
561 real_primary:
562         REAL            {
563                 $$ = $1;
564         }
565         | REAL_IDENTIFIER               {
566                 Real *r_p = $1->access_Real ();
567                 $$ = * r_p;
568                 DOUT << "Lookup real: " << *r_p << "\n";
569                 delete r_p;
570         }
571         | dim
572         | '(' real ')' {
573                 $$ = $2;
574         }
575         ;
576
577 real:
578         real_mult_expression
579         | real '+' real_mult_expression {
580                 $$ = $1 + $3;
581         }
582         | real '-' real_mult_expression {
583                 $$ = $1 - $3;
584         }
585         ;
586
587 real_mult_expression:
588         real_primary
589         | real_mult_expression '*' real_primary {
590                 $$ = $1 * $3;
591         }
592         | real_mult_expression '/' real_primary {
593                 $$ = $1 / $3;
594         }
595         ;
596
597 shape_array:
598         /* empty */ {
599                 $$ = new Array<Interval>;
600         }
601         | shape_array dim dim {
602                 $$->push(Interval($2, $2 + $3));
603         };
604
605 /*
606         MIDI
607 */
608 midi_block:
609         MIDI
610
611         '{' midi_body '}'       { $$ = $3; }
612         ;
613
614 midi_body: /* empty */          {
615                 $$ = THIS->default_midi_p ();
616         }
617         | midi_body STRING '=' translator_spec  {
618                 $$-> assign_translator (*$2, $4);
619                 delete $2;
620         }
621         | midi_body OUTPUT STRING ';'   {
622                 $$->outfile_str_ = *$3;
623                 delete $3;
624         }
625         | midi_body tempo_request ';' {
626                 $$->set_tempo ($2->dur_.length (), $2->metronome_i_);
627                 delete $2;
628         }
629         | midi_body error {
630
631         }
632         ;
633
634 tempo_request:
635         TEMPO entered_notemode_duration '=' unsigned    {
636                 $$ = new Tempo_req;
637                 $$->dur_ = *$2;
638                 delete $2;
639                 $$-> metronome_i_ = $4;
640         }
641         ;
642
643 Music_list: /* empty */ {
644                 $$ = new Music_list;
645         }
646         | Music_list Music {
647                 $$->add_music ($2);
648         }
649         | Music_list error {
650         }
651         ;
652
653
654 Sequential_music: '{' Music_list '}'            {
655                 $$ = new Sequential_music ($2);
656         }
657         ;
658
659 Simultaneous_music: '<' Music_list '>'  {
660                 $$ = new Simultaneous_music ($2);
661         }
662         ;
663 Music:
664         request_chord           { $$ = $1; }
665         | TYPE STRING Music     {
666                 $$ = $3;
667                 $$->translator_type_str_ = *$2;
668                 delete $2;
669         }
670         | TYPE STRING '=' STRING Music {
671                 $$ = $5;
672                 $$->translator_type_str_ = *$2;
673                 $$->translator_id_str_ = *$4;
674                 delete $2;
675                 delete $4;
676         }
677         | Simultaneous_music            { $$ = $1; }
678         | Sequential_music              { $$ = $1; }
679         | transposed_music      { $$ = $1; }
680         | MUSIC_IDENTIFIER { $$ = $1->access_Music (); }
681         | MELODIC
682                 { THIS->lexer_p_->push_note_state (); }
683         Music
684                 { $$ = $3;
685                   THIS->lexer_p_->pop_state ();
686                 }
687
688         | LYRIC
689                 { THIS->lexer_p_->push_lyric_state (); }
690         Music
691                 {
692                   $$ = $3;
693                   THIS->lexer_p_->pop_state ();
694                 }
695         | property_def
696         | translator_change
697         | relative_music        { $$ = $1; }
698         ;
699
700 relative_music:
701         RELATIVE absolute_musical_pitch Music {
702                 $$ = new Relative_octave_music ($3, *$2);
703                 delete $2;
704         }
705         ;
706
707 translator_change:
708         TRANSLATOR STRING '=' STRING  {
709                 Change_translator * t = new Change_translator;
710                 t-> change_to_type_str_ = *$2;
711                 t-> change_to_id_str_ = *$4;
712
713                 $$ = t;
714                 $$->set_spot (THIS->here_input ());
715                 delete $2;
716                 delete $4;
717         }
718         ;
719
720 property_def:
721         PROPERTY STRING '.' STRING '=' scalar   {
722                 Translation_property *t = new Translation_property;
723                 t-> translator_type_str_ = *$2;
724                 t-> var_str_ = *$4;
725                 t-> value_ = *$6;
726                 $$ = t;
727                 $$->set_spot (THIS->here_input ());
728                 delete $2;
729                 delete $4;
730                 delete $6;
731         }
732         ;
733
734 scalar:
735         STRING          { $$ = new Scalar (*$1); delete $1; }
736         | int           { $$ = new Scalar ($1); }
737         ;
738
739
740 transposed_music:
741         TRANSPOSE musical_pitch Music {
742                 $$ = $3;
743                 $$ -> transpose (*$2);
744                 delete $2;
745         }
746         ;
747
748
749 request_chord:
750         pre_requests simple_element post_requests       {
751                 THIS->add_requests ((Simultaneous_music*)$2);//ugh
752                 $$ = $2;
753         }
754         | command_element
755         ;
756
757
758
759
760 command_element:
761         command_req {
762                 $$ = new Request_chord;
763                 $$-> set_spot (THIS->here_input ());
764                 $1-> set_spot (THIS->here_input ());
765                 ((Simultaneous_music*)$$) ->add_music ($1);//ugh
766
767         }
768         ;
769
770 command_req:
771         abbrev_command_req
772         | verbose_command_req ';'       { $$ = $1; }
773         ;
774
775 abbrev_command_req:
776         '|'                             {
777                 $$ = new Barcheck_req;
778         }
779         | COMMAND_IDENTIFIER    {
780                 $$ = $1->access_Request ();
781         }
782         ;
783
784 verbose_command_req:
785         BAR STRING                      {
786                 $$ = new Bar_req (*$2);
787                 delete $2;
788         }
789         | MARK STRING {
790                 $$ = new Mark_req (*$2);
791                 delete $2;
792         }
793         | MARK unsigned {
794                 $$ = new Mark_req (to_str ($2));
795         }
796         | TIME_T unsigned '/' unsigned  {
797                 Time_signature_change_req *m = new Time_signature_change_req;
798                 m->beats_i_ = $2;
799                 m->one_beat_i_=$4;
800                 $$ = m;
801         }
802         | PENALTY '=' int       {
803                 Break_req * b = new Break_req;
804                 b->penalty_i_ = $3;
805                 b-> set_spot (THIS->here_input ());
806                 $$ = b;
807         }
808         | SKIP duration_length {
809                 Skip_req * skip_p = new Skip_req;
810                 skip_p->duration_ = *$2;
811                 delete $2;
812                 $$ = skip_p;
813         }
814         | tempo_request {
815                 $$ = $1;
816         }
817         | CADENZA unsigned      {
818                 $$ = new Cadenza_req ($2);
819         }
820         | PARTIAL duration_length       {
821                 $$ = new Partial_measure_req ($2->length ());
822                 delete $2;
823         }
824         | CLEF STRING {
825                 $$ = new Clef_change_req (*$2);
826                 delete $2;
827         }
828         | KEY NOTENAME_PITCH    {
829                 Key_change_req *key_p= new Key_change_req;
830                 key_p->pitch_arr_.push(*$2);
831                 key_p->ordinary_key_b_ = true;
832                 $$ = key_p;
833                 delete $2;
834         }
835         | KEYSIGNATURE pitch_list       {
836                 Key_change_req *key_p= new Key_change_req;
837                 key_p->pitch_arr_ = *$2;
838                 key_p->ordinary_key_b_ = false;
839                 $$ = key_p;
840                 delete $2;
841         }
842         | GROUPING intastint_list {
843                 $$ = get_grouping_req (*$2); delete $2;
844         }
845         ;
846
847 post_requests:
848         {
849                 /* something silly happened.  Junk this stuff*/
850                 if (!THIS->post_reqs.empty ())
851                 {
852                         warning ("Junking post-requests");
853                         THIS->post_reqs.clear ();
854                 }
855         }
856         | post_requests structured_post_request {
857                 $2->set_spot (THIS->here_input ());
858                 THIS->post_reqs.push ($2);
859         }
860         | post_requests close_request_parens    {
861                 Array<Request*>& r = *THIS->get_parens_request ($2);
862                 for (int i = 0; i < r.size (); i++ )
863                         r[i]->set_spot (THIS->here_input ());
864                 THIS->post_reqs.concat (r);
865                 delete &r;
866         }
867         ;
868
869 structured_post_request:
870         script_req
871         | post_request
872         ;
873
874 post_request:
875         POST_REQUEST_IDENTIFIER {
876                 $$ = (Request*)$1->access_Request ();
877         }
878         | dynamic_req {
879                 $$ = $1;
880         }
881         | abbrev_type   {
882                 Abbreviation_req* a = new Abbreviation_req;
883                 a->type_i_ = $1;
884                 $$ = a;
885         }
886         ;
887
888 sup_quotes:
889         '\'' {
890                 $$ = 1;
891         }
892         | sup_quotes '\'' {
893                 $$ ++;
894         }
895         ;
896 sub_quotes:
897         ',' {
898                 $$ = 1;
899         }
900         | sub_quotes ',' {
901                 $$ ++ ;
902         }
903         ;
904
905 steno_musical_pitch:
906         NOTENAME_PITCH  {
907                 $$ = $1;
908         }
909         | NOTENAME_PITCH sup_quotes     {
910                 $$ = $1;
911                 $$->octave_i_ +=  $2;
912         }
913         | NOTENAME_PITCH sub_quotes      {
914                 $$ = $1;
915                 $$->octave_i_ += - $2;
916         }
917         ;
918
919 explicit_musical_pitch:
920         MUSICAL_PITCH '{' int int int '}'       {/* ugh */
921                 $$ = new Musical_pitch;
922                 $$->octave_i_ = $3;
923                 $$->notename_i_ = $4;
924                 $$->accidental_i_ = $5;
925         }
926         ;
927 musical_pitch:
928         steno_musical_pitch
929         | explicit_musical_pitch
930         ;
931
932 steno_notepitch:
933         musical_pitch   {
934                 $$ = new Note_req;
935                 
936                 $$->pitch_ = *$1;
937                 delete $1;
938         }
939         | steno_notepitch  '!'          {
940                 $$->forceacc_b_ = ! $$->forceacc_b_;
941         }
942         ;
943
944
945 explicit_duration:
946         DURATION '{' int unsigned '}'   {
947                 $$ = new Duration;
948                 $$-> durlog_i_ = $3;
949                 $$-> dots_i_ = $4;
950         }
951         ;
952
953 dynamic_req:
954         ABSDYNAMIC '{' unsigned '}'     {
955                 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
956                 ad_p ->loudness_ = (Dynamic_req::Loudness)$3;
957                 $$ =ad_p;
958         }
959         | SPANDYNAMIC '{' int int '}' {
960                 Span_dynamic_req * sp_p = new Span_dynamic_req;
961                 sp_p->spantype = (Span_req::Spantype)$4;
962                 sp_p-> dynamic_dir_  = (Direction)$3;
963                 $$ = sp_p;
964         }
965         ;
966
967 plet_fraction:
968         unsigned '/' unsigned {
969                 $$[0] = $1;
970                 $$[1] = $3;
971         }
972         |
973         '/' unsigned {
974                 int num = $2 >? 1;
975                 $$[0] = guess_plet_a[(num <? GUESS_PLET) - 1];
976                 $$[1] = num;
977         }
978         ;
979
980 close_plet_parens:
981         ']' plet_fraction {
982                 $$ = MAEBTELP;
983                 THIS->plet_.type_i_ = $2[1];
984                 THIS->plet_.iso_i_ = $2[0];
985                 THIS->default_duration_.plet_ = THIS->plet_;
986         }
987         | TELP {
988                 $$ = TELP;
989                 THIS->plet_.type_i_ = 1;
990                 THIS->plet_.iso_i_ = 1;
991                 THIS->default_duration_.plet_ = THIS->plet_;
992         }
993         | TELP plet_fraction {
994                 $$ = TELP;
995                 THIS->plet_.type_i_ = $2[1];
996                 THIS->plet_.iso_i_ = $2[0];
997                 THIS->default_duration_.plet_ = THIS->plet_;
998         }
999         ;
1000
1001 close_request_parens:
1002         '~'     {
1003                 $$ = '~';
1004         }
1005         | '('   {
1006                 $$='(';
1007         }
1008         | ']'   {
1009                 $$ = ']';
1010         }
1011         | E_SMALLER {
1012                 $$ = '<';
1013         }
1014         | E_BIGGER {
1015                 $$ = '>';
1016         }
1017         | close_plet_parens
1018         ;
1019
1020 open_abbrev_parens:
1021         '[' ':' unsigned {
1022                 $$ = '[';
1023                 if (!Duration::duration_type_b ($3))
1024                         THIS->parser_error (_f ("not a duration: %d", $3));
1025                 else if ($3 < 8)
1026                         THIS->parser_error (_ ("can't abbreviate"));
1027                 else
1028                         THIS->set_abbrev_beam ($3);
1029         }
1030         ;
1031
1032 open_plet_parens:
1033         '[' plet_fraction {
1034                 $$ = BEAMPLET;
1035                 THIS->plet_.type_i_ = $2[1];
1036                 THIS->plet_.iso_i_ = $2[0];
1037                 THIS->default_duration_.plet_ = THIS->plet_;
1038         }
1039         | PLET plet_fraction {
1040                 $$ = PLET;
1041                 THIS->plet_.type_i_ = $2[1];
1042                 THIS->plet_.iso_i_ = $2[0];
1043                 THIS->default_duration_.plet_ = THIS->plet_;
1044         }
1045         ;
1046
1047 open_request_parens:
1048         E_EXCLAMATION   {
1049                 $$ = '!';
1050         }
1051         | ')'   {
1052                 $$=')';
1053         }
1054         | '['   {
1055                 $$='[';
1056         }
1057         | open_abbrev_parens
1058         | open_plet_parens
1059         ;
1060
1061
1062
1063 script_definition:
1064         SCRIPT '{' script_body '}'      { $$ = $3; }
1065         ;
1066
1067 script_body:
1068         STRING int int int int int              {
1069                 Script_def *s = new Script_def;
1070                 s->set_from_input (*$1,$2, $3,$4,$5, $6);
1071                 $$  = s;
1072                 delete $1;
1073         }
1074         ;
1075
1076 script_req:
1077         script_dir gen_script_def       {
1078                 Musical_script_req *m = new Musical_script_req;
1079                 $$ = m;
1080                 m->scriptdef_p_ = $2;
1081                 m->set_spot (THIS->here_input ());
1082                 if (!m->dir_)
1083                   m->dir_  = (Direction)$1;
1084         }
1085         ;
1086
1087 gen_script_def:
1088         text_def        { 
1089                 $$ = $1;
1090                 ((Text_def*) $$)->align_dir_ = LEFT; /* UGH */
1091         }
1092         | mudela_script { 
1093                 $$ = $1;
1094                 $$-> set_spot (THIS->here_input ());
1095         }
1096         | finger {
1097                 $$ = $1;
1098                 ((Text_def*)$$)->align_dir_ = RIGHT; /* UGH */
1099         }
1100         ;
1101
1102 text_def:
1103         string {
1104                 Text_def *t  = new Text_def;
1105                 $$ = t;
1106                 t->text_str_ = *$1;
1107                 delete $1;
1108                 $$->set_spot (THIS->here_input ());
1109         }
1110         ;
1111
1112 finger:
1113          DIGIT {
1114                 Text_def* t  = new Text_def;
1115                 $$ = t;
1116                 t->text_str_ = to_str ($1);
1117                 t->style_str_ = "finger";
1118                 $$->set_spot (THIS->here_input ());
1119         }
1120         ;
1121
1122 script_abbreviation:
1123         '^'             { $$ = get_scriptdef ('^'); }
1124         | '+'           { $$ = get_scriptdef ('+'); }
1125         | '-'           { $$ = get_scriptdef ('-'); }
1126         | '|'           { $$ = get_scriptdef ('|'); }
1127         | 'o'           { $$ = get_scriptdef ('o'); }
1128         | '>'           { $$ = get_scriptdef ('>'); }
1129         | '.'           {
1130                 $$ = get_scriptdef ('.');
1131         }
1132         ;
1133
1134 mudela_script:
1135         SCRIPT_IDENTIFIER               { $$ = $1->access_General_script_def (true); }
1136         | script_definition             { $$ = $1; }
1137         | script_abbreviation           {
1138                 $$ = THIS->lexer_p_->lookup_identifier (*$1)->access_General_script_def (true);
1139                 delete $1;
1140         }
1141         ;
1142
1143 script_dir:
1144         '_'     { $$ = -1; }
1145         | '^'   { $$ = 1; }
1146         | '-'   { $$ = 0; }
1147         ;
1148
1149 pre_requests:
1150         {
1151         }
1152         | pre_requests open_request_parens {
1153                 Array<Request*>& r = *THIS->get_parens_request ($2);
1154                 for (int i = 0; i < r.size (); i++ )
1155                         r[i]->set_spot (THIS->here_input ());
1156                 THIS->pre_reqs.concat (r);
1157                 delete &r;
1158         }
1159         ;
1160
1161 absolute_musical_pitch:
1162         steno_musical_pitch     {
1163                 $$ = $1;
1164         }
1165         ;
1166
1167 duration_length:
1168         steno_duration {
1169                 $$ = $1;
1170         }
1171         ;
1172
1173 dots:
1174         '.'             { $$ = 1; }
1175         | dots '.'      { $$ ++; }
1176         ;
1177
1178 entered_notemode_duration:
1179         /* */           {
1180                 $$ = new Duration (THIS->default_duration_);
1181         }
1182         | dots          {
1183                 $$ = new Duration (THIS->default_duration_);
1184                 $$->dots_i_  = $1;
1185         }
1186         | steno_duration        {
1187                 THIS->set_last_duration ($1);
1188         }
1189         ;
1190
1191 notemode_duration:
1192         entered_notemode_duration {
1193                 $$ = $1;
1194         }
1195         ;
1196
1197 steno_duration:
1198         unsigned                {
1199                 $$ = new Duration;
1200                 if (!Duration::duration_type_b ($1))
1201                         THIS->parser_error (_f ("not a duration: %d", $1));
1202                 else {
1203                         $$->durlog_i_ = Duration_convert::i2_type ($1);
1204                         $$->set_plet (THIS->plet_.iso_i_, THIS->plet_.type_i_);
1205                      }
1206         }
1207         | DURATION_IDENTIFIER   {
1208                 $$ = $1->access_Duration ();
1209         }
1210         | steno_duration '.'    {
1211                 $$->dots_i_ ++;
1212         }
1213         | steno_duration '*' unsigned  {
1214                 $$->plet_.iso_i_ *= $3;
1215         }
1216         | steno_duration '/' unsigned {
1217                 $$->plet_.type_i_ *= $3;
1218         }
1219         ;
1220
1221
1222 abbrev_type: 
1223         ':'     {
1224                 $$ =0;
1225         }
1226         | ':' unsigned {
1227                 if (!Duration::duration_type_b ($2))
1228                         THIS->parser_error (_f ("not a duration: %d", $2));
1229                 else if ($2 < 8)
1230                         THIS->parser_error (_ ("can't abbreviate"));
1231                 $$ = $2;
1232         }
1233         ;
1234
1235
1236
1237 simple_element:
1238         steno_notepitch notemode_duration  {
1239                 if (!THIS->lexer_p_->note_state_b ())
1240                         THIS->parser_error (_ ("have to be in Note mode for notes"));
1241                 $1->set_duration (*$2);
1242                 int durlog_i = $2->durlog_i_;
1243                 $$ = THIS->get_note_element ($1, $2);
1244         }
1245         | RESTNAME notemode_duration            {
1246                 $$ = THIS->get_rest_element (*$1, $2);
1247                 delete $1;  // delete notename
1248         }
1249         | MEASURES notemode_duration    {
1250                 Multi_measure_rest_req* m = new Multi_measure_rest_req;
1251                 m->duration_ = *$2;
1252                 delete $2;
1253
1254                 Simultaneous_music*velt_p = new Request_chord;
1255                 velt_p->set_spot (THIS->here_input ());
1256                 velt_p->add_music (m);
1257                 $$ = velt_p;
1258
1259         }
1260         | STRING notemode_duration                      {
1261                 if (!THIS->lexer_p_->lyric_state_b ())
1262                         THIS->parser_error (_ ("have to be in Lyric mode for lyrics"));
1263                 $$ = THIS->get_word_element (*$1, $2);
1264                 delete $1;
1265         }
1266         ;
1267
1268
1269 /*
1270         UTILITIES
1271  */
1272 pitch_list:                     {
1273                 $$ = new Array<Musical_pitch>;
1274         }
1275         | pitch_list musical_pitch      {
1276                 $$->push (*$2);
1277                 delete $2;
1278         }
1279         ;
1280
1281 unsigned:
1282         UNSIGNED        {
1283                 $$ = $1;
1284         }
1285         | DIGIT {
1286                 $$ = $1;
1287         };
1288
1289 int:
1290         unsigned {
1291                 $$ = $1;
1292         }
1293         | '-' unsigned {
1294                 $$ = -$2;
1295         }
1296         | INT_IDENTIFIER        {
1297                 int *i_p = $1->access_int ();
1298                 $$ = *i_p;
1299                 delete i_p;
1300         }
1301         ;
1302
1303 string_primary:
1304         STRING          {
1305                 $$ = $1;
1306         }
1307         | STRING_IDENTIFIER     {
1308                 String *s_p = $1->access_String ();
1309
1310                 $$ = s_p;
1311                 DOUT << "Lookup string: " << *s_p << "\n";
1312         }
1313         ;
1314
1315 string:
1316         string_primary {
1317                 $$ = $1;
1318         }
1319         | string '+' string_primary {
1320                 *$$ += *$3;
1321                 delete $3;
1322         }
1323         ;
1324
1325 dim:
1326         real_primary unit       { $$ = $1*$2; }
1327         ;
1328
1329
1330 unit:   CM_T            { $$ = 1 CM; }
1331         |IN_T           { $$ = 1 INCH; }
1332         |MM_T           { $$ = 1 MM; }
1333         |PT_T           { $$ = 1 PT; }
1334         ;
1335
1336 /*
1337         symbol tables
1338 */
1339 symtables:
1340         SYMBOLTABLES '{' symtables_body '}'     { $$ = $3; }
1341         ;
1342
1343 symtables_body:
1344                         {
1345                 $$ = new Lookup;
1346         }
1347         | IDENTIFIER            {
1348                 $$ = $1->access_Lookup ();
1349         }
1350         | symtables_body FONT STRING            {
1351                 $$->font_ = *$3;
1352                 $$->font_path_ = global_path.find (*$3);
1353                 if  (!$$->font_path_.length_i ())
1354                         THIS->here_input ().error (_f("can't open file: `%s'", $3->ch_C()));
1355
1356                 delete $3;
1357         }
1358         | symtables_body STRING '=' symtable            {
1359                 $$->add (*$2, $4);
1360                 delete $2;
1361         }
1362         ;
1363
1364 symtable:
1365         TABLE '{' symtable_body '}' { $$ = $3; }
1366         ;
1367
1368 symtable_body:
1369                                 { $$ = new Symtable; }
1370         | symtable_body STRING  symboldef {
1371                 $$->add (*$2, *$3);
1372                 delete $2;
1373                 delete $3;
1374         }
1375         ;
1376
1377 symboldef:
1378         STRING  box             {
1379                 $$ = new Atom (*$1, *$2);
1380                 delete $1;
1381                 delete $2;
1382         }
1383         | STRING {
1384                 Box b (Interval (0,0), Interval (0,0));
1385                 $$ = new Atom (*$1, b);
1386                 delete $1;
1387         }
1388         ;
1389
1390 box:
1391         dinterval dinterval     {
1392                 $$ = new Box (*$1, *$2);
1393                 delete $1;
1394                 delete $2;
1395         }
1396         ;
1397
1398 dinterval: dim  dim             {
1399                 $$ = new Interval ($1, $2);
1400         }
1401         ;
1402
1403 %%
1404
1405 void
1406 My_lily_parser::set_yydebug (bool b)
1407 {
1408 #ifdef YYDEBUG
1409         yydebug = b;
1410 #endif
1411 }
1412 void
1413 My_lily_parser::do_yyparse ()
1414 {
1415         yyparse ((void*)this);
1416 }
1417