Boost logo

Boost Users :

Subject: Re: [Boost-users] [proto] concise error messages
From: Eric Niebler (eric_at_[hidden])
Date: 2010-01-22 23:45:17


On 1/23/2010 9:46 AM, Manjunath Kudlur wrote:
>
> I wrote a small DSEL with proto. An example program can be found in
> the main function below. I use BOOST_MPL_ASSERT_MSG to check an
> expression against a grammar, and can make the compiler output a small
> string if the syntax is wrong. But I can do it only for the entire
> program. Is there a way to do finer grain grammar checking with proto?
> For example, I haven't defined the "<" operator for expressions, but
> when I use it in the DSEL code, I get 10 pages of error messages from
> g++, with the SYNTAX_NOT_CORRECT string somewhere. I would like to get
> somewhat more accurate than this. Any pointers?

There is currently no way to do error reporting at anything but the
top-level with Proto. And you can only get a yes/no answer from
proto::matches at that level, so you can't really provide users with
feedback about what specifically is wrong with their expression. It's a
known shortcoming. But see below for a suggestion about how to deal with
gcc's error reporting.

<snip>

> template<typename Expr>
> void check_grammar(const Expr&e)
> {
> BOOST_MPL_ASSERT_MSG((proto::matches<Expr, napl_grammar>::value),
> SYNTAX_NOT_CORRECT,
> (void));

OK, you detect and report errors ...

> cout<< napl_grammar()(e)<< "\n";
> }

... but then you unconditionally try to evaluate the expression anyway.
Gcc doesn't stop on the first error. If you pass this function an
invalid expression, gcc will issue the error caused by
BOOST_MPL_ASSERT_MSG in addition to any errors caused by then trying to
evaluate an invalid expression.

Instead, you should put the actual expression evaluation in a separate
function, as follows:

// called for valid expressions
template<typename Expr>
void check_grammar_impl(const Expr& e, mpl::true_)
{
    cout<< napl_grammar()(e)<< "\n";
}

// called for invalid expressions
template<typename Expr>
void check_grammar_impl(const Expr& e, mpl::false_)
{
     // no-op
}

template<typename Expr>
void check_grammar(const Expr&e)
{
    BOOST_MPL_ASSERT_MSG((proto::matches<Expr, napl_grammar>::value),
                         SYNTAX_NOT_CORRECT,
                         (void));
    // Dispatch to the correct impl depending on whether we have
    // a valid expression or not.
    check_grammar_impl(e, proto::matches<Expr, napl_grammar>());
}

That should reduce the noise gcc emits when your users create invalid
expressions.

HTH,

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net