yaparc 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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