yaparc 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,264 @@
1
+ ; ABC notation 2.0 - BNF specification.
2
+ ; This is a specification of the draft ABC 2.0 standard in BNF.
3
+ ; This BNF specification is not finished yet - it needs to be elaborated in some places.
4
+ ; It uses ABNF as defined in http://www.ietf.org/rfc/rfc2234.txt.
5
+ ; This file written by Henrik Norbeck.
6
+ ; --------------------------------------------------------------------------------
7
+ abc-file ::= *(abc-tune / comment / xcommand / file-field / text-line / tex)
8
+ file-field ::= field-area / field-book / field-composer / field-discography / field-file / field-group / field-history / field-length / field-meter / field-notes / field-origin / field-parts / field-tempo / field-rhythm / field-source / field-userdef-print / field-userdef-play / field-words / field-transcription / field-key / unused-field ; Default values for the whole file - all fields except number, title and voice
9
+ text-line ::= [non-comment-char tex-text] eol ; Free text between tunes. This is a catch-all rule - check for fields first!
10
+
11
+ ; --------------------------------------------------------------------------------
12
+ abc-tune ::= abc-header abc-music eol
13
+ abc-header ::= [field-number] title-fields *other-field field-key ; note that field-number is optional.
14
+ field-number ::= %x58.3A *WSP 1*DIGIT header-eol ; X:
15
+ title-fields ::= *(comment / xcommand / tex) 1*(field-title *(comment / xcommand / tex))
16
+ field-title ::= %x54.3A *WSP tex-text header-eol ; T:
17
+ other-field ::= field-area / field-book / field-composer / field-discography / field-file / field-group / field-history / field-length / field-meter / field-notes / field-origin / field-parts / field-tempo / field-rhythm / field-source / field-userdef-print / field-userdef-play / field-voice / field-words / field-transcription / field-macro / unused-field / comment / xcommand / tex
18
+ field-area ::= %x41.3A *WSP tex-text header-eol ; A:
19
+ field-book ::= %x42.3A *WSP tex-text header-eol ; B:
20
+ field-composer ::= %x43.3A *WSP tex-text header-eol ; C:
21
+ field-discography ::= %x44.3A *WSP tex-text header-eol ; D:
22
+ field-file ::= %x46.3A *WSP tex-text header-eol ; F:
23
+ field-group ::= %x47.3A *WSP tex-text header-eol ; G:
24
+ field-history ::= %x48.3A *WSP 1*(tex-text header-eol) ; H: field contents may extend over many lines, which is deprecated (maybe not allowed any longer?)
25
+ field-length ::= %x4C.3A *WSP note-length-strict header-eol ; L: default note length
26
+ field-meter ::= %x4D.3A *WSP time-signature header-eol ; M:
27
+ field-notes ::= %x4E.3A *WSP tex-text header-eol ; N:
28
+ field-origin ::= %x4F.3A *WSP tex-text header-eol ; O:
29
+ field-parts ::= %x50.3A *WSP parts-play-order header-eol ; P: in header defines in which order parts should be played
30
+ field-tempo ::= %x51.3A *WSP tempo header-eol ; Q:
31
+ field-rhythm ::= %x52.3A *WSP tex-text header-eol ; R:
32
+ field-source ::= %x53.3A *WSP tex-text header-eol ; S:
33
+ field-userdef-print ::= %x55.3A *WSP userdef header-eol ; U:
34
+ field-userdef-play ::= %x75.3A *WSP userdef header-eol ; u:
35
+ field-voice ::= %x56.3A *WSP voice header-eol ; V: options should be better defined
36
+ field-words ::= %x57.3A *WSP tex-text header-eol ; W: unformatted words, printed after the tune
37
+ field-transcription ::= %x5A.3A *WSP tex-text header-eol ; Z:
38
+ field-macro ::= %x6D.3A *WSP 1*(WSP / VCHAR) header-eol ; m: BarFly-style macros - do be defined better
39
+ field-key ::= %x4B.3A *WSP key header-eol ; K:
40
+ unused-field ::= (%x45 / %x49 / %4A / %59 / %61-6c / %6e-%74 / %76 / %78-7A) %3A *(WSP / VCHAR) eol ; E: I: J: Y: a:-l: n:-t: v: x: y: z: ignore - but for backward and forward compatibility
41
+
42
+ ; --------------------------------------------------------------------------------
43
+ time-signature ::= %x43 / %x43.7C / "none" / meter-num / 1*DIGIT ; C, C|, none or numeric
44
+ meter-num ::= (1*DIGIT *("+" 1*DIGIT) "/" 1*DIGIT) [1*SP meter-num]
45
+ ; e.g. 2/4 , 6/8 , 2+2+3/16 , 11/8 , 2/4 3/4 , 2+2+3/8 2+2+3+2+2+2/8
46
+ tempo ::= (note-length-strict "=" 1*DIGIT) / (%x43 [note-length] "=" 1*DIGIT) / 1*DIGIT ; 1*DIGIT is deprecated, kept for compatibility
47
+ note-length-strict ::= 1*DIGIT "/" 1*DIGIT
48
+ key ::= (key-def [1*WSP clef]) / clef / "HP" / "Hp"
49
+ key-def ::= basenote ["#" / "b"] [mode] *(1*WSP global-accidental)
50
+ mode ::= minor / major / lydian / ionian / mixolydian / dorian / aeolian / phrygian / locrian
51
+ minor ::= "m" ["in" ["o" ["r"]]] ; m, min, mino, minor - all modes are case insensitive
52
+ major ::= "maj" ["o" ["r"]]
53
+ lydian ::= "lyd" ["i" ["a" ["n"]]] ; major with sharp 4th
54
+ ionian ::= "ion" ["i" ["a" ["n"]]] ; =major
55
+ mixolydian ::= "mix" ["o" ["l" ["y" ["d" ["i" ["a" ["n"]]]]]]] ; major with flat 7th
56
+ dorian ::= "dor" ["i" ["a" ["n"]]] ; minor with sharp 6th
57
+ aeolian ::= "aeo" ["l" ["i" ["a" ["n"]]]] ; =minor
58
+ phrygian ::= "phr" ["y" ["g" ["i" ["a" ["n"]]]]] ; minor with flat 2nd
59
+ locrian ::= "loc" ["r" ["i" ["a" ["n"]]]] ; minor with flat 2nd and 5th
60
+ global-accidental ::= accidental basenote ; e.g. ^f =c _b
61
+ parts-play-order ::= 1*( ALPHA / ( "(" parts-play-order ")" ) *DIGIT) / "." ; dots are ignored - for legibility only
62
+
63
+ ; --------------------------------------------------------------------------------
64
+ voice ::= 1*(ALPHA / DIGIT) *(1*WSP (clef / voice-name / voice-subname / voice-transpose / "merge" / "up" / "down")) ; maybe "stems=up" / "stems=down" / "stems=normal" instead?
65
+ voice-name ::= ("name=" / "nm=") %x22 *non-quote %x22 ; \n in name = linefeed
66
+ voice-subname ::= ("subname=" / "snm=") %x22 *non-quote %x22 ; \n in name = linefeed
67
+ voice-transpose ::= "transpose=" ["-"] 1*DIGIT
68
+
69
+ ; --------------------------------------------------------------------------------
70
+ clef ::= ( ("clef=" (clef-note / clef-name)) / clef-name) clef-line ["+8" / "-8"] [1*WSP clef-middle]
71
+ clef-note ::= "G" / "C" / "F" / "P"
72
+ clef-name ::= "treble" / "alto" / "tenor" / "baritone" / "bass" / "mezzo" / "soprano" / "perc" / "none" ; Maybe also Doh1-4, Fa1-4
73
+ clef-line ::= "1" / "2" / "3" / "4" / "5"
74
+ cleff-middle ::= "middle=" basenote [octave]
75
+
76
+ ; --------------------------------------------------------------------------------
77
+ userdef ::= userdef-symbol *WSP "=" *WSP (long-gracing / chord-or-text)
78
+ header-eol ::= *WSP (comment / eol) ; there may be comments at the end of header lines
79
+
80
+ ; --------------------------------------------------------------------------------
81
+ abc-music ::= *(abc-line / comment / xcommand / tune-field / tex)
82
+ abc-line ::= barline / ([barline] 1*element *(barline 1*element) [barline]) abc-eol
83
+ barline ::= ( *":" *"[" 1*"|" *"]" ( *":" / nth-repeat-num ) ) / invisible-barline / dashed-barline ; e.g. :| | |:: |2 :||:
84
+ invisible-barline ::= "[|]" | "[]"
85
+ dashed-barline ::= ":"
86
+ element ::= stem / WSP / chord-or-text / gracing / grace-notes / broken-rhythm / tuplet / slur-begin / slur-end / rollback / multi-measure-rest / measure-repeat / nth-repeat / end-nth-repeat / inline-field / unused-char
87
+
88
+ ; --------------------------------------------------------------------------------
89
+ stem ::= note / ( "[" 2*note "]" ) ; stem
90
+ note ::= pitch [note-length] [tie] ; note
91
+ pitch ::= [accidental] basenote [octave]
92
+ rest ::= (normal-rest / invisible-rest / inaudible-rest) [note-length]
93
+ normal-rest ::= %x7A ; z = normal rest
94
+ invisible-rest ::= %x78 ; x = invisible rest
95
+ inaudible-rest ::= %x79 ; y = inaudible and invisible rest, for spacing
96
+ accidental ::= "^" / "^^" / "_" / "__" / "="
97
+ basenote ::= %x43 / %x44 / %x45 / %x46 / %x47 / %x41 / %x42 / %x63 / %x64 / %x65 / %x66 / %x67 / %x61 / %x62 ; CDEFGABcdefgab
98
+ octave ::= 1*"'" / 1*","
99
+ note-length ::= (*DIGIT ["/" *DIGIT]) / 1*"/"
100
+ tie ::= "-" ; tie
101
+
102
+ ; --------------------------------------------------------------------------------
103
+ broken-rhythm ::= stem *b-elem (1*"<" / 1*">") *b-elem stem
104
+ b-elem ::= WSP / chord-or-text / gracing / grace-notes / slur-begin / slur-end
105
+ tuplet ::= "("1*DIGIT [":" [1*DIGIT] ":" [1*DIGIT]] 2*(*t-elem stem)
106
+ t-elem ::= WSP / chord-or-text / gracing / grace-notes / broken-rhythm / slur-begin / slur-end
107
+
108
+ ; --------------------------------------------------------------------------------
109
+ gracing ::= "." / userdef-symbol / long-gracing ; gracings
110
+ userdef-symbol ::= "~" / %x48-59 / %x68-77 ; user definable symbols ~ H-Y, h-w
111
+ grace-notes ::= "{" acciaccatura 1*( grace-note-stem ) "}" ; grace notes can have length
112
+ grace-note-stem ::= grace-note / ( "[" 2*grace-note "]" )
113
+ grace-note ::= pitch [note-length] ; as note, but without tie
114
+ acciaccatura ::= "/"
115
+
116
+ ; --------------------------------------------------------------------------------
117
+ chord-or-text ::= %x22 (chord / text-expression) *(chord-newline (chord / text-expression)) %x22 ; ".."
118
+ chord ::= basenote [chord-accidental] [chord-type] ["/" basenote [chord-accidental]] *non-quote
119
+ chord-accidental ::= "#" / "b" / "="
120
+ chord-type ::= 1*( ALPHA / DIGIT / "+" / "-" ) ; e.g. m, 7, m7, +, mb5, sus, sus4, maj7, mmaj7, 7sus4, dim
121
+ text-expression ::= [ "^" / "<" / ">" / "_" / "@" ] 1*non-quote ; above, left, right, below, anywhere
122
+ non-quote ::= SP / %x21 / %x23-7E ; all characters except quote
123
+ chord-newline ::= "\n" / ";"
124
+
125
+ ; --------------------------------------------------------------------------------
126
+ slur-begin ::= "("
127
+ slur-end ::= ")"
128
+ rollback ::= "&"
129
+ measure-repeat ::= "/" ["/"] ; repeat whole measure
130
+ multi-measure-rest ::= %5A *DIGIT ; e.g. Z4
131
+ nth-repeat ::= "[" ( nth-repeat-num / nth-repeat-text )
132
+ nth-repeat-num ::= 1*DIGIT *(("," / "-") 1*DIGIT)
133
+ nth-repeat-text ::= %x22 *non-quote %x22
134
+ end-nth-repeat ::= "]"
135
+ unused-char ::= "#" / "$" / "*" / "+" / ";" / "?" / "@" / "`" ; ignore for backward and forward compatibility, but maybe warn about them
136
+
137
+ ; --------------------------------------------------------------------------------
138
+ inline-field ::= ifield-area / ifield-book / ifield-composer / ifield-discography / ifield-group / ifield-history / ifield-length / ifield-meter / ifield-notes / ifield-origin / ifield-part / ifield-tempo / ifield-rhythm / ifield-source / ifield-title / ifield-voice / ifield-words / ifield-lyrics / ifield-transcription / ifield-key
139
+ ifield-area ::= %5B.%41.%3A tex-text-ifield %5D ; [A:..]
140
+ ifield-book ::= %5B.%42.%3A *WSP tex-text-ifield %5D ; [B:..]
141
+ ifield-composer ::= %5B.%43.%3A *WSP tex-text-ifield %5D ; [C:..]
142
+ ifield-discography ::= %5B.%44.%3A *WSP tex-text-ifield %5D ; [D:..]
143
+ ifield-group ::= %5B.%47.%3A *WSP tex-text-ifield %5D ; [G:..]
144
+ ifield-history ::= %5B.%48.%3A *WSP tex-text-ifield %5D ; [H:..]
145
+ ifield-length ::= %5B.4C.3A *WSP note-length-strict %5D ; e.g. [L:1/8]
146
+ ifield-meter ::= %5B.4D.3A *WSP meter %5D ; e.g. [M:C|] [M: 2+3/8]
147
+ ifield-notes ::= %5B.%4E.%3A *WSP tex-text-ifield %5D ; [N:..]
148
+ ifield-origin ::= %5B.%4F.%3A *WSP tex-text-ifield %5D ; [O:..]
149
+ ifield-part ::= %5B.%50.%3A *WSP (ALPHA / tex-text-ifield) %5D ; e.g. [P:A]
150
+ ifield-tempo ::= %5B.%51.%3A *WSP tempo %5D ; e.g. [Q:1/4=120]
151
+ ifield-rhythm ::= %5B.%52.%3A *WSP tex-text-ifield %5D ; e.g. [R:reel]
152
+ ifield-source ::= %5B.%53.%3A *WSP tex-text-ifield %5D ; [S:..]
153
+ ifield-title ::= %5B.%54.%3A *WSP tex-text-ifield %5D ; e.g. [T:second version]
154
+ ifield-voice ::= %5B.%56.%3A *WSP voice %5D ; [V:..] options should be better defined
155
+ ifield-words ::= %5B.%57.%3A *WSP tex-text-ifield %5D ; [W:..]
156
+ ifield-lyrics ::= %5B.%77.%3A *WSP tex-text-ifield %5D ; [w:..]
157
+ ifield-transcription ::= %5B.%5A.%3A *WSP tex-text-ifield %5D ; [Z:..]
158
+ ifield-key ::= %5B.4B.3A *WSP key %5D ; e.g. [K:Ador] [K: Bphr ^d]
159
+ unused-ifield ::= %5B (%x45 / %x49 / %4A / %59 / %61-6c / %6e-%74 / %76 / %78-7A) %3A *(WSP / VCHAR) %5D ; E: I: J: Y: a:-l: n:-t: v: x: y: z: ignore - but for backward and forward compatibility
160
+ non-bracket-char ::= *(WSP / %21-%5C / %5E-7E) ; all except ]
161
+
162
+ ; --------------------------------------------------------------------------------
163
+ abc-eol ::= comment / ([line-continuation / hard-line-break] *WSP eol)
164
+ line-continuation ::= "\"
165
+ hard-line-break ::= "!" ; kept for compatibility with abc2win
166
+
167
+ ; --------------------------------------------------------------------------------
168
+ tune-field ::= field-area / field-book / field-composer / field-discography / field-group / field-history / field-length / field-meter / field-notes / field-origin / field-part / field-tempo / field-rhythm / field-source / field-title / field-voice / field-words / field-lyrics / field-transcription / field-key / unused-field
169
+ field-part ::= %x50.3A *WSP (ALPHA / tex-text) header-eol ; P:
170
+ field-lyrics ::= %x56.3A *WSP lyrics header-eol ; w: formatted lyrics printed under staff
171
+
172
+ ; --------------------------------------------------------------------------------
173
+ long-gracing ::= gracing-grace / gracing-vol / gracing-style / gracing-finger / gracing-phrase / gracing-exec / gracing-other
174
+ gracing-grace ::= "!trill!" / "!mordent!" / "!lowermordent!" / "!pralltriller!" / "!uppermordent!" / "!turn!" / "!roll!" / "!turnx!" / "!invertedturn!" / "!invertedturnx!" / "!trill(!" / "!trill)!"
175
+ gracing-vol ::= "!accent!" / "!emphasis!" / "!crescendo(!" / "!crescendo)!" / "!diminuendo(!" / "!diminuendo)!" / "!p!" / "!pp!" / "!ppp!" / "!pppp!" / "!mp!" / "!mf!" / "!fp!" / "!f!" / "!ff!" / "!fff!" / "!ffff!" / "!sfz!" / "!cresc!" / "!decresc!" / "!dimin!"
176
+ gracing-style ::= "!+!" / "!open!" / "!snap!" / "!upbow!" / "!downbow!" / "!slide!" / "!arpeggio!"
177
+ gracing-len ::= "!fermata!" / "!invertedfermata!" / "!tenuto!"
178
+ gracing-finger ::= "!0!" / "!1!" / "!2!" / "!3!" / "!4!" / "!5!"
179
+ gracing-phrase ::= "!shortphrase!" / "!mediumphrase!" / "!longphrase!"
180
+ gracing-exec ::= "!segno!" / "!coda!" / "!D.S.!" / "!D.C.!" / "!fine!" / ("!repeatbar" *DIGIT "!")
181
+ gracing-other ::= "!wedge!" / "!thumb!" / "!breath!" / ("!" 1*(SP / %x22-x7E) "!") ; any text between !! is allowed
182
+
183
+ ; --------------------------------------------------------------------------------
184
+ comment ::= "%" ([non-comment-char *(VCHAR / WSP)]) eol
185
+ non-comment-char ::= %x20-24 / %x26-%x7E / HTAB ; all characters except %
186
+ xcommand ::= "%%" xcom eol
187
+ xcom ::= xcom-staff / xcom-measurenb / xcom-text / xcom-layout / xcom-margins / xcom-midi / xcom-other ; more need to be defined
188
+ xcom-staff ::= xcom-staffbreak / xcom-multicol / xcom-staves / xcom-indent
189
+ xcom-staffbreak ::= "staffbreak" 1*WSP xcom-number xcom-unit
190
+ xcom-multicol ::= "multicol" 1*WSP ("start" / "new" / "end")
191
+ xcom-staves ::= "staves" 1*WSP stave-voice *( bar-staves stave-voice)
192
+ stave-voice ::= single-voice / bracketed-voice / braced-voice / paren-voice
193
+ bracketed-voice ::= "[" *WSP (single-voice / braced-voice / paren-voice) 1*(bar-staves (single-voice / braced-voice / paren-voice)) *WSP "]" ; staves joined by bracket
194
+ braced-voice ::= "{" *WSP (single-voice / paren-voice) 1*(bar-staves (single-voice / paren-voice)) *WSP "}" ; staves joined by brace
195
+ paren-voice ::= "(" single-voice 1*( 1*WSP single-voice) ")" ; on same staff
196
+ single-voice ::= 1*(ALPHA / DIGIT)
197
+ bar-staves ::= (*WSP "|" *WSP) / 1*WSP ; | to not bar
198
+ xcom-indent ::= "indent" 1*WSP xcom-number xcom-unit
199
+ xcom-measurenb ::= "measurenb" / "measurebox" / "measurefirst" / ("setbarnb" 1*WSP 1*DIGIT)
200
+ xcom-text ::= xcom-textline / xcom-textcenter / xcom-textblock
201
+ xcom-textline ::= "text" 1*WSP tex-text
202
+ xcom-textcenter ::= "center" 1*WSP tex-text
203
+ xcom-textblock ::= "begintext" [textblock-param] eol *(["%%"] tex-text) "%%endtext"
204
+ textblock-param ::= "obeylines" / ("fill" / "ragged") / ("align" / "justify") / "skip"
205
+ xcom-layout ::= xcom-sep / xcom-vskip / xcom-newpage
206
+ xcom-sep ::= "sep" [3(1*WSP xcom-number xcom-unit)] ; space-above, space-below, width
207
+ xcom-vskip ::= "vskip" 1*WSP xcom-number xcom-unit
208
+ xcom-newpage ::= "newpage" [1*WSP 1*DIGIT] ; optionally restart page numbering at n
209
+ xcom-margins ::= ("botmargin" / "topmargin" / "leftmargin" / "rightmargin") 1*WSP xcom-number xcom-unit
210
+ xcom-midi ::= "midi" 1*WSP (midi-channel / midi-program / midi-transpose)
211
+ midi-channel ::= "channel" 1*WSP midi-channel-number
212
+ midi-program ::= "program" 1*WSP [midi-channel-number 1*WSP] midi-program-number
213
+ midi-channel-number ::= %x31-39 / (%x31 %x30-36) ; channels 1-16
214
+ midi-program-number ::= %x31-39 / (%x31-39 %x30-39) / (%x31 %x30-31 %x30-39) / (%x31.32 %x30-38) ; programs 1-128
215
+ midi-transpose ::= "transpose" 1*WSP ["-"] 1*DIGIT
216
+ xcom-other ::= *(VCHAR / WSP)
217
+ xcom-number ::= 1*DIGIT ["." 1*DIGIT]
218
+ xcom-unit ::= ["cm" / "pt" / "in"]
219
+
220
+ ; --------------------------------------------------------------------------------
221
+ lyrics ::= *(lyrics-char / lyrics-syllable-break / lyrics-next-bar / lyrics-hold / lyrics-skip-note / lyrics-nbsp / lyrics-dash / tex-escape)
222
+ lyrics-ifield ::= *(lyrics-char-ifield / lyrics-syllable-break / lyrics-next-bar / lyrics-hold / lyrics-skip-note / lyrics-nbsp / lyrics-dash / tex-escape)
223
+ lyrics-syllable-break ::= "-" ; break between syllables in a word
224
+ lyrics-next-bar ::= "|" ; advance to next bar
225
+ lyrics-hold ::= "_" ; hold syllable for one more note
226
+ lyrics-skip-note ::= "*" ; =blank syllable
227
+ lyrics-nbsp ::= "~" ; non-breaking space = words on same note
228
+ lyrics-dash ::= "\-" ; printed as a -
229
+ lyrics-char ::= WSP / DIGIT / ALPHA / %x21-29 / %x2B-2C / %x2E-2F / %x3A-40 / %x5B / %x5D / %x5E / %x60 / %x7B-7D ; all characters without special meaning
230
+ lyrics-char-ifield ::= WSP / DIGIT / ALPHA / %x21-29 / %x2B-2C / %x2E-2F / %x3A-40 / %x5B / %x5E / %x60 / %x7B-7D ; all characters without special meaning and except ]
231
+
232
+ ; --------------------------------------------------------------------------------
233
+ tex-text ::= *(WSP / %21-%5B / %5D-7E / tex-escape) ; text that may contain TeX escapes
234
+ tex-text-ifield ::= *(WSP / %21-%5B / %5E-7E / tex-escape) ; as above, but except ]
235
+ tex-escape ::= "\" 1*(VCHAR) ; to be defined better
236
+
237
+ ; --------------------------------------------------------------------------------
238
+ tex ::= "\" *(VCHAR / WSP) eol ; deprecated - kept only for backward compatibility with abc2mtex
239
+ eol ::= CRLF / LF / CR ; only one version should occur in the whole file - win / *nix / mac line breaks
240
+
241
+ ; --------------------------------------------------------------------------------
242
+ ; Core rules in ABNF:
243
+ ; ALPHA ::= %x41-5A / %x61-7A ; A-Z / a-z
244
+ ; CR ::= %x0D ; carriage return
245
+ ; CRLF ::= %x0D.0A ; CR+LF
246
+ ; DIGIT ::= %x30-39 ; 0-9
247
+ ; DQUOTE ::= %x22 ; "
248
+ ; HTAB ::= %x09 ; tab
249
+ ; LF ::= %x0A ; linefeed
250
+ ; SP ::= %x20 ; space
251
+ ; VCHAR ::= %x21-7e ; printing chars
252
+ ; WSP ::= SP / HTAB ; whitespace
253
+ ; %xDD means a hexadecimal code for a character
254
+ ; %xCC-DD means any character in that range
255
+ ; %xCC.DD means two characters
256
+ ; / means or
257
+ ; * means 0 or more occurences of
258
+ ; 1* means 1 or more occurences of
259
+ ; 2* means 2 or more occurences of
260
+ ; [ ] means optional
261
+ ; ( ) used for grouping
262
+ ; " " is a literal string (note that it is case insensitive)
263
+ ; ; starts a comment to end of line
264
+ ; read more about ABNF at http://www.ietf.org/rfc/rfc2234.txt.
data/tests/test_abc.rb ADDED
@@ -0,0 +1,113 @@
1
+
2
+ require 'lib/yaparc.rb'
3
+ require 'test/unit'
4
+
5
+ ### c.f. http://www.norbeck.nu/abc/bnf/abc20bnf.htm###
6
+
7
+ module ABC
8
+
9
+ # KEYWORDS = %w{NOT AND OR ALL IN select from where EXISTS}
10
+
11
+ # abc-file ::= *(abc-tune / comment / xcommand / file-field / text-line / tex)
12
+ class AbcFile
13
+ include Yaparc::Parsable
14
+
15
+ def initialize
16
+ @parser = lambda do
17
+ Yaparc::ManyParser.new(
18
+ Yaparc::AltParser.new(AbcTune.new,
19
+ Comment.new,
20
+ Xcommand.new,
21
+ FileField.new,
22
+ TextLine.new,
23
+ Tex.new))
24
+ end
25
+ end
26
+ end
27
+
28
+ # file-field ::= field-area / field-book / field-composer / field-discography / field-file / field-group / field-history / field-length / field-meter / field-notes / field-origin / field-parts / field-tempo / field-rhythm / field-source / field-userdef-print / field-userdef-play / field-words / field-transcription / field-key / unused-field ; Default values for the whole file - all fields except number, title and voice
29
+ class FileField
30
+ include Yaparc::Parsable
31
+
32
+ def initialize
33
+ @parser = lambda do
34
+ Yaparc::AltParser.new(
35
+ FieldArea.new,
36
+ FieldBook.new,
37
+ FieldComposer.new,
38
+ FieldDiscography.new,
39
+ FieldFile.new,
40
+ FieldGroup.new,
41
+ FieldHistory.new,
42
+ FieldLength.new,
43
+ FieldMeter.new,
44
+ FieldNotes.new,
45
+ FieldOrigin.new,
46
+ FieldParts.new,
47
+ FieldTempo.new,
48
+ FieldRhythm.new,
49
+ FieldSource.new,
50
+ FieldUserdefPrint.new,
51
+ FieldUserdefPlay.new,
52
+ FieldWords.new,
53
+ FieldTranscription.new,
54
+ FieldKey.new,
55
+ UnusedField.new)
56
+ end
57
+ end
58
+ end
59
+
60
+ # abc-tune ::= abc-header abc-music eol
61
+ class AbcTune
62
+ include Yaparc::Parsable
63
+
64
+ def initialize
65
+ @parser = lambda do
66
+ Yaparc::SeqParser.new(AbcHeader.new,
67
+ AbcMusic.new,
68
+ Eol.new)
69
+ end
70
+ end
71
+ end
72
+
73
+ # abc-header ::= [field-number] title-fields *other-field field-key ; note that field-number is optional.
74
+ class AbcTune
75
+ include Yaparc::Parsable
76
+
77
+ def initialize
78
+ @parser = lambda do
79
+ Yaparc::SeqParser.new(
80
+ ZeroOneParser.new(FieldNumber.new)
81
+ TitleFields.new,
82
+ ManyParser.new(OtherField.new),
83
+ FieldKey.new)
84
+ end
85
+ end
86
+ end
87
+
88
+ # field-number ::= %x58.3A *WSP 1*DIGIT header-eol ; X:
89
+ class FieldNumber
90
+ include Yaparc::Parsable
91
+
92
+ def initialize
93
+ @parser = lambda do
94
+ Yaparc::SeqParser.new(
95
+
96
+
97
+ %x58.3A *WSP 1*DIGIT header-eol ; X:
98
+ end
99
+ end
100
+ end
101
+
102
+ ### eol ::= CRLF / LF / CR ; only one version should occur in the whole file - win / *nix / mac line breaks
103
+ class Eol
104
+ include Yaparc::Parsable
105
+
106
+ def initialize
107
+ @parser = lambda do
108
+ Yaparc::AltParser.new(RegexParser.new(/\n/))
109
+ end
110
+ end
111
+ end
112
+
113
+ end
data/tests/test_calc.rb CHANGED
@@ -3,8 +3,10 @@ require 'test/unit'
3
3
 
4
4
  module Calc
5
5
 
6
- class Expr < Yaparc::AbstractParser
7
-
6
+ # class Expr < Yaparc::AbstractParser
7
+ class Expr
8
+ include Yaparc::Parsable
9
+
8
10
  def initialize
9
11
  @parser = lambda do
10
12
  Yaparc::AltParser.new(
@@ -43,7 +45,9 @@ module Calc
43
45
  end
44
46
  end
45
47
 
46
- class Term < Yaparc::AbstractParser
48
+ # class Term < Yaparc::AbstractParser
49
+ class Term
50
+ include Yaparc::Parsable
47
51
 
48
52
  def initialize
49
53
  @parser = lambda do
@@ -59,8 +63,9 @@ module Calc
59
63
  end
60
64
  end
61
65
 
62
- class Factor < Yaparc::AbstractParser
63
-
66
+ # class Factor < Yaparc::AbstractParser
67
+ class Factor
68
+ include Yaparc::Parsable
64
69
 
65
70
  def initialize
66
71
  @parser = lambda do
data/tests/test_owl.rb ADDED
@@ -0,0 +1,68 @@
1
+ ontology ::= 'Ontology(' [ ontologyID ] { directive } ')'
2
+ directive ::= 'Annotation(' ontologyPropertyID ontologyID ')'
3
+ | 'Annotation(' annotationPropertyID URIreference ')'
4
+ | 'Annotation(' annotationPropertyID dataLiteral ')'
5
+ | 'Annotation(' annotationPropertyID individual ')'
6
+ | axiom
7
+ | fact
8
+ datatypeID ::= URIreference
9
+ classID ::= URIreference
10
+ individualID ::= URIreference
11
+ ontologyID ::= URIreference
12
+ datavaluedPropertyID ::= URIreference
13
+ individualvaluedPropertyID ::= URIreference
14
+ annotationPropertyID ::= URIreference
15
+ ontologyPropertyID ::= URIreference
16
+ annotation ::= 'annotation(' annotationPropertyID URIreference ')'
17
+ | 'annotation(' annotationPropertyID dataLiteral ')'
18
+ | 'annotation(' annotationPropertyID individual ')'
19
+
20
+ fact ::= individual
21
+ individual ::= 'Individual(' [ individualID ] { annotation } { 'type(' type ')' } { value } ')'
22
+ value ::= 'value(' individualvaluedPropertyID individualID ')'
23
+ | 'value(' individualvaluedPropertyID individual ')'
24
+ | 'value(' datavaluedPropertyID dataLiteral ')'
25
+ type ::= description
26
+
27
+ axiom ::= 'Class(' classID ['Deprecated'] modality { annotation } { description } ')'
28
+ | 'EnumeratedClass(' classID ['Deprecated'] { annotation } { individualID } ')'
29
+ | 'DisjointClasses(' description description { description } ')'
30
+ | 'EquivalentClasses(' description { description } ')'
31
+ | 'SubClassOf(' description description ')'
32
+ | 'Datatype(' datatypeID ['Deprecated'] { annotation } )'
33
+ | 'DatatypeProperty(' datavaluedPropertyID ['Deprecated'] { annotation } { 'super(' datavaluedPropertyID ')'} ['Functional'] { 'domain(' description ')' } { 'range(' dataRange ')' } ')'
34
+ | 'ObjectProperty(' individualvaluedPropertyID ['Deprecated'] { annotation } { 'super(' individualvaluedPropertyID ')' } [ 'inverseOf(' individualvaluedPropertyID ')' ] [ 'Symmetric' ] [ 'Functional' | 'InverseFunctional' | 'Functional' 'InverseFunctional' | 'Transitive' ] { 'domain(' description ')' } { 'range(' description ')' } ')'
35
+ | 'AnnotationProperty(' annotationPropertyID { annotation } ')'
36
+ | 'OntologyProperty(' ontologyPropertyID { annotation } ')'
37
+ | 'EquivalentProperties(' datavaluedPropertyID datavaluedPropertyID { datavaluedPropertyID } ')'
38
+ | 'SubPropertyOf(' datavaluedPropertyID datavaluedPropertyID ')'
39
+ | 'EquivalentProperties(' individualvaluedPropertyID individualvaluedPropertyID { individualvaluedPropertyID } ')'
40
+ | 'SubPropertyOf(' individualvaluedPropertyID individualvaluedPropertyID ')'
41
+
42
+ modality ::= 'complete' | 'partial'
43
+
44
+ description ::= classID
45
+ | restriction
46
+ | 'unionOf(' { description } ')'
47
+ | 'intersectionOf(' { description } ')'
48
+ | 'complementOf(' description ')'
49
+ | 'oneOf(' { individualID } ')'
50
+
51
+ restriction ::= 'restriction(' datavaluedPropertyID dataRestrictionComponent { dataRestrictionComponent } ')'
52
+ | 'restriction(' individualvaluedPropertyID individualRestrictionComponent { individualRestrictionComponent } ')'
53
+
54
+ dataRestrictionComponent ::= 'allValuesFrom(' dataRange ')'
55
+ | 'someValuesFrom(' dataRange ')'
56
+ | 'value(' dataLiteral ')'
57
+ | cardinality
58
+
59
+ individualRestrictionComponent ::= 'allValuesFrom(' description ')'
60
+ | 'someValuesFrom(' description ')'
61
+ | 'value(' individualID ')'
62
+ | cardinality
63
+ cardinality ::= 'minCardinality(' non-negative-integer ')'
64
+ | 'maxCardinality(' non-negative-integer ')'
65
+ | 'cardinality(' non-negative-integer ')'
66
+ dataRange ::= datatypeID | 'rdfs:Literal'
67
+ | 'oneOf(' { dataLiteral } ')'
68
+
data/tests/test_parser.rb CHANGED
@@ -5,12 +5,15 @@ require 'pp'
5
5
  class YaparcTest < Test::Unit::TestCase
6
6
  include ::Yaparc
7
7
 
8
-
9
- def setup
10
-
11
- end
12
-
13
- def teardown
8
+ def test_seq_alt_parse
9
+ parser = Yaparc::SeqParser.new(Yaparc::Symbol.new('scheme'),
10
+ Yaparc::Symbol.new(':'),
11
+ Yaparc::AltParser.new(Natural.new,
12
+ Identifier.new))
13
+ result = parser.parse("scheme:124")
14
+ assert_instance_of Result::OK, result
15
+ result = parser.parse("scheme:identifier")
16
+ assert_instance_of Result::OK, result
14
17
  end
15
18
 
16
19
  def test_succeed_parse
@@ -116,6 +119,17 @@ class YaparcTest < Test::Unit::TestCase
116
119
  parser = AltParser.new(FailParser.new, FailParser.new)
117
120
  result = parser.parse("abc")
118
121
  assert_instance_of Result::Fail, result
122
+
123
+ parser = AltParser.new(Natural.new, Ident.new)
124
+ result = parser.parse("abc")
125
+ assert_instance_of Result::OK, result
126
+ result = parser.parse("124")
127
+ assert_instance_of Result::OK, result
128
+ result = parser.parse("ABC124")
129
+ assert_instance_of Result::Fail, result
130
+ result = parser.parse("abc124")
131
+ assert_instance_of Result::OK, result
132
+ assert_equal 'abc124', result.value
119
133
  end
120
134
 
121
135
  def test_apply_parse
@@ -172,6 +186,17 @@ class YaparcTest < Test::Unit::TestCase
172
186
  Integer(match)
173
187
  end
174
188
  assert_equal 1234, result.value
189
+
190
+ parser = RegexParser.new(/([0-9]+):([a-z]+)/)
191
+ result = parser.parse_with_parameter("1234:ab") do |match1, match2|
192
+ assert_equal 'ab', match2
193
+ end
194
+
195
+ parser = RegexParser.new(/([0-9]+):([a-z]+)/) do |match1, match2|
196
+ [match2,match1]
197
+ end
198
+ result = parser.parse("1234:ab")
199
+ assert_equal ["ab", "1234"], result.value
175
200
  end
176
201
 
177
202
  def test_zero_one_parse
@@ -197,6 +222,18 @@ class YaparcTest < Test::Unit::TestCase
197
222
  assert_equal "abcdef", result.input
198
223
  end
199
224
 
225
+ def test_many_one_parse
226
+ is_digit = SatisfyParser.new(lambda {|i| i >= '0' and i <= '9'})
227
+ parser = ManyOneParser.new(is_digit,"")
228
+ result = parser.parse("123abc")
229
+ assert_equal "123", result.value
230
+ assert_equal "abc", result.input
231
+
232
+ result = parser.parse("abcdef")
233
+ assert_instance_of Result::Fail, result
234
+ assert_equal "abcdef", result.input
235
+ end
236
+
200
237
  def test_ident
201
238
  parser = Ident.new
202
239
  result = parser.parse("abc def")
@@ -220,19 +257,19 @@ class YaparcTest < Test::Unit::TestCase
220
257
  assert_equal "", result.input
221
258
  end
222
259
 
223
- def test_space
224
- parser = Space.new
225
- result = parser.parse(" abc")
226
- assert_instance_of Result::OK, result
227
- assert_equal "abc", result.input
228
- end
260
+ # def test_space
261
+ # parser = Space.new
262
+ # result = parser.parse(" abc")
263
+ # assert_instance_of Result::OK, result
264
+ # assert_equal "abc", result.input
265
+ # end
229
266
 
230
- def test_whitespace
231
- parser = WhiteSpace.new
232
- result = parser.parse(" \n abc")
233
- assert_instance_of Result::OK, result
234
- assert_equal "abc", result.input
235
- end
267
+ # def test_whitespace
268
+ # parser = WhiteSpace.new
269
+ # result = parser.parse(" \n abc")
270
+ # assert_instance_of Result::OK, result
271
+ # assert_equal "abc", result.input
272
+ # end
236
273
 
237
274
  # def test_token
238
275
  # parser = Token.new
@@ -241,10 +278,10 @@ class YaparcTest < Test::Unit::TestCase
241
278
  # assert_equal "abc", result.input
242
279
  # end
243
280
 
244
- def test_tokenize
245
- parser = Tokenize.new(Ident.new) do |tokenize|
246
- tokenize.prefix = Space.new
247
- tokenize.postfix = Space.new
281
+ def test_tokenize_with_block
282
+ parser = TokenizeParser.new(Ident.new) do |tokenize|
283
+ tokenize.prefix = SpaceParser.new
284
+ tokenize.postfix = SpaceParser.new
248
285
  end
249
286
 
250
287
  result = parser.parse(" abc")
@@ -256,9 +293,9 @@ class YaparcTest < Test::Unit::TestCase
256
293
  assert_instance_of Result::Fail, result
257
294
  assert_equal "\n abc", result.input
258
295
 
259
- parser = Tokenize.new(Ident.new) do |tokenize|
260
- tokenize.prefix = WhiteSpace.new
261
- tokenize.postfix = WhiteSpace.new
296
+ parser = TokenizeParser.new(Ident.new) do |tokenize|
297
+ tokenize.prefix = WhiteSpaceParser.new
298
+ tokenize.postfix = WhiteSpaceParser.new
262
299
  end
263
300
 
264
301
  result = parser.parse(" \n abc")
@@ -267,11 +304,31 @@ class YaparcTest < Test::Unit::TestCase
267
304
  assert_equal "", result.input
268
305
  end
269
306
 
307
+ def test_tokenize_without_block
308
+ parser = TokenizeParser.new(Ident.new, :prefix => WhiteSpaceParser.new, :postfix => WhiteSpaceParser.new)
309
+
310
+ result = parser.parse(" abc")
311
+ assert_instance_of Result::OK, result
312
+ assert_equal "abc", result.value
313
+ assert_equal "", result.input
314
+
315
+ parser = TokenizeParser.new(Ident.new, :prefix => SpaceParser.new, :postfix => SpaceParser.new)
316
+ result = parser.parse(" \n abc")
317
+ assert_instance_of Result::Fail, result
318
+ assert_equal "\n abc", result.input
319
+ end
320
+
270
321
  def test_identifier
271
322
  parser = Identifier.new
272
323
  result = parser.parse(" abc ")
273
324
  assert_equal "abc", result.value
274
325
  assert_equal "", result.input
326
+ result = parser.parse(" _abc ")
327
+ assert_instance_of Result::OK, result
328
+ result = parser.parse(" 0_abc ")
329
+ assert_instance_of Result::Fail, result
330
+ result = parser.parse(" _00abc ")
331
+ assert_instance_of Result::OK, result
275
332
 
276
333
  parser_with_keyword = Identifier.new("abc","efg")
277
334
  result = parser_with_keyword.parse("abc")
@@ -294,5 +351,12 @@ class YaparcTest < Test::Unit::TestCase
294
351
  assert_equal "%", result.value
295
352
  assert_equal "", result.input
296
353
  end
354
+
355
+ def test_literal_parser
356
+ parser = LiteralParser.new('%')
357
+ result = parser.parse(" % ")
358
+ assert_equal "%", result.value
359
+ assert_equal "", result.input
360
+ end
297
361
  end
298
362