> 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

Reply via email to