In message <[EMAIL PROTECTED]>, Paul Rosen
<[EMAIL PROTECTED]> writes
>I see two tasks: agreeing on the data structure that is the output, and
>actually writing the parser. I envision a function that looks something like
>this:
>
>    bool bSuccess = ParseABC(const char* szSource, CMusic& output,
>CParsingErrors& errors);

There is another approach. I haven't seen it mentioned, so I apologize
if I am covering old ground. I have seen ABC files with 17000 tunes in
them. They take a long time to parse :-)

A different approach to parsing an error handling would be via a
callback function

int parseABC(const char                 *szSource,
                abcParserControlFlags   flags,
                callbackFunc);

returned int is number of errors, or status code

callbackFunc would be the function prototype for the callable function.

The callback would look something like this:

ABC_ERROR_CODE callback(const char              *abcPhrase,
                                 ABC_PARSER_TOKEN       id,
                                DWORD           dataLen,
                                 void                   *data);

where:
abcPhrase would be the optional abc text that was parsed (could be a
bar, a single note, a line).

Id would be information from the parser telling you what is in dataLen
and data. Id could also be an error status (which is one reason why
abcPhrase is useful) for reporting a parse error mid-parse.

dataLen is the length of (data)
data is a pointer to data allocated by the parser to hold information
about the data referred to by (id). Depending on the id, data may point
to all sorts of data structures.

You could choose a slightly different approach where dataLen and data
are done away with and replaced by a abcData * object. The parser would
then pass data derived from this base class to the callback. This sounds
good until you realise that it'll be very hard to sensibly derived a
hierarchy for all abc datatypes and parser information from one root
structure.

The dataLen/data approach is probably friendlier to any non C/C++
language wishing to use the API.

Many XML parsers use the callback approach, although I'm not familiar
with the details of what they pass to the callback. There are merits for
a callback approach and demerits. Also the callback mechanism, to pass
data and length or objects derived from a common base class? Good and
bad in both.

Additionally, could pass flags to control what the parser passes to the
callback. Errors only, complete tunes only (so you get 17000 tune parsed
events for my example above), bars only (so you get 17000 times how many
bars in each tune for my example above), individual notation (you get
every event for the entire file). If the flags were a bitmask you could
get errors as well as the data. Some of the flags may turn on
compatibility options (AbcWin, BarFly, whatever).

Alternatively you may choose to have several callbacks, one for each
event type, etc. Although any callback user could piggy back that ontop
of the single callback.

Just some ideas.

Stephen
-- 
Stephen Kellett
Object Media Limited    http://www.objmedia.demon.co.uk
RSI Information:        http://www.objmedia.demon.co.uk/rsi.html
To subscribe/unsubscribe, point your browser to: http://www.tullochgorm.com/lists.html

Reply via email to