]> git.donarmstrong.com Git - lilypond.git/blob - parser.y
release: 0.0.4
[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 "debug.hh"
11 #include "parseconstruct.hh"
12 #include "dimen.hh"
13
14 #ifndef NDEBUG
15 #define YYDEBUG 1
16 #endif
17
18 %}
19
20
21 %union {    
22     Real real;
23     Command *command;
24     Identifier *id;    
25
26     Voice *voice;    
27     Voice_element *el;  
28     Staff *staff;    
29     String *string;
30     Score *score;
31     const char *consstr;
32     Paperdef *paper;
33     int i;
34 }
35
36 %token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
37 %token CM IN PT MM PAPER WIDTH METER
38
39 %type <consstr> unit
40 %token <id> IDENTIFIER
41 %token <string> PITCH DURATION RESTNAME
42 %token <real> REAL
43 %token <string> STRING
44
45 %type <paper> paper_block paper_body
46 %type <real> dim
47 %type <voice> voice_block voice_body voice_elts voice_elts_dollar
48 %type <el> voice_elt
49 %type <command> score_command
50 %type <score> score_block score_body
51 %type <staff> staff_block  rhythmstaff_block rhythmstaff_body
52 %type <i> int
53
54
55 %%
56
57 mudela: /* empty */
58         | score_block { 
59                 add_score($1);
60         }
61         ;
62
63
64 score_block: SCORE '{' score_body '}'   { $$ = $3; }
65         ;
66
67 score_body:             { $$ = new Score; } 
68         | score_body staff_block        { $$->add($2); }
69         | score_body score_command      { $$->add($2); }
70         | score_body paper_block        { delete $$->paper;
71                 $$->paper = $2;
72         }
73         ;
74
75 paper_block:
76         PAPER '{' paper_body '}'        { $$ = $3; }
77         ;
78
79 paper_body:
80         /* empty */                     { $$ = new Paperdef; }
81         | paper_body WIDTH dim          { $$->width = $3;}
82         | paper_body OUTPUT STRING      { $$->outfile = *$3;
83                 delete $3;
84         }
85         ;
86
87 dim:
88         REAL unit       { $$ = convert_dimen($1,$2); }
89         ;
90
91
92 unit:   CM              { $$ = "cm"; }
93         |IN             { $$ = "in"; }
94         |MM             { $$ = "mm"; }
95         |PT             { $$ = "pt"; }
96         ;
97         
98
99 staff_block:
100         rhythmstaff_block
101         ;
102
103 rhythmstaff_block:
104         RHYTHMSTAFF '{' rhythmstaff_body '}'    { $$ = $3; }
105         ;
106
107 rhythmstaff_body:
108         /* empty */                     { $$ = get_new_rhythmstaff(); }
109         | rhythmstaff_body voice_block  { $$->add_voice($2); }  
110         ;
111
112 voice_block:
113         VOICE '{' voice_body '}'        { $$ = $3; }
114         ;
115
116
117 voice_body:
118         REAL voice_elts_dollar { $$ = $2; $$->start = $1; }
119         | voice_elts_dollar     { $$ = $1; }
120         ;
121
122 voice_elts_dollar:
123         '$' voice_elts '$'  { $$ = $2; }
124         ;
125
126 voice_elts:
127         /* empty */             {
128             $$ = new Voice;
129         }
130         | voice_elts voice_elt {
131             $$->add($2);
132         }
133         ;
134
135 voice_elt:
136         PITCH DURATION                  { $$ = get_note_element(*$1, *$2);
137
138         }
139         |  RESTNAME DURATION            { $$ = get_rest_element(*$1, *$2);
140
141         }
142         ;
143
144 score_command:
145         BAR REAL                        {
146                 $$ = get_bar_command($2);
147         }
148         | METER REAL int int            {
149                 $$ = get_meter_command($2, $3, $4);
150         }
151         ;
152
153 int:
154         REAL                    {
155                 $$ = int($1);
156                 if (ABS($1-Real(int($$))) > 1e-8)
157                         yyerror("expecting integer number");
158                 
159         }
160         ;
161
162 %%
163
164 void
165 parse_file(String s)
166 {
167    *mlog << "Parsing ... ";
168 #ifdef YYDEBUG
169    yydebug = !monitor.silence("Parser");
170 #endif
171    new_input(s);
172    yyparse();
173 }