[proto] grammar compile error

Hello, When I have a grammar like this: struct create_table_grammar : boost::proto::shift_left < boost::proto::shift_left < boost::proto::terminal<tags::create> , boost::proto::terminal<tags::table> > , boost::proto::terminal<const char*>
{}; And this expression: create << table << "lala"; Where create and table are terminals with the respective tags. I have this compile error: examples/test1.cpp: In function ‘int main()’: examples/test1.cpp:12: error: no match for ‘operator<<’ in ‘sql::keywords::create << sql::keywords::table’ If I don't inner expressions, then (create << table) works. But I can't define a more restricted grammar this way. I want create << table to work only when preceded with another specific expression. I wanted create << table to be enabled, but to disable everything else except (create << table) << ""; Is this possible? Thanks, -- Felipe Magno de Almeida

Felipe Magno de Almeida wrote:
Hello,
When I have a grammar like this:
struct create_table_grammar : boost::proto::shift_left < boost::proto::shift_left < boost::proto::terminal<tags::create> , boost::proto::terminal<tags::table> > , boost::proto::terminal<const char*>
{};
And this expression:
create << table << "lala"; Where create and table are terminals with the respective tags.
I have this compile error: examples/test1.cpp: In function ‘int main()’: examples/test1.cpp:12: error: no match for ‘operator<<’ in ‘sql::keywords::create << sql::keywords::table’
Right, because the expression "create << table" doesn't match the grammar you've defined above.
If I don't inner expressions, then (create << table) works. But I can't define a more restricted grammar this way. I want create << table to work only when preceded with another specific expression. I wanted create << table to be enabled, but to disable everything else except (create << table) << "";
Is this possible?
Not directly. You will have to allow "create << table" in your grammar (possibly by not specifying any grammar when defining your domain, or else by specifying a loose one), and then define a /separate/ grammar that validates fully formed expressions for correctness. Presumably somewhere in your code there is a place where these expressions get evaluated. That's the place to ensure that "create << table" is always followed by a string literal. For that, you would use BOOST_MPL_ASSERT and proto::matches. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Sat, Jul 4, 2009 at 1:57 PM, Eric Niebler<eric@boostpro.com> wrote:
Felipe Magno de Almeida wrote:
[snip]
Is this possible?
Not directly. You will have to allow "create << table" in your grammar (possibly by not specifying any grammar when defining your domain, or else by specifying a loose one), and then define a /separate/ grammar that validates fully formed expressions for correctness.
Yes, I found that out. I'm planning in creating a full_grammar, which would only match a full expression. This can be passed as a compile-time assert to the expression evaluation. And I want to create the looser grammar, composed of all sub-expressions inside the full grammar somehow. Is there a way to do this in proto, or should I start creating it with mpl? Is there a way to iterate a grammar?
Presumably somewhere in your code there is a place where these expressions get evaluated. That's the place to ensure that "create << table" is always followed by a string literal. For that, you would use BOOST_MPL_ASSERT and proto::matches.
HTH,
-- Eric Niebler BoostPro Computing http://www.boostpro.com
Thanks, -- Felipe Magno de Almeida

