August 07, 2012
On 8/7/2012 2:14 PM, Jonathan M Davis wrote:
> I expect that the configuration stuff is going to have to be adjusted after I'm
> done, since I'm not sure that it's entirely clear what's worth configuring or
> not.

"When in doubt, leave it out."

If experience later shows it is really needed, it is easier to add it in than to have a blizzard of useless configuration options that cannot be removed.
August 07, 2012
Jacob Carlborg , dans le message (digitalmars.D:174421), a écrit :
> On 2012-08-07 12:06, Jonathan M Davis wrote:
> 
>> It's easier to see where in the range of tokens the errors occur. A delegate is disconnected from the point where the range is being consumed, whereas if tokens are used for errors, then the function consuming the range can see exactly where in the range of tokens the error is (and potentially handle it differently based on that information).
> 
> Just pass the same token to the delegate that you would have returned otherwise?

That's what I would do. If you have to define a way to return error
information as a token, better use it again when using delegates.
Personnaly, I would have the delegate be:
int delegate(Token);
A return value of 0 means: continue parsing. Any other value is an
error number and stops the parser (makes it empty). The error number
can be retrieved from the empty parser with a specific function.
If you want to throw, just throw in the delegate. No need to return a
specific value for that.

But a bool return value may be enough too...
August 07, 2012
On Tuesday, August 07, 2012 14:30:51 Walter Bright wrote:
> On 8/7/2012 2:14 PM, Jonathan M Davis wrote:
> > I expect that the configuration stuff is going to have to be adjusted after I'm done, since I'm not sure that it's entirely clear what's worth configuring or not.
> 
> "When in doubt, leave it out."
> 
> If experience later shows it is really needed, it is easier to add it in than to have a blizzard of useless configuration options that cannot be removed.

On the whole, I agree, and I'm definitely leaving some of that stuff out at this point. A simplified version of what I have at the moment is

struct LexConfig { /+ configuration options +/}

struct Lexer(alias config)
 if(is(typeof(config) == LexConfig))
{
 auto lex(R)(R range, SourcePos pos = SourcePos.init) {}
}

The main problem that I have is that if I end up with any delegates which need to take the range being lexed, then either I can't put them in the Lexer like I am with the error handler delegate (forcing you to pass it to the lex function every time that you lex a new range), or I have to templatize Lexer on the range type, which is also undesirable.

If it turns out later that we want to add such delegates and we didn't templatize Lexer on the range type, then we'll be forced to make it so that they're arguments to the lex function. But templatizing the Lexer on the range type is ugly enough that it's not really something that I want to do if I can reasonbly avoid it. Neither solution appeals to me. If we don't ever need to add such delegates, then it doesn't really matter, but I'd prefer to have a solution which is appropriately flexible if we _do_ need to add that sort of thing later.

I guess that I'll have to keep thinking about it to see if I can come up with a reasonable way to do it without hampering the API by either making it ugly through unneeded flexibility or by making it too simple to be able to reasonably add more functionality later.

- Jonathan M Davis
10 11 12 13 14 15 16 17 18 19 20
Next ›   Last »