]> git.donarmstrong.com Git - lilypond.git/blob - lily/parser.y
bc8876b5e4baea49dffa2119309e314708b9dbd9
[lilypond.git] / lily / parser.y
1 %{ // -*-Fundamental-*-
2 #include <iostream.h>
3
4 #include "lookup.hh"
5 #include "misc.hh"
6 #include "lexer.hh"
7 #include "paper-def.hh"
8 #include "midi-def.hh"
9 #include "input-score.hh"
10 #include "main.hh"
11 #include "keyword.hh"
12 #include "debug.hh"
13 #include "parseconstruct.hh"
14 #include "dimen.hh"
15 #include "identifier.hh"
16 #include "command-request.hh"
17 #include "musical-request.hh"
18 #include "voice-element.hh"
19
20 #ifndef NDEBUG
21 #define YYDEBUG 1
22 #endif
23
24 Array<Request*> pre_reqs, post_reqs;
25 Array<const char *> define_spots;
26 Paper_def*default_paper();
27 char const* defined_ch_c_l;
28 char const* req_defined_ch_c_l;
29 int fatal_error_i = 0;
30
31 %}
32
33
34 %union {
35     Array<Melodic_req*> *melreqvec;
36     Array<String> * strvec;
37     Array<int> *intvec;
38     Box *box;
39     Identifier *id;    
40     Input_music *music;
41     Input_score *score;
42     Input_staff *staff;    
43     Interval *interval;
44     Lookup*lookup;
45     Melodic_req * melreq;
46     Midi_def* midi;
47     Moment *moment;
48     Music_general_chord *chord;
49     Music_voice *mvoice;
50     Note_req *notereq;
51     Paper_def *paper;
52     Real real;
53     Request * request;
54     Script_def * script;
55     String *string;
56     Symbol * symbol;
57     Symtable * symtable;
58     Symtables * symtables;
59     Text_def * textdef;
60     Voice *voice;    
61     Voice_element *el;  
62     char c;
63     const char *consstr;
64     int i;
65     int ii[10];
66 }
67
68 %token BAR
69 %token CADENZA
70 %token CLEF
71 %token CM_T
72 %token COMMAND
73 %token COMMANDS
74 %token DURATIONCOMMAND
75 %token DYNAMIC
76 %token END
77 %token GEOMETRIC
78 %token GOTO
79 %token GROUPING
80 %token IN_T
81 %token KEY
82 %token MELODIC
83 %token METER
84 %token MIDI
85 %token MM_T
86 %token MULTIVOICE
87 %token MUSIC
88 %token OCTAVECOMMAND
89 %token OUTPUT
90 %token PAPER
91 %token PARTIAL
92 %token PLET
93 %token PT_T
94 %token SCORE
95 %token SCRIPT
96 %token SKIP
97 %token STAFF
98 %token START_T
99 %token STEM
100 %token SYMBOLTABLES
101 %token TABLE
102 %token TABLE
103 %token TEMPO
104 %token TEXID
105 %token TEXTSTYLE
106 %token TITLE
107 %token UNITSPACE
108 %token VOICE
109 %token VOICES
110 %token WIDTH
111
112 %token <i>      DOTS
113 %token <i>      INT
114 %token <id>     IDENTIFIER
115 %token <id>     MELODIC_REQUEST_IDENTIFIER 
116 %token <id>     POST_REQUEST_IDENTIFIER
117 %token <id>     REAL_IDENTIFIER
118 %token <id>     REQUEST_IDENTIFIER
119 %token <real>   REAL 
120 %token <string> DURATION RESTNAME
121 %token <string> STRING
122
123 %type <box>     box
124 %type <c>       open_request_parens close_request_parens close_plet_parens
125 %type <chord>   music_chord music_chord_body
126 %type <el>      voice_elt full_element lyrics_elt command_elt
127 %type <i>       int
128 %type <i>       octave_quotes octave_quote
129 %type <i>       script_dir
130 %type <id>      declaration
131 %type <ii>      default_duration explicit_duration notemode_duration
132 %type <ii>      mudela_duration
133 %type <interval>        dinterval
134 %type <intvec>  intastint_list
135 %type <lookup>  symtables symtables_body
136 %type <melreq>  melodic_request
137 %type <notereq> steno_note_req
138 %type <melreqvec>       pitch_list 
139 %type <midi>    midi_block midi_body
140 %type <moment>  duration_length
141 %type <music>   music 
142 %type <mvoice>   music_voice_body music_voice 
143
144 %type <paper>   paper_block paper_body
145 %type <real>    dim real
146 %type <real>    unit
147 %type <request> post_request pre_request command_req pure_post_request
148 %type <request> script_req textscript_req dynamic_req 
149 %type <score>   score_block score_body
150 %type <script>  script_definition script_body mudela_script
151 %type <staff>   staff_block staff_init staff_body
152 %type <string>  declarable_identifier
153 %type <symbol>  symboldef
154 %type <symtable>        symtable symtable_body
155 %type <textdef> mudela_text
156
157 %%
158
159 mudela: /* empty */
160         | mudela score_block {
161                 add_score($2);          
162         }
163         | mudela add_declaration { }
164         ;
165
166
167 /*
168         DECLARATIONS
169 */
170 add_declaration: declaration    {
171                 lexer->add_identifier($1);
172         }
173         ;
174
175 declarable_identifier:
176         STRING { $$ = $1;
177            if (lexer->lookup_identifier(*$1))
178                 warning("redeclaration of `" + *$1 + "'",
179                         lexer->here_ch_c_l());
180         }
181         | IDENTIFIER { $$ = new String($1->name); }
182         ;
183
184 declaration:
185         declarable_identifier '=' staff_block  {
186                 $$ = new Staff_id(*$1, $3, IDENTIFIER);
187                 delete $1; 
188         }
189         | declarable_identifier '=' music_voice {
190                 $$ = new M_voice_id(*$1, $3, IDENTIFIER);
191                 delete $1;
192         }
193         | declarable_identifier '=' script_definition {
194                 $$ = new Script_id(*$1, $3, IDENTIFIER);
195                 delete $1;
196         }
197         | declarable_identifier '=' music_chord  {
198                 $$ = new M_chord_id(*$1, $3, IDENTIFIER);
199                 delete $1;
200         }
201         | declarable_identifier '=' symtables {
202                 $$ = new Lookup_id(*$1, $3, IDENTIFIER);
203                 delete $1;
204         }
205         | declarable_identifier '=' real        {
206                 $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
207                 delete $1;
208         }
209         | declarable_identifier error '}' {
210
211         }
212         | declarable_identifier '=' pure_post_request {
213                 $$ = new Request_id(*$1, $3, POST_REQUEST_IDENTIFIER);
214                 delete $1;
215         }
216         | declarable_identifier '=' melodic_request {
217                 $$ = new Request_id(*$1, $3, MELODIC_REQUEST_IDENTIFIER);
218                 delete $1;
219         }
220         ;
221
222
223 /*
224         SCORE
225 */
226 score_block:
227         SCORE { define_spots.push(lexer->here_ch_c_l()); }
228         /*cont*/ '{' score_body '}'     {
229                 $$ = $4;
230                 $$->defined_ch_c_l_ = define_spots.pop();
231                 if (!$$->paper_p_ && ! $$->midi_p_)
232                         $$->paper_p_ = default_paper();
233
234                 /* handle error levels. */
235                 $$->errorlevel_i_ = lexer->errorlevel_i_;
236                 lexer->errorlevel_i_ = 0;
237
238                 /* unbarf score without global music. */
239                 if (!$$-> score_wide_music_p_) {
240                         $$-> score_wide_music_p_ = new Music_voice; 
241                 }
242         }
243         ;
244
245 score_body:             { 
246                 $$ = new Input_score; 
247         }
248         | score_body staff_block        { $$->add($2); }
249         | score_body COMMANDS '{' music_voice_body '}'          {
250                 $$->set($4);
251         }
252         | score_body paper_block                { $$->set($2);  }
253         | score_body midi_block         { $$->set($2);  }
254         | score_body error {
255
256         }
257         ;
258
259 intastint_list:
260         /* */   { $$ =new Array<int>; }
261         | intastint_list int '*' int    {
262                 $$->push($2); $$->push($4);
263         }
264         ;
265
266
267 /*
268         PAPER
269 */
270 paper_block:
271         PAPER
272
273         '{' paper_body '}'      { $$ = $3; }
274         ;
275
276 paper_body:
277         /* empty */                     {
278                 $$ = default_paper();
279         }
280         | paper_body WIDTH dim          { $$->linewidth = $3;}
281         | paper_body OUTPUT STRING      { $$->outfile = *$3;
282                 delete $3;
283         }
284         | paper_body symtables          { $$->set($2); }
285         | paper_body UNITSPACE dim      { $$->whole_width = $3; }
286         | paper_body GEOMETRIC REAL     { $$->geometric_ = $3; }
287         | paper_body error {
288
289         }
290         ;
291
292 /*
293         MIDI
294 */
295 midi_block:
296         MIDI
297
298         '{' midi_body '}'       { $$ = $3; }
299         ;
300
301 midi_body: { 
302                 $$ = new Midi_def; 
303         }
304         | midi_body OUTPUT STRING       { 
305                 $$->outfile_str_ = *$3; 
306                 delete $3; 
307         }
308         | midi_body TEMPO mudela_duration ':' int {
309                 $$->set_tempo( wholes( $3[0], $3[1] ), $5 );
310         }
311         | midi_body error {
312
313         }
314         ;
315
316 /*
317         STAFFs
318 */
319 staff_block:
320         STAFF   { define_spots.push(lexer->here_ch_c_l()); }
321 /*cont*/        '{' staff_body '}'      {
322                 $$ = $4; 
323                 $$-> defined_ch_c_l_ = define_spots.pop();
324         }
325         ;
326
327
328
329 staff_init:
330         IDENTIFIER              { $$ = $1->staff(true); }
331         | STRING                {
332                 $$ = new Input_staff(*$1);
333                 delete $1;
334         }
335         | MELODIC {
336                 $$ = new Input_staff("melodic");
337         }
338         ;
339
340 staff_body:
341         staff_init
342         | staff_body COMMANDS '{' music_voice_body '}'  {
343                 $$->set_score_wide($4);
344         }
345         | staff_body music      {
346                 $2->set_default_group( "staff_music" + String($$->music_.size()));
347                 $$->add($2);
348         }
349         | staff_body error {
350         }
351         ;
352
353 /*
354         MUSIC
355 */
356 music:
357         music_voice     { $$ = $1; }
358         | music_chord   { $$ = $1; }
359         ;
360
361 music_voice:  MUSIC '{' music_voice_body '}'    { $$ = $3; }
362         ;
363
364 music_voice_body:
365         IDENTIFIER {
366                 $$ = $1->mvoice(true);
367         }
368         | /* */         {
369                 $$ = new Music_voice;
370         }
371         | music_voice_body '+' IDENTIFIER {
372                 $$->concatenate($3->mvoice(true));
373         }
374         | music_voice_body full_element {
375                 $$->add_elt($2);
376         }
377         | music_voice_body voice_command {
378         }
379         | music_voice_body music        {
380                 $$->add($2);
381         }
382         | music_voice_body error {
383         }
384         ;
385
386 music_chord:  '{' music_chord_body '}'  { $$ = $2; }
387         ;
388
389 music_chord_body:
390         IDENTIFIER {
391                 $$=$1->mchord(true);
392         }
393         | /* */ {
394                 $$ = new Voice_group_chord;
395         }
396         | MULTIVOICE {
397                 $$ = new Multi_voice_chord;
398         }
399         | music_chord_body '+' IDENTIFIER {
400                 $$->concatenate($3->mchord(true));
401         }
402         | music_chord_body music {
403                 $$->add($2);
404         }
405         | music_chord_body full_element {
406                 $$ ->add_elt($2);
407         }
408         | music_chord_body error {
409         }
410         ;
411
412 /*
413         VOICE ELEMENTS
414 */
415 full_element:   pre_requests voice_elt post_requests {
416                 add_requests($2, pre_reqs);
417                 add_requests($2, post_reqs);
418                 $$ = $2;
419         }
420         | pre_requests lyrics_elt post_requests {
421                 add_requests($2, pre_reqs);
422                 add_requests($2, post_reqs);
423                 $$ = $2;
424         }
425         | command_elt
426         ;
427
428 command_elt:
429 /* empty */     {
430                 $$ = new Voice_element;
431                 $$-> defined_ch_c_l_ = lexer->here_ch_c_l();
432         }
433 /* cont: */
434         command_req     {
435                 $2-> defined_ch_c_l_ = $$->defined_ch_c_l_;
436                 $$->add($2);
437
438         }
439         ;
440
441 command_req:
442          '|'                            { 
443                 $$ = new Barcheck_req;
444         }
445         | BAR STRING                    {
446                 $$ = new Bar_req(*$2);
447                 delete $2;
448         }
449         | METER '{' int '*' int '}'     {
450                 Meter_change_req *m = new Meter_change_req;
451                 m->set($3,$5);
452                 // sorry hw, i need meter at output of track,
453                 // but don-t know where to get it... statics should go.
454                 Midi_def::num_i_s = $3;
455                 Midi_def::den_i_s = $5;
456                 $$ = m;
457         }
458         | SKIP '{' duration_length '}' {
459                 Skip_req * skip_p = new Skip_req;
460                 skip_p->duration_ = *$3;
461                 delete $3;
462                 $$ = skip_p;
463         }
464         | CADENZA '{' int '}'   {
465                 $$ = new Cadenza_req($3);
466         }
467         | PARTIAL '{' duration_length '}'       {
468                 $$ = new Partial_measure_req(*$3);
469                 delete $3;
470         }
471         | STEM '{' int '}'              {
472                 $$ = get_stemdir_req($3);
473         }
474         | CLEF STRING {
475                 $$ = new Clef_change_req(*$2);
476                 delete $2;
477         }
478         | KEY '{' pitch_list '}'        {       
479                 Key_change_req *key_p= new Key_change_req;
480                 key_p->melodic_p_arr_ = *$3;
481                 $$ = key_p;
482                 delete $3;
483         }
484         | GROUPING '{' intastint_list '}' {
485                 $$ = get_grouping_req(*$3); delete $3;
486         }
487         ;
488
489 post_requests:
490         {
491                 assert(post_reqs.empty());
492         }
493         | post_requests post_request {
494                 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
495                 post_reqs.push($2);
496         }
497         | post_requests close_plet_parens INT '/' INT { 
498                 post_reqs.push( get_request($2) ); 
499                 req_defined_ch_c_l = lexer->here_ch_c_l();
500                 post_reqs.push( get_plet_request( $2, $3, $5 ) ); 
501         }
502         ;
503
504 post_request:
505         pure_post_request
506         | POST_REQUEST_IDENTIFIER       {
507                 $$ = $1->request(false)->clone();
508         }
509         ;
510
511 pure_post_request:
512         close_request_parens    { 
513                 $$ = get_request($1); 
514         }
515         | script_req
516         | textscript_req
517         | dynamic_req
518         ;
519
520
521 octave_quote:
522         '\''            { $$ = 1; }
523         | '`'           { $$ = -1; }
524         ;
525
526 octave_quotes:
527         /**/ { $$ = 0; }
528         | octave_quotes octave_quote{ $$ += $2; }
529         ;
530
531 /*
532         URG!!
533 */
534 steno_note_req:
535         MELODIC_REQUEST_IDENTIFIER      {
536                 $$ = new Note_req;
537                 * (Melodic_req *) $$ = *$1->request(false)->melodic();
538         }
539         | octave_quote steno_note_req   {  
540                 $2-> octave_i_ += $1;
541                 $$ = $2; //ugh!!
542         }
543         | '!' steno_note_req            {
544                 $$ = $2;
545                 $2->forceacc_b_ = ! $2->forceacc_b_;
546         } 
547         ;
548
549 melodic_request:
550         MELODIC '{' int int int int '}' {/* ugh */
551                 $$ = new Melodic_req;
552                 $$->octave_i_ = $3;
553                 $$->notename_i_ = $4;
554                 $$->accidental_i_ = $5;
555                 $$->forceacc_b_ = $6;
556         }
557         ;
558
559 dynamic_req:
560         DYNAMIC '{' int '}'     {
561                 Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
562                 ad_p ->loudness_ = $3;
563                 $$ =ad_p;
564         }
565         ;
566
567 close_plet_parens:
568         ']' {
569                 req_defined_ch_c_l = lexer->here_ch_c_l();
570                 $$ = ']';
571         }
572         ;
573
574 close_request_parens:
575         '('     { 
576                 $$='(';
577         }
578         | ']'   { 
579                 $$ = ']';
580         }
581         ;
582   
583 open_request_parens:
584         ')'     { 
585                 $$=')';
586         }
587         | '['   {
588                 $$='[';
589         }
590         ;
591
592 script_definition:
593         SCRIPT '{' script_body '}'      { $$ = $3; }
594         ;
595
596 script_body:
597         STRING int int int              {
598                 $$ = new Script_def(*$1,$2, $3,$4);
599                 delete $1;
600         }       
601         ;
602
603 textscript_req:
604         script_dir mudela_text          { $$ = get_text_req($1,$2); }
605         ;
606
607 mudela_text:
608         STRING                  { 
609                 defined_ch_c_l = lexer->here_ch_c_l();
610                 $$ = get_text(*$1); 
611                 delete $1;
612         }
613         ;
614
615 script_req:
616         script_dir mudela_script        { 
617                 $$ = get_script_req($1, $2);
618         }
619         ;
620
621 mudela_script:
622         IDENTIFIER              { $$ = $1->script(true); }
623         | script_definition             { $$ = $1; }
624         | '^'           { $$ = get_scriptdef('^'); }
625         | '+'           { $$ = get_scriptdef('+'); }
626         | '-'           { $$ = get_scriptdef('-'); }
627         | '|'           { $$ = get_scriptdef('|'); }
628         | 'o'           { $$ = get_scriptdef('o'); }
629         | '>'           { $$ = get_scriptdef('>'); }
630         | '.'           { $$ = get_scriptdef('.'); }
631         | DOTS          {
632                 if ( $1 > 1 ) 
633                     warning( "too many staccato dots", lexer->here_ch_c_l() );
634                 $$ = get_scriptdef('.');
635         }
636         | error {
637                 $$ = get_scriptdef('.');
638                 yyerrok;
639         }
640         ;
641
642 script_dir:
643         '_'     { $$ = -1; }
644         |'^'    { $$ = 1; }
645         |'-'    { $$ = 0; }
646         ;
647
648 pre_requests:
649         | pre_requests pre_request {
650                 pre_reqs.push($2);
651                 $2->defined_ch_c_l_ = lexer->here_ch_c_l();
652         }
653         ;
654
655 pre_request: 
656         open_request_parens     { 
657                 defined_ch_c_l = lexer->here_ch_c_l();
658                 $$ = get_request($1); 
659         }
660         ;
661
662 voice_command:
663         PLET    '{' INT '/' INT '}'             {
664                 set_plet($3,$5);
665         }
666         | DURATIONCOMMAND '{' STRING '}'        {
667                 set_duration_mode(*$3);
668                 delete $3;
669         }
670         | DURATIONCOMMAND '{' notemode_duration '}'     {
671                 set_default_duration($3);
672         }
673         | OCTAVECOMMAND '{' octave_quotes '}'   {
674                 set_default_octave($3);
675         }
676         | TEXTSTYLE STRING      {
677                 set_text_style(*$2);
678                 delete $2;
679         }
680         ;
681
682 duration_length:        
683         mudela_duration         {
684                 $$ = new Moment(wholes($1[0], $1[1]));
685         }
686         |int '*' mudela_duration        {
687                 $$ = new Moment(Rational($1) * wholes($3[0], $3[1]));
688         }
689         ;
690
691 notemode_duration:
692         explicit_duration
693         | default_duration
694         ;
695
696 mudela_duration:
697         int             {
698                 $$[0] = $1;
699                 $$[1] = 0;
700         }
701         | int DOTS      {
702                 $$[0] = $1;
703                 $$[1] = $2;
704         }
705         ;
706
707
708 explicit_duration:
709         INT             {
710                 last_duration($1);
711                 $$[0] = $1;
712                 $$[1] = 0;
713         }
714         | INT DOTS      {
715                 last_duration($1);
716                 $$[0] = $1;
717                 $$[1] = $2;
718         }
719         | DOTS  {
720                 get_default_duration($$);
721                 $$[1] = $1;
722         }
723         | INT '*' INT '/' INT {
724                 // ugh, must use Duration
725                 set_plet( $3, $5 );
726                 $$[ 0 ] = $1;
727                 $$[ 1 ] = 0;
728                 set_plet( 1, 1 );
729         }
730         ;
731
732 default_duration:
733         /* empty */     {
734                 get_default_duration($$);
735         }
736         ;
737
738
739 voice_elt:
740         steno_note_req notemode_duration                {
741                 $$ = get_note_element($1, $2);
742         }
743         | RESTNAME notemode_duration            {
744                 $$ = get_rest_element(*$1, $2);
745                 delete $1;
746         }
747         ;
748
749 lyrics_elt:
750         mudela_text notemode_duration                   {
751                 $$ = get_word_element($1, $2);
752         };
753
754 /*
755         UTILITIES
756  */
757 pitch_list:                     {
758                 $$ = new Array<Melodic_req*>;
759         }
760         | pitch_list MELODIC_REQUEST_IDENTIFIER {
761                 $$->push($2->request(false)->clone()->melodic());
762         }
763         ;
764
765 int:
766         real                    {
767                 $$ = int($1);
768                 if ( distance($1,Real(int($$)) ) > 1e-8)
769                         error( "integer expected", lexer->here_ch_c_l() );
770         }
771         ;
772
773 real:
774         INT                     {
775                 $$ = Real($1);
776         }
777         | REAL          {
778                 $$ = $1;
779         }
780         | REAL_IDENTIFIER               {
781                 $$ = * $1->real(0);             
782         }
783         ;
784         
785
786
787 dim:
788         real unit       { $$ = $1*$2; }
789         ;
790
791
792 unit:   CM_T            { $$ = 1 CM; }
793         |IN_T           { $$ = 1 INCH; }
794         |MM_T           { $$ = 1 MM; }
795         |PT_T           { $$ = 1 PT; }
796         ;
797         
798 /*
799         symbol tables
800 */
801 symtables:
802         SYMBOLTABLES '{' symtables_body '}'     { $$ = $3; }
803         ;
804
805 symtables_body:
806                         {
807                 $$ = new Lookup;
808         }
809         | IDENTIFIER            {
810                 $$ = new Lookup(*$1->lookup(true));
811         }
812         | symtables_body TEXID STRING           {
813                 $$->texsetting = *$3;
814                 delete $3;
815         }
816         | symtables_body STRING '=' symtable            {
817                 $$->add(*$2, $4);
818                 delete $2;
819         }
820         ;
821
822 symtable:
823         TABLE '{' symtable_body '}' { $$ = $3; }
824         ;
825
826 symtable_body:
827                                 { $$ = new Symtable; }
828         | symtable_body STRING  symboldef {
829                 $$->add(*$2, *$3);
830                 delete $2;
831                 delete $3;
832         }
833         ;
834
835 symboldef:
836         STRING  box             {
837                 $$ = new Symbol(*$1, *$2);
838                 delete $1;
839                 delete $2;
840         }
841         | STRING {
842                 Box b;
843                 $$ = new Symbol(*$1, b);
844                 delete $1;
845         }
846         ;
847
848 box:
849         dinterval dinterval     {
850                 $$ = new Box(*$1, *$2);
851                 delete $1;
852                 delete $2;
853         }
854         ;
855
856 dinterval: dim  dim             {
857                 $$ = new Interval($1, $2);      
858         }
859         ;
860
861 %%
862
863 void
864 yyerror(const char *s)
865 {
866         lexer->LexerError(s);
867
868         if ( fatal_error_i )
869                 exit( fatal_error_i );
870 }
871
872 void
873 parse_file(String init, String s)
874 {
875    *mlog << "Parsing ... ";
876    lexer = new My_flex_lexer;
877
878 #ifndef NPRINT
879    yydebug = !monitor->silence("InitParser") && check_debug;
880    lexer->set_debug( !monitor->silence("InitLexer") && check_debug);
881 #endif
882
883    lexer->new_input(init);
884    yyparse();
885
886 #ifndef NPRINT
887    if (!monitor->silence("InitDeclarations") && check_debug)
888         lexer->print_declarations();
889
890    yydebug = !monitor->silence("Parser") && check_debug;
891    lexer->set_debug( !monitor->silence("Lexer") && check_debug);
892 #endif
893
894    lexer->new_input(s);
895    yyparse();
896 #ifdef NPRINT
897    if (!monitor->silence("Declarations") && check_debug)
898         lexer->print_declarations();
899 #endif
900    delete lexer;
901    lexer = 0;
902
903    if(!define_spots.empty())
904         warning("Braces don't match.",0);
905 }
906
907 Paper_def*
908 default_paper()
909 {
910     return new Paper_def(
911         lexer->lookup_identifier("default_table")->lookup(true));
912 }
913
914