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