On 12/15/08 3:12 PM, "Trevor Bača" <trevorb...@gmail.com> wrote:
> On Mon, Dec 15, 2008 at 2:09 PM, Han-Wen Nienhuys <hanw...@gmail.com> wrote:
>> On Mon, Dec 15, 2008 at 5:25 PM, Carl D. Sorensen <c_soren...@byu.edu> wrote:
>>>>
>>>>
>>>>
>>>> On 12/15/08 7:18 AM, "Han-Wen Nienhuys" <hanw...@gmail.com> wrote:
>>>>
>>>>
>>>>>> Try not to form mental models. Use the source instead.
>>>>
>>>> Unfortunately, not very many of us understand the source completely, and so
>>>> we need mental models to work in LilyPond. Of course, our mental models
>>>> will be incorrect in some detail, and we'll need to revise them from time
>>>> >> to
>>>> time.
>>
>> sure, but if you spend a lot of time and effort on theorizing (like
>> Trevor did), you might as well invest that time & effort into looking
>> at the source code itself.
>
> I think both are good: wanton speculation taken together with digging through
> source.
>
> :-)
>
> I've been digging through source this morning ... and I'm understanding much
> better ... but still unable to resolve at least one example, which I've
> included at the end of this message.
>
> What I've found so far:
>
> * There are 22 -iterator.cc files with Music_iterator being the base class
> from which the others all directly (or, more usually, indirectly) inherit.
> (Simple_music_iterator, Music_wrapper_iterator and Sequential_iterator are all
> popular choices to derive from, too, but all three inherit from Music_iterator
> at base.) Concrete iterators exist to iterate over regular stuff like
> EventChord and and 'simple music' (which parser.yy makes me think means
> basically notes and rests). Iterators also exist to iterate over more complex
> music expressions like grace music, time-scaled music, voltas, and music
> expressions passed to the \unfold command. My understanding of this flock of
> iterators available in the C++ source is as a type of realization of the
> visitor pattern that separates traversal from other activities like
> calculation and modification.
>
> * Additionally, both the comments at the head of music-iterator.hh and Erik's
> thesis make it clear that the object over which the different iterators
> iterate is a (conceptual) queue of music events *that all happen at the same
> moment*. That is, when it comes time to iterate, the first thing that happens
> is that the entire context tree (starting from the Global context and
> proceeding all the way to bottom-level voice contexts) are *prepared* for
> Moment 0; then iterators iterate over all events that happen at Moment 0 *no
> matter at which level of the context tree those different events occur*. This
> helps because I was assuming (wrongly) earlier that iteration would be a
> depth-first search starting from the root of the expression tree; if that were
> the case then each context would be visited before any of its children. But,
> in fact, section 9.4 of Erik's thesis says "One of the consequences of a
> OneTimeStep stream event, is that all contexts are visited in a post-order
> tree walk; i.e., each context is visited after all its children have been
> visited." I haven't been able to verify this in the code, however.
>
> * I've also found that a pronouncement like "\new Voice { c'4 }" is actually
> THREE expressions. The "\new Voice" is actually a music expression all by
> itself (of type ContextSpeccedMusic). There is a
> Context_specced_music_iterator defined in an eponymous .cc file and inheriting
> from Music_wrapper_iterator. The purpose of the Context_specced_music_iterator
> is to descend to the one (and only one) child that each ContextSpeccedMusic
> like "\new Voice" music have: something like Sequential is the usual option.
> So the parser (which I only understand vaguely) decomposes "\new Voice { c'4
> }" into three expressions with "\new Voice" parsed as ContextSpeccedMusic,
> with "{ }" parsed as Sequential, with "c'4" parsed as EventChord (I think).
> Further, the parser builds the resulting music expression such that
> ContextSpeccedMusic is the parent of Sequential which is, in turn, the parent
> of EventChord.
>
> * Also, all parsing is done before any iteration is done.
>
> * OK, so based on this understanding, can somebody please correct my
> understanding of the parsing (not the iteration, just the parsing) of the
> following expression (which is the same as my original example #2):
>
> {
> \new Voice {
> c'8 c'8 c'8 c'8
> }
> d'8 d'8 d'8 d'8
> }
>
> If I'm understanding how the parser works, then what should result here is a
> music expression that looks like this:
>
> Global
> V
> \new Score
> V
> \new Staff
> V
> \new Voice
> V
> Sequential
> V
> \new Voice, d'8, d'8, d'8, d'8
> V
> Sequential
> V
> c'8, c'8, c'8, c'8
>
>
> If I'm counting correctly, that's 15 total nodes in the expression tree. Eight
> atomic nodes and seven internal nodes. The Global, \new Score, \new Staff and
> the first \new Voice are all created implicitly.
>
> I know that the next part in the process is iteration. But I want to stop and
> check my understanding here: am I understanding the output of the parser
> correctly at this point?
>
>
> Trevor.
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel