1 %
{ // -*-Fundamental-*-
4 parser.y -- YACC parser for mudela
6 source file of the GNU LilyPond music typesetter
8 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
9 Jan Nieuwenhuizen <jan@digicash.com>
15 #define MUDELA_VERSION "0.1.9"
18 #include "translation-property.hh"
19 #include "script-def.hh"
20 #include "symtable.hh"
23 #include "my-lily-lexer.hh"
24 #include "paper-def.hh"
25 #include "midi-def.hh"
29 #include "parseconstruct.hh"
31 #include "identifier.hh"
32 #include "command-request.hh"
33 #include "musical-request.hh"
34 #include "my-lily-parser.hh"
35 #include "text-def.hh"
36 #include "translator-group.hh"
38 #include "music-list.hh"
40 #include "duration-convert.hh"
41 #include "change-translator.hh"
43 int const GUESS_PLET
= 5;
44 int guess_plet_a
[GUESS_PLET
] =
57 #define YYERROR_VERBOSE 1
59 #define YYPARSE_PARAM my_lily_parser_l
60 #define YYLEX_PARAM my_lily_parser_l
61 #define THIS ((My_lily_parser *) my_lily_parser_l)
63 #define yyerror THIS->parser_error
69 Array
<Interval
>* intarr
;
70 Array
<Melodic_req
*> *melreqvec
;/* should clean up naming */
71 Array
<String
> * strvec
;
79 Music_list
*musiclist
;
86 Music_output_def
* outputdef
;
93 General_script_def
* script
;
98 Symtables
* symtables
;
110 yylex (YYSTYPE *s
, void * v_l
)
112 My_lily_parser
*pars_l
= (My_lily_parser
*) v_l
;
113 My_lily_lexer
* lex_l
= pars_l
->lexer_p_
;
115 lex_l
->lexval_l
= (void*) s
;
116 return lex_l
->yylex ();
124 /* tokens which are not keywords */
148 %token MELODIC_REQUEST
179 %token E_EXCLAMATION E_SMALLER E_BIGGER E_CHAR
183 %token
<melreq
> NOTENAME_ID
184 %token
<id
> DURATION_IDENTIFIER
185 %token
<id
> IDENTIFIER
186 %token
<id
> MELODIC_REQUEST_IDENTIFIER
187 %token
<id
> MUSIC_IDENTIFIER
188 %token
<id
> VOICE_IDENTIFIER
189 %token
<id
> POST_REQUEST_IDENTIFIER
190 %token
<id
> SCRIPT_IDENTIFIER
191 %token
<id
> COMMAND_IDENTIFIER
192 %token
<id
> REAL_IDENTIFIER
193 %token
<id
> TRANS_IDENTIFIER
194 %token
<id
> INT_IDENTIFIER
195 %token
<id
> SCORE_IDENTIFIER
196 %token
<id
> MIDI_IDENTIFIER
197 %token
<id
> PAPER_IDENTIFIER
198 %token
<id
> REQUEST_IDENTIFIER
200 %token
<string> DURATION RESTNAME
201 %token
<string> STRING
203 %token
<i
> POST_QUOTES
204 %token
<i
> PRE_QUOTES
206 %type
<outputdef
> output_def
207 %type
<header
> mudela_header mudela_header_body
209 %type
<i
> open_request_parens close_request_parens
210 %type
<c
> open_abbrev_parens
211 %type
<i
> open_plet_parens close_plet_parens
212 %type
<music
> simple_element music_elt full_element lyrics_elt command_elt
213 %type
<i
> abbrev_type
214 %type
<i
> int unsigned
216 %type
<id
> identifier_init
217 %type
<duration
> explicit_steno_duration notemode_duration
218 %type
<duration
> entered_notemode_duration explicit_duration
219 %type
<interval
> dinterval
220 %type
<intvec
> intastint_list
221 %type
<lookup
> symtables symtables_body
222 %type
<melreq
> melodic_request steno_melodic_req
223 %type
<notereq
> steno_note_req
224 %type
<melreqvec
> pitch_list
225 %type
<midi
> midi_block midi_body
226 %type
<moment
> duration_length
228 %type
<scalar
> scalar
229 %type
<music
> Music transposed_music
230 %type
<music
> property_def translator_change
231 %type
<musiclist
> Voice Voice_body
232 %type
<chord
> Chord Chord_body
233 %type
<paper
> paper_block paper_body
234 %type
<real
> dim real
236 %type
<request
> abbrev_command_req
237 %type
<request
> post_request structured_post_request
238 %type
<pair
> plet_fraction
239 %type
<request
> command_req verbose_command_req
240 %type
<request
> script_req dynamic_req
241 %type
<score
> score_block score_body
242 %type
<intarr
> shape_array
243 %type
<script
> script_definition script_body mudela_script gen_script_def
244 %type
<textdef
> text_def finger
245 %type
<string> script_abbreviation
246 %type
<symbol
> symboldef
247 %type
<symtable
> symtable symtable_body
248 %type
<trans
> translator_spec translator_spec_body
249 %type
<tempo
> tempo_request
250 %type
<string> concat_strings
258 | mudela mudela_header
{
259 delete THIS
->default_header_p_
;
260 THIS
->default_header_p_
= $2;
262 | mudela score_block
{
265 | mudela add_declaration
{ }
267 | mudela check_version
{ }
268 | mudela add_notenames
{ }
273 if
(String
(*$2) != MUDELA_VERSION
) {
274 if
(THIS
->ignore_version_b_
) {
275 THIS
->here_input
().
error ("Incorrect mudela version");
277 THIS
->fatal_error_i_
= 1;
278 THIS
->parser_error
("Incorrect mudela version");
285 NOTENAMES
'{' notenames_body
'}'
290 | notenames_body CLEAR
{
291 THIS
->clear_notenames
();
293 | notenames_body STRING
'=' melodic_request
{
294 THIS
->add_notename
(*$2, $4);
303 | mudela_header_body STRING
'=' concat_strings
';' {
311 HEADER
'{' mudela_header_body
'}' {
321 | concat_strings STRING
{
332 THIS
->remember_spot
();
334 /* cont */ '=' identifier_init
{
335 THIS
->lexer_p_
->set_identifier
(*$1, $4);
336 $4->init_b_
= THIS
->init_parse_b_
;
337 $4->set_spot
(THIS
->pop_spot
());
343 $$
= new Score_id
($1, SCORE_IDENTIFIER
);
347 $$
= new Paper_def_id
($1, PAPER_IDENTIFIER
);
351 $$
= new Midi_def_id
($1, MIDI_IDENTIFIER
);
354 | script_definition
{
355 $$
= new Script_id
($1, SCRIPT_IDENTIFIER
);
359 $$
= new Music_id
($1, MUSIC_IDENTIFIER
);
363 $$
= new Lookup_id
($1, IDENTIFIER
);
367 $$
= new Real_id
(new Real
($1), REAL_IDENTIFIER
);
371 $$
= new Int_id
(new
int ($1), INT_IDENTIFIER
);
374 $$
= new Request_id
($1, POST_REQUEST_IDENTIFIER
);
377 $$
= new Request_id
($1, MELODIC_REQUEST_IDENTIFIER
);
381 $$
= new Translator_id
($1, TRANS_IDENTIFIER
);
383 | explicit_duration
{
384 $$
= new Duration_id
($1, DURATION_IDENTIFIER
);
391 TRANSLATOR
'{' translator_spec_body
'}'
395 translator_spec_body:
397 $$
= $1->translator
();
398 $$
-> set_spot
(THIS
->here_input
());
401 $$
= get_translator_l
(*$2)->clone
();
402 $$
->set_spot
(THIS
->here_input
());
405 | translator_spec_body STRING
'=' scalar
';' {
406 $$
-> set_property
(*$2, *$4);
410 | translator_spec_body CONSISTS STRING
';' {
411 $$
->group_l
()->consists_str_arr_.push
(*$3);
414 | translator_spec_body ACCEPTS STRING
';' {
415 $$
->group_l
()->accepts_str_arr_.push
(*$3);
424 SCORE
{ THIS
->remember_spot
();
425 THIS
->error_level_i_
=0;
427 /*cont*/ '{' score_body
'}' {
429 $$
->set_spot
(THIS
->pop_spot
());
430 if
(!$$
->def_p_arr_.size
())
431 $$
->add
(THIS
->default_paper
());
433 /* handle error levels. */
434 $$
->errorlevel_i_
= THIS
->error_level_i_
;
435 THIS
->error_level_i_
= 0;
436 if
(!$$
->header_p_
&& THIS
->default_header_p_
)
437 $$
->header_p_
= new Header
(*THIS
->default_header_p_
);
447 | score_body mudela_header
{
452 $2->warning
("More than one music block");
455 | score_body output_def
{
473 /* */ { $$
=new Array
<int>; }
474 | intastint_list
int '*' int {
475 $$
->push
($2); $$
->push
($4);
485 '{' paper_body
'}' { $$
= $3; }
490 $$
= THIS
->default_paper
();
493 $$
= $1->paperdef
();
495 | paper_body OUTPUT STRING
';' {
496 $$
->outfile_str_
= *$3;
499 | paper_body symtables
{ $$
->set
($2); }
500 | paper_body STRING
'=' dim
';' {
501 $$
->set_var
(*$2, $4);
503 | paper_body STRING
'=' real
';' {
504 $$
->set_var
(*$2, $4);
506 | paper_body STRING
'=' translator_spec
{
507 $$
-> assign_translator
(*$2, $4);
510 | paper_body SHAPE
'=' shape_array
';' {
511 $$
->shape_int_a_
= *$4;
521 $$
= new Array
<Interval
>;
523 | shape_array dim dim
{
524 $$
->push
(Interval
($2, $2 + $3));
533 '{' midi_body
'}' { $$
= $3; }
536 midi_body: /* empty */ {
537 $$
= THIS
->default_midi
();
539 | midi_body STRING
'=' translator_spec
{
540 $$
-> assign_translator
(*$2, $4);
543 | midi_body OUTPUT STRING
';' {
544 $$
->outfile_str_
= *$3;
547 | midi_body tempo_request
';' {
548 $$
->set_tempo
($2->dur_.length
(), $2->metronome_i_
);
557 TEMPO entered_notemode_duration
'=' unsigned {
561 $$
-> metronome_i_
= $4;
578 $$
->set_spot
(THIS
->here_input
());
586 full_element
{ $$
= $1; }
587 | TYPE STRING Music
{
589 $$
->translator_type_str_
= *$2;
592 | TYPE STRING
'=' STRING Music
{
594 $$
->translator_type_str_
= *$2;
595 $$
->translator_id_str_
= *$4;
601 | transposed_music
{ $$
= $1; }
602 | MUSIC_IDENTIFIER
{ $$
= $1->music
(); }
603 | MUSIC_IDENTIFIER
';' { $$
= $1->music
(); }
605 { THIS
->lexer_p_
->push_note_state
(); }
607 { $$
=$3; THIS
->lexer_p_
->pop_state
(); }
610 { THIS
->lexer_p_
->push_lyric_state
(); }
612 { $$
= $3; THIS
->lexer_p_
->pop_state
(); }
618 TRANSLATOR STRING
'=' STRING
{
619 Change_translator
* t
= new Change_translator
;
620 t
-> change_to_type_str_
= *$2;
621 t
-> change_to_id_str_
= *$4;
624 $$
->set_spot
(THIS
->here_input
());
631 PROPERTY STRING
'.' STRING
'=' scalar
{
632 Translation_property
*t
= new Translation_property
;
633 t
-> translator_type_str_
= *$2;
637 $$
->set_spot
(THIS
->here_input
());
645 STRING
{ $$
= new Scalar
(*$1); delete
$1; }
646 |
int { $$
= new Scalar
($1); }
651 '<' Chord_body
'>' { $$
= $2; }
652 | MULTI
unsigned Chord
{
654 $$
->multi_level_i_
=$2;
661 $$
-> multi_level_i_
= 1;
662 $$
->set_spot
(THIS
->here_input
());
670 TRANSPOSE steno_melodic_req Music
{
672 $$
-> transpose
($2);
683 pre_requests simple_element post_requests
{
684 THIS
->add_requests
((Chord
*)$2);//ugh
688 | voice_command
';' { $$
= 0; }
698 $$
= new Request_chord
;
699 $$
-> set_spot
(THIS
->here_input
());
700 $1-> set_spot
(THIS
->here_input
());
701 ((Chord
*)$$
) ->add
($1);//ugh
708 | verbose_command_req
';' { $$
= $1; }
713 $$
= new Barcheck_req
;
715 | COMMAND_IDENTIFIER
{
722 $$
= new Bar_req
(*$2);
725 | METER
unsigned '/' unsigned {
726 Meter_change_req
*m
= new Meter_change_req
;
730 | SKIP duration_length
{
731 Skip_req
* skip_p
= new Skip_req
;
732 skip_p
->duration_.set_plet
($2->num
(),
742 $$
= new Cadenza_req
($2);
744 | PARTIAL duration_length
{
745 $$
= new Partial_measure_req
(*$2);
749 $$
= new Clef_change_req
(*$2);
753 Key_change_req
*key_p
= new Key_change_req
;
754 key_p
->melodic_p_arr_
= *$2;
758 | GROUPING intastint_list
{
759 $$
= get_grouping_req
(*$2); delete
$2;
765 assert
(THIS
->post_reqs.empty
());
767 | post_requests structured_post_request
{
768 $2->set_spot
(THIS
->here_input
());
769 THIS
->post_reqs.push
($2);
771 | post_requests close_request_parens
{
772 Array
<Request
*>& r
= *THIS
->get_parens_request
($2);
773 for
(int i
= 0; i
< r.size
(); i
++ )
774 r
[i
]->set_spot
(THIS
->here_input
());
775 THIS
->post_reqs.concat
(r
);
780 structured_post_request:
786 POST_REQUEST_IDENTIFIER
{
787 $$
= (Request
*)$1->request
();
793 Abbreviation_req
* a
= new Abbreviation_req
;
806 $$
= $1->clone
()->musical
()->melodic
();
807 $$
->octave_i_
+= THIS
->default_octave_i_
;
809 | steno_melodic_req POST_QUOTES
{
810 $$
-> octave_i_
+= $2;
812 | PRE_QUOTES steno_melodic_req
{
814 $2-> octave_i_
-= $1;
821 * (Melodic_req
*) $$
= *$1;
824 | steno_note_req
'!' {
825 $$
->forceacc_b_
= ! $$
->forceacc_b_
;
827 /* have to duration here. */
831 MELODIC_REQUEST
'{' int int int '}' {/* ugh */
832 $$
= new Melodic_req
;
834 $$
->notename_i_
= $4;
835 $$
->accidental_i_
= $5;
840 DURATION
'{' int unsigned '}' {
848 ABSDYNAMIC
'{' unsigned '}' {
849 Absolute_dynamic_req
*ad_p
= new Absolute_dynamic_req
;
850 ad_p
->loudness_
= (Dynamic_req
::Loudness
)$3;
853 | SPANDYNAMIC
'{' int int '}' {
854 Span_dynamic_req
* sp_p
= new Span_dynamic_req
;
856 sp_p
-> dynamic_dir_
= $3;
862 unsigned '/' unsigned {
869 $$
[0] = guess_plet_a
[(num
<? GUESS_PLET
) - 1];
877 THIS
->plet_.type_i_
= $2[1];
878 THIS
->plet_.iso_i_
= $2[0];
879 THIS
->default_duration_.plet_.type_i_
= $2[1];
880 THIS
->default_duration_.plet_.iso_i_
= $2[0];
884 THIS
->plet_.type_i_
= 1;
885 THIS
->plet_.iso_i_
= 1;
886 THIS
->default_duration_.plet_.iso_i_
= 1;
887 THIS
->default_duration_.plet_.type_i_
= 1;
889 | TELP plet_fraction
{
891 THIS
->plet_.type_i_
= $2[1];
892 THIS
->plet_.iso_i_
= $2[0];
893 THIS
->default_duration_.plet_.type_i_
= $2[1];
894 THIS
->default_duration_.plet_.iso_i_
= $2[0];
898 close_request_parens:
914 | close_plet_parens
{
921 if
(!Duration
::duration_type_b
($3))
922 THIS
->parser_error
("1:Not a duration");
924 THIS
->parser_error
("Can't abbreviate");
926 THIS
->set_abbrev_beam
($3);
933 THIS
->plet_.type_i_
= $2[1];
934 THIS
->plet_.iso_i_
= $2[0];
935 THIS
->default_duration_.plet_.type_i_
= $2[1];
936 THIS
->default_duration_.plet_.iso_i_
= $2[0];
938 | PLET plet_fraction
{
940 THIS
->plet_.type_i_
= $2[1];
941 THIS
->plet_.iso_i_
= $2[0];
942 THIS
->default_duration_.plet_.type_i_
= $2[1];
943 THIS
->default_duration_.plet_.iso_i_
= $2[0];
957 | open_abbrev_parens
{
966 SCRIPT
'{' script_body
'}' { $$
= $3; }
970 STRING
int int int int int {
971 Script_def
*s
= new Script_def
;
972 s
->set_from_input
(*$1,$2, $3,$4,$5, $6);
979 script_dir gen_script_def
{
980 Musical_script_req
*m
= new Musical_script_req
;
982 m
->scriptdef_p_
= $2;
983 m
->set_spot
(THIS
->here_input
());
992 ((Text_def
*) $$
)->align_i_
= CENTER
; /* UGH */
996 $$
-> set_spot
(THIS
->here_input
());
1000 ((Text_def
*)$$
)->align_i_
= CENTER
;
1006 Text_def
*t
= new Text_def
;
1010 t
->style_str_
= THIS
->textstyle_str_
;
1011 $$
->set_spot
(THIS
->here_input
());
1017 Text_def
* t
= new Text_def
;
1019 t
->text_str_
= String
($1);
1020 t
->style_str_
= "finger";
1021 $$
->set_spot
(THIS
->here_input
());
1025 script_abbreviation:
1026 '^' { $$
= get_scriptdef
('^'); }
1027 |
'+' { $$
= get_scriptdef
('+'); }
1028 |
'-' { $$
= get_scriptdef
('-'); }
1029 |
'|' { $$
= get_scriptdef
('|'); }
1030 |
'o' { $$
= get_scriptdef
('o'); }
1031 |
'>' { $$
= get_scriptdef
('>'); }
1033 $$
= get_scriptdef
('.');
1038 SCRIPT_IDENTIFIER
{ $$
= $1->script
(); }
1039 | script_definition
{ $$
= $1; }
1040 | script_abbreviation
{
1041 $$
= THIS
->lexer_p_
->lookup_identifier
(*$1)->script
();
1055 | pre_requests open_request_parens
{
1056 Array
<Request
*>& r
= *THIS
->get_parens_request
($2);
1057 for
(int i
= 0; i
< r.size
(); i
++ )
1058 r
[i
]->set_spot
(THIS
->here_input
());
1059 THIS
->pre_reqs.concat
(r
);
1066 THIS
->set_duration_mode
(*$2);
1069 | DURATION entered_notemode_duration
{
1070 THIS
->set_default_duration
($2);
1075 This is weird, but default_octave_i_
1076 is used in steno_note_req too
1078 c' -> default_octave_i_ == 1
1080 /* why can't we have \oct 0 iso \oct{c'}*/
1081 THIS
->default_octave_i_
= 1; }
1084 THIS
->default_octave_i_
= $3->octave_i_
;
1087 | TEXTSTYLE STRING
{
1088 THIS
->textstyle_str_
= *$2;
1095 $$
= new Moment
(0,1);
1097 | duration_length explicit_steno_duration
{
1098 *$$
+= $2->length
();
1104 | dots
'.' { $$
++; }
1107 entered_notemode_duration:
1109 $$
= new Duration
(THIS
->default_duration_
);
1112 $$
= new Duration
(THIS
->default_duration_
);
1115 | explicit_steno_duration
{
1116 THIS
->set_last_duration
($1);
1122 entered_notemode_duration
{
1127 explicit_steno_duration:
1130 if
(!Duration
::duration_type_b
($1))
1131 THIS
->parser_error
("2:Not a duration");
1133 $$
->durlog_i_
= Duration_convert
::i2_type
($1);
1134 $$
->set_plet
(THIS
->default_duration_
);
1137 | DURATION_IDENTIFIER
{
1138 $$
= $1->duration
();
1140 | explicit_steno_duration
'.' {
1143 | explicit_steno_duration
'*' unsigned {
1144 $$
->plet_.iso_i_
= $3;
1146 | explicit_steno_duration
'/' unsigned {
1147 $$
->plet_.type_i_
= $3;
1157 if
(!Duration
::duration_type_b
($2))
1158 THIS
->parser_error
("3:Not a duration");
1160 THIS
->parser_error
("Can't abbreviate");
1167 steno_note_req notemode_duration
{
1168 if
(!THIS
->lexer_p_
->note_state_b
())
1169 THIS
->parser_error
("have to be in Note mode for notes");
1170 $1->set_duration
(*$2);
1171 int durlog_i
= $2->durlog_i_
;
1172 $$
= THIS
->get_note_element
($1, $2);
1174 | RESTNAME notemode_duration
{
1175 $$
= THIS
->get_rest_element
(*$1, $2);
1181 text_def notemode_duration
{
1182 /* this sux! text-def should be feature of lyric-engraver. */
1183 if
(!THIS
->lexer_p_
->lyric_state_b
())
1184 THIS
->parser_error
("Have to be in Lyric mode for lyrics");
1185 $$
= THIS
->get_word_element
($1, $2);
1193 $$
= new Array
<Melodic_req
*>;
1195 | pitch_list NOTENAME_ID
{
1196 $$
->push
($2->clone
()->musical
()->melodic
());
1216 int *i_p
= $1->intid
();
1227 Real
*r_p
= $1->real
();
1236 real unit
{ $$
= $1*$2; }
1240 unit: CM_T
{ $$
= 1 CM
; }
1241 |IN_T
{ $$
= 1 INCH
; }
1242 |MM_T
{ $$
= 1 MM
; }
1243 |PT_T
{ $$
= 1 PT
; }
1250 SYMBOLTABLES
'{' symtables_body
'}' { $$
= $3; }
1260 | symtables_body TEXID STRING
{
1261 $$
->texsetting
= *$3;
1264 | symtables_body STRING
'=' symtable
{
1271 TABLE
'{' symtable_body
'}' { $$
= $3; }
1275 { $$
= new Symtable
; }
1276 | symtable_body STRING symboldef
{
1285 $$
= new Atom
(*$1, *$2);
1290 Box b
(Interval
(0,0), Interval
(0,0));
1291 $$
= new Atom
(*$1, b
);
1297 dinterval dinterval
{
1298 $$
= new Box
(*$1, *$2);
1304 dinterval: dim dim
{
1305 $$
= new Interval
($1, $2);
1312 My_lily_parser::set_yydebug
(bool b
)
1319 My_lily_parser::do_yyparse
()
1321 yyparse ((void*)this
);
1325 My_lily_parser::default_paper
()
1327 Identifier
*id
= lexer_p_
->lookup_identifier
("default_paper");
1328 return id ? id
->paperdef
() : new Paper_def
;
1332 My_lily_parser::default_midi
()
1334 Identifier
*id
= lexer_p_
->lookup_identifier
("default_midi");
1335 return id ? id
->mididef
() : new Midi_def
;