I am sure this has been asked before, but I am not able to find an answer to my specific question in the archives. I wanted to create a grammar that can accept statements like if_(expr)[ statement-list ].else_[statement-list]. I created a if_expr type using proto::extends, and added a member called else_ to it, of type proto::function<proto::terminal<if_then_else>, Expr const&>. The code is given below. I am trying to match statements of the above form. Look for if_only_grammar and if_grammar below. The main function has 2 cases, one with just if_ and another with if_ and else_. My grammar matches neither of them. What am I doing wrong? I am quite the newbie to proto, so I am not still able to parse the compiler error message and understand it yet. I will be grateful for any help. Thanks, Manjunath #include <boost/proto/proto.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/assert.hpp> #include <iostream> #include <sstream> #include <string> using namespace boost; using namespace std; unsigned int ids; template<typename VT> struct Var { unsigned int id; Var() { id = ++ids; } }; struct if_fun {}; struct program {}; struct if_then_else {}; struct if_domain; template <typename Expr> struct if_expr : proto::extends<Expr, if_expr<Expr>, if_domain> { typedef proto::extends<Expr, if_expr<Expr>, if_domain> base_type; using base_type::operator =; typedef typename proto::result_of::make_expr<proto::tag::function, if_then_else, Expr const &>::type else_type; else_type else_; if_expr(Expr const &e = Expr()) : base_type(e) , else_(proto::make_expr<proto::tag::function>(if_then_else(), boost::ref(e))) {} }; struct if_domain : proto::domain<proto::generator<if_expr> > { }; struct napl_grammar; struct arith_expr_grammar; struct rel_expr_grammar; struct assign_grammar; struct statement_grammar; struct bb_grammar; struct if_only_grammar : proto::or_< proto::subscript<proto::function<if_expr<proto::terminal<if_fun>::type>, rel_expr_grammar >, bb_grammar>
{ };
struct if_grammar : proto::or_< if_only_grammar, proto::subscript<proto::function<proto::terminal<if_then_else>, if_only_grammar>, bb_grammar>
{ };
struct arith_expr_grammar : proto::or_< proto::plus< arith_expr_grammar, arith_expr_grammar>, proto::minus< arith_expr_grammar, arith_expr_grammar>, proto::multiplies< arith_expr_grammar, arith_expr_grammar>, proto::divides< arith_expr_grammar, arith_expr_grammar>, proto::terminal<Var<int> >, proto::terminal<int>, rel_expr_grammar
{ };
struct rel_expr_grammar : proto::or_< proto::less< arith_expr_grammar, arith_expr_grammar>, proto::greater< arith_expr_grammar, arith_expr_grammar>, proto::less_equal< arith_expr_grammar, arith_expr_grammar>, proto::greater_equal< arith_expr_grammar, arith_expr_grammar>, proto::equal_to< arith_expr_grammar, arith_expr_grammar>, proto::not_equal_to< arith_expr_grammar, arith_expr_grammar>, proto::logical_not< rel_expr_grammar>
{ };
struct assign_grammar : proto::or_< proto::assign<proto::terminal<Var<int> >, arith_expr_grammar>, proto::assign<proto::terminal<Var<int> >, rel_expr_grammar>
{ };
struct statement_grammar : proto::or_< assign_grammar, if_grammar
{ };
struct bb_grammar : proto::or_< statement_grammar, proto::comma<bb_grammar, statement_grammar>
{ };
struct napl_grammar : proto::or_< proto::terminal<program>, proto::subscript<proto::terminal<program>, bb_grammar>
{ };
template<typename Expr> void check_and_execute(const Expr &e, mpl::true_) { cout << "Program printer TBD.\n"; } template<typename Expr> void check_and_execute(const Expr &e, mpl::false_) { cout << "Should not be here\n"; } template<typename Expr> void check_grammar(const Expr &e) { BOOST_MPL_ASSERT_MSG((proto::matches<Expr, napl_grammar>::value), SYNTAX_NOT_CORRECT, (void)); check_and_execute(e, proto::matches<Expr, napl_grammar>()); //cout << napl_grammar()(e) << "\n"; } int main() { proto::terminal<Var<int> >::type i1, i2, i3, i4, i5; proto::terminal<program>::type Program; if_expr<proto::terminal<if_fun>::type> if_; int i=4242; check_grammar( Program[ if_(i1 < i2) [ i2 ] ]); /* check_grammar( Program[ if_(i1 < i2) [ i2 ].else_[ i3 ] ]); */ }
Hi Manjunath, in the future please put the name of the library you're asking about in the subject as I have done. On 1/27/2010 2:31 PM, Manjunath Kudlur wrote:
I am sure this has been asked before, but I am not able to find an answer to my specific question in the archives. I wanted to create a grammar that can accept statements like if_(expr)[ statement-list ].else_[statement-list]. <snip>
Proto has experimental (undocumented) support for data members like .else_ in the above expression. Have a look at libs/proto/example/virtual_member.cpp, which does pretty much exactly what you're trying to do above. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com
Eric, I did find some threads mentioning this in the archives. However, I had already written my code before I saw this, and I will feel better if I understand what's going wrong in my code. Could you please take a quick look? Thanks, Manjunath On Tue, Jan 26, 2010 at 10:45 PM, Eric Niebler <eric@boostpro.com> wrote:
Hi Manjunath, in the future please put the name of the library you're asking about in the subject as I have done.
On 1/27/2010 2:31 PM, Manjunath Kudlur wrote:
I am sure this has been asked before, but I am not able to find an answer to my specific question in the archives. I wanted to create a grammar that can accept statements like if_(expr)[ statement-list ].else_[statement-list].
<snip>
Proto has experimental (undocumented) support for data members like .else_ in the above expression. Have a look at libs/proto/example/virtual_member.cpp, which does pretty much exactly what you're trying to do above.
HTH,
-- Eric Niebler BoostPro Computing http://www.boostpro.com _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Eric Niebler
-
Manjunath Kudlur