Felipe Magno de Almeida wrote:
And I want to create the looser grammar, composed of all sub-expressions inside the full grammar somehow. Is there a way to do this in proto, or should I start creating it with mpl? Is there a way to iterate a grammar?
This sounds like more work than is truly necessary. There is really only one good reason to specify a grammar when defining a domain, and that is to disable troublesome operator overloads. My suggestion would be to not specify your dsel's grammar up front, but rather only validate full expressions at the point of evaluation. You lose no safety that way. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Sat, Jul 4, 2009 at 2:29 PM, Eric Niebler<eric@boostpro.com> wrote:
Felipe Magno de Almeida wrote:
And I want to create the looser grammar, composed of all sub-expressions inside the full grammar somehow. Is there a way to do this in proto, or should I start creating it with mpl? Is there a way to iterate a grammar?
This sounds like more work than is truly necessary. There is really only one good reason to specify a grammar when defining a domain, and that is to disable troublesome operator overloads. My suggestion would be to not specify your dsel's grammar up front, but rather only validate full expressions at the point of evaluation. You lose no safety that way.
Defining a grammar loosely is harder than specifying it fully. Doing it fully, all I need to do is: shift(create, table, table_name, columns) and I'm done. But if I do it for all partial expressions, I might forget something. I'm trying to define a SQL grammar. Having it checked earlier, helps me traversing it later, since I know it is right. Also, it prohibits most expressions right away, giving better error messages. I wouldn't have to check later on if there's a non-sensical terminal anywhere. create << table << create would have no overloads. All I need is to traverse a grammar, and define another grammar with all sub-expressions. Since the grammar is not very big, it shouldn't be too hard on the compiler (I hope). Though I'm not very experienced with proto yet. Is transforming a grammar a really difficult task?
-- Eric Niebler BoostPro Computing http://www.boostpro.com
-- Felipe Magno de Almeida

Felipe Magno de Almeida wrote:
On Sat, Jul 4, 2009 at 2:29 PM, Eric Niebler<eric@boostpro.com> wrote:
There is really only one good reason to specify a grammar when defining a domain, and that is to disable troublesome operator overloads. My suggestion would be to not specify your dsel's grammar up front, but rather only validate full expressions at the point of evaluation. You lose no safety that way.
Defining a grammar loosely is harder than specifying it fully. Doing it fully, all I need to do is: shift(create, table, table_name, columns) and I'm done.
Agreed.
But if I do it for all partial expressions, I might forget something. I'm trying to define a SQL grammar. Having it checked earlier, helps me traversing it later, since I know it is right.
I don't see it. You also know it's right if you check the full expression against your full grammar before you traverse the expression.
Also, it prohibits most expressions right away, giving better error messages.
This is not true. "Checking early" means dropping operator overloads via SFINAE, leading to error messages like "no operator << matches with arguments [complicated type 1] and [complicated type 2]" followed by a so-called candidate list, the list of every operator overload that didn't match. This is usually a huge and impenetrable error. But if you do a late check against the full expression with BOOST_MPL_ASSERT and proto::matches, the error is much shorter and takes users directly to a line of code that looks like this: BOOST_MPL_ASSERT((proto::matches< SqlExpression, SqlGrammar >)); That makes the error much more understandable.
I wouldn't have to check later on if there's a non-sensical terminal anywhere.
create << table << create would have no overloads.
All I need is to traverse a grammar, and define another grammar with all sub-expressions. Since the grammar is not very big, it shouldn't be too hard on the compiler (I hope). Though I'm not very experienced with proto yet.
Is transforming a grammar a really difficult task?
You're setting yourself up to climb a mountain, and I don't think you'll like the view from the top. My $0.02, -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Sat, Jul 4, 2009 at 10:35 PM, Eric Niebler<eric@boostpro.com> wrote:
Felipe Magno de Almeida wrote:
[snip]
Is transforming a grammar a really difficult task?
You're setting yourself up to climb a mountain, and I don't think you'll like the view from the top.
LOL. I gave up that idea. I have a create table command already working now. BTW, Proto is even more awesome now than it was the last time I played with it. When it was still inside xpressive directory.
My $0.02,
Thanks.
-- Eric Niebler BoostPro Computing http://www.boostpro.com
Regards, -- Felipe Magno de Almeida

Eric Niebler wrote:
This is not true. "Checking early" means dropping operator overloads via SFINAE, leading to error messages like "no operator << matches with arguments [complicated type 1] and [complicated type 2]" followed by a so-called candidate list, the list of every operator overload that didn't match. This is usually a huge and impenetrable error. Well, in my own experience, I got the following kind of message :
'no operator <foo> for type<A> and <B>' and no 'candidates are:' entry. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35
participants (3)
-
Eric Niebler
-
Felipe Magno de Almeida
-
joel