>   1) To increase portability we should stick to plain ANSI C. I'm
perfectly
> fine with it. The "complications" I was referring to, Paul, were those
that
> you encounter when you try to access a C++ library from another language
> (including C).

Well, I see why you want to stick with C. I'll study this some and see if I
can answer the objections.

It seems like there is a lot of C++ that could be used without changing
anything from the outside. For instance, you'd probably stay away from
exceptions and RTTI. The output struct wouldn't have any virtual functions
or collections. The public routines would have [extern "C"] in front of
them. In the Windows side, we haven't run into this as an issue. We allow
plug ins to our product, and we allow users to write extensions to our
scripting language, and we've never gotten a customer who's said, "Why do I
have to use C++ instead of C?"

But, the main thing is not as much the parser as the API out of it. I think
that it makes sense to have the output be a C structure, then supply a C++
class that converts it to something convenient to use. Then it is maximally
portable, and still good for C++.

>   3) The library will keep the state internally. Steven Bennet gave an
> example about "C". In the present stage the scanner will return T_NOTE or
> T_CHORD together with the "C" string depending on the context, we need to
> extend this behaviour to the whole parser. In cases like "K:none" or "K:"
> the parser will not give any error, the callback will be called with
> something like P_FIELD_K and an empty string. It will be up to the handler
> to decide if reject it or not.

I think the output needs to be a level past your program. For example, it
needs to answer the question, "what is the next item to display?" with "a
middle C# quarter note that starts a tie with the chord A#dim over it and a
staccato dot over it." or "a double bar line that repeats on the left that
ends a first ending marking."

>   4) The parser will endorse ONE syntax and will try to accomodate for as
> many extensions as we can. I can see it's not easy, we have to come up
with
> a solution! Any suggestion?

I think that is a hard question. Our programs should certainly have a
"strict" mode, where we only output files that meet the newest standard, but
read any popular old formats, if possible. I know there are complications
and contradictions involved with that, but I think that is crucial. (Perhaps
we can have more than one parser, for each different "dialect" out there. We
could try to interpret the tune with each successive parser until it has no
errors.)

That reminds me, the parser should be two-way. We should have a function
that takes the structure, and turns it into an ABC string. Then, for
instance, a transposer program would look like this (pseudo-code follows):

string = ReadFile(filename);
ParseTune(string, structure);
for (int i = 0; i < structure.number_of_notes; i++)
{
    structure.note[i] += 2; // up one step
}
CreateABC(structure, string);
WriteFile(string);

>   5) Tom Satter rightly pointed out that we have to choices: having
callback
> that gets called  each time an element is found or creating the entire
> structure and offering an API for navigating into it. I do esitate to do
the
> latter because I've heard of ABC files with thousands of songs in it! I
> would like to be able ot handle them without requiring megs and megs of
> memory.
>   The idea in the proposal (please tell me if some point need
clarification,
> consider that english is not my first language) tries to accomodate this
> situation. It will offer a call back mechanism and a set of default
handlers
> that builds an internal rapresentation of the ABC file.
>   It's not clear to me if you support this approach or not!

I envision the parser working on the tune level, not the file level. I was
going to comment on the interface you had where one passes in a filename. I
would rather pass in the entire string of a single tune. Then the memory is
not an issue. That would also be convenient for many applications. For
instance, I knocked up a simple example where I had one window with ABC
code, and another window that showed the sheet music. Every time the user
typed a character I reparsed it and redrew the sheet music. I just grabbed
the text from the window and gave it to the parser. I wouldn't want to have
to save it just to have the parser read it in.

Now, if someone wanted to read in a whole file, it would be pretty simple to
have a super-parser that splits the file on the "X:" characters and feeds
the chunks one at a time to the parser, saving the output to an array. Then
the application controls the memory use, and if it wanted to burn memory, it
could, but it would never be surprised.

I don't like the callback idea because I'd like to have the app to control
the flow and ask for the data it needs. Also, I think having the output be a
C-structure means the app could manipulate it how it wants.

I know there is a complication to this in that there are some universal
things in a file, where a tune is more than just what is between the "X:"
indicators. We probably need to pass two strings, one with the universal
stuff, and the other with the tune itself. The super-parser would be
responsible for that, I guess.

>   6) As Paul Rosen suggested I had a look at MusicXML. I found it very
> complicated for my taste but I'm not able to judge if all those details
are
> necessary or not. For example, is it necessary to be able to traverse the
> score both by parts and by measures? I'm not sure I understand, my music
> background is too limited I think!
> Has anyone a suggestion on how the ABC file should be represented?

Yes, I found it more complicated than I had hoped, but I haven't had a
chance to study it. The advantage of MusicXML is that there is a free
project that is a parser for it. That project could be either a model for
ours (since it takes some text and turns it into a structure), or it could
serve as a bad example. In any case, the structure that it outputs probably
has exactly the fields we need.

ABC is simpler than MusicXML in that there are musical ideas that can be
expressed in MusicXML that can't be expressed in ABC. I think that is ok,
because most folk music can be expressed pretty simply. Nevertheless, if we
use the same structure, then ABC could grow into it with version 3.

The score-wise versus part-wise stuff in MusicXML was interesting. I'll take
their word that it is useful, because it looks like a lot of thought went
into it. Off the top of my head, I can see a real difference in when I'd
want to use part-wise versus score-wise. A barbershop quartet is probably
easier to read part-wise. A piano right hand is probably easier to read
score-wise.

>   7) I also do agree with Paul not to use commercial parsers, that's why I
> used re2c for the lexer. My candidate for the parser is lemon, as always
I'm
> open to suggestion.

I didn't say not to use a commercial parser, just that I don't know of one
that I would use. Actually, I'd like for someone to say, "Here's a hot,
object-oriented parser. Check it out." I'm just tired of YACC-type parsers
that make such a mess of the code.

Paul Rosen
--- Life is a musical, every once in a while
      the plot stops and you start singing and dancing ---
http://home.earthlink.net/~catharsis.music/
http://home.earthlink.net/~theplums/



To subscribe/unsubscribe, point your browser to: http://www.tullochgorm.com/lists.html

Reply via email to