1 %{
2
3 #include <string>
4 #include <iostream>
5 #include <vector>
6 #include <assert.h>
7
8 #include "guidoelement.h"
9 #include "gmnreader.h"
10 #include "guidorational.h"
11
12 #include "guidoparse.h++"
13 #include "guidolex.c++"
14
15 int guidoarerror(const char*s);
guidoarwrap()16 int guidoarwrap() { return(1); }
17
18 extern guido::gmnreader* gReader;
19
vadd(std::vector<guido::Sguidoelement> * v1,std::vector<guido::Sguidoelement> * v2)20 static void vadd (std::vector<guido::Sguidoelement>* v1, std::vector<guido::Sguidoelement>* v2)
21 {
22 for (std::vector<guido::Sguidoelement>::iterator i = v2->begin(); i != v2->end(); i++)
23 v1->push_back(*i);
24 }
25
26 //#define parseDebug
27
28 #ifdef parseDebug
29 #define debug(msg) cout << msg << endl;
30 #define vdebug(msg,v) cout << msg << " " << v << endl;
31 #else
32 #define debug(msg)
33 #define vdebug(msg, v)
34 #endif
35
36 #define addElt(to,elt) (to)->push(*elt); delete elt
37
38 using namespace std;
39
40 namespace guido
41 {
42
43 %}
44
45
46 //%pure_parser
47
48 %union {
49 long int num;
50 float real;
51 const char* token;
52 std::string* str;
53 char c;
54 guido::Sguidoelement * elt;
55 guido::Sguidoattribute* attr;
56 std::vector<guido::Sguidoelement>* velt;
57 std::vector<guido::Sguidoattribute>* vattr;
58 guido::rational * r;
59 }
60
61 /*------------------------------ numbers ------------------------------*/
62 %token NUMBER
63 %token PNUMBER
64 %token NNUMBER
65 %token FLOAT
66
67 /*------------------------------ markers ------------------------------*/
68 %token STARTCHORD
69 %token ENDCHORD
70 %token STARTSEQ
71 %token ENDSEQ
72 %token STARTPARAM
73 %token ENDPARAM
74 %token STARTRANGE
75 %token ENDRANGE
76 %token SEP
77 %token IDSEP
78
79 /*------------------------------ tags ------------------------------*/
80 %token BAR
81 %token TAGNAME
82 %token ID
83
84 /*------------------------------ notes ------------------------------*/
85 %token DIATONIC
86 %token CHROMATIC
87 %token SOLFEGE
88 %token EMPTY
89 %token REST
90 %token DOT
91 %token DDOT
92 %token SHARP
93 %token FLAT
94
95 /*------------------------------ misc ------------------------------*/
96 %token MLS
97 %token SEC
98 %token UNIT
99 %token MULT
100 %token DIV
101 %token EQUAL
102 %token STRING
103 %token EXTRA
104
105 %type <num> NUMBER PNUMBER NNUMBER
106 %type <real> FLOAT floatn
107 %type <token> TAGNAME ID MLS SEC STRING UNIT DIATONIC CHROMATIC SOLFEGE REST
108 %type <token> EMPTY DOT DDOT EXTRA
109 %type <c> STARTCHORD ENDCHORD STARTSEQ ENDSEQ STARTPARAM ENDPARAM STARTRANGE ENDRANGE SEP IDSEP BAR
110 %type <c> SHARP FLAT MULT DIV EQUAL
111
112 %type <str> notename noteid tagname id
113 %type <num> dots accidentals accidental octave number pnumber nnumber signednumber
114 %type <r> duration
115 %type <elt> score voice note rest music chord tag tagid positiontag rangetag rangechordtag
116 %type <attr> tagarg tagparam
117 %type <velt> symbols voicelist chordsymbol chordsymbols taglist tagchordsymbol
118 %type <vattr> tagparams
119
120 %%
121
122 start : score {delete $1;}
123 ;
124
125 //_______________________________________________
126 score : STARTCHORD ENDCHORD { debug("new score"); $$ = gReader->newScore(); }
127 | STARTCHORD voicelist ENDCHORD { debug("score voicelist"); $$ = gReader->newScore(); addElt(*$$, $2); }
128 | voice { debug("score voice"); $$ = gReader->newScore(); addElt(*$$, $1); }
129 ;
130
131 voicelist : voice { debug("new voicelist"); $$ = new vector<Sguidoelement>; $$->push_back (*$1); delete $1; }
132 | voicelist SEP voice { debug("add voicelist"); $$ = $1; $$->push_back (*$3); delete $3; }
133 ;
134
135 voice : STARTSEQ symbols ENDSEQ { debug("new voice"); $$ = gReader->newVoice(); addElt(*$$, $2); }
136 ;
137
138 symbols : { debug("new symbols"); $$ = new vector<Sguidoelement>; }
139 | symbols music { debug("add music"); $$ = $1; $$->push_back(*$2); delete $2; }
140 | symbols tag { debug("add tag"); $$ = $1; $$->push_back(*$2); delete $2; }
141 | symbols chord { debug("add chord"); $$ = $1; $$->push_back(*$2); delete $2; }
142 ;
143
144 //_______________________________________________
145 // tags description
146 tag : positiontag { debug("position tag "); $$ = $1; }
147 | rangetag { debug("range tag "); $$ = $1; }
148 ;
149
150 positiontag : tagid { debug("new position tag "); $$ = $1; }
151 | tagid STARTPARAM tagparams ENDPARAM { debug("new tag + params"); $$ = $1; (*$1)->add (*$3); delete $3; }
152 ;
153
154 rangetag : positiontag STARTRANGE symbols ENDRANGE { debug("new range tag "); $$ = $1; (*$1)->push (*$3); delete $3; }
155 ;
156
157 tagname : TAGNAME { debug("tag name "); $$ = new string(guidoartext); }
158 ;
159
160 tagid : tagname { vdebug("new tag", *$1); $$ = gReader->newTag(*$1, 0); delete $1; if (!$$) { guidoarerror("unknown tag"); YYERROR;} }
161 | tagname IDSEP NUMBER { debug("new tag::id"); $$ = gReader->newTag(*$1, $2); delete $1; if (!$$) { guidoarerror("unknown tag"); YYERROR;} }
162 | BAR { debug("new bar"); $$ = gReader->newTag("bar", 0); }
163 ;
164
165 tagarg : signednumber { debug("new signednumber arg"); $$ = gReader->newAttribute($1); }
166 | floatn { debug("new FLOAT arg"); $$ = gReader->newAttribute($1); }
167 | signednumber UNIT { debug("new signednumber UNIT arg"); $$ = gReader->newAttribute($1); (*$$)->setUnit(guidoartext); }
168 | floatn UNIT { debug("new FLOAT UNIT arg"); $$ = gReader->newAttribute($1); (*$$)->setUnit(guidoartext); }
169 | STRING { debug("new STRING arg"); $$ = gReader->newAttribute(guidoartext, true); }
170 | id { debug("new ID arg"); $$ = gReader->newAttribute(*$1, false); delete $1; }
171 ;
172
173 tagparam : tagarg { $$ = $1; }
174 | id EQUAL tagarg { $$ = $3; (*$3)->setName(*$1); delete $1; }
175 ;
176
177 tagparams : tagparam { $$ = new vector<Sguidoattribute>; $$->push_back(*$1); delete $1; }
178 | tagparams SEP tagparam { $$ = $1; $$->push_back(*$3); delete $3; }
179 ;
180
181
182 //_______________________________________________
183 // chord description
184
185 chord : STARTCHORD chordsymbols ENDCHORD { debug("new chord"); $$ = gReader->newChord(); (*$$)->push(*$2); delete $2; }
186 ;
187
188 chordsymbols: tagchordsymbol { $$ = new vector<Sguidoelement>; vadd($$, $1); delete $1; }
189 | chordsymbols SEP tagchordsymbol { $$ = $1; vadd($$, $3); delete $3; }
190 ;
191
192 tagchordsymbol: chordsymbol { $$ = $1;}
193 | taglist chordsymbol { $$ = $1; vadd($$, $2); delete $2; }
194 | chordsymbol taglist { $$ = $1; vadd($$, $2); delete $2; }
195 | taglist chordsymbol taglist { $$ = $1; vadd($$, $2); delete $2; vadd($$, $3); delete $3; }
196 ;
197
198 chordsymbol : music { $$ = new vector<Sguidoelement>; $$->push_back(*$1); delete $1; }
199 | rangechordtag { $$ = new vector<Sguidoelement>; $$->push_back(*$1); delete $1; }
200 ;
201
202 rangechordtag : positiontag STARTRANGE tagchordsymbol ENDRANGE { debug("range chord tag"); $$ = $1; (*$$)->push(*$3); delete $3; }
203 ;
204
205 taglist : positiontag { debug("new taglist 1"); $$ = new vector<Sguidoelement>; $$->push_back(*$1); delete $1; }
206 | taglist positiontag { debug("new taglist 2"); $$ = $1; $$->push_back(*$2); delete $2; }
207 ;
208
209 //_______________________________________________
210 // notes description
211
212 music : note { $$ = $1; }
213 | rest { $$ = $1; }
214 ;
215
216 rest : REST duration dots { debug("new rest 1"); $$ = gReader->newRest($2, $3); delete $2; }
217 | REST STARTPARAM NUMBER ENDPARAM duration dots { debug("new rest 2"); $$ = gReader->newRest($5, $6); delete $5; }
218 ;
219
220 note : noteid octave duration dots { debug("new note v1"); $$ = gReader->newNote(*$1, 0, $2, $3, $4); delete $1; delete $3; }
221 | noteid accidentals octave duration dots { debug("new note v2"); $$ = gReader->newNote(*$1, $2, $3, $4, $5); delete $1; delete $4; }
222 ;
223
224 noteid : notename { vdebug("notename", *$1); $$ = $1; }
225 | notename STARTPARAM NUMBER ENDPARAM { $$ = $1; }
226 ;
227
228 notename : DIATONIC { debug("new diatonic note"); $$ = new string(guidoartext); }
229 | CHROMATIC { debug("new chromatic note"); $$ = new string(guidoartext); }
230 | SOLFEGE { debug("new solfege note"); $$ = new string(guidoartext); }
231 | EMPTY { debug("new empty note"); $$ = new string(guidoartext); }
232 ;
233
234 accidentals : accidental { debug("accidental"); $$ = $1; }
235 | accidentals accidental { debug("accidentals"); $$ = $1 + $2; }
236 ;
237
238 accidental : SHARP { debug("sharp"); $$ = 1; }
239 | FLAT { debug("flat"); $$ = -1; }
240 ;
241
242 octave : { debug("no octave"); $$ = -1000; } // implicit duration
243 | signednumber { debug("octave"); $$ = $1; }
244 ;
245
246 duration : { debug("implicit duration"); $$ = new rational(-1, 1); } // implicit duration
247 | MULT number DIV number { debug("duration ./."); $$ = new rational($2, $4); }
248 | MULT number { debug("duration *"); $$ = new rational($2, 1); }
249 | DIV number { debug("duration /"); $$ = new rational(1, $2); }
250 ;
251
252 dots : { debug("dots 0"); $$ = 0; }
253 | DOT { debug("dots 1"); $$ = 1; }
254 | DDOT { debug("dots 2"); $$ = 2; }
255 ;
256
257 //_______________________________________________
258 // misc
259
260 id : ID { $$ = new string(guidoartext); }
261 ;
262 number : NUMBER { vdebug("NUMBER", guidoartext); $$ = atol(guidoartext); }
263 ;
264 pnumber : PNUMBER { vdebug("NUMBER", guidoartext); $$ = atol(guidoartext); }
265 ;
266 nnumber : NNUMBER { vdebug("NUMBER", guidoartext); $$ = atol(guidoartext); }
267 ;
268 floatn : FLOAT { $$ = atof(guidoartext); }
269 ;
270 signednumber: number { $$ = $1; }
271 | pnumber { $$ = $1; }
272 | nnumber { $$ = $1; }
273 ;
274 %%
275
276 } // namespace
277
guidoarerror(const char * s)278 int guidoarerror(const char*s) {
279 YY_FLUSH_BUFFER;
280 return gReader->error(s, guidoarlineno);
281 }
282