]> git.donarmstrong.com Git - lilypond.git/blob - parser.y
7e2be63a68bb279c649508c531ab22ddb4b37964
[lilypond.git] / parser.y
1 %{ // -*-Fundamental-*-
2 #include <iostream.h>
3
4 #include "lexer.hh"
5 #include "paper.hh"
6 #include "staff.hh"
7 #include "score.hh"
8 #include "main.hh"
9 #include "keyword.hh"
10 #include "scommands.hh"
11 #include "debug.hh"
12 #include "parseconstruct.hh"
13 #include "dimen.hh"
14 #include "identifier.hh"
15
16 #ifndef NDEBUG
17 #define YYDEBUG 1
18 #endif
19
20 %}
21
22
23 %union {    
24     Real real;
25     Command *command;
26     Identifier *id;    
27     Score_commands *scommands;
28     Voice *voice;    
29     Voice_element *el;  
30     Staff *staff;    
31     String *string;
32     Score *score;
33     const char *consstr;
34     Paperdef *paper;
35     int i;
36 }
37
38 %token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
39 %token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS
40 %token MELODICSTAFF
41
42 %type <consstr> unit
43 %token <id>  IDENTIFIER
44 %token <string> NEWIDENTIFIER 
45 %token <string> PITCH DURATION RESTNAME
46 %token <real> REAL
47 %token <string> STRING
48 %type <id> declaration 
49 %type <paper> paper_block paper_body
50 %type <real> dim
51 %type <voice> voice_block voice_body voice_elts voice_elts_dollar
52 %type <el> voice_elt
53 %type <command> score_command
54 %type <score> score_block score_body
55 %type <staff> staff_block  rhythmstaff_block rhythmstaff_body
56 %type <staff> melodicstaff_block melodicstaff_body staffdecl
57 %type <i> int
58 %type <scommands> score_commands_block score_commands_body
59
60 %%
61
62 mudela: /* empty */
63         | mudela score_block { 
64                 add_score($2);
65         }
66         | mudela add_declaration {      }
67         ;
68
69 add_declaration: declaration    {
70                 add_identifier($1);
71         }
72         ;
73
74 declaration:
75         NEWIDENTIFIER '=' staff_block  {
76                 $$ = new Staff_id(*$1, $3);
77                 delete $1; // this sux
78         }
79         ;
80
81
82 score_block: SCORE '{' score_body '}'   { $$ = $3; }
83         ;
84
85 score_body:             { $$ = new Score; } 
86         | score_body staff_block        { $$->add($2); }
87         | score_body score_commands_block       { $$->set($2); }
88         | score_body paper_block                { $$->set($2);  }
89         ;
90 score_commands_block:
91         COMMANDS '{' score_commands_body '}' { $$ =$3;}
92         ;
93
94 score_commands_body:                    { $$ = new Score_commands; }
95         | score_commands_body score_command             {
96                 $$->parser_add($2);
97         }
98         ;
99
100 paper_block:
101         PAPER '{' paper_body '}'        { $$ = $3; }
102         ;
103
104 paper_body:
105         /* empty */                     { $$ = new Paperdef; }
106         | paper_body WIDTH dim          { $$->linewidth = $3;}
107         | paper_body OUTPUT STRING      { $$->outfile = *$3;
108                 delete $3;
109         }
110         | paper_body UNITSPACE dim      { $$->whole_width = $3; }
111         ;
112
113 dim:
114         REAL unit       { $$ = convert_dimen($1,$2); }
115         ;
116
117
118 unit:   CM              { $$ = "cm"; }
119         |IN             { $$ = "in"; }
120         |MM             { $$ = "mm"; }
121         |PT             { $$ = "pt"; }
122         ;
123         
124 /*
125         staff
126 */
127 staff_block:
128         staffdecl
129         | rhythmstaff_block
130         | melodicstaff_block
131         ;
132
133 staffdecl: STAFF '{' IDENTIFIER '}' { $$ = $3->staff(); }
134         ;
135
136 rhythmstaff_block:
137         RHYTHMSTAFF '{' rhythmstaff_body '}'    { $$ = $3; }
138         ;
139
140 rhythmstaff_body:
141         /* empty */                     { $$ = get_new_rhythmstaff(); }
142         | rhythmstaff_body voice_block  { $$->add_voice($2); }  
143         ;
144
145 melodicstaff_block:
146         MELODICSTAFF '{' melodicstaff_body '}'  { $$ = $3; }
147         ;
148
149 melodicstaff_body:
150         /* empty */                     { $$ = get_new_melodicstaff(); }
151         | melodicstaff_body voice_block         { $$->add_voice($2); }  
152         ;
153
154 /*
155         voice
156 */
157 voice_block:
158         VOICE '{' voice_body '}'        { $$ = $3; }
159         ;
160
161
162 voice_body:
163         REAL voice_elts_dollar { $$ = $2; $$->start = $1; }
164         | voice_elts_dollar     { $$ = $1; }
165         ;
166
167 voice_elts_dollar:
168         '$' voice_elts '$'  { $$ = $2; }
169         ;
170
171 voice_elts:
172         /* empty */             {
173             $$ = new Voice;
174         }
175         | voice_elts voice_elt {
176             $$->add($2);
177         }
178         ;
179
180 voice_elt:
181         PITCH DURATION                  { $$ = get_note_element(*$1, *$2);
182
183         }
184         |  RESTNAME DURATION            { $$ = get_rest_element(*$1, *$2);
185
186         }
187         ;
188
189 score_command:
190         SKIP int ':' REAL               {
191                 $$ = get_skip_command($2, $4);
192         }
193         | METER  int int                {
194                 $$ = get_meterchange_command($2, $3);
195         }
196 /*      | PARTIALMEASURE REAL           {
197                 $$ = get_partial_command($2);
198         }*/
199         ;
200         
201
202 int:
203         REAL                    {
204                 $$ = int($1);
205                 if (ABS($1-Real(int($$))) > 1e-8)
206                         yyerror("expecting integer number");
207                 
208         }
209         ;
210
211 %%
212
213 void
214 parse_file(String s)
215 {
216    *mlog << "Parsing ... ";
217 #ifdef YYDEBUG
218    yydebug = !monitor.silence("Parser");
219 #endif
220    new_input(s);
221    yyparse();
222    *mlog << "\n";
223 }