> Here's a compromise: perhaps the parser can have a function like the above > that takes only one tune, that is, takes a string that starts with "X:", and > ends just before the next "X:" command. Then there would be a super-parser > (trivial to write) that breaks the string on "X:" boundaries. I'm guessing > that most applications would be concerned with just one tune at a time, > anyway.
Actually, this is sort of close to what my parser is doing, but you're missing one *very* important thing -- the file fields. At the beginning of the file (prior to the first X: or T:) and in-between tunes (ie. After the first blank line in a tune, which ends the tune, and before the next X: or T:) there may be a variety of settings which can affect the remaining tunes in the file. In the ABC spec, these are the fields marked "Yes" for "File". Their existence complicates the job considerably. Note that while ABC 1.6 and 1.7.6 explicitly allow these fields in-between tunes, ABC 2.0 draft states they can only be at the beginning of a file. (There really ought to be a note about this in the Deprecated Syntax section... Or the restriction should be lifted.) You have four main approaches for dealing with these: 1) Parse the entire file sequentially. 2) Break it up into individual tunes, and ignore all the file fields 3) Break it up into individual tunes, and only allow file fields at the start of the file. (ie. ABC 2.0 style) 4) Break it up into individual tunes, but still support the file fields even if they're in-between tunes. I chose the 4th option. What I do is have my first pass parser break the file up into two types of section - global context sections (ie. Anything that isn't a tune - which includes file fields...) and tune sections. The first global context section is then parsed, creating a context object. That object is cached, and also passed to the parser for the next global context section repeatedly, resulting in a set of context objects, each of which corresponds to the context at the end of that global context section. This actually happens fairly quickly for most tune files, since there are frequently NO global context sections, or the only one found is at the beginning of the file. But I have the whole procedure anyway because the spec allows for these fields anywhere in-between tunes. Then, when I go to parse any given tune section, I pass in the context object for the last global context section that precedes the tune in the file. One other thing to be careful of in your first pass parser, should you go this route, is handling ABC 2.0 style continuation lines, and dealing with multi-line History fields. -->Steve Bennett To subscribe/unsubscribe, point your browser to: http://www.tullochgorm.com/lists.html