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