[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Round the Java rough edges
From: |
Joel E. Denny |
Subject: |
Re: [PATCH] Round the Java rough edges |
Date: |
Fri, 9 Mar 2007 13:49:13 -0500 (EST) |
On Fri, 9 Mar 2007, Paolo Bonzini wrote:
> >> Always define a public Lexer interface.
> >
> > Is it possible for the user to add methods to it? Otherwise, the only
> > YYLexer methods available in the parser semantic actions are the inherited
> > Lexer methods provided by Bison, right?
>
> He can downcast. But you have a point here.
>
> > Wouldn't "%code lexer" be more useful for the parent Lexer?
>
> It would be if the parent were an abstract class. Since it is an interface,
> it's much less interesting to add things there.
I'm thinking it's inconvenient to downcast everywhere, so being able to
add methods to the interface would be nice. I'm not sure what the
performance implications of downcasting are in Java.
> > It still would seem simpler to me if the user could work completely within
> > the Lexer parent just as he does for the parser class. That is, he would
> > only subtype Lexer (and possibly make Lexer an interface) if a Lexer
> > hierarchy actually made sense for his application.
>
> Unfortunately, I have to provide a parent for the user lexer class,
> in order to make it a compile error if the user forgets a method.
If a method is actually invoked anywhere but the user forgets to declare
it in Lexer, it will be a compile error anyway, right? This is similar to
when the user forgets yylex or yyerror in Yacc parsers.
Then again, it occurs to me now that the Lexer interface gives Bison a way
to inline method documentation for Javadoc. This documentation shows
what's actually required of these methods by the rest of Bison-generated
code. That's nice, and I'm not sure how that would be possible if the
user were to define these methods directly in Lexer.
As a solution to all of the above issues in this email, what if you keep
Lexer as an interface, drop "%code lexer", and add "%define
lexer_type_name", which would specify the name of the user-defined subtype
of Lexer? I believe that would keep things simple and consistent.
Moreover, the parser class could use lexer_type_name as the type of its
Lexer member (to avoid downcasts) and of the Lexer argument in the parser
class constructor. If the user wanted to make his Lexer subtype an
interface or abstract class or final or whatever, that would be totally up
to him because he would define the type entirely.
Now, if you wanted to guarantee that the user defined his lexer type to
extend/implement the Lexer interface, Bison could add something like this
to the parser class constructor:
Lexer lexer_interface = lexer_arg;
Type compatibility here is checked statically at least by gcj. Maybe
there's a better way to check this.
> >>> 4. Provide "%define parser_class_modifiers" and "%define
> >>> lexer_class_modifiers" to specify abstract, interface, final, or other
> >>> modifiers on these classes. Contains just public by default?
> >
> >> For the parser, I'm still using "%define public" and "%define abstract"
> >
> > What about final?
>
> I don't think there's a good reason *ever* to use final. In fact, I'm
> going to be coherent and remove it from the "%code lexer" class.
It's supposed to avoid dynamic lookup and thus improve performance, which
is usually important for parsers.