[Top][All Lists]

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

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

From: Anthony Heading
Subject: Re: trying out the c++ parser skeleton / b4_post_prologue
Date: Wed, 12 Jul 2006 09:22:41 -0400
User-agent: Thunderbird (Windows/20060516)

Akim Demaille wrote:
Could you please detail why you'd like to do that?  For several
reasons, including recursion support, I think the proper way to extend
the parser is to couple it with a parsing driver.

Yes, I did read the example in the docs, and thought it an odd design.
Perhaps you also could expand on those reasons - here are my thoughts as
an end-user.

First, it is very natural in C++ for a programmer to link in some
types of application-specific code by providing an implementation of
an abstract interface. See e.g. Stroustrup C++PL ch. 24, MFC, Qt, etc.
I was surprised to find, for example, that in this bison-c++, the
interface to the lexer is not created as an abstract virtual function
for the end-programmer to implement, but instead remains a C macro.
Obviously this isn't wrong per se, but there has been a decade of
aggregate common thinking (agree with it or not) about how ideally
C++ code should differ from C, and the bison-c++ design differs
enough in many areas from this convergence of practice that I found
it unintuitive and hard to use. Therefore I chose to ignore the
documentation example, and instead read the skeleton source code.

Your parsing-driver suggestion leads the semantic action code to be
filled with references to a driver handle. | TOKEN_IDENTIFIER { $$ = driver.variables[*$1]; }

This is the main reason for my attempt to subclass.  To me, this is
unacceptable - the programmer should totally own the scope in
which the semantic actions are being executed.  Yacc has always
allowed this.  But in C++, there is the huge benefit that this
scope can transparently be an _instance_ of a parser, which
surely is a great tool to solve many of the recursion problems.

If I were starting again, I would flip your parser/parsing-driver
relationship, and have the semantic action code generated within
the scope of the parsing driver, i.e. within the scope of a
user-extensible class which maintains the semantic state.  I would
certainly make bison not the user do the boilerplate work: e.g. "$1" conceptually can be automatically expanded to
"yy_parser_instance_->yysemantic_stack_[1]" so that bison reaches
out to find the parser class, the user isn't required to reach
to find his driver via e.g "driver.variables".  But then I'd
go further to suggest that the parser-driver should inherit from
the parser rather than being in a strange peer relationship, because
there's enormous support within the C++ language for that type
of design.

But probably we're not starting again, so I'm not sure what to
suggest.  I've spent another couple of hours this morning studying
the code while composing this response, and I begin to understand
the frustration expressed by e.g. Hans.  So in my now somewhat-
considered view, the current C++ skeleton is a poor design, and
I'm inclined not to use it.
That's a bit troublesome though, because a non-POD C++ YYSTYPE
is a very desirable thing, and I don't believe that works fully
with the C parser.  And as Hans mentions, bison isn't static
enough for a user to maintain their own skeleton.  Hmm...

Thanks for the responses.



reply via email to

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