bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: trying out the c++ parser skeleton / b4_post_prologue


From: Akim Demaille
Subject: Re: trying out the c++ parser skeleton / b4_post_prologue
Date: Thu, 13 Jul 2006 14:39:03 +0200
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux)

>>> "Anthony" == Anthony Heading <address@hidden> writes:

 >> Obviously you can't add these new members in a subclass, since the
 >> user actions are run in the superclass.

 > Ah - I was certainly assuming a solution to that problem:  to achieve
 > what I was aiming for it would be necessary to have the actions run
 > with those members in scope.

But I can't see elegant means to achieve this.


 > OK.  My complaints are:
 >  1)  The pattern is not so intuitive - the simplicity is maybe relative

Well, the pattern is mostly useful if you want to do sophisticate
things, otherwise use a plain "context" is quite straightforward.

 >  2) The scope in which the semantic actions run seems to be wasted
 >  - it's not utilisable by the end-user for anything except a single
 >  "driver" variable.

What do you propose?


 > OK.  I guess there's more than one aspect to this.  Specifically, I
 > want to access the token table parser::yytname_[] from my "driver"
 > code.  This variable with many others are declared as private
 > members, which is a bit extreme given that they're fully accessible
 > in a C parser.

This is because I believe this "feature" was never designed, it just
"happened".  I'd much prefer to understand what are the concrete needs
from the user, and fulfill them via a call to an interface rather than
exposing implementation details.  yytname is a nice example of what,
imho, should not have been documented.  Rather, the function that is
in the documentation

for (i = 0; i < YYNTOKENS; i++)
  @{
    if (yytname[i] != 0
        && yytname[i][0] == '"'
        && ! strncmp (yytname[i] + 1, token_buffer,
                      strlen (token_buffer))
        && yytname[i][strlen (token_buffer) + 1] == '"'
        && yytname[i][strlen (token_buffer) + 2] == 0)
      break;
  @}

should be provided.  The user shouldn't have to copy it, it should be
provided.


 > With a nod to the benefits of encapsulation, I compromised by
 > changing the skeleton to make everything protected, which
 > admittedly begs the question as to the need to subclass :-).

I'm not eager to bind myself to implementation details.  If something
smarter than an array could be used, I'd be sad to be bound to it
because of a public or protected.

My strategy is more to look for the use cases, and them design the
interface that suits them.  I've been working for years on Autoconf
where far too much of the internals had been exposed, requiring huge
effort from the maintainers to try to maintain backward compatibility
while still addressing bugs or fixing bad details.

"By default private" is now my motto.

 > But anyway, there's a lot of such useful static data which it's
 > nice to be able to bring into scope in the way that an inheritance
 > relationship provides.

Such as?


 > Hmm.  Well, I'm wanting user actions to run in the context of the user-
 > controlled state, so I suppose I'm thinking that bison should write
 > out an implementation of a member function e.g. MyDriver::parse().
 > The user probably has to declare that himself.

A driver is not needed to run bison.  There is none for the simple
calculator for instance.  I'm not willing to make the basic example
more complex to make the complex one slightly simpler.  And actually,
the driver pattern is just what it is: a pattern, a suggestion.  The
user is free to do differently!  Including several members.


 >> There is one feature that Hans (and I, for one) wants for quite a
 >> while now, and that was technically difficult until very recently:
 >> %define for code.

 > I'll look forward to that.

Committed this morning.

2006-07-13  Akim Demaille  <address@hidden>

        Support %define "KEY" {VALUE}.
        * src/scan-code.h, src/scan-code.l (translate_action)
        (translate_rule_action, translate_symbol_action, translate_code):
        Return char *, not const char *.
        * src/parse-gram.y (declaration): Rename as...
        (prologue_declaration): this.
        (string_content): Remove this nonterminal, use STRING.
        (braceless, content, content.opt): New nonterminal.
        Use them.
        (%define): Now accept content.opt, i.e., accept also BRACED_CODE
        as value.
        * src/scan-gram.l (getargs.h): Don't include it.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]