[EMAIL PROTECTED] writes:
> > This won't work.  I think (but my knowledge of parsing is quite
> > limited.  I will change that soon) that the number of 'contexts' is
> > quite large in practice.  (because of transformations bison makes.
> > Run bison -v for fun some time.)
> 
> I was not using "context" to refer to the states of the parsing
> machine.  If \shape appears in some totally bizarre place, then "parse
> error" seems more reasonable.  It's when \shape appears at the top
> level, or in the \midi block, for example, that I think there should
> be a reasonable message.  When \shape appears in the wrong block the
> input LOOKS syntactically correct.  Assuming the \shape command is a
> correct one, then it is parsable.  

We could get over this by writing our own  recursive descent parser,
but then we had better be very sure that we don't have to change the
language any further.  Modifying a .y file is very easy. Modifying a
hand-made parser is a lot of work.

> I'm not totally convinced that this is impossible.  It might be tricky
> or a bit complicated, though.  I think that doing it the way I
> proposed involves a mid-action rule which the manual says can be
> troublesome.
> 
> Let me give a simple example of what I was thinking.  The \shape
> command is permitted only within \paper.  It can appear absolutely
> nowhere else, as far as I can tell.  So 
>    \paper{ \KEYWORD { \shape ...}}
> is illegal because the shape isn't right inside the \paper.  
> 
> So this can be implemented using the flag as I mentioned something
> like this:
> 
>    PAPER '{' {pushflag(); flag=INPAPER;} statement '}'
>             { do_default_paper_action();
>               popflag();
>             }
> 
>    OTHERKEYWORD '{' {pushflag(); flag = SOMETHINGELSE; statement '}'
>      ...
>       etc
> 
> Every keyword that changes the context stores the old value of the
> flag on a stack and sets a new value.  

Yep.  This is a very error prone coding style.  I am against this, for
it will generate lots of bugs.  As I said, if this can somehow be done
without all the overhead (by massaging Bison), it's a lot better.

> Then there is a rule for statement that looks like
> 
>    statement: SHAPE dimarray ';'
>      { if (flag==INPAPER) { do_normal_shape_handling();}
>        else { produce_error("\\shape only allowed in \\paper\n"); }
>      }


You forget about passing around values. do_normal_shape_handling ()
needs a Paper_def structure to do something useful.  

To make this whole scheme work, you also have to pass around a lot
pointers, and make sure that they are of the correct type and are cast
correctly.  A lot of work, and that makes for a lot of bugs.

> But it seems like enough work has been done, and enough thought has
> already been put into designing the real grammar that the time has,
> perhaps, been reached to write an abstract grammar.  You know

Maybe.  But since the real grammar is not near what I'd like it to be,
*I* prefer working on the real grammar for now (but do go ahead with
the abstract grammar).

I'll give my idea of the `abstract grammar' now (* = 0 or more, ? = 1
or 0, + = more than one) (the music_def is like the current Music
thing, expression is more or less like the current righthandside for
assignment), maybe you can get a feel for how I view the language. An
important point, is that to me the language is mainly made of
expressions (for music) and dictionaries (for conversions).


mudela: statement*
        ;

statement:
        identifier_assignment
        | global_expression
        ;

/* set default paper, default header, etc. 
        a global output_def adds one to the list of outputs.
*/
global_expression:  
        expression
        ;

identifier_assignment:
        STRING '=' expression ';'
        ;

output_command:
        SCORE '{' music_def header_def? output_def* '}'
        ;

header_def:
        HEADER dict
        ;

output_def:
        output_type dict
        ;

output_type:
        PAPER
        | MIDI
        ;

dict: '{' identifier_assignment* '}'
        ;

expression:
        music_def
        | translator_def
        | int
        | real
        | output_def
        | dict
        | intlist
        ;

> something about the problem you're trying to solve.  You can always
> rewrite the abstract grammar later if you realize (as a result of
> better understanding of the problem) that it has deficiencies.  
> The other option is to continually extend your real grammar in an
> ad-hoc fashion.  Is that really preferable?  

-- 

Han-Wen Nienhuys, [EMAIL PROTECTED] ** GNU LilyPond - The Music Typesetter 
      http://www.cs.uu.nl/people/hanwen/lilypond/index.html 

Reply via email to