Thanks for the feedback- glad Sprache is working for you.
The feature you're looking for is already implemented in the source repository but hasn't been built into a new release. Checking out the code and building it yourself is probably the fastest way to go, another official release is still a little while away.
Cheers,
Nick
On 28/04/2011, at 2:58 AM, BradW <bra...@gmail.com> wrote:
> Hello, Sprache is a life saver for us! I’ve re-written our DSL parser
> with it, and it’s a great improvement. Our parser is now 250 lines of
> readable rules, replacing 500 lines of spaghetti code in our hand-
> rolled parsing class.
>
> Now I am wanting to show better error messages to the user, especially
> showing the line number rather than the char position number. Is there
> any documentation or example of producing more information in error
> messages?
>
> Thanks,
> Brad
Thanks. I ended up parsing the character count out of error message
and then compute the line number from that, not ideal but fairly
simple anyway. Now that I have your source will look for where you
report the error line number.
Next issue on error messages: I was able to get the error messages to
appear as desired on the smallest granular parser by using XMany().
However, this is forcing me to change my language so that two elements
that can appear in lists ("Questionnaire" and "QuestionGroup") will
NOT both start with "Q". So changing the second to just "Group"
solved that.
Of course this is not ideal to have to change the language definition.
I am wondering what you think of making a String parser (maybe call
it XString) to be more aggressive than just finding a "partial match"
on the first character, and instead require that it either match the
*entire string* or return a failure. I was trying to come up with
alternate XString parser to act this way, but I don't know if it will
work -- I don't understand enough of how this code works. Do you
think this is not going to work out, like there is no way to create an
XString parser to work this way? (Warning: I haven't even run this
code, but I think you see what I'm trying to accomplish...to do NO
i.Advance() unless we know that the entire string I'm looking for is
going to match...)
public static Parser<IEnumerable<char>> XString(string s)
{
return i =>
{
if (!i.AtEnd)
{
var remainingString = i.Source.Substring(i.Position);
if (remainingString.Length >= s.Length)
{
if (remainingString.Substring(0, s.Length) == s)
{
for (int c = s.Length; c > 0; c--)
i.Advance();
return new Success<IEnumerable<char>>(s, i);
}
}
return new Failure<IEnumerable<char>>(i,
() => string.Format("unexpected '{0}'", i.Current),
() => new[] { "expected " + s });
}
return new Failure<IEnumerable<char>>(i,
() => "Unexpected end of input reached",
() => new[] { "expected " + s });
};